1、计算方法
设
{a1,a2,a3,...,an}
,其衰减率为
decay
,对应的影子变量为:
{m1,m2,m3,...,mn}
,则:
mn=decay∗mn−1+(1−decay)∗an
可以展开来分析:
m1=a1
m2=decay∗a1+(1−decay)∗a2
m3=decay∗m2+(1−decay)∗a3=decay2∗a1+(1−decay)∗decay∗a2+(1−decay)∗a3
m4=decay∗m3+(1−decay)∗a4=decay3∗a1+(1−decay)∗decay2∗a2+(1−decay)∗decay∗a3+(1−decay)∗a4
......
以其类推
mn=decay∗mn−1+(1−decay)∗an=decayn−1∗a1+decayn−2∗(1−decay)+...+(1−decay)∗an
一般而言,为了使模型趋于收敛,会选择decay为接近1的数,例如:
decay = 0.99;
那么:
m1=a1
m2=0.99∗a1+0.01∗a2
m3=0.99∗m2+0.01∗a3=0.992∗a1+0.01∗0.99∗a2+0.01∗a3
我们发现初始值对后面影响非常大,若初始值与真实值偏差较大时,函数收敛速度非常慢;为了解决该问题,tensorflow提供了num_updates参数来动态设置decay的大小;
decay=min{DECAY,1+num_updates10+num_updates}
例:
DECAY = 0.99
第一轮,先设num_updates = 0;
那么:
decay=min{0.99,1+010+0}=0.1
则:
m1=a1
m2=0.1∗a1+0.9∗a2
第二轮,可设num_updates = 100
那么:
decay=min{0.99,1+10110+100}=0.91
则:
m3=0.91∗m2+0.09∗a3
以此类推,从而可以动态调整decay值大小。
import tensorflow as tf
test1 = tf.Variable(0,dtype=tf.float32)
num_updates = tf.Variable(0,dtype=tf.float32)
DECAY = 0.99
Moving_average = tf.train.ExponentialMovingAverage(DECAY,num_updates)
#跟新test1
Moving_average_op = Moving_average.apply([test1])
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
#第一次打印出初始值,滑动平均值,输出值应该为[0,0]
print(sess.run([test1,Moving_average.average(test1)]))
#更新test1
sess.run(tf.assign(test1,3))
sess.run(Moving_average_op)
#第二次打印初始值,滑动平均值,输出值应该为[3,0],滑动平均值计算0*0.1+0.9*3=2.7
print(sess.run([test1,Moving_average.average(test1)]))
#更新test2与num_updates
sess.run(tf.assign(test1,5))
sess.run(tf.assign(num_updates,90))
sess.run(Moving_average_op)
#第三次打印初始值,滑动平均值,输出值应该为[3,0],滑动平均值计算2.7*0.91+5*0.09
print(sess.run([test1,Moving_average.average(test1)]))
输出值
[0.0, 0.0]
[3.0, 2.6999998]
[5.0, 2.9069998]