Coursera吳恩達《優化深度神經網絡》課程筆記(1)-- 深度學習的實用層面

我的CSDN博客地址:紅色石頭的專欄 
我的知乎主頁:紅色石頭 
我的微博:RedstoneWill的微博 
我的GitHub:RedstoneWill的GitHub 
我的微信公衆號:紅色石頭的機器學習之路(ID:redstonewill) 
歡迎大家關注我!共同學習,共同進步!

Andrew Ng的深度學習專項課程的第一門課《Neural Networks and Deep Learning》的5份筆記我已經整理完畢。迷路的小夥伴請見如下鏈接:

Coursera吳恩達《神經網絡與深度學習》課程筆記(1)– 深度學習概述

Coursera吳恩達《神經網絡與深度學習》課程筆記(2)– 神經網絡基礎之邏輯迴歸

Coursera吳恩達《神經網絡與深度學習》課程筆記(3)– 神經網絡基礎之Python與向量化

Coursera吳恩達《神經網絡與深度學習》課程筆記(4)– 淺層神經網絡

Coursera吳恩達《神經網絡與深度學習》課程筆記(5)– 深層神經網絡

在接下來的幾次筆記中,我們將對第二門課《Improving Deep Neural Networks: Hyperparameter tuning, Regularization and Optimization》進行筆記總結和整理。我們在第一門課中已經學習瞭如何建立一個神經網絡,或者淺層的,或者深度的。而這第二門課,我們將着重討論和研究如何優化神經網絡模型,例如調整超參數,提高算法運行速度等等。開始吧~

1. Train/Dev/Test sets

選擇最佳的訓練集(Training sets)、驗證集(Development sets)、測試集(Test sets)對神經網絡的性能影響非常重要。除此之外,在構建一個神經網絡的時候,我們需要設置許多參數,例如神經網絡的層數、每個隱藏層包含的神經元個數、學習因子(學習速率)、激活函數的選擇等等。實際上很難在第一次設置的時候就選擇到這些最佳的參數,而是需要通過不斷地迭代更新來獲得。這個循環迭代的過程是這樣的:我們先有個想法Idea,先選擇初始的參數值,構建神經網絡模型結構;然後通過代碼Code的形式,實現這個神經網絡;最後,通過實驗Experiment驗證這些參數對應的神經網絡的表現性能。根據驗證結果,我們對參數進行適當的調整優化,再進行下一次的Idea->Code->Experiment循環。通過很多次的循環,不斷調整參數,選定最佳的參數值,從而讓神經網絡性能最優化。

這裏寫圖片描述

深度學習已經應用於許多領域中,比如NLP,CV,Speech Recognition等等。通常來說,最適合某個領域的深度學習網絡往往不能直接應用在其它問題上。解決不同問題的最佳選擇是根據樣本數量、輸入特徵數量和電腦配置信息(GPU或者CPU)等,來選擇最合適的模型。即使是最有經驗的深度學習專家也很難第一次就找到最合適的參數。因此,應用深度學習是一個反覆迭代的過程,需要通過反覆多次的循環訓練得到最優化參數。決定整個訓練過程快慢的關鍵在於單次循環所花費的時間,單次循環越快,訓練過程越快。而設置合適的Train/Dev/Test sets數量,能有效提高訓練效率。

一般地,我們將所有的樣本數據分成三個部分:Train/Dev/Test sets。Train sets用來訓練你的算法模型;Dev sets用來驗證不同算法的表現情況,從中選擇最好的算法模型;Test sets用來測試最好算法的實際表現,作爲該算法的無偏估計。

之前人們通常設置Train sets和Test sets的數量比例爲70%和30%。如果有Dev sets,則設置比例爲60%、20%、20%,分別對應Train/Dev/Test sets。這種比例分配在樣本數量不是很大的情況下,例如100,1000,10000,是比較科學的。但是如果數據量很大的時候,例如100萬,這種比例分配就不太合適了。科學的做法是要將Dev sets和Test sets的比例設置得很低。因爲Dev sets的目標是用來比較驗證不同算法的優劣,從而選擇更好的算法模型就行了。因此,通常不需要所有樣本的20%這麼多的數據來進行驗證。對於100萬的樣本,往往只需要10000個樣本來做驗證就夠了。Test sets也是一樣,目標是測試已選算法的實際表現,無偏估計。對於100萬的樣本,往往也只需要10000個樣本就夠了。因此,對於大數據樣本,Train/Dev/Test sets的比例通常可以設置爲98%/1%/1%,或者99%/0.5%/0.5%。樣本數據量越大,相應的Dev/Test sets的比例可以設置的越低一些。

現代深度學習還有個重要的問題就是訓練樣本和測試樣本分佈上不匹配,意思是訓練樣本和測試樣本來自於不同的分佈。舉個例子,假設你開發一個手機app,可以讓用戶上傳圖片,然後app識別出貓的圖片。在app識別算法中,你的訓練樣本可能來自網絡下載,而你的驗證和測試樣本可能來自不同用戶的上傳。從網絡下載的圖片一般像素較高而且比較正規,而用戶上傳的圖片往往像素不穩定,且圖片質量不一。因此,訓練樣本和驗證/測試樣本可能來自不同的分佈。解決這一問題的比較科學的辦法是儘量保證Dev sets和Test sets來自於同一分佈。值得一提的是,訓練樣本非常重要,通常我們可以將現有的訓練樣本做一些處理,例如圖片的翻轉、假如隨機噪聲等,來擴大訓練樣本的數量,從而讓該模型更加強大。即使Train sets和Dev/Test sets不來自同一分佈,使用這些技巧也能提高模型性能。

最後提一點的是如果沒有Test sets也是沒有問題的。Test sets的目標主要是進行無偏估計。我們可以通過Train sets訓練不同的算法模型,然後分別在Dev sets上進行驗證,根據結果選擇最好的算法模型。這樣也是可以的,不需要再進行無偏估計了。如果只有Train sets和Dev sets,通常也有人把這裏的Dev sets稱爲Test sets,我們要注意加以區別。

2. Bias/Variance

偏差(Bias)和方差(Variance)是機器學習領域非常重要的兩個概念和需要解決的問題。在傳統的機器學習算法中,Bias和Variance是對立的,分別對應着欠擬合和過擬合,我們常常需要在Bias和Variance之間進行權衡。而在深度學習中,我們可以同時減小Bias和Variance,構建最佳神經網絡模型。

如下圖所示,顯示了二維平面上,high bias,just right,high variance的例子。可見,high bias對應着欠擬合,而high variance對應着過擬合。

這裏寫圖片描述

上圖這個例子中輸入特徵是二維的,high bias和high variance可以直接從圖中分類線看出來。而對於輸入特徵是高維的情況,如何來判斷是否出現了high bias或者high variance呢?

例如貓識別問題,輸入是一幅圖像,其特徵維度很大。這種情況下,我們可以通過兩個數值Train set error和Dev set error來理解bias和variance。假設Train set error爲1%,而Dev set error爲11%,即該算法模型對訓練樣本的識別很好,但是對驗證集的識別卻不太好。這說明了該模型對訓練樣本可能存在過擬合,模型泛化能力不強,導致驗證集識別率低。這恰恰是high variance的表現。假設Train set error爲15%,而Dev set error爲16%,雖然二者error接近,即該算法模型對訓練樣本和驗證集的識別都不是太好。這說明了該模型對訓練樣本存在欠擬合。這恰恰是high bias的表現。假設Train set error爲15%,而Dev set error爲30%,說明了該模型既存在high bias也存在high variance(深度學習中最壞的情況)。再假設Train set error爲0.5%,而Dev set error爲1%,即low bias和low variance,是最好的情況。值得一提的是,以上的這些假設都是建立在base error是0的基礎上,即人類都能正確識別所有貓類圖片。base error不同,相應的Train set error和Dev set error會有所變化,但沒有相對變化。

一般來說,Train set error體現了是否出現bias,Dev set error體現了是否出現variance(正確地說,應該是Dev set error與Train set error的相對差值)。

我們已經通過二維平面展示了high bias或者high variance的模型,下圖展示了high bias and high variance的模型:

這裏寫圖片描述

模型既存在high bias也存在high variance,可以理解成某段區域是欠擬合的,某段區域是過擬合的。

3. Basic Recipe for Machine Learning

機器學習中基本的一個訣竅就是避免出現high bias和high variance。首先,減少high bias的方法通常是增加神經網絡的隱藏層個數、神經元個數,訓練時間延長,選擇其它更復雜的NN模型等。在base error不高的情況下,一般都能通過這些方式有效降低和避免high bias,至少在訓練集上表現良好。其次,減少high variance的方法通常是增加訓練樣本數據,進行正則化Regularization,選擇其他更復雜的NN模型等。

這裏有幾點需要注意的。第一,解決high bias和high variance的方法是不同的。實際應用中通過Train set error和Dev set error判斷是否出現了high bias或者high variance,然後再選擇針對性的方法解決問題。

第二,Bias和Variance的折中tradeoff。傳統機器學習算法中,Bias和Variance通常是對立的,減小Bias會增加Variance,減小Variance會增加Bias。而在現在的深度學習中,通過使用更復雜的神經網絡和海量的訓練樣本,一般能夠同時有效減小Bias和Variance。這也是深度學習之所以如此強大的原因之一。

4. Regularization

如果出現了過擬合,即high variance,則需要採用正則化regularization來解決。雖然擴大訓練樣本數量也是減小high variance的一種方法,但是通常獲得更多訓練樣本的成本太高,比較困難。所以,更可行有效的辦法就是使用regularization。

我們先來回顧一下之前介紹的Logistic regression。採用L2 regularization,其表達式爲:

J(w,b)=1mi=1mL(y^(i),y(i))+λ2m||w||22J(w,b)=1m∑i=1mL(y^(i),y(i))+λ2m||w||22

||w||22=j=1nxw2j=wTw||w||22=∑j=1nxwj2=wTw

這裏有個問題:爲什麼只對w進行正則化而不對b進行正則化呢?其實也可以對b進行正則化。但是一般w的維度很大,而b只是一個常數。相比較來說,參數很大程度上由w決定,改變b值對整體模型影響較小。所以,一般爲了簡便,就忽略對b的正則化了。

除了L2 regularization之外,還有另外一隻正則化方法:L1 regularization。其表達式爲:

J(w,b)=1mi=1mL(y^(i),y(i))+λ2m||w||1J(w,b)=1m∑i=1mL(y^(i),y(i))+λ2m||w||1

||w||1=j=1nx|wj|||w||1=∑j=1nx|wj|

與L2 regularization相比,L1 regularization得到的w更加稀疏,即很多w爲零值。其優點是節約存儲空間,因爲大部分w爲0。然而,實際上L1 regularization在解決high variance方面比L2 regularization並不更具優勢。而且,L1的在微分求導方面比較複雜。所以,一般L2 regularization更加常用。

L1、L2 regularization中的λλ就是正則化參數(超參數的一種)。可以設置λλ爲不同的值,在Dev set中進行驗證,選擇最佳的λλ。順便提一下,在python中,由於lambda是保留字,所以爲了避免衝突,我們使用lambd來表示λλ

在深度學習模型中,L2 regularization的表達式爲:

J(w[1],b[1],,w[L],b[L])=1mi=1mL(y^(i),y(i))+λ2ml=1L||w[l]||2J(w[1],b[1],⋯,w[L],b[L])=1m∑i=1mL(y^(i),y(i))+λ2m∑l=1L||w[l]||2

||w[l]||2=i=1n[l]j=1n[l1](w[l]ij)2||w[l]||2=∑i=1n[l]∑j=1n[l−1](wij[l])2

通常,我們把||w[l]||2||w[l]||2稱爲Frobenius範數,記爲||w[l]||2F||w[l]||F2。一個矩陣的Frobenius範數就是計算所有元素平方和再開方,如下所示:

||A||F=i=1mj=1n|aij|2||A||F=∑i=1m∑j=1n|aij|2

值得注意的是,由於加入了正則化項,梯度下降算法中的dw[l]dw[l]計算表達式需要做如下修改:

dw[l]=dw[l]before+λmw[l]dw[l]=dwbefore[l]+λmw[l]

w[l]:=w[l]αdw[l]w[l]:=w[l]−α⋅dw[l]

L2 regularization也被稱做weight decay。這是因爲,由於加上了正則項,dw[l]dw[l]有個增量,在更新w[l]w[l]的時候,會多減去這個增量,使得w[l]w[l]比沒有正則項的值要小一些。不斷迭代更新,不斷地減小。

w[l]:===w[l]αdw[l]w[l]α(dw[l]before+λmw[l])(1αλm)w[l]αdw[l]beforew[l]:=w[l]−α⋅dw[l]=w[l]−α⋅(dwbefore[l]+λmw[l])=(1−αλm)w[l]−α⋅dwbefore[l]

其中,(1αλm)<1(1−αλm)<1

5. Why regularization reduces overfitting

爲什麼正則化能夠有效避免high variance,防止過擬合呢?下面我們通過幾個例子說明。

還是之前那張圖,從左到右,分別表示了欠擬合,剛好擬合,過擬合三種情況。

這裏寫圖片描述

假如我們選擇了非常複雜的神經網絡模型,如上圖左上角所示。在未使用正則化的情況下,我們得到的分類超平面可能是類似上圖右側的過擬合。但是,如果使用L2 regularization,當λλ很大時,w[l]0w[l]≈0w[l]w[l]近似爲零,意味着該神經網絡模型中的某些神經元實際的作用很小,可以忽略。從效果上來看,其實是將某些神經元給忽略掉了。這樣原本過於複雜的神經網絡模型就變得不那麼複雜了,而變得非常簡單化了。如下圖所示,整個簡化的神經網絡模型變成了一個邏輯迴歸模型。問題就從high variance變成了high bias了。

這裏寫圖片描述

因此,選擇合適大小的λλ值,就能夠同時避免high bias和high variance,得到最佳模型。

還有另外一個直觀的例子來解釋爲什麼正則化能夠避免發生過擬合。假設激活函數是tanh函數。tanh函數的特點是在z接近零的區域,函數近似是線性的,而當|z|很大的時候,函數非線性且變化緩慢。當使用正則化,λλ較大,即對權重w[l]w[l]的懲罰較大,w[l]w[l]減小。因爲z[l]=w[l]a[l]+b[l]z[l]=w[l]a[l]+b[l]。當w[l]w[l]減小的時候,z[l]z[l]也會減小。則此時的z[l]z[l]分佈在tanh函數的近似線性區域。那麼這個神經元起的作用就相當於是linear regression。如果每個神經元對應的權重w[l]w[l]都比較小,那麼整個神經網絡模型相當於是多個linear regression的組合,即可看成一個linear network。得到的分類超平面就會比較簡單,不會出現過擬合現象。

這裏寫圖片描述

6. Dropout Regularization

除了L2 regularization之外,還有另外一種防止過擬合的有效方法:Dropout。

Dropout是指在深度學習網絡的訓練過程中,對於每層的神經元,按照一定的概率將其暫時從網絡中丟棄。也就是說,每次訓練時,每一層都有部分神經元不工作,起到簡化複雜網絡模型的效果,從而避免發生過擬合。

這裏寫圖片描述

Dropout有不同的實現方法,接下來介紹一種常用的方法:Inverted dropout。假設對於第ll層神經元,設定保留神經元比例概率keep_prob=0.8,即該層有20%的神經元停止工作。dldl爲dropout向量,設置dldl爲隨機vector,其中80%的元素爲1,20%的元素爲0。在python中可以使用如下語句生成dropout vector:

dl = np.random.rand(al.shape[0],al.shape[1])<keep_prob
  • 1

然後,第ll層經過dropout,隨機刪減20%的神經元,只保留80%的神經元,其輸出爲:

al = np.multiply(al,dl)
  • 1

最後,還要對alal進行scale up處理,即:

al /= keep_prob
  • 1

以上就是Inverted dropout的方法。之所以要對alal進行scale up是爲了保證在經過dropout後,alal作爲下一層神經元的輸入值儘量保持不變。假設第ll層有50個神經元,經過dropout後,有10個神經元停止工作,這樣只有40神經元有作用。那麼得到的alal只相當於原來的80%。scale up後,能夠儘可能保持alal的期望值相比之前沒有大的變化。

Inverted dropout的另外一個好處就是在對該dropout後的神經網絡進行測試時能夠減少scaling問題。因爲在訓練時,使用scale up保證alal的期望值沒有大的變化,測試時就不需要再對樣本數據進行類似的尺度伸縮操作了。

對於m個樣本,單次迭代訓練時,隨機刪除掉隱藏層一定數量的神經元;然後,在刪除後的剩下的神經元上正向和反向更新權重w和常數項b;接着,下一次迭代中,再恢復之前刪除的神經元,重新隨機刪除一定數量的神經元,進行正向和反向更新w和b。不斷重複上述過程,直至迭代訓練完成。

值得注意的是,使用dropout訓練結束後,在測試和實際應用模型時,不需要進行dropout和隨機刪減神經元,所有的神經元都在工作。

7. Understanding Dropout

Dropout通過每次迭代訓練時,隨機選擇不同的神經元,相當於每次都在不同的神經網絡上進行訓練,類似機器學習中Bagging的方法(三個臭皮匠,賽過諸葛亮),能夠防止過擬合。

除此之外,還可以從權重w的角度來解釋爲什麼dropout能夠有效防止過擬合。對於某個神經元來說,某次訓練時,它的某些輸入在dropout的作用被過濾了。而在下一次訓練時,又有不同的某些輸入被過濾。經過多次訓練後,某些輸入被過濾,某些輸入被保留。這樣,該神經元就不會受某個輸入非常大的影響,影響被均勻化了。也就是說,對應的權重w不會很大。這從從效果上來說,與L2 regularization是類似的,都是對權重w進行“懲罰”,減小了w的值。

這裏寫圖片描述

總結一下,對於同一組訓練數據,利用不同的神經網絡訓練之後,求其輸出的平均值可以減少overfitting。Dropout就是利用這個原理,每次丟掉一定數量的隱藏層神經元,相當於在不同的神經網絡上進行訓練,這樣就減少了神經元之間的依賴性,即每個神經元不能依賴於某幾個其他的神經元(指層與層之間相連接的神經元),使神經網絡更加能學習到與其他神經元之間的更加健壯robust的特徵。

在使用dropout的時候,有幾點需要注意。首先,不同隱藏層的dropout係數keep_prob可以不同。一般來說,神經元越多的隱藏層,keep_out可以設置得小一些.,例如0.5;神經元越少的隱藏層,keep_out可以設置的大一些,例如0.8,設置是1。另外,實際應用中,不建議對輸入層進行dropout,如果輸入層維度很大,例如圖片,那麼可以設置dropout,但keep_out應設置的大一些,例如0.8,0.9。總體來說,就是越容易出現overfitting的隱藏層,其keep_prob就設置的相對小一些。沒有準確固定的做法,通常可以根據validation進行選擇。

Dropout在電腦視覺CV領域應用比較廣泛,因爲輸入層維度較大,而且沒有足夠多的樣本數量。值得注意的是dropout是一種regularization技巧,用來防止過擬合的,最好只在需要regularization的時候使用dropout。

使用dropout的時候,可以通過繪製cost function來進行debug,看看dropout是否正確執行。一般做法是,將所有層的keep_prob全設置爲1,再繪製cost function,即涵蓋所有神經元,看J是否單調下降。下一次迭代訓練時,再將keep_prob設置爲其它值。

8. Other regularization methods

除了L2 regularization和dropout regularization之外,還有其它減少過擬合的方法。

一種方法是增加訓練樣本數量。但是通常成本較高,難以獲得額外的訓練樣本。但是,我們可以對已有的訓練樣本進行一些處理來“製造”出更多的樣本,稱爲data augmentation。例如圖片識別問題中,可以對已有的圖片進行水平翻轉、垂直翻轉、任意角度旋轉、縮放或擴大等等。如下圖所示,這些處理都能“製造”出新的訓練樣本。雖然這些是基於原有樣本的,但是對增大訓練樣本數量還是有很有幫助的,不需要增加額外成本,卻能起到防止過擬合的效果。

這裏寫圖片描述

在數字識別中,也可以將原有的數字圖片進行任意旋轉或者扭曲,或者增加一些noise,如下圖所示:

這裏寫圖片描述

還有另外一種防止過擬合的方法:early stopping。一個神經網絡模型隨着迭代訓練次數增加,train set error一般是單調減小的,而dev set error 先減小,之後又增大。也就是說訓練次數過多時,模型會對訓練樣本擬合的越來越好,但是對驗證集擬合效果逐漸變差,即發生了過擬合。因此,迭代訓練次數不是越多越好,可以通過train set error和dev set error隨着迭代次數的變化趨勢,選擇合適的迭代次數,即early stopping。

這裏寫圖片描述

然而,Early stopping有其自身缺點。通常來說,機器學習訓練模型有兩個目標:一是優化cost function,儘量減小J;二是防止過擬合。這兩個目標彼此對立的,即減小J的同時可能會造成過擬合,反之亦然。我們把這二者之間的關係稱爲正交化orthogonalization。該節課開始部分就講過,在深度學習中,我們可以同時減小Bias和Variance,構建最佳神經網絡模型。但是,Early stopping的做法通過減少得帶訓練次數來防止過擬合,這樣J就不會足夠小。也就是說,early stopping將上述兩個目標融合在一起,同時優化,但可能沒有“分而治之”的效果好。

與early stopping相比,L2 regularization可以實現“分而治之”的效果:迭代訓練足夠多,減小J,而且也能有效防止過擬合。而L2 regularization的缺點之一是最優的正則化參數λλ的選擇比較複雜。對這一點來說,early stopping比較簡單。總的來說,L2 regularization更加常用一些。

9. Normalizing inputs

在訓練神經網絡時,標準化輸入可以提高訓練的速度。標準化輸入就是對訓練數據集進行歸一化的操作,即將原始數據減去其均值μμ後,再除以其方差σ2σ2

μ=1mi=1mX(i)μ=1m∑i=1mX(i)

σ2=1mi=1m(X(i))2σ2=1m∑i=1m(X(i))2

X:=Xμσ2X:=X−μσ2

以二維平面爲例,下圖展示了其歸一化過程:

這裏寫圖片描述

值得注意的是,由於訓練集進行了標準化處理,那麼對於測試集或在實際應用時,應該使用同樣的μμσ2σ2對其進行標準化處理。這樣保證了訓練集合測試集的標準化操作一致。

之所以要對輸入進行標準化操作,主要是爲了讓所有輸入歸一化同樣的尺度上,方便進行梯度下降算法時能夠更快更準確地找到全局最優解。假如輸入特徵是二維的,且x1的範圍是[1,1000],x2的範圍是[0,1]。如果不進行標準化處理,x1與x2之間分佈極不平衡,訓練得到的w1和w2也會在數量級上差別很大。這樣導致的結果是cost function與w和b的關係可能是一個非常細長的橢圓形碗。對其進行梯度下降算法時,由於w1和w2數值差異很大,只能選擇很小的學習因子αα,來避免J發生振盪。一旦αα較大,必然發生振盪,J不再單調下降。如下左圖所示。

然而,如果進行了標準化操作,x1與x2分佈均勻,w1和w2數值差別不大,得到的cost function與w和b的關係是類似圓形碗。對其進行梯度下降算法時,αα可以選擇相對大一些,且J一般不會發生振盪,保證了J是單調下降的。如下右圖所示。

這裏寫圖片描述

另外一種情況,如果輸入特徵之間的範圍本來就比較接近,那麼不進行標準化操作也是沒有太大影響的。但是,標準化處理在大多數場合下還是值得推薦的。

10. Vanishing and Exploding gradients

在神經網絡尤其是深度神經網絡中存在可能存在這樣一個問題:梯度消失和梯度爆炸。意思是當訓練一個 層數非常多的神經網絡時,計算得到的梯度可能非常小或非常大,甚至是指數級別的減小或增大。這樣會讓訓練過程變得非常困難。

舉個例子來說明,假設一個多層的每層只包含兩個神經元的深度神經網絡模型,如下圖所示:

這裏寫圖片描述

爲了簡化複雜度,便於分析,我們令各層的激活函數爲線性函數,即g(Z)=Zg(Z)=Z。且忽略各層常數項b的影響,令b全部爲零。那麼,該網絡的預測輸出Y^Y^爲:

Y^=W[L]W[L1]W[L2]W[3]W[2]W[1]XY^=W[L]W[L−1]W[L−2]⋯W[3]W[2]W[1]X

如果各層權重W[l]W[l]的元素都稍大於1,例如1.5,則預測輸出Y^Y^將正比於1.5L1.5L。L越大,Y^Y^越大,且呈指數型增長。我們稱之爲數值爆炸。相反,如果各層權重W[l]W[l]的元素都稍小於1,例如0.5,則預測輸出Y^Y^將正比於0.5L0.5L。網絡層數L越多,Y^Y^呈指數型減小。我們稱之爲數值消失。

也就是說,如果各層權重W[l]W[l]都大於1或者都小於1,那麼各層激活函數的輸出將隨着層數ll的增加,呈指數型增大或減小。當層數很大時,出現數值爆炸或消失。同樣,這種情況也會引起梯度呈現同樣的指數型增大或減小的變化。L非常大時,例如L=150,則梯度會非常大或非常小,引起每次更新的步進長度過大或者過小,這讓訓練過程十分困難。

11. Weight Initialization for Deep Networks

下面介紹如何改善Vanishing and Exploding gradients這類問題,方法是對權重w進行一些初始化處理。

深度神經網絡模型中,以單個神經元爲例,該層(ll)的輸入個數爲n,其輸出爲:

z=w1x1+w2x2++wnxnz=w1x1+w2x2+⋯+wnxn

a=g(z)a=g(z)

這裏寫圖片描述

這裏忽略了常數項b。爲了讓z不會過大或者過小,思路是讓w與n有關,且n越大,w應該越小纔好。這樣能夠保證z不會過大。一種方法是在初始化w時,令其方差爲1n1n。相應的python僞代碼爲:

w[l] = np.random.randn(n[l],n[l-1])*np.sqrt(1/n[l-1]) 
  • 1

如果激活函數是tanh,一般選擇上面的初始化方法。

如果激活函數是ReLU,權重w的初始化一般令其方差爲2n2n

w[l] = np.random.randn(n[l],n[l-1])*np.sqrt(2/n[l-1]) 
  • 1

除此之外,Yoshua Bengio提出了另外一種初始化w的方法,令其方差爲2n[l1]n[l]2n[l−1]n[l]

w[l] = np.random.randn(n[l],n[l-1])*np.sqrt(2/n[l-1]*n[l]) 
  • 1

至於選擇哪種初始化方法因人而異,可以根據不同的激活函數選擇不同方法。另外,我們可以對這些初始化方法中設置某些參數,作爲超參數,通過驗證集進行驗證,得到最優參數,來優化神經網絡。

12. Numerical approximation of gradients

Back Propagation神經網絡有一項重要的測試是梯度檢查(gradient checking)。其目的是檢查驗證反向傳播過程中梯度下降算法是否正確。該小節將先介紹如何近似求出梯度值。

這裏寫圖片描述

利用微分思想,函數f在點θθ處的梯度可以表示成:

g(θ)=f(θ+ε)f(θε)2εg(θ)=f(θ+ε)−f(θ−ε)2ε

其中,ε>0ε>0,且足夠小。

13. Gradient checking

介紹完如何近似求出梯度值後,我們將介紹如何進行梯度檢查,來驗證訓練過程中是否出現bugs。

梯度檢查首先要做的是分別將W[1],b[1],,W[L],b[L]W[1],b[1],⋯,W[L],b[L]這些矩陣構造成一維向量,然後將這些一維向量組合起來構成一個更大的一維向量θθ。這樣cost function J(W[1],b[1],,W[L],b[L])J(W[1],b[1],⋯,W[L],b[L])就可以表示成J(θ)J(θ)

然後將反向傳播過程通過梯度下降算法得到的dW[1],db[1],,dW[L],db[L]dW[1],db[1],⋯,dW[L],db[L]按照一樣的順序構造成一個一維向量dθdθ的維度與θθ一致。

接着利用J(θ)J(θ)對每個θiθi計算近似梯度,其值與反向傳播算法得到的dθidθi相比較,檢查是否一致。例如,對於第i個元素,近似梯度爲:

dθapprox[i]=J(θ1,θ2,,θi+ε,)J(θ1,θ2,,θiε,)2εdθapprox[i]=J(θ1,θ2,⋯,θi+ε,⋯)−J(θ1,θ2,⋯,θi−ε,⋯)2ε

計算完所有θiθi的近似梯度後,可以計算dθapproxdθapproxdθ的歐氏(Euclidean)距離來比較二者的相似度。公式如下:

||dθapproxdθ||2||dθapprox||2+||dθ||2||dθapprox−dθ||2||dθapprox||2+||dθ||2

一般來說,如果歐氏距離越小,例如10710−7,甚至更小,則表明dθapproxdθapproxdθ越接近,即反向梯度計算是正確的,沒有bugs。如果歐氏距離較大,例如10510−5,則表明梯度計算可能出現問題,需要再次檢查是否有bugs存在。如果歐氏距離很大,例如10310−3,甚至更大,則表明dθapproxdθapproxdθ差別很大,梯度下降計算過程有bugs,需要仔細檢查。

14. Gradient Checking Implementation Notes

在進行梯度檢查的過程中有幾點需要注意的地方:

  • 不要在整個訓練過程中都進行梯度檢查,僅僅作爲debug使用。

  • 如果梯度檢查出現錯誤,找到對應出錯的梯度,檢查其推導是否出現錯誤。

  • 注意不要忽略正則化項,計算近似梯度的時候要包括進去。

  • 梯度檢查時關閉dropout,檢查完畢後再打開dropout。

  • 隨機初始化時運行梯度檢查,經過一些訓練後再進行梯度檢查(不常用)。

更多AI資源請關注公衆號:紅色石頭的機器學習之路(ID:redstonewill) 
這裏寫圖片描述

發佈了47 篇原創文章 · 獲贊 118 · 訪問量 39萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章