创建Keras自定义回调进行验证

时间:2019-06-10 15:30:03

标签: python-3.x keras

我想在每个训练时期结束时创建一个自定义回调,以评估验证集上的性能。使用自定义指标评估性能。同样,尽早停止培训应该是培训和验证过程的重要组成部分。

这是我的验证回调代码:

class ValidationCallback(Callback):
    def __init__(self, X, Y, Batch_dev, output_shape, patience=0):
        super(ValidationCallback, self).__init__()
        self.patience = patience
        self.best = np.Inf
        self.best_weights = None

        self.X = X
        self.Y = Y
        self.Batch_dev = Batch_dev
        self.output_shape = output_shape

    def on_train_begin(self, logs=None):
        self.wait = 0
        self.stopped_epoch = 0
        self.best = np.PZERO
        self.val_uas = []

    def on_epoch_end(self, epoch, logs=None):
        val = Validation(self.X, self.Y, self.Batch_dev, self.output_shape, self.model)
        _, _, ua_score = val.validate(epoch)
        self.val_uas.append(ua_score)
        logs['val_ua'] = ua_score
        current = logs.get('val_ua')
        if np.less(self.best, current):
            print(self.wait, self.patience)
            print(current, self.best)
            self.best = current
            self.wait = 0
            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(self.wait, self.patience)
                print(current, self.best)
                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))

培训如下:

validation = ValidationCallback(dev_x, dev_y, batch_size, output_shape, patience=10)
reduce_lr = ReduceLROnPlateau(
    monitor='loss', patience=10, verbose=1, factor=0.8, min_lr=0.000001
    )
mcp_save = ModelCheckpoint(
    model_name, save_best_only=True, monitor='val_ua', mode='max'
    )
tensorboard = TensorBoard(
    log_dir='./LOGS/log', batch_size=batch_size
    )

hist = model.fit_generator(
    generator=generate_batch_train(train_x, train_y, batch_size),
    steps_per_epoch=np.ceil(len(train_x)/batch_size),
    epochs=epochs,
    shuffle=True,
    callbacks=[validation, reduce_lr, mcp_save, tensorboard],
    workers=10,
    use_multiprocessing=True,
    max_queue_size=100,
    verbose=1,
)

我在下面看到错误,这很奇怪,因为val中的epochval.validate(epoch)都不是NoneType。我在这里做错什么吗?谢谢!

Epoch 1/200
70/70 [==============================] - 33s 466ms/step - loss: 1.2720 - UAcc: 0.3852
<data_prepare2.Validation object at 0x7fdb920fc240>
0
Valuating test set...
Epoch: 0, acc: 0.3323330372676745, ua: 0.31934171326259553

0 10
0.31934171326259553 0.0
Epoch 2/200
70/70 [==============================] - 19s 278ms/step - loss: 1.1851 - UAcc: 0.4285
<data_prepare2.Validation object at 0x7fdb91a6eb38>
1
Traceback (most recent call last):
  File "ser_learning4.py", line 190, in <module>
    verbose=1,
  File "/data/anaconda/envs/py35/lib/python3.5/site-packages/keras/legacy/interfaces.py", line 91, in wrapper
    return func(*args, **kwargs)
  File "/data/anaconda/envs/py35/lib/python3.5/site-packages/keras/engine/training.py", line 1418, in fit_generator
    initial_epoch=initial_epoch)
  File "/data/anaconda/envs/py35/lib/python3.5/site-packages/keras/engine/training_generator.py", line 251, in fit_generator
    callbacks.on_epoch_end(epoch, epoch_logs)
  File "/data/anaconda/envs/py35/lib/python3.5/site-packages/keras/callbacks.py", line 79, in on_epoch_end
    callback.on_epoch_end(epoch, logs)
  File "ser_learning4.py", line 120, in on_epoch_end
    _, _, ua_score = val.validate(epoch)
TypeError: 'NoneType' object is not iterable

0 个答案:

没有答案