Batch Normalization 以及 Pytorch的实现
Internal Covariate Shift
在说明 Batch Normalization 之前, 我们需要知道为什么要引入 Batch Normalization, Batch Normalization可以使得我们在训练阶段使用更大的学习率, 以及不必过分的关心模型参数的初始化. 为什么这么说呢, 因为在非线性神经元, 例如 \(sigmoid\) 函数, 在反向传播的过程中, 使用随机梯度下降的时候, 我们求导的结果不仅与训练数据有关, 而且与模型的参数有关, 例如:
\[g(x) = \frac{1}{1+exp(-x)} \z = g(Wu + b)
\]
我们知道 \(sigmoid\) 函数的特点是, 在 \(y\) 的绝对值很大的时候, 函数的梯度特别小, 这使得网络进入一个饱和状态, 并且收敛速度十分慢, 而 \(y\) 又受到 \(W\) 和 \(b\) 的影响, 所以模型的参数对模型的训练影响很大.
Internal Covariate Shift 的定义是, 训练过程中由于网络参数的变化而导致的网络激活层输出分布的变化. 通过在训练过程中, 格式化网络输入层的分布, 可以提高训练的速度.
Batch Normalization
\[\begin{array}{l}{\frac{\partial \ell}{\partial \gamma}=\sum_{i=1}^{m} \frac{\partial \ell}{\partial y_{i}} \cdot \widehat{x}_{i}} \\ {\frac{\partial \ell}{\partial \beta}=\sum_{i=1}^{m} \frac{\partial \ell}{\partial y_{i}}} \\{\frac{\partial \ell}{\partial \widehat{x}_{i}}=\frac{\partial \ell}{\partial y_{i}} \cdot \gamma} \\ {\frac{\partial \ell}{\partial \sigma_{B}^{2}}=\sum_{i=1}^{m} \frac{\partial \ell}{\partial \widehat{x}_{i}} \cdot\left(x_{i}-\mu_{\mathcal{B}}\right) \cdot \frac{-1}{2}\left(\sigma_{\mathcal{B}}^{2}+\epsilon\right)^{-3 / 2}} \\ {\frac{\partial \ell}{\partial \mu_{\mathcal{B}}}=\left(\sum_{i=1}^{m} \frac{\partial \ell}{\partial \widehat{x}_{i}} \cdot \frac{-1}{\sqrt{\sigma_{\mathcal{B}}^{2}+\epsilon}}\right)+\frac{\partial \ell}{\partial \sigma_{\mathcal{B}}^{2}} \cdot \frac{\sum_{i=1}^{m}-2\left(x_{i}-\mu_{\mathcal{B}}\right)}{m}} \\ {\frac{\partial \ell}{\partial x_{i}} = \frac{\partial \ell}{\partial \widehat{x}_{i}} \cdot \frac{1}{\sqrt{\sigma_{\mathcal{B}}^{2}+\epsilon}} + \frac{\partial \ell}{\partial \sigma_{\mathcal{B}}^{2}} \cdot \frac{2\left(x_{i}-\mu_{\mathcal{B}}\right)}{m} + \frac{\partial \ell}{\partial \mu_{\mathcal{B}}} \cdot \frac{1}{m}} \\ \end{array}
\]