原文链接:Cross-Iteration Batch Normalization
代码链接:https://github.com/Howal/Cross-iterationBatchNorm
随着BN的提出,现有的网络基本都在使用。但是在显存有限或者某些任务不允许大batch(比如检测或者分割任务相比分类任务训练时的batchsize一般会小很多)的情况下,BN效果就会差很多,如下图所示,当batch小于16时分类准确率急剧下降。

为了改善小batch情况下网络性能下降的问题,有各种新的normalize方法被提出来了(LN、IN、GN),详情请看文章GN-Group Normalization。上述不同的normalize方式适用于不同的任务,其中GN就是为检测任务设计的,但是它会降低推断时的速度。
本文的思想其实很简单,既然从空间维度不好做,那么就从时间维度进行,通过以前算好的BN参数用来计算更新新的BN参数,从而改善网络性能。从上图可以看出使用新提出的CBN,即使batch size小也可以获得较好的分类准确率。
通过过去的BN参数来计算新的BN参数有个问题,就是过去的BN参数是根据过去的网络参数计算出的feature来估算的,新的BN参数计算时,参数已经更新过了,如果直接使用之前的参数来计算新的BN参数会使得参数估计不准,网络性能下降,如上图中的Naive CBN。为了改进这种缺陷,文章使用泰勒多项式来估算新的BN参数。下面来介绍具体的计算方式。
一、Batch Normalization
先来回顾一下原始的BN计算公式。
BN操作的公式如下
上式中表示第t个mini-batch训练时的网络参数,
表示第t个mini-batch中第i个样本经过网络得到的feature map,
表示bn后均值为0和方差为1的特征,
和
表示当前mini-batch计算出来的均值和方差,
是防除零的系数,
和
表示BN中需要学习的参数。
和
计算方式如下
其中,m表示mini-batch里面有m个样本。
二、估计之前的均值和方差
假设现在是第t次迭代,那t之前的迭代计算时,拿次迭代来说,已经计算过了对应的均值和方差了,但是之前的计算是使用之前的网络参数得到的,用符号表示为
和
。现在想要估计的是参数
和
。文章认为连续几次网络参数的变化是平滑的,所以根据泰勒展开式可以估计出上述的两个参数:
其中和
表示对网络参数求偏导数,
表示泰勒展开式的高阶项,当
较小时,高阶项可以忽略不计。
注意:要精确的获得上式中的和
的值计算量会很大,因为网络中的第l层的参数
和
会依赖之前的层,例如依赖
和
,这里
,
表示第r层的参数。实际上文章发现当
时,偏导数
和
减小的非常快。
所以上两等式可以近似表示为下两式
三、Cross-Iteration Batch Normalization
CBN的工作方式如下

上一节利用之前的参数估算出来了当前参数下l层在次迭代的参数值,通过这些估计值可以计算出l层在当前迭代时的BN参数,计算公式如下:
注意:在有效的统计时是一直都会满足的,但是利用泰勒展开式估算不一定能满足条件,所以上述使用了max函数来保证这一点。还要说的是,代码实现的时候并没有这样写,实现时k是指所有
的元素,即过滤了不满足条件的值
最后CBN更新特征的方式同BN
CBN的伪代码如下

四、计算量优化
文章附录还有一个求偏导的优化方式来节省计算量,假设l和l-1层卷积的通道数为和
,K表示l层卷积的kernelsize,因此
和
通道数为
,
的维度数为
,如果直接计算
和
,时间复杂度为
。通过下面的推导我们可以知道可以在
和
时间内求出
和
下面拿来举例说明,为了简化符号,下面用
和
代替
和
。
上式中表示
中第j个通道的值,
表示第i个样本的第j个通道值。
上式中,n和k分别表示输入feature的通道维度索引和卷积的kernel维度索引,offset表示卷积时的索引值,表示l-1层的输出。
计算公式如下
从上式可以看出当j=q时才要计算,其它情况不用计算,这样就减少了计算量。
到这里CBN就介绍完了,思想很简单,但是公式较多,可以看看代码实现,代码量不多。最后要说的是,这篇文章提出来时为了解决小batch训练的情况,yolov4提出有一点就是方便用户使用一个GPU训练,所以yolov4借用了该算法的思想。
网友评论