目錄
一、Batchnorm解決的問題
二、Batchnorm 原了解讀
☆加入可訓練的參數alpha 和 beta的作用:
三、caffe中為什麼bn層要和scale層一起使用
1、caffe中BatchNorm層參數:
2、☆BN在訓練和測試階段的差別
3、caffe中scale層參數
三、❤❤融合BatchNorm+Scale層到卷積層進行推理加速
四、BatchNorm層訓練和測試的注意事項
五、BatchNorm的好處
一、Batchnorm解決的問題
- 網絡層輸入分布的波動較大;Batchnorm就是使網絡每層的輸入分布想對穩定。
Internal Covariate Shift:深度學習的網絡較深,每一層的輸入依賴上一層輸出,随着訓練進行,網絡參數(W和b)更新,使得每一層的輸入分布波動比較大,這會使得模型訓練收斂比較困難。
- (1)網絡參數需要不停調整來适應輸入資料分布的變化,導緻網絡學習速度的降低;
- (2)網絡的訓練過程,随着一層一層傳導,深層網絡層的輸入容易陷入梯度飽和區(即sigmoid函數兩側,梯度接近于0),減緩網絡收斂速度。
簡單一句話:在訓練過程中,每輪疊代網絡層的輸入資料分布變化很大的話,使得資料抖動很大,導緻權重變化也會很大,網絡很難收斂。而batch norm會将資料歸一化,減少不同batch間資料的抖動情況,進而提高訓練速度加快收斂。
___________________________________________________________________________
PS:不想關注的太細,該小節後面不用細看了。
機器學習領域有個很重要的假設:IID獨立同分布假設,就是假設訓練資料和測試資料是滿足相同分布的,這是通過訓練資料獲得的模型能夠在測試集獲得好的效果的一個基本保障。那BatchNorm的作用是什麼呢?BatchNorm就是在深度神經網絡訓練過程中使得每一層神經網絡的輸入保持相同的分布。
如果ML系統執行個體集合<X,Y>中的輸入值X的分布老是變,這不符合IID假設,網絡模型很難穩定的學規律,這不得引入遷移學習才能搞定嗎,我們的ML系統還得去學習怎麼迎合這種分布變化啊。對于深度學習這種包含很多隐層的網絡結構,在訓練過程中,因為各層參數不停在變化,是以每個隐層都會面臨covariate shift的問題,也就是在訓練過程中,隐層的輸入分布老是變來變去,這就是所謂的“Internal Covariate Shift”,Internal指的是深層網絡的隐層,是發生在網絡内部的事情,而不是covariate shift問題隻發生在輸入層。
BN的基本思想其實相當直覺:因為深層神經網絡在做非線性變換前的激活輸入值(就是那個x=WU+B,U是輸入)随着網絡深度加深或者在訓練過程中,其分布逐漸發生偏移或者變動,之是以訓練收斂慢,一般是整體分布逐漸往非線性函數的取值區間的上下限兩端靠近(對于Sigmoid函數來說,意味着激活輸入值WU+B是大的負值或正值),是以這導緻反向傳播時低層神經網絡的梯度消失,這是訓練深層神經網絡收斂越來越慢的本質原因,而BN就是通過一定的規範化手段,把每層神經網絡任意神經元這個輸入值的分布強行拉回到均值為0方差為1的标準正态分布,其實就是把越來越偏的分布強制拉回比較标準的分布,這樣使得激活輸入值落在非線性函數對輸入比較敏感的區域,這樣輸入的小變化就會導緻損失函數較大的變化,意思是這樣讓梯度變大,避免梯度消失問題産生,而且梯度變大意味着學習收斂速度快,能大大加快訓練速度。
dropout和bN抑制過拟合的方法有着統一的思想, 即:
在訓練階段引入随機性, 防止過度比對; 在測試階段通過求期望等方式在全局去除掉這種随機性, 進而獲得确定而準确的結果。
二、Batchnorm 原了解讀
☆加入可訓練的參數alpha 和 beta的作用:
- 防止每層特征被歸一化成一樣的,網絡學習不到輸入資料的特征,加入可學習的alpha 和 beta能夠時網絡參數有一定的分布移動和差異。
之前就說過,為了減小輸入分布波動,對神經網絡的每一層做歸一化不就可以了,假設将每一層輸出後的資料都歸一化到0均值,1方差,滿足正太分布,但是,此時有一個問題,每一層的資料分布都是标準正太分布,導緻其完全學習不到輸入資料的特征,因為,費勁心思學習到的特征分布被歸一化了,是以,直接對每一層做歸一化顯然是不合理的。
但是如果稍作修改,加入可訓練的參數alpha 和 beta做歸一化,那能防止每層特征歸一化成一樣,接下來結合下圖的僞代碼做詳細的分析:
流程圖:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIwczX0xiRGZkRGZ0Xy9GbvNGL2EzXlpXazxSd10mY3lEVOBTTq1Ee0clWv5kMMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL1QjN3ITOwUTMzIjNwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
三、caffe中為什麼bn層要和scale層一起使用
這個問題首先要清楚BN的是做什麼的。它其實做了兩件事:
- (1)輸入歸一化:x_norm = (x - mean) / var,其中mean和var是個累計計算的均值和方差。
- (2)對歸一化後的x進行比例縮放和位移:y = alpha * x_norm + beta,其中的alpha和beta是通過疊代學習得到的。
那麼caffe中的BN層其實隻做了第一件事,scale層做了第二件事。
1、caffe中BatchNorm層參數:
BatchNorm是進行歸一化,計算
eps是在分母的var項上加一個小值,防止方差為0時出錯,預設為1e-5;
1.1 caffe的BN層共有三個參數:均值mean、方差variance和滑動系數moving_average_fraction
- 參數mean,variance是由輸入資料計算直接計算得到的,參數moving_average_fraction是指定的,一般為0.99,并且不通過反向傳播更新;
- 是以上面三個參數都與學習率和衰減率無關,是以網絡中lr_mult和decay_mult都為0;
- 參數moving_average_fraction是控制均值和方差滑動更新的系數,訓練網絡更新均值和方差會用到它。
1.2 BN層中還有一個參數use_global_stats
- use_global_stats:如果為true,則使用事先儲存的均值和方差,否則采用滑動平均的方式計算更新全局的均值和方差。
- 該參數預設時,網絡測試時設定為true,訓練階段設定為false。
1.3 更重要的一點:由于BN層中會做歸一化處理,是以BN層前的那個卷積層應當将bias關閉,因為BN的操作會做一個減去均值的操作,是以卷積層有沒有bias都會被這個減法操作去除掉,是以這時候bias不起作用,是以将其關閉可以減少參數量且不影響模型準确率。
layer {
name: "conv1_bn"
type: "BatchNorm"
bottom: "conv1"
top: "conv1"
batch_norm_param {
use_global_stats: true #訓練時為false,測試時為true
}
#參數mean,variance是由輸入資料計算直接計算得到的,moving_average_fraction是指定的,
#是以都與學習率和衰減率無關,是以lr_mult和decay_mult都為0
param { #參數mean均值
lr_mult: 0.0 #網絡目前層的局部學習率.目前層學習率=base_lr*lr_mult;base_lr為網絡基礎學習率
decay_mult: 0 #網絡目前層的局部衰減率
}
param { #參數variance方差
lr_mult: 0.0
}
param { #參數moving_average_fraction滑動系數,預設0.999
lr_mult: 0.0
}
}
2、☆BN在訓練和測試階段的差別
- 訓練階段:每輪疊代時會計算目前batch中特征的均值和方法;并使用移動平均法更新訓練集整體的均值和方內插補點(供測試階段使用)。
- 測試階段:使用的均值和方差是整個訓練集的均值和方差。整個訓練集的均值和方差的值通常是在訓練的同時用移動平均法來計算的。
3、caffe中scale層參數
Scale是将BatchNorm得到的資料做線性變換:
bias_term在這裡打開!學習率系數設定為1即可,無需decay_mult。
layer {
name: "conv1_scale"
type: "Scale"
bottom: "conv1"
top: "conv1"
param {
lr_mult: 1.0
decay_mult: 0
}
param {
lr_mult: 1.0
decay_mult: 0
}
scale_param {
bias_term: true
}
}
三、❤❤融合BatchNorm+Scale層到卷積層進行推理加速
在推理時BatchNorm非常耗時,可以将訓練時學習到的BatchNorm+Scale的線性變換參數融合到卷積層。具體方法為:
- 1、識别prototxt檔案中的Batch和Scale層,直接删除(這要求BatchNorm和Scale層中top和bottom名保持一緻,才能保證删除BatchNorm和Scale層後資料仍然能夠正确傳輸,如上文中示例所用的方式)
- 2、修改caffemodel的weight,将convolution的bias_term修改為true,并用Convolution+BatchNorm+Scale的等效weight和bias去替換原來的weight和新打開的bias_term。convolution輸出值為wx+b,作為BatchNorm層的輸入.
- 3、另外,有些網絡使用了dropout層防止過拟合,在預測時可直接删除dropout層,并不影響預測時資料的傳輸。
合并具體公式:
參考:https://zhuanlan.zhihu.com/p/110552861
四、BatchNorm層訓練和測試的注意事項
1:BatchNormal層:
BN層的設定一般是按照conv->bn->scale->relu的順序來形成一個block。
use_global_stats:為True時,使用儲存的均值,方差;為False時,滑動計算均值方差。在caffe中,該參數預設的話,TEST階段自動置為True, 其他階段為False. 當Finetune需要freeze BN的參數時,要把該參數置為False,否則均值,方差仍在更新;
moving_average_fraction:滑動系數,預設0.999;
eps:加在var上面的,防止标準化時分母為0。
五、☆BatchNorm的好處
BatchNorm為什麼NB呢,關鍵還是效果好。
1)BN使得網絡中每層輸入資料的分布相對穩定,加快了模型學習速度;
BN通過規範化與線性變換使得每一層網絡的輸入資料的均值與方差都在一定範圍内,使得後一層網絡不必不斷去适應底層網絡中輸入的變化,進而實作了網絡中層與層之間的解耦,允許每一層進行獨立學習,有利于提高整個神經網絡的學習速度。
2)BN使得模型對網絡中的參數不那麼敏感,使調參過程變得簡單多了,對于初始化要求沒那麼高,而且可以使用較大的學習率等;
使用Batch Normalization之後,抑制了參數微小變化随着網絡層數加深被放大的問題,使得網絡對參數大小的适應能力更強,此時我們可以設定較大的學習率而不用過于擔心模型divergence的風險。
3)BN具有一定的正則化效果。不用Dropout也能達到很好的泛化效果;
在Batch Normalization中,由于我們使用mini-batch的均值與方差作為對整體訓練樣本均值與方差的估計,盡管每一個batch中的資料都是從總體樣本中抽樣得到,但不同mini-batch的均值與方差會有所不同,這就為網絡的學習過程中增加了随機噪音,與Dropout通過關閉神經元給網絡訓練帶來噪音類似,在一定程度上對模型起到了正則化的效果。
4)BN允許網絡使用飽和性激活函數(例如sigmoid,tanh等),緩解梯度消失問題
在不使用BN層的時候,由于網絡的深度與複雜性,很容易使得底層網絡變化累積到上層網絡中,導緻模型的訓練很容易進入到激活函數的梯度飽和區;通過normalize操作可以讓激活函數的輸入資料落在梯度非飽和區,緩解梯度消失的問題;另外通過自适應學習
與
又讓資料保留更多的原始資訊。
參考:
https://zhuanlan.zhihu.com/p/34879333
https://blog.csdn.net/zhuiqiuk/article