Результат tf.ExponentialMovingAverage не соответствует ожидаемому - PullRequest
0 голосов
/ 05 июля 2018

Я хотел бы изучить, как работает 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 не обновляет значение тени, используя последнее значение тени, но вычисляет скользящее среднее независимо для каждой итерации.

Я не так думаю? Любая помощь будет оценена!

1 Ответ

0 голосов
/ 05 июля 2018

В вашем примере есть некоторые заблуждения:

  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
...