天天看點

Dropout深入了解

文章目錄

    • 簡介
    • What is dropout?
    • How it works?
    • Dropout in neural networks
      • Training stage
      • Test stage
    • Code implementation
    • Some questions
    • References

簡介

在2012年,Alex、Hinton(大佬們呀)在其論文《ImageNet Classification with Deep Convolutional Neural Networks》中用到了Dropout算法,用于防止過拟合。并且,這篇論文提到的AlexNet網絡模型引爆了神經網絡應用熱潮,并赢得了2012年圖像識别大賽冠軍,使得CNN成為圖像分類上的核心算法模型。部分摘自部落格。

首先我們從神經網絡訓練的兩個難題說起:

  • 費事
  • 易過拟合

這兩個缺點真是抱在深度學習大腿上的兩個大包袱,一左一右,相得益彰,額不,臭氣相投。過拟合是很多機器學習的通病,過拟合了,得到的模型基本就廢了。而為了解決過拟合問題,一般會采用ensemble方法,即訓練多個模型做組合,此時,費時就成為一個大問題,不僅訓練起來費時,測試起來多個模型也很費時。總之,幾乎形成了一個死鎖。

Dropout的出現很好的可以解決這個問題,并在一定程度上達到正則化的效果。

What is dropout?

那麼什麼是Dropout呢?

Dropout是CNN中防止過拟合提高效果的一個大殺器。衆所周知,在訓練深度學習模型時,如果模型的參數太多,而訓練樣本又太少,訓練出來的模型很容易産生過拟合的現象。過拟合具體表現在:模型在訓練資料上損失函數較小,預測準确率較高;但是在測試資料上損失函數比較大,預測準确率較低。

Dropout可以作為訓練深度神經網絡的一種trick供選擇。在每個訓練批次(batch)中,通過忽略一半的特征檢測器(讓一半的隐層節點值為0),可以明顯地減少過拟合現象。這種方式可以減少特征檢測器(隐層節點)間的互相作用(即減弱神經元節點間的聯合适應性,增強了泛化能力。),檢測器互相作用是指某些檢測器依賴其他檢測器才能發揮作用。

Dropout說的簡單一點就是:我們在前向傳播的時候,讓某個神經元的激活值以一定的機率p停止工作,這樣可以使模型泛化性更強,因為它不會太依賴某些局部的特征(或者說不會太依賴于某幾個局部特征的互相作用模型才起作用),如下所示:

Dropout深入了解

對于神經網絡單元,按照一定的機率将其暫時從網絡中丢棄。注意是暫時,對于随機梯度下降來說,由于是随機丢棄,故而每一個mini-batch都在訓練不同的網絡。因而,對于一個有N個節點的神經網絡,有了dropout後,就可以看做是 2 n 2^n 2n個模型的集合了,但此時要訓練的參數數目卻是不變的,這就解脫了費時的問題。(解決過拟合和費時問題的直覺了解)

How it works?

假設我們要訓練這樣一個神經網絡,如下:

Dropout深入了解
Dropout深入了解

輸入是x輸出是y,正常的流程是:我們首先把x通過網絡前向傳播,然後把誤差反向傳播以決定如何更新參數讓網絡進行學習。使用Dropout之後,過程變成如下:

  1. 首先随機(暫時)删掉網絡中一半(比例是個超參)的隐藏神經元,輸入輸出神經元保持不變(下圖中虛線為部分臨時被删除的神經元)
    Dropout深入了解
  2. 然後把輸入x通過修改後的網絡前向傳播,然後把得到的損失結果通過修改的網絡反向傳播。一小批訓練樣本(batch)執行完這個過程後,在沒有被删除的神經元上(即在上圖的網絡中)按照随機梯度下降法更新對應的參數(w,b)。
  3. 然後繼續重複這一過程:
    • 恢複被删掉的神經元(此時被删除的神經元保持原樣,而沒有被删除的神經元已經有所更新)
    • 從隐藏層神經元中随機選擇一個一定比例(如50%)的子集臨時删除掉(備份被删除神經元的參數)。
    • 對一小批訓練樣本,先前向傳播然後反向傳播損失并根據随機梯度下降法更新參數(w,b) (沒有被删除的那一部分參數得到更新,删除的神經元參數保持被删除前的結果)。
    不斷重複這一過程。

Dropout in neural networks

Dropout的具體工作流程上面已經介紹完了,那麼上述操作具體是如何實作的呢?如何用代碼實作dropout呢?

而為了達到ensemble的特性,有了dropout後,神經網絡的訓練和預測就會發生一些變化。下面,我們來具體講解一下Dropout代碼層面的一些公式推導及代碼實作思路。

Training stage

無可避免的,在訓練網絡的每個單元都要添加一道機率流程。如下:

Dropout深入了解

對應的公式變化如下:

  • 沒有dropout的神經網絡:

    z i ( l + 1 ) = w i ( l + 1 ) y l + b i ( l + 1 ) z_{i}^{(l+1)} =\mathbf{w}_{i}^{(l+1)} \mathbf{y}^{l}+b_{i}^{(l+1)} zi(l+1)​=wi(l+1)​yl+bi(l+1)​

    y i ( l + 1 ) = f ( z i ( l + 1 ) ) y_{i}^{(l+1)} =f\left(z_{i}^{(l+1)}\right) yi(l+1)​=f(zi(l+1)​)

  • 有dropout的神經網絡:

    r j ( l ) ∼ Bernoulli ⁡ ( p ) r_{j}^{(l)} \sim \operatorname{Bernoulli}(p) rj(l)​∼Bernoulli(p)

    y ~ ( l ) = r ( l ) ∗ y ( l ) \tilde{\mathbf{y}}^{(l)} =\mathbf{r}^{(l)} * \mathbf{y}^{(l)} y~​(l)=r(l)∗y(l)

    z i ( l + 1 ) = w i ( l + 1 ) y ~ l + b i ( l + 1 ) z_{i}^{(l+1)} =\mathbf{w}_{i}^{(l+1)} \widetilde{\mathbf{y}}^{l}+b_{i}^{(l+1)} zi(l+1)​=wi(l+1)​y

    ​l+bi(l+1)​

    y i ( l + 1 ) = f ( z i ( l + 1 ) ) y_{i}^{(l+1)} =f\left(z_{i}^{(l+1)}\right) yi(l+1)​=f(zi(l+1)​)

上面公式中Bernoulli函數是為了生成機率r向量,也就是随機生成一個0、1的向量。

代碼層面實作讓某個神經元以機率p停止工作(失活),其實就是讓它的激活函數輸出值以機率p變為0。比如我們某一層網絡神經元的個數為1000個,其激活函數輸出值為 y 1 , y 2 , y 3 , . . . . . . , y 1000 y_1, y_2, y_3, ......, y_{1000} y1​,y2​,y3​,......,y1000​,我們dropout比率選擇0.4,那麼這一層神經元經過dropout後,1000個神經元中會有大約400個的值被置為0。(一定是大約400個)

注:經過上面屏蔽掉某些神經元,使其激活值為0以後,我們還需要對向量 y 1 , y 2 , y 3 , . . . . . . , y 1000 y_1, y_2, y_3, ......, y_{1000} y1​,y2​,y3​,......,y1000​進行縮放,也就是乘以 1 / ( 1 − p ) 1/(1-p) 1/(1−p)(其實 p p p為丢棄機率,那麼 ( 1 − p ) (1-p) (1−p)就為保留機率)。如果你在訓練的時候,經過置0後,沒有對 y 1 , y 2 , y 3 , . . . . . . , y 1000 y_1, y_2, y_3, ......, y_{1000} y1​,y2​,y3​,......,y1000​進行縮放(rescale),那麼在測試的時候,就需要對權重進行縮放。

注:在訓練階段,對某一層的激活輸出值進行dropout操作後(此時p為丢棄機率,那麼1-p就為保留機率),為了保證訓練和測試階段,某一層通過的資訊量大小是一定的(自己了解)。可以通過兩種方法來實作:

  1. 在訓練的時候,經過置0後,對 y 1 , y 2 , y 3 , . . . . . . , y 1000 y_1, y_2, y_3, ......, y_{1000} y1​,y2​,y3​,......,y1000​進行縮放(即除以 ( 1 − p ) (1-p) (1−p)),這樣做的目的是:經過縮放後,此時訓練過程中某層每個神經元激活值的輸出期望為: E ( x ) = ( 1 − p ) ( y / ( 1 − p ) ) + p ∗ 0 = y E(x) = (1-p)(y/(1-p)) + p * 0 = y E(x)=(1−p)(y/(1−p))+p∗0=y,是以測試(或預測)階段就不再需要特殊處理了。(後面的代碼示例就是用的這種方式)
  2. 如果在訓練的時候,經過置0後,沒有對 y 1 , y 2 , y 3 , . . . . . . , y 1000 y_1, y_2, y_3, ......, y_{1000} y1​,y2​,y3​,......,y1000​進行縮放(rescale),那麼在測試的時候,就需要對權重進行縮放(乘以失活率p)。此操作如下圖所示:

Test stage

預測模型的時候,每一個神經單元的權重參數要乘以機率p。(如果訓練階段沒有做縮放的話,否則不需要這一步)

Dropout深入了解

測試階段Dropout公式為:

w t e s t ( l ) = p W ( l ) w_{test}^{(l)} = pW^{(l)} wtest(l)​=pW(l)

Code implementation

dropout示例代碼如下:

# coding:utf-8
import numpy as np
 
# dropout函數的實作
def dropout(x, level):
    if level < 0. or level >= 1: #level是機率值,必須在0~1之間
        raise ValueError('Dropout level must be in interval [0, 1[.')
    retain_prob = 1. - level  # 0.6
 
    # 我們通過binomial函數,生成與x一樣的維數向量。binomial函數就像抛硬币一樣,我們可以把每個神經元當做抛硬币一樣
    # 硬币 正面的機率為p,n表示每個神經元試驗的次數
    # 因為我們每個神經元隻需要抛一次就可以了是以n=1,size參數是我們有多少個硬币。
    random_tensor = np.random.binomial(n=1, p=retain_prob, size=x.shape) #即将生成一個0、1分布的向量,0表示這個神經元被屏蔽,不工作了,也就是dropout了
    print('random_tensor:', random_tensor)
    print()
 
    x *= random_tensor
    print('dropoutted:', x)
    
    x /= retain_prob   # 縮放操作:dropout後的資料再除以一個保留機率(1 - 丢棄機率)
    return x
 
#對dropout的測試,大家可以跑一下上面的函數,了解一個輸入x向量,經過dropout的結果  
x=np.asarray([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], dtype=np.float32)
print('x: ', x)
dropout(x, 0.4)
           

運作結果如下所示,想必現在大家應該都很清楚了吧。。。

Dropout深入了解

另一個版本:

Dropout深入了解

Some questions

  1. 取平均的作用: 先回到标準的模型即沒有dropout,我們用相同的訓練資料去訓練5個不同的神經網絡,一般會得到5個不同的結果,此時我們可以采用 “5個結果取均值”或者“多數取勝的投票政策”去決定最終結果。例如3個網絡判斷結果為數字9,那麼很有可能真正的結果就是數字9,其它兩個網絡給出了錯誤結果。這種“綜合起來取平均”的政策通常可以有效防止過拟合問題。因為不同的網絡可能産生不同的過拟合,取平均則有可能讓一些“相反的”拟合互相抵消。dropout掉不同的隐藏神經元就類似在訓練不同的網絡,随機删掉一半隐藏神經元導緻網絡結構已經不同,整個dropout過程就相當于對很多個不同的神經網絡取平均。而不同的網絡産生不同的過拟合,一些互為“反向”的拟合互相抵消就可以達到整體上減少過拟合。
  2. 減少神經元之間複雜的共适應關系: 因為dropout程式導緻兩個神經元不一定每次都在一個dropout網絡中出現。這樣權值的更新不再依賴于有固定關系的隐含節點的共同作用,阻止了某些特征僅僅在其它特定特征下才有效果的情況 。迫使網絡去學習更加魯棒的特征 ,這些特征在其它的神經元的随機子集中也存在。換句話說假如我們的神經網絡是在做出某種預測,它不應該對一些特定的線索片段太過敏感,即使丢失特定的線索,它也應該可以從衆多其它線索中學習一些共同的特征。從這個角度看dropout就有點像L1,L2正則,減少權重使得網絡對丢失特定神經元連接配接的魯棒性提高。
  3. Dropout類似于性别在生物進化中的角色: 雖然直覺上看dropout是ensemble在分類性能上的一個近似,然而實際中,dropout畢竟還是在一個神經網絡上進行的,隻訓練出了一套模型參數。在自然界中,在中大型動物中,一般是有性繁殖,有性繁殖是指後代的基因從父母兩方各繼承一半。但是從直覺上看,似乎無性繁殖更加合理,因為無性繁殖可以保留大段大段的優秀基因。而有性繁殖則将基因随機拆了又拆,破壞了大段基因的聯合适應性。但是有性繁殖的方式不僅僅可以将優秀的基因傳下來,還可以降低基因之間的聯合适應性,使得複雜的大段大段基因聯合适應性變成比較小的一個一個小段基因的聯合适應性。dropout也能達到同樣的效果,它強迫一個神經單元,和随機挑選出來的其他神經單元共同工作,達到好的效果。消除減弱了神經元節點間的聯合适應性,增強了泛化能力。

再次特别感謝大佬部落格。

done~

References

  • https://blog.csdn.net/stdcoutzyx/article/details/49022443
  • https://blog.csdn.net/program_developer/article/details/80737724#commentsedit
  • https://blog.csdn.net/hjimce/article/details/50413257
  • https://blog.csdn.net/stdcoutzyx/article/details/49022443
  • https://zhuanlan.zhihu.com/p/23178423
  • https://blog.csdn.net/qunnie_yi/article/details/80128463
  • https://blog.csdn.net/whiteinblue/article/details/37808623
  • https://www.cnblogs.com/tornadomeet/p/3258122.html?_t_t_t=0.09445037946091872
  • Hinton G E, Srivastava N, Krizhevsky A, et al. Improving neural networks by preventing co-adaptation of feature detectors[J]. arXiv preprint arXiv:1207.0580, 2012.

繼續閱讀