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

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

Andrew Ng的深度學習專項課程的第一門課《Neural Networks and Deep Learning》的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||22 ||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||1 ||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的表示式為: