最近在做基於MTCNN的人臉識別和檢測的項目,在訓練模型的過程中總是會不定時地出現損失值為nan的情況,Debug了好久終於找到了問題所在,這里總結以下可能出現nan的幾種情況:
1、在分類問題中,我們經常使用到交叉熵損失函數,需要注意的是:由於交叉熵損失函數里有對數計算,因此對數的真數部分不能為0,所以我們在計算計算交叉熵時需要給這個真數部分限定一個范圍,否則會出現數值下溢的問題,我們可以采取的辦法是使用tf.clip_by_value(input,min_value,max_value)函數來限定真數的下限;
2、另一種情況是在訓練開始時后出現損失函數值為nan,這種情況一般是由於學習率太大,我們需要減小學習率;或者是在訓練一段時間后出現nan,這種情況可能是由於梯度爆炸導致的,一種典型的情況是在訓練RNN的過程中會出現梯度爆炸,我們可以對梯度進行裁剪,將梯度的最大值限定在某個常數;
3、還有一種就比較奇葩了,就是我遇到的情況,准確地講這是一個bug,我在計算一個批次的損失時使用了tf.reduce_mean()這個函數,在將tensor丟進這個函數之前,tensor是根據一個索引篩選過的,問題來了:要是這個經過選擇的tensor為空會出現什么情況?我特意將這個情況實驗了以下,結果發現:這種情況下返回的就是nan。果斷使用tf.reduce_sum(),與前面不同的是此時計算出來的損失會是原來的倍數,將代碼修改之后,這個bug終於被解決掉了。
找bug找的好辛苦,特此紀念一下。。。
