tf.train.ExponentialMovingAverage是指数加权平均的求法,具体的公式是 total=a*total+(1-a)*next,

下面讲起具体的使用方式:

  1. ema = tf.train.ExponentialMovingAverage(0.9)  0.9:就是其衰减因子。
  2. total=ema.apply([next1,next2,nex3...]),这里的传入的参数是一个变量列表,可以同时计算多个加权平均数。
  3. total1=a*total1+(1-a)*next1, total2=a*total2+(1-a)*next2,可以取出相应的值total1=ema.average(next1),这一步只是取值,不是计算,上一步如果sess.run(total)便开始计算。

具体的执行方式开始debug看源码,以下讲一下具体的应用以及指数加权平均的初始值的问题:

import tensorflow as tf

w1 = tf.Variable(1.0)
w2 = tf.Variable(2.0)
w3 = tf.Variable(2.0)
w4 = tf.Variable(2.0)
ema = tf.train.ExponentialMovingAverage(0.9)
update=tf.assign_add(w1,1.0)
ema_op = ema.apply([w1,w2,w3,w4])

init=tf.initialize_all_variables()
with tf.Session() as sess:
    sess.run(init)
    for i in range(3):
       
        sess.run(ema_op)
        for i in [w1,w2,w3,w4]:
            print(sess.run(ema.average(i)))

        sess.run(update) 

执行的结果:

#第一次执行:ema.apply

1.0
2.0
2.0

2.0 

#第二次执行:ema.apply

1.1
2.0
2.0

2.0

#第三次执行:ema.apply

1.2900001
2.0

2.0

可以发现只要你的next不更新,那么使用都是一个数据,也就是你的原始初始化数据,只有当你的数据更新,形成一个序列才会

逐步计算其指数加权平均。

2:需要注意的地方:

with tf.Session() as sess:
    sess.run(init)
    for i in range(3):
        sess.run(ema_op)
        for i in [w1,w2,w3,w4]:
            print(sess.run(ema.average(i)))

        sess.run(update) 

其结果是:

1.0
2.0
2.0
2.0
1.1
2.0
2.0
2.0
1.2900001
2.0
2.0

2.0

如果变成:

with tf.Session() as sess:
    sess.run(init)

    for i in range(3):

        sess.run(update) 

        sess.run(ema_op)
        for i in [w1,w2,w3,w4]:
            print(sess.run(ema.average(i)))

        sess.run(update) 

结果是:

1.1
2.0
2.0
2.0
1.2900001
2.0
2.0
2.0
1.5610001
2.0
2.0
2.0

1.1=1*0.9+2*0.1

3:如果将w1换成update,代码如下:

w1 = tf.Variable(1.0)
w2 = tf.Variable(2.0)
w3 = tf.Variable(2.0)
w4 = tf.Variable(2.0)
ema = tf.train.ExponentialMovingAverage(0.9)
update=tf.assign_add(w1,1.0)
ema_op = ema.apply([update,w2,w3,w4])#这句和下面那句不能调换顺序


init=tf.initialize_all_variables()
with tf.Session() as sess:
    sess.run(init)
    for i in range(3):
        sess.run(ema_op)
        for i in [update,w2,w3,w4]:
            print(sess.run(ema.average(i)))

结果如下:

0.20000005
2.0
2.0
2.0
0.4800001
2.0
2.0
2.0
0.8320002
2.0
2.0

2.0

0.2=0.9*0+0.1*2

这就是就是加权平均的使用方式需要注意的是:

  1. appy方法中应用的是哪个张量,其初值是多少。
  2. 每次appy时,张量是否改变,是否形成一个序列。
  3. 当在apply前是否对张量改变,如果改变在之前的是total 之后的值是next,再apply计算下一个total。
  4. 如果apply里面的张量是由其他op计算而来的,那么其之前的total为0,next就是这个张量 total=0*0.9+next*0.1。