我使用张量流实现了一个网络,并且损失没有收敛。然后,我在网络中获得了一些价值,并且发现BN层不起作用。请看下面的图片:
我们可以看到s2是s1批量标准化的结果,但是s2中的值仍然很大。我不知道出什么问题了。为什么s2中的值太大?
我已将代码更新为github。有兴趣的人可以对其进行测试。
答案 0 :(得分:0)
根据官方的tensorflow文档here,
训练时,需要更新Moving_mean和Moving_variance。 默认情况下,更新操作位于tf.GraphKeys.UPDATE_OPS中,因此 它们需要与train_op一起执行。另外,请务必添加 获取update_ops集合之前的所有batch_normalization ops。 否则,update_ops将为空,并且训练/推论不会 工作正常。
例如:
training = tf.placeholder(tf.bool, name="is_training")
# ...
x_norm = tf.layers.batch_normalization(x, training=training)
# ...
update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
train_op = optimizer.minimize(loss)
train_op = tf.group([train_op, update_ops])
# or, you can also do something like this:
# with tf.control_dependencies(update_ops):
# train_op = optimizer.minimize(loss)
因此,按照tensorflow文档中所述获取更新操作非常重要,因为在训练期间必须更新层的移动方差和移动平均值。如果您不这样做,则批量标准化将无法进行,并且网络将无法按预期进行训练。声明一个占位符以告知网络是在训练时间还是在推理时间也是有用的,因为在测试(或推理)时间中,均值和方差是固定的。使用先前计算的均值和每个训练批次的方差来估计它们。