煉丹筆記 : 調參技巧

轉載於:煉丹筆記六 : 調參技巧 - 會寫代碼的好廚師的文章 - 知乎 https://zhuanlan.zhihu.com/p/56745640

本期問題

能否聊一聊深度學習中的調參技巧?

我們主要從以下幾個方面來講.

1. 深度學習中有哪些參數需要調?
2. 深度學習在什麼時候需要動用調參技巧?又如何調參?
3. 訓練網絡的一般過程是什麼?

1. 深度學習有哪些需要們關注的參數呢?

大家記住一點:需要用到調參技巧的參數都是超參數!!因此,這個問題還可以換成更專業一點:神經網絡中有哪些超參數?主要從兩個方面來看

  • 和網絡設計相關的參數:神經網絡的網絡層數、不同層的類別和搭建順序、隱藏層神經元的參數設置、LOSS層的選擇、正則化參數
  • 和訓練過程相關的參數:網絡權重初始化方法、學習率使用策略、迭代次數、小批量數據 minibatch的大小、輸入數據相關

2. 深度學習在什麼時候需要動用調參技巧,以及如何進行調參呢?

通常網絡訓練的結果一般表現爲以下五種情況:過擬合、欠擬合、恰好擬合,趨於收斂但一直在震盪以及完全不收斂。關於過擬合、欠擬合和恰好擬和,在機器學習中的定義描述如下:(不知道的可以移步此博客:https://www.imooc.com/article/44090 )

過擬合、欠擬合、恰好擬合的現象,從圖像看就表現成如下:

我們分別來看一下,在這幾種種情況下,需要考慮調整哪些參數?

先上圖:

首先來看恰好擬合的情況!

恰好擬合:從LOSS曲線上看,訓練集和測試集的LOSS都已經收斂,且很接近!模型能夠擬合訓練樣本和測試樣本的分佈,且是一致的!這樣的優點就是模型的泛化能力強,簡單來講就是在訓練集和測試集上效果都很好。通常表現如A圖所示。

這個時候還需要調參??效果都這麼好。需要調參! 主要集中在網絡結構設計方面的參數,在工程項目上,同樣的效果。我們需要考慮更小、更輕量型的網絡結構,計算量=====功耗,網絡大小=======內存!!!一定要學會減少計算量、較小網絡大小,當然如果說你的算力隨便用,後面的內容可以忽略了。這時候可以考慮:

  • 減少網絡層數
  • 減少不同的層的參數,主要是卷積核的數量
  • 考慮深度可分離這樣的輕量型卷積結構

還有一種情況,就是雖然訓練集和測試集都已經完美收斂,擬合。
但是測試集的LOSS沒辦法達到訓練集的LOSS,這時候也是考驗丹師的實力的時候了!
別急,我們在後面聊!

再來看欠擬合的情況!


欠擬合:從LOSS曲線上看,訓練集和測試集從趨勢上還沒有收斂!如圖B所示。(不要告訴我不知道什麼是收斂,好吧..就是loss曲線變平了,如A所示)
當然,欠擬合也有可能表現在訓練集和測試集上效果都一般,在訓練集上的精度也不高。
這個時候,怎麼辦?需要調整哪些參數?通常考慮以下幾個方面的參數調整:

  • 加大訓練迭代次數,有可能是網絡還沒訓練完!!這種低級錯誤千萬不能犯
  • 加大迭代次數的同時可以考慮進一步衰減調小學習率
  • 添加更多的層,也有可能是網絡容量不夠!
  • 去掉正則化約束的部分,l1\l2正則(正則主要是爲了防止過擬合)
  • 加入BN層加快收斂速度
  • 增加網絡的非線性度(ReLu),
  • 優化數據集,進行數據清洗,參考博客《煉丹筆記之數據清洗》https://mp.weixin.qq.com/s/W8angaDewLTY_YniN8JmeQ

再來看過擬合的情況!


過擬合:從樣本曲線上看,從看都趨向收斂,但是測試集上的LOSS很高,甚至出現回升的現象。如D圖所示。說明模型的泛化能力很差,有可能訓練集和測試集數據分佈不一致,更加可能的是模型太複雜。

其實,過擬合纔是困擾丹師們最大的痛!怎麼解決呢?通常有以下策略:

  • 增加樣本數量,訓練樣本太少或者說小樣本問題,很容易導致過擬合。推薦閱讀博主的另一篇文章,關於小樣本問題的博客:《煉丹筆記之小樣本學習》,鏈接地址:https://mp.weixin.qq.com/s/6hzGMOMrG2w-54c4zyRj5g
  • 數據增強,可以參考博主的另一篇博客《煉丹筆記之數據增強》https://mp.weixin.qq.com/s/KfiggFTzDRMjQWzvFd_C_g
  • 早停法(Early stopping),從LOSS不在下降的地方拿到模型,作爲訓練好的模型
  • 增加網絡的稀疏度,
  • 降低網絡的複雜度(深度)
  • L1 regularization,
  • L2 regulariztion,
  • 添加Dropout,
  • 適當降低Learning rate,
  • 適當減少epoch的次數,


再來看,趨於收斂但是震盪的情況!


在C圖中,我們還提到了一種情況,就是網絡在訓練集上已經趨於收斂,但是在測試集上存在很嚴重的LOSS震盪的情況,怎麼辦?這時候,可以從以下幾個角度考慮:

  • 訓練集和測試集分佈是否存在較大的差異?
  • 是否由於數據增強做的太過分了?
  • 學習率是不是還很高?如果是,降低學習率,或者在等等,等到學習率到 10e-6/10e-7這樣的大小
  • 測試集LOSS的計算是基於單個batch還是整個測試集?(一定要基於整個測試集來看)
  • 網絡是否存在欠擬合的可能,如果欠擬合參考上面欠擬合的方法

再來看,完全不收斂的情況!

在上面,我們並沒有給出完全不收斂的情況曲線圖。
那這要怎麼判斷網絡有沒有完全沒收斂?一個是LOSS一直都很高,自己按照自己定義的LOSS函數估計下,全部爲0的時候LOSS是多少,就可以大致估計出LOSS要低於多少網絡才能算作是收斂了。

如果網絡不收斂怎麼辦?考慮以下幾點:

  • 數據錯誤,先檢查數據!輸入數據是不是有問題?預處理是不是有問題?數據增強是不是有問題?標籤是不是有問題!避免低級錯誤啊!!
  • 網絡設計或者參數使用錯誤,一定要確保網絡層的設計和參數設置正確,確保沒有問題啊!!
  • 考慮LOSS設計是否存在問題,優化函數是否合理?
  • 設計的算法本身是夠存在問題,是否存在正負樣本嚴重失衡的問題? 推薦閱讀博客,《煉丹筆記之樣本不平衡問題》:https://mp.weixin.qq.com/s/R7z-mtgr4XiOVAYwP2SBIw


最後,我們再來考慮,在已經收斂的情況下,如何進一步提高模型的精度!

  • 優化網絡結構,使用更好的backbone
  • 使用更好的LOSS函數,比如:迴歸問題可以考慮smooth-l1等
  • 考慮使用難例挖掘的方法
  • 有條件的話,加大batchsize
  • 考慮預訓練模型
  • 觀察測試樣本,查找case,針對Case來,補充樣本+數據增強
  • 以上方法都試過發現,依然不行,可以重新開始閱讀論文了。推薦arxiv、各大頂會系列、trans系列
  • 當然,也可能遇到算法極限了,要麼自己創新,要麼多燒香拜佛等着大牛提出新方法吧。
  • 嘗試不同的優化函數,交替訓練,fine-tuning
  • 不同的權重初始化方法
  • 嘗試不同的學習率初始值和衰減值
  • 考慮在梯度上做文章,可以是梯度裁剪、梯度校驗、梯度歸一化等方法


再來聊一聊,關於自動調參的問題。目前正處於研究階段,有一些方法,但是不通用。

  • 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庫,可以上手即用:1)jaberg/hyperopt, 比較簡單。2)fmfn/BayesianOptimization, 比較複雜,支持並行調參。


如果有時間,推薦一些其他的博客:見參考文獻


3. 調參的一般過程是什麼?


基本上遵循從粗到細,先易後難的順序,具體給出煉丹流程如下:


1. 首先是搭建模型:

  • 如果有源碼,先直接把源碼跑通,沒有源碼考慮自己的搭建模型;
  • 主幹網絡可以直接考慮:resnet(後續網絡優化部分在考慮裁剪或者其他網絡結構)
  • loss根據相應的任務來進行選擇,可能是交叉熵損失(分類任務)、smooth-l1(迴歸任務)等
  • 優化函數,採用Adam或者SGD都可以。先隨便選一個常用的優化方法就可以
  • 學習率可以從0.1或者0.01開始
  • batchsize:32或者64

2. 準備小規模樣本,比如存在100w數據,可以先打包1w數據或者幾千樣本,可以暫時先不考慮數據增強,正常打包後直接訓練網絡,用小批量樣本來測試網絡搭建中可能存在的bug,直到網絡可以收斂,確保網絡搭建的準確性,方便後續出現問題時,問題的定位。
3. 小規模樣本訓練收斂之後,則可以確定模型框架沒有問題。開始加大樣本規模到100W,使用大規模樣本訓練;
4. 訓練後,分析訓練集和測試集LOSS的變化情況,考慮上述過擬合、欠擬合、收斂不穩定等不同情況,優化相應的參數;
5. 在LOSS出現較爲理想的結果之後,基本上網絡訓練也趨於穩定。接下來則是重點排查難點問題,嘗試創新性的調整網絡架構,嘗試新的loss,調整數據增強策略,不同優化函數,不同學習率,不同batchsize等等,通過各種手段,來提高準確度。其中,最關鍵的一定是“數據清洗”。推薦閱讀博客《煉丹筆記之數據清洗》:https://mp.weixin.qq.com/s/W8angaDewLTY_YniN8JmeQ
6. 另外,丹師應該對業界內的baseline方法有一個大概的瞭解,方法能夠調到什麼程度,也要做到心裏有數。這樣,才能在上面的這些操作,都完成的差不多了,算法沒辦法調優的時候,有一個藉口,告訴自己:業界也就這個水平了~~~哈哈。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章