Keras 回调函数,如ReduceLROnPlateau、ModelCheckpoint、EarlyStopping 抛出 NoneType 属性错误

问题描述 投票:0回答:1

我正在使用 Keras(带有 TensorFlow 后端)使用 train_on_batch()、evaluate() 和回调函数 on_epoch_end() 来训练模型。这是以下链接中原始代码的一部分:https://www.kaggle.com/code/kmader/pretrained-inceptionv3-for-bone-age

我没有使用给定的 fit_generator() ,而是尝试实现它的原始版本,因为由于以下链接中描述的错误, fit_generator() 无法工作:https://github.com/keras-team/keras/问题/8595

下面给出的是回调函数列表的内核-

from keras.callbacks import ModelCheckpoint, LearningRateScheduler, EarlyStopping, ReduceLROnPlateau
weight_path="/kaggle/working/{}_weights.best.hdf5".format('bone_age')

checkpoint = ModelCheckpoint(weight_path, monitor='val_loss', verbose=1, 
                             save_best_only=True, mode='min', save_weights_only = True)


reduceLROnPlat = ReduceLROnPlateau(monitor='val_loss', factor=0.8, patience=10, verbose=1, mode='auto', epsilon=0.0001, cooldown=5, min_lr=0.0001)
early = EarlyStopping(monitor="val_loss", 
                      mode="min", 
                      patience=5) # probably needs to be more patient, but kaggle time is limited
callbacks_list = [reduceLROnPlat, checkpoint, early]

以及主要训练内核-

epochs = 2
steps_per_epoch = 10

for epoch in range(epochs):
    print("Epoch {}/{}".format(epoch + 1, epochs))

    # Training phase
    for step in range(steps_per_epoch):
        # Get the next batch of training data and labels
        batch_X, batch_Y = next(train_gen)

        # Train on batch
        loss = bone_age_model.train_on_batch(batch_X, batch_Y)

        print("Step {" + str(step + 1) + "}/{" + str(steps_per_epoch) + "}

    # Validation phase
    val_loss, accuracy = bone_age_model.evaluate(test_X, test_Y)
    print("Validation Loss: " + str(round(val_loss, 4)))

#     Apply callbacks
    for callback in callbacks_list:
        callback.on_epoch_end(epoch, logs={'val_loss': val_loss})

(注意:我在 Kaggle 上运行代码,既不在 Google Colab 上运行,也不在我的本地 PC 上运行)

我注意到以下错误:

AttributeError                            Traceback (most recent call last)
<ipython-input-56-28ff6d63cd15> in <module>()
     27 #     Apply callbacks
     28     for callback in callbacks_list:
---> 29         callback.on_epoch_end(epoch, logs={'val_loss': val_loss})  # Call the callback at the end of each epoch
     30 
     31 

/opt/conda/lib/python3.6/site-packages/Keras-2.1.3-py3.6.egg/keras/callbacks.py in on_epoch_end(self, epoch, logs)
    914     def on_epoch_end(self, epoch, logs=None):
    915         logs = logs or {}
--> 916         logs['lr'] = K.get_value(self.model.optimizer.lr)
    917         current = logs.get(self.monitor)
    918         if current is None:

AttributeError: 'NoneType' object has no attribute 'optimizer'

我尝试逐一使用回调函数,即callbacks_list中只有一个回调函数,但所有回调函数都会导致错误。

  1. callbacks_list = [reduceLROnPlat] 给出上述错误。
  2. callbacks_list = [早期]给出
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-19-28ff6d63cd15> in <module>()
     27 #     Apply callbacks
     28     for callback in callbacks_list:
---> 29         callback.on_epoch_end(epoch, logs={'val_loss': val_loss})  # Call the callback at the end of each epoch
     30 
     31 

/opt/conda/lib/python3.6/site-packages/Keras-2.1.3-py3.6.egg/keras/callbacks.py in on_epoch_end(self, epoch, logs)
    498             )
    499             return
--> 500         if self.monitor_op(current - self.min_delta, self.best):
    501             self.best = current
    502             self.wait = 0

AttributeError: 'EarlyStopping' object has no attribute 'best'
  1. callbacks_list = [检查点] 给出
AttributeError                            Traceback (most recent call last)
<ipython-input-38-28ff6d63cd15> in <module>()
     27 #     Apply callbacks
     28     for callback in callbacks_list:
---> 29         callback.on_epoch_end(epoch, logs={'val_loss': val_loss})  # Call the callback at the end of each epoch
     30 
     31 

/opt/conda/lib/python3.6/site-packages/Keras-2.1.3-py3.6.egg/keras/callbacks.py in on_epoch_end(self, epoch, logs)
    414                         self.best = current
    415                         if self.save_weights_only:
--> 416                             self.model.save_weights(filepath, overwrite=True)
    417                         else:
    418                             self.model.save(filepath, overwrite=True)

AttributeError: 'NoneType' object has no attribute 'save_weights'

我对此有点陌生,并且在理论上研究过一些。有人可以解释一下我是否使用了错误的函数或者 keras 模块中是否有错误(因为我看到很多帖子声称旧版本的模块中有错误)?由于所有模块都抛出某种错误,我相信我的实现存在问题。

PS:我不知道这是否相关,但我正在使用 InceptionV3 和 Resnet 的预训练模型。

python keras kaggle model-checking
1个回答
0
投票

确实,如果不访问模型权重,回调就无法保存模型权重:)

当您使用 keras fit 函数时,它会创建一个回调列表并将模型传递给它,其代码如下:

if not isinstance(callbacks, callbacks_module.CallbackList):
    callbacks = callbacks_module.CallbackList(
        callbacks,
        add_history=True,
        add_progbar=verbose != 0,
        verbose=verbose,
        epochs=epochs,
        steps=epoch_iterator.num_batches,
        model=self,
    )

它本身为传递给它的每个回调设置模型,其代码如下:

def set_model(self, model):
    super().set_model(model)
    if self._history:
        model.history = self._history
    for callback in self.callbacks:
        callback.set_model(model)

因此,为了手动使用回调,您需要在调用它们之前设置模型。在训练循环之前的示例中,您可以添加以下代码行来解决问题:

for callback in callback_list:
    callback.set_model(bone_age_model)

然后您的检查点可以访问模型,例如您的模型检查点可以访问权重以保存它们。

备注: 您可以使用 CallbackList 类来统一回调,而无需每次都进行循环,请参阅 keras 文档 例如使用。

© www.soinside.com 2019 - 2024. All rights reserved.