1. Dropout簡介
1.1 Dropout出現的原因
在機器學習的模型中,如果模型的參數太多,而訓練樣本又太少,訓練出來的模型很容易産生過拟合的現象。在訓練神經網絡的時候經常會遇到過拟合的問題,過拟合具體表現在:模型在訓練資料上損失函數較小,預測準确率較高;但是在測試資料上損失函數比較大,預測準确率較低。
過拟合是很多機器學習的通病。如果模型過拟合,那麼得到的模型幾乎不能用。為了解決過拟合問題,一般會采用模型內建的方法,即訓練多個模型進行組合。此時,訓練模型費時就成為一個很大的問題,不僅訓練多個模型費時,測試多個模型也是很費時。
綜上所述,訓練深度神經網絡的時候,總是會遇到兩大缺點:
(1)容易過拟合
(2)費時
Dropout可以比較有效的緩解過拟合的發生,在一定程度上達到正則化的效果。
1.2 什麼是Dropout
在2012年,Hinton在其論文《Improving neural networks by preventing co-adaptation of feature detectors》中提出Dropout。當一個複雜的前饋神經網絡被訓練在小的資料集時,容易造成過拟合。為了防止過拟合,可以通過阻止特征檢測器的共同作用來提高神經網絡的性能。
在2012年,Alex、Hinton在其論文《ImageNet Classification with Deep Convolutional Neural Networks》中用到了Dropout算法,用于防止過拟合。并且,這篇論文提到的AlexNet網絡模型引爆了神經網絡應用熱潮,并赢得了2012年圖像識别大賽冠軍,使得CNN成為圖像分類上的核心算法模型。
随後,又有一些關于Dropout的文章《Dropout:A Simple Way to Prevent Neural Networks from Overfitting》、《Improving Neural Networks with Dropout》、《Dropout as data augmentation》。
從上面的論文中,我們能感受到Dropout在深度學習中的重要性。那麼,到底什麼是Dropout呢?
Dropout可以作為訓練深度神經網絡的一種trick供選擇。在每個訓練批次中,通過忽略一半的特征檢測器(讓一半的隐層節點值為0),可以明顯地減少過拟合現象。這種方式可以減少特征檢測器(隐層節點)間的互相作用,檢測器互相作用是指某些檢測器依賴其他檢測器才能發揮作用。
Dropout說的簡單一點就是:我們在前向傳播的時候,讓某個神經元的激活值以一定的機率p停止工作,這樣可以使模型泛化性更強,因為它不會太依賴某些局部的特征,如圖1所示。

圖1:使用Dropout的神經網絡模型
2. Dropout工作流程及使用
2.1 Dropout具體工作流程
假設我們要訓練這樣一個神經網絡,如圖2所示。
圖2:标準的神經網絡
輸入是x輸出是y,正常的流程是:我們首先把x通過網絡前向傳播,然後把誤差反向傳播以決定如何更新參數讓網絡進行學習。使用Dropout之後,過程變成如下:
(1)首先随機(臨時)删掉網絡中一半的隐藏神經元,輸入輸出神經元保持不變(圖3中虛線為部分臨時被删除的神經元)
圖3:部分臨時被删除的神經元
(2) 然後把輸入x通過修改後的網絡前向傳播,然後把得到的損失結果通過修改的網絡反向傳播。一小批訓練樣本執行完這個過程後,在沒有被删除的神經元上按照随機梯度下降法更新對應的參數(w,b)。
(3)然後繼續重複這一過程:
- . 恢複被删掉的神經元(此時被删除的神經元保持原樣,而沒有被删除的神經元已經有所更新)
- . 從隐藏層神經元中随機選擇一個一半大小的子集臨時删除掉(備份被删除神經元的參數)。
- . 對一小批訓練樣本,先前向傳播然後反向傳播損失并根據随機梯度下降法更新參數(w,b) (沒有被删除的那一部分參數得到更新,删除的神經元參數保持被删除前的結果)。
不斷重複這一過程。
2.2 Dropout在神經網絡中的使用
Dropout的具體工作流程上面已經詳細的介紹過了,但是具體怎麼讓某些神經元以一定的機率停止工作(就是被删除掉)?代碼層面如何實作呢?
下面,我們具體講解一下Dropout代碼層面的一些公式推導及代碼實作思路。
(1)在訓練模型階段
無可避免的,在訓練網絡的每個單元都要添加一道機率流程。
圖4:标準網絡和帶有Dropout網絡的比較
對應的公式變化如下:
- . 沒有Dropout的網絡計算公式:
-
深度學習中Dropout原了解析 - . 采用Dropout的網絡計算公式:
-
深度學習中Dropout原了解析 -
上面公式中Bernoulli函數是為了生成機率r向量,也就是随機生成一個0、1的向量。
代碼層面實作讓某個神經元以機率p停止工作,其實就是讓它的激活函數值以機率p變為0。比如我們某一層網絡神經元的個數為1000個,其激活函數輸出值為y1、y2、y3、......、y1000,我們dropout比率選擇0.4,那麼這一層神經元經過dropout後,1000個神經元中會有大約400個的值被置為0。
注意: 經過上面屏蔽掉某些神經元,使其激活值為0以後,我們還需要對向量y1……y1000進行縮放,也就是乘以1/(1-p)。如果你在訓練的時候,經過置0後,沒有對y1……y1000進行縮放(rescale),那麼在測試的時候,就需要對權重進行縮放,操作如下。
(2)在測試模型階段
預測模型的時候,每一個神經單元的權重參數要乘以機率p。
深度學習中Dropout原了解析 - 圖5:預測模型時Dropout的操作
- 測試階段Dropout公式:
-
深度學習中Dropout原了解析
3. 為什麼說Dropout可以解決過拟合?
(1)取平均的作用: 先回到标準的模型即沒有dropout,我們用相同的訓練資料去訓練5個不同的神經網絡,一般會得到5個不同的結果,此時我們可以采用 “5個結果取均值”或者“多數取勝的投票政策”去決定最終結果。例如3個網絡判斷結果為數字9,那麼很有可能真正的結果就是數字9,其它兩個網絡給出了錯誤結果。這種“綜合起來取平均”的政策通常可以有效防止過拟合問題。因為不同的網絡可能産生不同的過拟合,取平均則有可能讓一些“相反的”拟合互相抵消。dropout掉不同的隐藏神經元就類似在訓練不同的網絡,随機删掉一半隐藏神經元導緻網絡結構已經不同,整個dropout過程就相當于對很多個不同的神經網絡取平均。而不同的網絡産生不同的過拟合,一些互為“反向”的拟合互相抵消就可以達到整體上減少過拟合。
(2)減少神經元之間複雜的共适應關系: 因為dropout程式導緻兩個神經元不一定每次都在一個dropout網絡中出現。這樣權值的更新不再依賴于有固定關系的隐含節點的共同作用,阻止了某些特征僅僅在其它特定特征下才有效果的情況 。迫使網絡去學習更加魯棒的特征 ,這些特征在其它的神經元的随機子集中也存在。換句話說假如我們的神經網絡是在做出某種預測,它不應該對一些特定的線索片段太過敏感,即使丢失特定的線索,它也應該可以從衆多其它線索中學習一些共同的特征。從這個角度看dropout就有點像L1,L2正則,減少權重使得網絡對丢失特定神經元連接配接的魯棒性提高。
(3)Dropout類似于性别在生物進化中的角色:物種為了生存往往會傾向于适應這種環境,環境突變則會導緻物種難以做出及時反應,性别的出現可以繁衍出适應新環境的變種,有效的阻止過拟合,即避免環境改變時物種可能面臨的滅絕。
4. Dropout在Keras中的源碼分析
下面,我們來分析Keras中Dropout實作源碼。
Keras開源項目GitHub位址為:
https://github.com/fchollet/keras/tree/master/keras
其中Dropout函數代碼實作所在的檔案位址:
https://github.com/fchollet/keras/blob/master/keras/backend/theano_backend.py
Dropout實作函數如下:
圖6:Keras中實作Dropout功能
我們對keras中Dropout實作函數做一些修改,讓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
# 我們通過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)
x *= random_tensor
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)
函數中,x是本層網絡的激活值。Level就是dropout就是每個神經元要被丢棄的機率。
注意: Keras中Dropout的實作,是屏蔽掉某些神經元,使其激活值為0以後,對激活值向量x1……x1000進行放大,也就是乘以1/(1-p)。
思考:上面我們介紹了兩種方法進行Dropout的縮放,那麼Dropout為什麼需要進行縮放呢?
因為我們訓練的時候會随機的丢棄一些神經元,但是預測的時候就沒辦法随機丢棄了。如果丢棄一些神經元,這會帶來結果不穩定的問題,也就是給定一個測試資料,有時候輸出a有時候輸出b,結果不穩定,這是實際系統不能接受的,使用者可能認為模型預測不準。那麼一種”補償“的方案就是每個神經元的權重都乘以一個p,這樣在“總體上”使得測試資料和訓練資料是大緻一樣的。比如一個神經元的輸出是x,那麼在訓練的時候它有p的機率參與訓練,(1-p)的機率丢棄,那麼它輸出的期望是px+(1-p)0=px。是以測試的時候把這個神經元的權重乘以p可以得到同樣的期望。
總結:
目前Dropout被大量利用于全連接配接網絡,而且一般認為設定為0.5或者0.3,而在卷積網絡隐藏層中由于卷積自身的稀疏化以及稀疏化的ReLu函數的大量使用等原因,Dropout政策在卷積網絡隐藏層中使用較少。總體而言,Dropout是一個超參,需要根據具體的網絡、具體的應用領域進行嘗試。
Reference:
- 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.
- Krizhevsky A, Sutskever I, Hinton G E. Imagenet classification with deep convolutional neural networks[C]//Advances in neural information processing systems. 2012: 1097-1105.
- Srivastava N, Hinton G, Krizhevsky A, et al. Dropout: A simple way to prevent neural networks from overfitting[J]. The Journal of Machine Learning Research, 2014, 15(1): 1929-1958.
- Srivastava N. Improving neural networks with dropout[J]. University of Toronto, 2013, 182.
- Bouthillier X, Konda K, Vincent P, et al. Dropout as data augmentation[J]. arXiv preprint arXiv:1506.08700, 2015.
- 深度學習(二十二)Dropout淺層了解與實作,位址:https://blog.csdn.net/hjimce/article/details/50413257
- 了解dropout,位址:https://blog.csdn.net/stdcoutzyx/article/details/49022443
- Dropout解決過拟合問題 - 曉雷的文章 - 知乎,位址:https://zhuanlan.zhihu.com/p/23178423
- 李理:卷積神經網絡之Dropout,位址:https://blog.csdn.net/qunnie_yi/article/details/80128463
- Dropout原理,代碼淺析,位址:https://blog.csdn.net/whiteinblue/article/details/37808623
- Deep learning:四十一(Dropout簡單了解),位址:https://www.cnblogs.com/tornadomeet/p/3258122.html?_t_t_t=0.09445037946091872