1. 程式人生 > >自適應學習速率SGD優化方法比較(SGD,Adagrad,Adadelta,Adam,Adamax,Nadam)

自適應學習速率SGD優化方法比較(SGD,Adagrad,Adadelta,Adam,Adamax,Nadam)

前言

(標題不能再中二了)本文僅對一些常見的優化方法進行直觀介紹和簡單的比較,各種優化方法的詳細內容及公式只好去認真啃論文了,在此我就不贅述了。

SGD

此處的SGD指mini-batch gradient descent,關於batch gradient descent, stochastic gradient descent, 以及 mini-batch gradient descent的具體區別就不細說了。現在的SGD一般都指mini-batch gradient descent。

SGD就是每一次迭代計算mini-batch的梯度,然後對引數進行更新,是最常見的優化方法了。即:

g_t=\nabla_{\theta_{t-1}}{f(\theta_{t-1})}

\Delta{\theta_t}=-\eta*g_t

其中,\eta

是學習率,g_t是梯度 SGD完全依賴於當前batch的梯度,所以\eta可理解為允許當前batch的梯度多大程度影響引數更新

缺點:(正因為有這些缺點才讓這麼多大神發展出了後續的各種演算法)

  • 選擇合適的learning rate比較困難 - 對所有的引數更新使用同樣的learning rate。對於稀疏資料或者特徵,有時我們可能想更新快一些對於不經常出現的特徵,對於常出現的特徵更新慢一些,這時候SGD就不太能滿足要求了
  • SGD容易收斂到區域性最優,並且在某些情況下可能被困在鞍點【原來寫的是“容易困於鞍點”,經查閱論文發現,其實在合適的初始化和step size的情況下,鞍點的影響並沒這麼大。感謝@冰橙
    的指正】

Momentum

momentum是模擬物理裡動量的概念,積累之前的動量來替代真正的梯度。公式如下:

m_t=\mu*m_{t-1}+g_t

\Delta{\theta_t}=-\eta*m_t

其中,\mu是動量因子

特點:

  • 下降初期時,使用上一次引數更新,下降方向一致,乘上較大的\mu能夠進行很好的加速
  • 下降中後期時,在區域性最小值來回震盪的時候,gradient\to0\mu使得更新幅度增大,跳出陷阱
  • 在梯度改變方向的時候,\mu能夠減少更新 總而言之,momentum項能夠在相關方向加速SGD,抑制振盪,從而加快收斂

Nesterov

nesterov項在梯度更新時做一個校正,避免前進太快,同時提高靈敏度。 將上一節中的公式展開可得:

\Delta{\theta_t}=-\eta*\mu*m_{t-1}-\eta*g_t

可以看出,m_{t-1}並沒有直接改變當前梯度g_t,所以Nesterov的改進就是讓之前的動量直接影響當前的動量。即:

g_t=\nabla_{\theta_{t-1}}{f(\theta_{t-1}-\eta*\mu*m_{t-1})}

m_t=\mu*m_{t-1}+g_t

\Delta{\theta_t}=-\eta*m_t

所以,加上nesterov項後,梯度在大的跳躍後,進行計算對當前梯度進行校正。如下圖:

preview

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

其實,momentum項和nesterov項都是為了使梯度更新更加靈活,對不同情況有針對性。但是,人工設定一些學習率總還是有些生硬,接下來介紹幾種自適應學習率的方法

Adagrad

Adagrad其實是對學習率進行了一個約束。即:

n_t=n_{t-1}+g_t^2

\Delta{\theta_t}=-\frac{\eta}{\sqrt{n_t+\epsilon}}*g_t

此處,對g_t從1到t進行一個遞推形成一個約束項regularizer,-\frac{1}{\sqrt{\sum_{r=1}^t(g_r)^2+\epsilon}}\epsilon用來保證分母非0

特點:

  • 前期g_t較小的時候, regularizer較大,能夠放大梯度
  • 後期g_t較大的時候,regularizer較小,能夠約束梯度
  • 適合處理稀疏梯度
缺點:
  • 由公式可以看出,仍依賴於人工設定一個全域性學習率
  • \eta設定過大的話,會使regularizer過於敏感,對梯度的調節太大
  • 中後期,分母上梯度平方的累加將會越來越大,使gradient\to0,使得訓練提前結束

Adadelta

Adadelta是對Adagrad的擴充套件,最初方案依然是對學習率進行自適應約束,但是進行了計算上的簡化。 Adagrad會累加之前所有的梯度平方,而Adadelta只累加固定大小的項,並且也不直接儲存這些項,僅僅是近似計算對應的平均值。即:

n_t=\nu*n_{t-1}+(1-\nu)*g_t^2

\Delta{\theta_t} = -\frac{\eta}{\sqrt{n_t+\epsilon}}*g_t

在此處Adadelta其實還是依賴於全域性學習率的,但是作者做了一定處理,經過近似牛頓迭代法之後:

E|g^2|_t=\rho*E|g^2|_{t-1}+(1-\rho)*g_t^2

\Delta{x_t}=-\frac{\sqrt{\sum_{r=1}^{t-1}\Delta{x_r}}}{\sqrt{E|g^2|_t+\epsilon}}

其中,E代表求期望。

此時,可以看出Adadelta已經不用依賴於全域性學習率了。

特點:

  • 訓練初中期,加速效果不錯,很快
  • 訓練後期,反覆在區域性最小值附近抖動

RMSprop

RMSprop可以算作Adadelta的一個特例:

\rho=0.5時,E|g^2|_t=\rho*E|g^2|_{t-1}+(1-\rho)*g_t^2就變為了求梯度平方和的平均數。

如果再求根的話,就變成了RMS(均方根):

RMS|g|_t=\sqrt{E|g^2|_t+\epsilon}

此時,這個RMS就可以作為學習率\eta的一個約束:

\Delta{x_t}=-\frac{\eta}{RMS|g|_t}*g_t

特點:

  • 其實RMSprop依然依賴於全域性學習率
  • RMSprop算是Adagrad的一種發展,和Adadelta的變體,效果趨於二者之間
  • 適合處理非平穩目標 - 對於RNN效果很好

Adam

Adam(Adaptive Moment Estimation)本質上是帶有動量項的RMSprop,它利用梯度的一階矩估計和二階矩估計動態調整每個引數的學習率。Adam的優點主要在於經過偏置校正後,每一次迭代學習率都有個確定範圍,使得引數比較平穩。公式如下:

m_t=\mu*m_{t-1}+(1-\mu)*g_t

n_t=\nu*n_{t-1}+(1-\nu)*g_t^2

\hat{m_t}=\frac{m_t}{1-\mu^t}

\hat{n_t}=\frac{n_t}{1-\nu^t}

\Delta{\theta_t}=-\frac{\hat{m_t}}{\sqrt{\hat{n_t}}+\epsilon}*\eta

其中,m_tn_t分別是對梯度的一階矩估計和二階矩估計,可以看作對期望E|g_t|E|g_t^2|的估計;\hat{m_t}\hat{n_t}是對m_tn_t的校正,這樣可以近似為對期望的無偏估計。 可以看出,直接對梯度的矩估計對記憶體沒有額外的要求,而且可以根據梯度進行動態調整,而-\frac{\hat{m_t}}{\sqrt{\hat{n_t}}+\epsilon}對學習率形成一個動態約束,而且有明確的範圍。

特點:

  • 結合了Adagrad善於處理稀疏梯度和RMSprop善於處理非平穩目標的優點
  • 對記憶體需求較小
  • 為不同的引數計算不同的自適應學習率
  • 也適用於大多非凸優化 - 適用於大資料集和高維空間

Adamax

Adamax是Adam的一種變體,此方法對學習率的上限提供了一個更簡單的範圍。公式上的變化如下:

n_t=max(\nu*n_{t-1},|g_t|)

\Delta{x}=-\frac{\hat{m_t}}{n_t+\epsilon}*\eta

可以看出,Adamax學習率的邊界範圍更簡單

Nadam

Nadam類似於帶有Nesterov動量項的Adam。公式如下:

\hat{g_t}=\frac{g_t}{1-\Pi_{i=1}^t\mu_i}

m_t=\mu_t*m_{t-1}+(1-\mu_t)*g_t

\hat{m_t}=\frac{m_t}{1-\Pi_{i=1}^{t+1}\mu_i}

n_t=\nu*n_{t-1}+(1-\nu)*g_t^2

\hat{n_t}=\frac{n_t}{1-\nu^t}\bar{m_t}=(1-\mu_t)*\hat{g_t}+\mu_{t+1}*\hat{m_t}

\Delta{\theta_t}=-\eta*\frac{\bar{m_t}}{\sqrt{\hat{n_t}}+\epsilon}

可以看出,Nadam對學習率有了更強的約束,同時對梯度的更新也有更直接的影響。一般而言,在想使用帶動量的RMSprop,或者Adam的地方,大多可以使用Nadam取得更好的效果。

經驗之談

  • 對於稀疏資料,儘量使用學習率可自適應的優化方法,不用手動調節,而且最好採用預設值
  • SGD通常訓練時間更長,但是在好的初始化和學習率排程方案的情況下,結果更可靠
  • 如果在意更快的收斂,並且需要訓練較深較複雜的網路時,推薦使用學習率自適應的優化方法。
  • Adadelta,RMSprop,Adam是比較相近的演算法,在相似的情況下表現差不多。
  • 在想使用帶動量的RMSprop,或者Adam的地方,大多可以使用Nadam取得更好的效果
最後展示兩張可厲害的圖,一切盡在圖中啊,上面的都沒啥用了... ...