编写自己的自定义EarlyStopping 回调怎么样? Tensorflow 文档提供了一个很好的入门示例:
import numpy as np
class EarlyStoppingAtMinLoss(keras.callbacks.Callback):
"""Stop training when the loss is at its min, i.e. the loss stops decreasing.
Arguments:
patience: Number of epochs to wait after min has been hit. After this
number of no improvement, training stops.
"""
def __init__(self, patience=0):
super(EarlyStoppingAtMinLoss, self).__init__()
self.patience = patience
# best_weights to store the weights at which the minimum loss occurs.
self.best_weights = None
def on_train_begin(self, logs=None):
# The number of epoch it has waited when loss is no longer minimum.
self.wait = 0
# The epoch the training stops at.
self.stopped_epoch = 0
# Initialize the best as infinity.
self.best = np.Inf
def on_epoch_end(self, epoch, logs=None):
current = logs.get("loss")
if np.less(current, self.best):
self.best = current
self.wait = 0
# Record the best weights if current results is better (less).
self.best_weights = self.model.get_weights()
else:
self.wait += 1
if self.wait >= self.patience:
self.stopped_epoch = epoch
self.model.stop_training = True
print("Restoring model weights from the end of the best epoch.")
self.model.set_weights(self.best_weights)
def on_train_end(self, logs=None):
if self.stopped_epoch > 0:
print("Epoch %05d: early stopping" % (self.stopped_epoch + 1))
注意示例中的self.stopped_epoch 变量。通过这种方式,您可以完全控制显示的内容以及提前停止逻辑的工作方式。此外,使用logs 字典,您可以访问时期 x 的当前损失和准确度。另一方面,如果您只想在训练模型后使用简单的打印语句,您可以获取回调的最后一个时期并打印它:
model.compile(optimizer='adam', loss='mse' )]
cbfile = 'best_model.h5'
early_stopping = EarlyStopping(monitor='val_loss', mode='auto', verbose=0, patience=10)
calls = [early_stopping,
ModelCheckpoint(cbfile, monitor = 'val_loss', mode = 'auto',\
save_best_only = True ) ]
history = model.fit(Xvect, Yvect, epochs=mcycl, batch_size=32,\
validation_split=dsplit, verbose=0, callbacks = calls )
saved = load_model('best_model.h5')
score = saved.evaluate(Xvect, Yvect, verbose=0)
print('"Overall loss for best fit":',np.round(score,4))
print("Epoch %05d: early stopping" % (early_stopping.stopped_epoch + 1))