为什么要批量规范化?
深层的神经网络有一个特点,就是它的数据端(浅层)到损失端(深层)的“距离”是很远的,
利用反向传播(深层→浅层)进行训练的时候,浅层往往训练的比较慢,
一旦浅层发生变化,所有的层都要跟着变,所以深度较大的层要重新学习多次,导致收敛变慢。
批量规范化(Batch Normalization,简称BN)可以稳定数据的分布,使得深层对于浅层的变化不那么敏感。
如何批量规范化?
全连接层
对全连接层,BN作用在特征维。
具体来说,就是对于全连接层的输入输出的一个批量 B \mathcal{B} B,我们可以看成一个矩阵,每行是一条数据样本,每一列是一个特征向量,BN会对每一列的特征向量进行规范化操作。
- 先求出特征向量的均值 μ ^ B \hat{\boldsymbol{\mu}}_\mathcal{B} μ^B和方差 σ ^ B {\hat{\boldsymbol{\sigma}}_\mathcal{B}} σ^B的估计值:
μ ^ B = 1 ∣ B ∣ ∑ x ∈ B x , σ ^ B 2 = 1 ∣ B ∣ ∑ x ∈ B ( x − μ ^ B ) 2 + ϵ . \begin{split}\begin{aligned} \hat{\boldsymbol{\mu}}_\mathcal{B} &= \frac{1}{|\mathcal{B}|} \sum_{\mathbf{x} \in \mathcal{B}} \mathbf{x},\\ \hat{\boldsymbol{\sigma}}_\mathcal{B}^2 &= \frac{1}{|\mathcal{B}|} \sum_{\mathbf{x} \in \mathcal{B}} (\mathbf{x} - \hat{\boldsymbol{\mu}}_{\mathcal{B}})^2 + \epsilon.\end{aligned}\end{split} μ^Bσ^B2=∣B∣1x∈B∑x,=∣B∣1x∈B∑(x−μ^B)2+ϵ.
其中 x ∈ B \mathbf{x} \in \mathcal{B} x∈B表示一个来自小批量 B \mathcal{B} B的输入特征;
此外,在方差估计值中添加一个小的常量 ϵ > 0 \epsilon > 0 ϵ>0,避免 σ ^ B {\hat{\boldsymbol{\sigma}}_\mathcal{B}} σ^B为零(后面 σ ^ B {\hat{\boldsymbol{\sigma}}_\mathcal{B}} σ^B要作为分母) - 再根据以下表达式转换 x \mathbf{x} x:
B N ( x ) = γ ⊙ x − μ ^ B σ ^ B + β . \mathrm{BN}(\mathbf{x}) = \boldsymbol{\gamma} \odot \frac{\mathbf{x} - \hat{\boldsymbol{\mu}}_\mathcal{B}}{\hat{\boldsymbol{\sigma}}_\mathcal{B}} + \boldsymbol{\beta}. BN(x)=γ⊙σ^Bx−μ^B+β.
其中拉伸参数(scale) γ \boldsymbol{\gamma} γ和偏移参数(shift) β \boldsymbol{\beta} β,它们的形状与 x \mathbf{x} x相同。是需要与其他模型参数一起学习的参数。
卷积层
对卷积层,BN作用在通道维。思想和将1X1卷积层看作全连接层类似。
通道维可以看作是特征维,BN会对每一个通道的输出进行规范化操作。
举个例子,假设我们的小批量包含 m m m个样本,并且对于每个通道,卷积的输出具有高度 p p p和宽度 q q q。 那么对于卷积层,我们在每个输出通道的 m ⋅ p ⋅ q m \cdot p \cdot q m⋅p⋅q个元素上同时执行每个批量规范化。
因此,在计算平均值和方差时,我们会收集所有空间位置的值,然后在相同通道内应用相同的均值和方差,以便在每个空间位置对值进行规范化。
批量规范化究竟做了什么?
源论文是想用BN来减少内部的协变量偏移,但这个只是直觉性的
后续论文指出它可能通过在每个Batch加入噪音(也就是均值和方差)控制模型复杂度
当然这些都不是定论(有够玄学的-_-)