三種梯度下降算法的比較和幾種優化算法

前言

這篇文章介紹了三種梯度下降方法的原理與優缺點,詳細地講解了MomentumRMSpropAdam優化算法,給出了使用建議。


三種梯度下降方法

1.Batch Gradient Descent,全部樣本梯度下降一次,訓練樣本很大時,單次迭代需要時間太長。

2.Stochastic Gradient Descent,單個樣本梯度下降一次,沒有了向量化加速,效率比Batch Gradient Descent低,到達loss最低區域後還可能會跳出來,當然這也可以使它從局部最小值區域跳出來,可以使用學習率衰減來緩解這個問題。

3.Mini-batch Gradient Descent,部分樣本梯度下降一次,上兩個方法的折中,它可能不會收斂也可能不會在很小的範圍內波動(同樣可以用學習率衰減的方法來緩解這個問題)。

下面是loss的梯度圖,三條線是三種梯度下降方法每下降一次的路線,藍色是Batch Gradient Descent,紫色是Stochastic Gradient Descent,綠色是Mini-batch Gradient Descent

進階理解:
相對於GD,SGD能更有效的利用信息,特別是信息比較冗餘的時候。舉個例子,比如所有樣本都需要向一個方向優化,GD優化一次需要對整個樣本集迭代一次,而SGD只對一個樣本優化就可以達到同樣的效果。SGD相對於GD的另外一個優點是可以跳出局部最小值區域。
而mini-batch GD綜合了兩者的優點,既有了GD的向量化加速,還能像SGD更有效利用樣本信息、可以跳出局部最小值區域的優點。另外,使用mini-batch,你還會發現不需要等待整個訓練集被處理完就可以開始進行後續工作。

下面總結一下mini-batch的優點:
1.有向量化加速,加快了訓練速度。
2.能有效利用樣本信息,特別是信息比較冗餘的時候。
3.有隨機性,可以跳出局部最小值區域。
4.不需要等待整個訓練集被處理完就可以開始進行後續工作。

下面是mini-batch的僞代碼,中括號上標代表層數:
nmini batchfor   t=1,...n::{a[1]=g(W[1]Xt+b[1])a[2]=g(W[2]Xt+b[2])            ...a[l]=g(W[l]Xt+b[l])loss:L=1ni=1lL(y^[i],y[i]):{dwdbW[l]=W[l]αdW[l]b[l]=b[l]αdb[l] \begin{aligned} 將樣本分爲n個mini \ batch\\ for \ \ \ t=1,...n:\\ &前向傳播:\\ &\begin{cases} a^{[1]} = g(W^{[1]}X_t+b^{[1]})\\ a^{[2]} = g(W^{[2]}X_t+b^{[2]})\\ \ \ \ \ \ \ \ \ \ \ \ \ ...\\ a^{[l]} = g(W^{[l]}X_t+b^{[l]})\\ \end{cases}\\ &計算loss: L_總 = \frac{1}{n} \sum^l_{i=1}L(\hat{y}^{[i]},y^{[i]}) \\ &反向傳播:\\ &\begin{cases} 計算各層梯度 dw和db \\ W^{[l]}=W^{[l]}-\alpha dW^{[l]} \\ b^{[l]}=b^{[l]}-\alpha db^{[l]} \\ \end{cases}\\ \end{aligned}

用法總結

首先,如果訓練集較小,直接使用Batch Gradient Descent梯度下降法,樣本集較小就沒必要使用mini-batch梯度下降法,這裏的少是說小於差不多2000個樣本,這樣比較適合使用Batch Gradient Descent梯度下降法。

樣本數目較大的話,一般的mini-batch大小爲64到512,考慮到電腦內存設置和使用的方式,如果mini-batch大小是2的次方,代碼會運行地快一些。64到512的mini-batch比較常見。


下面講幾種常見的梯度下降優化算法:

動量梯度下降法(Momentum)

Gradient descent with Momentum,這個梯度下降方法,基本的想法就是計算梯度的指數加權平均數,並利用它更新權重。直觀來講,就是給普通的梯度下降加了個“慣性”,就像開車,你不能開着開着想往右拐就瞬間拐到右邊,它有個向前再往右的過程,換言之,你想改變行駛方向,是需要從之前的行駛方向慢慢改變的,並不能瞬間改變。同理,Momentum梯度下降也一樣,比如這次迭代算出來你需要向a方向優化,但你並不能直接將你的方向改成a,需要綜合考慮之前的方向。
下圖左邊是普通隨機梯度下降,右邊是Momentum隨機梯度下降,可以看出後者加快了優化速度,抑制了震盪。

因爲mini-batch相比標準的梯度下降來說,更新參數更快,所以收斂過程會有浮動(loss下降曲線),使用動量梯度下降法可以減小該浮動,還能加速訓練。

看下mini-batch GD with Momentum的公式:

vdWvdbdWdb0nmini batchfor   t=1,...n:{a[1]=g(W[1]Xt+b[1])a[2]=g(W[2]Xt+b[2])            ...a[l]=g(W[l]Xt+b[l])loss:L=1ni=1lL(y^[i],y[i]):{dwdbvdW[l]=βvdW[l]+(1β)dW[l]vdb[l]=βvdb[l]+(1β)db[l]W[l]=W[l]αvdW[l]W[l]=b[l]αvdb[l] \begin{aligned} {\color{Red}{初始化每層的v_{dW}、v_{db},}}&{\color{Red}{形狀和dW、db一致,元素全爲0}}\\ 將樣本分爲n個mini \ batch\\ for \ \ \ t=1,...n:\\ &前向傳播:\\ &\begin{cases} a^{[1]} = g(W^{[1]}X_t+b^{[1]})\\ a^{[2]} = g(W^{[2]}X_t+b^{[2]})\\ \ \ \ \ \ \ \ \ \ \ \ \ ...\\ a^{[l]} = g(W^{[l]}X_t+b^{[l]})\\ \end{cases}\\ &計算loss: L_總 = \frac{1}{n} \sum^l_{i=1}L(\hat{y}^{[i]},y^{[i]}) \\ &反向傳播:\\ &\begin{cases} 計算各層梯度 dw和db \\ {\color{Red}{v_{dW^{[l]}} = \beta v_{dW^{[l]}} + (1 - \beta) dW^{[l]}}} \\ \\ {\color{Red}{v_{db^{[l]}} = \beta v_{db^{[l]}} + (1 - \beta) db^{[l]}}} \\ \\ W^{[l]} = W^{[l]} - \alpha {\color{Red}{v_{dW^{[l]}}}} \\ \\ W^{[l]} = b^{[l]} - \alpha {\color{Red}{v_{db^{[l]}}}} \\ \end{cases}\\ \end{aligned}

β\beta越大,收斂過程越平滑,一般取值爲0.8~0.999,0.9會是一個不錯的選擇。

RMSprop

RMSprop的算法,全稱是root mean square prop算法,它也可以加速收斂,我們來看看它是如何運作的。

sdWsdbdWdb0nmini batchfor   t=1,...,n:{a[1]=g(W[1]Xt+b[1])a[2]=g(W[2]Xt+b[2])            ...a[l]=g(W[l]Xt+b[l])loss:L=1ni=1lL(y^[i],y[i]):{dwdbsdW[l]=βsdW[l]+(1β)(dW[l])2sdb[l]=βsdb[l]+(1β)(db[l])2W[l]=W[l]αsdW+εdW[l]b[l]=b[l]αsdb+εdb[l] \begin{aligned} {\color{Red}{初始化每層的s_{dW}、s_{db},}}&{\color{Red}{形狀和dW、db一致,元素全爲0}}\\ 將樣本分爲n個mini \ batch\\ for \ \ \ t=1,...,n:\\ &前向傳播:\\ &\begin{cases} a^{[1]} = g(W^{[1]}X_t+b^{[1]})\\ a^{[2]} = g(W^{[2]}X_t+b^{[2]})\\ \ \ \ \ \ \ \ \ \ \ \ \ ...\\ a^{[l]} = g(W^{[l]}X_t+b^{[l]})\\ \end{cases}\\ &計算總loss: L_總 = \frac{1}{n} \sum^l_{i=1}L(\hat{y}^{[i]},y^{[i]}) \\ &反向傳播:\\ &\begin{cases} 計算各層梯度 dw和db \\ {\color{Red}{s_{dW^{[l]}} = \beta s_{dW^{[l]}} + (1 - \beta) (dW^{[l]})^2}} \\ \\ {\color{Red}{s_{db^{[l]}} = \beta s_{db^{[l]}} + (1 - \beta) (db^{[l]})^2}} \\ \\ W^{[l]} = W^{[l]} - {\color{Red}{\frac{\alpha}{\sqrt{s_{dW} +\varepsilon}}}}dW^{[l]} \\ \\ b^{[l]} = b^{[l]} - {\color{Red}{\frac{\alpha}{\sqrt{s_{db} +\varepsilon}}}}db^{[l]} \\ \end{cases}\\ \end{aligned}

ε\varepsilon是一個很小的數,使後兩個式子無論如何都不會除以一個接近於零的數,一般 ε=108\varepsilon = 10^{-8}

原理:參數更新時 αsdW+ε{\color{Red}{\frac{\alpha}{\sqrt{s_{dW} +\varepsilon}}}} 的作用是使梯度大的參數不要更新地太猛。因爲梯度dWdW越大,sdWs_{dW}就越大,而αsdW+ε{\color{Red}{\frac{\alpha}{\sqrt{s_{dW} +\varepsilon}}}}就越小,參數更新的幅度就越小。至於爲什麼使用平方指數加權平均,可能是因爲想要先平方再開方來取絕對值?有懂的大佬請不吝賜教。
總而言之,RMSprop使得梯度大的參數更新幅度不那麼大,很大程度上緩解了梯度下降震盪的問題,如下圖所示,藍線代表普通梯度下降,綠線代表RMSprop。

爲何不把Momentum和RMSprop結合在一起用呢?那就有了Adam。

Adam

Adam 優化算法(Adam optimization algorithm),基本上就是將MomentumRMSprop結合在一起,那麼來看看如何使用Adam算法。

vdWvdbsdWsdbdWdb0nmini batchfor   t=1,...,n:{a[1]=g(W[1]Xt+b[1])a[2]=g(W[2]Xt+b[2])            ...a[l]=g(W[l]Xt+b[l])loss:L=1ni=1lL(y^[i],y[i]):{dw(db)v^dW[l]=β1v^dW[l]+(1β1)dW[l]s^dW[l]=β2s^dW[l]+(1β2)(dW[l])2vdW[l]=v^dW[l]1(β1)tsdW[l]=s^dW[l]1(β2)tW[l]=W[l]αvdW[l]sdW[l]+ε \begin{aligned} {\color{Red}{初始化每層的v_{dW}、v_{db}、s_{dW}、s_{db},}}&{\color{Red}{形狀和dW、db一致,元素全爲0}}\\ 將樣本分爲n個mini \ batch\\ for \ \ \ t=1,...,n:\\ &前向傳播:\\ &\begin{cases} a^{[1]} = g(W^{[1]}X_t+b^{[1]})\\ a^{[2]} = g(W^{[2]}X_t+b^{[2]})\\ \ \ \ \ \ \ \ \ \ \ \ \ ...\\ a^{[l]} = g(W^{[l]}X_t+b^{[l]})\\ \end{cases}\\ &計算總loss: L_總 = \frac{1}{n} \sum^l_{i=1}L(\hat{y}^{[i]},y^{[i]}) \\ &反向傳播:\\ &\begin{cases} 計算各層梯度 dw (db同理) \\ {\color{Red}{\hat{v}_{dW^{[l]}} = \beta_1 \hat{v}_{dW^{[l]}} + (1 - \beta_1) dW^{[l]}}} \\ \\ {\color{Red}{\hat{s}_{dW^{[l]}} = \beta_2 \hat{s}_{dW^{[l]}} + (1 - \beta_2) (dW^{[l]})^2}} \\ \\ {\color{Red}{v_{dW^{[l]}} = \frac{\hat{v}_{dW^{[l]}}}{1 - (\beta_1)^t}}} \\ \\ {\color{Red}{s_{dW^{[l]}} = \frac{\hat{s}_{dW^{[l]}}}{1 - (\beta_2)^t}}} \\ \\ W^{[l]} = W^{[l]} - \alpha {\color{Red}{\frac{v_{dW^{[l]}}}{\sqrt{s_{dW^{[l]}}} + \varepsilon}}} \\ \end{cases}\\ \end{aligned}

  • tt 表示Adam的步數
  • ll 神經網絡當前所在的層
  • β1\beta_1 一般爲0.90.9β2\beta_2 一般爲0.990.99
  • α\alpha 是 learning rate
  • ε\varepsilon 是一個很小的數,防止除數爲0,一般爲10810^{-8}

看一下反向傳播中紅色公式,前兩個式子分別是MomentumRMSprop

至於第三和第四個式子,是爲了使各個梯度的權值之和爲1。以Momentum的式子爲例,設定β1=0.9\beta_1=0.9

t=1和t=2時:
v^dW[1]=0.1dW[1]vdW[1]=0.1dW[1]10.91=dW[1]v^dW[2]=0.09dW[1]+0.1dW[2]vdW[2]=0.09dW[1]+0.1dW[2]10.92=0.47dW[1]+0.53dW[2] \begin{aligned} \hat{v}_{dW^{[1]}} &= 0.1dW^{[1]}\\ v_{dW^{[1]}} &= \frac{0.1dW^{[1]}}{1-0.9^1}= {\color{Red}{dW^{[1]}}} \\ \hat{v}_{dW^{[2]}} &= 0.09dW^{[1]}+0.1dW^{[2]}\\ v_{dW^{[2]}} &= \frac{0.09dW^{[1]}+0.1dW^{[2]}}{1-0.9^2} = {\color{Red}{0.47dW^{[1]}+0.53dW^{[2]}}} \\ \end{aligned}

可以看到每一步中所有梯度的權值和都會變成1。

總結

梯度下降除非樣本很少,一般來說都用mini-batch了,梯度下降的優化算法我推薦Adam,不需要花費太多時間來選擇優化算法,效果都差不多,不如花時間去優化模型裏別的超參。
下面貼了兩張比較各個優化算法的動圖,很直觀。動圖來自這篇博客:An overview of gradient descent optimization algorithms


References:

[1] Ruder (2017) An overview of gradient descent optimization algorithms
[2] Bottou et.al(2018) Optimization Methods for Large-Scale Machine Learning
[3] D. Lee et.al (2016) Gradient Descent Only Converges to Minimizers
[4] http://zh.gluon.ai/chapter_optimization/adam.html

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