優化器算法optimizer

其實本來是沒有想寫關於optimizer的,因爲網上的一搜一大把,但是我發現好多文章都講的亂七八糟,可能可能知道相關概念的人來看就比較順暢,但是對於小白或者是之前接觸比較少的人來說,就比較費勁,我這裏也是作爲自己的筆記,重新梳理一下,多數資料也是來源於之前的大牛blog,最後會有相關參考鏈接

1.相關背景

1.1.指數加權移動平均(Exponential Weighted Moving Average)

1.1.1.演化與概述

算術平均(權重相等)—>加權平均(權重不等)—>移動平均(大約是隻取最近的 N 次數據進行計算)—> 批量歸一化(BN)及各種優化算法的基礎
EMA:是以指數式遞減加權的移動平均,各數值的加權影響力隨時間呈指數式遞減,時間越靠近當前時刻的數據加權影響力越大

在這裏插入圖片描述

1.1.2.公式理解

  • vt=βvt1+(1β)θtv_t = \beta v_{t-1} + (1 - \beta)\theta_{t},公式中 θt\theta_{t} 爲 t 時刻的實際溫度;係數 \beta 表示加權下降的快慢,值越小權重下降的越快;vtv_t 爲 t 時刻 EMA 的值。
  • v0=0v_0 = 0 時,可得:vt=(1β)(θt+βθt1+β2θt2+...+βt1θ1)v_t = (1-\beta) (\theta_{t}+\beta\theta_{t-1}+\beta^{2}\theta_{t-2}+ ... +\beta^{t-1}\theta_{1}),從公式中可以看到:每天溫度(θ\theta)的權重係數以指數等比形式縮小,時間越靠近當前時刻的數據加權影響力越大。
  • 在優化算法中,我們一般取 β>=0.9\beta >= 0.9,而 1+β+β2+...+βt1=1βt1β1 + \beta + \beta^{2} + ... + \beta^{t-1} = \frac{1-\beta^{t}}{1-\beta},所以當 t 足夠大時 βt0\beta^{t} \approx 0,此時便是嚴格意義上的指數加權移動平均。
  • 在優化算法中,我們一般取 β>=0.9\beta >= 0.9,此時有 β11β1e0.36\beta^{\frac{1}{1-\beta}} \approx \frac{1}{e} \approx 0.36,也就是說 N=11βN = \frac{1}{1-\beta} 天后,曲線的高度下降到了約原來的 13\frac{1}{3},由於時間越往前推移θ\theta 權重越來越小,所以相當於說:我們每次只考慮最近(latest) N=11βN = \frac{1}{1-\beta} 天的數據來計算當前時刻的 EMA,這也就是移動平均的來源。

1.1.3.EMA 偏差修正

在這裏插入圖片描述
β\beta = 0.98 時,理想狀況下,我們應該能得到綠色曲線,然而現實我們得到的卻是紫色曲線,它的起點比真實的要低很多,不能很好的估計起始位置的溫度,此問題稱爲:冷啓動問題,這是由於 v0v_0 = 0 造成的。
解決方案:將所有時刻的 EMA 除以 1βt1 - \beta^{t} 後作爲修正後的 EMA。當 t 很小時,這種做法可以在起始階段的估計更加準確;當 t 很大時,偏差修正幾乎沒有作用,所以對原來的式子幾乎沒有影響。注意:我們一般取 β>=0.9\beta >= 0.9,計算 t 時刻偏修正後的 EMA 時,用的還是 t-1 時刻修正前的EMA。

1.1.4.EMA 在 Momentum 優化算法中應用的理解

假設每次梯度的值都是 g、γ=0.95\gamma = 0.95 ,此時參數更新幅度會加速下降,當 n 達到 150 左右,此時達到了速度上限,之後將勻速下降(可參考一中的公式理解)。
假如,在某個時間段內一些參數的梯度方向與之前的不一致時,那麼真實的參數更新幅度會變小;相反,若在某個時間段內的參數的梯度方向都一致,那麼其真實的參數更新幅度會變大,起到加速收斂的作用。在迭代後期,由於隨機噪聲問題,經常會在收斂值附近震盪,動量法會起到減速作用,增加穩定性。

2.遞歸下降算法

2.1.BGD MBGD SGD

具體可參考之前的文章
或者這個參考鏈接:
深度學習——優化器算法Optimizer詳解(BGD、SGD、MBGD、Momentum、NAG、Adagrad、Adadelta、RMSprop、Adam)

近期的的研究表明,深層神經網絡之所以比較難訓練,並不是因爲容易進入local minimum。相反,由於網絡結構非常複雜,在絕大多數情況下即使是 local minimum 也可以得到非常好的結果。而之所以難訓練是因爲學習過程容易陷入到馬鞍面中,即在坡面上,一部分點是上升的,一部分點是下降的。而這種情況比較容易出現在平坦區域,在這種區域中,所有方向的梯度值都幾乎是 0。

2.2.Momentum

動量方法旨在加速學習,特別是在面對小而連續的梯度但是含有很多噪聲的時候。動量模擬了物體運動時的慣性,即在更新的時候在一定程度上會考慮之前更新的方向,同時利用當前batch的梯度微調最終的結果。這樣則可以在一定程度上增加穩定性,從而更快的學習。
公式:
mt=μmt1+gtΔθt=ηmtm_t = \mu * m_{t-1} +g_t \\\Delta \theta_t = -\eta *m_t

在這裏插入圖片描述
加入的這一項,可以使得梯度方向不變的維度上速度變快,梯度方向有所改變的維度上的更新速度變慢,這樣就可以加快收斂並減小震盪。

超參數設定值: 一般 γ 取值 0.9 左右。

優點:

  • 下降初期時,使用上一次參數更新,當下降方向一致時能夠加速學習
  • 下降中後期,在局部最小值附近來回振盪時,gradient–>0,使得更新幅度增大,跳出陷阱;
  • 在梯度改變方向時,能減少更新。總體而言,momentum能夠在相關方向上加速學習,抑制振盪,從而加速收斂

缺點:

  • 這種情況相當於小球從山上滾下來時是在盲目地沿着坡滾,如果它能具備一些先知,例如快要上坡時,就知道需要減速了的話,適應性會更好。

2.3.Nesterov Accelerated Gradient

可以看到,此前積累的動量mt1m_{t−1}並沒有直接改變當前梯度gtg_t,所以Nesterov的改進就是讓之前的動量直接影響當前的動量,即:
在這裏插入圖片描述
所以,加上Nesterov項後,梯度在大的跳躍後,進行計算對當前梯度進行校正。

Nesterov動量和標準動量的區別在於梯度的計算上。Nesterov動量的梯度計算是在施加當前速度之後。因此,Nesterov動量可以解釋爲往標準動量方法中添加了一個校正因子。
其實說白了就是當前位置在用上次的梯度先暫時更新一下θ\theta,然後再計算梯度,這樣就能看到如果按照上次的梯度更新時的效果,相當於往前看了一步,這樣再和之前動量結合,從而起了校正的作用

那到底爲什麼呢?從數學上看怎麼校正的呢?看下面等效形式
在這裏插入圖片描述
這個NAG的等效形式與Momentum的區別在於,本次更新方向多加了一個β[g(θi1)g(θi2)]\beta[g(\theta_{i-1}) - g(\theta_{i-2})],它的直觀含義就很明顯了:如果這次的梯度比上次的梯度變大了,那麼有理由相信它會繼續變大下去,那我就把預計要增大的部分提前加進來;如果相比上次變小了,也是類似的情況。這樣的解釋聽起來好像和原本的解釋一樣玄,但是讀者可能已經發現了,這個多加上去的項不就是在近似目標函數的二階導嘛!所以NAG本質上是多考慮了目標函數的二階導信息,怪不得可以加速收斂了!其實所謂“往前看”的說法,在牛頓法這樣的二階方法中也是經常提到的,比喻起來是說“往前看”,數學本質上則是利用了目標函數的二階導信息。

其他相關參考:比Momentum更快:揭開Nesterov Accelerated Gradient的真面目

2.4 Adagrad

接下來的這幾個都是自適應學習率的遞歸下降算法
在訓練開始的時候,我們遠離最終的最優值點,需要使用較大的學習率。經過幾輪訓練之後,我們需要減小訓練學習率。
在採用mini-batch梯度下降時,迭代的過程中會伴隨有噪音,雖然cost function會持續下降,但是算法收斂的結果是在最小值附近處擺動,而減小學習率,則會使得最後的值在最小值附近,更加接近收斂點。
在這裏插入圖片描述

Divide the learning rate of each parameter by the root mean square of its previous derivatives(將每個參數除以之前所有梯度的均方和)。 在這裏插入圖片描述
這裏ntn_t是從t=1開始進行遞推形成一個約束項regularizer(其實就是之前所有梯度的平方和),ε保證分母非0;

在這裏插入圖片描述
我們發現一個現象,本來應該是隨着gradient的增大,我們的學習率是希望增大的,也就是圖中的gt;但是與此同時隨着gradient的增大,我們的分母是在逐漸增大,也就對整體學習率是減少的,這是爲什麼呢?
這是因爲隨着我們更新次數的增大,我們是希望我們的學習率越來越慢。因爲我們認爲在學習率的最初階段,我們是距離損失函數最優解很遠的,隨着更新的次數的增多,我們認爲越來越接近最優解,於是學習速率也隨之變慢。

特點:
  (1) 前期gtgt較小的時候,regularizer較大,能夠放大梯度
  (2) 後期gtgt較大的時候,regularizer較小,能夠約束梯度
  (3) 適合處理稀疏梯度。
缺點:
  (1) 需要手動設置一個全局的學習率
  (2) ηη設置過大時,會使regularizer過於敏感,對梯度的調節太大
  (3) 中後期,分母上梯度平方的累積將會越來越大,使gradient–>0,使得訓練提前結束

2.5.Adadelta

Adadelta是Adagrad的拓展,最初方案依舊是對學習率進行自適應約束,但是進行了計算上的簡化。Adagrad會累加之前所有的梯度平方,而Adadelta只累加固定大小的項,並且也不直接存儲這些項,僅僅是近似計算對應的平均值。即:
在這裏插入圖片描述

AdaDelta算法主要是爲了解決AdaGrad算法中存在的缺陷,下面先介紹一下AdaGrad算法優點和以及存在的問題:

AdaGrad的迭代公式如下所示:
Δxt=ηi=1tgi2gt\Delta{x_{t}}=\frac{\eta}{\sqrt{\sum_{i=1}^{t}{g_i^2}}}*g_t
xt=xt1Δxtx_t=x_{t-1}-\Delta{x_t}

其中gtg_t 表示當前迭代次數的梯度值。

優點

  • 學習率將隨着梯度的倒數增長,也就是說較大梯度具有較小的學習率,而較小的梯度具有較大的學習率,可以解決普通的sgd方法中學習率一直不變的問題
    缺點
  • 還是需要自己手動指定初始學習率,而且由於分母中對歷史梯度一直累加,學習率將逐漸下降至0,並且如果初始梯度很大的話,會導致整個訓練過程的學習率一直很小,從而導致學習時間變長。
    而AdaDelta算法的提出就是爲了解決上述的問題,AdaDelta有兩種解決方案:

改進方法一:Accumulate Over Window

  • 在一個窗口w中對梯度進行求和,而不是對梯度一直累加
  • 因爲存放 w 之前的梯度是低效的,所以可以用對先前所有梯度均值(使用RMS即均方根值實現)的一個指數衰減作爲代替的實現方法。

更新公式如下:
① 將累計梯度信息從全部歷史梯度變爲當前時間向前的一個窗口期內的累積:
E[g2]t=ρE[g2]t1+(1ρ)gt2E[g^2]_t=\rho*E[g^2]_{t-1}+(1-\rho)*g_t^2

相當於歷史梯度信息的累計乘上一個衰減係數ρ\rho,然後用(1ρ1-\rho)作爲當前梯度的平方加權係數相加。

②然後將上述E[gt2]E[g_t^2]開方後,作爲每次迭代更新後的學習率衰減係數:
xt+1=xtηE[g2]t+ϵgt{x_{t+1}}=x_t-\frac{\eta}{\sqrt{E[g^2]_t+\epsilon}}*g_t


RMS(gt)=E[g2]t+ϵRMS(g_t)=\sqrt{E[g^2]_t+\epsilon}
其中ϵ\epsilon是爲了防止分母爲0而加上的一個極小值。
這種更新方法解決了對歷史梯度一直累加而導致學習率一直下降的問題,當時還是需要自己選擇初始的學習率。

改進方法二:Correct Units with Hessian Approximation
這一部分沒搞懂,牛頓法的公式怎麼變成了下面的?
通過牛頓法可以知道,牛頓法迭代步長是f(x)f^{\prime\prime}(x),一階牛頓迭代公式爲;
xt+1=xtf(x)f(x)x_{t+1}=x_t-\frac{f^{\prime}(x)}{f^{\prime\prime}(x)}

可以看出牛頓算法的迭代步長是二階近似的解析解,不需要我們手動指定學習率。
而高階的牛頓法迭代的步長爲Hessian\boldsymbol{Hessian}矩陣。
AdaDelta算法正是採用了這種思想,採用Hessian\boldsymbol{Hessian}矩陣的對角線近似Hessian\boldsymbol{Hessian}矩陣。
公式如下所示:
Δxfx2fx2\Delta{x}\approx{\frac{\frac{\partial{f}}{\partial{x}}}{\frac{\partial^2{f}}{\partial{x^2}}}}
於是有:
12fx2=Δxfx\frac{1}{{\frac{\partial^2{f}}{\partial{x^2}}}}=\frac{\Delta{x}}{\frac{\partial{f}}{\partial{x}}}
而更新公式爲:
xt+1=xt12fx2gt=Δxfxgtx_{t+1}=x_t-\frac{1}{{\frac{\partial^2{f}}{\partial{x^2}}}}*g_t=\frac{\Delta{x}}{\frac{\partial{f}}{\partial{x}}}*g_t
同理對分子分母按照上一個方法進行處理,可以得到以下公式:

  • 其中假設x附近的曲率是平滑的,而xt+1x_{t+1}
    可以近似xtx_t
    Δx=RMS[(Δx)]t1RMS[g]tgt\Delta{x}=\frac{RMS[(\Delta{x})]_{t-1}}{RMS[g]_t}*g_t
    xt+1=xtΔxx_{t+1}=x_t-\Delta{x}
    其中gtg_t爲本次迭代的梯度。
  • 由於RMS永遠爲正,所以能保證更新的方向一直爲梯度的負方向
  • 分子作爲一個加速項,作爲動量在時間窗口ww上積累先前的梯度。
    下面是論文中的算法展示:
    在這裏插入圖片描述

2.6 RMSProp

RMSprop 和 Adadelta 都是爲了解決 Adagrad 學習率急劇下降問題的,
RMSProp可以看做爲Adadalta的一個特例,RMSprop 與 Adadelta 的第一種形式相同:(使用的是指數加權平均,旨在消除梯度下降中的擺動,與Momentum的效果一樣,某一維度的導數比較大,則指數加權平均就大,某一維度的導數比較小,則其指數加權平均就小,這樣就保證了各維度導數都在一個量級,進而減少了擺動。允許使用一個更大的學習率η)
在這裏插入圖片描述
優點:
(1) 由於採用了梯度平方的指數加權平均,改進了AdaGrad在深度學習中過早結束的問題,效果趨於二者之間
(2) 適用於處理非平穩過程(也即過程依賴於時間,採用指數加權平均時對於非平穩過程處理較好)-對於RNN效果較好
缺點:
(1) 仍然依賴於全局學習率

2.7 Adam

這個算法是另一種計算每個參數的自適應學習率的方法。相當於 RMSprop + Momentum

除了像 Adadelta 和 RMSprop 一樣存儲了過去梯度的平方 vt 的指數衰減平均值 ,也像 momentum 一樣保持了過去梯度 mt 的指數衰減平均值:
在這裏插入圖片描述

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

在這裏插入圖片描述

梯度更新規則:

在這裏插入圖片描述
超參數設定值:
建議 β1 = 0.9,β2 = 0.999,ϵ = 10e−8

實踐表明,Adam 比其他適應性學習方法效果要好。

這裏拿出Adadelta、RMSprop和Adam說一下自己的理解:

  • RMSprop是運用了二階移動平均的方式來調態自適應整動步長,不過這裏依然依賴於全局的學習率η\eta
  • Adadelta運用的同樣是二階移動平均自適應調整步長,AdaDelta算法還維護一個額外的狀態變量 ΔxtΔx_t,使用 Δxt1Δx_{t−1} 來計算自變量的變化量,因此這裏不依賴超參數η\eta
  • Adam同時採用了二階移動平均自適應調整步長,同時也是用了momentum移動平均來調整偏導,算是RMSprop和momentum的一個結合體,因此這裏依賴全局學習率η\eta

2.8 如何選擇優化算法

如果數據是稀疏的,就用自適用方法,即 Adagrad, Adadelta, RMSprop, Adam

RMSprop, Adadelta, Adam 在很多情況下的效果是相似的。

Adam 就是在 RMSprop 的基礎上加了 bias-correction 和 momentum

隨着梯度變的稀疏,Adam 比 RMSprop 效果會好。
整體來講,Adam 是最好的選擇

很多論文裏都會用 SGD,沒有 momentum 等。SGD 雖然能達到極小值,但是比其它算法用的時間長,而且可能會被困在鞍點。

如果需要更快的收斂,或者是訓練更深更復雜的神經網絡,需要用一種自適應的算法。

在這裏插入圖片描述
在這裏插入圖片描述

其他相關優化方法

參考 常見的幾種最優化方法(梯度下降法、牛頓法、擬牛頓法、共軛梯度法等)
如何通俗易懂地講解牛頓迭代法?

參考鏈接

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