吳恩達Deeplearning.ai之2-1:深度學習的實用層面

這篇筆記主要是關於深度學習的實用層面的,包括以下內容:

目錄

1. 訓練、驗證、測試集(Train\Development\Test sets)

1.1 吳恩達老師

1.2 西瓜書

1.2.1 留出法

1.2.2 交叉驗證法

1.2.3 自助法

2. 偏差/方差(Bias/Variance)

3. 機器學習基礎(Basic 'recipe' for machine learning)

4. 正則化(Regularization)                                       

4.1 邏輯迴歸:

4.2 神經網絡

4.3 正則和正則

5. 爲什麼正則化可以防止過擬合(Why regularization reduce overfiting)

6. Dropout正則化(Drop regularization)

7. 理解Dropout(Understanding Dropout)

7.1 dropout爲什麼可以防止過擬合

8. 其它正則化方法(other regularization methods)

8.1 數據擴增

8.2 Early stopping

9. 歸一化輸入(Normalizing inputs)

10. 梯度消失/梯度爆炸(Vanishing/exploding gradients)

11. 神經網絡的權值初始化(Weight initialization for deep network)

12. 梯度的數值逼近(Numerical approximation of gradients)

13. 梯度檢驗(Gradient checking)

14. 梯度檢驗的注意事項(Gradients checking implementation notes)

1. 訓練、驗證、測試集(Train\Development\Test sets)

在建模的時候,通常是在訓練集上訓練模型,在測試集上測試模型的泛化性能。對於一個數據集,既要訓練又要驗證最後再對模型進行測試,這就需要對數據集進行劃分,把數據集劃分爲三個子數據集:訓練集、驗證集以及測試集。

1.1 吳恩達老師

處理小數據量時,可以對數據集進行以下劃分:

無驗證集:trainset:testset = 7:3

有驗證集:trainset:dev:testset = 6:2:2

處理大數據量時,數據集中的絕大部分數據都用來訓練模型,所以有以下劃分:

trainset:dev:testset = 98:1:1

數據集的劃分在機器學習中是一個比較重要又關鍵的步驟,但是吳恩達老師在這部分講的東西並不是很多,所以在此補充了周志華老師西瓜書中的相關內容。

1.2 西瓜書

數據集的劃分方式有多種,常見的方法有留出法、交叉驗證法以及自助法。

1.2.1 留出法

“留出法”(hold-out)直接將數據集D劃分爲兩個互斥的集合,其中一個作爲訓練集S,一個作爲測試集T。在訓練集S上訓練模型,用T來評估其測試誤差,對泛化誤差進行估計。也可以將數據集D劃分爲三個互斥集合,一個爲訓練集S、一個爲驗證集V、一個爲測試集T。

需要格外注意的是,訓練集、驗證集和測試集中的數據要有一致的分佈,比如在分類任務中,三個數據集中的正負樣本的比例要相似;各個特徵所佔的比例也要儘量相似。若從採樣的角度看待數據集的劃分,那麼保留類別比例的採樣方式通常稱爲“分層採樣”。如數據集D中有500個正樣本、500個負樣本,那麼對D進行分層抽樣得到含60%的訓練集S、20%的驗證集V和20%的測試集T,那麼訓練集中包含300個正樣本、300個負樣本;驗證集中包含100個正樣本、100個負樣本;測試集中包含100個正樣本、100個負樣本。

1.2.2 交叉驗證法

“交叉驗證法”(cross validation)將數據集D劃分爲k個大小相似的互斥子集,每個子集儘可能的保證有一致的數據分佈。每次採用k-1個子集的並集作爲訓練集,餘下的子集作爲測試集;這樣就可以獲得k組訓練/測試集,進行k次訓練和測試,返回k個測試結果的均值。同常將這種交叉驗證的方法稱爲“k折交叉驗證”。通常k取值爲10,此時稱爲10折交叉驗證。

                                 

圖片來自周志華老師的西瓜書。

1.2.3 自助法

“自助法”(bootstrapping)以可重複採樣爲基礎,對包含m個樣本的數據集D進行採樣,每次從D中隨機挑選一個樣本,將其拷貝到D'中,然後把該樣本放回數據集D,此樣本在下次採樣中仍然有可能被選中,重複m次這樣的操作,會得到包含m個樣本的數據集D'。顯然有一部分樣本會多次出現在數據集D'中,有一部分樣本不會出現在數據集D'中。據統計,初始數據集D中大約有36.8%的樣本不會出現在採樣數據集D'中。這樣用D'作爲訓練集、D\D'作爲測試集。

自助法產生的數據集改變了初始數據集的分佈,這會引入估計偏差,因此,自助法在數據集很小時是一種有效的劃分方式,在數據集較大時,一般採用留出法和交叉驗證法。

2. 偏差/方差(Bias/Variance)

在機器學習和深度學習中,我們要做的就是找到使得模型誤差最小的參數。所以誤差,是建模中最爲關鍵的因素。一般情況下,誤差由三部分組成,即:

                                                             error = bias^{2}+variance + noise

其中bias爲偏差,variance爲方差,noise爲噪聲。

偏差度量了學習算法的預測值和真實值偏離程度,即刻畫學習算法本身的擬合能力方差度量了同樣大小的訓練集的變動所導致的學習性能的變化,刻畫了數據擾動所造成的影響噪聲表達了當前任務上任何學習算法所能達到的預期泛化誤差的下界,即刻畫了學習問題本身的難度。而本小節只考慮偏差和方差之間的權衡。

              

在上面的左圖中,線性模型不能很好的擬合數據,從而造成了high bias,這時候模型是欠擬合,也就是模型過於簡單了;右圖中的模型對所有的樣本都正確的分類,模型的擬合能力很強以致於把訓練樣本自身的特徵當做了所有潛在樣本都會具有的一般特徵,導致了模型的泛化能力差,即在測試集上的誤差較大,這就造成了high variance,這時模型是過擬合。中圖的模型是一個恰到好處的模型,既較好的擬合(沒有過度擬合)了數據,也有較好的泛化能力。

可以看到,左圖和右圖是不能同時達到的,bias和variance之間有個權衡,其取值與訓練程度之間的關係如下:

                                        

可以看到,在虛線處,模型的泛化誤差最小,虛線之後,隨着模型複雜度的增加,模型的偏差越來越低,方差越來越高,同時模型的泛化誤差越來越高。

關於bias和variance的種類可以用下面的靶向圖形象的表示

                                                      

我們最不希望看到的情況就是模型的偏差和方差都很高,如下圖所示:

                                                      

上圖中的模型將數據中的噪聲(衆多黑圈中的紅叉和衆多紅叉中的黑圈)學習了,反而更一般的特徵沒有學習到。關於偏差和方差的更詳細的分析可以參考這篇文章

3. 機器學習基礎(Basic 'recipe' for machine learning)

在建模中,解決high bias和high variance的過程:

                                     

4. 正則化(Regularization)                                       

在上面一小節我們可以知道,可以通過增加數據量來防止過擬合(或者解決high variance問題),但是通常獲取更多的數據成本比較高,因此常用的防止過擬合的策略是正則化。所謂正則化就是在代價函數後面加入正則化項。

4.1 邏輯迴歸:

加入L_{2}正則化項後的代價函數:

                                                              J(w,b) = \frac{1}{m}\sum_{i=1}^{m}l(\hat{y^{(i)}},y^{(i)}) + \frac{\lambda}{2m}||w||_{2}^{2}         

L_{2}正則化: \frac{\lambda}{2m}||w||_{2}^{2} = \frac{\lambda}{2m}\sum_{j = 1}^{n}w_{j}^{2} = \frac{\lambda}{2m}w^{T}w,L_{2}正則項前的係數之所以取\frac{\lambda}{2m},是爲了對||w||^{2}_{2}求導後能將係數2約掉。

L_{1}正則化:\frac{\lambda}{2m}||w||_{1} = \frac{\lambda}{2m}\sum_{j = 1}^{n}|w_{j}|

\lambda爲正則化因子,其取值大於0。在python中,因爲lambda是定義匿名函數的關鍵字,所以通常用變量lambd表示參數\lambda

4.2 神經網絡

加入L_{2}正則化項後的代價函數:

                                                   J(w^{[1]},b^{[1]}...w^{[l]},b^{[l]}) = \frac{1}{m}\sum_{i=1}^{m}l(\hat{y^{(i)}},y^{(i)}) + \frac{\lambda}{2m}\sum_{l= 1}^{L}||w^{[l]}||_{F}^{2}

其中||w^{[l]}||^{2}_{F} = \sum_{i=1}^{n^{[l-1]}}\sum_{j=1}^{n^{[l]}}(w_{ij}^{[l]})^{2}(n^{[l-1]},n^{[l]})w的維度,該矩陣範數稱爲:Frobenius norm.

因爲在神經網絡中需要進行反向傳播,所以需要知道在加入正則項後的權值矩陣W的梯度:

                                                         dW^{[l]} = (from backprop) + \frac{\lambda}{m}W^{[l]}

代入梯度更新公式W^{[l]} := W^{[l]} - \alpha \ dW^{[l]}得:

                                                    W^{[l]} := W^{[l]}-\alpha[(from backprop) + \frac{\lambda}{m}W^{[l]}] \\ = W^{[l]} - \alpha\frac{\lambda}{m}W^{[l]} - \alpha(from backprop)\\ = (1-\frac{\alpha\lambda}{m})W^{[l]} - \alpha(from backprop)

因爲\alpha > 0,\lambda > 0,所以\frac{\alpha\lambda}{m} > 0,那麼(1-\frac{\alpha\lambda}{m}) < 1,這樣會給原來的W^{[l]}一個衰減的參數,所以L_{2}正則化也被稱爲“權重衰減(Weight decay)”

4.3 \large L_{1}正則和\large L_{2}正則

既然說到了正則化,就不得不說L_{1}正則和L_{2}正則的區別和聯繫,儘管這不是吳恩達老師課程中的內容。

首先L_{1}正則和L_{2}正則都可以防止過擬合(爲什麼正則化可以防止過擬合將在下一小節說明),除此之外L_{1}正則更容易獲得“稀疏解”,即它求得的w會有更少的非零分量。可以從下面兩個角度進行說明:

1. 貝葉斯角度

L_{1}正則化相當於對模型參數w引入了拉普拉斯先驗,而L_{2}正則化相當於對模型參數w引入了高斯先驗,拉普拉斯分佈和高斯分佈的曲線圖如下(圖片來自百面機器學習):

            

可以看到高斯分佈在極值點處是平滑的,也就是高斯先驗分佈認爲w在極值點附近取不同值的可能性是接近的,這就是L_{2}正則化只會讓參數w接近0點,而不會等於0的原因;拉普拉斯分佈在極值點處是一個尖峯,所以拉普拉斯先驗分佈中參數w取值爲0的可能性要更高。

2. 解空間角度

帶正則項和帶約束條件是等價的,可以看做正則項是在最優化問題上加了個約束條件,L_{1}正則化的解空間是一個菱形,而L_{2}正則化的解空間是一個圓形,如下圖所示(圖片來自西瓜書):

                                                           

可以看到L_{1}正則化與平方誤差項等值線的交點常出現在座標軸上,這就意味着w_{1}w_{2}爲0,而L_{2}正則化與平方誤差項等值項的交點通常出現在某個象限中,即w_{1}w_{2}都不爲0,所以L_{1}正則化更容易得到稀疏解。

5. 爲什麼正則化可以防止過擬合(Why regularization reduce overfiting)

神經網絡的有正則化項的代價函數如下:

                                             J(w^{[1]},b^{[1]}...w^{[l]},b^{[l]}) = \frac{1}{m}\sum_{i=1}^{m}l(\hat{y^{(i)}},y^{(i)}) + \frac{\lambda}{2m}\sum_{l= 1}^{L}||w^{[l]}||_{F}^{2}

我們的目的是要最小化代價函數,當\lambda取值較大時,爲了是代價函數最小,就需要讓參數w儘量小,這時神經網絡中很多神經元的權重就變小了,即某些網絡的影響變小了,相當於網絡變的簡單了,從而防止了過擬合。

另一種解釋:

假設激活函數爲g(z) = tanh(z),其函數圖像如下:

                                                            

可以看到在x取值較小時,即紅色曲線部分,這部分曲線是接近於線性的,加入正則化項後,w會變小,那麼Z也會變小,此時激活函數的作用類似於線性函數,前面說過線性函數的線性疊加還是線性函數,所以這是神經網絡類似於一個線性模型,這也簡化了網絡,從而達到防止過擬合的目的。

6. Dropout正則化(Drop regularization)

Dropout(隨機失活)是爲每一個神經元節點設置一個隨機失活的概率,對於保留下來的節點,我們將會得到節點較少,規模較小的網絡。下面的左圖是一個全連接網絡,右圖是一個經過Dropout後的網絡。

               

Inverted dropout:

# 神經元保留概率
keep_pro = 0.8      
# d3爲一個隨機矩陣,矩陣中元素爲True或False             
d3 = np.random.rand(a3.shape[0],a3.shape[1])<keep_pro
# 使a3中的某些元素爲0,即其對應的神經元失活
a3 = np.multiply(a3,d3)
a3 /= keep_pro

說明一下最後一句 a3 /= keep_pro. 上面將keep_pro設置爲0.8,那麼有20%的神經元會失活,即a^{[3]}中有20%的元素爲0,在下一層的計算中有Z^{[4]} = W^{[4]}a^{[3]} + b^{[4]},爲了不影響Z^{[4]}的期望值,所以需要W^{[4]}a^{[3]}除以keep_pro.

7. 理解Dropout(Understanding Dropout)

這裏我們以單個神經元入手,單個神經元的工作就是接收輸入,併產生一些有意義的輸出,但是加入了Dropout以後,輸入的特徵都是有可能會被隨機清除的,所以該神經元不會再特別依賴於任何一個輸入特徵,也就是說不會給任何一個輸入設置太大的權重。

所以通過傳播過程,dropout將產生和L2範數相同的收縮權重的效果。

對於不同的層,設置的keep_prob也不同,一般來說神經元較少的層,會設keep_prob=1.0神經元多的層,則會將keep_prob設置的較小

7.1 dropout爲什麼可以防止過擬合

dropout能防止過擬合的第一感覺是因爲它使一些神經元失活了,從而使得網絡規模更小,模型變的更簡單,其實我們還可以從其它的角度去思考這個問題。

1. dropout有取平均的作用:dropout掉不同的隱藏神經元就類似在訓練不同的網絡,隨機刪掉一半隱藏神經元導致網絡結構已經不同,整個dropout過程就相當於對很多個不同的神經網絡取平均。而不同的網絡產生不同的過擬合,一些互爲“反向”的擬合相互抵消就可以達到整體上減少過擬合。

2. dropout可以減少神經元之間複雜的共適應關係:因爲dropout程序導致兩個神經元不一定每次都在一個dropout網絡中出現。這樣權值的更新不再依賴於有固定關係的隱含節點的共同作用,阻止了某些特徵僅僅在其它特定特徵下才有效果的情況 。迫使網絡去學習更加魯棒的特徵 ,這些特徵在其它的神經元的隨機子集中也存在。換句話說假如我們的神經網絡是在做出某種預測,它不應該對一些特定的線索片段太過敏感,即使丟失特定的線索,它也應該可以從衆多其它線索中學習一些共同的特徵。從這個角度看dropout就有點像L1,L2正則,減少權重使得網絡對丟失特定神經元連接的魯棒性提高。

8. 其它正則化方法(other regularization methods)

8.1 數據擴增

前面說過,防止過擬合的其中一種方式是增加數據量,但是有時候獲取大量數據的成本比較高,這時我們就可以根據已有數據進行一些數據擴增,比如在做圖像處理時,圖像的數量較少時,我們可以通過翻轉圖像,裁剪圖像等獲得更多的數據。

               

8.2 Early stopping

early shopping就是提前停止訓練神經網絡,在泛化誤差還沒有增加的時候停止。

                                

9. 歸一化輸入(Normalizing inputs)

歸一化就是讓數據點更加均勻的分佈在原點附近,如下圖所示。                          

                          

具體的歸一化公式爲:x = \frac{x-\mu}{\sigma^{2}},其中\mu爲樣本均值,\sigma^{2}爲樣本方差。

那麼爲什麼要對數據進行歸一化呢,因爲如果各個特徵有不同的量綱有較大差距,那麼每個特徵對應的權重會有很大的差距,這樣以來代價函數的反應到圖像上就如左邊兩幅圖,在這種情況下代價函數的優化速度會非常慢;而進行歸一化後,其代價函數圖像如右邊兩幅圖,形狀比較規則,在這種情況下梯度下降速度會很快。

                             

10. 梯度消失/梯度爆炸(Vanishing/exploding gradients)

當神經網絡較深時,容易發生梯度消失和梯度爆炸的現象,假設有如下的網絡(每一層只有兩個神經元):

                          

爲了計算簡單,令激活函數爲線性函數即g(z) = z,令偏差b^{[l]} = 0,那麼容易得到以下式子:

                                                                  \hat{y} = W^{[L]}W^{[L-1]}...W^{[3]}W^{[2]}W^{[1]}X

如果權重矩陣W^{[l]}的元素大於1:

W^{[l]} = \begin{bmatrix} 1.5 & 0\\ 0 & 1.5 \end{bmatrix},那麼有\hat{y} = W^{[l]}\begin{bmatrix} 1.5 & 0\\ 0& 1.5 \end{bmatrix}^{[l-1]} X,激活函數的值指數級增加

如果權重矩陣W^{[l]}的元素小於1:

W^{[l]} = \begin{bmatrix} 0.5 & 0\\ 0 & 0.5 \end{bmatrix},那麼有\hat{y} = W^{[l]}\begin{bmatrix} 0.5 & 0\\ 0& 0.5 \end{bmatrix}^{[l-1]} X,激活函數的值指數級減小

實際上,上面是前向傳播的過程,是激活函數的值的增減變化,並不是梯度的指數級增加或指數級下降;對於反向傳播,梯度的變化情況實際上是和前向傳播中激活函數的變化情況是類似的。

在梯度函數上出現的以指數級遞增或者遞減的情況就分別稱爲梯度爆炸或者梯度消失。

關於如何解決梯度爆炸和梯度消失問題,可以看這篇文章

11. 神經網絡的權值初始化(Weight initialization for deep network)

利用權值初始化可以在一定程度上緩解梯度消失和梯度爆炸的問題,以單個神經元爲例:

                                                     

在忽略偏置b的情況下,有:z = w_{1}x_{1} + w_{2}x_{2} + ... + w_{n}x_{n},爲了防止z過大或過大,當神經元的特徵數n比較大時,我們希望w_{i}較小,這樣纔會使得每一項w_{i}x_{i}比較小,從而使得每一項的和z不會太大。通常令w_{i}的方差爲\frac{1}{n},即Var(w_{i}) = \frac{1}{n}

參數初始化的代碼實現爲:

# 服從標準正態分佈的矩陣乘以wi的標準差
wl = np.random.randn(wl.shape[0],wl.shape[1])*np.sqrt(1/n)

當激活函數爲tanh時,通常令Var(w_{i}) = \frac{1}{n};當激活函數爲ReLu時,通常令Var(w_{i}) = \frac{2}{n}。其中n爲第l層每個神經元的輸入特徵數,即n = n^{[l-1]}

12. 梯度的數值逼近(Numerical approximation of gradients)

使用雙邊誤差去逼近導數要比單邊誤差逼近導數精確的多。

                         

雙邊誤差(實際上就是高等數學中的導數的定義):

                                                                    f'(x) = \lim_{x \to 0}\frac{f(x+\varepsilon)-f(x-\varepsilon)}{2\varepsilon}

單邊誤差:

                                                                           f'(x) = \lim_{x \to 0}\frac{f(x+\varepsilon)-f(x)}{\varepsilon}

假設上面的函數爲f(\theta) = \theta^{3},那麼f(\theta)\theta = 1處的導數爲:f'(\theta)_{\theta = 1} = 3\theta^{2}_{\theta = 1} = 3,由雙邊誤差求得的f'(1) = \frac{(1.01)^3-(0.99)^3}{2*0.01} = 3.0001,誤差爲0.0001 = \varepsilon^{2};而由單邊誤差求得的f'(1) = \frac{(1.01)^3-(1)^3}{0.01} = 3.0301,誤差爲0.0301 \approx 3\varepsilon,明顯可以看到由雙邊誤差求得的導數的精度更高。

13. 梯度檢驗(Gradient checking)

在做梯度檢驗之前首先將參數W^{[1]},b^{[1]},...,W^{[L]},b^{[L]}連接爲一個向量\theta;將梯度dW^{[1]},db^{[1]},...,dW^{[L]},db^{[L]}連接爲一個向量d\theta.

                      

接下來用上一小節中講到的雙邊誤差求得近似梯度,然後比較其與實際梯度的差值,判斷近似梯度d\theta_{appro}與實際梯度d\theta的接近程度,具體的衡量公式爲:

                                                                                \frac{||d\theta_{appro}-d\theta||_{2}}{||d\theta_{appro}||_{2}+||d\theta||_{2}}

其中||\cdot ||_{2}爲歐幾里得範數,其爲向量各元素的平方的和,然後開平方。若上面公式的值小於10^{-7},那麼說明梯度沒問題,如果小於10^{-5},則需要檢驗程序中是否有bug

                            

14. 梯度檢驗的注意事項(Gradients checking implementation notes)

1、不要在訓練過程中使用梯度檢驗,只在debug的時候使用,使用完畢關閉梯度檢驗的功能;
2、如果算法的梯度檢驗出現了錯誤,要檢查每一項,找出錯誤,也就是說要找出哪個d\theta_{appro}[i]d\theta[i]的值相差比較大;
3、不要忘記了正則化項;
4、梯度檢驗不能與dropout同時使用。因爲每次迭代的過程中,dropout會隨機消除隱層單元的不同神經元,這時是難以計算dropout在梯度下降上的代價函數J;

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