1. 程式人生 > >深度學習常見策略總結(優化器選擇,防止過擬合策略)

深度學習常見策略總結(優化器選擇,防止過擬合策略)

1. 優化器的選擇

 關於深度學習各種優化器的介紹和對比在網上有很多圖文並茂的講解,比如我上一篇博文轉載的文章:深度學習——優化器演算法Optimizer詳解(BGD、SGD、MBGD、Momentum、NAG、Adagrad、Adadelta、RMSprop、Adam)。有需要的可以移步去學習。

2. 防止過擬合策略

我們在進行深度學習模型訓練時候,很容易出現過擬合現象:訓練集準確率高,測試集準確率低。過擬合產生的原因可以分為兩個:(1)訓練資料不夠,無法對整個資料分佈進行評估;(2)引數學習迭代次數過多,擬合了訓練資料中的噪聲和訓練樣例中沒有代表性的特徵。

如何解決過擬合的問題呢?

(1)資料集擴增

針對過擬合原因的第一種情況,當然是選擇資料集擴增的方法來防止過擬合了。常見的資料集擴增方法有:

  • 從資料來源獲取更多資料
  • 資料增強(Data Augmentation):通過一定規則擴充資料。如在物體分類問題裡,物體在影象中的位置、姿態、尺度,整體圖片明暗度等都不會影響分類結果。我們就可以通過影象平移、翻轉、縮放、切割等手段將資料庫成倍擴充;
  • 根據當前資料集估計資料分佈引數,使用該分佈產生更多特徵。(這種方法不推薦,因為我們一般是不清楚分佈特徵的,或者不能全面總結出特徵,否則模型的學習就無意義了,如果我們根據自己片面的理解擴增的資料集用於訓練,會影響模型的實際效能)

(2)Early stopping

深度學習模型如CNN對網路引數學習更新過程,會使用一些優化器(第一部分所講)不斷迭代,如梯度下降(Gradient descent)學習演算法。Early stopping就是在多個連續Epoch迭代中,模型的準確率不再變化,或者微弱變化時候就停止訓練,防止後面學習到與資料分佈特徵無關的噪聲。

(3)正則化(Regularization)

正則化是機器學習中常用的防止過擬合方法,通過將權值大小加入到Cost裡面,訓練時候限制權值變大。

模型越複雜,越容易過擬合。原先以最小化損失(經驗風險最小化)為目標:

現在加入正則化後以最小化損失和模型複雜度(結構風險最小化)為目標:

通過降低複雜模型的複雜度來防止過擬合的規則稱為正則化。

也就是說當我們有很多特徵變數時,其中每一個變數都能對預測產生一點影響。所以要保留全部的特徵變數。正如我們在房價預測的例子中看到的那樣,我們可以有很多特徵變數,其中每一個變數都是有用的,因此我們不希望把它們刪掉,這就導致了正則化概念的發生。[4]

更通俗直觀的理解如下:

image

如上圖,如果用一個二次函式來擬合這些資料,那麼能達到一個很好的擬合效果。然而,如果我們用一個更高次的多項式去擬合,最終我們可能會得到一個曲線,它能很好地擬合訓練集,但卻並不是一個好的結果,因為它過度擬合了資料,因此,一般性並不是很好。

因此,我們考慮在原先的損失函式中加上懲罰項,從而使引數 θ3 和 θ4 足夠的小。就可以上圖中X^3和X^4對預測結果的影響。

原來的代價函式(均方誤差):

我們人為加入引數的懲罰項後:

這裡的1000是我隨意設定的值(實際是正則2的引數 λ)。在原有代價函式的基礎上加上 1000 乘以 θ3 和θ4這一項後,只有將 θ3 和 θ4 的值接近於 0,才能使代價函式最小化,就像我們忽略了這兩個值一樣。如果我們做到這一點( θ3 和 θ4 接近 0 ),那麼我們將得到一個近似的二次函式。

image

因此,我們最終恰當地擬合了資料,我們所使用的正是二次函式加上一些非常小,貢獻很小項(因為這些項的 θ3、 θ4 非常接近於0)。顯然,這是一個更好的假設。

上面僅僅是一個便於理解的例子,我們指定了只懲罰引數θ3 和 θ4 ,實際中我們不知道哪些引數重要,所以會懲罰所有的引數,即:

下面就是正則化項,  λ 在這裡我們稱為正則化引數。

image

正則化有L1和L2兩種,它們的具體可以在網上找到介紹,如[5]。總體來說,L1 正則化可以理解為每次從權重中減去一個常數。

L2 正則化可以理解為每次移除權重的 x%。本質都是為了降低模型的複雜度,防止過擬合。

 

(4)Dropout函式

我們知道如果要訓練一個大型的網路,訓練資料很少的話,那麼很容易引起過擬合(也就是在測試集上的精度很低),可能我們會想到用L2正則化、或者減小網路規模。然而深度學習領域大神Hinton,在2012年文獻中[6]提出在每次訓練的時候,讓一半的特徵檢測器停過工作,這樣可以提高網路的泛化能力,Hinton又把它稱之為dropout。

Hinton認為在神經網路產生過擬合主要是因為神經元之間的協同作用產生的。因此在神經網路進行訓練的時候,讓部分神經元失活,這樣就阻斷了部分神經元之間的協同作用,從而強制要求一個神經元和隨機挑選出的神經元共同進行工作,減輕了部分神經元之間的聯合適應性。

Dropout的實現說的簡單一點就是我們讓在前向傳導的時候,讓某個神經元的啟用值以一定的概率p,讓其停止工作,示意圖如下。加入Dropout後,反向傳播訓練肯定會受影響,所以具體實現就需要仔細看看論文和原始碼裡是怎麼做的。

Keras裡面的Dropout原始碼如下。函式中,x是本層網路的啟用值。Level就是dropout就是每個神經元要被丟棄的概率。不過對於dropout後,為什麼需要進行rescale(即除以retain_prob)我也不太理解,附上論文地址[7]以及此部分參考文獻[8],有空再學習一下。

#dropout函式的實現  
def dropout(x, level):  
    if level < 0. or level >= 1:#level是概率值,必須在0~1之間  
        raise Exception('Dropout level must be in interval [0, 1[.')  
    retain_prob = 1. - level  
    #我們通過binomial函式,生成與x一樣的維數向量。binomial函式就像拋硬幣一樣,我們可以把每個神經元當做拋硬幣一樣  
    #硬幣 正面的概率為p,n表示每個神經元試驗的次數  
    #因為我們每個神經元只需要拋一次就可以了所以n=1,size引數是我們有多少個硬幣。  
    sample=np.random.binomial(n=1,p=retain_prob,size=x.shape)#即將生成一個0、1分佈的向量,0表示這個神經元被遮蔽,不工作了,也就是dropout了  
    print sample  
    x *=sample#0、1與x相乘,我們就可以遮蔽某些神經元,讓它們的值變為0  
    print x  
    x /= retain_prob  
  
    return x  
#對dropout的測試,大家可以跑一下上面的函式,瞭解一個輸入x向量,經過dropout的結果  
x=np.asarray([1,2,3,4,5,6,7,8,9,10],dtype=np.float32)  
dropout(x,0.4)

(5)Batch Normalization(批標準化)[1][2]

目前BN是深度學習中較好的一種優化策略。在優化效能很大程度上超越了正則化和Dropout策略。它的優勢可以總結如下三點[3]:

  • 提高了網路的訓練速度,收斂過程大大加快。可以選擇較大的初始學習率,同時學習率的衰減速度也會變大,就加快了網路的收斂,不需要像之前一樣慢慢調整學習率。
  • 提高了網路泛化能力。可以不用理會過擬閤中的dropout、L2正則項引數的選擇問題。

      BN正則化模型:使用BN訓練時,一個樣本只與minibatch中其他樣本有相互關係;對於同一個訓練樣本,網路的輸出會發生        變化。這些效果有助於提升網路泛化能力,像dropout一樣防止網路過擬合,同時BN的使用,可以減少或者去掉dropout類似        的策略

  • 不需要使用區域性響應歸一化層。BN本身就是一個歸一化網路層。可以採用具有非線性飽和特性的啟用函式(比如:s型啟用函式),因為它可以避免網路陷入飽和狀態。

問題提出:

深度網路引數訓練時內部存在協方差偏移(Internal Covariate Shift)現象:深度網路內部資料分佈在訓練過程中發生變化的現象。

為什麼會帶來不好影響:訓練深度網路時,神經網路隱層引數更新會導致網路輸出層輸出資料的分佈發生變化,而且隨著層數的增加,根據鏈式規則,這種偏移現象會逐漸被放大。這對於網路引數學習來說是個問題:因為神經網路本質學習的就是資料分佈(representation learning),如果資料分佈變化了,神經網路又不得不學習新的分佈。為保證網路引數訓練的穩定性和收斂性,往往需要選擇比較小的學習速率(learning rate),同時引數初始化的好壞也明顯影響訓練出的模型精度,特別是在訓練具有飽和非線性(死區特性)的網路,比如即採用S或雙S啟用函式網路,比如LSTM,GRU。[9]

解決辦法:

引入Batch Normalization,作為深度網路模型的一個層,每次先對input資料進行歸一化,再送入神經網路輸入層。

 

關於BN的實現大家可以直接看原文[1],這裡有知乎的一個問題:深度學習中 Batch Normalization為什麼效果好?[10],講解的很細緻,大家可以圍觀。這裡附上兩個關於BN的常見問題[11]:

關於BN的兩點理解: 
1.為什麼它能緩解DNN訓練中的梯度消失/爆炸現象? 
關於梯度消失的一個簡單例子是0.930≈0.040.930≈0.04,而BN通過歸範化各層的輸入資料使得原本會減小的data value的scale變大,這樣反向求出的梯度scale應該也會相應增大。 
2.為什麼在normalize後還有一個scale and shift操作? 
就像上面演算法註釋解釋的,僅是簡單的對網路層輸入作歸一化可能會改變原本的輸入表示,而加入scale and shift操作,讓歸一化操作有機會通過對引數γ,βγ,β 的學習將其變回去,不改變輸入表示。

 

參考文獻

[1] Batch Normalization: Accelerating Deep Network Training b y Reducing Internal Covariate Shift

[2] Batch Normalization 學習筆記

[3] 深入理解Batch Normalization批標準化

[4] 機器學習之正則化(Regularization)

[5]【一看就懂】機器學習之L1和L2正則化

[6] 《Improving neural networks by preventing co-adaptation of feature detectors》

[7] Regularization of Neural Networks using DropConnect

[8] 深度學習之-Dropout的講解(5)

[9] <深度學習優化策略-1>Batch Normalization(BN)

[10] 深度學習中 Batch Normalization為什麼效果好?

[11]關於深度學習中的Batch normalization的理解