哦哇資訊網

最全機器學習最佳化器Optimizer彙總

由 極市平臺 發表于 美食2023-02-06

作者丨蘇學演算法

編輯丨極市平臺

前言

首先,為什麼需要最佳化器(Optimizer)這個東西呢,因為許多問題都是需要“最佳化”的(當然也包括未來35歲的你我 )。人生中,你經歷的很多事都可以有一個目標函式(諸如買到房子,找到物件,生個娃,再“雞”個娃,再買個房子,再幫他找個物件。。。),那麼有了目標,就需要進行求解,也就是最佳化。如果你的目標很簡單,就像一個沙盤大小,那你可以一眼就看出沙盤的最低點(或者最高點)在哪,也就是最優解;但是,如果你的目標函式是一個撒哈拉沙漠,你想找到最優解(最低點)的話,那就沒有那麼容易了。。。

如何在複雜的目標函式中找到最優解,衍生出了一系列最佳化演算法,本文則主要以最佳化器為著筆點展開。

關於最佳化器(Optimizer),TensorFlow與PyTorch框架中都進行了封裝,為了對這些最佳化器進行更加深入的瞭解,本文以經典綜述文獻 An overview of gradient descent optimization algorithms 為線索,結合一些優秀的文章,對目前主流的最佳化演算法進行彙總。

當然,僅從面試的角度,最佳化器也是面試官最愛考察的內容之一

統一變數

當前使用的許多最佳化演算法,是對梯度下降法的衍生和最佳化。

在微積分中,對多元函式的引數 θ 求偏導數,把求得的各個引數的導數以向量的形式寫出來就是

梯度

。梯度就是函式變化最快的地方。梯度下降是迭代法的一種,在求解機器學習演算法的模型引數 θ 時,即無約束問題時,梯度下降是最常採用的方法之一。

顧名思義,

梯度下降法的計算過程就是沿梯度下降的方向求解極小值,也可以沿梯度上升方向求解最大值

梯度下降法 (Gradient Descent)

梯度下降法是最基本的最佳化演算法之一。梯度下降法就是沿著梯度下降最快的方向求極小值。

簡單理解就是,上面提到的場景中,你要在撒哈拉沙漠中找最低點,你根本不知道最低點在哪,但是在你所站的位置上,總有一個方向的坡度最陡,你沿著這個方向往下滑是有可能到最低點的。

梯度下降法引數更新為:

梯度下降演算法中,沿著梯度的方向不斷減小模型引數,從而最小化損失函式。基本策略可以理解為”

在你目光所及的範圍內,不斷尋找最陡最快的路徑下山

標準的梯度下降主要有兩個缺點:

訓練速度慢

:每走一步都要計算調整下一步的方向,下山的速度變慢。在應用於大型資料集中,每輸入一個樣本都要更新一次引數,且每次迭代都要遍歷所有的樣本。會使得訓練過程及其緩慢,需要花費很長時間才能得到收斂解。

容易陷入區域性最優解

:由於是在有限視距內尋找下山的方向。當陷入平坦的窪地,會誤以為到達了山地的最低點,從而不會繼續往下走。所謂的區域性最優解就是鞍點。落入鞍點,梯度為0,使得模型引數不在繼續更新。“鞍部” 如下圖所示

因此,真正在使用時,主要是經過改進的以下三類方法,區別在於

每次引數更新時計算的樣本資料量不同

批次梯度下降法(BGD, Batch Gradient Descent)

隨機梯度下降法(SGD, Stochastic Gradient Descent)

小批次梯度下降法(Mini-batch Gradient Descent)

批次梯度下降法 (Batch Gradient Descent, BGD)

這裡的“批次”其實指的就是整個訓練集的資料,後面 MBGD 中的 mini-batch 才是真正意義上的 “一批”

優點

由於

每一步迭代使用了全部樣本

,每次下降的方向為總體的平均梯度,因此損失函式收斂過程會比較穩定。對於凸函式可以收斂到全域性最小值,對於非凸函式可以收斂到區域性最小值。

缺點

每一步更新中,都要利用全部樣本計算梯度,計算起來非常慢,遇到很大量的資料集也會非常棘手,而且不能投入新資料實時更新模型。

隨機梯度下降(Stochastic Gradient Descent, SGD)

隨機梯度下降法, 不像BGD每一次引數更新, 需要計算整個資料樣本集的梯度, 而是每次引數更新 時, 僅僅選取一個樣本 (xi,yi) 計算其梯度, 引數更新公式為

最全機器學習最佳化器Optimizer彙總

公式看起來和上面標準GD一樣,但不同點在於,這裡的樣本是從所有樣本中隨機選取一個,而標準GD是所有的樣本都輸入進行計算。

可以看到BGD和SGD是兩個極端,SGD由於每次引數更新僅僅需要計算一個樣本的梯度,訓練速度很快,即使在樣本量很大的情況下,可能只需要其中一部分樣本就能迭代到最優解,由於每次迭代並不是都向著整體最最佳化方向,導致梯度下降的波動非常大(如下圖),更容易從一個區域性最優跳到另一個區域性最優,準確度下降。

最全機器學習最佳化器Optimizer彙總

論文中提到,當緩慢降低學習率時,SGD會顯示與BGD相同的收斂行為,幾乎一定會收斂到區域性(非凸最佳化)或全域性最小值(凸最佳化)

優點

由於每次迭代只使用了一個樣本計算梯度,訓練速度快,包含一定隨機性,但是從期望來看,每次計算的梯度基本是正確的導數的。雖然看起來SGD波動非常大,會走很多彎路,但是對梯度的要求很低(計算梯度快),而且對於引入噪聲,大量的理論和實踐工作證明,只要噪聲不是特別大,SGD都能很好地收斂。

應用大型資料集時,訓練速度很快。比如每次從百萬資料樣本中,取幾百個資料點,算一個SGD梯度,更新一下模型引數。相比於標準梯度下降法的遍歷全部樣本,每輸入一個樣本更新一次引數,要快得多

缺點

更新頻繁,帶有隨機性,會造成損失函式在收斂過程中嚴重震盪。SGD沒能單獨克服區域性最優解的問題(主要)

SGD在隨機選擇梯度的同時會引入噪聲,使得權值更新的方向不一定正確(次要)

小批次梯度下降法(Mini-batch Gradient Descent, MBGD or SGD)

小批次梯度下降法就是結合BGD和SGD的折中, 對於含有 n 個訓練樣本的資料集, 每次引數更 新, 選擇一個大小為 m($ m

最全機器學習最佳化器Optimizer彙總

小批次梯度下降法即保證了訓練的速度,又能保證最後收斂的準確率,目前的SGD預設是小批次梯度下降演算法。常用的小批次尺寸範圍在50到256之間,但可能因不同的應用而異。

優點

可以降低引數更新時的方差,收斂更穩定,另一方面可以充分地利用深度學習庫中高度最佳化的矩陣操作來進行更有效的梯度計算

缺點:

Mini-batch gradient descent 不能保證很好的收斂性,learning rate 如果選擇的太小,收斂速度會很慢,如果太大,loss function 就會在極小值處不停地震盪甚至偏離(有一種措施是先設定大一點的學習率,當兩次迭代之間的變化低於某個閾值後,就減小 learning rate,不過這個閾值的設定需要提前寫好,這樣的話就不能夠適應資料集的特點)。對於非凸函式,還要避免陷於區域性極小值處,或者鞍點處,因為鞍點所有維度的梯度都接近於0,SGD 很容易被困在這裡(會在鞍點或者區域性最小點震盪跳動,因為在此點處,如果是BGD的訓練集全集帶入,則最佳化會停止不動,如果是mini-batch或者SGD,每次找到的梯度都是不同的,就會發生震盪,來回跳動)。

SGD對所有引數更新時應用同樣的 learning rate,如果我們的資料是稀疏的,我們更希望對出現頻率低的特徵進行大一點的更新, 且learning rate會隨著更新的次數逐漸變小。

在梯度下降公式 θt+1=θt−αgt 中,能改進的兩個點,一是學習率,二是梯度。其分別衍生出自適應(adaptive)學習率方法與動量(momentum)方法。後面講展開介紹

動量最佳化法(Momentum)

動量最佳化法引入了物理之中的概念。動量 p=mv,當一個小球從山頂滾下,速度越來越快,動量越來越大,開始加速梯度下降,當跨越了山谷,滾到對面的坡上時,速度減小,動量減小。

帶動量的小球不僅可以加速梯度;還可以藉著積累的動量,衝過小的山坡,以避免落入區域性最優點。

Momentum

梯度下降法容易被困在區域性最小的溝壑處來回震盪,可能存在曲面的另一個方向有更小的值;有時候梯度下降法收斂速度還是很慢。動量法就是為了解決這兩個問題提出的

momentum演算法思想:引數更新時在一定程度上保留之前更新的方向,同時又利用當前batch的梯度微調最終的更新方向,簡言之就是透過積累之前的動量來 (previous_sum_of_gradient) 加速當前的梯度。

SGD只使用了當步引數的梯度,隨機性較大。如果將歷次迭代的梯度按比例融合,可能更加穩定、更有利於跳出區域性最優。

假設 mt 表示 t 時刻的動量, γ 表示動量因子, 通常取值 0。9 或者近似值, 在SGD的基礎上增加動量, 則引數更新公式為

最全機器學習最佳化器Optimizer彙總

動量因子 γ 的經驗值為 0。9, 這就意味著下降方向主要是此前累積的下降方向, 並略微偏向當前時刻的下降方向。在梯度方向改變時, momentum能夠降低引數更新速度, 從而減少震盪, 在梯度方向相同時, momentum可以加速引數更新, 從而加速收斂, 如下圖

最全機器學習最佳化器Optimizer彙總

動量主要解決SGD的兩個問題:

隨機梯度的方法(引入的噪聲)

Hessian矩陣病態問題(可以理解為SGD在收斂過程中和正確梯度相比來回擺動比較大的問題)

優點

前後梯度一致的時候能夠加速學習;前後梯度不一致的時候能夠抑制震盪,越過區域性極小值(加速收斂,減小震盪)

缺點

增加了一個超引數

NAG(Nesterov accelerated gradient)

最全機器學習最佳化器Optimizer彙總

加上nesterov項後,梯度在大的跳躍後,進行計算對當前梯度進行校正。 下圖是momentum和nesterrov的對比表述圖

最全機器學習最佳化器Optimizer彙總

momentum首先計算一個梯度(短的藍色向量),然後在加速更新梯度的方向進行一個大的跳躍(長的藍色向量),nesterov項首先在之前加速的梯度方向進行一個大的跳躍(棕色向量),計算梯度然後進行校正(綠色向量)

最全機器學習最佳化器Optimizer彙總

Momentum和Nexterov都是為了使梯度更新更靈活。但是人工設計的學習率總是有些生硬,下面介紹幾種自適應學習率的方法。

自適應學習率最佳化演算法

傳統的最佳化演算法要麼將學習率設定為常數要麼根據訓練次數調節學習率。往往忽視了學習率其他變化的可能性。然而,學習率對模型的效能有著顯著的影響,因此需要採取一些策略來想辦法更新學習率,從而提高訓練速度

先來看一下使用統一的全域性學習率的缺點可能出現的問題

對於某些引數,透過演算法已經最佳化到了極小值附近,但是有的引數仍然有著很大的梯度。

如果學習率太小,則梯度很大的引數會有一個很慢的收斂速度; 如果學習率太大,則已經最佳化得差不多的引數可能會出現不穩定的情況。 解決方案:

對每個參與訓練的引數設定不同的學習率,在整個學習過程中透過一些演算法自動適應這些引數的學習率。 如果損失與某一指定引數的偏導的符號相同,那麼學習率應該增加; 如果損失與該引數的偏導的符號不同,那麼學習率應該減小。

自適應學習率演算法主要有:AdaGrad演算法,RMSProp演算法,Adam演算法以及AdaDelta演算法等

AdaGrad((Adaptive Gradient))

Adagrad其實是對學習率進行了一個約束,對於經常更新的引數,我們已經積累了大量關於它的知識,不希望被單個樣本影響太大,希望學習速率慢一些;對於偶爾更新的引數,我們瞭解的資訊太少,希望能從每個偶然出現的樣本(稀疏特徵的樣本)身上多學一些,即學習速率大一些。而該方法中開始使用二階動量,才意味著“自適應學習率”最佳化演算法時代的到來。

AdaGrad 演算法,獨立地適應所有模型引數的學習率,縮放每個引數反比於其

所有梯度歷史平均值總和的平方根

具有損失函式最大梯度的引數相應地有個快速下降的學習率

而具有小梯度的引數在學習率上有相對較小的下降。

最全機器學習最佳化器Optimizer彙總

優點

自適應的學習率,無需人工調節

缺點

仍需要手工設定一個全域性學習率η, 如果 η 設定過大的話,會使 regularizer 過於敏感,對梯度的調節太大

中後期,

分母上梯度累加的平方和會越來越大,使得引數更新量趨近於0

,使得訓練提前結束,無法學習

Adadelta

由於AdaGrad調整學習率變化過於激進,我們考慮一個改變二階動量計算方法的策略:不累積全部歷史梯度,而只關注過去一段時間視窗的下降梯度,即Adadelta只累加固定大小的項,並且也不直接儲存這些項,僅僅是近似計算對應的平均值(指數移動平均值),這就避免了二階動量持續累積、導致訓練過程提前結束的問題了,引數更新公式如下

最全機器學習最佳化器Optimizer彙總

優點

不依賴全域性learning rate

訓練初中期,加速效果不錯,很快

缺點

: 訓練後期,反覆在區域性最小值附近抖動

RMSprop

RMSprop 和 Adadelta 都是為了解決 Adagrad 學習率急劇下降問題的,但是RMSProp演算法修改了AdaGrad的梯度平方和累加為

指數加權的移動平均

,使得其在非凸設定下效果更好。

指數加權平均,旨在消除梯度下降中的擺動,與Momentum的效果一樣,某一維度的導數比較大,則指數加權平均就大,某一維度的導數比較小,則其指數加權平均就小,這樣就保證了各維度導數都在一個量級,進而減少了擺動。

另外,

指數衰減平均的方式可以淡化遙遠過去的歷史對當前步驟引數更新量的影響

,衰減率表明的是隻是最近的梯度平方有意義,而很久以前的梯度基本上會被遺忘

並且RMSprop允許使用一個更大的學習率 η

設定引數: 全域性初始學習率 η=0。001, decay_rate ρ=0。9, 極小常量 ϵ=10e−6, 引數更新如下:

最全機器學習最佳化器Optimizer彙總

優點

RMSprop算是Adagrad的一種發展,和Adadelta的變體,效果趨於二者之間

適合處理非平穩目標(包括季節性和週期性)——對於RNN效果很好

缺點

其實RMSprop依然依賴於全域性學習率 \eta\eta

Adam(Adaptive Moment Estimation)

Adam 結合了前面方法的一階動量和二階動量,相當於 Ada + Momentum,SGD-M和NAG在SGD基礎上增加了一階動量,AdaGrad和AdaDelta在SGD基礎上增加了二階動量。

Adam 除了像 Adadelta 和 RMSprop 一樣儲存了過去梯度的平方 vt 的指數衰減平均值, 也像 momentum 一樣保持了過去梯度 mt 的指數衰減平均值:

最全機器學習最佳化器Optimizer彙總

如果 mt 和 vt 被初始化為0向量, 那麼它們就會向0偏置, 所以做了偏差校正, 透過計算偏差校正後的 mt 和 vt 來抵消這些偏差

最全機器學習最佳化器Optimizer彙總

最終的更新公式為

最全機器學習最佳化器Optimizer彙總

通常情況下,預設值為 β1=0。9,β2=0。999,β1=0。002

優點

Adam梯度經過偏置校正後,每一次迭代學習率都有一個固定範圍,使得引數比較平穩。

結合了Adagrad善於處理稀疏梯度和RMSprop善於處理非平穩目標的優點

為不同的引數計算不同的自適應學習率

也適用於大多非凸最佳化問題——適用於大資料集和高維空間。

缺點

: Adam 使用動量的滑動平均,可能會隨著訓練資料變化而抖動比較劇烈,在online場景可能波動較大,在廣告場景往往效果不如 AdaGrad

Nadam

其實如果說要整合所有方法的優點於一身的話,Nadam應該就是了,Adam遺漏了啥?沒錯,就是Nesterov項,我們在Adam的基礎上,加上Nesterov項就是Nadam了,引數更新公式如下:

最全機器學習最佳化器Optimizer彙總

可以看出,Nadam對學習率有更強的約束,同時對梯度的更新也有更直接的影響。一般而言,在使用帶動量的RMSprop或Adam的問題上,使用Nadam可以取得更好的結果。

AdamW

Adam有很多的優點,但是在很多資料集上的最好效果還是用SGD with Momentum細調出來的。可見Adam的泛化性並不如SGD with Momentum。Decoupled Weight Decay Regularization 提出其中一個重要原因就是 Adam中L2正則化項並不像在SGD中那麼有效

L2正則和Weight Decay在Adam這種自適應學習率演算法中並不等價,只有在標準SGD的情況下,可以將L2正則和Weight Decay看做一樣。特別是,當與自適應梯度相結合時,L2正則化導致具有較大歷史引數和/或梯度幅度的權重比使用權重衰減時更小。

使用Adam最佳化帶L2正則的損失並不有效,如果引入L2正則化項,在計算梯度的時候會加上正則項求梯度的結果。正常的權重衰減是對所有的權重都採用相同的係數進行更新,本身比較大的一些權重對應的梯度也會比較大,懲罰也越大。但由於Adam計算步驟中減去項會有除以梯度平方的累積,使得梯度大的減去項偏小,從而具有大梯度的權重不會像解耦權重衰減那樣得到正則化。 這導致自適應梯度演算法的L2和解耦權重衰減正則化的不等價。

而在常見的深度學習庫中只提供了L2正則,並沒有提供權重衰減的實現。這可能就是導致Adam跑出來的很多效果相對SGD with Momentum有偏差的一個原因

AdamW 使用了嚴謹的 weight decay(非L2正則),即權重衰減不參與一、二動量計算,只在最後的更新公式中使用。其更新公式如下:

最全機器學習最佳化器Optimizer彙總

最佳化器對比 & 總結

收斂直觀對比

下圖描述了在一個曲面上,6種最佳化器的表現

最全機器學習最佳化器Optimizer彙總

動圖封面

下圖在一個存在鞍點的曲面,比較6中最佳化器的效能表現:

最全機器學習最佳化器Optimizer彙總

動圖封面

下圖圖比較了6種最佳化器收斂到目標點(五角星)的執行過程

最全機器學習最佳化器Optimizer彙總

動圖封面

總結 & tricks

目前,最流行並且使用很高的最佳化器(演算法)包括SGD、具有動量的SGD、RMSprop、具有動量的RMSProp、AdaDelta和Adam。在實際應用中,選擇哪種最佳化器應結合具體問題。在充分理解資料的基礎上,依然需要根據資料特性、演算法特性進行充分的調參實驗,找到最優解。

首先,各大演算法孰優孰劣並無定論

。如果是剛入門,優先考慮SGD+NesteroV Momentum或者Adam。(Standford 231n : The two recommended updates to use are either SGD+NesteroV Momentum or Adam)

選擇你熟悉的演算法

:這樣你可以更加熟練地利用你的經驗進行調參。

充分了解你的資料

:如果模型是非常稀疏的,那麼優先考慮自適應學習率的演算法。如果在意更快的收斂,並且需要訓練較深較複雜的網路時,推薦使用自適應學習率的最佳化方法。

根據你的需求來選擇

:在模型設計實驗過程中,要快速驗證新模型的效果,可以先用Adam進行快速實驗最佳化;在模型上線或者結果釋出前,可以用精調的SGD進行模型的極致最佳化。

先用小資料集進行實驗

:有論文研究指出,隨機梯度下降演算法的收斂速度和資料集的大小的關係不大。因此可以先用一個具有代表性的小資料集進行實驗,測試一下最好的最佳化演算法,並透過引數搜尋來尋找最優的訓練引數。

考慮不同演算法的組合

:先用Adam進行快速下降,而後再換到SGD進行充分的調優。切換策略可以參考本文介紹的方法。

資料集一定要充分的打散(shuffle)

:這樣在使用自適應學習率演算法的時候,可以避免某些特徵集中出現,而導致的有時學習過度、有時學習不足,使得下降方向出現偏差的問題。

訓練過程中持續監控

:監控訓練資料和驗證資料上的目標函式值以及精度或者AUC等指標的變化情況。對訓練資料的監控是要保證模型進行了充分的訓練——下降方向正確,且學習率足夠高;對驗證資料的監控是為了避免出現過擬合。

制定一個合適的學習率衰減策略

:可以使用定期衰減策略,比如每過多少個epoch就衰減一次;或者利用精度或者AUC等效能指標來監控,當測試集上的指標不變或者下跌時,就降低學習率。

參考文獻:

An overview of gradient descent optimization algorithms

收藏 | 各種 Optimizer 梯度下降最佳化演算法回顧和總結

最佳化方法總結以及Adam存在的問題(SGD, Momentum, AdaDelta, Adam, AdamW,LazyAdam)

最佳化演算法Optimizer比較和總結

Adam,AdamW,LAMB最佳化器原理與程式碼

TAG: 梯度SGD引數學習演算法