Deep Learning Note: 2-6 批量标准化

  批量标准化(Batch Normalization)是深度学习中的一个重要算法,它可以让网络更加强健,令网络对更大范围的参数都有较好的效果,使得超参数的搜索更加容易,也有助于训练更深的网络。

1. 标准化激活值

  前文介绍了对输入特征进行标准化的方法,标准化有助于提高学习速度。在神经网络中,对其中各层的激活值进行标准化,也有利于提高下一层参数的学习速度,这就是批量标准化所做的。例如对第 2 层的激活值 $a^{[2]}$ 进行标准化,会有利于提高对第 3 层参数 $W^{[3]}$ 和 $b^{[3]}$ 的学习速度。实践中,在对激活值($a^{[2]}$)还是对激活函数的输入($z^{[2]}$)进行标准化的问题上存在争论,更多的时候是对激活函数的输入进行标准化。

  批量标准化的计算过程为,对于网络中的中间值,如第 $l$ 层激活函数的输入 $z = \begin{bmatrix} z^{(1)} & z^{(2)} & … & z^{(m)}\end{bmatrix} $,计算:

\begin{equation}
\mu = \frac{1}{m} \sum_{i=1}^m z^{(i)} \tag{1}
\end{equation}

\begin{equation}
\sigma^2 = \frac{1}{m} \sum_{i=1}^m (z^{(i)} – \mu)^2 \tag{2}
\end{equation}

\begin{equation}
z_{norm}^{(i)} = \frac{z^{(i)} – \mu}{\sqrt{\sigma^2 + \epsilon}} \tag{3}
\end{equation}

\begin{equation}
\tilde{z}^{(i)} = \gamma z_{norm}^{(i)} + \beta \tag{4}
\end{equation}

  上面式 (3) 中的 $\epsilon$ 是一个很小的数值,避免 $\sigma^2$ 过小,保证数值稳定性。通过式 (1) 到 (3) 计算得到的 $z_{norm}$ 具有 0 均值和单位方差。通过式 (4),$\gamma$ 和 $\beta$ 可以进一步控制 $\tilde{z}$ 的方差和均值。$\gamma$ 和 $\beta$ 是可以学习的参数,例如在梯度下降算法中,可以像更新参数 $W$ 和 $b$ 一样更新 $\gamma$ 和 $\beta$。之后,使用 $\tilde{z}$ 代替 $z$ 进行后续的计算,如作为该层激活函数的输入。

  式 (4) 中使用 $\gamma$ 和 $\beta$ 控制 $\tilde{z}$ 的方差和均值的意义在于,除了要对 $z$ 进行标准化,使其具有固定的均值和方差,另一方面,对于不同的场景,可能需要 $\tilde{z}$ 具有不同的分布,而不单单是 0 均值和单位方差。比如对于 Sigmoid 激活函数,我们可能会希望其输入具有较大的方差,或者不为 0 的均值,以更好地利用其中间两端的非线性的区间,而不仅仅局限于正中间的一段线性区间。

2. 在神经网络中应用批量标准化

  批量标准化通常应用于小批量梯度下降,对于第 $t$ 个小批量样本集合 $X^{\{t\}}$,网络中第 $l$ 层的前向传播计算过程为:

  1. 使用第 $l-1$ 层输出的激活值 $A^{[l-1]}$ 和 第 $l$ 层的参数 $W^{[l]}$,计算得到第 $l$ 层激活函数的输入 $Z^{[l]}$。
  2. 使用第 $l$ 层参数 $\gamma^{[l]}$、$\beta^{[l]}$ 计算标准化的 $\tilde{Z}^{[l]}$。
  3. 使用 $\tilde{Z}^{[l]}$ 作为第 $l$ 层激活函数 $g^{[l]}(Z)$ 的输入,计算第 $l$ 的激活值 $A^{[l]} = g^{[l]}(\tilde{Z}^{[l]})$。

  反向传播的计算过程为:

  1. 通过反向传播计算得到第 $l$ 层各参数的偏导 $dW^{[l]}$、$d\gamma^{[l]}$、$d\beta^{[l]}$。
  2. 更新参数: $W^{[l]} = W^{[l]} – \alpha dW^{[l]}$,$\gamma^{[l]} = \gamma^{[l]} – \alpha d\gamma^{[l]}$,$\beta^{[l]} = \beta^{[l]} – \alpha d\beta^{[l]}$

  以上过程的计算都是在当前小样本 $X^{\{t\}}$ 上进行,涉及的参数有权重 $W^{[l]}$ 和批量标准化的两个参数 $\gamma^{[l]}$ 和 $\beta^{[l]}$。注意参数中没有偏置 $b^{[l]}$,因为$b^{[l]}$ 在一次循环中只是一个常数,由 $Z^{[l]} = W^{[l]}A^{[l-1]} + b^{[l]}$,在使用了批量标准化后,经过上面式 (3) 减去均值 $\mu$ 的步骤,就会将偏置 $b^{[l]}$ 减掉,所以在使用批量标准化后,就没有必要使用偏置参数 $b^{[l]}$ 了。

  除了小批量梯度下降,批量标准化也可用于动量梯度下降、RMSprop 和 Adam 算法,只需要修改反向传播时对各参数的更新方式。

3. 对批量标准化的理解

  前面介绍标准化激活值时与标准化输入做了类比,说明批量标准化通过标准化激活值,有利于提高学习速度。批量标准化有助于解决 Covariate Shifting 问题,即网络输入的分布发生后,会对网络性能产生影响的现象。

  比如要训练一个分类器用于识别猫的图片,训练时只是用了黑猫的图片,模型能够很好地分辨黑猫,此时使用其他颜色的猫来测试这个分类器,发现性能出现下降。模型只学会了识别黑猫,当输入数据的分布发生变化,比如猫的颜色变了,模型就不能很好地进行预测了,虽然要解决的问题(映射)本身并没有发生变化(识别图片是否有猫)。

  从神经网络的角度来看,例如对于一个 5 层的网络,从第 3 层的角度来看,第 3 到 5 层网络根据第 2 层的输出,通过训练得到对应的参数,使得网络输出与样本的实际标签尽可能接近。而第 2 层的输出又依赖其之前网络的输出和参数,随着训练的进行,参数不断更新,第 2 层的输出也在发生变化,对第 3 层来说,它的输入一直在发生变化,增大了其学习其中规律的难度。

  批量标准化并不会限制各层的输出具有固定的值,而是限制各层输出具有固定的分布,即不论各层的输出如何变化,各层的输出(也即下一层的输入)都具有稳定的均值和方差,由该层的批量标准化参数 $\gamma$ 和 $\beta$ 控制。在训练过程中,各层在更新自己的参数时,其输出仍能保持稳定,这样后面一层不需要跟随前面一层的学习而进行额外的适应,例如第 2 层的学习过程中更新了参数,但其输出对第 3 层来说仍有相同的分布,第 3 层就不会被第 2 层的学习影响,在一定程度上降低了层与层之间的耦合,使得每层可以更加独立的进行学习,加快了学习速度。由此,批量标准化减少了各层更新参数对其之后网络的影响,使得各层的输入都更加稳定,减少了输入发生变化时对网络的影响。

  批量标准化还会产生少量的正则化效果。在批量标准化中,每一个小批量都使用该批量的均值和方差进行了标准化,相比整个数据集的均值和方差,每个小批量的均值和方差都有一定的噪声,由式 (3),减去均值时引入了加性噪声,除以方差时引入了乘性噪声。这些噪声进而被引入到了各层的激活值中,由此产生了少量的的正则化效果,使得模型更难以过拟合。选择较大的小批量大小可以减小批量均值和方差的噪声,从而降低正则化效果,反之选择较小的小批量大小可以提高正则化效果。但由于小批量均值和方差的噪声很小,所以批量标准化只有少量的正则化效果,正则化也不是批量标准化的目标。

4. 测试时的批量标准化

  在训练时,批量标准化一次性处理一个小批量的数据,在该小批量上计算上面的式 (1) 到 式 (4)。而测试时,不需要使用小批量,每次只要处理一个数据,需要使用其他方式来得到式(1) 和式(2) 的均值和方差。在批量标准化的典型实现中,使用各个小批量的均值和方差的指数加权平均来估计测试中使用的均值和方差。

  例如对于网络中的第 $l$ 层,对于第 $t$ 个小批量 $X^{\{t\}}$,首先计算该小批量的均值 $\mu ^{[l]\{t\}}$ 和方差 $\sigma^{2[l]\{t\}}$,然后通过指数加权平均对 $\mu ^{[l]\{t\}}$ 和 $\sigma^{2[l]\{t\}}$ 进行累计,得到 $\mu_{test} ^{[l]}$ 和 $\sigma_{test}^{2[l]}$;在测试时,使用 $\mu_{test}^{[l]}$ 和 $\sigma_{test}^{2[l]}$ 对测试样本进行处理,即:

\begin{equation}
z_{norm}^{[l](i)} = \frac{z^{[l](i)} – \mu_{test}^{[l]}}{\sqrt{\sigma_{test}^{2[l]} + \epsilon}}
\end{equation}

\begin{equation}
\tilde{z}^{[l](i)} = \gamma^{[l]} z_{norm}^{[l](i)} + \beta^{[l]}
\end{equation}