BN講解(轉載)
本文轉載自:http://blog.csdn.net/shuzfan/article/details/50723877
本次所講的內容為Batch Normalization,簡稱BN,來源於《Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift》,是一篇很好的paper。後來也被用到了深度殘差網絡中~
1-Motivation
作者認為:網絡訓練過程中參數不斷改變導致後續每一層輸入的分布也發生變化,而學習的過程又要使每一層適應輸入的分布,因此我們不得不降低學習率、小心地初始化。作者將分布發生變化稱之為 internal covariate shift。
大家應該都知道,我們一般在訓練網絡的時會將輸入減去均值,還有些人甚至會對輸入做白化等操作,目的是為了加快訓練。為什麽減均值、白化可以加快訓練呢,這裏做一個簡單地說明:
首先,圖像數據是高度相關的,假設其分布如下圖a所示(簡化為2維)。由於初始化的時候,我們的參數一般都是0均值的,因此開始的擬合y=Wx+b,基本過原點附近,如圖b紅色虛線。因此,網絡需要經過多次學習才能逐步達到如紫色實線的擬合,即收斂的比較慢。如果我們對輸入數據先作減均值操作,如圖c,顯然可以加快學習。更進一步的,我們對數據再進行去相關操作,使得數據更加容易區分,這樣又會加快訓練,如圖d。
白化的方式有好幾種,常用的有PCA白化(由於原始數據存在冗余,通過PCA降維,使用最低維度來表達數據,消除冗余,減速訓練):即對數據進行PCA操作之後,在進行方差歸一化。這樣數據基本滿足0均值、單位方差、弱相關性。作者首先考慮,對每一層數據都使用白化操作,但分析認為這是不可取的。因為白化需要計算協方差矩陣、求逆等操作,計算量很大,此外,反向傳播時,白化操作不一定可導。於是,作者采用下面的Normalization方法。
2-Normalization via Mini-Batch Statistics
數據歸一化方法很簡單,就是要讓數據具有0均值和單位方差,如下式:
但是作者又說如果簡單的這麽幹,會降低層的表達能力。比如下圖,在使用sigmoid激活函數的時候,如果把數據限制到0均值單位方差,那麽相當於只使用了激活函數中近似線性的部分,這顯然會降低模型表達能力。
為此,作者又為BN增加了2個參數,用來保持模型的表達能力。
於是最後的輸出為:
上述公式中用到了均值E和方差Var,需要註意的是理想情況下E和Var應該是針對整個數據集的,但顯然這是不現實的。因此,作者做了簡化,用一個Batch的均值和方差作為對整個數據集均值和方差的估計。
整個BN的算法如下:
求導的過程也非常簡單,有興趣地可以自己再推導一遍或者直接參見原文。
測試
實際測試網絡的時候,我們依然會應用下面的式子:
特別註意: 這裏的均值和方差已經不是針對某一個Batch了,而是針對整個數據集而言。因此,在訓練過程中除了正常的前向傳播和反向求導之外,我們還要記錄每一個Batch的均值和方差,以便訓練完成之後按照下式計算整體的均值和方差:
BN before or after Activation
作者在文章中說應該把BN放在激活函數之前,這是因為Wx+b具有更加一致和非稀疏的分布。但是也有人做實驗表明放在激活函數後面效果更好,在深度殘差網絡一文中,作者是將其放在了卷積層後面。RELU層前面。這是實驗鏈接,裏面有很多有意思的對比實驗:https://github.com/ducha-aiki/caffenet-benchmark
3-Experiments
作者在文章中也做了很多實驗對比,我這裏就簡單說明2個。
下圖a說明,BN可以加速訓練。圖b和c則分別展示了訓練過程中輸入數據分布的變化情況。
下表是一個實驗結果的對比,需要註意的是在使用BN的過程中,作者發現Sigmoid激活函數比Relu效果要好。
BN講解(轉載)