Tensorflow Keras中的批处理规范化

Tensorflow Keras中的批处理规范化,tensorflow,keras,batch-normalization,Tensorflow,Keras,Batch Normalization,如何更新keras批次标准化中的移动平均值和移动方差 我在tensorflow文档中发现了这一点,但我不知道在哪里放置train_op,也不知道如何使用keras模型: update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS) with tf.control_dependencies(update_ops): train_op = optimizer.minimize( loss ) 我没有找到任何帖

如何更新keras批次标准化中的移动平均值和移动方差

我在tensorflow文档中发现了这一点,但我不知道在哪里放置
train_op
,也不知道如何使用keras模型:

update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
        with tf.control_dependencies(update_ops):
            train_op = optimizer.minimize( loss )

我没有找到任何帖子说明如何使用train_op,以及是否可以在
模型中使用它。编译

如果需要使用一些新值更新现有模型的权重,则可以执行以下操作:

w = model.get_layer('batchnorm_layer_name').get_weights()
# Order: [gamma, beta, mean, std]
for j in range(len(w[0])):
    gamma = w[0][j]
    beta = w[1][j]
    run_mean = w[2][j]
    run_std = w[3][j]
    w[2][j] = new_run_mean_value1
    w[3][j] = new_run_std_value2

model.get_layer('batchnorm_layer_name').set_weights(w)

如果使用BatchNormalization层,则无需手动更新移动平均值和方差。Keras负责在训练期间更新这些参数,并在测试期间保持这些参数不变(使用
模型。预测
模型。评估
功能,与
模型相同。安装生成器
和朋友)


Keras还跟踪学习阶段,以便在培训和验证/测试期间运行不同的代码路径。

对这个问题有两种解释:第一种是假设目标是使用高级培训api,Matias Valdenegro回答了这个问题

第二个问题——如评论中所讨论的——是是否可以使用标准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 )
... 
# train
lo, _ = tf_sess.run(fetches=[loss, train_step],
                    feed_dict={tf_batch_data: bd,
                               tf_batch_labels: bl,
                               tensorflow.keras.backend.learning_phase(): 1})

...

# eval
lo = tf_sess.run(fetches=[loss],
                    feed_dict={tf_batch_data: bd,
                               tf_batch_labels: bl,
                               tensorflow.keras.backend.learning_phase(): 0})

然后使用tensorflow会话获取训练操作。要区分批处理规范化层的训练和评估模式,需要向 keras发动机的学习阶段状态(参见上文相同章节的“培训和测试期间的不同行为”)。例如,这将像这样工作

update_ops  = model.updates
with tf.control_dependencies(update_ops):
     train_op = optimizer.minimize( loss )
... 
# train
lo, _ = tf_sess.run(fetches=[loss, train_step],
                    feed_dict={tf_batch_data: bd,
                               tf_batch_labels: bl,
                               tensorflow.keras.backend.learning_phase(): 1})

...

# eval
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。

您想做什么?一般来说,在Keras中工作不需要为BatchNormalization做任何事情。我只是尝试使用BatchNormalization。让我困惑的是Tensorflow和Keras之间的差异,因此我不确定我是否真的不需要做任何其他事情(除了确保在验证期间关闭批次标准化),或者我是否必须手动更新移动平均值和方差。@MatiasValdenegro来自
优化器。最小化(损失)
,看起来他正在尝试手动执行梯度下降步骤(而不是使用更高级别的API来驱动配件)
optimizer.minimize()
(例如,使用'AdamOptimizer'或'GradientDescentOptimizer')将使用梯度下降来更新一步的常规权重,但它不会对批次标准均值和方差做任何事。对于我来说,如果使用
batch\u Normaled=tf.keras.layers.BatchNormalization()(隐藏,training=True),则
update\u ops
为空
。因此,移动平均线的更新(例如,
批量标准化/移动平均线
)似乎没有发生。如果您将model.fit_生成器与训练集和验证集一起使用会怎么样?@A.Hendry Same,我只是忘了提一下。@MatiasValdenegro我怀疑这是否有效。我在同样使用优化器的训练循环中打印变量
batch\u normalization/moving\u mean
的前两个元素。最小化(损失)
,它们永远不会改变。我正在使用一个
tensorflow.train.AdamOptimizer
并手动运行
optimizer.minimize(loss)
来反向传播权重更新。我怀疑一个更高级别的API(例如
tensorflow.keras.models.Model.fit()
)除了反向传播之外,还做了一些事情来更新批处理规范统计数据,仅仅使用
优化器。最小化(损失)
@Syncopated我不知道你在说什么,我的答案是关于使用keras,似乎你没有使用纯粹的Keras。@MatiasValdenegro看到这个问题被标记为“tensorflow”和“Keras”,我说的是在tensorflow中使用Keras,但看到作者似乎已经接受了答案,也许他不是真的在谈论tensorflow。