天天看點

Batch Normalization原理 與 反向傳播公式推導1.Batch Normalization的動機2.Batch Normalization的原理3.Batch Normalization的反向傳播

1.Batch Normalization的動機

在進行深度神經網絡訓練過程中,每一層的輸入的分布在不斷訓練過程中都會發生變化。我們知道,神經網絡每一層都相當于一個機率分布函數,将資訊輸入該函數,就會輸出相應的分類或回歸結果。我們最希望的是每次的輸入的機率分布都是相同的,這樣訓練的到的每一層網絡都能夠更加接近真實的輸入輸出關系。但是不幸的是,随着網絡參數的不斷更新,輸出結果也在不斷變動之中,導緻下一層的輸入樣本的機率分布也在變化。這種分布的改變到比較深的層次就會産生很大影響,深層的神經網絡每次更新參數就會變動劇烈。

按照論文《Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift》中的說法,為了克服這個問題,需要降低學習率、采用更加謹慎的參數初始化,以確定訓練過程中不會梯度爆炸或者消失,當然訓練過程更加緩慢;同時導緻使用飽和非線性激活函數更加困難(所謂飽和非線性就是sigmoid、softmax等激活函數,ReLU則是非飽和線性),因為機率分布和激活函數處理的機率分布偏離嚴重,這種困難指的就是淺層的資料可能過早進入飽和區導緻訓練過程死掉,也就是梯度消失。這種現象綜合起來叫做Internal Covariate Shift(ICS),有将ICS翻譯成内部協變偏移的,本人了解的Internal指的是一個神經網絡内部,Covariate就是層與層之間;本來層與層之間不該互相影響,結果因為以上原因,導緻協同的偏移變化。在論文《Layer Normalization》中Jimmy Lei Ba更關心的是在商業或用途中對神經網絡速度和訓練成本的影響。總之,Batch Normalization可以提升速度,訓練本身更快,還不會因為初始參數設定不當梯度爆炸或消失進而訓練過早停止而前功盡棄。

多說兩句,機器學習的基本假設就是所有的輸入樣本都是獨立同分布(IID)。對于用于圖像識别的神經網絡而言,我們可以把一個卷積核(神經元)覆寫的像素範圍成為一個特征元,sigmoid函數作為伯努利分布函數的激活函數,判斷這個特征元是A還是非A。深度卷積神經網絡前面的特征提取網絡,采用ReLU激活函數,并不對特征元進行分類,而是不斷強化特征元的特點。對于YOLO模型,随着神經網絡的不斷深入,這個特征元越來越大,大的特征元可以友善的判斷圖像中較大的範圍區域是不是某種目标。比如将圖像分割為1313的區域以後,最終的每個特征元就可以涵蓋一個33區域的特征,這就是圖像中比較大的一塊區域了,便于識别較大目标。每個通道使用一組相同的卷積核提取目标,就是強化每個通道中每個特征元的機率分布特征。卷積網絡必然存在樣本相加,産生的機率分布叫做邊緣機率分布(因為是求和,在表格中往往将這種值放在margin(表頭)的位置,是以叫margin distribution,和“邊緣”無關,呵呵!)。顯然邊緣分布會發生變化嘛。

其實,對于特征提取的backbone網絡,梯度消失還是很難的,本人了解最大的影響就是爆炸或者偏差過大。

2.Batch Normalization的原理

先說說Normalization怎麼翻譯,看到有的文章中翻譯成“正則化”,這絕對是不對滴,正則化是為了加速收斂對LOSS函數設定限制條件。這裡也可翻譯為“歸一化”,也很像向量或者矩陣歸一化的騷操作,不過确實沒有實作歸一的功能,感覺最好的翻譯方式是“标準化”。說了半天這個,因為中國有句古話“名不正而言不順”嘛。

先說說每層的激活函數都是非線性激活函數的情況。前面說到邊緣機率分布,當這些特征元加在一起,去參加篩選時,可能突然會發現集體跑偏了。啥意思呢,比如本來輸入的每個特征元是0-1之間的獨立同分布,當然屬于啥分布也不管,進入sigmoid函數,反正就是你大于某個門檻值就滑入1,小于某個門檻值就滑入0。如果權重求和後集體跑偏到了低于某個門檻值的位置,所有的激活函數判決就都是0,可不訓練停止了嘛。但是咱加了個标準化 x − m e a n v a r i a n c e \frac{x-mean}{variance} variancex−mean​,就強行把這些跑偏的特征分布拉回均值為0,方差不變的一個高斯分布中,然後接着去參加篩選,仍然會有很多特征元樣本點不過早滑入飽和區。是以标準化其實就是把大部分激活的值落入非線性函數的線性區内,其對應的導數遠離導數飽和區。

不考慮ReLU,多數情況下,樣本點會在sigmoid的線性區分布,如果方差比較小,都集中再在性區,這樣還不如直接使用線性激活函數;如果方差太大,直接二分類到飽和區,那就沒有效果。咋辦呢?就加個系數,相當于把方差拉大或者縮小,找個平衡點,又把特征特别明顯的樣本分類了,又把中間的樣本保留成火種進行下一層的處理。這樣特征就強化了。當然,這樣做有時候太激進了,都參照着mean去往中心偏移了,前面權重求和中的偏置項也給砍沒了,這時候需要糾正回來,于是在标準化的時候再加回來吧,于是就标準化就成了以下的樣子。

s c a l e ∗ x − m e a n v a r i a n c e + b i a s scale*\frac{x-mean}{\sqrt{variance}}+bias scale∗variance

​x−mean​+bias

其實,在YOLO模型中,batch normalization是放在卷積子產品中用的,這個CNN的偏置和标準的偏置項是共用的。

我們再說說激活函數不是非線性函數的情況,比如ReLU,可以這麼了解,因為樣本小于0,輸出就強制為0,也是飽和區了,這裡作為一個調節,可以防止樣本過多跑到強制為0飽和區,過濾掉特征不明顯的幹擾特征元樣本。對于圖像樣本,實際是很難把握資料集的樣本分布的,但通常大量圖像樣本中做到正态分布,每個批次輸入的圖像又千差萬别,均值和方差可能也不相同,又不能先把所有網絡層輸入的均值和方差提前算出來,怎麼辦?YOLO中采用了一種滾動更新mean和variance的方法,就是以提前設定或者預訓練得到的mean和variance為準,先乘0.99,再将每次訓練用新算出來的mean和variance乘0.01,加到以前權重0.99的mean和variance上,進行滾動更新。

這個方法前向傳播非常簡單,我們這裡定義輸入的值為列向量 z = { z 1 , z 2 , . . . , z n , . . . , z N } T \textbf{\textit{z}}=\lbrace{z_{1},z_{2},...,z_{n},...,z_{N}}\rbrace^{T} z={z1​,z2​,...,zn​,...,zN​}T,因為都在一個層中,下标就不再标注層序号。标準化後的值為 z o \textbf{\textit{z}}^{o} zo,此時,batch normalization的過程可以表示為

z o = s c a l e ∗ z n o r m + b ∗ I = s c a l e ∗ z − I ∗ M e a n ( z ) I ∗ V a r ( z ) + b ∗ I \textbf{\textit{z}}^{o}=scale*\textbf{\textit{z}}^{norm}+b*\textbf{\textit{I}}=scale*\frac{\textbf{\textit{z}}-\textbf{\textit{I}}*Mean(\textbf{\textit{z}})}{\textbf{\textit{I}}*\sqrt{Var(\textbf{\textit{z}})}}+b*\textbf{\textit{I}} zo=scale∗znorm+b∗I=scale∗I∗Var(z)

​z−I∗Mean(z)​+b∗I

,其中 M e a n ( z ) = 1 N ∑ n = 1 N z n Mean(\textbf{\textit{z}}) = \frac{1}{N}\sum_{n=1}^{N}{z_{n}} Mean(z)=N1​∑n=1N​zn​, V a r ( z ) = 1 N ∑ n = 1 N ( z n − M e a n ( z ) ) 2 Var(\textbf{\textit{z}}) = \frac{1}{N}\sum_{n=1}^{N}{(z_{n}-Mean(\textbf{\textit{z}}))^{2}} Var(z)=N1​∑n=1N​(zn​−Mean(z))2

下面推導一下反向傳播的過程。

3.Batch Normalization的反向傳播

由于标準化的過程涉及到的參數包含系數 s c a l e scale scale,偏置 b i a s bias bias,是以反向傳播主要計算針對 z \textbf{\textit{z}} z,系數 s c a l e scale scale,偏置 b i a s bias bias的梯度。

先計算針對 z \textbf{\textit{z}} z的梯度。

∂ L O S S ∂ z = ∂ L O S S ∂ z o ∂ z o ∂ z = s c a l e ∗ ∂ L O S S ∂ z o ∂ z n o r m ∂ z \frac{\partial{LOSS}}{\partial{\textbf{\textit{z}}}} =\frac{\partial{LOSS}}{\partial{\textbf{\textit{z}}^{o}}}\frac{\partial{\textbf{\textit{z}}^{o}}}{\partial{\textbf{\textit{z}}}} =scale*\frac{\partial{LOSS}}{\partial{\textbf{\textit{z}}^{o}}}\frac{\partial{\textbf{\textit{z}}^{norm}}}{\partial{\textbf{\textit{z}}}} ∂z∂LOSS​=∂zo∂LOSS​∂z∂zo​=scale∗∂zo∂LOSS​∂z∂znorm​

其中, ∂ L O S S ∂ z o \frac{\partial{LOSS}}{\partial{\textbf{\textit{z}}^{o}}} ∂zo∂LOSS​就是LOSS到激活函數輸入位置的梯度傳播,這個在上一篇文章《YOLOv3反向傳播原理 之 公式推導》中已經介紹,這裡重點計算 ∂ z n o r m ∂ z \frac{\partial{\textbf{\textit{z}}^{norm}}}{\partial{\textbf{\textit{z}}}} ∂z∂znorm​

這個步驟,這個步驟就是對每一個元素進行計算,計算完放入每個向量對應的位置,其中第m個元素為 ∂ z n n o r m ∂ z m \frac{\partial{z_{n}^{norm}}}{\partial{z_{m}}} ∂zm​∂znnorm​​, z n n o r m = z n − M e a n ( z ) V a r ( z ) z_{n}^{norm} =\frac{z_{n}-Mean(\textbf{\textit{z}})}{\sqrt{Var(\textbf{\textit{z}})}} znnorm​=Var(z)

​zn​−Mean(z)​

∂ z n n o r m ∂ z m = ( 1 ( m = n ) − 1 N ) V a r ( z ) − ∂ V a r ( z ) ∂ z m ( z n − M e a n ( z ) ) V a r ( z ) \frac{\partial{z_{n}^{norm}}}{\partial{{z}_{m}}} =\frac{(\textbf{1}(m=n)-\dfrac{1}{N})\sqrt{Var(\textbf{\textit{z}})}-\dfrac{\partial{\sqrt{Var(\textbf{\textit{z}})}}}{\partial{z_{m}}}(z_{n}-Mean(\textbf{\textit{z}}))}{Var(\textbf{\textit{z}})} ∂zm​∂znnorm​​=Var(z)(1(m=n)−N1​)Var(z)

​−∂zm​∂Var(z)

​​(zn​−Mean(z))​

下面,我們計算 ∂ V a r ( z ) ∂ z m \dfrac{\partial{\sqrt{Var(\textbf{\textit{z}})}}}{\partial{z_{m}}} ∂zm​∂Var(z)

​​

可得

∂ V a r ( z ) ∂ z m = 1 2 1 V a r ( z ) ∂ V a r ( z ) ∂ z m = 1 2 1 V a r ( z ) 2 N ∑ n = 1 N ( 1 ( m = n ) − 1 N ) ( z m − M e a n ( z ) ) = 1 N V a r ( z ) ( ( z m − M e a n ( z ) ) − 1 N ∑ n = 1 N ( z m − M e a n ( z ) ) ) = z m − M e a n ( z ) N V a r ( z ) \dfrac{\partial{\sqrt{Var(\textbf{\textit{z}})}}}{\partial{z_{m}}} =\frac{1}{2}\frac{1}{\sqrt{Var(\textbf{\textit{z}})}}\dfrac{\partial{Var(\textbf{\textit{z}})}}{\partial{z_{m}}}\\ =\frac{1}{2}\frac{1}{\sqrt{Var(\textbf{\textit{z}})}}\frac{2}{N}\sum_{n=1}^{N}{(\textbf{1}(m=n)-\dfrac{1}{N})(z_{m}-Mean(\textbf{\textit{z}}))}\\ =\frac{1}{N\sqrt{Var(\textbf{\textit{z}})}}\left((z_{m}-Mean(\textbf{\textit{z}}))-\dfrac{1}{N}\sum_{n=1}^{N}{(z_{m}-Mean(\textbf{\textit{z}}))}\right)\\ =\frac{z_{m}-Mean(\textbf{\textit{z}})}{N\sqrt{Var(\textbf{\textit{z}})}} ∂zm​∂Var(z)

​​=21​Var(z)

​1​∂zm​∂Var(z)​=21​Var(z)

​1​N2​n=1∑N​(1(m=n)−N1​)(zm​−Mean(z))=NVar(z)

​1​((zm​−Mean(z))−N1​n=1∑N​(zm​−Mean(z)))=NVar(z)

​zm​−Mean(z)​

帶入上式可得

∂ z n n o r m ∂ z m = ( 1 ( m = n ) − 1 N ) V a r ( z ) − ( z m − M e a n ( z ) ) ( z n − M e a n ( z ) ) N V a r ( z ) 3 \frac{\partial{z_{n}^{norm}}}{\partial{{z}_{m}}} =\frac{(\textbf{1}(m=n)-\dfrac{1}{N})}{\sqrt{Var(\textbf{\textit{z}})}}-\frac{(z_{m}-Mean(\textbf{\textit{z}}))(z_{n}-Mean(\textbf{\textit{z}}))}{N\sqrt[3]{Var(\textbf{\textit{z}})}} ∂zm​∂znnorm​​=Var(z)

​(1(m=n)−N1​)​−N3Var(z)

​(zm​−Mean(z))(zn​−Mean(z))​

好了,這裡求得了任意 x n n o r m x^{norm}_{n} xnnorm​對任意 x m x^{m} xm的導數,建立一個 N × N N×N N×N的矩陣 ∂ z n o r m ∂ z \frac{\partial{\textbf{\textit{z}}^{norm}}}{\partial{\textbf{\textit{z}}}} ∂z∂znorm​,第(n,m)個元素就是 ∂ z n n o r m ∂ z m \frac{\partial{z_{n}^{norm}}}{\partial{{z}_{m}}} ∂zm​∂znnorm​​。

但是再YOLO模型中,隻需要對角線上的梯度就行了。

對于scale的求導就是

∂ L O S S ∂ s c a l e = ∂ L O S S ∂ z o ∂ z o ∂ s c a l e \frac{\partial{LOSS}}{\partial{scale}} =\frac{\partial{LOSS}}{\partial{\textbf{\textit{z}}^{o}}}\frac{\partial{\textbf{\textit{z}}^{o}}}{\partial{scale}} ∂scale∂LOSS​=∂zo∂LOSS​∂scale∂zo​

其中,

∂ z m o ∂ s c a l e = z m n o r m \frac{\partial{z^{o}_{m}}}{\partial{scale}} ={z^{norm}_{m}} ∂scale∂zmo​​=zmnorm​

但是scale參數為針對整個feature map的參數,每次計算都會使用,和求bias一樣,可以将所有的 ∂ L O S S ∂ z m o ∂ z m o ∂ s c a l e m \frac{\partial{LOSS}}{\partial{z^{o}_{m}}}\frac{\partial{z^{o}_{m}}}{\partial{scale_{m}}} ∂zmo​∂LOSS​∂scalem​∂zmo​​疊加起來,這樣就相當于求内積,得到

∂ L O S S ∂ s c a l e = ∂ L O S S ∂ z o ∂ z o ∂ s c a l e \frac{\partial{LOSS}}{\partial{scale}} =\frac{\partial{LOSS}}{\partial{\textbf{\textit{z}}^{o}}}\frac{\partial{\textbf{\textit{z}}^{o}}}{\partial{scale}} ∂scale∂LOSS​=∂zo∂LOSS​∂scale∂zo​

對于bias,在卷積神經網絡中和神經元的偏置一起計算,再累加:

∂ L O S S ∂ b i a s = ∑ ∂ L O S S b i a s m \frac{\partial{LOSS}}{\partial{bias}} =\sum{\frac{\partial{LOSS}}{bias_{m}}} ∂bias∂LOSS​=∑biasm​∂LOSS​

以上就是反向傳播公式的推導。

繼續閱讀