Tensorflow中的`tf.layers.batch_normalization`没有将更新操作添加到`tf.GraphKeys.UPDATE_OPS`。

9
以下代码(可复制/粘贴并运行)演示了如何使用tf.layers.batch_normalization
import tensorflow as tf
bn = tf.layers.batch_normalization(tf.constant([0.0]))
print(tf.get_collection(tf.GraphKeys.UPDATE_OPS))

> []     # UPDATE_OPS collection is empty

使用TF 1.5,文档(如下所述)明确指出,在这种情况下UPDATE_OPS不应为空https://www.tensorflow.org/api_docs/python/tf/layers/batch_normalization):
注:训练时需要更新moving_mean和moving_variance。默认情况下,更新操作被放置在tf.GraphKeys.UPDATE_OPS中,因此它们需要作为train_op的依赖项添加。例如:
update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
with tf.control_dependencies(update_ops):
    train_op = optimizer.minimize(loss)
1个回答

7

只需按照引用中提到的方法将您的代码更改为训练模式(通过将training标志设置为True),即可进行批量归一化:

注意:在训练时,需要更新移动平均值和移动方差。默认情况下,更新操作被放置在tf.GraphKeys.UPDATE_OPS中,因此它们需要作为train_op的一个依赖项添加。

 import tensorflow as tf
 bn = tf.layers.batch_normalization(tf.constant([0.0]), training=True)
 print(tf.get_collection(tf.GraphKeys.UPDATE_OPS))

将输出:

[< tf.Tensor 'batch_normalization/AssignMovingAvg:0' shape=(1,) dtype=float32_ref>, 
 < tf.Tensor 'batch_normalization/AssignMovingAvg_1:0' shape=(1,) dtype=float32_ref>]

Gamma和Beta最终都会被归入可训练变量集合(TRAINABLE_VARIABLES)中:

print(tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES))

[<tf.Variable 'batch_normalization/gamma:0' shape=(1,) dtype=float32_ref>, 
 <tf.Variable 'batch_normalization/beta:0' shape=(1,) dtype=float32_ref>]

1
谢谢!事后看来那很明显。为了完整起见,我编辑了你的答案以显示Gamma和Beta最终进入TRAINABLE_VARIABLES集合。 - David Parks
哦,我实际上做了 trainable=True 而不是 training=True,如果其他人犯同样的错误,这是一个坑。 - David Parks
1
如果training是一个张量变量,那么它不会按预期工作。如果training为false,则tf.GraphKeys.UPDATE_OPS仍将返回所有批量归一化更新操作。 - Spenhouet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接