Batchnorm原理及代码详解

论文名字:Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift
论文地址:https://arxiv.org/abs/1502.03167
参考了一些优秀同学的博客,结合SSD总结了一下便于理解。嘻嘻

BN层的优点

1.加快训练速度,这样我们就可以使用较大的学习率来训练网络。
2.提高网络的泛化能力。
3.BN层本质上是一个归一化网络层,可以替代局部响应归一化层(LRN层)。
4.可以打乱样本训练顺序(这样就不可能出现同一张照片被多次选择用来训练),论文中提到可以提高1%的精度。

BN层的背景意义

神经网络学习过程本质就是为了学习数据分布,一旦训练数据与测试数据的分布不同,那么网络的泛化能力也大大降低;另外一方面,一旦每批训练数据的分布各不相同(batch 梯度下降),那么网络就要在每次迭代都去学习适应不同的分布,这样将会大大降低网络的训练速度,这也正是为什么我们需要对数据都要做一个归一化预处理的原因。
在深度网络的训练过程中,前面层训练参数的更新将导致后面层输入数据分布的变化并累积下去,而数据分布一直发生变化会影响网络的训练速度。我们把网络中间层在训练过程中,数据分布的改变称之为:“Internal Covariate Shift”。而BN算法就是解决训练过程中,中间层数据分布发生改变的情况。

BN层是如何实现的

在这里插入图片描述

BN层的计算流程

1.计算样本均值。
2.计算样本方差。
3.样本数据标准化处理。只做到第三步的话,只使用了sigmoid激活函数的线性部分,会降低层的表达能力;引入第4步增加层的非线性。
4.进行平移和缩放处理。引入了γ和β两个参数。来训练γ和β两个参数。引入了这个可学习重构参数γ、β,让我们的网络可以学习恢复出原始网络所要学习的特征分布。

BN层在CNN中的使用

假如某一层卷积层有6个特征图,每个特征图的大小是100×100 ,这样就相当于这一层网络有6×100×100个神经元,如果采用BN,就会有6100100个参数γ、β,这样岂不是太恐怖了。因此卷积层上的BN使用,其实也是使用了类似权值共享的策略,把一整张特征图当做一个神经元进行处理。
卷积神经网络经过卷积后得到的是一系列的特征图,如果min-batch sizes为k,那么网络某一层输入数据可以表示为四维矩阵(k,h,w,c),c为特征图个数,w、h分别为特征图的宽高。在cnn中我们可以把每个特征图看成是一个特征处理(一个神经元),因此在使用Batch Normalization,mini-batch size 的大小就是:khw,于是对于每个特征图都只有一对可学习参数:γ、β。
说白了,在网络训练中以batch-size作为最小单位来不断迭代。每当有新的batch-size进入到网络里面就会产生新的γ和β。也就是说我们训练过程中要生成 图片总量/batch-size 组参数。

BN层的整体流程

在这里插入图片描述
输入:待进入激活函数的变量
输出:
1.这里的K,在卷积网络中可以看作是卷积核个数,如网络中第n层有64个卷积核,就需要计算64次。要注意,在正向传播时,会使用γ与β使得BN层输出与输入一样。
2.在反向传播时利用γ与β求得梯度从而改变训练权值(变量)。
3.通过不断迭代直到训练结束,求得关于不同层的γ与β。
4.不断遍历训练集中的图片,取出每个batch_size中的γ与β,最后统计每层BN的γ与β各自的和除以图片数量得到平均直,并对其做无偏估计值作为每一层的E[x]与Var[x]。 5.在预测的正向传播时,对测试数据求取γ与β,并使用该层的E[x]与Var[x],通过图中11:所表示的公式计算BN层输出。

SSD中的BN层

在这里插入图片描述

  • nets/ssd_vgg_300.py

用于建立基于VGG特征提取网络的SSD300模型的nets/ssd_vgg_300.py文件中
只有第一个特征层block4用到了BN:

  • ssd_net

其中ssd_net接口用于建立SSD网络:
可以看到在block6 block7中采用的是dropout,默认参数为0.5,其余层没有用到:
在这里插入图片描述
在这里插入图片描述
(为什么这样做我的理解是,由于第一个特征图比较靠前,norm比较大,所以需要引入l2_normalize来减少,而后面特征层归一化的话学习不到数据的真正分布,为了防止过拟合就在block6(19×19)和 block7(19×19)加入了dropout)

对于多尺度预测特征图是否采用BN的描述如下:
在这里插入图片描述

  • ssd_multibox_layer

调用的ssd_multibox_layer接口用于多尺度预测loc_pred位置和cls_pred类别:
在这里插入图片描述

  • nets/custom_layers.py

其中是否正则化调用了nets/custom_layers.py中的l2_normalization接口:
首先在输入数据(k,h,w,c)特征图个数的维度上进行正则化,过程见 nn.l2_normalize
在这里插入图片描述
然后对每一个特征图取一个可学习的scale因子(gamma),对各个层放缩调整,最后返回调整后的特征图。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值