2019/04/18 滑动平均介绍和在tensorflow中的应用

原文:https://blog.csdn.net/weixin_40532940/article/details/83999838

滑动平均:

或者被称之为加权平均,可以用来估计变量的局部均值,使变量的更新与一段时间内的取值有关。

1.滑动平均介绍

       变量v在t时刻记为v_{t}\theta _{t}为变量v在t时刻的取值,即在不适用滑动平均模型时v_{t}=\theta _{t},在使用滑动平均模型后,v_{t}的更新公式如下:

                                     v_{t}=\beta *v_{t-1} + \left ( 1-\beta \right ) * \theta _{t}

上面的式子中\beta \in \left [ 0,1 \right ]\beta = 0相当于没有使用滑动平均。

假设开始的v_{0} = 0, \beta = 0.9之后的每个时刻对变量进行赋值,不适用滑动平均和使用滑动平均的结果如下:

         这里t时刻变量v的滑动平均值大致等于过去1/(1-β)个时刻θ的平均值。这个结论在滑动平均开始时相差比较大,所以有了Bias correction,将v_{t}除以\left ( 1 - \beta _{t}\right )修正对均值的估计。这样我们的公式就变成了。

                                      v_{t}=\frac{\beta *v_{t-1} + \left ( 1-\beta \right ) * \theta _{t}}{1-\beta ^{t}}

这里的t越大,那么我们等式的分母越接近1。表示我们得到的β越大,表示我们得到的滑动平均值和θ的历史值有关。如果β=0.9,则大致等于过去10个θ值的平均;如果β=0.99,则大致等于过去100个θ值的平均。占内存少,不需要保存过去10个或者100个历史θ值,就能够估计其均值。(当然,滑动平均不如将历史值全保存下来计算均值准确,但后者占用更多内存和计算成本更高)(这里需要了解过去的10个值和100个值表示一种近似)
 

2.Tensorflow中使用滑动平均来更新变量(参数)

    在初始化 ExponentialMovingAverage 时,需要提供一个衰减率(decay),即公式(1)(2)中的β。这个衰减率将用于控制模型的更新速度。

ExponentialMovingAverage 对每一个变量(variable)会维护一个影子变量(shadow_variable),这个影子变量的初始值就是相应变量的初始值,而每次运行变量更新时,影子变量的值会更新为:

 shadow_variable = decay * shadow_variable + (1 - decay) * variable

 上述,decay 决定了影子变量的更新速度,decay 越大影子变量越趋于稳定。在实际运用中,decay一般会设成非常接近1的数(比如0.999或0.9999)。为了使得影子变量在训练前期可以更新更快,ExponentialMovingAverage 还提供了 num_updates 参数动态设置 decay 的大小。如果在初始化 ExponentialMovingAverage 时提供了 num_updates 参数,那么每次使用的衰减率将是:

min\left \{ decay, \frac{1+num\:updates}{1+num\:updates} \right \}

3.滑动平均为什么在测试过程中使用

对神经网络边的权重 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 对参数的更新也存在抖动。
 

猜你喜欢

转载自blog.csdn.net/evergreenswj/article/details/89378021