EarlyStopping 回调在 Keras 中表现得很神秘

meg*_*ger 5 python callback keras tensorflow

我的模型在第 4 个 epoch 后停止训练,尽管我希望它在此之后继续训练。我已将监视器设置为验证损失并将耐心设置为 2,我认为这意味着在验证损失连续增加 2 个时期后训练停止。然而,训练似乎在这之前就停止了。

我将 EarlyStopping 定义如下:

callbacks = [
        EarlyStopping(monitor='val_loss', patience=2, verbose=0),
    ]
Run Code Online (Sandbox Code Playgroud)

在 fit 函数中,我像这样使用它:

hist = model.fit_generator(
            generator(imgIds, batch_size=batch_size, is_train=True),
            validation_data=generator(imgIds, batch_size=batch_size, is_val=True),
            validation_steps=steps_per_val,
            steps_per_epoch=steps_per_epoch,
            epochs=epoch_count,
            verbose=verbose_level,
            callbacks=callbacks)
Run Code Online (Sandbox Code Playgroud)

我不明白为什么训练在第 4 个时期之后结束。

675/675 [==============================] - 1149s - loss: 0.1513 - val_loss: 0.0860
Epoch 2/30
675/675 [==============================] - 1138s - loss: 0.0991 - val_loss: 0.1096
Epoch 3/30
675/675 [==============================] - 1143s - loss: 0.1096 - val_loss: 0.1040
Epoch 4/30
675/675 [==============================] - 1139s - loss: 0.1072 - val_loss: 0.1019
Finished training intermediate1.
Run Code Online (Sandbox Code Playgroud)

Nic*_*ite 4

我认为你对EarlyStopping回调的解释有点偏差;当损失没有从历代以来的最佳损失改善时,它就会停止patience。您的模型在第 1 轮的最佳损失为 0.0860,对于第 2 轮和第 3 轮,损失没有改善,因此它应该在第 3 轮之后停止训练。但是,由于关闭,它会继续训练一个轮次- 一个错误,至少我会根据文档所说的来称呼它patience,即:

耐心:没有改善的时期数,之后将停止训练。

来自 Keras 源代码(为清晰起见稍作编辑):

class EarlyStopping(Callback):
    def on_epoch_end(self, epoch, logs=None):
        current = logs.get(self.monitor)

        if np.less(current - self.min_delta, self.best):
            self.best = current
            self.wait = 0
        else:
            if self.wait >= self.patience:
                self.stopped_epoch = epoch
                self.model.stop_training = True
            self.wait += 1
Run Code Online (Sandbox Code Playgroud)

请注意,直到检查, howself.wait才会递增,因此,虽然您的模型应该在第 3 轮之后停止训练,但它又继续了 1 轮。self.patience

不幸的是,如果您想要一个按照您所描述的方式运行的回调,在没有连续改进的patience情况下停止训练,那么您必须自己编写它。但我认为你只需EarlyStopping稍微修改回调即可完成此操作。

编辑:相差一错误已修复