【譯】梯度下降優(yōu)化算法概覽(gradient descent optimization algorithms)

之前一直想總結(jié)一下深度學習中常用的梯度下降算法的,后來發(fā)現(xiàn)有人做了,那好吧,直接翻譯吧。

一、變量的更新方法

1.1 Batch gradient descent

這種變量的更新方法是利用整個數(shù)據(jù)集的數(shù)據(jù),也就是一個batch來計算出損失函數(shù)的梯度,進而來更新網(wǎng)絡(luò)中的參數(shù)\theta,公式如下:
\theta = \theta -\eta\cdot\nabla_{\theta}J(\theta)
因為這種更新方法,我們更新一次參數(shù)需要對整個數(shù)據(jù)集進行計算,所以更新一次參數(shù)的速度很慢。而且這種方式也不允許我們進行線上更新,比如隨時有新的圖片輸入的情況。

這種batch的梯度下降更新方式的偽代碼如下所示:

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

上面表示的過程是對于預先定義的迭代次數(shù)nb_epochs,先通過損失函數(shù)和整個數(shù)據(jù)集計算出各個參數(shù)的梯度值,然后利用所得的梯度和預定義學習率更新參數(shù)。batch gradient descent能保證在凸損失函數(shù)曲面取得全局最優(yōu)解,對于非凸曲面能取得局部最優(yōu)解。

1.2 Stochastic gradient descent

這個方法叫做隨機梯度下降,簡稱SGD。該方法是為一個樣例(樣例包含訓練樣本x^{(i)}和標注y^{(i)})來更新一次參數(shù),如下式所示:
\theta = \theta -\eta\cdot\nabla_{\theta}J(\theta; x^{(i)}, y^{(i)})
因為該更新方法是對每一個樣例而言的,所以參數(shù)更新比Batch的方式快。但這種方式可能會導致參數(shù)更新波動較大,如下圖所示。

1.png

相對于Batch方式,SGD的更新方式,波動大可能能使得梯度下降到更好的另一個局部最優(yōu)解,但另一方面來講,SGD的更新可能導致梯度一直在局部最優(yōu)解附近波動。然而,訓練時不斷的緩慢減小學習率,SGD能和Batch方法一樣,在凸損失函數(shù)曲面取得全局最優(yōu)解,對于非凸曲面能取得局部最優(yōu)解。

SGD的偽代碼如下所示:

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
1.3 Mini-batch gradient descent

這種更新方式是目前用的最多的一種更新方式,如下式所示:
\theta = \theta -\eta\cdot\nabla_{\theta}J(\theta; x^{(i:i+n)}, y^{(i:i+n)})
這種方式有兩個優(yōu)點:
a) 相對于SGD來說可以減小參數(shù)更新的波動
b) 能夠利用矩陣操作,來提高參數(shù)的更新效率
一般minibatch的值在50~256之間選擇,不同的應(yīng)用選擇不同,這個也是一個超參數(shù)。

Mini-batch gradient descent的偽代碼如下所示:
for i in range(nb_epochs):
np.random.shuffle(data)
for batch in get_batches(data, batch_size):
params_grad = evaluate_gradient(loss_function, batch, params)
params = params - learning_rate * params_grad

二、挑戰(zhàn)

上述的方法不一定能保證好的收斂性,而且還有下面一些挑戰(zhàn):

  1. learning rate這個超參數(shù)不好選擇。太小收斂速度慢,太大容易在局部最優(yōu)附近波動。
  2. learning rate的變化規(guī)則不好定。預先定好的規(guī)則不能很好的適應(yīng)數(shù)據(jù)集的特征。
  3. 同一個learning rate對所有的參數(shù)進行更新。不同的參數(shù)可能需要更新的步長不一致,但是上述方法都是按照相同的步長更新。
  4. 對于非凸損失函數(shù),參數(shù)的更新不能很好的使得梯度更新跳出高緯函數(shù)的多個局部最優(yōu),甚至是遇到某些鞍點(可以想象一個馬鞍的形狀,一個緯度坡度是上升的,其他的坡度是下降的)的區(qū)域,不能很快的跳出鞍點。

三、梯度下降優(yōu)化算法

為了解決上述一些問題,下面介紹一些常用的優(yōu)化算法。

3.1 Momentum

SGD容易在一些類似于溝壑的曲面上震蕩,可以想象一個小球在一個溝上滑動,這個溝壑一個緯度比其他緯度更陡,SGD更新方法在更陡的坡上震蕩較大,導致算法更新到達局部最優(yōu)的時間較長。為了解決這種問題,Momentum梯度優(yōu)化算法提出來了,可以想象在坡度更不陡的方向上給小球加上一個動量,使得小球更快的跑到局部最優(yōu)點。如下圖所示


2.png

Momentum是SGD的一種改進方法,該算法新增一個\gamma的超參數(shù),根據(jù)以前的動量和新的梯度來計算新的動量,公式如下所示:
v_t = \gamma v_{t-1} + \eta\cdot\nabla_{\theta}J(\theta)
\theta = \theta -v_t
通常\gamma設(shè)置為0.9左右的數(shù)值。
類似與一個球從u形山谷形狀的坡度滾下,它向最低點方向的速度是越來越快的,上述中的參數(shù)v_t就會使得同一個方向的梯度疊加,不斷變化方向的梯度會相互抵消,所以可以使得梯度可以更快的收斂。

3.2 Nesterov accelerated gradient

假象一個球讓它沒有指導的自由的沿著山坡滾到山谷,這樣做法非常的不安全。我們希望有一個更為聰明的小球,當它快要滾到山谷的時候,它速度減慢。

Nesterov accelerated gradient下面簡稱NAG就是這樣一種梯度更新算法。在上述的momentum算法中,我們會使用\gamma v_{t-1}來更新參數(shù),這樣就可以得到新的參數(shù)位置\theta-\gamma v_{t-1}。下面我們可以通過即將得到的新參數(shù)位置先一步的得到我們要更新的參數(shù)大小,如下式所示:
v_t=\gamma v_{t-1}+\eta\nabla_{\theta}J(\theta-\gamma v_{t-1})
\theta=\theta-v_t
如下圖所示,假設(shè)我們設(shè)\gamma為0.9。對于momentum來說,優(yōu)化器先計算出參數(shù)的梯度,如圖中的短藍線所示,然后momentum要更新的動量為圖中的長藍線。對于NAG來說,先計算出梯度,然后指導帶更新的動量大小如下圖的長灰線所示,根據(jù)所得的灰線再計算要修改真正要更新動量的大小和方向,最后得到長的綠色線。通過這種更新方式可以防止參數(shù)更新過快的問題,這種算法對RNNs來說有較好的效果。

3.png

3.3 Adagrad

Adagrad是這樣的一種更新算法,它對于不同的參數(shù)有不同的更新參數(shù),對于頻繁更新參數(shù)采用小的更新值,不頻繁的更新參數(shù)采用較大的更新值進行更新。

之前所提到的算法,對于所有參數(shù)\theta中的每個參數(shù)\theta_i來說,使用的都是相同的學習率\eta來更新的。而Adagrad優(yōu)化算法,對于t時刻,每個參數(shù)\theta_i使用的學習率是不同的。為了方便理解,對于每個參數(shù)\theta_i來解釋一下它的原理。下面規(guī)定使用符號g_{t,i}來表示目標函數(shù)對于在t時刻,參數(shù)\theta_i的梯度值。
g_{t,i}=\nabla_{\theta_t}J_{\theta_{t,i}}
對于SGD來說,在在t時刻,參數(shù)\theta_i的更新方式如下:
\theta_{t+1,i}={\theta_{t,i}}-\eta\cdot g_{t,i}
而Adagrad在t時刻對\theta_i參數(shù)的更新值是更新\theta_i過去的梯度來求得的:
\theta_{t+1,i}={\theta_{t,i}}-\frac{\eta}{\sqrt{G_{t,ii}+\epsilon}}\cdot g_{t,i}
上式中G\in R^{d\times d},是一個對角矩陣,該矩陣中每個對角線上的元素(i,i)為過去0-t時刻參數(shù)\theta_i梯度的平方和。\epsilon是為了防止除零設(shè)置的一個參數(shù),一般設(shè)置為1e-8。這個算法還有個有趣的事情,公式中不加入平方根,會導致算法效果不好。
因為G_t包含了過去的梯度值的平方,對于所有參數(shù)來說,上述公式可以寫成矩陣的形式:
\theta_{t+1}={\theta_{t}}-\frac{\eta}{\sqrt{G_{t}+\epsilon}}\odot g_{t}
\odot表示矩陣元素間相乘。

使用Adagrad算法的一個好處就是可以不用手動調(diào)節(jié)訓練率,一般\eta默認設(shè)置為0.01。
而它也有不太好的地方,因為該算法不斷的在分母加過去的梯度平方值,導致隨著訓練次數(shù)的增加,訓練的步長越來越小,可能最后模型還沒收斂,參數(shù)確不怎么更新了。

3.4 Adadelta

Adadelta是Adagrad的升級版,它的提出是為了解決Adagrad梯度不停減小的問題。
Adadelta采用的不是將過去所有的梯度平方相加,而是引入了指數(shù)平均來做的。
E[g^2]_t=\gamma E[g^2]_{t-1}+(1-\gamma)g^2_{t}
這里\gamma和momentum里設(shè)置的一樣,為0.9。

下面為了更好理解,先把SGD公式抄過來
\Delta\theta_{t}=-\eta\cdot g_{t,i}
\theta_{t+1}=\theta_t+\Delta\theta_{t}
對于Adagrad來說是過去所有梯度平方和
\Delta\theta_{t}=-\frac{\eta}{\sqrt{G_{t}+\epsilon}}\odot g_{t}
現(xiàn)在將分母替換為指數(shù)平均數(shù)得到下式
\Delta\theta_{t}=-\frac{\eta}{\sqrt{E[g^2]+\epsilon}}g_{t}
上式中因為分母為梯度的均方根形式,所以可以簡寫為
\Delta\theta_{t}=-\frac{\eta}{RME[g]_t}g_{t}

Adadelta作者發(fā)現(xiàn)上式的更新(也包括SGD,momentum,Adagrad)中,\Delta值和待更新的參數(shù)假設(shè)的單位(hypothetical units)不同(這里的單位是假設(shè)的,如果有單位的話,adagrad的更新參數(shù)的單位分子和分母抵消了),為了解決這個問題,文章又引入下面一個指數(shù)平均:
E[\Delta \theta^2]_t=\gamma E[\Delta\theta^2]_{t-1}+(1-\gamma)\Delta\theta^2_{t}
上式的均方根誤差的形式如下
RMS[\Delta\theta]_t=\sqrt{E[\Delta\theta^2]_t+\epsilon}
因為在求\Delta\theta_t時,RMS[\Delta\theta]_t還沒求出來,所以使用\Delta\theta_{t-1}作為代替,參數(shù)的更新規(guī)則如下:
\Delta\theta_{t}=-\frac{RME[\Delta\theta]_{t-1}}{RME[g]_t}g_{t}
\theta_{t+1}=\theta_t+\Delta\theta_{t}
從上面公式可以看出,使用Adadelta不需要設(shè)置學習率。

3.5 RMSProp

RMSProp通過文章而公布的一個算法,它是在Geoff Hinton課堂上提出的算法。

和Adadelta一樣,RMSProp也是Adagrad一個改進版本,只是它和Adadelta是獨立提出來的。它的公式其實上面已經(jīng)介紹過了,下面再抄一遍:
E[g^2]_t=\gamma E[g^2]_{t-1}+(1-\gamma)g^2_{t}
\theta_{t+1}=\theta_t-\frac{\eta}{\sqrt{E[g^2]+\epsilon}}g_{t}
一般的\gamma設(shè)置為0.9,\eta設(shè)置為0.001。

3.6 Adam

Adam全稱Adaptive Moment Estimation,Adam不僅像Adadelta和RMSprop一樣計算過去梯度平方的指數(shù)平均值v_t,還會計算過去梯度的指數(shù)平均值m_t。
m_t=\beta_1 m_{t-1}+(1-\beta_1)g_t
v_t=\beta_2 v_{t-1}+(1-\beta_2)g^2_t
從上式可以看出,當m_tv_t初始化為0,且在\beta_1\beta_2值接近1的情況下,這兩個指數(shù)平均值一直在0附近。
Adam為了消除這種影響,使用下面兩式來代替上述兩個momentum:
\hat{m_t}=\frac{m_t}{1-\beta^t_1}
\hat{v_t}=\frac{v_t}{1-\beta^t_2}
然后類似與Adadelta和RMSprop,Adam參數(shù)更新算法如下所示:
\theta_{t+1}=\theta_t-\frac{\eta}{\sqrt{\hat v_t}+\epsilon}\hat m_t
通常,上式中\beta_1設(shè)為0.9,\beta_2設(shè)為0.999,\epsilon設(shè)為10^{-8}

3.7 AdaMax

不同于Adam,在計算v_t時使用的是過去的梯度平方也就是l_2 norm,更為廣義的可以計算過去梯度的l_p norm。
v_t=\beta^p_2 v_{t-1}+(1-\beta^p_2)|g_t|^p

AdaMax就是將之前的1范數(shù)和2范數(shù)替換成了無窮范數(shù),下面為了防止符號與之前的符號混淆,使用u_t代替v_t:
u_t=\beta^{\infty}_2 u_{t-1}+(1-\beta^{\infty}_2)|g_t|^{\infty}\\=max(\beta_2\cdot u_{t-1}, |g_t|)
于是,AdaMax的參數(shù)更新規(guī)則為
\theta_{t+1}=\theta_t-\frac{\eta}{u_t}\hat{m_t}
通常,\eta設(shè)為0.002,\beta_1設(shè)為0.9,\beta_2設(shè)為0.999。

4.8 Nadam

因為Adam優(yōu)化器可以看作RMSprop與momentum的結(jié)合,而NAG又是來源于原始的momentum,那Nadam可以看作是將NAG和Adam結(jié)合的一個算法。

為了使公式能和Adam統(tǒng)一,下面momentum項用m_t表示。下面先來用新的符號重寫一下momentum算法:
g_t=\nabla\theta_t J(\theta_t)
m_t = \gamma m_{t-1}+\eta g_t
\theta_{t+1}=\theta_t-m_t
將上面三個式子合并得
\theta_{t+1}=\theta_t-(\gamma m_{t-1}+\eta g_t)
而NAG算法可以表示如下:
g_t=\nabla\theta_t J(\theta_t-\gamma m_{t-1})
m_t = \gamma m_{t-1}+\eta g_t
\theta_{t+1}=\theta_t-m_t
下面Dozat提出將NAG做一些修改,不同于原來的NAG算法,先更新梯度,然后更新參數(shù)。這里直接通過look-ahead momentum直接更新參數(shù):
g_t=\nabla\theta_t J(\theta_t)
m_t = \gamma m_{t-1}+\eta g_t
\theta_{t+1}=\theta_t-(\gamma m_t+\eta g_t)
從上式可以看出,不同于以往是通過m_{t-1}來更新參數(shù),這里是使用m_{t}來更新參數(shù)。

為了將NAG應(yīng)用到Adam中,先抄寫Adam公式:
m_t=\beta_1 m_{t-1}+(1-\beta_1)g_t
v_t=\beta_2 v_{t-1}+(1-\beta_2)g^2_t
\hat{m_t}=\frac{m_t}{1-\beta^t_1}
\hat{v_t}=\frac{v_t}{1-\beta^t_2}
\theta_{t+1}=\theta_t-\frac{\eta}{\sqrt{\hat v_t}+\epsilon}\hat m_t
\hat m_t展開得到下式:
\theta_{t+1}=\theta_t-\frac{\eta}{\sqrt{\hat v_t}+\epsilon}(\frac{\beta_1m_{t-1}}{1-\beta^t_1}+\frac{(1-\beta_1)g_t}{1-\beta^t_1})
上式又可寫為:
\theta_{t+1}=\theta_t-\frac{\eta}{\sqrt{\hat v_t}+\epsilon}(\beta_1\hat{m}_{t-1}+\frac{(1-\beta_1)g_t}{1-\beta^t_1})
這個式子與上面寫的momentum式子很像,類似于將momentum做一個NAG的優(yōu)化,得到Nadam。
\theta_{t+1}=\theta_t-\frac{\eta}{\sqrt{\hat v_t}+\epsilon}(\beta_1\hat{m}_t+\frac{(1-\beta_1)g_t}{1-\beta^t_1})

參考

  1. An overview of gradient descent optimization algorithms
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容