【问题标题】:Tensorflow Callback: how to save best model on the memory not on the diskTensorflow Callback:如何将最佳模型保存在内存而不是磁盘上
【发布时间】:2020-05-06 08:45:56
【问题描述】:

我使用 Tensorflow 使用以下函数进行回归

import tensorflow as tf

def ff(*args, **kwargs):
    model = tf.keras.models.Sequential()
    model.add(tf.keras.Input(shape=[inp_train.shape[-1],]))
    for i in range(n_layer):
        model.add(tf.keras.layers.Dense(n_unit, activation=act))
    model.add(tf.keras.layers.Dense(out_train.shape[1]))
    model.compile(optimizer=opt, loss='mae')
    early_stop  = tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=100)
    check_point = tf.keras.callbacks.ModelCheckpoint('best_model.h5', monitor='val_loss', save_best_only=True)
    model.fit(inp_train, out_train, epochs=n_epoch, batch_size=s_batch, validation_data=(inp_val, out_val), callbacks=[early_stop, check_point], verbose=0)
    best_model = tf.keras.models.load_model('best_model.h5')
    return model, best_mode

如您所见,我通过check_point 回调保存了最佳模型,并在以后使用它进行预测。问题是这样我必须先将最好的模型保存在磁盘上,然后再从磁盘加载。如果我想并行运行几次,因为每次运行都会创建一个同名文件,所以它不起作用。

那么,如何在变量中分配最佳模型而无需将其保存在磁盘上?

【问题讨论】:

  • 编写一个简单的MetricsCallback 类,将model 复制到任何你喜欢的地方
  • @pinkspikyhairman 好的。如何在不将其保存到磁盘的情况下获得最佳模型,然后将其加载并复制到我喜欢的任何地方?
  • 在答案下方查看我更新的 cmets
  • 您正在使用 EarlyStopping 监控 val_loss,因此训练以最佳模型结束。因此,只需删除您的检查点代码行并使用我的自定义回调应该适合您。如果您仍然不相信,请告诉我,我将在我的自定义回调中添加监控 val_loss,但实际上没有任何意义,因为 EarlyStopping 正在这样做。我的解决方案可以满足您的要求,即。不保存模型并存储在“变量”中。
  • @pinkspikyhairman 感谢您的更新。实际上,如果耐心大于 1,EarlyStopping 不会以最佳模型结束。我们仍然可以通过 restore_best_weights=True 恢复最佳模型。但是,这仅在调用 EarlyStopping 时才有效。看看这个:[github.com/keras-team/keras/issues/12511]

标签: python tensorflow callback


【解决方案1】:

注意:我修复了一个错误并且未经测试

我必须为自己做这件事,我想我会分享:

回调:

class SaveBestModel(tf.keras.callbacks.Callback):
    def __init__(self, save_best_metric='val_loss', this_max=False):
        self.save_best_metric = save_best_metric
        self.max = this_max
        if this_max:
            self.best = float('-inf')
        else:
            self.best = float('inf')

    def on_epoch_end(self, epoch, logs=None):
        metric_value = logs[self.save_best_metric]
        if self.max:
            if metric_value > self.best:
                self.best = metric_value
                self.best_weights = self.model.get_weights()

        else:
            if metric_value < self.best:
                self.best = metric_value
                self.best_weights= self.model.get_weights()

用法:

save_best_model = SaveBestModel()
model.fit(data, callbacks=[save_best_model]
#set best weigts
model.set_weights(save_best_model.best_weights)

【讨论】:

  • 感谢这个解决方案,但是 100 个 epoch 它不起作用你知道为什么吗?
  • 我刚刚更新了它,但现在无法真正测试它。如果效果更好,请告诉我
【解决方案2】:

这里是创建回调并在回调时将模型保存到外部list 的基本示例。它必须是一个列表(或允许使用方法进行修改的类型)。在回调类__init___ 方法中,基类tf.keras.callbacks.Callback 使用附加参数列表进行了扩展。这个例子表明它有效。当在 training_end 上调用回调时,它会将当前模型附加到列表中。

import tensorflow as tf
from tensorflow.python.keras.models import Model

# define a custom callback
class MyCustomCallback(tf.keras.callbacks.Callback):

  def __init__(self, external_list):
      self.list_obj = external_list

  def on_train_end(self, logs=None):
      self.list_obj.append(self.model)

# test the idea works
model_save_list = []
my_callback = MyCustomCallback(model_save_list)

model1 = Model()
my_callback.set_model(model1)
my_callback.on_train_end()

print(model_save_list)

运行这个,你会看到内部模型被添加到你的列表对象中:

[<tensorflow.python.keras.engine.training.Model object at 0x10d230b50>]

通过将新的回调添加到回调中来修改您的训练,如下所示:

model.fit(inp_train, out_train, epochs=n_epoch, batch_size=s_batch, validation_data=(inp_val, out_val), callbacks=[early_stop, my_callback], verbose=0)

【讨论】:

  • 感谢您的回答。似乎它仍然使用'check_point',它将模型保存在磁盘上。你看,tf.keras.callbacks.ModelCheckPoint 在硬盘上创建了一个名为“model_best.h5”的文件。我想要一个解决方法,不在硬盘上创建这个文件,而是将它分配给一个变量。
  • 另外最好的模型不一定是最后一个模型。你看,我用早停时的耐心走得更远。因此,最佳模型位于提前停止的最后一个时期之前。
  • 我的解决方案不需要检查点,这是对培训的回调,但我认为你的观点最后不一定是最好的......我会努力的:)
猜你喜欢
  • 2015-06-27
  • 2011-04-24
  • 2010-12-01
  • 2015-11-13
  • 1970-01-01
  • 2021-05-03
  • 2018-06-27
  • 2011-06-08
  • 2012-05-13
相关资源
最近更新 更多