發現一篇寫的很好的關于學習率的文章
1.學習率的重要性
1)學習率設定太小,需要花費過多的時間來收斂
2)學習率設定較大,在最小值附近震蕩卻無法收斂到最小值
3)進入局部極值點就收斂,沒有真正找到的最優解
4)停在鞍點處,不能夠在另一次元繼續下降
梯度下降算法有兩個重要的控制因子:一個是步長,由學習率控制;一個是方向,由梯度指定。
2.學習率的設定類型
1)固定學習率
每次疊代每個參數都使用同樣的學習率。找到一個比較好的固定學習率非常關鍵,否則會導緻收斂太慢或者不收斂。
2)不同的參數使用不同的學習率
如果資料是稀疏的且特征分布不均,似乎我們更應該給予較少出現的特征一個大的更新。這時可能需要對不同特征對應的參數設定不同的學習率。深度學習的梯度下降算法中Adagrad 和Adam方法都針對每個參數設定了相應的學習率,這部分内容詳見《梯度下降算法總結》,本篇不作讨論。
3)動态調整學習率
動态調整就是我們根據應用場景,在不同的優化階段能夠動态改變學習率,以得到更好的結果。動态調整學習率是本篇的重點内容,為了解決梯度學習在一些複雜問題時出現的挑戰,資料科學家們在動态調整學習率的政策上做了很多研究和嘗試。
4)自适應學習率
自适應學習率從某種程度上講也算是動态調整學習率的範疇,不過更偏向于通過某種算法來根據實時情況計算出最優學習率,而不是人為固定一個簡單政策讓梯度下降按部就班地實行。
3.學習率的設定政策
3.1 固定學習率
固定學習率适用于那些目标函數是凸函數的模型,通常為了保證收斂會選一個稍微小的數值,如0.01、0.001。固定學習率的選擇對梯度下降影響非常大,下圖展示了不同學習率對梯度下降的影響。
3.2學習率衰減
一般情況下,初始參數所得目标值與要求的最小值距離比較遠,随着疊代次數增加,會越來越靠近最小值。學習率衰減的基本思想是學習率随着訓練的進行逐漸衰減,即在開始的時候使用較大的學習率,加快靠近最小值的速度,在後來些時候用較小的學習率,提高穩定性,避免因學習率太大跳過最小值,保證能夠收斂到最小值。
1)learning rate在每疊代stepsize次後減少gamma倍
2)learning rate呈多項式曲線下降
3)learning rate随疊代次數增加而下降。
3.3找到合适的學習率
Leslie N. Smith在一篇《Cyclical Learning Rates for Training Neural Networks》論文中提出一個非常簡單的尋找最佳學習率的方法。這種方法可以用來确定最優的初始學習率,也可以界定适合的學習率的取值範圍。
在這種方法中,我們嘗試使用較低學習率來訓練神經網絡,但是在每個批次中以指數形式增加(或線性增加)。
目前,該方法在 Fast.ai 包中已經作為一個函數可直接進行使用。Fast.ai 包是由 Jeremy Howard 開發的一種進階 pytorch 包(就像 Keras 之于 Tensorflow)。
#run on learn object where learning rate is increased exponentially
learn.lr_find()
#plot graph of learning rate against iterations
learn.sched.plot_lr()
每次疊代後學習率以指數形式增長:
同時,記錄每個學習率對應的Loss值,然後畫出學習率和Loss值的關系圖:
learn.sched.plot()
通過找出學習率最高且Loss值仍在下降的值來确定最佳學習率。在上述情況中,該值将為0.01。
3.4基于Armijo準則的線性回溯搜尋算法
既然是計算學習率,我們就需要轉換視角,将學習率?看作是未知量,因目前點??、目前搜尋方向??都是已知的,故有下面的關于?的函數:
梯度下降尋找f(x)最小值,那麼在??和??給定的前提下,即尋找函數?(??+???)的最小值,可以證明存在?使得h(x)的導數為0,則?就是要尋找的學習率。
1)二分線性搜尋
二分線性搜尋是最簡單的處理方式,不斷将區間[α1,α2]分成兩半,選擇端點異号的一側,直到區間足夠小或者找到目前最優學習率。
2)回溯線性搜尋
基于Armijo準則計算搜素方向上的最大步長,其基本思想是沿着搜尋方向移動一個較大的步長估計值,然後以疊代形式不斷縮減步長,直到該步長使得函數值?(??+α??)相對與目前函數值?(??)的減小程度大于預設的期望值(即滿足Armijo準則)為止。
(1)二分線性搜尋的目标是求得滿足 ℎ′(?)≈0 的最優步長近似值,而回溯線性搜尋放松了對步長的限制,隻要步長能使函數值有足夠大的變化即可。
(2)二分線性搜尋可以減少下降次數,但在計算最優步長上花費了不少代價;回溯線性搜尋找到一個差不多的步長即可。
3)二次插值法
二次插值法是回溯線性搜尋的繼續優化,利用了多項式插值(Interpolation) 方法。多項式插值的思想是通過多項式插值法拟合簡單函數,然後根據該簡單函數估計原函數的極值點,這裡我們使用二次函數來拟合。
3.5.循環學習率
使用較快的學習率也有助于我們在訓練中更早地跳過一些局部極小值。
人們也把早停和學習率衰減結合起來,在疊代 10 次後損失函數沒有改善的情況下學習率開始衰減,最終在學習率低于某個确定的門檻值時停止。
近年來,循環學習率變得流行起來,在循環學習率中,學習率是緩慢增加的,然後緩慢減小,以一種循環的形式持續着。
3.6餘弦退火
餘弦退火可以當做是學習率衰減的一種方式,早些時候都是使用指數衰減或者線性衰減,現在餘弦衰減也被普遍使用[2]。
在采用小批量随機梯度下降(MBGD/SGD)算法時,神經網絡應該越來越接近Loss值的全局最小值。當它逐漸接近這個最小值時,學習率應該變得更小來使得模型不會超調且盡可能接近這一點。
從下圖可以看出,随着x的增加,餘弦值首先緩慢下降,然後加速下降,再次緩慢下降。這種下降模式能和學習率配合,以一種十分有效的計算方式來産生很好的效果。
3.7熱重新開機随機梯度下降(SGDR)
在訓練時,梯度下降算法可能陷入局部最小值,而不是全局最小值。下圖展示了陷入局部最小值的梯度下降算法。
梯度下降算法可以通過突然提高學習率,來“跳出”局部最小值并找到通向全局最小值的路徑。Loshchilov和Hutter在《SGDR: Stochastic Gradient Descent with Warm Restarts》論文中提出了熱重新開機随機梯度下降(Stochastic Gradient Descent with Warm Restarts, SGDR)方法,這種方法将餘弦退火與熱重新開機相結合,使用餘弦函數作為周期函數,并在每個周期最大值時重新開始學習速率。“熱重新開機”是因為學習率重新開始時并不是從頭開始的,而是由模型在最後一步收斂的參數決定的。
用Fast.ai庫可以快速導入SGDR算法。當調用learn.fit(learning_rate, epochs)函數時,學習率在每個周期開始時重置為參數輸入時的初始值,然後像上面餘弦退火部分描述的那樣,逐漸減小。
3.8不同網絡層使用不同學習率
一般情況下,在訓練時通過優化網絡層會比提高網絡深度要更重要,在網絡中使用有差别的學習率(Differential Learning rates),可以很好的提高模型性能。
3.9快照內建和随機權重平均
最後将要提到的政策可以說是多個優化方法綜合應用的政策,可能已經超出了“學習率的設定”主題的範圍了,不過,我覺得下面的方法是最近一段時間研究出來的一些非常好的優化方法,是以也包括了進來,權當做是學習率優化的綜合應用了。
本小節主要涉及三個優化政策:快照內建(Snapshot Ensembling)、快速幾何內建(Fast Geometric Ensembling,FGE)、随機權重平均(Stochastic Weight Averaging,SWA)。
在經典機器學習中,內建學習(Ensemble learning)是非常重要的思想,很多情況下都能帶來非常好的性能,是以幾乎是機器學習比賽中必用的“神兵利器”。
內建學習算法本身不算一種單獨的機器學習算法,而是通過建構并結合多個機器學習器來完成學習任務。可以說是“集百家之所長”,完美的诠釋了“三個臭皮匠賽過諸葛亮”。內建學習在機器學習算法中擁有較高的準确率,不足之處就是模型的訓練過程可能比較複雜,效率不是很高。
強力的內建學習算法主要有2種:基于Bagging的算法和基于Boosting的算法,基于Bagging的代表算法有随機森林,而基于Boosting的代表算法則有Adaboost、GBDT、XGBOOST等,這部分内容我們後面會單獨講到。
內建學習的思路就是組合若幹不同的模型,讓它們基于相同的輸入做出預測,接着通過某種平均化方法決定內建模型的最終預測。這個決定過程可能是通過簡單的投票或取均值,也可能是通過另一個模型,該模型能夠基于內建學習中衆多模型的預測結果,學習并預測出更加準确的最終結果。嶺回歸是一種可以組合若幹個不同預測的結果的方法,Kaggle 上衛星資料識别熱帶雨林競賽的冠軍就使用過這一方法。
內建學習的思想同樣适用于深度學習,內建應用于深度學習時,組合若幹網絡的預測以得到一個最終的預測。通常,使用多個不同架構的神經網絡得到的性能會更好,因為不同架構的網絡一般會在不同的訓練樣本上犯錯,因而內建學習帶來的收益會更大。
當然,你也可以內建同一架構的模型,也許效果會出乎意料的好。就好比本小節将要提到的快照內建方法,在訓練同一個網絡的過程中儲存了不同的權值快照,然後在訓練之後建立了同一架構、不同權值的內建網絡。這麼做可以提升測試的表現,同時也超省事,因為你隻需要訓練一個模型、訓練一次就好,隻要記得随時儲存權值就行。
快照內建應用了我們剛才提到的熱重新開機随機梯度下降(Stochastic Gradient Descent with Warm Restarts, SGDR),這種循環學習率幾乎為快照內建量身打造,利用熱重新開機随機梯度下降法的特點,每次收斂到局部極值點的時候就可以緩存一個權重快照,緩存那麼幾個就可以做內建學習了。
無論是經典機器學習中的內建學習,還是深度學習裡面的內建學習,抑或是改良過的快照內建方法,都是模型空間内的內建,它們均是組合若幹模型,接着使用這些模型的預測以得到最終的預測結果。而一些資料科學家還提出了一種全新的權值空間内的內建,這就是随機權重平均法,該方法通過組合同一網絡在訓練的不同階段的權值得到一個內建,接着使用組合後的權值做出預測。這種方法有兩個好處:
- 組合權重後,我們最終仍然得到一個模型,這有利于加速預測。
- 事實證明,這種方法勝過目前最先進的快照內建。
在了解其實作原理之前,我們首先需要了解損失平面(loss surface)和泛化解(generalizable solution)。
權值空間的解
第一個不得不提到的是,經過訓練的網絡是高維權值空間中的一個點。對給定的架構而言,每個不同的網絡權值組合都代表了一個不同的模型。任何給定架構都有無窮的權重組合,因而有無窮多的解。訓練神經網絡的目标是找到一個特定的解(權值空間中的點),使得訓練資料集和測試資料集上的損失函數的值都比較低。
在訓練期間,訓練算法通過改變權值來改變網絡并在權值空間中漫遊。梯度下降算法在一個損失平面上漫遊,該平面的海拔為損失函數的值。
窄極值和寬極值
坦白的講,可視化并了解高維權值空間的幾何特性非常困難,但我們又不得不去了解它。因為随機梯度下降的本質是,在訓練時穿過這一高維空間中的損失平面,試圖找到一個良好的解——損失平面上的一個損失值較低的“點”。不過後來我們發現,這一平面有很多局部極值。但這些局部極值并不都有一樣好的性質。
一般極值點會有寬的極值和窄的極值,如下圖所示:
資料科學家研究試驗後發現:寬的局部極小值在訓練和測試過程中産生類似的損失;但對于窄的局部極小值而言,訓練和測試中産生的損失就會有很大差別。這意味着,寬的極值比窄的極值有更好的泛化性。
平坦度可以用來衡量一個解的優劣。其中的原理是,訓練資料集和測試資料集會産生相似但不盡相同的損失平面。你可以将其想象為測試平面相對訓練平面而言平移了一點。對窄的解來說,一個在測試的時候損失較低的點可能因為這一平移産生變為損失較高的點。這意味着窄的(尖銳的)解的泛化性不好——訓練損失低,測試損失高。另一方面,對于寬的(平坦的)解而言,這一平移造成的訓練損失和測試損失間的差異較小。
之是以提到窄極值和寬極值,是因為随機權重平均(SWA)就能帶來讨人喜歡的、寬的(平坦的)解。
快照內建(Snapshot Ensembling)
快照內建應用了應用了熱重新開機随機梯度下降(SGDR),最初,SGD會在權值空間中跳出一大步。接着,由于餘弦退火,學習率會逐漸降低,SGD逐漸收斂到局部極小值,緩存權重作為一個模型的“快照”,把它加入內建模型。然後将學習率恢複到更高的值,這種更高的學習率将算法從局部極小值推到損失面中的随機點,然後使算法再次收斂到另一個局部極小值。重複幾次,最後,他們對所有緩存權重集的預測進行平均,以産生最終預測。
上圖對比了使用固定學習率的單個模型與使用循環學習率的快照內建的收斂過程,快照內建是在每次學習率周期末尾儲存模型,然後在預測時使用。快照內建的周期長度為 20 到 40 個 epoch。較長的學習率周期是為了在權值空間中找到足夠具有差異化的模型,以發揮內建的優勢。如果模型太相似,那麼內建模型中不同網絡的預測将會過于接近,以至于內建并不會帶來多大益處了。
快照內建表現優異,提升了模型的表現,但快速幾何內建效果更好。
快速幾何內建
《Loss Surfaces, Mode Connectivity, and Fast Ensembling of DNNs》中提出的快速幾何內建 FGE 和快照內建非常像,但是也有一些獨特的特點。它們的不同主要有兩點。第一,快速幾何內建使用線性分段周期學習率規劃,而不是餘弦變化。第二,FGE 的周期長度要短得多——2 到 4 個 epoch。乍一看大家肯定直覺上覺得這麼短的周期是不對的,因為每個周期結束的時候的得到的模型互相之間離得太近了,這樣得到的內建模型沒有什麼優勢。然而作者們發現,在足夠不同的模型之間,存在着損失較低的連通路徑。我們有機會沿着這些路徑用較小的步長行進,同時這些模型也能夠有足夠大的差異,足夠發揮內建的優勢。是以,相比快照內建, FGE 表現更好,搜尋模型的步長更小(這也使其訓練更快)。
随機權重平均(Stochastic Weight Averaging,SWA)
随機權重平均隻需快速幾何內建的一小部分算力,就可以接近其表現。SWA 可以用在任意架構和資料集上,都會有不錯的表現。根據論文中的實驗,SWA 可以得到我之前提到過的更寬的極小值。在經典認知下,SWA 不算內建,因為在訓練的最終階段你隻得到一個模型,但它的表現超過了快照內建,接近 FGE。
結合????在測試集上優于 SGD 的表現,這意味着盡管????訓練時的損失較高,它的泛化性更好。
SWA 的直覺來自以下由經驗得到的觀察:每個學習率周期得到的局部極小值傾向于堆積在損失平面的低損失值區域的邊緣(上圖左側的圖形中,褐色區域誤差較低,點?1、?2、?3分别表示3個獨立訓練的網絡,位于褐色區域的邊緣)。對這些點取平均值,可能得到一個寬闊的泛化解,其損失更低(上圖左側圖形中的????)。
下面是 SWA 的工作原理。它隻儲存兩個模型,而不是許多模型的內建:
- 第一個模型儲存模型權值的平均值(????)。在訓練結束後,它将是用于預測的最終模型。
- 第二個模型(?)将穿過權值空間,基于周期性學習率規劃探索權重空間。
SWA權重更新公式
在每個學習率周期的末尾,第二個模型的目前權重将用來更新第一個模型的權重。是以,在訓練階段,隻需訓練一個模型,并在記憶體中儲存兩個模型。預測時隻需要平均模型,基于其進行預測将比之前描述的內建快很多,因為在那種內建中,你需要使用多個模型進行預測,最後再進行平均。