給卷積神經(jīng)網(wǎng)絡(luò)“修理工”的一份“說明書”
大數(shù)據(jù)文摘出品
編譯:羅然、雪清、Aileen
這篇文章的主要內(nèi)容來自作者的自身經(jīng)驗(yàn)和一些在線資源(如最出名的斯坦福大學(xué)的CS231n課程講義),是關(guān)于如何調(diào)試卷積神經(jīng)網(wǎng)絡(luò)從而提升其性能的。
文章主要關(guān)注深度神經(jīng)網(wǎng)絡(luò)架構(gòu)下的有監(jiān)督學(xué)習(xí)方式。雖然這個指南基于Python3.6壞境使用tensorflow(TF)編程,但它仍然可以作為一種語言無關(guān)的指南來使用。
假設(shè)我們有一個卷積神經(jīng)網(wǎng)絡(luò)來訓(xùn)練和評估,并假設(shè)評估結(jié)果比預(yù)期的更糟。
下文是排除故障并逐步提高性能的步驟,第一部分是進(jìn)行故障排除之前的必備事項(xiàng)和良好實(shí)踐。每個后續(xù)的章節(jié)標(biāo)題都對應(yīng)著一個問題,該部分專門用于解決這個問題。
我們會先拋出“更為常見”的問題,在每個標(biāo)題下,也會優(yōu)先給出“最容易實(shí)現(xiàn)”的解決方案。
故障排除前…
以下是在編寫深度學(xué)習(xí)算法時要遵循的最佳實(shí)踐,關(guān)于這個主題的很好的資料來源于CS231n課程講義以及Bengio的綜述論文。
- Stanford's CS231n課程講義:http://cs231n.github.io/
- Bengio的綜述論文:https://arxiv.org/pdf/1206.5533v2.pdf
1. 使用適當(dāng)?shù)娜罩居涗浐陀幸饬x的變量名稱。在TF中能夠通過名稱來跟蹤不同的變量,并在TF的可視化工具TensorBoard中顯示出計(jì)算圖。
最重要的是,每隔幾個訓(xùn)練步驟都要確保記錄了相關(guān)的值,例如:step_number, accuracy, loss, learning_rate。適用的話,加上更具體的度量標(biāo)準(zhǔn)(例如在圖像分割任務(wù)中使用mean_intersection_over_union,即mean_iou)。之后,就可以根據(jù)訓(xùn)練步驟畫出損失曲線。
譯者注:IoU,預(yù)測窗口與標(biāo)記窗口之間的交并比。
2. 確保你的網(wǎng)絡(luò)連接正確。使用TensorBoard或其他調(diào)試技術(shù)確保計(jì)算圖中每個操作的輸入和輸出都準(zhǔn)確無誤,還要確保在將數(shù)據(jù)和標(biāo)簽送入網(wǎng)絡(luò)之前對其進(jìn)行適當(dāng)?shù)念A(yù)處理和匹配。
3. 實(shí)施數(shù)據(jù)擴(kuò)充(data augmentation)技術(shù)。雖然這一點(diǎn)并不是對所有情況都適用,但是如果處理圖像的話,應(yīng)用簡單的數(shù)據(jù)擴(kuò)充技術(shù)(例如鏡像,旋轉(zhuǎn),隨機(jī)裁剪和尺度變換,添加噪聲,elastically deforming等),大部分時候會帶來巨大的性能提升。而且TF具有大多數(shù)這些操作的內(nèi)置函數(shù),十分良心了。
4. 對所有層使用權(quán)重初始化和正則化。不要將權(quán)重初始化為相同的值,更糟的是將其初始化為0。這樣做會帶來對稱性(symmetry)和潛在的梯度彌散問題,在大多數(shù)情況下會導(dǎo)致可怕的結(jié)果。通常,如果在權(quán)重初始化時遇到問題,可以考慮將Batch Normalization層添加到網(wǎng)絡(luò)中。
BN論文鏈接:https://arxiv.org/abs/1502.03167。
5. 確保正則項(xiàng)不會“壓倒”損失函數(shù)中的其他項(xiàng)。關(guān)閉正則化,找出“損失”的數(shù)量級,然后適當(dāng)?shù)卣{(diào)整正則項(xiàng)大小。確保隨著正則化強(qiáng)度的增加,損失也在增加。
6. 嘗試過擬合一個小數(shù)據(jù)集。關(guān)閉正則化/隨機(jī)失活/數(shù)據(jù)擴(kuò)充,使用訓(xùn)練集的一小部分,讓神經(jīng)網(wǎng)絡(luò)訓(xùn)練幾個周期。確??梢詫?shí)現(xiàn)零損失,如果沒有,那么很可能什么地方出錯了。
在某些情況下,將損失降到0尤其具有挑戰(zhàn)性。例如,在圖像語義分割中,如果你的損失涉及每個像素的softmax-ed logits和ground truth labels之間的交叉熵,那么可能真的難以將其降低到0。不過,你應(yīng)當(dāng)尋求達(dá)到接近100%的準(zhǔn)確率,通過獲取softmax-ed logits的argmax并將其與ground truth labels進(jìn)行比較來計(jì)算。
譯者注:在機(jī)器學(xué)習(xí)中,“ground truth”一詞指的是監(jiān)督學(xué)習(xí)技術(shù)中訓(xùn)練集分類的準(zhǔn)確性,簡單地說就是正確標(biāo)注的數(shù)據(jù)。
7. 在過擬合上述小數(shù)據(jù)集的同時,找到合適的學(xué)習(xí)率。下面的內(nèi)容直接引自Bengio的論文:最優(yōu)學(xué)習(xí)率通常接近于不會增加訓(xùn)練誤差的最大學(xué)習(xí)率,一種可以指導(dǎo)啟發(fā)式設(shè)置學(xué)習(xí)率的觀測方法是,例如,以較大的學(xué)習(xí)率開始,如果訓(xùn)練誤差發(fā)散,就用最大學(xué)習(xí)率除以3再試試,直到觀察不到發(fā)散為止。
8. 執(zhí)行梯度檢驗(yàn)(gradient checks)。如果你在計(jì)算圖中使用自定義操作——即不是內(nèi)置的TF操作,則梯度檢驗(yàn)尤其重要。下面的鏈接有一些實(shí)現(xiàn)梯度檢驗(yàn)的技巧。
Gradient checks:http://cs231n.github.io/neural-networks-3/
如果損失(Loss Value)沒有改善…
如果你訓(xùn)練了幾個周期,損失還是沒有改善,甚至還越來越大,則應(yīng)該考慮下面幾個步驟了:
1.確保使用了合理的損失函數(shù),而且優(yōu)化的是正確的張量。此處提供常見的損失函數(shù)列表。
https://en.wikipedia.org/wiki/Loss_functions_for_classification
2. 使用一個得當(dāng)?shù)膬?yōu)化器,此處提供了常用優(yōu)化器列表。
https://keras.io/optimizers/
3. 確保變量真的在訓(xùn)練。為了檢查這一點(diǎn),你可以查看TensorBoard的直方圖,或者編寫一個腳本,在幾個不同的訓(xùn)練實(shí)例中計(jì)算每個張量的范數(shù)(L1或 L∞),并打印出這些張量的名稱。
如果你的變量未按預(yù)期進(jìn)行訓(xùn)練,請參閱下列文章:
https://gist.github.com/zeyademam/0f60821a0d36ea44eef496633b4430fc#variable-not-training
4. 調(diào)整初始學(xué)習(xí)率并實(shí)施適當(dāng)?shù)膶W(xué)習(xí)率計(jì)劃(learning rate schedule),這可能是最具影響力的“修復(fù)”。如果損失越來越嚴(yán)重,可能是初始學(xué)習(xí)率太大了。另一方面,如果損失幾乎不變,可能是初始學(xué)習(xí)率太小了。無論如何,一旦確定了有效的初始學(xué)習(xí)率,就應(yīng)該進(jìn)行學(xué)習(xí)率衰減。像ADAM這樣的優(yōu)化器會在內(nèi)部實(shí)現(xiàn)學(xué)習(xí)率衰減,但是,這些學(xué)習(xí)率的更新通常會很慢,在優(yōu)化器之上實(shí)現(xiàn)自己的學(xué)習(xí)率計(jì)劃會是個好主意。
5. 確保沒有過擬合。有一些方法可以實(shí)現(xiàn)過擬合,也有一些方法可以避免它。繪制損失值與訓(xùn)練周期的曲線圖,如果曲線看起來像拋物線,那么很可能過擬合了。
請參閱這篇文章:
https://gist.github.com/zeyademam/0f60821a0d36ea44eef496633b4430fc#overfitting
如果變量沒在訓(xùn)練…
像上面說的那樣,使用TensorBoard的直方圖,或編寫一個腳本,在幾個不同的訓(xùn)練實(shí)例中計(jì)算每個張量的范數(shù),并打印出這些張量的名稱。如果變量未按預(yù)期進(jìn)行訓(xùn)練:
1. 確保TF將其視為可訓(xùn)練的變量。查看TF GraphKeys以獲取更多詳細(xì)信息。
https://www.tensorflow.org/api_docs/python/tf/GraphKeys
2. 確保沒發(fā)生梯度彌散。如果下游變量(接近輸出的變量)訓(xùn)練正常但上游變量(接近輸入的變量)幾乎不變,則可能遇上了梯度彌散的問題。
請參閱下面的文章:
https://gist.github.com/zeyademam/0f60821a0d36ea44eef496633b4430fc#vanishingexploding-gradients
3. 確保ReLus還在“放電”。如果大部分神經(jīng)元“電壓”被“鉗制”為零,那么應(yīng)該重新修正權(quán)重初始化策略,嘗試使用不太激進(jìn)的學(xué)習(xí)率計(jì)劃,并嘗試減少正則化(權(quán)重衰減)。
譯者注:ReLu,線性整流函數(shù),又稱修正線性單元,是一種人工神經(jīng)網(wǎng)絡(luò)中常用的激活函數(shù)。
梯度彌散/梯度爆炸…
1. 考慮使用更好的權(quán)重初始化策略。如果在訓(xùn)練開始時梯度更新非常小,則這點(diǎn)尤其重要。
2. 考慮換一下激活函數(shù)。如果正在使用ReLus,請考慮使用leaky ReLu或MaxOut激活函數(shù)替換它們。你應(yīng)該完全避免sigmoid激活函數(shù),并遠(yuǎn)離tanh。
3.如果用遞歸神經(jīng)網(wǎng)絡(luò)的話,考慮使用LSTM。
詳情請看這篇文章:
https://medium.com/@karpathy/yes-you-should-understand-backprop-e2f06eab496b
過擬合…
過擬合就是網(wǎng)絡(luò)“記住”了訓(xùn)練數(shù)據(jù)的情況。如果網(wǎng)絡(luò)在訓(xùn)練集和驗(yàn)證集上,準(zhǔn)確率差別很大,可能它就過擬合了。
參見此處的Train / Val準(zhǔn)確率部分:http://cs231n.github.io/neural-networks-3/
1. 實(shí)施數(shù)據(jù)擴(kuò)充技術(shù)。可上翻至本文第一節(jié)“故障排除前”中的內(nèi)容。
2. 實(shí)施隨機(jī)失活(dropout)。隨機(jī)失活指在訓(xùn)練期間每個步驟隨機(jī)地忽略掉一些神經(jīng)元,在前向傳播期間這些神經(jīng)元的貢獻(xiàn)被移除并且在反向傳播期間它們不被更新。
了解更多信息:
https://machinelearningmastery.com/dropout-regularization-deep-learning-models-keras/
3. 增加正則化。
4. 實(shí)施批規(guī)范化操作(Batch normalization)。
詳情請看這里:https://arxiv.org/abs/1502.03167
5. 實(shí)施基于驗(yàn)證集的早期停止(early stopping)。由于網(wǎng)絡(luò)訓(xùn)練了太多個周期,因此可能會發(fā)生過擬合,早期停止有助于消除這個問題。
參考這里:
https://en.wikipedia.org/wiki/Early_stopping#Validation-based_early_stopping
6. 如果其他一切都失敗了,請使用較小的網(wǎng)絡(luò)。這真的應(yīng)該是你的最后手段,事實(shí)上這里的課程講義對這種做法保持謹(jǐn)慎。
還能調(diào)試些什么…
1. 考慮使用加權(quán)的損失函數(shù)(weighted loss function)。例如,在圖像語義分割中,神經(jīng)網(wǎng)絡(luò)對輸入圖像中的每個像素進(jìn)行分類。與其他類相比,某些類可能很少出現(xiàn),在這種情況下,權(quán)衡少見的類可能會改進(jìn)mean_iou度量。
2. 更改網(wǎng)絡(luò)架構(gòu)。你之前的網(wǎng)絡(luò)可能太深或太淺。
3. 考慮使用集成模型。
4. 用小數(shù)步長卷積(strided convolutions)替換最大值匯合層和平均值匯合層。
5. 執(zhí)行徹底的超參數(shù)搜索。
6. 更改隨機(jī)數(shù)種子。
7. 如果上面的方法都失敗了,還是去尋找更多數(shù)據(jù)吧。
相關(guān)報道:https://gist.github.com/zeyademam/0f60821a0d36ea44eef496633b4430fc
【本文是51CTO專欄機(jī)構(gòu)大數(shù)據(jù)文摘的原創(chuàng)譯文,微信公眾號“大數(shù)據(jù)文摘( id: BigDataDigest)”】

戳這里,看該作者更多好文