在面對模型不收斂的時候,首先要保證訓(xùn)練的次數(shù)夠多。在訓(xùn)練過程中,loss并不是一直在下降,準確率一直在提升的,會有一些震蕩存在。只要總體趨勢是在收斂就行。若訓(xùn)練次數(shù)夠多(一般上千次,上萬次,或者幾十個epoch)沒收斂,再考慮采取措施解決。
一、數(shù)據(jù)與標簽
沒有對數(shù)據(jù)進行預(yù)處理。數(shù)據(jù)分類標注是否準確?數(shù)據(jù)是否干凈?
沒有對數(shù)據(jù)進行歸一化。由于不同評價指標往往具有不同的量綱和量綱單位,這樣的情況會影響到數(shù)據(jù)分析的結(jié)果,為了消除指標之間的量綱影響,需要進行數(shù)據(jù)標準化處理,以解決數(shù)據(jù)指標之間的可比性。原始數(shù)據(jù)經(jīng)過數(shù)據(jù)標準化處理后,各指標處于同一數(shù)量級,適合進行綜合對比評價。此外,大部分神經(jīng)網(wǎng)絡(luò)流程都假設(shè)輸入輸出是在0附近的分布,從權(quán)值初始化到激活函數(shù)、從訓(xùn)練到訓(xùn)練網(wǎng)絡(luò)的優(yōu)化算法。將數(shù)據(jù)減去均值并除去方差。
樣本的信息量太大導(dǎo)致網(wǎng)絡(luò)不足以fit住整個樣本空間。樣本少只可能帶來過擬合的問題,你看下你的training set上的loss收斂了嗎?如果只是validate set上不收斂那就說明overfitting了,這時候就要考慮各種anti-overfit的trick了,比如dropout,SGD,增大minibatch的數(shù)量,減少fc層的節(jié)點數(shù)量,momentum,finetune等。
標簽的設(shè)置是否正確。
二、模型
網(wǎng)絡(luò)設(shè)定不合理。如果做很復(fù)雜的分類任務(wù),卻只用了很淺的網(wǎng)絡(luò),可能會導(dǎo)致訓(xùn)練難以收斂。應(yīng)當(dāng)選擇合適的網(wǎng)絡(luò),或者嘗試加深當(dāng)前網(wǎng)絡(luò)?傮w來說,網(wǎng)絡(luò)不是越深越好,開始可以搭建一個3~8層的網(wǎng)絡(luò),當(dāng)這個網(wǎng)絡(luò)實現(xiàn)的不錯時,你可以考慮實驗更深的網(wǎng)絡(luò)來提升精確度。從小網(wǎng)絡(luò)開始訓(xùn)練意味著更快,并且可以設(shè)置不同參數(shù)觀察對網(wǎng)絡(luò)的影響而不是簡單的堆疊更多層。
Learning rate不合適,如果太大,會造成不收斂,如果太小,會造成收斂速度非常慢。學(xué)習(xí)率設(shè)定不合理。在自己訓(xùn)練新網(wǎng)絡(luò)時,可以從0.1開始嘗試,如果loss不下降的意思,那就降低,除以10,用0.01嘗試,一般來說0.01會收斂,不行的話就用0.001. 學(xué)習(xí)率設(shè)置過大,很容易震蕩。不過剛剛開始不建議把學(xué)習(xí)率設(shè)置過小,尤其是在訓(xùn)練的開始階段。在開始階段我們不能把學(xué)習(xí)率設(shè)置的太低否則loss不會收斂。我的做法是逐漸嘗試,從0.1,0.08,0.06,0.05 ......逐漸減小直到正常為止。有的時候候?qū)W習(xí)率太低走不出低估,把沖量提高也是一種方法,適當(dāng)提高mini-batch值,使其波動不大。learning rate設(shè)大了會帶來跑飛(loss突然一直很大)的問題。這個是新手最常見的情況——為啥網(wǎng)絡(luò)跑著跑著看著要收斂了結(jié)果突然飛了呢?可能性最大的原因是你用了relu作為激活函數(shù)的同時使用了softmax或者帶有exp的函數(shù)做分類層的loss函數(shù)。當(dāng)某一次訓(xùn)練傳到最后一層的時候,某一節(jié)點激活過度(比如100),那么exp(100)=Inf,發(fā)生溢出,bp后所有的weight會變成NAN,然后從此之后weight就會一直保持NAN,于是loss就飛起來辣。如果lr設(shè)的過大會出現(xiàn)跑飛再也回不來的情況。這時候你停一下隨便挑一個層的weights看一看,很有可能都是NAN了。對于這種情況建議用二分法嘗試。0.1~0.0001.不同模型不同任務(wù)最優(yōu)的lr都不一樣。
隱層神經(jīng)元數(shù)量錯誤。在一些情況下使用過多或過少的神經(jīng)元數(shù)量都會使得網(wǎng)絡(luò)很難訓(xùn)練。太少的神經(jīng)元數(shù)量沒有能力來表達任務(wù),而太多的神經(jīng)元數(shù)量會導(dǎo)致訓(xùn)練緩慢,并且網(wǎng)絡(luò)很難清除一些噪聲。隱層神經(jīng)元數(shù)量可以從256 到1024中間開始設(shè)置,然后可以看看研究人員使用的數(shù)字,可以用作參考。如果他們使用的數(shù)字與這個大不相同,那么可以想象一下這其中的原理。在決定使用隱層的單元數(shù)量之前,最為關(guān)鍵的是考慮你需要通過這個網(wǎng)絡(luò)表達信息的實際值的最少數(shù)量,然后再慢慢增加這個數(shù)字。如果你做回歸任務(wù)可以考慮使用的神經(jīng)元數(shù)量為輸入或輸出變量的2到3倍。實際上,與其它因素相比,隱藏單元的數(shù)量通常對于神經(jīng)網(wǎng)絡(luò)的性能影響相當(dāng)小。并且在很多情況下,增大所需要隱藏單元的數(shù)量僅僅是減慢了訓(xùn)練速度。
錯誤初始化網(wǎng)絡(luò)參數(shù)。如果沒有正確初始化網(wǎng)絡(luò)權(quán)重,那么網(wǎng)絡(luò)將不能訓(xùn)練。通常使用的比較多的初始化權(quán)重的方法有‘he’,’lecun’,’xavier’在實際應(yīng)用中這些方法有非常好的性能而網(wǎng)絡(luò)偏差通常初始化為0,你可以選擇一個最適合你任務(wù)的初始化方式。
沒有正則化。 正則化典型的就是dropout、加噪聲等。即使數(shù)據(jù)量很大或者你覺得網(wǎng)絡(luò)不可能出現(xiàn)過擬合,但是對網(wǎng)絡(luò)進行正則化還是很有必要的。dropout 通常從設(shè)定參數(shù)為0.75或0.9開始,根據(jù)你認為網(wǎng)絡(luò)出現(xiàn)過擬合的可能性來調(diào)整這個參數(shù)。另外,如果你確定這個網(wǎng)絡(luò)不會出現(xiàn)過擬合,那么可以將參數(shù)設(shè)定為0.99。正則化不僅僅可以防止過擬合,并且在這個隨機過程中,能夠加快訓(xùn)練速度以及幫助處理數(shù)據(jù)中的異常值并防止網(wǎng)絡(luò)的極端權(quán)重配置。對數(shù)據(jù)擴增也能夠?qū)崿F(xiàn)正則化的效果,最好的避免過擬合的方法就是有大量的訓(xùn)練數(shù)據(jù)。
Batch Size 過大。Batch size 設(shè)置的過大會降低網(wǎng)絡(luò)的準確度,因為它降低了梯度下降的隨機性。另外,在相同情況下batch size 越大那么要達到相同的精確度通常需要訓(xùn)練更多的epoch。我們可以嘗試一些較小的batch size 如 16 ,8 甚至是1。使用較小的batch size 那么一個epoch就可以進行更多次的權(quán)值更新。這里有兩個好處,第一,可以跳出局部最小點。其二可以表現(xiàn)出更好的泛化性能。
學(xué)習(xí)率設(shè)的不對。許多深度學(xué)習(xí)的框架默認開啟了gradient clipping ,這個可以處理gradient explosion問題,這個是非常有用的,但是在默認情況下它也很難找到最佳學(xué)習(xí)率。如果你正確的清理了數(shù)據(jù),刪除了異常值,以及設(shè)定了正確的學(xué)習(xí)率,那么可以不需要使用gradient clipping,偶爾你也會遇到gradient explosion問題,那么你可以開啟gradient clipping。但是,出現(xiàn)這種問題一般情況下表明數(shù)據(jù)有其它問題,而gradient clipping只是一個臨時的解決方案。
最后一層的激活函數(shù)用的不對。在最后一層使用錯誤的激活函數(shù)會導(dǎo)致網(wǎng)絡(luò)最終不能輸出你期望的范圍值,最常見的錯誤就是最后一層使用Relu函數(shù),其輸出無負值。如果是做回歸任務(wù),大多數(shù)情況下不需要使用激活函數(shù),除非你知道你所期望的值作為輸出。想象一下你的數(shù)據(jù)值實際代表了什么,以及再歸一化之后它們的范圍是多少,最有可能的情況是輸出沒有邊界的正數(shù)和負數(shù)。在這種情況下,最后一層不應(yīng)該使用激活函數(shù)。如果你的輸出值只能在某個范圍內(nèi)有意義,如0~1范圍內(nèi)的概率組成。那么最后一層可以使用sigmoid函數(shù)。
網(wǎng)絡(luò)存在壞梯度。 如果你訓(xùn)練了幾個epoch誤差沒有改變,那可能是你使用了Relu,可以嘗試將激活函數(shù)換成leaky Relu。因為Relu激活函數(shù)對正值的梯度為1,負值的梯度為0。因此會出現(xiàn)某些網(wǎng)絡(luò)權(quán)值的成本函數(shù)的斜率為0,在這種情況下我們說網(wǎng)絡(luò)是“dead”,因為網(wǎng)絡(luò)已經(jīng)不能更新。
如何通過train loss與test loss分析網(wǎng)絡(luò)當(dāng)下的狀況?
train loss 不斷下降,test loss不斷下降,說明網(wǎng)絡(luò)仍在學(xué)習(xí);
train loss 不斷下降,test loss趨于不變,說明網(wǎng)絡(luò)過擬合;
train loss 趨于不變,test loss不斷下降,說明數(shù)據(jù)集100%有問題;
train loss 趨于不變,test loss趨于不變,說明學(xué)習(xí)遇到瓶頸,需要減小學(xué)習(xí)率或批量數(shù)目;
train loss 不斷上升,test loss不斷上升,說明網(wǎng)絡(luò)結(jié)構(gòu)設(shè)計不當(dāng),訓(xùn)練超參數(shù)設(shè)置不當(dāng),數(shù)據(jù)集經(jīng)過清洗等問題。