【深度學習】常見的學習率衰減算法的介紹與選擇

前言

模型準確率的提高除了模型本身的設計學習的過程也十分重要,好的學習過程可以讓模型更快更好地趨近於最優。而學習過程中除了學習算法,學習率的控制也尤爲重要,固定值的學習率很容易最終不斷振盪,無法實現收斂。本文主要整理介紹一些學習率衰減算法,同時也簡單介紹一些例如warm up和batch size有關的學習率控制經驗。

學習率衰減算法

注意:代碼方面的用法僅供參考,還沒來得及具體考證,準確起見還是看相應的註釋吧。

1、分段常數衰減:固定步長/多步長

分段常數衰減比較好理解,基本思想是事先定義好訓練區間,在不同的區間定義不同的區間設置不同的學習率的常數值。而根據區間長度是否固定還有固定步長衰減和多步長衰減。前者是每隔固定步數衰減一次,後者是根據設定的不同區間來更新。


PyTorch可以分別通過下面的代碼實現,參數根據實際需要修改即可:
torch.optim.lr_scheduler.StepLR(optimizer_StepLR, step_size=step_size, gamma=0.65)
torch.optim.lr_scheduler.MultiStepLR(optimizer_MultiStepLR,
milestones=[200, 300, 320, 340, 200], gamma=0.8)

2、指數衰減/自然指數衰減

指數衰減即根據指數曲線進行衰減,一般來說開始衰減的快後來慢,根據設置的參數決定底數。
torch.optim.lr_scheduler.ExponentialLR(optimizer_ExpLR, gamma=0.98)
指數衰減的公式如下:

而自然指數衰減即再乘個e,其代碼和公式如下:
torch.optim.lr_scheduler.ExponentialLR(optimizer_ExpLR, gamma=0.98)
decayed_learning_rate = learning_rateexp(-decay_rateglobal_step)

3、多項式衰減


這個也很好理解,從初始學習率到結束學習率以多項式冪的形式衰減,當global_step達到decay_steps時即衰減到最終學習率的時刻。從圖像和解析式中可以看到一般來說越往後下降的越快。

PyTorch中的實現是否會截斷後面的以及調用方式目前還不太瞭解,以後有機會補上吧,但其思路大概就是這樣,通過多項式的曲線進行學習率下降。

4、餘弦衰減

​ 餘弦衰減就是採用餘弦的相關方式進行學習率的衰減,衰減圖和餘弦函數相似。

從公式可以看到,學習率乘以的衰減係數從1隨着global_step增大衰減到α,最終衰減部分曲線類似於cosine曲線,下降速度率逐漸變快。
PyTorch中並沒有截斷後面的,也就說經過半個週期還是會按照餘弦曲線回升,調用方式如下:torch.optim.lr_scheduler.CosineAnnealingLR(optimizer_CosineLR, T_max=150, eta_min=0)
eta_min表示學習率的最小值,默認它是0表示學習率至少爲正值。對應到這個公式eta_min = α * learning_rate,T_max 對應1/2個cos週期所對應的epoch數值。

比較

下面在ImageNet-2012上使用SGD對各類學習率衰減算法的學習效果進行測試,可以看到不同的算法表現存在一定差異但也不存在絕對好的算法,在不同的迭代次數各有不同的表現。例如poly前期速度較慢但後期比較穩定,exp前期速度較快後期又所收斂。建議選擇一些普遍效果效果較好的然後根據實際情況進行調整。(來源:https://github.com/ducha-aiki/caffenet-benchmark/blob/master/Lr_policy.md)
另外下面的學習率衰減方法與上面介紹的不完全一樣,分的更加細緻,僅供參考。



其他學習率控制算法

學習率除了訓練過程中隨着loss降低不斷衰減在訓練初期還有一些小的技巧,統稱爲學習率控制算法,這裏介紹兩個具有代表性的算法。一個與訓練初始階段有關,一個與batch size和lr的關係有關。(摘自:https://blog.csdn.net/Swocky/article/details/105809498)

1、Warm up

由於剛開始訓練時模型的權重(weights)是隨機初始化的,此時選擇一個較大的學習率,可能會帶來模型的不穩定。學習率預熱就是在剛開始訓練的時候先使用一個較小的學習率,訓練一些epoches或iterations,等模型穩定時再修改爲預先設置的學習率進行訓練。
上述的方法是constant warmup,18年Facebook又針對上面的warmup進行了改進,因爲從一個很小的學習率一下變爲比較大的學習率可能會導致訓練誤差突然增大。提出了gradual warmup來解決這個問題,即從最開始的小學習率開始,每個iteration增大一點,直到最初設置的比較大的學習率。

2、Linear scaling learning rate

實驗證明,大的batch size在相同的epoch下準確率會更小,使用warm up可以在一定程度上解決這個問題,而Linear scaling learning rate也是一種有效的方法。
在mini-batch SGD訓練時,梯度下降的值是隨機的,因爲每一個batch的數據是隨機選擇的。增大batch size不會改變梯度的期望,但是會降低它的方差。也就是說,大batch size會降低梯度中的噪聲,所以我們可以增大學習率來加快收斂。
具體做法很簡單,比如ResNet原論文中,batch size爲256時選擇的學習率是0.1,當我們把batch size變爲一個較大的數b時,學習率應該變爲 0.1 × b/256。即線性的根據batch大小設置學習率,從而達到更好的學習效果。
簡單的說,大的batch size計算得到的梯度噪聲更小,所以可以使用更大的學習率來加大收斂。那麼這裏就有一個問題了,爲什麼小的batch size一般收斂的更快呢?這是因爲小的batch size儘管方向不一定準確,但是更新次數多,最終收斂速度會更快。而大的batch size雖然噪聲小,方向也更準確,但是由於學習率效果不會很好,這樣線性的增加學習率其實也是相當於用單次更新量變大彌補更新次數小的事實。

總結

學習率衰減算法多種多樣,除了上面介紹的還有許多別的方式。當然如同激活函數、優化算法等等,也沒有絕對的最優,只能說某種算法對於一般情況表現較好。一般來說可以先選擇普遍表現還不錯的算法進行嘗試,然後再嘗試一些別的算法,具體問題具體分析,得到比較好的學習率衰減算法,加快學習速度。當然,最後提到的warm up與linear scaling learning rate也值得注意,也是學習率控制的重要技巧。
另外整理的比較粗略,可能存在一些問題,很多地方也不夠細緻,有機會再完善一下。

參考資料

https://mp.weixin.qq.com/s/ky52jO92jsRZ9qpkcUmxEA
https://www.jianshu.com/p/125fe2ab085b
https://zhuanlan.zhihu.com/p/93624972
https://blog.csdn.net/hongxue8888/article/details/78652602

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