tf.ExponentialMovingAverage的结果与预期不符

时间:2018-07-05 12:35:14

标签: python tensorflow moving-average

我想研究tf.ExponentialMovingAverage的工作原理。这是代码:

w1 = tf.constant(10., dtype=tf.float32)
w2 = tf.constant(20., dtype=tf.float32)
w3 = tf.constant(40., dtype=tf.float32)
tf.add_to_collection('w', w1)
tf.add_to_collection('w', w2)
tf.add_to_collection('w', w3)

w = tf.get_collection('w')

ema = tf.train.ExponentialMovingAverage(decay=0.9)
ema_op = ema.apply(w)

with tf.control_dependencies([ema_op]):
    with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        for i in w:
            print(sess.run(ema.average(i)))

结果是:

1.0000002
2.0000005
4.000001

但是,根据tf.ExponentialMovingAverage中的公式,结果应为

0.9 * 0 + (1 - 0.9) * 10. = 1.0
0.9 * 1.0 + (1 - 0.9) * 20. = 2.9
0.9 * 2.9 + (1 - 0.9) * 40 = 6.61

似乎tf.ExponentialMovingAverage不会使用上一个阴影值更新阴影值,而是为每次迭代独立计算移动平均值。

我想错了吗?任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:1)

此内容将更新为https://stackoverflow.com/a/51192719/1497720,以便您始终可以正确获得

的输出
0.0
1.0000002
2.9000006
6.6100016

代码如下:

import tensorflow as tf
w = tf.Variable(0.0, dtype=tf.float32)
ema = tf.train.ExponentialMovingAverage(decay=0.9)
ema_op = ema.apply([w])

assigns = []

with tf.control_dependencies([ema_op]):
    for val in [10., 20., 40.]:
        assigns.append(tf.assign(w, tf.constant(val)))

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for assign in assigns:
        sess.run(assign)
        print(sess.run(ema.average(w)))
    sess.run(ema_op)
    print(sess.run(ema.average(w)))

答案 1 :(得分:0)

您的示例中存在一些误解:

  1. 移动平均基于变量或张量定义。您有效地为每个常数创建了移动平均值(解释了得到的结果)。
  2. 每次要更新移动平均线时,您都必须拨打ema_op
  3. 移动平均值使用变量的初始值初始化(不像您期望的那样为零)。

以下示例的行为符合您的预期:

import tensorflow as tf

w = tf.Variable(0.0, dtype=tf.float32)
ema = tf.train.ExponentialMovingAverage(decay=0.9)
ema_op = ema.apply([w])

assigns = []

with tf.control_dependencies([ema_op]):
    for val in [10., 20., 40.]:
        assigns.append(tf.assign(w, tf.constant(val)))

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for assign in assigns:
        _, _, w_ = sess.run([ema_op, assign, ema.average(w)])
        print w_
    _, w_ = sess.run([ema_op, ema.average(w)])
    print w_

结果输出为:

0.0
1.0000002
2.9000006
6.6100016