在訓練過程中loss出現NaN的原因以及可以采取的方法


NaN的意思是not a number,不是一個數字。

1、梯度爆炸

一般loss的相關量是w——> w的相關量(更新方式)是梯度——>和梯度有關

原因:在學習過程中,梯度變得非常大,使得學習的過程偏離了正常的軌跡。

症狀:觀察輸出日志(runtime log)中每次迭代的loss值,你會發現loss隨着迭代有明顯的增長,最后因為loss值太大以致於不能用浮點數去表示,所以變成了NaN。

可采取的方法:(1)降低學習率,降低至少一個數量級。如果在你的模型中有多個loss層,就不能降低基礎的學習率base_lr,而是要檢查日志,找到產生梯度爆炸的層,然后降低該層中的loss_weight。

2、錯誤的學習率策略及參數

原因:在學習過程中,caffe不能得出一個正確的學習率,相反會得到inf或者nan的值。這些錯誤的學習率呈上所有的梯度使得所有參數變成無效的值。

症狀:觀察輸出日志(runtime log),應該可以看到學習率變成Nan.

可采取的方法:修改文件中所有能影響學習率的參數。比如,如果你設置的學習率策略是lr_policy:"policy",而你又忘了設置最大迭代次數max_iter,那么最后你會得到lr=NaN...

3、錯誤的損失函數

原因:有時,在損失層計算損失值時會出現NaN的情況。比如,向InfogainLoss層沒有歸一化輸入值,使用自定義的損失層等。

症狀:觀察輸出日志(runtime log)的時候,你可能不會發現任何異常:loss逐漸下降,然后突然出現NaN.

可采取的方法:嘗試重現該錯誤,打印損失層的值並調試。

舉個例子:如果有個label並沒有在批量數據中出現,頻率為0,結果loss出現了NaN的情況,在這種情況下,需要用足夠大的batch來避免這個錯誤。

4、錯誤的輸入

原因:你的輸入中存在NaN!

症狀:一旦學習過程中碰到這種錯誤的輸入,輸出就會變成NaN。觀察輸出日志(runtime log)的時候,你可能也不會出現任何異常:loss逐漸下降,然后突然出現NaN.

可采取的方法:重建你的輸入數據集,確保你的訓練集/驗證集中沒有臟數據(錯誤的圖片文件)。調試時,使用一個簡單的網絡去讀取輸入,如果有一個輸入有錯誤,這個網絡的loss也會出現NaN.

5、Pooling層的步長大於核的尺寸

由於一些原因,步長stride > 核尺寸kernel_size的pooling層會出現NaN。

 參考:https://www.jianshu.com/p/9018d08773e6


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM