BN是由Google於2015年提出,這是一個深度神經網絡訓練的技巧,它不只能夠加快了模型的收斂速度,並且更重要的是在必定程度緩解了深層網絡中「梯度彌散」的問題,從而使得訓練深層網絡模型更加容易和穩定。因此目前BN已經成爲幾乎全部卷積神經網絡的標配技巧了。網絡
從字面意思看來Batch Normalization(簡稱BN)就是對每一批數據進行歸一化,確實如此,對於訓練中某一個batch的數據{x1,x2,...,xn},注意這個數據是能夠輸入也能夠是網絡中間的某一層輸出。在BN出現以前,咱們的歸一化操做通常都在數據輸入層,對輸入的數據進行求均值以及求方差作歸一化,可是BN的出現打破了這一個規定,咱們能夠在網絡中任意一層進行歸一化處理,由於咱們如今所用的優化方法大多都是min-batch SGD,因此咱們的歸一化操做就成爲Batch Normalization。函數
咱們知道網絡一旦train起來,那麼參數就要發生更新,除了輸入層的數據外(由於輸入層數據,咱們已經人爲的爲每一個樣本歸一化),後面網絡每一層的輸入數據分佈是一直在發生變化的,由於在訓練的時候,前面層訓練參數的更新將致使後面層輸入數據分佈的變化。以網絡第二層爲例:網絡的第二層輸入,是由第一層的參數和input計算獲得的,而第一層的參數在整個訓練過程當中一直在變化,所以必然會引發後面每一層輸入數據分佈的改變。咱們把網絡中間層在訓練過程當中,數據分佈的改變稱之爲:「Internal Covariate Shift」。BN的提出,就是要解決在訓練過程當中,中間層數據分佈發生改變的狀況。性能
如上圖所示,BN步驟主要分爲4步:學習
一個標準的歸一化步驟就是減均值除方差,那這種歸一化操做有什麼做用呢?咱們觀察下圖,測試
a中左圖是沒有通過任何處理的輸入數據,曲線是sigmoid函數,若是數據在梯度很小的區域,那麼學習率就會很慢甚至陷入長時間的停滯。減均值除方差後,數據就被移到中心區域如右圖所示,對於大多數激活函數而言,這個區域的梯度都是最大的或者是有梯度的(好比ReLU),這能夠看作是一種對抗梯度消失的有效手段。對於一層如此,若是對於每一層數據都那麼作的話,數據的分佈老是在隨着變化敏感的區域,至關於不用考慮數據分佈變化了,這樣訓練起來更有效率。優化
那麼爲何要有第4步,不是僅使用減均值除方差操做就能得到目的效果嗎?咱們思考一個問題,減均值除方差獲得的分佈是正態分佈,咱們可否認爲正態分佈就是最好或最能體現咱們訓練樣本的特徵分佈呢?不能,好比數據自己就很不對稱,或者激活函數未必是對方差爲1的數據最好的效果,好比Sigmoid激活函數,在-1~1之間的梯度變化不大,那麼非線性變換的做用就不能很好的體現,換言之就是,減均值除方差操做後可能會削弱網絡的性能!針對該狀況,在前面三步以後加入第4步完成真正的batch normalization。spa
BN的本質就是利用優化變一下方差大小和均值位置,使得新的分佈更切合數據的真實分佈,保證模型的非線性表達能力。BN的極端的狀況就是這兩個參數等於mini-batch的均值和方差,那麼通過batch normalization以後的數據和輸入徹底同樣,固然通常的狀況是不一樣的。orm
在訓練時,咱們會對同一批的數據的均值和方差進行求解,進而進行歸一化操做。可是對於預測時咱們的均值和方差怎麼求呢?好比咱們預測單個樣本時,那還怎麼求均值和方法呀!實際上是這種樣子的,對於預測階段時所使用的均值和方差,其實也是來源於訓練集。好比咱們在模型訓練時咱們就記錄下每一個batch下的均值和方差,待訓練完畢後,咱們求整個訓練樣本的均值和方差指望值,做爲咱們進行預測時進行BN的的均值和方差:blog
最後測試階段,BN的使用公式就是:input
關於BN的使用位置,在CNN中通常應做用與非線性激活函數以前,s型函數s(x)的自變量x是通過BN處理後的結果。所以前向傳導的計算公式就應該是:
其實由於偏置參數b通過BN層後實際上是沒有用的,最後也會被均值歸一化,固然BN層後面還有個β參數做爲偏置項,因此b這個參數就能夠不用了。所以最後把BN層+激活函數層就變成了:
注意前面寫的都是對於通常狀況,對於卷積神經網絡有些許不一樣。由於卷積神經網絡的特徵是對應到一整張特徵響應圖上的,因此作BN時也應以響應圖爲單位而不是按照各個維度。好比在某一層,batch大小爲m,響應圖大小爲w×h,則作BN的數據量爲m×w×h。
BN在深層神經網絡的做用很是明顯:若神經網絡訓練時遇到收斂速度較慢,或者「梯度爆炸」等沒法訓練的狀況發生時均可以嘗試用BN來解決。同時,常規使用狀況下一樣能夠加入BN來加速模型訓練,甚至提高模型精度。