1. 程式人生 > >深度學習優化演算法總結

深度學習優化演算法總結

  深度學習優化演算法最耳熟能詳的就是GD(Gradient Descend)梯度下降,然後又有一個所謂的SGD(Stochastic Gradient Descend)隨機梯度下降,其實還是梯度下降,只不過每次更新梯度不用整個訓練集而是訓練集中的隨機樣本。梯度下降的好處就是用到了當前迭代的一些性質,以至於總能較快找到駐點。而像遺傳演算法等智慧優化演算法,則是基於巨大的計算資源上的。它們並不使用函式特性,通常需要“種群”幾乎遍佈整個引數空間才能進行有效的優化,更像是一種暴力搜尋。而因為神經網路引數量太大,幾百萬維的引數量不可能讓種群達到“密佈”(即使每個維度兩個“個體”,種群規模也是2的百萬次冪),所以神經網路優化通常都用基於梯度下降的演算法。

  現在,神經網路優化常用的都是梯度下降演算法的變體,下面介紹Momentum, RMSProp, Adam這三種最常用的。它們都對梯度下降的某些不足做出了改進。

Momentum 

  Momentum是動量的意思。它對每次迭代進行平滑處理,以至於不會像GD一樣,當梯度很大時一下子跳地太遠,在梯度較小時又跳得太少。定義很簡單,就比GD多了一步:

$V_t = \beta V_{t-1} + (1-\beta) \nabla \theta_t$

$\theta_{t+1} = \theta_t - \eta V_t$

  其中$\theta_t$表示第$t$次迭代的引數張量,$\nabla \theta_t$表示關於它的梯度。$\eta$是模型學習率。$\beta$是平滑因子,也就是積累梯度的權重,越大則之前的梯度對當前影響越大,越小則此次迭代的梯度對當前影響越大,而等於0時Momentum就退化成GD了。$V_{t-1}$表示第$t$步迭代以前累積的梯度動量。

  相較GD,加上平滑的概念以後,Momentum會更加註重優化的全域性性,這是因為它每次迭代都取決於之前所有梯度的加權和。拿跑步來舉例,GD的每一步都是當前地面坡度最陡的方向,而Momentum則是添加了慣性,每一步都將跑步速度向坡度最陡的方向調整。

RMSProp

  RMSProp改進了GD的擺動幅度過大的問題,從而加快收斂速度。迭代式如下:

$\begin{gather}S_t = \beta S_{t-1} + (1-\beta)( \nabla \theta_t)^2 \label{}\end{gather}$

$\begin{gather}\displaystyle \theta_{t+1} = \theta_t - \eta \frac{\nabla \theta_t}{\sqrt{S_t}+\varepsilon}||\sqrt{S_t}||\label{}\end{gather}$

  $(1)$式中的$( \nabla \theta_t)^2$和$(2)$式中的分式分別表示按元素進行的平方操作和除法操作。$(2)$式中的$\varepsilon$是為了防止除數為0而設定的較小數,它和張量$S_t$執行的加法就是把它加到$S_t$的每個元素。$||\sqrt{S_t}||$是二範數(我自己加的,為了避免梯度值改變太大,可以無視)。

  按迭代式可以看出,RMSProp對梯度的方向進行了較弱的規範化,讓梯度的每一個元素向單位值1或-1靠近,這樣一來,優化時的擺動幅度就會減小一些。而又為了不至於靠得太近而直接變成全1和-1,用於規範化的是之前梯度平方的累積量而不是直接用當前梯度的平方。當然,如果$\beta=0$,那就是當前梯度的平方來規範化了,這樣一來,每次更新方向的每個元素值就都是1和-1了。下面來分析各種情況。

  以下是分別用GD、Momentum、RMSProp對二元函式$z = x^2+10y^2$進行優化的例子。初始點位於$(250,-150)$,學習率為0.02,Momentum和RMSProp的$\beta$都為0.9。它們分別迭代了113、78、65次:

  可以看出RMSProp少走了很多彎路,路線更平緩。Momentum雖然比GD多走很多彎路,但是迭代的次數還是有所降低的。但是,當把初始點改成$(350,1)$時,EMSProp的表現就不太好了,三者的迭代次數分別為122、78、293:

  這回Momentum迭代效率最高(次數最少),反而是RMSProp走了很多彎路迭代次數也多效率最低,這是因為梯度張量的各個元素都向1和-1靠近的緣故。

Adam

  以上介紹的兩個優化演算法在不同的起始位置似乎各有優缺點,而Adam就是將Momentum和RMSProp的優勢結合起來的演算法。下面是迭代式: 

$\begin{gather}V_t =\beta_1 V_{t-1} + (1-\beta_1) \nabla \theta_t\label{}\end{gather}$

$\begin{gather}S_t =\beta_2 S_{t-1} + (1-\beta_2)( \nabla \theta_t)^2 \label{}\end{gather}$

$\begin{gather}\hat{V_t} =\frac{V_t}{1-\beta_1^t}\label{}\end{gather}$

$\begin{gather}\hat{S_t} =\frac{S_t}{1-\beta_2^t} \label{}\end{gather}$

$\begin{gather}\theta_{t+1} = \theta_t - \eta \frac{\hat{V_t}}{\sqrt{\hat{S_t}}+\varepsilon}\left\|\sqrt{\hat{S_t}}\right\|\label{}\end{gather}$

  Adam實際上就是前面兩個演算法的簡單結合,但可以發現它多除了一個$1-\beta^t$($\beta^t$表示$\beta$的$t$次方),這是為了讓開始的幾次更新不至於太小(因為乘了$1-\beta$)。隨著迭代往後,$1-\beta^t$接近於1。

  下面對以上演算法做個比較。依舊是對二元函式$z = x^2+10y^2$進行優化,初始點位於$(250,-150)$,學習率為0.02。Momentum和RMSProp的$\beta=0.9$,Adam的$\beta_1=0.9$,$\beta_2=0.999$。Adam的迭代次數為207,另外三個演算法迭代次數沒變:

  Adam繞得厲害,迭代次數也比另外三個演算法多。把$\beta1$改成0.5後,Adam的迭代次數變為了40:

  $\beta1$越小,Adam是越退化為RMSProp的。如果設定$\beta1=0$退化為RMSProp,迭代次數又上升到了61(比上面的RMSProp效率高是因為$\beta2=0.999$而不是$0.9$)。說明不同情況下Adam的引數設定會直接影響迭代效率。

  總的來說,Adam就是加上動量的同時,又使用了規範化,讓每次迭代能用上之前的梯度,並且更新步伐的每個元素稍微靠近1和-1一些。而這樣有什麼好處,只能實踐出真知。

總結

  這些基於梯度下降的優化演算法都大同小異,它們在不同情況下發揮時好時壞,有的改良演算法在某些情況下效果可能比原始的GD還差。所以選擇優化演算法還是要視情況而定,我們應該選擇對高概率情況優化效果好的演算法。另外,我上面用迭代次數來比較演算法的優劣性不夠嚴謹,因為不同演算法每次迭代的計算量都不同。像Adam的計算量差不多是Momentum和RMSProp的兩倍,如果要嚴謹,還是得用計算時間作比