目錄html
博客:blog.shinelee.me | 博客園 | CSDNgit
在博文《爲何要作特徵歸一化/標準化? 博客園 | csdn | blog》中,咱們介紹了對輸入進行Standardization後,梯度降低算法更容易選擇到合適的(較大的)學習率,降低過程會更加穩定。github
在博文《網絡權重初始化方法總結(下):Lecun、Xavier與He Kaiming 博客園 | csdn | blog》中,咱們介紹瞭如何經過權重初始化讓網絡在訓練之初保持激活層的輸出(輸入)爲zero mean unit variance分佈,以減輕梯度消失和梯度爆炸。算法
但在訓練過程當中,權重在不斷更新,致使激活層輸出(輸入)的分佈會一直變化,可能沒法一直保持zero mean unit variance分佈,仍是有梯度消失和梯度爆炸的可能,直覺上感到,這多是個問題。下面具體分析。網絡
神經網絡能夠當作是上圖形式,對於中間的某一層,其前面的層能夠當作是對輸入的處理,後面的層能夠當作是損失函數。一次反向傳播過程會同時更新全部層的權重\(W_1, W_2, \dots, W_L\),前面層權重的更新會改變當前層輸入的分佈,而跟據反向傳播的計算方式,咱們知道,對\(W_k\)的更新是在假定其輸入不變的狀況下進行的。若是假定第\(k\)層的輸入節點只有2個,對第\(k\)層的某個輸出節點而言,至關於一個線性模型\(y = w_1 x_1 + w_2 x_2 + b\),以下圖所示,app
假定當前輸入\(x_1\)和\(x_2\)的分佈如圖中圓點所示,本次更新的方向是將直線\(H_1\)更新成\(H_2\),本覺得切分得不錯,可是當前面層的權重更新完畢,當前層輸入的分佈換成了另一番樣子,直線相對輸入分佈的位置可能變成了\(H_3\),下一次更新又要根據新的分佈從新調整。直線調整了位置,輸入分佈又在發生變化,直線再調整位置,就像是直線和分佈之間的「追逐遊戲」。對於淺層模型,好比SVM,輸入特徵的分佈是固定的,即便拆分紅不一樣的batch,每一個batch的統計特性也是相近的,所以只需調整直線位置來適應輸入分佈,顯然要容易得多。而深層模型,每層輸入的分佈和權重在同時變化,訓練相對困難。框架
上面是從網絡中單拿出一層分析,下面看一下多層的狀況。在反向傳播過程當中,每層權重的更新是在假定其餘權重不變的狀況下,向損失函數下降的方向調整本身。問題在於,在一次反向傳播過程當中,全部的權重會同時更新,致使層間配合「缺少默契」,每層都在進行上節所說的「追逐遊戲」,並且層數越多,相互配合越困難,文中把這個現象稱之爲 Internal Covariate Shift,示意圖以下。爲了不過於震盪,學習率不得不設置得足夠小,足夠小就意味着學習緩慢。機器學習
爲此,但願對每層輸入的分佈有所控制,因而就有了Batch Normalization,其出發點是對每層的輸入作Normalization,只有一個數據是談不上Normalization的,因此是對一個batch的數據進行Normalization。ide
Batch Normalization,簡稱BatchNorm或BN,翻譯爲「批歸一化」,是神經網絡中一種特殊的層,現在已經是各類流行網絡的標配。在原paper中,BN被建議插入在(每一個)ReLU激活層前面,以下所示,函數
若是batch size爲\(m\),則在前向傳播過程當中,網絡中每一個節點都有\(m\)個輸出,所謂的Batch Normalization,就是對該層每一個節點的這\(m\)個輸出進行歸一化再輸出,具體計算方式以下,
其操做能夠分紅2步,
假設BN層有\(d\)個輸入節點,則\(x\)可構成\(d \times m\)大小的矩陣\(X\),BN層至關於經過行操做將其映射爲另外一個\(d\times m\)大小的矩陣\(Y\),以下所示,
將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 \]
其中,\(x_i^{(b)}\)表示輸入當前batch的\(b\)-th樣本時該層\(i\)-th輸入節點的值,\(x_i\)爲\([x_i^{(1)}, x_i^{(2)}, \dots, x_i^{(m)}]\)構成的行向量,長度爲batch size \(m\),\(\mu\)和\(\sigma\)爲該行的均值和標準差,\(\epsilon\)爲防止除零引入的極小量(可忽略),\(\gamma\)和\(\beta\)爲該行的scale和shift參數,可知
可見,不管\(x_i\)本來的均值和方差是多少,經過BatchNorm後其均值和方差分別變爲待學習的\(\beta\)和\(\gamma\)。
對於目前的神經網絡計算框架,一個層要想加入到網絡中,要保證其是可微的,便可以求梯度。BatchNorm的梯度該如何求取?
反向傳播求梯度只需抓住一個關鍵點,若是一個變量對另外一個變量有影響,那麼他們之間就存在偏導數,找到直接相關的變量,再配合鏈式法則,公式就很容易寫出了。
\[ \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層輸出\(y_i\)的偏導\(\frac{\partial \ell}{\partial y_{i}}\),而後是對可學習參數的偏導\(\frac{\partial \ell}{\partial \gamma}\)和\(\frac{\partial \ell}{\partial \beta}\),用於對參數進行更新,想繼續回傳的話還須要求對輸入 \(x\)偏導,因而引出對變量\(\mu\)、\(\sigma^2\)和\(\hat{x}\)的偏導,根據鏈式法則再求這些變量對\(x\)的偏導。
在實際實現時,一般以矩陣或向量運算方式進行,好比逐元素相乘、沿某個axis求和、矩陣乘法等操做,具體能夠參見Understanding the backward pass through Batch Normalization Layer和BatchNorm in Caffe。
在預測階段,全部參數的取值是固定的,對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\),以下所示,
由於Standardization和scale and shift均爲線性變換,在預測階段全部參數均固定的狀況下,參數能夠合併成\(y=kx+b\)的形式,如上圖中行號11所示。
使用Batch Normalization,能夠得到以下好處,
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\)參數,若卷積層有\(n\)個卷積核,則有\(n\)對\(\gamma\)和\(\beta\)參數。
BatchNorm有兩個過程,Standardization和scale and shift,前者是機器學習經常使用的數據預處理技術,在淺層模型中,只需對數據進行Standardization便可,Batch Normalization可不能夠只有Standardization呢?
答案是能夠,但網絡的表達能力會降低。
直覺上理解,淺層模型中,只須要模型適應數據分佈便可。對深度神經網絡,每層的輸入分佈和權重要相互協調,強制把分佈限制在zero mean unit variance並不見得是最好的選擇,加入參數\(\gamma\)和\(\beta\),對輸入進行scale and shift,有利於分佈與權重的相互協調,特別地,令\(\gamma=1, \beta = 0\)等價於只用Standardization,令\(\gamma=\sigma, \beta=\mu\)等價於沒有BN層,scale and shift涵蓋了這2種特殊狀況,在訓練過程當中決定什麼樣的分佈是適合的,因此使用scale and shift加強了網絡的表達能力。
表達能力更強,在實踐中性能就會更好嗎?並不見得,就像曾經參數越多不見得性能越好同樣。在caffenet-benchmark-batchnorm中,做者實驗發現沒有scale and shift性能可能還更好一些,圖見下一小節。
原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上作了以下對比實驗,
實驗代表,放在先後的差別彷佛不大,甚至放在ReLU後還好一些。
放在ReLU後至關於直接對每層的輸入進行歸一化,以下圖所示,這與淺層模型的Standardization是一致的。
caffenet-benchmark-batchnorm中,還有BN層與不一樣激活函數、不一樣初始化方法、dropout等排列組合的對比實驗,能夠看看。
因此,BN究竟應該放在激活的前面仍是後面?以及,BN與其餘變量,如激活函數、初始化方法、dropout等,如何組合纔是最優?可能只有直覺和經驗性的指導意見,具體問題的具體答案可能仍是得實驗說了算(微笑)。
BN層的有效性已有目共睹,但爲何有效可能還須要進一步研究,這裏有一些解釋,
BN層讓損失函數更平滑。論文How Does Batch Normalization Help Optimization中,經過分析訓練過程當中每步梯度方向上步長變化引發的損失變化範圍、梯度幅值的變化範圍、光滑度的變化,認爲添加BN層後,損失函數的landscape(loss surface)變得更平滑,相比高低不平上下起伏的loss surface,平滑loss surface的梯度預測性更好,能夠選取較大的步長。以下圖所示,
BN更有利於梯度降低。論文An empirical analysis of the optimization of deep network loss surfaces中,繪製了VGG和NIN網絡在有無BN層的狀況下,loss surface的差別,包含初始點位置以及不一樣優化算法最終收斂到的local minima位置,以下圖所示。沒有BN層的,其loss surface存在較大的高原,有BN層的則沒有高原,而是山峯,所以更容易降低。
這裏再提供一個直覺上的理解,沒有BN層的狀況下,網絡沒辦法直接控制每層輸入的分佈,其分佈前面層的權重共同決定,或者說分佈的均值和方差「隱藏」在前面層的每一個權重中,網絡若想調整其分佈,須要經過複雜的反向傳播過程調整前面的每一個權重實現,BN層的存在至關於將分佈的均值和方差從權重中剝離了出來,只需調整\(\gamma\)和\(\beta\)兩個參數就能夠直接調整分佈,讓分佈和權重的配合變得更加容易。
這裏多說一句,論文How Does Batch Normalization Help Optimization中對比了標準VGG以及加了BN層的VGG每層分佈隨訓練過程的變化,發現二者並沒有明顯差別,認爲BatchNorm並無改善 Internal Covariate Shift。但這裏有個問題是,二者的訓練均可以收斂,對於不能收斂或者訓練過程十分震盪的模型呢,其分佈變化是怎樣的?我也不知道,沒作過實驗(微笑)。
以上。