Hello大家好,本期將和大家一起分享和討論一下深度學習中的一個基礎組件:Optimizer,也就是優化器。這是一個在煉丹過程中容易被忽視,但其實又非常重要的組件。接下來幾分鐘裡,讓我們重溫優化器的發展和應用,希望對大家有所幫助。本期是機器學習基礎三篇中的第二篇,希望大家多多支持~
什麼是優化器概括地來說,優化器其實是一種算法,它在模型優化過程中,動態地調整梯度的大小和方向,使模型能夠收斂到更好的位置,或者用更快的速度進行收斂。
優化器的起源在微積分中,對多元函數的參數 θ 求偏導數,把求得的各個參數的導數以向量的形式寫出來就是梯度。梯度就是函數變化最快的方向。梯度下降法是迭代法的一種,在求解機器學習算法的模型參數 θ 時,即無約束問題時,梯度下降是最常採用的方法之一。
我們可以把模型的參數空間想像成是一個曲面,曲面的高度是整體上模型預測值與真實值的誤差。我們的目的就是找到整個曲面的最低點,這樣我們其實就找到了模型參數的最優點。梯度下降是一個常用方法,它讓參數朝著梯度下降最大的方向去變化。
假設模型參數為 θ,損失函數為 J(θ) ,損失函數 J(θ) 關於參數 θ 的偏導數,也就是梯度為 ▽θJ(θ) ,學習率為 α ,則使用梯度下降法更新參數為:
批量梯度下降法BGD第一種很天然的想法是批量梯度下降法BGD(Batch Gradient Descent),其實就是每次用全量的數據對參數進行梯度下降。
假設訓練樣本總數為n,樣本為 {(x1,y1), .... (xn, yn)} ,模型參數為 θ ,損失函數為 J(θ) ,學習率為 α,則使用BGD更新參數為:
由上式可以看出,每進行一次參數更新,需要計算整個數據樣本集,因此導致批量梯度下降法的速度會比較慢,尤其是數據集非常大的情況下,收斂速度就會非常慢,但是由於每次的下降方向為總體平均梯度,它可能得到的會是一個全局最優解。
隨機梯度下降法SGD但是上述的這種方案,因為效率和空間的限制基本是不可使用的,那麼人們想到了對每個樣本進行梯度下降。
隨機梯度下降法SGD(Stochastic Gradient Descent),不像BGD每一次參數更新,需要計算整個數據樣本集的梯度,而是每次參數更新時,僅僅選取一個樣本 (xi, yi) 計算其梯度,參數更新公式為:
可以看到BGD和SGD是兩個極端,SGD由於每次參數更新僅僅需要計算一個樣本的梯度,訓練速度很快,即使在樣本量很大的情況下,可能只需要其中一部分樣本就能迭代到最優解,由於每次迭代並不是都向著整體最優化方向,導致梯度下降的波動非常大,更容易從一個局部最優跳到另一個局部最優,準確度下降。
小批量梯度下降法小批量梯度下降法就是結合BGD和SGD的折中,對於含有n個訓練樣本的數據集,每次參數更新,選擇一個大小為m (m < n) 的mini-batch數據樣本計算其梯度,其參數更新公式如下:
小批量梯度下降法即保證了訓練的速度,又能保證最後收斂的準確率,目前的SGD已經默認是小批量梯度下降算法。不過它也有一定的問題,比如選擇合適的learning rate比較困難 ,學習率太低會收斂緩慢,學習率過高會使收斂時的波動過大, 易收斂到局部最優。
動量優化法於是學者想到了一些方法,解決上述問題,比如動量優化法。動量優化方法引入物理學中的動量思想,加速梯度下降。當我們將一個小球從山上滾下來,沒有阻力時,它的動量會越來越大,但是如果遇到了阻力,速度就會變小,動量優化法就是借鑑此思想,使得梯度方向在不變的維度上,參數更新變快,梯度有所改變時,更新參數變慢,這樣就能夠加快收斂並且減少動蕩。動量優化法比較代表性的有Momentum和Nesterov。
Momentummomentum 算法思想:參數更新時在一定程度上保留之前更新的方向,同時又利用當前batch的梯度微調最終的更新方向,簡言之就是通過積累之前的動量來加速當前的梯度。假設 mt 表示t時刻的動量, μ 表示動量因子,通常取值0.9或者近似值,在SGD的基礎上增加動量,則參數更新公式如下
在梯度方向改變時,momentum能夠降低參數更新速度,從而減少震蕩;在梯度方向相同時,momentum可以加速參數更新, 從而加速收斂。總而言之,momentum能夠加速SGD收斂,抑制震蕩。
NAG(Nesterov accelerated gradient)momentum保留了上一時刻的梯度 ▽θJ(θ) ,對其沒有進行任何改變,NAG是momentum的改進,在梯度更新時做一個矯正,具體做法就是在當前的梯度 ▽θJ(θ) 上添加上一時刻的動量 μ* mt ,梯度改變為 ▽θJ(θ - u*mt)
首先,按照原來的更新方向更新一步(棕色線),然後在該位置計算梯度值(紅色線),然後用這個梯度值修正最終的更新方向(綠色線)。上圖中描述了兩步的更新示意圖,其中藍色線是標準momentum更新路徑。
自適應學習率優化算法上述是動量優化法的思想,另一方面在機器學習中,學習率是一個非常重要的超參數,但是學習率是非常難確定的,雖然可以通過多次訓練來確定合適的學習率,但是一般也不太確定多少次訓練能夠得到最優的學習率,屬於玄學事件,對人為的經驗要求比較高,所以是否存在一些策略自適應地調節學習率的大小,從而提高訓練速度。目前的自適應學習率優化算法主要有:AdaGrad算法,Adam算法,AdaDelta算法等。
AdaGrad定義參數:全局學習率 δ ; 一個極小的常量 ε ,通常取值10e-8, 目的是為了分母為0的處理; 梯度加速變量(gradient accumulation variable) r 。
從上式可以看出,r累積了t時刻前所有梯度g的平方和,那麼其實g乘上的係數可以認為是一個約束項,隨著迭代次數越來越多,平方和越來越大,係數越來越小,那麼可以隨著時間縮小梯度,使參數更新量減小。
AdadeltaAdagrad會累加之前所有的梯度平方,而Adadelta只累加固定大小的項,並且也不直接存儲這些項,僅僅是近似計算對應的平均值
Adadelta的特點是訓練初中期,加速效果不錯,加速比較快,但是訓練後期由於沒有累積的效應,所以經常會在局部最小值附近抖動。
Adam: adaptive Moment EstimationAdam幾乎是使用最為廣泛的自適應學習率優化器了,它有自己的獨到之處。在Adam中,動量直接併入了梯度的一階矩計算。Adam的關鍵是偏置修正,修正從原點初始化的一階矩(動量項)和(非中心的)二階矩估計。β1 = 0.9, β2 = 0.999, ε = 1e-8。
其中,mt ,vt 分別是對梯度的一階矩估計和二階矩估計;帶帽的是對他們的偏差校正,這樣可以近似為對期望的無偏估計。以下是vt的表示和其期望的推導:
可以看到,t時刻的二階矩的期望相對梯度平方的期望是有偏的,通過係數修正以後就無偏了,訓練更加穩定。
所以,Adam梯度經過偏置校正後,每一次迭代學習率都有一個固定範圍,使得參數比較平穩。結合了Adagrad善於處理稀疏梯度和AdaDelte善於處理非平穩目標的優點,為不同的參數計算不同的自適應學習率。同時,也適用於大多非凸優化問題——適用於大數據集和高維空間。
AdamWAdam的論文最後提到,Adam非常魯棒,廣泛用於各種非凸優化問題。但是,後來的一些實驗卻漸漸發現帶動量的SGD效果反而比複雜的Adam更好。17年末,人們發現,這可能是因為WeightDecay的施加。之前的實現,在Adam上實施的權重衰減似乎都是錯誤的,並提出了AdamW來修復。
紅色部分是直接在梯度上施加L2正則,綠色的是在參數上實施權重的衰減,在SGD上兩者是能夠統一的,在Adam上兩者是不一樣的,形成了錯誤的改變。AdamW修正了這一點,使它的實驗效果恢復了它的領先位置。
AdaboundSGD的問題是前期收斂速度慢。SGD前期收斂慢的原因:SGD在更新參數時對各個維度上梯度的放縮是一致的,並且在訓練數據分布極不均時訓練效果很差。而因為收斂慢的問題應運而生的自適應優化算法Adam、AdaGrad 等,但這些自適應的優化算法雖然可以在訓練早期展現出快速的收斂速度,但其在測試集上的表現卻經常會陷入停滯,並最終被 SGD 超過。
一些學者對Adam的這系列問題進行了分析,認為原因出在自適應方法訓練後期不穩定的極端學習率。深入來看,自適應學習率訓練到後期,學習率出現極端情況,更新參數時有些維度上學習率特別大,有些維度學習率特別小,導致效果受到影響。
所以後面又提出過Adabound算法,Adam和SGD都可以認為是它的特例,它在訓練過程中用上下界去規範參數,對於SGD, 上界下界ηl = ηu = α, 對於Adam ηl = 0 and ηu = ∞。
現在很多研究都是將SGD和Adam結合來彌補兩者各自的缺陷,但還沒有具有顛覆性的算法出現改變優化器的格局。
未完待續本期的機器學習知識就給大家分享到這裡,感謝大家的閱讀和支持,下期我們還會帶來新的分享,敬請期待!
歡迎關注樸素人工智慧,這裡有很多最新最熱的論文閱讀分享,也有人工智慧的基礎知識討論和整理,有問題或建議可以在公眾號下留言。
參考資料1.https://zhuanlan.zhihu.com/p/55150256?utm_source=wechat_session&utm_medium=social&utm_oi=942087358187851776&utm_campaign=shareopn
預訓練語言模型專題