我想在每个训练时期结束时创建一个自定义回调,以评估验证集上的性能。使用自定义指标评估性能。同样,尽早停止培训应该是培训和验证过程的重要组成部分。
这是我的验证回调代码:
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
中的epoch
和val.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