【问题标题】:How to preserve metric values over training sessions in Keras?如何在 Keras 的培训课程中保留指标值?
【发布时间】:2018-02-13 00:36:59
【问题描述】:

我有一个 fit() 函数,它使用 ModelCheckpoint() 回调来保存模型,如果它比任何以前的模型都好,使用 save_weights_only=False,所以它保存了整个模型。这应该允许我在以后使用 load_model() 恢复训练。

不幸的是,在 save()/load_model() 往返过程中的某处,度量值没有被保留——例如,val_loss 设置为 inf。这意味着当训练恢复时,在第一个 epoch 之后 ModelCheckpoint() 将始终保存模型,这几乎总是比之前会话中的前一个冠军差。

我已经确定可以在恢复训练前设置ModelCheckpoint()的当前最佳值,如下:

myCheckpoint = ModelCheckpoint(...)
myCheckpoint.best = bestValueSoFar

显然,我可以监控我需要的值,将它们写到一个文件中,并在我恢复时再次读取它们,但鉴于我是 Keras 新手,我想知道我是否遗漏了一些明显的东西。

【问题讨论】:

  • 如果您有疑问,您应该将最有帮助的回复标记为Answer,以便不再将其列为未决问题。
  • 明天我才能做到,但谢谢你提醒我。

标签: keras


【解决方案1】:

我不认为您必须自己存储指标值。在keras 项目中有一个feature-request 关于非常相似的事情,但它已经关闭。也许您可以尝试使用那里提供的解决方案。在keras 的理念中,存储指标并不是很有用,因为您只是保存model,这意味着:架构和每一层的权重;不是历史或其他任何东西。

最简单的方法是创建一种metafile,其中包含模型的度量值和模型本身的名称。然后您可以加载metafile,获取最佳度量值并获取产生它们的模型的名称,再次加载模型,继续训练。

【讨论】:

  • 感谢您指向功能请求。我最终做了类似的事情,代码如下。
【解决方案2】:

我最终快速编写了自己的回调,以跟踪最佳训练值,以便我可以重新加载它们。它看起来像这样:

# State monitor callback. Tracks how well we are doing and writes
# some state to a json file. This lets us resume training seamlessly.
#
# ModelState.state is:
#
# { "epoch_count": nnnn,
#   "best_values": { dictionary with keys for each log value },
#   "best_epoch": { dictionary with keys for each log value }
# }

class ModelState(callbacks.Callback):

    def __init__(self, state_path):

        self.state_path = state_path

        if os.path.isfile(state_path):
            print('Loading existing .json state')
            with open(state_path, 'r') as f:
                self.state = json.load(f)
        else:
            self.state = { 'epoch_count': 0,
                           'best_values': {},
                           'best_epoch': {}
                         }

    def on_train_begin(self, logs={}):

        print('Training commences...')

    def on_epoch_end(self, batch, logs={}):

        # Currently, for everything we track, lower is better

        for k in logs:
            if k not in self.state['best_values'] or logs[k] < self.state['best_values'][k]:
                self.state['best_values'][k] = float(logs[k])
                self.state['best_epoch'][k] = self.state['epoch_count']

        with open(self.state_path, 'w') as f:
            json.dump(self.state, f, indent=4)
        print('Completed epoch', self.state['epoch_count'])

        self.state['epoch_count'] += 1

然后,在 fit() 函数中,如下所示:

# Set up the model state, reading in prior results info if available

model_state = ModelState(path_to_state_file)

# Checkpoint the model if we get a better result

model_checkpoint = callbacks.ModelCheckpoint(path_to_model_file,
                                             monitor='val_loss',
                                             save_best_only=True,
                                             verbose=1,
                                             mode='min',
                                             save_weights_only=False)


# If we have trained previously, set up the model checkpoint so it won't save
# until it finds something better. Otherwise, it would always save the results
# of the first epoch.

if 'best_values' in model_state.state:
    model_checkpoint.best = model_state.state['best_values']['val_loss']

callback_list = [model_checkpoint,
                model_state]

# Offset epoch counts if we are resuming training. If you don't do
# this, only epochs-initial_epochs epochs will be done.

initial_epoch = model_state.state['epoch_count']
epochs += initial_epoch

# .fit() or .fit_generator, etc. goes here.

【讨论】:

    猜你喜欢
    • 2022-11-11
    • 1970-01-01
    • 2017-08-31
    • 2017-12-31
    • 2019-06-16
    • 1970-01-01
    • 2021-08-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多