【问题标题】:How to dynamically update batch norm momentum in TF2?如何在 TF2 中动态更新批范数动量?
【发布时间】:2021-03-21 19:03:01
【问题描述】:

我发现了一个 PyTorch 实现,它将批规范 momentum 参数从第一个时期的 0.1 衰减到最后一个时期的 0.001。有关如何使用 TF2 中的批处理规范 momentum 参数执行此操作的任何建议? (即,从0.9 开始,以0.999 结束)例如,这是在 PyTorch 代码中所做的:

# in training script
momentum = initial_momentum * np.exp(-epoch/args.epochs * np.log(initial_momentum/final_momentum))
model_pos_train.set_bn_momentum(momentum)

# model class function
def set_bn_momentum(self, momentum):
    self.expand_bn.momentum = momentum
    for bn in self.layers_bn:
        bn.momentum = momentum

解决方案:

在使用tf.keras.Model.fit() API 时,下面选择的答案提供了一个可行的解决方案。但是,我使用的是自定义训练循环。这是我所做的:

每个纪元之后:

mi = 1 - initial_momentum  # i.e., inital_momentum = 0.9, mi = 0.1
mf = 1 - final_momentum  # i.e., final_momentum = 0.999, mf = 0.001
momentum = 1 - mi * np.exp(-epoch / epochs * np.log(mi / mf))
model = set_bn_momentum(model, momentum)

set_bn_momentum 函数(归功于this article):

def set_bn_momentum(model, momentum):
    for layer in model.layers:
        if hasattr(layer, 'momentum'):
            print(layer.name, layer.momentum)
            setattr(layer, 'momentum', momentum)

    # When we change the layers attributes, the change only happens in the model config file
    model_json = model.to_json()

    # Save the weights before reloading the model.
    tmp_weights_path = os.path.join(tempfile.gettempdir(), 'tmp_weights.h5')
    model.save_weights(tmp_weights_path)

    # load the model from the config
    model = tf.keras.models.model_from_json(model_json)

    # Reload the model weights
    model.load_weights(tmp_weights_path, by_name=True)
    return model

这种方法不会给训练例程增加大量开销。

【问题讨论】:

  • 不清楚你在做什么。你能准确地展示你想要的pytorch代码吗?

标签: tensorflow pytorch tensorflow2.0 batch-normalization momentum


【解决方案1】:

您可以在每个批次的开始/结束时设置一个动作,这样您就可以在该时期控制任何参数。

在回调选项下方:

class CustomCallback(keras.callbacks.Callback):
    def on_epoch_begin(self, epoch, logs=None):
        keys = list(logs.keys())
        print("Start epoch {} of training; got log keys: {}".format(epoch, keys))

    def on_epoch_end(self, epoch, logs=None):
        keys = list(logs.keys())
        print("End epoch {} of training; got log keys: {}".format(epoch, keys))

    def on_train_batch_begin(self, batch, logs=None):
        keys = list(logs.keys())
        print("...Training: start of batch {}; got log keys: {}".format(batch, keys))

    def on_train_batch_end(self, batch, logs=None):
        keys = list(logs.keys())
        print("...Training: end of batch {}; got log keys: {}".format(batch, keys))

    def on_test_batch_begin(self, batch, logs=None):
        keys = list(logs.keys())
        print("...Evaluating: start of batch {}; got log keys: {}".format(batch, keys))

    def on_test_batch_end(self, batch, logs=None):
        keys = list(logs.keys())
        print("...Evaluating: end of batch {}; got log keys: {}".format(batch, keys))

您可以访问动力

batch = tf.keras.layers.BatchNormalization()
batch.momentum = 0.001

在模型内部你必须指定正确的层

model.layers[1].momentum = 0.001

您可以在writing_your_own_callbacks找到更多信息和示例

【讨论】:

  • 谢谢。您知道如何在回调中访问模型的批范数动量参数,或者更好的特定层吗?
  • 我猜你可以通过self.model.layers访问
  • 对不起,我已经阅读了动力,但我已经写了学习率,我已经更新了我的答案
猜你喜欢
  • 1970-01-01
  • 2017-10-26
  • 2020-04-09
  • 2022-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多