目錄
1.BN的作用
BN層的設定一般是按照conv→bn→scale→relu的順序來形成一個block。
關於bn,有一個注意點,caffe實現中的use_global_stats參數在訓練時設置爲false,測試時設置爲true。
因爲在訓練時bn作用的對象是一個batch_size,而不是整個訓練集,如果沒有將其設置爲false,則有可能造成bn後數據更加偏離中心點,導致nan或87.3365的問題。
caffe 中爲什麼bn層要和scale層一起使用
這個問題首先要理解batchnormal是做什麼的。它其實做了兩件事。
1) 輸入歸一化 x_norm = (x-u)/std, 其中u和std是個累計計算的均值和方差。
2)y=alpha×x_norm + beta,對歸一化後的x進行比例縮放和位移。其中alpha和beta是通過迭代學習的。
那麼caffe中的bn層其實只做了第一件事。scale層做了第二件事。
這樣也就理解了scale層裏爲什麼要設置bias_term=True,這個偏置就對應2)件事裏的beta。
2.BN在caffe中代碼
第一種情況,phase: TRAIN/TEST都不加 ,caffe會自動匹配去設置use_global_stats的值
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param{
lr_mult:1
decay_mult:1
}
param{
lr_mult:2
decay_mult:0
}
convolution_param{
num_output:32
kernel_size:5
weight_filler{
type:"xavier"
}
bias_filler{
type:"constant"
}
}
}
layer {
name: "BatchNorm1"
type: "BatchNorm"
bottom: "conv1"
top: "conv1"
param {
lr_mult: 0
decay_mult: 0
}
param {
lr_mult: 0
decay_mult: 0
}
param {
lr_mult: 0
decay_mult: 0
}
}
layer {
name: "scale1"
type: "Scale"
bottom: "conv1"
top: "conv1"
scale_param {
bias_term: true
}
}
layer{
name:"relu1"
type:"ReLU"
bottom:"conv1"
top:"conv1"
}
第二種情況:加上use_global_stats, 測試的時候再改成true
layer {
name: "BatchNorm1"
type: "BatchNorm"
bottom: "conv1"
top: "conv1"
param {
lr_mult: 0
decay_mult: 0
}
param {
lr_mult: 0
decay_mult: 0
}
param {
lr_mult: 0
decay_mult: 0
}
batch_norm_param {
use_global_stats: false
}
}
3.補充
在下面參考【3】中,主要說了一下幾點:
(1)加快訓練速度的方法由兩種:白化和去均值
假設其分佈如上圖a所示(簡化爲2維)。由於初始化的時候,我們的參數一般都是0均值的(初始化值爲全0),因此開始的擬合y=Wx+b,基本過原點附近,如圖b紅色虛線。因此,網絡需要經過多次學習才能逐步達到如紫色實線的擬合,即收斂的比較慢。如果我們對輸入數據先作減均值操作,如圖c,顯然可以加快學習。更進一步的,我們對數據再進行去相關操作,使得數據更加容易區分,這樣又會加快訓練,如圖d。
(2)BN可以讓數據具有0均值和單位方差,加快收斂速度,對比圖如下:
(3)在使用BN的過程中,作者發現Sigmoid激活函數比Relu效果要好。
這一點作者並沒有在文章中作出理論說明,我覺得應該是實驗確定的。