Convolution+BatchNorm+Scale模块参数设置 & 融合BatchNorm+Scale层到Convolution层

Convolution+BatchNorm+Scale+Relu的组合模块在卷积后进行归一化,然后在放出非线性Relu层,可以加速训练收敛。但在推理时BatchNorm非常耗时,可以将训练时学习到的BatchNorm+Scale的线性变换参数融合到卷积层,替换原来的Convolution层中weight和bias,实现在不影响准确度的前提下加速预测时间。

一、Convolution+BatchNorm+Scale层在caffe中参数设置示例:

layer {
  name:  "Conv1"
  type: "Convolution"
  bottom: "Conv1"
  top:  "Conv2"
  convolution_param {
    num_output: 64
    kernel_h:1
    kernel_w:3
    pad_h: 0
    pad_w: 1
    stride: 1
    weight_filler {
        type: "msra"
      }
    bias_term: false
  }
}

layer {
  name: "Conv2/bn"
  type: "BatchNorm"
  bottom:  "Conv2"
  top:  "Conv2"
  batch_norm_param {
    use_global_stats: false
	  eps:1e-03
  }
  param {
    lr_mult: 0
    decay_mult: 0
  }
  param {
    lr_mult: 0
    decay_mult: 0
  }
  param {
    lr_mult: 0
    decay_mult: 0
  }
  include {
    phase: TRAIN
  }
}

layer {
  name: "Conv2/bn"
  type: "BatchNorm"
  bottom:  "Conv2"
  top:  "Conv2"
  batch_norm_param {
    use_global_stats: true
	  eps:1e-03
  }
  param {
    lr_mult: 0
    decay_mult: 0
  }
  param {
    lr_mult: 0
    decay_mult: 0
  }
  param {
    lr_mult: 0
    decay_mult: 0
  }
  include {
    phase: TEST
  }
}

layer {
  name: "Conv2/bn/scale"
  type: "Scale"
  bottom:  "Conv2"
  top:  "Conv2"
  param {
    lr_mult: 1
    decay_mult: 0
  }
  param {
    lr_mult: 1
    decay_mult: 0
  }
  scale_param {
    bias_term: true
  }
}

二、解释说明:

1、Convolution层的设置:

  • 权重: 强烈建议手动选择weight_filler初始化方式!对于Convolution+BatchNorm+Scale的组合模块,建议使用msra模式初始化。 (msra: short for  Microsoft Research Asia or He-initialization, ref:Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification)。其他情况xavier初始化比较常用, xavier初始化可以根据输入和输出神经元的个数,自动地决定初始化值的大小。caffe中默认的weight_filler是constant, value:0, 这种默认的初始化方式得到的结果一般不好,我就遇到过使用了默认的weight_filler后导致图像语义分割错误地得到同色图片的情况。
  • 因为BatchNorm层会减去平均值,所以convolution层的bias_term设置并没有意义。bias_term默认值为true, 默认的bias_filler也是constant, value:0。所以手动设置bias_term: false。
  • 学习率和权重衰减系数,因为只有weight,没有bias,使用如下默认值(无需手动设置) 
param {
    lr_mult: 1
    decay_mult: 1
  }

2、BatchNorm层设置:

BatchNorm是进行归一化,计算

                                                                    \frac{x-mean}{\sqrt{var+\varepsilon }}                                                (1)

  • use_global_stats在训练时设为false,神经网络只针对每一个batch的数据进行归一化操作,并每一步都利用滑移平均计算更新全局的mean和variance,但是并没有使用这两个全局的统计量;在测试时use_global_stats设为true,直接使用训练时计算好的全局mean和variance进行归一化;
  • eps是在分母的var项上加一个小值,防止方差为0时出错;
  • moving_average_fraction默认值为0.999,值越小表示较新迭代计算的mean和var权重更大,之前的迭代影响越小;
  • BatchNorm的三个参数mean,variance,moving_average_fraction。其中mean,variance是由输入数据计算直接计算得到的,moving_average_fraction是指定的,因此都与学习率和衰减率无关,设定

param {
lr_mult: 0
decay_mult: 0
}
param {
lr_mult: 0
decay_mult: 0
}
param {
lr_mult: 0
decay_mult: 0
}

参考资料:

https://github.com/hujie-frank/SENet/issues/26 

https://gist.github.com/ducha-aiki/c0d1325f0cebe0b05c36

 

3、Scale层设置:

Scale是将BatchNorm得到的数据做线性变换:

                                                                   \gamma (\frac{x-mean}{\sqrt{var+\varepsilon }})+\beta                               (2)

bias_term在这里打开!学习率系数设定为1即可,无需decay_mult。

param {
     lr_mult: 1
     decay_mult: 0
}
param {
     lr_mult: 1
     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层的输入,带入公式(1)(2)中,得到公式如下:

                                                   W_{new}=\frac{W_{old}\cdot \gamma }{\sqrt{var+\epsilon} }                                             (3)

                                                   b_{new}=\frac{b_{old}\cdot \gamma }{\sqrt{var+\epsilon} }+\frac{mean\cdot \gamma }{\sqrt{var+\epsilon} }+\beta                  (4)

其中各参数的含义和定义同上文公式(1)(2)

3、另外,有些网络使用了dropout层防止过拟合,在预测时可直接删除dropout层,并不影响预测时数据的传输。

代码可以参考https://download.csdn.net/download/cxiazaiyu/10657938

代码中识别type类型符合BatchNorm, Scale和dropout的层对神经网络配置文件prototxt和权重文件caffemodel做相应修改。

你可能感兴趣的:(深度学习)