optimizer

在不少機器學習和深度學習的應用中,咱們發現用的最多的優化器是 Adam,爲何呢?html

下面是 TensorFlow 中的優化器, 
https://www.tensorflow.org/api_guides/python/train 
這裏寫圖片描述python

在 keras 中也有 SGD,RMSprop,Adagrad,Adadelta,Adam 等: 
https://keras.io/optimizers/算法

咱們能夠發現除了常見的梯度降低,還有 Adadelta,Adagrad,RMSProp 等幾種優化器,都是什麼呢,又該怎麼選擇呢?api

在 Sebastian Ruder 的這篇論文中給出了經常使用優化器的比較,今天來學習一下: 
https://arxiv.org/pdf/1609.04747.pdf網絡

本文將梳理:機器學習

  • 每一個算法的梯度更新規則和缺點
  • 爲了應對這個不足而提出的下一個算法
  • 超參數的通常設定值
  • 幾種算法的效果比較
  • 選擇哪一種算法

優化器算法簡述?

首先來看一下梯度降低最多見的三種變形 BGD,SGD,MBGD, 
這三種形式的區別就是取決於咱們用多少數據來計算目標函數的梯度, 
這樣的話天然就涉及到一個 trade-off,即參數更新的準確率和運行時間。ide

1. Batch gradient descent
  • 1
  • 2

梯度更新規則
BGD 採用整個訓練集的數據來計算 cost function 對參數的梯度: 函數

θ=θαθJ(θ)

 

缺點
因爲這種方法是在一次更新中,就對整個數據集計算梯度,因此計算起來很是慢,遇到很大量的數據集也會很是棘手,並且不能投入新數據實時更新模型學習

咱們會事先定義一個迭代次數 epoch,首先計算梯度向量 params_grad,而後沿着梯度的方向更新參數 params,learning rate 決定了咱們每一步邁多大。優化

Batch gradient descent 對於凸函數能夠收斂到全局極小值,對於非凸函數能夠收斂到局部極小值。

2. Stochastic gradient descent
  • 1
  • 2

梯度更新規則
和 BGD 的一次用全部數據計算梯度相比,SGD 每次更新時對每一個樣本進行梯度更新, 對於很大的數據集來講,可能會有類似的樣本,這樣 BGD 在計算梯度時會出現冗餘, 而 SGD 一次只進行一次更新,就沒有冗餘,並且比較快,而且能夠新增樣本。

缺點
SGD 由於更新比較頻繁,會形成 cost function 有嚴重的震盪,此外SGD對噪聲比較敏感。

這裏寫圖片描述

BGD 能夠收斂到局部極小值,固然 SGD 的震盪可能會跳到更好的局部極小值處。

當咱們稍微減少 learning rate,SGD 和 BGD 的收斂性是同樣的。

3. Mini-batch gradient descent
  • 1
  • 2

梯度更新規則
MBGD 每一次利用一小批樣本,即 n 個樣本進行計算, 這樣它能夠下降參數更新時的方差,收斂更穩定, 另外一方面能夠充分地利用深度學習庫中高度優化的矩陣操做來進行更有效的梯度計算。 
和 SGD 的區別是每一次循環不是做用於每一個樣本,而是具備 n 個樣本的Batch。

超參數設定值: 
n 通常取值在 50~200

缺點
Mini-batch gradient descent 不能保證很好的收斂性,

①learning rate 若是選擇的過小,收斂速度會很慢,若是太大,loss function 就會在極小值處不停地震盪甚至偏離。

②有一種措施是先設定大一點的學習率,當兩次迭代之間的變化低於某個閾值後,就減少 learning rate,不過這個閾值的設定須要提早寫好,這樣的話就不可以適應數據集的特色。此外,這種方法是對全部參數更新時應用一樣的 learning rate,若是咱們的數據是稀疏的,咱們更但願對出現頻率低的特徵進行大一點的更新

③另外,對於非凸函數,還要避免陷於局部極小值處,或者鞍點處,由於鞍點周圍的error 是同樣的,全部維度的梯度都接近於0,SGD 很容易被困在這裏。

鞍點:一個光滑函數的鞍點鄰域的曲線,曲面,或超曲面,都位於這點的切線的不一樣邊。 
例如這個二維圖形,像個馬鞍:在x-軸方向往上曲,在y-軸方向往下曲,鞍點就是(0,0)

這裏寫圖片描述

爲了應對上面的三點挑戰就有了下面這些算法。

[應對挑戰 1]

4. Momentum(動量法)
  • 1
  • 2

SGD 在 ravines 的狀況下容易被困住, ravines就是曲面的一個方向比另外一個方向更陡,這時 SGD 會發生震盪而遲遲不能接近極小值:

這裏寫圖片描述

梯度更新規則
Momentum 經過加入 γvt1 ,能夠加速 SGD, 而且抑制震盪 

vt=γvt1+αθJ(θ)

 

θ=θvt


當咱們將一個小球從山上滾下來時,沒有阻力的話,它的動量會愈來愈大,可是若是遇到了阻力,速度就會變小。 
加入的這一項,可使得梯度方向不變的維度上速度變快,梯度方向有所改變的維度上的更新速度變慢,這樣就能夠加快收斂並減少震盪。

 

超參數設定值: 
通常 γ取值 0.9 左右。

缺點: 
這種狀況至關於小球從山上滾下來時是在盲目地沿着坡滾,若是它能具有一些先知,例如快要上坡時,就知道須要減速了的話,適應性會更好。

5. Nesterov accelerated gradient(NAG)
  • 1
  • 2

梯度更新規則
用 θγvt1來近似當作參數下一步會變成的值,則在計算梯度時,不是在當前位置,而是將來的位置上 

vt=γvt1+αθJ(θγvt1)


θ=θvt


超參數設定值: 
γ仍然取值 0.9 左右。

 

效果比較: 
這裏寫圖片描述

藍色是 Momentum 的過程,會先計算當前的梯度,而後在更新後的累積梯度後會有一個大的跳躍。 
而 NAG 會先在前一步的累積梯度上(brown vector)有一個大的跳躍,而後衡量一下梯度作一下修正(red vector),這種預期的更新能夠避免咱們走的太快。

NAG 可使 RNN 在不少任務上有更好的表現。

目前爲止,咱們能夠作到,在更新梯度時順應 loss function 的梯度來調整速度,而且對 SGD 進行加速。

咱們還但願能夠根據參數的重要性而對不一樣的參數進行不一樣程度的更新。

[應對挑戰 2]

6. Adagrad
  • 1
  • 2

這個算法就能夠對低頻的參數作較大的更新,對高頻的作較小的更新,也所以,對於稀疏的數據它的表現很好,很好地提升了 SGD 的魯棒性,例如識別 Youtube 視頻裏面的貓,訓練 GloVe word embeddings,由於它們都是須要在低頻的特徵上有更大的更新。

梯度更新規則

θt+1,i=θt,iαGt,ii+ϵ−−−−−−−√gt,i

 

其中gt,i爲:t 時刻參數 θi的梯度;Gt是個對角矩陣, (i,i) 元素就是 t 時刻參數 θi 的梯度gt,i的平方和。

Adagrad 的優勢是減小了學習率的手動調節

超參數設定值: 
通常 η 就取 0.01。

缺點: 
它的缺點是分母會不斷積累,這樣學習率就會收縮並最終會變得很是小。

7. Adadelta
  • 1
  • 2

這個算法是對 Adagrad 的改進, 

Δθt=αE[g2]t+ϵ−−−−−−−−√gt


和 Adagrad 相比,就是分母的G換成了過去的梯度平方E[g2]t的衰減平均值。

 

這個分母至關於梯度的均方根 root mean squared (RMS) ,因此能夠用 RMS 簡寫: 

Δθt=αRMS[g]tgt

 

其中 E 的計算公式以下,t 時刻的依賴於前一時刻的平均和當前的梯度:

 

E[g2]t=γE[g2]t1+(1γ)g2t

 

梯度更新規則:

此外,還將學習率 α換成了 RMS[Δθ],這樣的話,咱們甚至都不須要提早設定學習率了: 
這裏寫圖片描述

超參數設定值: 
γ 通常設定爲 0.9,

7. RMSprop
  • 1
  • 2

RMSprop 是 Geoff Hinton 提出的一種自適應學習率方法。

RMSprop 和 Adadelta 都是爲了解決 Adagrad 學習率急劇降低問題的。

梯度更新規則
RMSprop 與 Adadelta 的第一種形式相同: 

E[g2]t=0.9E[g2]t1+0.1g2t


θt+1=θtαE[g2]t+ϵ−−−−−−−−√gt

 

超參數設定值: 
Hinton 建議設定 γ爲 0.9, 學習率 α爲 0.001。

8. Adam
  • 1
  • 2

這個算法是另外一種計算每一個參數的自適應學習率的方法。目前在DL領域,是最多見的優化器。

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

若是 mt和 vt 被初始化爲 0 向量,那它們就會向 0 偏置,因此作了誤差校訂, 
經過計算誤差校訂後的 mt 和 vt 來抵消這些誤差: 
這裏寫圖片描述

梯度更新規則

θt+1=θtαvt+ϵ−−−−−√mt

 

超參數設定值: 
建議 β1 = 0.9,β2 = 0.999,ϵ = 10e−8

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

效果比較?

下面看一下幾種算法在鞍點和等高線上的表現: 
這裏寫圖片描述 
這裏寫圖片描述 
上面兩種狀況均可以看出,Adagrad, Adadelta, RMSprop 幾乎很快就找到了正確的方向並前進,收斂速度也至關快,而其它方法要麼很慢,要麼走了不少彎路才找到。

由圖可知自適應學習率方法即 Adagrad, Adadelta, RMSprop, Adam 在這種情景下會更合適並且收斂性更好。

如何選擇?

若是數據是稀疏的,就用自適應方法,即 Adagrad, Adadelta, RMSprop, Adam。

RMSprop, Adadelta, Adam 在不少狀況下的效果是類似的。

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

隨着梯度變的稀疏,Adam 比 RMSprop 效果會好。

總體來說,Adam 是最好的選擇。

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

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

參考:

http://sebastianruder.com/optimizing-gradient-descent/index.html#fn:24 
http://www.redcedartech.com/pdfs/Select_Optimization_Method.pdf 
https://stats.stackexchange.com/questions/55247/how-to-choose-the-right-optimization-algorithm

相關文章
相關標籤/搜索