批归一化层(Batch Normallization)是一种在卷积神经网络模型中大量使用,为了加速模型收敛的技术。为什么CNN 中引入 BN 层可以加速网络的收敛呢?因为将输入的样本数据或特征图,归一化后,改善了输入数据的分布,或者说减少了内部相关变量分布的偏移,模型在统一的分布中更能获取数据的特征。所以这里的归一化,其实是标准化(Standardization),即
x n e w = x − μ σ x_{new} = \frac{x - \mu}{\sigma} xnew=σx−μ
一张图可以解释,改善输入数据的分布,可以更容易找到模型参数w和b,从而加速模型收敛
此外,BN 还充当正则器的作用,减少了 dropout 的需要。原文摘要如下
Batch Normalization allows us to use much higher learning rates and be less careful about initialization. It also acts as a regularizer, in some cases eliminating the need for Dropout.
在训练时,卷积层和 BN 是两个模块,但是为什么训练时不能融合,而训练完成后,仅执行前向推理却可以融合?因为训练时是按批次输入数据的,BN 就是为了解决小批次输入数据的分布偏移而提出的,因此训练时需要BN层。而训练后的推理,是单样本输入,训练时 BN 的参数已经确定,这些参数相当于对前一层的特征图数据做一次线性变换,而卷积层也可以转化为对特征图的线性变换。因此这两个相邻的算子可以融合。
模型训练时通过移动平均的方法近似获得整个样本集的均值和方差
μ = μ n = α μ n − 1 + ( 1 − α ) ⋅ 1 N ∑ i n x i , n \mu = \mu_n = \alpha\mu_{n-1} + (1-\alpha)\cdot\frac{1}{N}\sum_{i}^nx_{i,n} μ=μn=αμn−1+(1−α)⋅N1i∑nxi,n
对于特征图 Fc,i,j 中第 c 个通道的 ( i , j ) 的值,写程向量和矩阵形式为
( F ~ 1 , i , j F ~ 2 , i , j ⋮ F ~ C , i , j ) = ( 1 σ 1 2 + ε 0 0 0 0 1 σ 2 2 + ε 0 0 0 ⋱ 0 0 0 0 0 1 σ n 2 + ε ) ( F 1 , i , j F 2 , i , j ⋮ F C , i , j ) + ( − μ 1 σ 1 2 + ε − μ 2 σ 2 2 + ε ⋮ − μ n σ n 2 + ε ) \left(\begin{array}{l} \tilde{F}_{1, i, j} \\ \tilde{F}_{2, i, j} \\ \vdots \\ \tilde{F}_{C, i, j} \end{array}\right)=\left(\begin{array}{cccc} \frac{1}{\sqrt{\sigma_{1}^{2}+\varepsilon}} & 0 & 0 & 0 \\ 0 & \frac{1}{\sqrt{\sigma_{2}^{2}+\varepsilon}} & 0 & 0 \\ 0 & \ddots & 0 & 0\\ 0 & 0 & 0 & \frac{1}{\sqrt{\sigma_{n}^{2}+\varepsilon}} \end{array}\right)\left(\begin{array}{l} F_{1, i, j} \\ F_{2, i, j} \\ \vdots \\ F_{C, i, j} \end{array}\right)+\left(\begin{array}{c} -\frac{\mu_{1}}{\sqrt{\sigma_{1}^{2}+\varepsilon}} \\ -\frac{\mu_{2}}{\sqrt{\sigma_{2}^{2}+\varepsilon}} \\ \vdots \\ -\frac{\mu_{n}}{\sqrt{\sigma_{n}^{2}+\varepsilon}} \end{array}\right) F~1,i,jF~2,i,j⋮F~C,i,j = σ12+ε10000σ22+ε1⋱00000000σn2+ε1 F1,i,jF2,i,j⋮FC,i,j + −σ12+εμ1−σ22+εμ2⋮−σn2+εμn
即 F = W * x + b,因此可将两者合并
F ~ i , j = W b n ( W c o n v F i , j + b c o n v ) + b b n \tilde{F}_{i, j} = W_{bn}(W_{conv}F_{i,j} + b_{conv}) + b_{bn} F~i,j=Wbn(WconvFi,j+bconv)+bbn
从而新的卷积层的 W 为 Wbn* Wconv ,新的 b 为 Wbn * Wconv + Wbn
具体实现可参考PyTorch的相关源码。
Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift
ML 入门:归一化、标准化和正则化
BN与Conv层的合并
模型推理加速技巧:融合BN和Conv层