滑动平均(exponential mobing average),也叫做指数加权平均(exponentially weighted moving average),可以用来估计变量的局部值,是的变量的更新与一段时间内的历史值有关。

比如下图:

就是不使用滑动平均和使用滑动平均的区别。可以发现使用滑动平均后,值更能反应结果在一段时间内的变化。

那这个图是不是和batch下的结果很像呢?如果我们对网络参数进行滑动平均,这样就会使得网络具有更好的鲁棒性(robust)。

因此这个方法通常在测试数据上使用。在采用随机梯度下降算法训练的模型中,使用滑动平均在很多场景下都可以提高最终模型在测试集上的表现。

因为EMA维护了一个shadow weight,这个shadow weight就是从weight上平均而来的,也就具备了更多的鲁棒性。而训练阶段,我们需要真实的weight来进行下一次梯度下降。

而参数decay[ema_momentum]则是抖动程度,如果decay=0.999,直观来说则是将最后1000次的训练抖动进行了平均。

那么怎么使用呢?

下面描述在bert4keras中如何使用ema平滑。

在优化器定义时:

from bert4keras.optimizers import Adam, extend_with_exponential_moving_average
AdamEMA = extend_with_exponential_moving_average(Adam, 'AdamEMA')
optimizer = AdamEMA(learning_rate, ema_momentum=0.999)

在测试时:

optimizer.apply_ema_weights()
res = model.predict(data)
optimizer.reset_old_weights()

之所以在测试的时候要应用,而测试之后恢复,是因为这个平均,只在测试阶段才有效,训练阶段还是要根据实际数据得出结果(因为参数平均是根据真实结果进行平均)。


0 条评论

发表回复

Avatar placeholder

您的电子邮箱地址不会被公开。 必填项已用 * 标注