吳恩達《優化深度神經網路》課程筆記(2)– 優化演算法

紅色石頭發表於2018-07-31

上節課我們主要介紹瞭如何建立一個實用的深度學習神經網路。包括Train/Dev/Test sets的比例選擇,Bias和Variance的概念和區別:Bias對應欠擬合,Variance對應過擬合。接著,我們介紹了防止過擬合的兩種方法:L2 regularization和Dropout。然後,介紹瞭如何進行規範化輸入,以加快梯度下降速度和精度。然後,我們介紹了梯度消失和梯度爆炸的概念和危害,並提出瞭如何使用梯度初始化來降低這種風險。最後,我們介紹了梯度檢查,來驗證梯度下降演算法是否正確。本節課,我們將繼續討論深度神經網路中的一些優化演算法,通過使用這些技巧和方法來提高神經網路的訓練速度和精度。

1. Mini-batch gradient descent

之前我們介紹的神經網路訓練過程是對所有m個樣本,稱為batch,通過向量化計算方式,同時進行的。如果m很大,例如達到百萬數量級,訓練速度往往會很慢,因為每次迭代都要對所有樣本進行進行求和運算和矩陣運算。我們將這種梯度下降演算法稱為Batch Gradient Descent。

為了解決這一問題,我們可以把m個訓練樣本分成若干個子集,稱為mini-batches,這樣每個子集包含的資料量就小了,例如只有1000,然後每次在單一子集上進行神經網路訓練,速度就會大大提高。這種梯度下降演算法叫做Mini-batch Gradient Descent。

假設總的訓練樣本個數m=5000000,其維度為(n_x,m)。將其分成5000個子集,每個mini-batch含有1000個樣本。我們將每個mini-batch記為X^{{t}},其維度為(n_x,1000)。相應的每個mini-batch的輸出記為Y^{{t}},其維度為(1,1000),且t=1,2,\cdots,5000

這裡順便總結一下我們遇到的神經網路中幾類字母的上標含義:

  • X^{(i)} :第i個樣本
  • Z^{[l]}:神經網路第l層網路的線性輸出

  • X^{{t}},Y^{{t}}:第t組mini-batch

Mini-batches Gradient Descent的實現過程是先將總的訓練樣本分成T個子集(mini-batches),然後對每個mini-batch進行神經網路訓練,包括Forward Propagation,Compute Cost Function,Backward Propagation,迴圈至T個mini-batch都訓練完畢。

for\ \ t=1,\cdots,T

\ \ \ \ Forward\ Propagation

\ \ \ \ Compute Cost Function

\ \ \ \ Backward Propagation

\ \ \ \ W:=W-\alpha\cdot dW

\ \ \ \ b:=b-\alpha\cdot db

經過T次迴圈之後,所有m個訓練樣本都進行了梯度下降計算。這個過程,我們稱之為經歷了一個epoch。對於Batch Gradient Descent而言,一個epoch只進行一次梯度下降演算法;而Mini-Batches Gradient Descent,一個epoch會進行T次梯度下降演算法。

值得一提的是,對於Mini-Batches Gradient Descent,可以進行多次epoch訓練。而且,每次epoch,最好是將總體訓練資料重新打亂、重新分成T組mini-batches,這樣有利於訓練出最佳的神經網路模型。

2. Understanding mini-batch gradient descent

Batch gradient descent和Mini-batch gradient descent的cost曲線如下圖所示:

對於一般的神經網路模型,使用Batch gradient descent,隨著迭代次數增加,cost是不斷減小的。然而,使用Mini-batch gradient descent,隨著在不同的mini-batch上迭代訓練,其cost不是單調下降,而是受類似noise的影響,出現振盪。但整體的趨勢是下降的,最終也能得到較低的cost值。

之所以出現細微振盪的原因是不同的mini-batch之間是有差異的。例如可能第一個子集(X^{{1}},Y^{{1}})是好的子集,而第二個子集(X^{{2}},Y^{{2}})包含了一些噪聲noise。出現細微振盪是正常的。

如何選擇每個mini-batch的大小,即包含的樣本個數呢?有兩個極端:如果mini-batch size=m,即為Batch gradient descent,只包含一個子集為(X^{{1}},Y^{{1}})=(X,Y);如果mini-batch size=1,即為Stachastic gradient descent,每個樣本就是一個子集(X^{{1}},Y^{{1}})=(x^{(i)},y^{(i)}),共有m個子集。

我們來比較一下Batch gradient descent和Stachastic gradient descent的梯度下降曲線。如下圖所示,藍色的線代表Batch gradient descent,紫色的線代表Stachastic gradient descent。Batch gradient descent會比較平穩地接近全域性最小值,但是因為使用了所有m個樣本,每次前進的速度有些慢。Stachastic gradient descent每次前進速度很快,但是路線曲折,有較大的振盪,最終會在最小值附近來回波動,難以真正達到最小值處。而且在數值處理上就不能使用向量化的方法來提高運算速度。

實際使用中,mini-batch size不能設定得太大(Batch gradient descent),也不能設定得太小(Stachastic gradient descent)。這樣,相當於結合了Batch gradient descent和Stachastic gradient descent各自的優點,既能使用向量化優化演算法,又能叫快速地找到最小值。mini-batch gradient descent的梯度下降曲線如下圖綠色所示,每次前進速度較快,且振盪較小,基本能接近全域性最小值。

一般來說,如果總體樣本數量m不太大時,例如m\leq2000,建議直接使用Batch gradient descent。如果總體樣本數量m很大時,建議將樣本分成許多mini-batches。推薦常用的mini-batch size為64,128,256,512。這些都是2的冪。之所以這樣設定的原因是計算機儲存資料一般是2的冪,這樣設定可以提高運算速度。

3. Exponentially weighted averages

該部分我們將介紹指數加權平均(Exponentially weighted averages)的概念。

舉個例子,記錄半年內倫敦市的氣溫變化,並在二維平面上繪製出來,如下圖所示:

看上去,溫度資料似乎有noise,而且抖動較大。如果我們希望看到半年內氣溫的整體變化趨勢,可以通過移動平均(moving average)的方法來對每天氣溫進行平滑處理。

例如我們可以設V_0=0,當成第0天的氣溫值。

第一天的氣溫與第0天的氣溫有關:

V_1=0.9V_0+0.1\theta_1

第二天的氣溫與第一天的氣溫有關:

V_2=0.9V_1+0.1\theta_2=0.9(0.9V_0+0.1\theta_1)+0.1\theta_2=0.9^2V_0+0.9\cdot0.1\theta_1+0.1\theta_2

第三天的氣溫與第二天的氣溫有關:

V_3=0.9V_2+0.1\theta_3=0.9(0.9^2V_0+0.9\cdot0.1\theta_1+0.1\theta_2)+0.1\theta_3=0.9^3V_0+0.9^2\cdot 0.1\theta_1+0.9\cdot 0.1\theta_2+0.1\theta_3

即第t天與第t-1天的氣溫迭代關係為:

V_t=0.9V_{t-1}+0.1\theta_t=0.9^tV_0+0.9^{t-1}\cdot0.1\theta_1+0.9^{t-2}\cdot 0.1\theta_2+\cdots+0.9\cdot0.1\theta_{t-1}+0.1\theta_t

經過移動平均處理得到的氣溫如下圖紅色曲線所示:

這種滑動平均演算法稱為指數加權平均(exponentially weighted average)。根據之前的推導公式,其一般形式為:

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

上面的例子中,\beta=0.9\beta值決定了指數加權平均的天數,近似表示為:

\frac{1}{1-\beta}

例如,當\beta=0.9,則\frac{1}{1-\beta}=10,表示將前10天進行指數加權平均。當\beta=0.98,則\frac{1}{1-\beta}=50,表示將前50天進行指數加權平均。\beta值越大,則指數加權平均的天數越多,平均後的趨勢線就越平緩,但是同時也會向右平移。下圖綠色曲線和黃色曲線分別表示了\beta=0.98\beta=0.5時,指數加權平均的結果。

這裡簡單解釋一下公式\frac{1}{1-\beta}是怎麼來的。準確來說,指數加權平均演算法跟之前所有天的數值都有關係,根據之前的推導公式就能看出。但是指數是衰減的,一般認為衰減到\frac1e就可以忽略不計了。因此,根據之前的推導公式,我們只要證明

\beta^{\frac{1}{1-\beta}}=\frac1e

就好了。

\frac{1}{1-\beta}=NN>0,則\beta=1-\frac{1}{N}\frac1N<1。即證明轉化為:

(1-\frac1N)^N=\frac1e

顯然,當N>>0時,上述等式是近似成立的。

至此,簡單解釋了為什麼指數加權平均的天數的計算公式為\frac{1}{1-\beta}

4. Understanding exponetially weighted averages

我們將指數加權平均公式的一般形式寫下來:

V_t=\beta V_{t-1}+(1-\beta)\theta_t=(1-\beta)\theta_t+(1-\beta)\cdot\beta\cdot\theta_{t-1}+(1-\beta)\cdot \beta^2\cdot\theta_{t-2}+\cdots+(1-\beta)\cdot \beta^{t-1}\cdot \theta_1+\beta^t\cdot V_0

觀察上面這個式子,\theta_t,\theta_{t-1},\theta_{t-2},\cdots,\theta_1是原始資料值,(1-\beta),(1-\beta)\beta,(1-\beta)\beta^2,\cdots,(1-\beta)\beta^{t-1}是類似指數曲線,從右向左,呈指數下降的。V_t的值就是這兩個子式的點乘,將原始資料值與衰減指數點乘,相當於做了指數衰減,離得越近,影響越大,離得越遠,影響越小,衰減越厲害。

我們已經知道了指數加權平均的遞推公式。實際應用中,為了減少記憶體的使用,我們可以使用這樣的語句來實現指數加權平均演算法:

V_{\theta}=0

Repeat:

\ \ \ \ Get\ next\ \theta_t

\ \ \ \ V_{\theta}:=\beta V_{\theta}+(1-\beta)\theta_t

5. Bias correction in exponentially weighted average

上文中提到當\beta=0.98時,指數加權平均結果如下圖綠色曲線所示。但是實際上,真實曲線如紫色曲線所示。

我們注意到,紫色曲線與綠色曲線的區別是,紫色曲線開始的時候相對較低一些。這是因為開始時我們設定V_0=0,所以初始值會相對小一些,直到後面受前面的影響漸漸變小,趨於正常。

修正這種問題的方法是進行偏移校正(bias correction),即在每次計算完V_t後,對V_t進行下式處理:

\frac{V_t}{1-\beta^t}

在剛開始的時候,t比較小,(1-\beta^t)<1,這樣就將V_t修正得更大一些,效果是把紫色曲線開始部分向上提升一些,與綠色曲線接近重合。隨著t增大,(1-\beta^t)\approx1V_t基本不變,紫色曲線與綠色曲線依然重合。這樣就實現了簡單的偏移校正,得到我們希望的綠色曲線。

值得一提的是,機器學習中,偏移校正並不是必須的。因為,在迭代一次次數後(t較大),V_t受初始值影響微乎其微,紫色曲線與綠色曲線基本重合。所以,一般可以忽略初始迭代過程,等到一定迭代之後再取值,這樣就不需要進行偏移校正了。

6. Gradient descent with momentum

該部分將介紹動量梯度下降演算法,其速度要比傳統的梯度下降演算法快很多。做法是在每次訓練時,對梯度進行指數加權平均處理,然後用得到的梯度值更新權重W和常數項b。下面介紹具體的實現過程。

原始的梯度下降演算法如上圖藍色折線所示。在梯度下降過程中,梯度下降的振盪較大,尤其對於W、b之間數值範圍差別較大的情況。此時每一點處的梯度只與當前方向有關,產生類似折線的效果,前進緩慢。而如果對梯度進行指數加權平均,這樣使當前梯度不僅與當前方向有關,還與之前的方向有關,這樣處理讓梯度前進方向更加平滑,減少振盪,能夠更快地到達最小值處。

權重W和常數項b的指數加權平均表示式如下:

V_{dW}=\beta\cdot V_{dW}+(1-\beta)\cdot dW

V_{db}=\beta\cdot V_{db}+(1-\beta)\cdot db

從動量的角度來看,以權重W為例,V_{dW}可以成速度V,dW可以看成是加速度a。指數加權平均實際上是計算當前的速度,當前速度由之前的速度和現在的加速度共同影響。而\beta<1,又能限制速度V_{dW}過大。也就是說,當前的速度是漸變的,而不是瞬變的,是動量的過程。這保證了梯度下降的平穩性和準確性,減少振盪,較快地達到最小值處。

動量梯度下降演算法的過程如下:

On\ iteration\ t:

\ \ \ \ Compute\ dW,\ db\ on\ the\ current\ mini-batch

\ \ \ \ V_{dW}=\beta V_{dW}+(1-\beta)dW

\ \ \ \ V_{db}=\beta V_{db}+(1-\beta)db

\ \ \ \ W=W-\alpha V_{dW},\ b=b-\alpha V_{db}

初始時,令V_{dW}=0,V_{db}=0。一般設定\beta=0.9,即指數加權平均前10天的資料,實際應用效果較好。

另外,關於偏移校正,可以不使用。因為經過10次迭代後,隨著滑動平均的過程,偏移情況會逐漸消失。

補充一下,在其它文獻資料中,動量梯度下降還有另外一種寫法:

V_{dW}=\beta V_{dW}+dW

V_{db}=\beta V_{db}+db

即消去了dWdb前的係數(1-\beta)。這樣簡化了表示式,但是學習因子\alpha相當於變成了\frac{\alpha}{1-\beta},表示\alpha也受\beta的影響。從效果上來說,這種寫法也是可以的,但是不夠直觀,且調參涉及到\alpha,不夠方便。所以,實際應用中,推薦第一種動量梯度下降的表示式。

7. RMSprop

RMSprop是另外一種優化梯度下降速度的演算法。每次迭代訓練過程中,其權重W和常數項b的更新表示式為:

S_W=\beta S_{dW}+(1-\beta)dW^2

S_b=\beta S_{db}+(1-\beta)db^2

W:=W-\alpha \frac{dW}{\sqrt{S_W}},\ b:=b-\alpha \frac{db}{\sqrt{S_b}}

下面簡單解釋一下RMSprop演算法的原理,仍然以下圖為例,為了便於分析,令水平方向為W的方向,垂直方向為b的方向。

從圖中可以看出,梯度下降(藍色折線)在垂直方向(b)上振盪較大,在水平方向(W)上振盪較小,表示在b方向上梯度較大,即db較大,而在W方向上梯度較小,即dW較小。因此,上述表示式中S_b較大,而S_W較小。在更新W和b的表示式中,變化值\frac{dW}{\sqrt{S_W}}較大,而\frac{db}{\sqrt{S_b}}較小。也就使得W變化得多一些,b變化得少一些。即加快了W方向的速度,減小了b方向的速度,減小振盪,實現快速梯度下降演算法,其梯度下降過程如綠色折線所示。總得來說,就是如果哪個方向振盪大,就減小該方向的更新速度,從而減小振盪。

還有一點需要注意的是為了避免RMSprop演算法中分母為零,通常可以在分母增加一個極小的常數\varepsilon

W:=W-\alpha \frac{dW}{\sqrt{S_W}+\varepsilon},\ b:=b-\alpha \frac{db}{\sqrt{S_b}+\varepsilon}

其中,\varepsilon=10^{-8},或者其它較小值。

8. Adam optimization algorithm

Adam(Adaptive Moment Estimation)演算法結合了動量梯度下降演算法和RMSprop演算法。其演算法流程為:

V_{dW}=0,\ S_{dW},\ V_{db}=0,\ S_{db}=0

On\ iteration\ t:

\ \ \ \ Cimpute\ dW,\ db

\ \ \ \ V_{dW}=\beta_1V_{dW}+(1-\beta_1)dW,\ V_{db}=\beta_1V_{db}+(1-\beta_1)db

\ \ \ \ S_{dW}=\beta_2S_{dW}+(1-\beta_2)dW^2,\ S_{db}=\beta_2S_{db}+(1-\beta_2)db^2

\ \ \ \ V_{dW}^{corrected}=\frac{V_{dW}}{1-\beta_1^t},\ V_{db}^{corrected}=\frac{V_{db}}{1-\beta_1^t}

\ \ \ \ S_{dW}^{corrected}=\frac{S_{dW}}{1-\beta_2^t},\ S_{db}^{corrected}=\frac{S_{db}}{1-\beta_2^t}

\ \ \ \ W:=W-\alpha\frac{V_{dW}^{corrected}}{\sqrt{S_{dW}^{corrected}}+\varepsilon},\ b:=b-\alpha\frac{V_{db}^{corrected}}{\sqrt{S_{db}^{corrected}}+\varepsilon}

Adam演算法包含了幾個超引數,分別是:\alpha,\beta_1,\beta_2,\varepsilon。其中,\beta_1通常設定為0.9,\beta_2通常設定為0.999,\varepsilon通常設定為10^{-8}。一般只需要對\beta_1\beta_2進行除錯。

實際應用中,Adam演算法結合了動量梯度下降和RMSprop各自的優點,使得神經網路訓練速度大大提高。

9. Learning rate decay

減小學習因子\alpha也能有效提高神經網路訓練速度,這種方法被稱為learning rate decay。

Learning rate decay就是隨著迭代次數增加,學習因子\alpha逐漸減小。下面用圖示的方式來解釋這樣做的好處。下圖中,藍色折線表示使用恆定的學習因子\alpha,由於每次訓練\alpha相同,步進長度不變,在接近最優值處的振盪也大,在最優值附近較大範圍內振盪,與最優值距離就比較遠。綠色折線表示使用不斷減小的\alpha,隨著訓練次數增加,\alpha逐漸減小,步進長度減小,使得能夠在最優值處較小範圍內微弱振盪,不斷逼近最優值。相比較恆定的\alpha來說,learning rate decay更接近最優值。

Learning rate decay中對\alpha可由下列公式得到:

\alpha=\frac{1}{1+decay_rate*epoch}\alpha_0

其中,deacy_rate是引數(可調),epoch是訓練完所有樣本的次數。隨著epoch增加,\alpha會不斷變小。

除了上面計算\alpha的公式之外,還有其它可供選擇的計算公式:

\alpha=0.95^{epoch}\cdot \alpha_0

\alpha=\frac{k}{\sqrt{epoch}}\cdot \alpha_0\ \ \ \ or\ \ \ \ \frac{k}{\sqrt{t}}\cdot \alpha_0

其中,k為可調引數,t為mini-bach number。

除此之外,還可以設定\alpha為關於t的離散值,隨著t增加,\alpha呈階梯式減小。當然,也可以根據訓練情況靈活調整當前的\alpha值,但會比較耗時間。

10. The problem of local optima

在使用梯度下降演算法不斷減小cost function時,可能會得到區域性最優解(local optima)而不是全域性最優解(global optima)。之前我們對區域性最優解的理解是形如碗狀的凹槽,如下圖左邊所示。但是在神經網路中,local optima的概念發生了變化。準確地來說,大部分梯度為零的“最優點”並不是這些凹槽處,而是形如右邊所示的馬鞍狀,稱為saddle point。也就是說,梯度為零並不能保證都是convex(極小值),也有可能是concave(極大值)。特別是在神經網路中引數很多的情況下,所有引數梯度為零的點很可能都是右邊所示的馬鞍狀的saddle point,而不是左邊那樣的local optimum。

類似馬鞍狀的plateaus會降低神經網路學習速度。Plateaus是梯度接近於零的平緩區域,如下圖所示。在plateaus上梯度很小,前進緩慢,到達saddle point需要很長時間。到達saddle point後,由於隨機擾動,梯度一般能夠沿著圖中綠色箭頭,離開saddle point,繼續前進,只是在plateaus上花費了太多時間。

總的來說,關於local optima,有兩點總結:

  • 只要選擇合理的強大的神經網路,一般不太可能陷入local optima
  • Plateaus可能會使梯度下降變慢,降低學習速度

值得一提的是,上文介紹的動量梯度下降,RMSprop,Adam演算法都能有效解決plateaus下降過慢的問題,大大提高神經網路的學習速度。


更多AI資源請關注公眾號:AI有道(ID:redstonewill)

相關文章