EMA指数加权平均
什么是EMA?
滑动平均(exponential moving average),或者叫做指数加权平均(exponentially weighted moving average),可以用来估计变量的局部均值,使得变量的更新与一段时间内的历史取值有关。
滑动平均可以看作是变量的过去一段时间取值的均值,相比对变量直接赋值而言,滑动平均得到的值在图像上更加平缓光滑,抖动性更小,不会因为某次的异常取值而使得滑动平均值波动很大,如图 1所示。
假设我们得到一个参数θ \thetaθ在不同的 epoch 下的值
θ 1 , θ 2 , . . . , θ t \theta_1,\theta_2,...,\theta_tθ
1
,θ
2
,...,θ
t
当训练结束的θ \thetaθ的MovingAverage 就是:
v t = β ∗ v t − 1 + ( 1 − β ) ∗ v t v_t=\betav_{t-1}+(1-\beta)v_tv
t
=β∗v
t−1
+(1−β)∗v
t
β \betaβ代表衰减率,该衰减率用于控制模型更新的速度。
Andrew Ng在Course 2 Improving Deep Neural Networks中讲到,t tt时刻变量v vv的滑动平均值大致等于过去1 / ( 1 − β ) 1/(1−\beta)1/(1−β)个时刻v vv值的平均。
图1 不同 β \betaβ 值做EMA的效果对比(天气预报数据)
当β \betaβ越大时,滑动平均得到的值越和v vv的历史值相关。如果β = 0.9 \beta=0.9β=0.9,则大致等于过去10个v vv值的平均;如果β = 0.99 \beta=0.99β=0.99,则大致等于过去100个v vv值的平均。(数学证明先省略,因为作者暂时没理解证明过程==)
滑动平均的好处:
占内存少,不需要保存过去10个或者100个历史v vv值,就能够估计其均值。(当然,滑动平均不如将历史值全保存下来计算均值准确,但后者占用更多内存和计算成本更高)
为什么EMA在测试过程中使用通常能提升模型表现?
滑动平均可以使模型在测试数据上更健壮(robust)。“采用随机梯度下降算法训练神经网络时,使用滑动平均在很多应用中都可以在一定程度上提高最终模型在测试数据上的表现。”
对神经网络边的权重 weights 使用滑动平均,得到对应的影子变量shadow_weights。在训练过程仍然使用原来不带滑动平均的权重 weights,以得到 weights 下一步更新的值,进而求下一步 weights 的影子变量 shadow_weights。之后在测试过程中使用shadow_weights 来代替 weights 作为神经网络边的权重,这样在测试数据上效果更好。因为 shadow_weights 的更新更加平滑,对于:
随机梯度下降,更平滑的更新说明不会偏离最优点很远;
梯度下降 batch gradient decent,影子变量作用可能不大,因为梯度下降的方向已经是最优的了,loss 一定减小;
mini-batch gradient decent,可以尝试滑动平均,因为mini-batch gradient decent 对参数的更新也存在抖动。
举例来说,设decay=0.999decay=0.999,直观理解,在最后的1000次训练过程中,模型早已经训练完成,正处于抖动阶段,而滑动平均相当于将最后的1000次抖动进行了平均,这样得到的权重会更加robust。