这个问题有两种解释:第一种是假设目标是使用高级训练API,这个问题已经被Matias Valdenegro回答了。
第二种解释 - 如评论中所讨论的 - 是是否可以像在keras a simplified tensorflow interface和“Collecting trainable weights and state updates”中讨论的那样,使用标准的tensorflow优化器来进行批量归一化。正如在那里提到的,更新操作可以在layer.updates中访问,而不是在tf.GraphKeys.UPDATE_OPS
中,实际上,如果你在tensorflow中有一个keras模型,你可以像这样使用标准的tensorflow优化器和批量归一化。
update_ops = model.updates
with tf.control_dependencies(update_ops):
train_op = optimizer.minimize( loss )
然后使用tensorflow会话来获取train_op。为了区分批量归一化层的训练和评估模式,您需要提供keras引擎的学习阶段状态(请参见上面给出的同一tutorial page中的“训练和测试期间的不同行为”)。例如,这可以像这样工作
...
lo, _ = tf_sess.run(fetches=[loss, train_step],
feed_dict={tf_batch_data: bd,
tf_batch_labels: bl,
tensorflow.keras.backend.learning_phase(): 1})
...
lo = tf_sess.run(fetches=[loss],
feed_dict={tf_batch_data: bd,
tf_batch_labels: bl,
tensorflow.keras.backend.learning_phase(): 0})
我在tensorflow 1.12中尝试了这个方法,并且它适用于包含批量归一化的模型。鉴于我现有的tensorflow代码和即将到来的tensorflow 2.0版本,我很想自己使用这种方法,但是由于tensorflow文档中没有提到这种方法,我不确定长期是否支持它,最终我决定不使用它,并投入更多的时间改变代码以使用高级API。
optimizer.minimize(loss)
看来,他似乎正在尝试手动执行梯度下降步骤(而不是使用更高级别的 API 来驱动拟合)。optimizer.minimize()
(例如使用 'AdamOptimizer' 或 'GradientDescentOptimizer')将使用梯度下降来更新常规权重一步,但它不会对批量归一化的均值和方差做任何事情。 - Joshua Chiabatch_normed = tf.keras.layers.BatchNormalization()(hidden, training=True)
,那么update_ops
是空的。因此似乎没有移动平均值(例如batch_normalization/moving_mean
)的更新发生。 - Ivan