此篇文章是在原創教程這個欄目下,但實際上是一篇匯總整理文章。相信大家在做深度學習時對調參尤為無奈,經驗不足亂調一通,或者參數太多無從下手,我也如此。希望通過此文匯總網上一些調參的經驗方法,供大家參考。此文會對網上每一篇調參文章做簡練的總結與提煉,以此為此文的組成單元,並附上原文的鏈接。如果遇到不對的地方,歡迎指正~本文也將不定期更新,最后祝大家調參(煉金)順利!
有多少人工,就有多少智能!(笑哭臉)



正文開始
UNIT 1
-
case1:網絡錯誤沒有正確訓練,損失完全不收斂。可能兩種原因:1,錯誤的input data,網絡無法學習。 2,錯誤的網絡,網絡無法學習。解決辦法:(1)請檢測自己的數據是否存在可以學習的信息,這個數據集中的數值是否泛化(防止過大或過小的數值破壞學習)。(2)如果是錯誤的數據則你需要去再次獲得正確的數據,如果是數據的數值異常我們可以使用zscore函數來解決這個問題(3)如果是網絡的錯誤,則希望調整網絡,包括:網絡深度,非線性程度,分類器的種類等等。
-
case2:部分收斂。可能原因:1.underfitting,就是網絡的分類太簡單了沒辦法去分類,因為沒辦法分類就是沒辦法學到正確的知識。2.overfitting,就是網絡的分類太復雜了以至於它可以學習數據中的每一個信息甚至是錯誤的信息他都可以學習。解決辦法:(1)underfitting: 增加網絡的復雜度(深度),降低learning rate,優化數據集,增加網絡的非線性度(ReLu),采用batch normalization。(2)overfitting: 豐富數據,增加網絡的稀疏度,降低網絡的復雜度(深度),L1 regularization,L2 regulariztion,添加Dropout,Early stopping,適當降低Learning rate,適當減少epoch的次數,
-
case3:全部收斂但效果不好。這是個好的開始,接下來我們要做的就是微調一些參數。解決辦法:調整方法就是保持其他參數不變,只調整一個參數。這里需要調整的參數會有:learning rate,minibatch size,epoch,filter size,number of filter
原文鏈接:https://blog.csdn.net/qq_20259459/article/details/70316511
UNIT 2
-
好的實驗環境是成功的一半:(1)將各個參數的設置部分集中在一起。如果參數的設置分布在代碼的各個地方,那么修改的過程想必會非常痛苦。(2)可以輸出模型的損失函數值以及訓練集和驗證集上的准確率。(3)可以考慮設計一個子程序,可以根據給定的參數,啟動訓練並監控和周期性保存評估結果。再由一個主程序,分配參數以及並行啟動一系列子程序。
-
畫圖:畫圖是一個很好的習慣,一般是訓練數據遍歷一輪以后,就輸出一下訓練集和驗證集准確率。同時畫到一張圖上。這樣訓練一段時間以后,如果模型一直沒有收斂,那么就可以停止訓練,嘗試其他參數了,以節省時間。 如果訓練到最后,訓練集,測試集准確率都很低,那么說明模型有可能欠擬合。那么后續調節參數方向,就是增強模型的擬合能力。例如增加網絡層數,增加節點數,減少dropout值,減少L2正則值等等。 如果訓練集准確率較高,測試集准確率比較低,那么模型有可能過擬合,這個時候就需要向提高模型泛化能力的方向,調節參數。
-
從粗到細分階段調參:(1)建議先參考相關論文,以論文中給出的參數作為初始參數。至少論文中的參數,是個不差的結果。(2)如果找不到參考,那么只能自己嘗試了。可以先從比較重要,對實驗結果影響比較大的參數開始,同時固定其他參數,得到一個差不多的結果以后,在這個結果的基礎上,再調其他參數。例如學習率一般就比正則值,dropout值重要的話,學習率設置的不合適,不僅結果可能變差,模型甚至會無法收斂。(3)如果實在找不到一組參數,可以讓模型收斂。那么就需要檢查,是不是其他地方出了問題,例如模型實現,數據等等。
-
提高速度:調參只是為了尋找合適的參數,而不是產出最終模型。一般在小數據集上合適的參數,在大數據集上效果也不會太差。因此可以嘗試對數據進行精簡,以提高速度,在有限的時間內可以嘗試更多參數。(1)對訓練數據進行采樣。例如原來100W條數據,先采樣成1W,進行實驗看看。(2)減少訓練類別。例如手寫數字識別任務,原來是10個類別,那么我們可以先在2個類別上訓練,看看結果如何。
-
超參數范圍:建議優先在對數尺度上進行超參數搜索。比較典型的是學習率和正則化項,我們可以從諸如0.001 0.01 0.1 1 10,以10為階數進行嘗試。因為他們對訓練的影響是相乘的效果。不過有些參數,還是建議在原始尺度上進行搜索,例如dropout值: 0.3 0.5 0.7)。
-
經驗參數:
- learning rate: 1 0.1 0.01 0.001, 一般從1開始嘗試。很少見learning rate大於10的。學習率一般要隨着訓練進行衰減。衰減系數一般是0.5。 衰減時機,可以是驗證集准確率不再上升時,或固定訓練多少個周期以后。 不過更建議使用自適應梯度的辦法,例如adam,adadelta,rmsprop等,這些一般使用相關論文提供的默認值即可,可以避免再費勁調節學習率。對RNN來說,有個經驗,如果RNN要處理的序列比較長,或者RNN層數比較多,那么learning rate一般小一些比較好,否則有可能出現結果不收斂,甚至Nan等問題。
- 網絡層數: 先從1層開始。
- 每層結點數: 16 32 128,超過1000的情況比較少見。超過1W的從來沒有見過。
- batch size: 128上下開始。batch size值增加,的確能提高訓練速度。但是有可能收斂結果變差。如果顯存大小允許,可以考慮從一個比較大的值開始嘗試。因為batch size太大,一般不會對結果有太大的影響,而batch size太小的話,結果有可能很差。
- clip c(梯度裁剪): 限制最大梯度,其實是value = sqrt(w1^2+ w2^2….),如果value超過了閾值,就算一個衰減系系數,讓value的值等於閾值: 5,10,15
- dropout: 0.5
- L2正則:1.0,超過10的很少見。
- 詞向量embedding大小:128,256
- 正負樣本比例: 這個是非常忽視,但是在很多分類問題上,又非常重要的參數。很多人往往習慣使用訓練數據中默認的正負類別比例,當訓練數據非常不平衡的時候,模型很有可能會偏向數目較大的類別,從而影響最終訓練結果。除了嘗試訓練數據默認的正負類別比例之外,建議對數目較小的樣本做過采樣,例如進行復制。提高他們的比例,看看效果如何,這個對多分類問題同樣適用。 在使用mini-batch方法進行訓練的時候,盡量讓一個batch內,各類別的比例平衡,這個在圖像識別等多分類任務上非常重要。
-
自動調參:
- Gird Search. 這個是最常見的。具體說,就是每種參數確定好幾個要嘗試的值,然后像一個網格一樣,把所有參數值的組合遍歷一下。優點是實現簡單暴力,如果能全部遍歷的話,結果比較可靠。缺點是太費時間了,特別像神經網絡,一般嘗試不了太多的參數組合。
- Random Search。Bengio在Random Search for Hyper-Parameter Optimization中指出,Random Search比Gird Search更有效。實際操作的時候,一般也是先用Gird Search的方法,得到所有候選參數,然后每次從中隨機選擇進行訓練。
- Bayesian Optimization. 貝葉斯優化,考慮到了不同參數對應的實驗結果值,因此更節省時間。和網絡搜索相比簡直就是老牛和跑車的區別。具體原理可以參考這個論文: Practical Bayesian Optimization of Machine Learning Algorithms ,這里同時推薦兩個實現了貝葉斯調參的Python庫,可以上手即用:
- jaberg/hyperopt, 比較簡單。
- fmfn/BayesianOptimization, 比較復雜,支持並行調參。
原文鏈接:https://blog.csdn.net/anshiquanshu/article/details/77938831
UNIT 3
一些大的注意事項
- 剛開始, 先上小規模數據,模型往大了放,只要不爆顯存,能用256個filter你就別用128個。直接奔着過擬合去。沒錯,就是訓練過擬合網絡, 連測試集驗證集這些都可以不用。如果小數據量下,這么粗暴的大網絡奔着過擬合去都沒效果,那么有可能是:模型的輸入輸出是不是有問題? 代碼錯誤? 模型解決的問題定義是不是有問題? 你對應用場景的理解是不是有錯?
- Loss設計要合理。一般來說分類就是Softmax, 回歸就是L2的loss. 但是要注意loss的錯誤范圍(主要是回歸), 你預測一個label是10000的值, 模型輸出0, 你算算這loss多大, 這還是單變量的情況下. 一般結果都是nan. 所以不僅僅輸入要做normalization, 輸出也要這么弄。多任務情況下, 各loss想法限制在一個量級上, 或者最終限制在一個量級上, 初期可以着重一個任務的loss。
- 觀察loss勝於觀察准確率。准確率雖然是評測指標,但是訓練過程中還是要注意loss的。你會發現有些情況下,准確率是突變的,原來一直是0, 可能保持上千迭代, 然后突然變1。要是因為這個你提前中斷訓練了, 只有老天替你惋惜了. 而loss是不會有這么詭異的情況發生的, 畢竟優化目標是loss。給NN一點時間, 要根據任務留給NN的學習一定空間. 不能說前面一段時間沒起色就不管了. 有些情況下就是前面一段時間看不出起色, 然后開始穩定學習。
- 確認分類網絡學習充分。分類網絡就是學習類別之間的界限. 你會發現, 網絡就是慢慢的從類別模糊到類別清晰的. 怎么發現? 看Softmax輸出的概率的分布. 如果是二分類, 你會發現, 剛開始的網絡預測都是在0.5上下, 很模糊. 隨着學習過程, 網絡預測會慢慢的移動到0,1這種極值附近. 所以, 如果你的網絡預測分布靠中間, 再學習學習。
- Learning Rate設置合理。太大: loss爆炸, 或者nan。太小: 半天loss沒反映。需要進一步降低了: loss在當前LR下一路降了下來, 但是半天不再降了。如果上面的Loss設計那塊你沒法合理, 初始情況下容易爆, 先上一個小LR保證不爆, 等loss降下來了, 再慢慢升LR, 之后當然還會慢慢再降LR。
- 對比訓練集和驗證集的loss。 判斷過擬合, 訓練是否足夠, 是否需要early stop的依據。
- 清楚receptive field的大小。CV的任務, context window是很重要的. 所以你對自己模型的receptive field的大小要心中有數. 這個對效果的影響還是很顯著的. 特別是用FCN, 大目標需要很大的receptive field。
簡短的注意事項
- 預處理:-mean/std zero-center就夠了, PCA, 白化什么的都用不上。
- shuffle, shuffle, shuffle(洗牌、打亂)。
- 網絡原理的理解最重要,CNN的conv這塊,你得明白sobel算子的邊界檢測。
- Dropout, Dropout, Dropout(不僅僅可以防止過擬合, 其實這相當於做人力成本最低的Ensemble, 當然, 訓練起來會比沒有Dropout的要慢一點, 同時網絡參數你最好相應加一點, 對, 這會再慢一點)。
- CNN更加適合訓練回答是否的問題, 如果任務比較復雜, 考慮先用分類任務訓練一個模型再finetune。
- 無腦用ReLU(CV領域)。
- 無腦用3x3。
- 無腦用xavier。
- LRN一類的, 其實可以不用. 不行可以再拿來試試看。
- filter數量2^n
- 多尺度的圖片輸入(或者網絡內部利用多尺度下的結果)有很好的提升效果。
- 第一層的filter, 數量不要太少. 否則根本學不出來(底層特征很重要)。
- sgd adam 這些選擇上, 看你個人選擇. 一般對網絡不是決定性的. 反正我無腦用sgd + momentum。
- batch normalization我一直沒用, 雖然我知道這個很好, 我不用僅僅是因為我懶. 所以要鼓勵使用batch normalization。
- 不要完全相信論文里面的東西. 結構什么的覺得可能有效果, 可以拿去試試。
- 你有95%概率不會使用超過40層的模型。
- shortcut的聯接是有作用的。
作者:星空小屋
鏈接:https://blog.csdn.net/u014157632和https://5663015.github.io/
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並注明出處。