tensorflow 2.3中的回调

tensorflow 2.3中的回调,tensorflow,keras,callback,early-stopping,Tensorflow,Keras,Callback,Early Stopping,我正在写我自己的回调,根据一些自定义条件停止训练。满足条件后,EarlyStoping可停止训练: self.model.stop_training = True e、 g.来自 类EarlyStoppingAtMinLoss(keras.callbacks.Callback): “当损失达到最小值时停止训练,即损失停止减少 论据: 耐心:在min被命中后等待的时间数。在此之后 没有改善的次数,培训停止。 “”“ 问题是,它不适用于tensorflow 2.2和2.3。有解决办法吗?还有什么方

我正在写我自己的回调,根据一些自定义条件停止训练。满足条件后,EarlyStoping可停止训练:

self.model.stop_training = True
e、 g.来自

类EarlyStoppingAtMinLoss(keras.callbacks.Callback): “当损失达到最小值时停止训练,即损失停止减少

论据: 耐心:在min被命中后等待的时间数。在此之后 没有改善的次数,培训停止。 “”“


问题是,它不适用于tensorflow 2.2和2.3。有解决办法吗?还有什么方法可以停止TF2.3中模型的训练呢?

我复制了您的代码,并添加了一些打印语句,以查看发生了什么。我还将监控的损失从培训损失更改为验证损失,因为培训损失在许多时期内都会不断减少,而验证损失则会更快地趋于平稳。最好监控验证损失,以便尽早停止和节省重量,然后使用训练损失。您的代码运行良好,如果在经历了数个历代之后,损失没有减少,则会停止训练。确保你有下面的代码

patience=3 # set patience value
callbacks=[EarlyStoppingAtMinLoss(patience)]
# in model.fit include callbacks=callbacks
下面是用print语句修改的代码,这样您就可以看到发生了什么

class EarlyStoppingAtMinLoss(keras.callbacks.Callback):
    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("val_loss")
        print('epoch = ', epoch +1, '   loss= ', current, '   best_loss = ', self.best, '   wait = ', self.wait)
        if np.less(current, self.best):
            self.best = current
            self.wait = 0
            print ( ' loss improved setting wait to zero and saving weights')
            # Record the best weights if current results is better (less).
            self.best_weights = self.model.get_weights()
        else:
            self.wait += 1
            print ( ' for epoch ', epoch +1, '  loss did not improve setting wait to ', self.wait)
            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))
我复制了你的新代码并运行了它。显然,tensorflow不评估model.stop_批量培训。因此,即使model.stop\u training在on\u train\u batch\u end中设置为True,它仍会继续处理批次,直到历元的所有批次都完成。然后在纪元结束时,tensorflow评估模型。停止训练,训练确实停止


谢谢,代码按原样工作,解释了里面发生了什么。 我想把这个回调转换成批处理版本

我从一些数据中得到的是:

批次=42损失=709.771484375最佳损失=27.087162017822266 批次42丢失的等待=40未将设置等待改进为41 等待:41耐心:3从最佳状态结束恢复模型权重 一批

就好像在“epoch\u end”转换为“on\u batch\u end”使脚本忽略了这一行“self.model.stop\u training=True”-它打印出它结束了,但训练仍在继续。(仍然是TF2.3.0)


那么,epoch回调和批回调有什么区别吗?

谢谢。我试图理解回调,所以:在epoch条件和批处理条件之间有什么区别吗?当我在新纪元结束时更改为列车结束时,行为似乎有所不同(张贴在下面)。我再次复制了您的代码,正在查看它,以了解它为什么不停止培训。将返回给您查看我在下面修改的答案。显然,tensorflow只在一个时期结束时评估model.stop_培训,而不是在批次中。因此,批处理将继续运行,直到历元的所有批处理都完成。然后在时代结束时对model.stop\u训练进行评估。
class EarlyStoppingAtMinLoss(tf.keras.callbacks.Callback):
    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_batch = 0
        # Initialize the best as infinity.
        self.best = np.Inf

    def on_train_batch_end(self, batch, logs=None):
        current = logs.get("loss")
        print('batch = ', batch +1, '   loss= ', current, '   best_loss = ', self.best, '   wait = ', self.wait)
        if np.less(current, self.best):
            self.best = current
            self.wait = 0
            print ( ' loss improved setting wait to zero and saving weights')
            # Record the best weights if current results is better (less).
            self.best_weights = self.model.get_weights()
        else:
            self.wait += 1
            print ( ' for batch ', batch +1, '  loss did not improve setting wait to ', self.wait)
            print('wait:', self.wait)
            print('patience:', self.patience)
            if self.wait >= self.patience:
                self.stopped_batch = batch
                self.model.stop_training = True
                print("Restoring model weights from the end of the best batch.")
                self.model.set_weights(self.best_weights)


    def on_train_end(self, logs=None):
        if self.stopped_batch > 0:
            print("Batch %05d: early stopping" % (self.stopped_batch + 1))