Batch Normalization

轉自http://www.javashuo.com/article/p-cllgntyn-nr.html算法

 

簡介
Batch Normalization簡稱BN,是2015年提出的一種方法《Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift》,已經普遍被證實其有效性和重要性。雖然有些細節處理還解釋不清其理論緣由,可是實踐證實好用纔是真的好。
原論文地址:https://arxiv.org/abs/1502.03167網絡

機器學習領域有個很重要的假設:IID獨立同分布假設,就是假設訓練數據和測試數據是知足相同分佈的,這是經過訓練數據得到的模型可以在測試集得到好的效果的一個基本保障。而BN就是在深度神經網絡訓練過程當中使得每一層神經網絡的輸入保持相同分佈的。
爲何深度神經網絡隨着網絡深度加深,訓練起來越困難,收斂愈來愈慢?這是個在DL領域很接近本質的好問題。不少論文都是解決這個問題的,好比ReLU激活函數,再好比ResNet等,BN本質上也是解釋並從某個不一樣的角度來解決這個問題的。機器學習

1、Internal Covariate Shift 現象:
從論文名字能夠看出,BN是用來解決「Internal Covariate Shift」問題的。首先來解釋一下什麼叫作covariate shift現象,這個指的是訓練集的數據分佈和預測集的數據分佈不一致,這樣的狀況下若是咱們在訓練集上訓練出一個分類器,確定在預測集上不會取得比較好的效果。這種訓練集和預測集樣本分佈不一致的問題就叫作「covariate shift」現象。
對於深度學習這種包含不少隱層的網絡結構,在訓練過程當中,由於各層參數不停在變化,因此每一個隱層都會面臨covariate shift的問題。也就是在訓練過程當中,隱層的輸入分佈總是變來變去,致使網絡模型很難穩定的學規律,這就是所謂的「Internal Covariate Shift」,Internal指的是深層網絡的隱層,是發生在網絡內部的事情,而不是covariate shift問題只發生在輸入層。函數

2、Batch Normalization 由來:
針對上述問題,因而提出了BatchNorm的基本思想:能不能讓每一個隱層節點的激活輸入分佈固定下來呢?這樣就避免了「Internal Covariate Shift」問題了。
啓發來源:以前的研究代表若是在圖像處理中對輸入圖像進行白化(Whiten)操做的話(所謂白化,就是對輸入數據分佈變換到0均值,單位方差的正態分佈)那麼神經網絡會較快收斂。
那麼BN做者就開始推論:圖像是深度神經網絡的輸入層,作白化能加快收斂,那麼其實對於深度網絡來講,其中某個隱層的神經元是下一層的輸入,意思是其實深度神經網絡的每個隱層都是輸入層,不過是相對下一層來講而已,那麼能不能對每一個隱層都作白化呢?因此BN能夠理解爲對深層神經網絡每一個隱層神經元的激活值作簡化版本的白化操做。性能

3、Batch Normalization 原理:
BN的基本思想其實至關直觀:由於深層神經網絡在作非線性變換前的激活輸入值x隨着網絡深度加深或者在訓練過程當中,其分佈逐漸發生偏移或者變更,之因此訓練收斂慢,通常是總體分佈逐漸往非線性函數的取值區間的上下限兩端靠近,因此這致使反向傳播時低層神經網絡的梯度消失,這是訓練深層神經網絡收斂愈來愈慢的本質緣由。
而BN就是經過必定的規範化手段,把每層神經網絡任意神經元這個輸入值的分佈強行拉回到均值爲0方差爲1的標準正態分佈,其實就是把愈來愈偏的分佈強制拉回比較標準的分佈,這樣使得激活輸入值落在非線性函數對輸入比較敏感的區域,這樣輸入的小變化就會致使損失函數較大的變化,意思是這樣讓梯度變大,避免梯度消失問題產生,並且梯度變大意味着學習收斂速度快,能大大加快訓練速度。
上面說得仍是顯得抽象,下面更形象地表達下這種調整到底表明什麼含義:學習

 

 

假設某個隱層神經元原先的激活輸入x取值符合正態分佈,正態分佈均值是-2,方差是0.5,對應上圖中最左端的淺藍色曲線,經過BN後轉換爲均值爲0,方差是1的正態分佈(對應上圖中的深藍色圖形)。這意味着輸入x的取值正態分佈總體右移2(均值的變化),圖形曲線更平緩了(方差增大的變化)。那麼把激活輸入x調整到這個正態分佈有什麼用?首先咱們看下均值爲0,方差爲1的標準正態分佈表明什麼含義:測試

 

 

 這意味着在一個標準差範圍內,也就是說64%的機率x其值落在[-1,1]的範圍內,在兩個標準差範圍內,也就是說95%的機率x其值落在了[-2,2]的範圍內。那麼這又意味着什麼?咱們知道,激活值x=WU+B,U是真正的輸入,x是某個神經元的激活值,假設非線性函數是sigmoid,那麼看下sigmoid(x)函數及其導數:優化

 

 

因此通過BN後,均值是0,方差是1,那麼意味着95%的x值落在了[-2,2]區間內,很明顯這一段是sigmoid(x)函數接近於線性變換的區域,意味着x的小變化會致使非線性函數值較大的變化,也便是梯度變化較大,對應導數函數圖中明顯大於0的區域,就是梯度非飽和區。
也就是說.net

通過BN後,目前大部分Activation的值落入非線性函數的線性區內,其對應的導數遠離導數飽和區,這樣來加速訓練收斂過程。

到了這裏,又會發現一個問題:若是都經過BN,那麼不就跟把非線性函數替換成線性函數效果相同了?咱們知道,若是是多層的線性函數變換其實這個深層是沒有意義的,由於多層線性網絡跟一層線性網絡是等價的。這意味着網絡的表達能力降低了,這也意味着深度的意義就沒有了。因此BN爲了保證非線性的得到,對變換後的知足均值爲0方差爲1的x又進行了scale加上shift操做(y=scale*x+shift),每一個神經元增長了兩個參數scale和shift參數,這兩個參數是經過訓練學習到的,意思是經過scale和shift把這個值從標準正態分佈左移或者右移一點並長胖一點或者變瘦一點,每一個實例挪動的程度不同,這樣等價於非線性函數的值從正中心周圍的線性區往非線性區動了動。核心思想應該是想找到一個線性和非線性的較好平衡點,既能享受非線性的較強表達能力的好處,又避免太靠非線性區兩頭使得網絡收斂速度太慢。固然,論文做者並未明確這樣說。3d

4、Batch Normalization 算法流程:
上面是對BN的抽象分析和解釋,具體在Mini-Batch SGD下作BN怎麼作?其實論文裏面這塊寫得很清楚也容易理解。
在多層CNN裏,BN放在卷積層以後,激活和池化以前,以LeNet5爲例:

 

 

對於Mini-Batch SGD來講,一次訓練過程裏面包含m個訓練實例,其具體BN操做就是對於隱層內每一個神經元的激活值來講,進行以下變換:

變換的意思是:某個神經元對應的原始的激活x經過減去mini-Batch內m個實例得到的m個激活x求得的均值E(x)併除以求得的方差Var(x)來進行轉換。

上文說過通過這個變換後會致使網絡表達能力降低,爲了防止這一點,每一個神經元增長兩個調節參數(scale和shift),這兩個參數是經過訓練來學習到的,用來對變換後的激活反變換,使得網絡表達能力加強,即對變換後的激活進行以下的scale和shift操做,這實際上是變換的反操做:

這就是算法的關鍵之處了,每個神經元x都會有這樣的一對參數,當:

這樣的時候能夠恢復出原始的某一層學習到的特徵的,所以咱們引入這個能夠學習的參數使得咱們的網絡能夠恢復出原始網絡所要學習的特徵分佈,最後BN層的前向傳導公式爲:

 

 

上面公式中的m指的是mini-batch size。也就是每個batch來作一個這樣的BN。代碼對應也是四句話:


5、BN帶來的好處:

沒有它以前,須要當心的調整學習率和權重初始化,可是有了BN能夠放心的使用大學習率;
極大提高了訓練速度,收斂過程大大加快;
Batch Normalization自己上也是一種正則的方式,能夠代替其餘正則方式如Dropout等。
6、BN的缺陷:
Batch Normalization中的batch就是批量數據,即每一次優化時的樣本數目,一般BN網絡層用在卷積層後,用於從新調整數據分佈。假設神經網絡某層一個batch的輸入爲X=[x1,x2,…,xn],其中xi表明一個樣本,n爲batch size。
當batch值很小時,計算的均值和方差不穩定。研究代表對於ResNet類模型在ImageNet數據集上,batch從16下降到8時開始有很是明顯的性能降低。因此BN不適應於當訓練資源有限而沒法應用較大的batch的場景。

注:參考知乎各位大佬深度學習中 Batch Normalization爲何效果好?和郭耀華大神【深度學習】深刻理解Batch Normalization批標準化

相關文章
相關標籤/搜索