【问题标题】:Is there a way in Keras to immediately stop training?Keras 有没有办法立即停止训练?
【发布时间】:2020-09-21 22:04:29
【问题描述】:

我正在为我的tf.keras 培训编写自定义提前停止回调。为此,我可以在其中一个回调函数中设置变量self.model.stop_training = True,例如on_epoch_end()。但是,Keras 仅在当前 epoch 完成时才停止训练,即使我在一个 epoch 的训练中设置了这个变量,例如在 on_batch_end() 中。

因此我的问题是:Keras 有没有办法立即停止训练,即使是在当前时代的进度内?

【问题讨论】:

  • 我知道一种方法,但你不会喜欢它:)

标签: python tensorflow keras


【解决方案1】:

在 keras 中,当监控的数量停止改善时,您可以使用 EarlyStopping 停止。从您的问题来看,尚不清楚您要停止的条件是什么。如果你只是想监控EarlyStopping中的值,但只想在批处理后停止,如果值没有改善,你可以重写EarlyStopping类并实现on_batch_end中的逻辑而不是@987654326 @:

class EarlyBatchStopping(Callback):


    def __init__(self,
                 monitor='val_loss',
                 min_delta=0,
                 patience=0,
                 verbose=0,
                 mode='auto',
                 baseline=None,
                 restore_best_weights=False):
        super(EarlyStopping, self).__init__()

        self.monitor = monitor
        self.baseline = baseline
        self.patience = patience
        self.verbose = verbose
        self.min_delta = min_delta
        self.wait = 0
        self.stopped_epoch = 0
        self.restore_best_weights = restore_best_weights
        self.best_weights = None

        if mode not in ['auto', 'min', 'max']:
            warnings.warn('EarlyStopping mode %s is unknown, '
                          'fallback to auto mode.' % mode,
                          RuntimeWarning)
            mode = 'auto'

        if mode == 'min':
            self.monitor_op = np.less
        elif mode == 'max':
            self.monitor_op = np.greater
        else:
            if 'acc' in self.monitor:
                self.monitor_op = np.greater
            else:
                self.monitor_op = np.less

        if self.monitor_op == np.greater:
            self.min_delta *= 1
        else:
            self.min_delta *= -1

    def on_train_begin(self, logs=None):
        # Allow instances to be re-used
        self.wait = 0
        self.stopped_epoch = 0
        if self.baseline is not None:
            self.best = self.baseline
        else:
            self.best = np.Inf if self.monitor_op == np.less else -np.Inf

    def on_batch_end(self, epoch, logs=None):
        current = self.get_monitor_value(logs)
        if current is None:
            return

        if self.monitor_op(current - self.min_delta, self.best):
            self.best = current
            self.wait = 0
            if self.restore_best_weights:
                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
                if self.restore_best_weights:
                    if self.verbose > 0:
                        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 and self.verbose > 0:
            print('Epoch %05d: early stopping' % (self.stopped_epoch + 1))

    def get_monitor_value(self, logs):
        monitor_value = logs.get(self.monitor)
        if monitor_value is None:
            warnings.warn(
                'Early stopping conditioned on metric `%s` '
                'which is not available. Available metrics are: %s' %
                (self.monitor, ','.join(list(logs.keys()))), RuntimeWarning
            )
        return monitor_value

如果你有其他逻辑,你可以使用on_batch_end,并根据你的逻辑设置self.model.stop_training = True,但我想你明白了。

【讨论】:

    【解决方案2】:

    您可以使用model.stop_training 参数停止训练。

    例如,如果我们想在 2nd epochs 3rd batch 停止训练,那么您可以执行以下操作。

    import keras
    from keras.models import Sequential
    from keras.layers import Dense
    from keras.optimizers import SGD
    import numpy as np
    import pandas as pd
    
    class My_Callback(keras.callbacks.Callback):
        def on_epoch_begin(self, epoch, logs={}):
          self.epoch = epoch
    
        def on_batch_end(self, batch, logs={}):
            if self.epoch == 1 and batch == 3:
              print (f"\nStopping at Epoch {self.epoch}, Batch {batch}")
              self.model.stop_training = True
    
    
    X_train = np.random.random((100, 3))
    y_train = pd.get_dummies(np.argmax(X_train[:, :3], axis=1)).values
    
    clf = Sequential()
    clf.add(Dense(9, activation='relu', input_dim=3))
    clf.add(Dense(3, activation='softmax'))
    clf.compile(loss='categorical_crossentropy', optimizer=SGD())
    
    clf.fit(X_train, y_train, epochs=10, batch_size=16, callbacks=[My_Callback()])
    

    输出:

    Epoch 1/10
    100/100 [==============================] - 0s 337us/step - loss: 1.0860
    Epoch 2/10
     16/100 [===>..........................] - ETA: 0s - loss: 1.0830
    Stopping at Epoch 1, Batch 3
    <keras.callbacks.callbacks.History at 0x7ff2e3eeee10>
    

    【讨论】:

      猜你喜欢
      • 2020-12-25
      • 2018-01-08
      • 2015-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-18
      • 2013-12-25
      相关资源
      最近更新 更多