测试时的 Batch Norm( Batch Norm at test time)
Batch 归一化将你的数据以 mini-batch 的形式逐一处理,但在测试时,你可能需要对每个样本逐一处理:
$u = \frac{1}{m}\sum\limits_i { {z^{(i)}}}$
${\sigma ^2} = \frac{1}{m}\sum\limits_i {({z^{(i)}}} - u{)^2}$
$z_{norm}^{(i)} = \frac{ { {z^{(i)}} - u}}{ {\sqrt { {\sigma ^2} + \varepsilon } }}$
${ {\tilde z}^{(i)}} = \gamma z_{norm}^{(i)} + \beta$
在训练时,这些就是用来执行 Batch 归一化的等式。在一个 mini-batch 中,你将 mini-batch 的${z^{(i)}}$ 值求和,计算均值,所以这里你只把一个 mini-batch 中的样本都加起来,我用 m 来表示这个 mini-batch 中的样本数量,而不是整个训练集。然后计算方差,再计算$z_{norm}^{(i)}$ 即用均值和标准差来调整,加上$\varepsilon$是为了数值稳定性。${\tilde z}$是用$\gamma$和$\beta$再次调整${z_{norm}}$得到的。
请注意用于调节计算的u和${\sigma ^2}$是在整个 mini-batch 上进行计算,但是在测试时,你可能不能将一个 mini-batch 中的 6428 或 2056 个样本同时处理,因此你需要用其它方式来得到u和${\sigma ^2}$,而且如果你只有一个样本,一个样本的均值和方差没有意义。那么实际上,为了将你的神经网络运用于测试,就需要单独估算u和${\sigma ^2}$,在典型的 Batch 归一化运用中,你需要用一个指数加权平均来估算,这个平均数涵盖了所有 mini-batch:
选择l层为例:
第一个 mini-batch 和l层的的u为:${u^{\left\{ 1 \right\}\left[ l \right]}}$
第二个 mini-batch 和l层的的u为:${u^{\left\{ 2 \right\}\left[ 2 \right]}}$
依次类推。
可以采用指数加权平均的方法来追踪你看到的这个均值向量的最新平均值。同样的,你可以用指数加权平均来追踪你在这一层的第一个 mini-batch 中所见的${\sigma ^2}$的值,以及第二个 mini-batch 中所见的${\sigma ^2}$的值。因此在用不同的 mini-batch 训练神经网络的同时,能够得到你所查看的每一层的u和${\sigma ^2}$的实时数值。
最后在测试时,计算等式:
$z_{norm}^{(i)} = \frac{ { {z^{(i)}} - u}}{ {\sqrt { {\sigma ^2} + \varepsilon } }}$
只需要带入你的z值,使用u和${\sigma ^2}$的加权平均。
进而计算式子:
${ {\tilde z}^{(i)}} = \gamma z_{norm}^{(i)} + \beta$
总结一下就是,在训练时u和${\sigma ^2}$是在整个 mini-batch 上计算出来的包含了像是 64 或28 或其它一定数量的样本,但在测试时,你可能需要逐一处理样本,方法是根据你的训练集估算u和${\sigma ^2}$,估算的方式有很多种,理论上你可以在最终的网络中运行整个训练集来得到u和${\sigma ^2}$但在实际操作中,我们通常运用指数加权平均(也叫做流动平均)来追踪在训练过程中你看到的u和${\sigma ^2}$。