1. 程式人生 > >cs231n 批量歸一化的引數優化

cs231n 批量歸一化的引數優化

 

1

啟用函式(Activation functions)

          - 資料預處理(Data Preprocessing)

          - 權重初始化(Weight Initialization)

          -

正則化(Regularization:避免過擬合的一種技術)

          - 梯度檢查(Gradient checking)

    2)動態訓練(Training dynamics)
          - 跟蹤學習過程 (Babysitting the learning process)

          - 引數更新 (Parameter updates)

          - 超級引數優化(Hyperparameter optimization)

          - 批量歸一化(BN:Batch Normalization:解決在訓練過程中資料分佈發生改變的問題以防止梯度消失或爆炸、加快訓練速度
    3)評估(Evaluation)
          - 模型組合(Model ensembles)

             (訓練多個獨立的模型取這些模型結果的平均值)

   神經網路學習過程本質就是為了:學習資料分佈

那麼網路的泛化能力也大大降低使訓練資料與測試資料的分佈相同。

2. 啟用函式(Activation Functions)

    詳細內容參見:啟用函式

    總結:

     1)使用ReLU時     2)嘗試使用Leaky ReLU/Maxout/ELU

     3)可以使用tanh     4)不要使用sigmoid

 

3. 資料預算處理(Data Preprocessing)

        

     1)為什麼輸入資料需要歸一化(Normalized Data)?

           歸一化後有什麼好處呢?原因在於神經網路學習過程本質就是為了學習資料分佈那麼網路的泛化能力也大大降低;另外一方面那麼網路就要在每次迭代都去學習適應不同的分佈這也正是為什麼我們需要對資料都要做一個歸一化預處理的原因。

          對於深度網路的訓練是一個複雜的過程那麼後面幾層就會被累積放大下去。一旦網路某一層的輸入資料的分佈發生改變所以如果訓練過程中那麼將會影響網路的訓練速度。

4. 權重初始化(Weight Initialization)

    1)小的隨機數

         w= 0.01 * np.random.randn(fan_in    2)神經元將飽和         w = 1.0 * np.random.randn(fan_in    3)合理的初始化(Xavier init)

         w = np.random.randn((fan_in    權重初始化是一個重要的研究領域。

5. 批量歸一化(BN: Batch Normalization)

5.1 BN訓練    

    1)隨機梯度下降法(SGD)對於訓練深度網路簡單高效就是需要我們人為的去選擇引數以至於我們很多時間都浪費在這些的調參上。那麼使用BN(詳見論文《Batch Normalization_ Accelerating Deep Network Training by Reducing Internal Covariate Shift》)之後可以不需要那麼刻意的慢慢調整引數

    2)神經網路一旦訓練起來除了輸入層的資料外(因為輸入層資料後面網路每一層的輸入資料分佈是一直在發生變化的前面層訓練引數的更新將導致後面層輸入資料分佈的變化。以網路第二層為例:網路的第二層輸入而第一層的引數在整個訓練過程中一直在變化資料分佈的改變稱之為:“Internal  Covariate Shift”。Paper所提出的演算法中間層資料分佈發生改變的情況這個牛逼演算法的誕生。

   3)BN的地位:與啟用函式層、卷積層、全連線層、池化層一樣   4)BN的本質原理:在網路的每一層輸入的時候也就是先做一個歸一化處理(歸一化至:均值0、方差為1)可不像我們想象的那麼簡單一個可學習、有引數(γ、β)的網路層

   5)歸一化公式:

        

   6)如果是僅僅使用上面的歸一化公式然後送入網路下一層B你強制把它給我歸一化處理、標準差也限制在了1這樣就相當於我這一層網路所學習到的特徵分佈被你搞壞了引入了可學習引數γ、β       

       上面的公式表明引數γ、β是可以恢復出原始的某一層所學到的特徵的。

   

     7)引入了這個可學習重構引數γ、β             

             

 

     8)BN層是對於每個神經元做歸一化處理而不是對一整層網路的神經元進行歸一化。既然BN是對單個神經元的運算每個特徵圖的大小是100*100如果採用BN這樣豈不是太恐怖了。因此卷積層上的BN使用把一整張特徵圖當做一個神經元進行處理。

    9)卷積神經網路經過卷積後得到的是一系列的特徵圖那麼網路某一層輸入資料可以表示為四維矩陣(m,wm為min-batch sizesw、h分別為特徵圖的寬高。在CNN中我們可以把每個特徵圖看成是一個特徵處理(一個神經元)mini-batch size 的大小就是:m*w*h這就是相當於求取所有樣本所對應的一個特徵圖的所有神經元的平均值、方差    10)    在使用BN前減小學習率、小心的權重初始化的目的是:使其輸出的資料分佈不要發生太大的變化。

    11) BN的作用:

       1)改善流經網路的梯度

       2)允許更大的學習率大幅提高訓練速度

            你可以選擇比較大的初始學習率甚至在網路訓練到一半的時候現在我們可以採用初始很大的學習率因為這個演算法收斂很快。當然這個演算法即使你選擇了較小的學習率因為它具有快速訓練收斂的特性;

       3)減少對初始化的強烈依賴

       4)改善正則化策略:作為正則化的一種形式            你再也不用去理會過擬閤中drop out、L2正則項引數的選擇問題你可以移除這兩項了引數因為BN具有提高網路泛化能力的特性;

       5)再也不需要使用使用區域性響應歸一化層了(區域性響應歸一化是Alexnet網路用到的方法因為BN本身就是一個歸一化網路層;

       6)可以把訓練資料徹底打亂(防止每批訓練的時候文獻說這個可以提高1%的精度)。

       注:以上為學習過程均值和方差(mean/std)不基於小批量進行計算     

5.2 BN測試

     1)實際測試時         

        這裡的均值和方差已經不是針對某一個Batch了在訓練過程中除了正常的前向傳播和反向求導之外以便訓練完成之後按照下式計算整體的均值和方差:  

         

 

       上面簡單理解就是:對於均值來說直接計算所有batch u值的平均值;然後對於標準偏差採用每個batch σB的無偏估計。最後測試階段        

     2)BN可以應用於一個神經網路的任何神經元上。文獻主要是把BN變換啟用函式層是這樣的:

                              z=g(Wu+b)

          也就是我們希望一個啟用函式比如s型函式s(x)的自變數x是經過BN處理後的結果。因此前向傳導的計算公式就應該是:
                              z=g(BN(Wu+b))

          其實因為偏置引數b經過BN層後其實是沒有用的當然BN層後面還有個β引數作為偏置項                               z=g(BN(Wu))

 

6. 跟蹤訓練過程

   1)Learning Rate

         - Learning Rate太小(如1e-6)         - Learning Rate太大(如1e-6)cost增長爆炸 (cur cost > 3* original cost)

         - 在[1e-3       

     2)Mini-batch SGD

           Loop:

           1. Sample a batch of data

           2. Forward prop it through the graph           3. Backprop to calculate the gradients

           4. Update the parameters using gradient

7. 引數優化

    引數優化直觀顯示圖 

    引數優化的目的是:減少損失(loss)    Caffe Solver7.1 Gradient Descent Variants

7.1.1 Batch gradient descent

             每次基於整個資料集計算梯度。       
   for i in range(nb_epochs):
     params_grad = evaluate_gradient(loss_function, params)
     params = params - learning_rate * params_grad

7.1.2 SGD(Stochastic Gradient Descent: 隨機梯度下降)

       

     每次基於一個數據樣本計算梯度。

 

  for i in range(nb_epochs):
    np.random.shuffle(data)
    for example in data:
      params_grad = evaluate_gradient(loss_function, params)
      params = params - learning_rate * params_grad

 

 

7.1.3 Mini-batch Gradient Descent

       

    每次基於n個數據樣本計算梯度。

 

  for i in range(nb_epochs):
    np.random.shuffle(data)
    for batch in get_batches(data, batch, params)
      params = params - learning_rate * params_grad
   優點:

 

    1)減少引數更新的變化    2)使用先進的Deep Learning庫    注:n一般取[50視具體應用而定。

7.1.4 梯度下降演算法面臨的挑戰

   1)選擇合適的Learning Rate是困難的太大阻礙收斂或且導致損失函式在最小值附近波動或發散;
   2)預先定義的Learning Rate變動規則不能適應資料集的特性;
   3)同樣的Learning Rate運用到所有的引數更新(後面的AdaGrad, RMSProp, Adam為解決此問題而生);
   4)最小化高度非凸損失函式的羝問題是:避免陷入眾多的區域性最優值。    

 

7.2 Momentum(動量)

     關鍵優點: 利用物體運動時的慣性且減少振盪。

      關鍵缺點:球盲目地沿著斜坡向山下滾。

       

     當Loss function的表面曲線的一維比其它維有更多的溝壑時如上圖左邊所示然後猶猶豫豫地向區域性最優點前進。

     Momentum即動量即更新的時候在一定程度上保留之前更新的方向可以在一定程度上增加穩定性並且還有一定擺脫區域性最優的能力: 

    # Momentum update
    V = gama * V + learning_rate * dw  # integrate velocity
    w -= V                             # integrate position

     就是Momentum0.9有時隨著時間而變化表示要在多大程度上保留原來的更新方向在訓練開始時所以初始值一般選為0.5;當梯度不那麼大時即當前batch的梯度多大程度上影響最終更新方向之和不一定為1。

     Momentum的物理解釋是:當我們把球推下山時速度越來越快(直到其最大速度,<1)梯度方向不停變化的維度的動量不停地減少更快的收斂速度並減少振盪

     

7.3 Nesterov Accelerated Gradient (NAG)

      關鍵優點:一個聰明的球且知道在斜坡向上之前減速。

                        沿著當前方向然後再看向哪個方向走最快可以做出明智的決策。

    

     

     

   w_ahead = w - gama * v
   # evaluate dw_ahead (the gradient at w_ahead instead of at w)
   v = gama * v + learning_rate * dw_ahead
   w -= v

 

       Momentum:

            1)計算當前的梯度(上圖中:比較小的藍色向量)

            2)沿著更新的累積的梯度方向進行一大跳(上圖中:比較大的藍色向量)

       NAG:

            1)沿著以前累積的梯度方向進行一大跳 (上圖中:棕色向量)

            2)在新的位置測量梯度            3)這個有預料的更新可以防止走的太快並導致增加的響應

       關鍵區別:

            1)計算梯度的位置不一樣

  

7.4 每個引數有自適應的學習率(Per-parameter Adaptive Learning Rate)

      本章描述的方法(AdaGrad、AdaDelta、RMSprop、Adam)專為解決Learning Rate自適應的問題。

      前面討論的基於梯度的優化方法(SGD、Momentum、NAG)的Learning Rate是全域性的      引數的有些維度變化快有些維度是正的斜坡(如鞍點);採用相同的Learning Rate是不科學的比如有的引數可能已經到了僅需要微調的階段還需要較大幅度的調動。理想的方案是根據引數每個維度的變化率      下面討論如何自適應Learing Rate的方案:AdaGrad、AdaDelta、RMSProp、Adam。

7.4.1 AdaGrad(Adaptive Gradient )

     關鍵優點:不需要手動調整Learning Rate      關鍵缺點:在分母中累積了梯度的平方從而導致Learning Rate單調遞減從而不能再學到相關知識(AdaDelta、RMSprop、Adam專為解決此問題而生)。

     AdaGrad方法給引數的每個維度給出適應的Learning Rate。給不經常更新的引數以較大的Learning Rate     在AdaGrad中     其公式如下:

    
θi

     其示意程式碼如下:

 

# Assume the gradient dx and parameter vector x
cache += dx**2
x -= learning_rate * dx / (np.sqrt(cache + 1e-8))

 

     learning_rate 是初始學習率所以初始值就不像之前的演算法那樣重要了。而1e-8指一個比較小的數     其含義是隨著其更新的總距離增多7.4.2 AdaDelta (Adaptive Delta)

    關鍵優點:1) 解決了AdaGrad Learning Rate單調遞減的問題。 (是AdaGrad的擴充套件)

                      2) 不需要設定預設的Learning Rate 

   RMS(Root Mean Squared) : 均方根

   Adagrad演算法存在三個問題:

    1)其學習率是單調遞減的訓練後期學習率非常小
    2)其需要手工設定一個全域性的初始學習率
    3)更新W時左右兩邊的單位不同
    Adadelta針對上述三個問題提出了比較漂亮的解決方案。

    

7.4.3 RMSprop

     RMSprop是由Geoff Hinton設計的。RMSprop與AdaDelta的目的一樣:解決AdaGrad的Learning Rate逐步消失的問題。

    

7.4.4 Adam (Adaptive Moment Estimation)

    Adam的目的是:為每個引數計算自適應的Learning Rate。

    

     其實際效果與AdaDelta、RMSProp相比7.5 優化演算法效果視覺化

    

              SGD optimization on Beale's function

    

                SGD optimization on Long Valley

      

                SGD optimization on Saddle Point

7.6 如何選擇優化演算法

     1)總結:

           - RMSprop是AdaGrad的擴充套件           - RMSprop與AdaDelta相比其它相同

           - Adam與RMSprop相比           - RMSprop、AdaDelta和Adam是非常類似的演算法效果相當

7.7 優化SGD的其它策略

7.7.1 Shuffling and Curriculum Learning

      1)Shuffling:每次迭代前      2)Curriculum Learning:把訓練樣本按某種有意義的方式進行排序7.7.2 批量歸一化Batch Normalization (BN)        

      為了便於訓練通過mean=0我們不同程度地更新引數這將降低訓練速度且放大變化      BN為每一個mini-batch重建歸一化引數。使模型結構的部分進行歸一化且引數初始化要求沒哪麼高。

      此外作為一個正則化(Regularizer)      正則化(Regularizer):是一個用於解決過擬合(Overfitting)問題的一種技術。具體實現方法是在損失函式中增加懲罰因子(引數向量的範數7.7.3 早期停止(Early Stopping)

     在訓練時如果驗證集的錯誤率不能得到改善8. Regularization: Dropout

    在前向計算時如下圖所示:

    

    示意程式碼如下:

    p = 0.5  # probability of keeping a unit active, np.dot(W1, X) + b1)
      M1 = np.random.rand(*H1.shape) < p  # first dropout mask
      H1 *= M1   # drop

      H2 = np.maximum(0, H1) + b2)
      M2 = np.random.rand(*H2.shape) < p  # send dropout mask
      H2 *= M2   # drop 
      out = np.dot(W3一個dropout mask對應一個模型    

在測試時 直接計算每層的啟用值其程式碼如下:
   def predict(X):
      # ensembled forward pass
      H1 = np.maxmium(0,X)+b1) * p  # Note: scale the activations
      H2 = np.maxmium(0,H1)+b2) * p # Note: scale the activations
      out = np.dot(W3,H2) + b3