你的神經網絡不工作的37個原因

37 Reasons why your Neural Network is not working

原文鏈接:https://blog.slavv.com/37-reasons-why-your-neural-network-is-not-working-4020854bd607

網絡已經訓練了12個小時了。看起來一切都好:梯度穩定,損失在降低。但是當檢測的時候就是檢測不出來東西。到底哪裏出了問題呢?

下面是一些很好的檢查策略。

0. 如何使用這份指南

很多地方可以出錯,但是一些優先級高的問題需要先處理。

  1. 首先使用一個對這個類型的數據有用的簡單模型(例如,對於圖像可以用VGG)。如果可以,使用標準loss。
  2. 關掉全部附加操作。如:regularization和數據增強
  3. 如果是finetuning一個模型,再次檢查一下預處理(preprocessing),它應該和原始模型訓練一樣。?
  4. 檢驗輸入數據是正確的。
  5. 從非常小的數據集開始(2-20個樣本)。在這個數據集上過擬合然後逐漸添加更多的數據。
  6. 開始逐漸把之前關掉的小功能添加回來:augmentation/regularization, custom loss functions,嘗試更復雜的模型。

如果完成了上述步驟還是不行的話,開始從下面的列表一個一個的驗證。

I. 數據問題

1. 檢查你的輸入數據

檢查你餵給網絡的輸入數據是否正確。舉個例子,我不止一次的將圖像的寬與高搞混。有時候,我錯誤地將全部都是零的數據餵給模型。或者一遍又一遍地使用同一個batch。所以打印一組batches的輸入和目標輸出,看看它們是否正確。

2. 嘗試隨機輸入

嘗試將隨機數字作爲輸入而不是實際的數據,看看是否表現的一樣。如果是,很確定是你的網絡再某一些點上將數據變成了垃圾。試着一層一層的debugging,看看哪裏出了問題。

3. 檢查data loader

你的數據可能沒事但將它們傳入網絡的代碼可能錯了。在做任何操作之前打印網絡第一層的輸入,檢查一下。

4. 確保輸入是連接着輸出標籤的

檢查一些輸入樣本是否有正確的標籤。確保打亂輸入樣本時輸出標籤也跟着變化。

5. 輸入和輸出的關聯性太隨機了嗎?

輸入和輸出的關聯性並不大。

6. 數據集中的髒數據太多?

檢查一些輸入樣本是否有正確的標籤。

7. 打亂數據集

如果你的數據集從未被打亂過,而且有特定的順序(標籤順序),這對學習是個負面影響。打亂數據集避免這個情況。確保同時打亂輸入和輸出標籤。

8. 減少類別失衡

如果有類別失衡的情況,你可能需要平衡你的損失函數。

9. 是否有足夠多的訓練數據

如果你從頭訓練一個網絡(not finetuning),你可能需要大量的數據。對於圖像分類,對每個類別你可能需要1000個圖像或者更多。

10. 確認你的batches不會包含單一的標籤

可能出現在有序的數據集的情況。打亂數據集避免這個情況。

11. 減小batch大小

非常大的batch會減少模型的generalization能力。

Addition 1. 首先使用標準的數據集

在測試新的網絡結構或寫新代碼時,首先使用標準的數據集而不是你自己的數據集。這是因爲這些數據集有相關的問題已經被解決了。而且不會有標籤錯誤,訓練測試分佈不同等等數據集相關的問題。

II. 數據 Normalization/Augmentation

12. Standardize the features

你的輸入是否平均值爲0,方差爲1。

13. 數據增強做太多了?

過多的數據增強再加上regularization(weight L2,dropout,等)可以導致網絡欠擬合。

14. 檢查預訓練模型的preprocessing

如果你使用預訓練的模型。確保在訓練的時候使用同樣normalization和preprocessing。例如,圖像的像素值應該在範圍[0, 1], [-1, 1]或[0, 255]。

15. 檢查訓練/驗證/測試集的預處理

在CS231n中指出。所有的預處理統計必須只在訓練集上進行計算,然後應用於驗證/測試集。例如,在整個數據集上計算平均值並減去它,然後再分成訓練/驗證/測試集會出現錯誤。

在每一個樣本和batch上檢查不同的預處理。

III. 實現錯誤

16. 嘗試解決一個簡單版本的問題

這會幫助找到bug在哪。例如,當目標輸出是一個目標類別和座標,試着先只預測類別。

17. 查看正確的損失

來自CS231n:

確保在初始化小參數時得到預期的損失。最好先單獨檢查data loss (因此將正則化強度設置爲零)。例如,對於使用Softmax分類器的CIFAR-10,我們期望初始損失爲2.302,因爲我們期望每個類的擴散概率爲0.1(因爲有10個類),而Softmax損失是正確類的負對數概率,因此:-ln(0.1) = 2.302。對於Weston Watkins SVM,我們期望所有期望的邊距都被破壞(因爲所有的分數都近似爲零),因此期望損失9(因爲每個錯誤的類的邊距爲1)。如果您沒有看到這些損失,那麼初始化可能會有問題。

在這之後,嘗試提高正則化強度應該可以提高損失。

18. 檢查你的損失函數

如果你實現的你自己的損失函數,使用單元測試,檢查一下有沒有bug。有時候,損失函數輕微的錯誤可以輕微的影響網絡的性能。

19. 檢驗損失輸入

如果你使用框架提供的loss函數,請確保傳遞給它的是它所期望的。例如,在PyTorch中,我將混合NLLLoss和CrossEntropyLoss,因爲前者需要一個softmax輸入,而後者不需要。

20. 調整損失權重

如果損失由幾個較小的損失函數組成,請確保它們相對於每個損失函數的大小是正確的。這可能需要測試不同的權重組合。

21. 監控其他度量

對於你的網絡是否訓練的正確,有時候損失不是最好的監控器。如果可以,也可以使用其他度量如正確率。

22. 測試每一個自定義層

你在網絡中有你自己自定義的層嗎?多次確認確保它們工作正常。

23. 檢查是否有frozen層或變量

檢查一下是否有無意中禁用了一些應該可學習的層/變量的梯度更新。

24. 增加網絡大小

也許您的網絡的表達能力不足以到達目標函數。嘗試在全連接層中添加更多層或更多隱藏單元。

25. 檢查隱藏層維度錯誤

如果你的輸入像這樣 (k, H, W) = (64, 64, 64),這會很容易錯過錯誤的關聯維度。先使用不同的數字作爲輸入維度的值,然後檢查是否正確。

26. 探索梯度檢查

如果你手動實現的梯度下降,梯度檢查確保向後傳播是正確的。

http://ufldl.stanford.edu/tutorial/supervised/DebuggingGradientChecking

http://cs231n.github.io/neural-networks-3/#gradcheck

https://www.coursera.org/lecture/machine-learning/gradient-checking-Y3s6r

IV. 訓練錯誤

27. 從一個很小的數據集開始解決問題

過擬合一個很小的數據集的子集,然後確保訓練正常。例如,一個類別只訓練一個或兩個樣本,然後看網絡是否可以學到它們的不同。然後每個類別加入更多的樣本。

28. 檢查權重初始化

如果不確定,就使用 XavierHe 初始化。另外,你的初始化可能會領向一個壞的局部最低值,所以試一下不同的初始化看看是否有幫助。

29. 檢查你的超參數

可能你使用的特別壞的超參數設置。如果可以,試一試grid search

30. 減少regularization

太多的regularization可以造成網絡嚴重的欠擬合。減少regularization像dropout,batch norm,weight/bias L2 regularization等等。在這個教程中,建議要首先避免欠擬合。這意味着你先要充分的過擬合,然後再解決過擬合。

31. 給模型多點時間

在你的網絡開始做有意義的預測之前,可能它需要更多的時間去訓練。如果你的loss穩定下降,就讓它繼續訓練。

32. 從訓練模式轉換爲測試模式

有一些架構有一些層像Batch Norm,Dropout和其他的在訓練和測試表現不同的層。轉換爲合適的模型對模型正確預測可能會幫助。

33. 訓練可視化

  • 監視每一層的激活、權重和更新。確保它們的量級匹配。例如,參數更新的量級(權重和偏差)應該是1-e3。

  • 考慮一個可視化庫,比如Tensorboard和Crayon。在緊要關頭,你還可以打印權重/偏差/激活。

  • 注意那些平均值遠遠大於0的層激活。嘗試Batch Norm或ELUs。

  • Deeplearning4j指出了在權重和偏見的直方圖中應該期望什麼:

    “對於權重,這些直方圖應該在一段時間後具有近似高斯(正態)分佈。對於偏差,這些直方圖通常從0開始,並且通常以近似高斯分佈結束(LSTM是一個例外)。注意那些發散到+/-∞的參數。注意那些非常大的偏見。如果類的分佈非常不平衡,這有時會發生在用於分類的輸出層。”

  • 檢查層更新,它們應該有一個高斯分佈。

34. 嘗試不同的優化器

你選擇的優化器不應該阻止你的網絡進行訓練,除非你選擇了特別糟糕的超參數。然而,對任務使用適當優化器有助於在最短的時間內獲得最多的訓練。你正在使用的論文描述算法的時候應該有指定了優化器。如果沒有,我傾向於使用Adam或帶動量的普通SGD。

更多關於梯度下降優化器的內容看這篇優秀的博文

35. 梯度爆炸/消失

  • 檢查層更新,因爲非常大的值可以表明爆炸梯度。梯度裁剪可能會有所幫助。
  • 檢查層激活。Deeplearning4j提供了一個很好的指導:“激活的良好標準偏差在0.5到2.0之間。明顯超出這一範圍可能意味着激活消失或爆炸。”

36. 學習率增加/減少

一個很低的學習率會導致你的模型收斂非常慢。

一個很高的學習率可以再開始的時候很快降低損失,但是可能很難找到最好的權重。

通過將當前的學習率乘以0.1或10來測試最佳的學習率。

37. 解決NaNs

據我所知,在訓練RNNs時,獲得一個NaN(Non-a-Number)是一個很大的問題。一些解決方法:

  • 降低學習速度,特別是如果你在前100次迭代中得到了NaNs。
  • 除以零或零的自然對數或負數可以導致NaNs。
  • Russell Stewart對如何解決NaNs有很好的建議。
  • 試着一層一層地評估你的網絡,看看NaNs出現在哪裏。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章