TensorFlow中tf.layers.batch_normalization未将更新操作加入tf.GraphKeys.UPDATE_OPS
TensorFlow 1.5中
tf.layers.batch_normalization的正确使用方式 在TensorFlow 1.5版本中,很多开发者会碰到tf.layers.batch_normalization的滑动均值(moving_mean)和滑动方差(moving_variance)不更新的问题——核心原因是:默认情况下这些更新操作会被放入tf.GraphKeys.UPDATE_OPS集合,但你必须手动将这个集合作为依赖添加到训练操作中,否则更新逻辑不会被执行。
下面是一段可直接复制运行的代码示例,完整展示该API的正确使用流程:
import tensorflow as tf # 构建基础模型结构 inputs = tf.placeholder(tf.float32, shape=[None, 32]) x = tf.layers.dense(inputs, 64, activation=tf.nn.relu) # 添加批量归一化层,注意指定training=True区分训练/推理模式 x = tf.layers.batch_normalization(x, training=True) x = tf.layers.dense(x, 10, activation=tf.nn.softmax) # 定义损失与优化器 labels = tf.placeholder(tf.int32, shape=[None]) loss = tf.losses.sparse_softmax_cross_entropy(labels=labels, logits=x) # 关键步骤:获取UPDATE_OPS集合,并让训练操作依赖这些更新 update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS) with tf.control_dependencies(update_ops): train_op = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss) # 模拟训练执行 with tf.Session() as sess: sess.run(tf.global_variables_initializer()) # 此处省略数据加载逻辑,实际训练时传入对应feed_dict即可 for step in range(100): # 执行train_op时会同步触发UPDATE_OPS里的均值/方差更新 _, current_loss = sess.run([train_op, loss], feed_dict={inputs: ..., labels: ...})
根据TensorFlow 1.5官方文档的明确说明,这里有个必须注意的点:
注意:训练时,需要更新moving_mean和moving_variance。默认情况下,更新操作会被放入tf.GraphKeys.UPDATE_OPS,因此需要将其作为依赖项添加到train_op中。
如果跳过tf.control_dependencies(update_ops)这一步,批量归一化层的滑动统计量就不会在训练中更新,最终导致模型的归一化效果失效。
内容的提问来源于stack exchange,提问作者David Parks
相关产品推荐
相关产品推荐

