如下截取一部分train.prototxt的片段:
layer {
name: "conv2_em/bn"
type: "BatchNorm"
bottom: "conv2_em"
top: "conv2_em"
param {
lr_mult: 0
decay_mult: 0
}
param {
lr_mult: 0
decay_mult: 0
}
param {
lr_mult: 0
decay_mult: 0
}
}
可以看到这一层是batchnormal层,其中的参数设置,三个param中的lr_mult和decay_mult都设置为0。
原因如下:
caffe中的batchnormal层中有三个参数(具体代表什么自行去caffe源码中看吧:均值、方差和滑动系数),训练时这三个参数是通过当前的数据计算得到的,并且不通过反向传播更新,因此必须将lr_mult和decay_mult都设置为0,因为caffe中这两个参数缺省值是默认为1;如果为1,则会通过反向传播更新该层的参数,这显然是错误的做法。
此外,对于参数use_global_stats:如果为真,则使用保存的均值和方差,否则采用滑动平均计算新的均值和方差。该参数缺省的时候,如果是测试阶段则等价为真,如果是训练阶段则等价为假。
moving_average_fraction:滑动平均的衰减系数,默认为0.999
eps:分母附加值,防止除以方差时出现除0操作,默认为1e-5(不同框架采用的默认值不一样)
更重要的一点:由于BN层中会做归一化处理,因此BN层前的那个卷积层应当将bias关闭,因为BN的操作会做一个减去均值的操作,因此卷积层有没有bias都会被这个减法操作去除掉,所以这时候bias不起作用,因此将其关闭可以减少参数量且不影响模型准确率。
22 convolution_param {
23 num_output: 32
24 bias_term: false
25 pad: 1
26 kernel_size: 3
27 stride: 2
28 weight_filler {
29 type: "msra"
30 }
31 }
同时,由于caffe中,Scale层不需要对两个参数正则化,所以设置如下:
param {
lr_mult: 1
decay_mult: 0
}
param {
lr_mult: 1
decay_mult: 0
}