介绍
现在BN层被广泛应用于图像分类网络,批量归一化的特性能保证信号不会过大,能良好的传播到下一层神经网络当中。但它也有一些缺点,如:
- 依赖bachsize,当batchsize较小时,效果不好
- 破坏一个batch内样本之间的独立性
- 带来额外的计算和显存开销
- 导致奇怪的Bug
本文试图从信号传播可视化,合适的权重初始化等角度,摆脱CNN对BN层的依赖,保证每一层网络的信号传播(不至于信号幅度过大,爆炸)。
绘制信号传播(Signal Propagation Plots)
为了更加直观看到信号在Resnet内传播时的变化,我们提出了一种信号可视化的方法。即给定一个服从高斯分布的随机输入(或者真实样本数据),给网络一个固定的随机初始化,然后统计网络中各个地方的激活值,主要观察以下三个统计量
- 通道均值平方(Average Channel Squared Mean),在NHW维度上计算均值的平方,然后在通道维度上取平均
- 通道平均方差 (Average Channel Variance),在NHW维度上计算方差,然后在通道维度上取平均。该统计量可以反应信号是爆炸还是弥散了。
- 残差分支上的通道平均方差(Average Channel Variance on the end of the residual branch),这可以反应残差分支(即残差块的主分支)是否被正确初始化了。
此外ResNet关于BN和ReLU激活的放置位置一直以来都有争议,在这次实验内,我们也分别记录了两种不同放置位置的统计量(以600层的ResNetV2为测试模型,注意不是原版ResNet)
ResNetV2
这是何恺明等人提出的一个变种,通过预先BN和激活,再输入到卷积层等结构,其优点是收敛速度比原版的快。下面是一个示意图
其中蓝线画的是 BN接ReLU 的结构,红线画的是 ReLU接BN 的结构,黑色点表示一个stage的结束。
我们可以观察到:
BN-ReLU结构下,Average Channel Variance线性增长
在BN-ReLU结构中,Average Channel Variance的方差在一个Stage内,呈现线性增长,然后到了第二个stage的第一个Block(我们也称Transition Block),又被重置。这是因为在普通的Block下,跨层连接是将输入连接到输出的
这个残差块的公式可以写成
X l + 1 = F l ( X l ) + X l X_{l+1}=F_l(X_l)+X_l Xl+1=Fl(Xl)+Xl
对应的方差可写为
V a r ( X l + 1 ) = V a r ( F l ( X l ) ) + V a r ( X l ) Var(X_{l+1})=Var(F_l(X_l))+Var(X_l) Var(Xl+1)=Var(Fl(Xl))+Var(Xl)
由于跨层连接的分支没有经过BN,进而导致方差呈线性增长
而在Transition Block中,跨层连接分支是归一化,激活的输入接了一个卷积层
归一化的输入能确保方差为1,因此该Block的Average Channel Variance被重置。
这里我有一点疑问是,BN+ReLU后的输入,显然不能保证方差为1,与论文说法的Normalized Input并不准确。我自己实验的时候,是在TransitionBlock这里将方差重置到0.2附近
BN-ReLU结构下,Average Channel Squared Mean也是线性增长
这是因为在残差主分支中,最后一个卷积层的输入是前面ReLU激活单元修正后的值,该部分值经过ReLU后,其均值为正(因为消去了负值)。这导致最后卷积输出的每个通道均值也为正数,出现均值偏移(mean shift)的现象。
而对于ReLU-BN结构,由于BN层放的是最后,所以能够保证每一层的均值均在0附近,相对更加稳定。
Normalizer-Free ResNet
从以上的分析我们观察到两点
- 残差分支上的BN层以一个与输入信号标准差成比例的因子,对输入进行缩放
- 引入一个常数因子,让信号的方差逐级增大。
为了达到以上两个目的,我们构造了一个残差块的新形式
X l + 1 = X l + α ∗ f l ( x l / β l ) X_{l+1}=X_{l}+\alpha*f_{l}(x_{l}/\beta_{l}) Xl+1=Xl+α∗fl(xl/βl)
有以下三个设计思想
- f l f_{l} fl是残差块分支,参数在初始化时保持方差,即
V a r ( f l ( z ) ) = V a r ( z ) Var(f_{l}(z))=Var(z) Var(fl(z))=Var(z) - β l \beta_{l} βl是一个固定的标量,值为 V a r ( x l ) \sqrt{Var(x_{l})} Var(xl)。这样能保证 f l f_{l} fl方差为1
- α \alpha α则是一个超参数,用于控制相邻Block的方差增长速率
在初始输入方差为1的假设下,每一层Block的方差以 1 + α 2 1+\alpha^2 1+α2增长
为什么不能直接使用He初始化
基于上述Block设计,我们以He初始化方式设置权重,但是实际信号传播并不好
He初始化公式如下
W N [ 0 , 2 n i ] W~N[0, \sqrt{\frac{2}{n_i}}] W N[0,ni2]
考虑以下变换