Batch Normalization詳解


博客:blog.shinelee.me | 博客園 | CSDN

動機

在博文《爲什麼要做特徵歸一化/標準化? 博客園 | csdn | blog》中,我們介紹了對輸入進行Standardization後,梯度下降算法更容易選擇到合適的(較大的)學習率,下降過程會更加穩定。

在博文《網絡權重初始化方法總結(下):Lecun、Xavier與He Kaiming 博客園 | csdn | blog》中,我們介紹瞭如何通過權重初始化讓網絡在訓練之初保持激活層的輸出(輸入)爲zero mean unit variance分佈,以減輕梯度消失和梯度爆炸。

但在訓練過程中,權重在不斷更新,導致激活層輸出(輸入)的分佈會一直變化,可能無法一直保持zero mean unit variance分佈,還是有梯度消失和梯度爆炸的可能,直覺上感到,這可能是個問題。下面具體分析。

單層視角

http://gradientscience.org/batchnorm/

神經網絡可以看成是上圖形式,對於中間的某一層,其前面的層可以看成是對輸入的處理,後面的層可以看成是損失函數。一次反向傳播過程會同時更新所有層的權重W1,W2,,WLW_1, W_2, \dots, W_L,前面層權重的更新會改變當前層輸入的分佈,而跟據反向傳播的計算方式,我們知道,對WkW_k的更新是在假定其輸入不變的情況下進行的。如果假定第kk層的輸入節點只有2個,對第kk層的某個輸出節點而言,相當於一個線性模型y=w1x1+w2x2+by = w_1 x_1 + w_2 x_2 + b,如下圖所示,

https://wiki2.org/en/Linear_classifier#/media/File:Svm_separating_hyperplanes.png

假定當前輸入x1x_1x2x_2的分佈如圖中圓點所示,本次更新的方向是將直線H1H_1更新成H2H_2,本以爲切分得不錯,但是當前面層的權重更新完畢,當前層輸入的分佈換成了另外一番樣子,直線相對輸入分佈的位置可能變成了H3H_3,下一次更新又要根據新的分佈重新調整。直線調整了位置,輸入分佈又在發生變化,直線再調整位置,就像是直線和分佈之間的“追逐遊戲”。對於淺層模型,比如SVM,輸入特徵的分佈是固定的,即使拆分成不同的batch,每個batch的統計特性也是相近的,因此只需調整直線位置來適應輸入分佈,顯然要容易得多。而深層模型,每層輸入的分佈和權重在同時變化,訓練相對困難。

多層視角

上面是從網絡中單拿出一層分析,下面看一下多層的情況。在反向傳播過程中,每層權重的更新是在假定其他權重不變的情況下,向損失函數降低的方向調整自己。問題在於,在一次反向傳播過程中,所有的權重會同時更新,導致層間配合“缺乏默契”,每層都在進行上節所說的“追逐遊戲”,而且層數越多,相互配合越困難,文中把這個現象稱之爲 Internal Covariate Shift,示意圖如下。爲了避免過於震盪,學習率不得不設置得足夠小,足夠小就意味着學習緩慢。

https://gab41.lab41.org/batch-normalization-what-the-hey-d480039a9e3b

爲此,希望對每層輸入的分佈有所控制,於是就有了Batch Normalization,其出發點是對每層的輸入做Normalization,只有一個數據是談不上Normalization的,所以是對一個batch的數據進行Normalization。

什麼是Batch Normalization

Batch Normalization,簡稱BatchNorm或BN,翻譯爲“批歸一化”,是神經網絡中一種特殊的層,如今已是各種流行網絡的標配。在原paper中,BN被建議插入在(每個)ReLU激活層前面,如下所示,

http://gradientscience.org/batchnorm/

如果batch size爲mm,則在前向傳播過程中,網絡中每個節點都有mm個輸出,所謂的Batch Normalization,就是對該層每個節點的這mm個輸出進行歸一化再輸出,具體計算方式如下,

Batch Normalization Transform

其操作可以分成2步,

  1. Standardization:首先對mmxx進行 Standardization,得到 zero mean unit variance的分佈x^\hat{x}
  2. scale and shift:然後再對x^\hat{x}進行scale and shift,縮放並平移到新的分佈yy,具有新的均值β\beta方差γ\gamma

假設BN層有dd個輸入節點,則xx可構成d×md \times m大小的矩陣XX,BN層相當於通過行操作將其映射爲另一個d×md\times m大小的矩陣YY,如下所示,

Batch Normalization

將2個過程寫在一個公式裏如下,

yi(b)=BN(xi)(b)=γ(xi(b)μ(xi)σ(xi)2+ϵ)+β y_i^{(b)} = BN\left(x_{i}\right)^{(b)}=\gamma \cdot\left(\frac{x_{i}^{(b)}-\mu\left(x_{i}\right)}{\sqrt{\sigma\left(x_{i}\right)^2 + \epsilon}}\right)+\beta
其中,xi(b)x_i^{(b)}表示輸入當前batch的bb-th樣本時該層ii-th輸入節點的值,xix_i[xi(1),xi(2),,xi(m)][x_i^{(1)}, x_i^{(2)}, \dots, x_i^{(m)}]構成的行向量,長度爲batch size mmμ\muσ\sigma爲該行的均值和標準差,ϵ\epsilon爲防止除零引入的極小量(可忽略),γ\gammaβ\beta爲該行的scale和shift參數,可知

  • μ\muσ\sigma爲當前行的統計量,不可學習。
  • γ\gammaβ\beta爲待學習的scale和shift參數,用於控制yiy_i的方差和均值。
  • BN層中,xix_ixjx_j之間不存在信息交流(ij)(i \neq j)

可見,無論xix_i原本的均值和方差是多少,通過BatchNorm後其均值和方差分別變爲待學習的β\betaγ\gamma

Batch Normalization的反向傳播

對於目前的神經網絡計算框架,一個層要想加入到網絡中,要保證其是可微的,即可以求梯度。BatchNorm的梯度該如何求取?

反向傳播求梯度只需抓住一個關鍵點,如果一個變量對另一個變量有影響,那麼他們之間就存在偏導數,找到直接相關的變量,再配合鏈式法則,公式就很容易寫出了。
γ=i=1myix^iβ=i=1myix^i=yiγσB2=i=1mx^i(xiμB)12(σB2+ϵ)3/2μB=(i=1mx^i1σB2+ϵ)+σB2i=1m2(xiμB)mxi=x^i1σB2+ϵ+σB22(xiμB)m+μB1m \begin{array}{l} {\frac{\partial \ell}{\partial \gamma}=\sum_{i=1}^{m} \frac{\partial \ell}{\partial y_{i}} \cdot \widehat{x}_{i}} \\ {\frac{\partial \ell}{\partial \beta}=\sum_{i=1}^{m} \frac{\partial \ell}{\partial y_{i}}} \\ {\frac{\partial \ell}{\partial \widehat{x}_{i}}=\frac{\partial \ell}{\partial y_{i}} \cdot \gamma} \\ {\frac{\partial \ell}{\partial \sigma_{B}^{2}}=\sum_{i=1}^{m} \frac{\partial \ell}{\partial \widehat{x}_{i}} \cdot\left(x_{i}-\mu_{\mathcal{B}}\right) \cdot \frac{-1}{2}\left(\sigma_{\mathcal{B}}^{2}+\epsilon\right)^{-3 / 2}} \\ {\frac{\partial \ell}{\partial \mu_{\mathcal{B}}}=\left(\sum_{i=1}^{m} \frac{\partial \ell}{\partial \widehat{x}_{i}} \cdot \frac{-1}{\sqrt{\sigma_{\mathcal{B}}^{2}+\epsilon}}\right)+\frac{\partial \ell}{\partial \sigma_{\mathcal{B}}^{2}} \cdot \frac{\sum_{i=1}^{m}-2\left(x_{i}-\mu_{\mathcal{B}}\right)}{m}} \\ {\frac{\partial \ell}{\partial x_{i}} = \frac{\partial \ell}{\partial \widehat{x}_{i}} \cdot \frac{1}{\sqrt{\sigma_{\mathcal{B}}^{2}+\epsilon}} + \frac{\partial \ell}{\partial \sigma_{\mathcal{B}}^{2}} \cdot \frac{2\left(x_{i}-\mu_{\mathcal{B}}\right)}{m} + \frac{\partial \ell}{\partial \mu_{\mathcal{B}}} \cdot \frac{1}{m}} \\ \end{array}
根據反向傳播的順序,首先求取損失\ell對BN層輸出yiy_i的偏導yi\frac{\partial \ell}{\partial y_{i}},然後是對可學習參數的偏導γ\frac{\partial \ell}{\partial \gamma}β\frac{\partial \ell}{\partial \beta},用於對參數進行更新,想繼續回傳的話還需要求對輸入 xx偏導,於是引出對變量μ\muσ2\sigma^2x^\hat{x}的偏導,根據鏈式法則再求這些變量對xx的偏導。

在實際實現時,通常以矩陣或向量運算方式進行,比如逐元素相乘、沿某個axis求和、矩陣乘法等操作,具體可以參見Understanding the backward pass through Batch Normalization LayerBatchNorm in Caffe

Batch Normalization的預測階段

在預測階段,所有參數的取值是固定的,對BN層而言,意味着μ\muσ\sigmaγ\gammaβ\beta都是固定值。

γ\gammaβ\beta比較好理解,隨着訓練結束,兩者最終收斂,預測階段使用訓練結束時的值即可。

對於μ\muσ\sigma,在訓練階段,它們爲當前mini batch的統計量,隨着輸入batch的不同,μ\muσ\sigma一直在變化。在預測階段,輸入數據可能只有1條,該使用哪個μ\muσ\sigma,或者說,每個BN層的μ\muσ\sigma該如何取值?可以採用訓練收斂最後幾批mini batch的 μ\muσ\sigma的期望,作爲預測階段的μ\muσ\sigma,如下所示,

Training a Batch-Normalized Network

因爲Standardization和scale and shift均爲線性變換,在預測階段所有參數均固定的情況下,參數可以合併成y=kx+by=kx+b的形式,如上圖中行號11所示。

Batch Normalization的作用

使用Batch Normalization,可以獲得如下好處,

  • 可以使用更大的學習率,訓練過程更加穩定,極大提高了訓練速度。
  • 可以將bias置爲0,因爲Batch Normalization的Standardization過程會移除直流分量,所以不再需要bias。
  • 對權重初始化不再敏感,通常權重採樣自0均值某方差的高斯分佈,以往對高斯分佈的方差設置十分重要,有了Batch Normalization後,對與同一個輸出節點相連的權重進行放縮,其標準差σ\sigma也會放縮同樣的倍數,相除抵消。
  • 對權重的尺度不再敏感,理由同上,尺度統一由γ\gamma參數控制,在訓練中決定。
  • 深層網絡可以使用sigmoid和tanh了,理由同上,BN抑制了梯度消失。
  • Batch Normalization具有某種正則作用,不需要太依賴dropout,減少過擬合

幾個問題

卷積層如何使用BatchNorm?

For convolutional layers, we additionally want the normalization to obey the convolutional property – so that different elements of the same feature map, at different locations, are normalized in the same way. To achieve this, we jointly normalize all the activations in a mini-batch, over all locations.

so for a mini-batch of size m and feature maps of size p × q, we use the effective mini-batch of size m′

= |B| = m · pq. We learn a pair of parameters γ(k) and β(k) per feature map, rather than per activation.

—— Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift

1個卷積核產生1個feature map,1個feature map有1對γ\gammaβ\beta參數,同一batch同channel的feature map共享同一對γ\gammaβ\beta參數,若卷積層有nn個卷積核,則有nnγ\gammaβ\beta參數。

沒有scale and shift過程可不可以?

BatchNorm有兩個過程,Standardization和scale and shift,前者是機器學習常用的數據預處理技術,在淺層模型中,只需對數據進行Standardization即可,Batch Normalization可不可以只有Standardization呢?

答案是可以,但網絡的表達能力會下降。

直覺上理解,淺層模型中,只需要模型適應數據分佈即可。對深度神經網絡,每層的輸入分佈和權重要相互協調,強制把分佈限制在zero mean unit variance並不見得是最好的選擇,加入參數γ\gammaβ\beta,對輸入進行scale and shift,有利於分佈與權重的相互協調,特別地,令γ=1,β=0\gamma=1, \beta = 0等價於只用Standardization,令γ=σ,β=μ\gamma=\sigma, \beta=\mu等價於沒有BN層,scale and shift涵蓋了這2種特殊情況,在訓練過程中決定什麼樣的分佈是適合的,所以使用scale and shift增強了網絡的表達能力。

表達能力更強,在實踐中性能就會更好嗎?並不見得,就像曾經參數越多不見得性能越好一樣。caffenet-benchmark-batchnorm中,作者實驗發現沒有scale and shift性能可能還更好一些,圖見下一小節。

BN層放在ReLU前面還是後面?

paper建議將BN層放置在ReLU前,因爲ReLU激活函數的輸出非負,不能近似爲高斯分佈。

The goal of Batch Normalization is to achieve a stable distribution of activation values throughout training, and in our experiments we apply it before the nonlinearity since that is where matching the first and second moments is more likely to result in a stable distribution.

—— Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift

但是,在caffenet-benchmark-batchnorm中,作者基於caffenet在ImageNet2012上做了如下對比實驗,

https://github.com/ducha-aiki/caffenet-benchmark/blob/master/batchnorm.md

實驗表明,放在前後的差異似乎不大,甚至放在ReLU後還好一些。

放在ReLU後相當於直接對每層的輸入進行歸一化,如下圖所示,這與淺層模型的Standardization是一致的。

https://www.microsoft.com/en-us/research/video/how-does-batch-normalization-help-optimization/

caffenet-benchmark-batchnorm中,還有BN層與不同激活函數、不同初始化方法、dropout等排列組合的對比實驗,可以看看。

所以,BN究竟應該放在激活的前面還是後面?以及,BN與其他變量,如激活函數、初始化方法、dropout等,如何組合纔是最優?可能只有直覺和經驗性的指導意見,具體問題的具體答案可能還是得實驗說了算(微笑)。

BN層爲什麼有效?

BN層的有效性已有目共睹,但爲什麼有效可能還需要進一步研究,這裏有一些解釋,

  • BN層讓損失函數更平滑。論文How Does Batch Normalization Help Optimization中,通過分析訓練過程中每步梯度方向上步長變化引起的損失變化範圍、梯度幅值的變化範圍、光滑度的變化,認爲添**加BN層後,損失函數的landscape(loss surface)變得更平滑,相比高低不平上下起伏的loss surface,平滑loss surface的梯度預測性更好,可以選取較大的步長。**如下圖所示,

    https://arxiv.org/abs/1805.11604

  • BN更有利於梯度下降。論文An empirical analysis of the optimization of deep network loss surfaces中,繪製了VGG和NIN網絡在有無BN層的情況下,loss surface的差異,包含初始點位置以及不同優化算法最終收斂到的local minima位置,如下圖所示。沒有BN層的,其loss surface存在較大的高原,有BN層的則沒有高原,而是山峯,因此更容易下降。
    https://arxiv.org/abs/1612.04010

  • 這裏再提供一個直覺上的理解,沒有BN層的情況下,網絡沒辦法直接控制每層輸入的分佈,其分佈前面層的權重共同決定,或者說分佈的均值和方差“隱藏”在前面層的每個權重中,網絡若想調整其分佈,需要通過複雜的反向傳播過程調整前面的每個權重實現,BN層的存在相當於將分佈的均值和方差從權重中剝離了出來,只需調整γ\gammaβ\beta兩個參數就可以直接調整分佈,讓分佈和權重的配合變得更加容易。

這裏多說一句,論文How Does Batch Normalization Help Optimization中對比了標準VGG以及加了BN層的VGG每層分佈隨訓練過程的變化,發現兩者並無明顯差異,認爲BatchNorm並沒有改善 Internal Covariate Shift但這裏有個問題是,兩者的訓練都可以收斂,對於不能收斂或者訓練過程十分震盪的模型呢,其分佈變化是怎樣的?我也不知道,沒做過實驗(微笑)。

以上。

參考

發佈了55 篇原創文章 · 獲贊 77 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章