训练时使用一个minibatch的训练数据计算均值和方差然后标准化数据,在test的时候我们也希望作相同的处理,比较直接的方法是在训练集上重新计算一遍统计量,但是,如果有1000w数据,这种计算就比较花费时间,而test的速度越快越好,所以在训练的时候,顺便就把均值和方差计算出来了,当然不是精确值,是近似值,这就是moving average。
running_mean = momentum * running_mean + (1 - momentum) * sample_mean
running_var = momentum * running_var + (1 - momentum) * sample_var
running_var = momentum * running_var + (1 - momentum) * sample_var
可以理解为每次更新running mean相当于把之前的值衰减一些(* momentum),然后把当前的minibatch sample mean加进去一部分(* (1-momentum))。其实也就是一阶指数平滑平均
var同理,两个值在训练迭代过程中相当于是在不断的moving。完全是经验主义,没什么道理可讲,所以batch normalization本身是个次优的normalization,可能今后会被更优的normalization模型所取代。
在test时,直接使用训练得到的running mean/var标准化数据:
x_stand = (x - running_mean) / np.sqrt(running_var)
out = x_stand * gamma + beta
out = x_stand * gamma + beta
转自:https://www.zhihu.com/question/55621104