2016-05-14 209 views
18

我有一個「單熱編碼」(全1和零)的數據矩陣,有260,000行和35列。我正在使用Keras來訓練一個簡單的神經網絡來預測一個連續變量。使網絡中的代碼如下:訓練迴歸網絡時NaN損失

model = Sequential() 
model.add(Dense(1024, input_shape=(n_train,))) 
model.add(Activation('relu')) 
model.add(Dropout(0.1)) 

model.add(Dense(512)) 
model.add(Activation('relu')) 
model.add(Dropout(0.1)) 

model.add(Dense(256)) 
model.add(Activation('relu')) 
model.add(Dropout(0.1)) 
model.add(Dense(1)) 

sgd = SGD(lr=0.01, nesterov=True); 
#rms = RMSprop() 
#model.compile(loss='categorical_crossentropy', optimizer=rms, metrics=['accuracy']) 
model.compile(loss='mean_absolute_error', optimizer=sgd) 
model.fit(X_train, Y_train, batch_size=32, nb_epoch=3, verbose=1, validation_data=(X_test,Y_test), callbacks=[EarlyStopping(monitor='val_loss', patience=4)]) 

然而,在訓練過程中,我很好看的損失減少,但第二個時期的中間過程,它進入楠:

Train on 260000 samples, validate on 64905 samples 
Epoch 1/3 
260000/260000 [==============================] - 254s - loss: 16.2775 - val_loss: 
13.4925 
Epoch 2/3 
88448/260000 [=========>....................] - ETA: 161s - loss: nan 

我試過用RMSProp代替SGD,我試過tanh而不是relu,我試過並沒有輟學,都沒有用。我嘗試了一個較小的模型,即只有一個隱藏層和相同的問題(它在不同的點上變成了nan)。但是,它的功能較少,即只有5列,並提供相當好的預測。它似乎有某種溢出,但我無法想象爲什麼 - 損失不是不合理地大。

Python版本2.7.11,僅在Linux機器上運行,僅限CPU。我用最新版本的Theano測試了它,而且我也得到了Nans,所以我嘗試去Theano 0.8.2並且有同樣的問題。與最新版本的凱拉斯有同樣的問題,並且還與0.3.2版本。

+0

嘗試損失='mean_squared_error',優化器='亞當'與一個隱藏層 - 仍然nans? –

+0

@ 1「當Adam優化器使用上述模型時,我會得到nans。僅僅有一層,在三個培訓階段並沒有提供任何幫助。 –

回答

21

神經網絡迴歸很難得到工作,因爲輸出是無界的,所以你特別容易出現exploding gradients problem(可能的原因)。

歷史上,梯度分解的一個關鍵解決方案是降低學習速率,但隨着像Adam這樣的參數自適應學習速率算法的出現,您不再需要設置學習速率以獲得良好性能。除非你是神經網絡惡魔,並且知道如何調整學習計劃,否則幾乎沒有理由再使用SGD。

這裏有一些事情你可能嘗試:

  1. 通過quantile normalizingz scoring歸你輸出。要嚴格,請在訓練數據上計算這種轉換,而不是在整個數據集上。例如,在分位數歸一化的情況下,如果示例在訓練集的第60百分位,則它的值爲0.6。 (您也可以將分位數標準化值向下移動0.5,以使第0百分位數爲-0.5,第100百分位數爲+0.5)。

  2. 通過增加輟學率或增加L1和L2懲罰加權正規化。 L1正則化類似於特徵選擇,並且由於您認爲將特徵數量減少到5可以提供良好的性能,L1也可以。

  3. 如果這些仍然沒有幫助,請減小網絡的大小。這並不總是最好的主意,因爲它可能會損害性能,但在您的情況下,您有相對於輸入特徵(35)的大量第一層神經元(1024),因此可能有所幫助。

  4. 將批量大小從32增加到128. 128是相當標準的,可能會增加優化的穩定性。

7

1" 回答是相當不錯的。但是,所有的修復似乎解決問題間接而不是直接。我會建議使用梯度的剪裁,這將只是剪輯高於某個任何梯度值。

在Keras你可以使用clipnorm=1(見https://keras.io/optimizers/)簡單地夾所有梯度與限額以上1

+0

公平點!例如,這是一種完全合法的策略,經常與循環神經網絡一起使用。然而,在訴諸此之前,檢查一下簡單的優化沒有出錯是很好的做法。 –

10

我之前遇到過同樣的問題。我搜索並找到這個問題和答案。上面提到的所有技巧對訓練深度神經網絡都很重要。我試了一下,但還是得到了NAN。

我也在這裏找到這個問題。 https://github.com/fchollet/keras/issues/2134。 我引用了作者的總結如下: 「我想指出這一點,以便將來存檔可能會遇到此問題的其他人。在進入訓練過程之後,我突然回到了失誤功能。我檢查了relus,優化器,丟失函數,根據relus,我的網絡規模和網絡形狀的丟失率。我仍然得到損失,最終變成了一個南非,我變得非常沮喪。

然後,我明白了。我可能會有一些不好的意見。事實證明,我交給我的CNN的一張圖片(並且意味着正常化)僅僅是0。我沒有檢查這種情況,當我減去平均值並通過std偏差進行歸一化,因此我最終得到了一個只是nan的樣例矩陣。一旦我修復了我的標準化功能,我的網絡現在可以完美訓練。「

我同意上面的觀點:輸入對您的網絡很敏感。 在我的情況下,我使用密度估計的對數值作爲輸入。絕對值可能非常大,這可能導致經過幾個梯度的NaN。我認爲輸入檢查是必要的。首先,您應確保輸入不包含包括-inf或inf或絕對值中的某些非常大的數字。

+0

我和你有同樣的問題。在檢查我的數據時,我發現有多個inf數據點的地方。解決這個問題。 – troymyname00

-1

我試過這個頁面上的每一個建議和其他許多人無濟於事。我們用熊貓導入csv文件,然後使用帶文本輸入的keras Tokenizer創建詞彙表和單詞矢量矩陣。在注意到一些CSV文件導致nan而其他人工作後,突然我們看了看文件的編碼,並意識到ascii文件不與keras一起工作,導致nan丟失和0.0000e+00的準確性;然而,utf-8和utf-16文件分別是正在工作!突破。

如果執行文本分析和嘗試這些建議後得到nan損失,使用file -i {input}(Linux)或file -I {input}(OSX)發現您的文件類型。如果您有ISO-8859-1us-ascii,請嘗試轉換爲utf-8utf-16le。還沒有嘗試過後者,但我想它會起作用。希望這可以幫助一個非常非常沮喪的人!