梯度下降及其優化演算法

本文主要參考An overview of gradient descent optimization algorithms和其中文翻譯博客。

這篇文章首先介紹了梯度下降的三個框架,全量梯度下降(Batch gradient descent),隨機梯度下降(Stochastic gradient descent)以及批量梯度下降(Mini-batch gradient descent)。我們最常用的框架當屬批量梯度下降了,相對於隨機梯度下降,它降低了收斂波動性,即降低了參數更新的方差,使得更新更加穩定;相對於全量梯度下降,其提高了每次學習的速度,並且其不用擔心內存瓶頸從而可以利用矩陣運算進行高效計算。由此帶來的batch size的大小是個需要根據不同的實驗任務靈活調整的超參數,在更新速度與更次次數中進行折中。

最普通的梯度下降演算法是最速梯度下降法,通過沿著目標函數J(	heta)的梯度(一階導數)相反方向-	riangledown_{	heta}J(	heta)來不斷更新模型參數來到達目標函數的極小值點(收斂):

	heta = 	heta - eta ullet  	riangledown_{	heta}J(	heta)

其中,每次更新的步長eta 是非常重要的超參數。

梯度下降演算法得到了廣泛的應用,但是仍然存在一些問題有待解決:

  1. 首先,選擇一個合理的學習速率很難,學習速率過小則會導致收斂很慢,但是如果學習速率過大,又會導致極值點附近的震蕩,阻礙收斂。
  2. 學習速率調整(又稱學習速率調度,Learning rate schedules)。一般使用某種事先設定的策略或者在每次迭代中衰減一個較小的閾值,例如退火演算法。但是這些基於人工先驗的演算法都是基於經驗,無法根據具體問題的特點進行自適應的調整。
  3. 對不同的參數使用不同的學習速率。如果數據特徵是稀疏的或者每個特徵有著不同的取值統計特徵與空間,那麼便不能在每次更新中每個參數使用相同的學習速率,那些很少出現的特徵應該使用一個相對較大的學習速率,例如訓練詞向量時。
  4. 對於非凸目標函數,容易陷入那些次優的局部極值點中;以及比局部極值點更經常出現也更難解決的鞍點問題。

針對學習速率的自適應調整以及局部極值的問題,下邊討論一些常用的優化演算法:

1,動量(Momentum)

動量的出現主要是為了解決兩個問題,海森矩陣的不良條件數和隨機梯度的方差。這兩個問題會導致梯度步驟在目標函數到達「峽谷地帶」時的震蕩,阻礙收斂。我們引入變數v充當速度的角色,代表參數在參數空間移動的方向和速度(假設參數為單位質量,則其可看作參數的動量),即可解決這一震蕩問題,加快收斂。

v_t = gamma v_{t-1} +  eta ullet  	riangledown_{	heta}J(	heta)

	heta = 	heta - v_t

在實踐中,gamma的一般取值為0.5,0,9和0.99。和學習速率一樣,它也會隨著時間變化,一般初始值是一個比較小的值,隨後慢慢變大。

2, Nesterov accelerated gradient(NAG)

不僅增加了動量項,並且在計算梯度時,使用了根據動量項預先估計的參數,在Momentum的基礎上進一步加快收斂,提高響應性。

v_t = gamma v_{t-1} +  eta ullet  	riangledown_{	heta}J(	heta - gamma v_{t-1})

	heta = 	heta - v_t

以上兩種方法在每次學習過程中根據損失函數的斜率做到自適應更新來加速收斂。

下邊介紹根據不同參數的特性自適應調整其學習速率。

3,Adagrad

自適應地獨立地調整不同參數的學習速率,放縮每個參數反比於其所有梯度歷史平方值總和的平方根。對稀疏特徵,得到大的學習更新,對非稀疏特徵,得到較小的學習更新,因此該優化演算法適合處理稀疏特徵數據。Dean等[4]發現Adagrad能夠很好的提高SGD的魯棒性,google用其來訓練大規模神經網路(看片識貓:recognize cats in Youtube videos)。Pennington等[5]在GloVe中便使用Adagrad來訓練得到詞向量(Word Embeddings), 頻繁出現的單詞賦予較小的更新,不經常出現的單詞則賦予較大的更新。

Adagrad在每一個更新步驟t中對於每一個模型參數	heta_i使用不同的學習速率eta_i.設第t次更新步驟中,目標函數的參數	heta_i梯度為g_{t,i},即:

g_{t,i} = 	riangledown_	heta J(	heta_i)

	heta_{t+1,i} = 	heta_{t,i} - frac{eta}{sqrt{G_{t,ii}+epsilon}}ullet g_{t,i}

G_t in Re ^ {d 	imes d}是一個對角矩陣,其中第i行的對角元素e_{ii}為過去到當前第i個參數	heta_i的梯度的平方和;epsilon是一個平滑參數,為了使得分母不為0(通常epsilon取e?8)。另外如果分母不開根號,演算法性能會很糟糕。

再進一步,將所有G_{t,ii},g_{t,i}的元素寫成向量G_t,g_t,可以將更新公式寫成點乘操作:

	heta_{t+1} = 	heta_{t} - frac{eta}{sqrt{G_{t}+epsilon}} odot  g_{t}

由上可見,Adagrad 的優勢是它能夠為每個參數自適應不同的學習速率,同時其缺點在於需要計算參數梯度序列的平方和,並且經驗上發現,對於訓練深度神經網路模型,積累梯度平方會導致有效學習速率過早和過量的減小,影響學習的效果。並且,Adagrad仍然依賴於超參數全局學習率eta.

4,RMSProp

針對梯度平方和累計越來越大的問題,RMSProp使用歷史梯度平方的衰減平均值代替梯度平方和。動態平均值E[g^2]_t僅僅取決於當前的梯度值與上一時刻的平均值:

E[g^2]_t = gamma E[g^2]_{t-1} + (1-gamma) g^2_{t}

	heta_{t+1} = 	heta_{t} - frac{eta}{sqrt{E[g^2]_t+epsilon}} odot g_{t,i}

Hinton建議,gamma = 0.9, eta = 0.001,但是還是沒有能夠解決演算法依賴全局學習率的問題,從而誕生了Adadelta。

5,Adadelta

針對梯度平方和累計越來越大的問題,解決方法與RMSProp一致,在此基礎上,Adadelta做了一些擺脫超參eta的工作,具體演算法可查看文獻,比較重要的就是做了海森矩陣的近似。

6,Adam(Adaptive Moment Estimation)

與Adadelta與RMSprop區別在於,它計算歷史梯度衰減方式不同,不使用歷史平方衰減,其衰減方式類似動量,如下:

m_t = eta_1 m_{t-1} + (1-eta_1)g_t

v_t = eta_2v_{t-1} + (1-eta_2)g_t^2

根據每個參數的梯度的一階矩估計m_t和二階矩估計v_t動態調整針對每個參數的學習速率;

Adam的作者發現他們傾向於0向量(接近於0向量),特別是在衰減因子(衰減率)eta_1,eta_2接近於1時。為了改進這個問題,對m_tv_t進行偏差修正(bias-corrected):

	ilde{m_t} = frac{m_t}{1-eta_1^t}

	ilde{v_t} = frac{v_t}{1-eta_2^t}

參數更新方程為:

	heta_{t+1} = 	heta_t - frac{eta}{sqrt{	ilde{v_t}}  + epsilon}  	ilde{m_t}

經驗值:eta_1 = 0.9, eta_2 = 0.999, epsilon= 10^{-8}. 一般情況下,Adam的效果要好於其他幾個演算法。

推薦閱讀:

TAG:機器學習 | 深度學習DeepLearning |