An overview of gradient descent optimization algorithms 論文閱讀

0. 寫在前面的話

  學習論文,首先要構建一個知識架構,即大體分爲哪幾部分。然後再關注Abstraction、Introduction、Conclusion,接着看非數學的部分,最後再去看相關的數學公式。簡單總結一下,先構建知識網絡,再構建每一部分的具體細節。

  本篇文章的主體架構爲:
  1. Abstraction
  2. Introduction
  3. Variants
  4. Challenges
  5. Most common algorithms
  6. Parallel and distributed SGD
  7. Other optimizing stategy
  8. Conclusion

1. 摘要

  梯度下降優化算法越來越受到大家的歡迎,但卻經常被用作黑盒算法去使用,所以很難得到不同算法的優劣之處。本篇文章的目的是給讀者提供不同算法的直觀解釋(直覺),從而讀者能夠根據自己需要去使用。在本篇論文中,我們將會學習到梯度下降的不同變種、遇到的困難、最常用的優化算法,以及在並行和分佈式計算中的梯度下降框架,其它優化梯度下降的策略。

2. 圖片

在這裏插入圖片描述
http://imgur.com/a/Hqolp

3. 導論

  梯度下降是最受歡迎的優化算法,也是在優化神經網絡中最常用的方法。與此同時,各種深度學習框架(如lasagne、caffe、keras)都包括了最常用的梯度下降優化算法。但這些算法通常被用作黑盒算法,所以很難去理性分析它們的優缺點。

  本篇論文的目標是給讀者提供各種優化算法的直觀解釋,從而讀者能夠根據自己所需選擇適合的優化算法。在第二章,我們首先將學習梯度下降算法的各種變種形式。在第三章,我們將會描述梯度下降在訓練過程中遇到的困難。在第四章,我們將分別介紹最常用的優化算法,它們是如何解決遇到的困難,然後如何進行參數的更新。在第五章,我們將介紹一些有關並行計算和分佈式計算中是如何使用梯度下降的。在第六章,我們將會介紹一些其他方法來優化梯度下降。

  梯度下降是通過往目標函數梯度θJ(θ)\nabla _ { \theta } J ( \theta )的反方向更新參數θRd\theta \in R^d,從而得到目標函數J(θ)J(\theta)的最小值。學習率η\eta決定了往局部極小值行進的步長。換句話說,我們往曲面(目標函數)下降的方向移動,直至到達山谷。

4. 梯度下降的變種

  梯度下降有三種變種,區別是用多少數據來計算損失函數的梯度。根據計算的數據多少,我們需要在參數的準確性和執行時間之間進行抉擇。

4.1 批梯度下降

  Vanilla gradient descent,也稱爲是批梯度下降, 對參數θ\theta進行更新的公式爲:
θ=θηθJ(θ)\theta=\theta-\eta \cdot \nabla _ { \theta } J ( \theta )

  每次更新參數都需要計算整個數據集的梯度,所以批梯度下降計算速度很慢,不適合大數據集,而且批梯度下降不適合在線更新參數。

  在代碼中,批梯度下降類似於如下的表示:

for i in range ( nb_epochs ):
	params_grad = evaluate_gradient ( loss_function , data , params )
	params = params - learning_rate * params_grad

  在每個epoch中,我們都需要計算整個數據集的梯度。需要注意的是,最新的深度學習框架都提供了自動而且高效求解梯度(自動求導)的功能。如果自己進行求導,梯度檢查是個很好的想法。然後,我們在梯度方向更新參數,學習率決定了更新參數的步長。批梯度下降將會收斂到凸函數平面的全局最小值或者非凸函數平面的局部最小值。

4.2 隨機梯度下降

  隨機梯度下降(SGD)是對每個訓練樣本(x(i),y(i)x^{(i)},y^{(i)})求梯度並進行參數更新:
θ=θηθJ(θ;x(i);y(i))\theta=\theta-\eta \cdot \nabla _ { \theta } J ( \theta;x^{(i)};y^{(i)})

  批梯度下降在大型數據集中會有很多的冗餘計算,因爲它在每次更新參數時重新計算很多相似樣本的梯度。SGD通過單個樣本進行更新參數來消除冗餘。因此SGD要比批梯度下降要快得多,它可以用在在線學習中。但SGD頻繁更新參數,就會導致損失函數的方差比較大,如下圖劇烈的震盪:
在這裏插入圖片描述

  批梯度下降會收斂到盆地的最小值,而SGD的劇烈震盪可能會跳躍到更好的局部最小值。其中overshooting指的是下圖中的紫色曲線(此圖來源於博客 https://blog.csdn.net/m0_37622530/article/details/81143368):
在這裏插入圖片描述
  然而,當我們降低學習率,SGD就會表現出和批梯度下降相同的收斂行爲,即在凸平面中收斂到全局最小值或者在非凸平面中收斂到局部最小值。需要注意的是在每個epoch中,我們需要shuffle訓練數據,僞代碼如下所示:

for i in range (nb_epochs):
	np.random.shuffle ( data )
	for example in data :
		params_grad = evaluate_gradient ( loss_function , example , params )
		params = params - learning_rate * params_grad

4.3 小批量梯度下降

  小批量梯度下降是對n個訓練樣本求梯度並進行參數更新:
θ=θηθJ(θ;x(i;i+n);y(i;i+n))\theta=\theta-\eta \cdot \nabla _ { \theta } J ( \theta;x^{(i;i+n)};y^{(i;i+n)})

  a. 小批量梯度下降會減少參數更新的方差,所以將會導致更加穩定的收斂。b. 小批量梯度下降能夠充分利用深度學習框架的矩陣優化算法。通常的小批量的數量取50到256之間,根據不同的應用進行調整。小批量梯度下降是神經網絡中最常用的選擇,而且SGD這個名稱也會包括小批量梯度下降。爲了簡單起見,下文中使用SGD就會省略參數(x(i;i+n),y(i;i+n))(x^{(i;i+n)},y^{(i;i+n)})。

  設置batch_size的默認值爲50,小批量梯度下降的僞代碼如下所示:

for i in range (nb_epochs):
	np.random.shuffle (data)
	for batch in get_batches (data , batch_size =50):
		params_grad = evaluate_gradient ( loss_function , batch , params )
		params = params - learning_rate * params_grad

5. 挑戰

  • 選擇合適的學習率非常困難。學習率過低將會導致很慢的收斂,學習率過大可能阻礙收斂,使得在最小值附近波動甚至遠離最小值。
  • 學習速率時間表是通過退火來調整學習率,例如按照預設的時間表來降低學習率或者當梯度小於某個閾值以後改變學習率。這些時間表和閾值,都是預先設置的,無法根據數據集進行自適應更改,可參照博客:http://www.sohu.com/a/224777308_129720
  • 另外,對於所有參數而言,學習率都是相同的。如果數據是稀疏的,而且特徵的頻率並不相同,所以更新參數的程序不應該是相同的。
  • 另外一個重要挑戰是在神經網絡學習中,通常的損失函數都是非凸函數,如何避免陷入到局部最小值點。Dauphin等人認爲難度是陷入到鞍點,而不是局部最小值點。這些鞍點通常被相同損失值的平面所包圍,這使得SGD難以突破,這是因爲梯度在所有維度上都接近於零。

6. 梯度下降優化算法

  我們將介紹深度學習社區常用用的一些算法,從而能夠應對上述的挑戰。我們將不會討論不適合高維度數據的方法,比如二階方法(牛頓法等)。

6.1 動量法

  SGD無法穿越溝壑,如表面在一個維度上比另一個維度更陡峭的區域[19],通常它是局部最小值點。 在這些情景中,SGD在山溝的斜坡上擺動,同時只是在底部向局部最佳緩慢移動,如圖2a所示:
在這裏插入圖片描述
  動量法可以幫助SGD在相關方向上進行加速,並抑制震盪的發生。它是在SGD的梯度基礎上,增加了γ\gamma倍的上一個時間點的向量。
vt=γvt1+ηθJ(θ)v_t = \gamma v_{t-1}+\eta \nabla _{\theta} J(\theta) θ=θvt\theta = \theta - v_t

  爲了更好的說明動量法,我們以下圖中的竹筒爲例,假如起始點爲左上方的位置,最小值點爲最下方。
在這裏插入圖片描述
  此時梯度的方向爲右下方,包括如下兩個分量,分量一是垂直於竹筒的(向右),分量二是沿着竹筒的(向下的)。但是分量一遠大於分量二,這樣小球就會左右搖擺,緩慢往下走,雖然最終也能達到最小值點,但是就會耗費大量時間。
在這裏插入圖片描述
  但如果使用了動量法,沿着竹筒的向量就會越來越大,而垂直於竹筒的向量由於左右搖擺,並不會沿着一個方向累加。

6.2 Nesterov accelerated gradient

  然而,滾下山坡的球盲目的跟隨斜坡是不太讓人滿意的。我們希望有個更加聰明的球,在遇到下一個上坡之前能夠及時停下來。

  NAG(該方法)是一種給動量法增加了先見之明的方法。在動量法中,使用γvt1\gamma v_{t-1}θ\theta的反方向移動。θγvt1\theta - \gamma v_{t-1}是下個θ\theta的近似值(爲什麼省略了t1t-1時刻的梯度呢?個人看法是覺得梯度變化值小,爲了簡化計算期間,就去掉了)。公式如下所示:

vt=γvt1+ηθJ(θγvt1)v_t = \gamma v_{t-1}+\eta \nabla _{\theta} J(\theta-\gamma v_{t-1}) θ=θvt\theta = \theta - v_t

  這次我們依然設置γ\gamma爲0.9。當動量法首次計算當前梯度(短藍色向量),累積的變量爲長藍色向量。NAG是首先進行累計向量的跳轉(第一個棕色向量),然後通過先見之明的計算得到紅色變量,所以最終結果是跳轉到第一個綠色向量。這種先知之明降低了不穩定性,從而提高了RNN在許多任務上訓練的速度。
在這裏插入圖片描述
  上述方法解決了學習方向的一些問題,但我們還希望根據特徵的稀疏性針對性的進行調整參數。

6.3 Adagrad

  Adagrad也是梯度下降算法,它的思想是根據參數進行適應性的學習。具體來說,是對頻繁出現的參數設置較小的學習率,而對很少出現的參數設置較大的學習率。所以該方法很適合細數數據。Dean等人發現Adagrad大幅提高了SGD的魯棒性,並用它來訓練谷歌的視頻物體識別(如貓)對應的神經網絡。另外,Pennington等人在訓練Glove詞向量的時候,很少出現的參數需要更大的學習率。

  之前,我們對於每個參數都是設置相同的學習率η\eta。而Adagrad是對每個參數θi\theta_i在每個時間點tt都採用不同的學習率。爲了簡潔起見,gt,ig_{t,i}是損失函數對於參數θi\theta_itt時刻的梯度。
gt,i=θJ(θi)g_{t,i}=\nabla_{\theta} J(\theta_i) θt+1=θtηgt,i\theta_{t+1}=\theta_t-\eta \cdot g_{t,i}

  對於Adagrad來說,對於θi\theta_i在某個時間點進行更新,它還會基於過去梯度的歷史來計算:
θt+1=θtηGt,ii+ϵgt,i\theta_{t+1}=\theta_t - \frac{\eta}{\sqrt {G_{t,ii} + \epsilon}} \cdot g_{t,i}

  GtRd×dG_t \in R^{d \times d}是一個對角矩陣,其中每個對角線元素爲梯度的平方和,非對角線元素爲0。ϵ\epsilon是平滑項,避免分母爲0(通常是在1e-8的數量級). 。

  由於GtG_t爲對角矩陣,非對角元素均爲0,我們可以通過逐元素矩陣-向量乘法來進行計算:
θt+1=θtηGt+ϵgt\theta_{t+1} = \theta_{t} - \frac{\eta}{\sqrt{G_t+ \epsilon}} \odot g_t

  Adagrad的主要優點是不需要手動調整學習率,默認η\eta可以選爲0.01。Adagrad的主要缺點是分母中一直在積累平方和,所以分母一直在增加,就會導致學習率變小。最終學習率可能會變得無限小。下列算法會解決該缺陷。

6.4 Adadelta

  Adadelta是Adagrad的延伸,目的是爲了減少它單調遞減的學習率。Adagrad是對所有梯度的平方和進行累加,而Adadelta是對固定窗口w的梯度進行累加(使用移動平均來代替累加)。

  Adadelta不是低效率的對之前梯度的平方進行存儲,而是進行遞歸計算,計算公式如下所示:
E[g2]t=γE[g2]t1+(1γ)gt2E[g^2]_t = \gamma E[g^2]_{t-1} + (1 - \gamma)g^2_t

θt+1=θt+Δθt\theta_{t+1}=\theta_{t} + \Delta \theta_{t}
  最原始的SGD的參數變化量爲:
Δθt=ηgt,i\Delta \theta_t = - \eta \cdot g_{t,i}
  Adagrad的參數參數變量爲:
Δθt=ηGt+ϵgt\Delta \theta_t = - \frac{\eta}{\sqrt{G_t + \epsilon}} \odot g_t
  Adadelta的參數參數變量爲:
Δθt=ηE[g2]t+ϵgt\Delta \theta_t = - \frac{\eta}{\sqrt{E[g^2]_t + \epsilon}} g_t
  使用RMS來替換,則Adadelta如下所示:
Δθt=ηRMS[g]tgt\Delta \theta_t = - \frac{\eta}{RMS[g]_t} g_t
  但如果從量綱來講,Δθt\Delta \theta_t是一個無量綱的。而θt+1=θt+Δθt\theta_{t+1}=\theta_{t}+\Delta \theta_t,所以這就會有問題。

6.6 Adam

  Adam本質上是綜合了動量法和Adadelta的優點。

7. 結論

  在這篇文章中,我們初步瞭解了梯度下降的三種變體,其中小批量梯度下降是最受歡迎的。然後,我們介紹了SGD的一些優化算法,如Momentum, Nesterov accelerated gradient, Adagrad, Adadelta, RMSprop, Adam,以及優化異步SGD的一些算法。最終,我們構建了一些策略去改進SGD,例如shuffling(打亂順序)、curriculum learning, batch normalization, and early stopping(早停)。

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