MovingAverage
MovingAverage中文名字叫滑动平均,在金融行业也有应用,在tensorflow这里,我们所说的MovingAverage是对过去不同时间内计算得到的变量值求一个平均值。这里的变量说的就是神经网络模型的权重w和偏置a。Tensroflow官网是这么说MovingAverage的:Empirically it has been found that using the moving average of the trained parameters of a deep network is better than using its trained parameters directly。翻译过来就是:从经验上来说,我们发现对神经网络训练得到的变量参数(即权重和偏置值)使用滑动平均会比直接使用最后一次更新得到的变量值好。想想也是,我们不能放弃前面求出来的权重值和偏置值,我们应该把它们利用起来。
TensorFlow中提供了ema
=
tf.train.ExponentialMovingAverage(decay,num_updates)
来实现滑动平均模型。这里的名字里多了Exponential,它表示我们对过往计算出来的变量值前面会乘以一个加权系数,越早产生的变量值的系数越小,越晚产生的变量值系数越大。下面我们通过shadow variable的公式来理解一下。
shadow_variable
shadow_ variable(n+1)=decay×shadow_ variable(n)+(1-decay)×variable(n+1)
式中, variable(n+1)为变量更新后最新的值; shadow_variable(n+1)是 variable 的 影子变量,也是变量更新后其影子变量的最新值,其初始值就等于变量值; decay 为衰减率。从公式可以看到, decay 决定了滑动平均模型的更新速度,一般会设成非常接近 1 的数(如 0.99 或 0.999) , decay 值越大模型更新得越慢越稳。 例如,设置 decay 为 0.99,变量 variable 的初始值为 0,并依次更新为 5、 10、 15、 20,则相应的影子变量会如下表所示。
可见,经过4次更新,最新的 shadow_ variable(0.7415)离variable(25)还是比较遥远的,也就是更新速度比较慢。
为此,ExponentialMovingAverage()接受指定 num_updates 参数来限制 decay 的 大小,如果在初始化时提供了 num_updates 参数,那么每次使用的衰减率 decay 值将由下式决定:
decay=min{decay,1+num_updates/10+num_updates}
将 num_updates 值设置得较小(例如 1 ),会得到较快的影子变量更新速度。
在得到初始化的滑动平均类之后,可以通过这个类的函数 apply()提供 要进行滑动平均计算的变量。 这个函数的原型为 apply(self, var_ list),其中 var list 参数是一个传递进来的参数列表。 average()真正执行了影子变量的计算。它是 ExponentialMovingAverage 类的一个函数,在使用时,对其传入需要进行计算的变量即可。接下来, 就将滑动平均的方法应用到隐藏层与输出层的权重参数与偏置参数。
#初始化一个滑动平均类,衰减率为 0.99 #为了使模型在训练前期可以更新得更快,这里提供了num_updates 参数,并设置为当前网络的训练轮数
averages_class = tf.train.ExponentialMovingAverage(0.99, training step)
#定义一个更新变量滑动平均值的操作需要向滑动平均类的 apply {)函数提供一个参数列表 #train variables()函数返回集合图上 Graph.TRAINABLE VARIABLES 中 的元素,这个集合的元素就是所有没有指定 trainable variables=False 的参数
averages op= averages class.apply(tf.trainable variables())
#再次计算经过神经网络前向传播后得到的 y 值,这里使用了滑动平均,但要牢记 滑动平均值只是一个影子变量
average_y = hidden_layer (x, averages_ class . average (weightsl) , averages_class.average(biasesl), averages_class.average(weights2), averages_class.average(biases2) , ’ average_y’)
以上内容部分摘抄自《TensorFlow深度学习算法原理与编程实战》蒋子阳 P203、204.
补充: