在深度学习模型的训练过程中,回调函数扮演着至关重要的角色。随着模型变得越来越复杂,训练时间也随之增加,通常需要数小时。在传统的训练流程中,在开始训练之前会设定好所有的选项和参数,例如学习率、优化器、损失函数等,然后启动训练。一旦训练开始,无法暂停训练来更改参数。有时,当模型训练了几个小时后,可能想要在后期调整一些参数,这在传统流程中是不可能的。这时,TensorFlow的回调函数就显得尤为重要。
首先,需要定义回调函数,然后在调用模型的fit()
方法时传递这些回调函数。例如,可以设置一个回调函数来在遇到NaN值时停止训练,或者在验证集的准确率不再提升时减少学习率。以下是如何实现这些功能的示例代码:
model.fit(X_train, y_train, epochs=10, validation_data=(X_test, y_test), callbacks=[
NanStop, LrValAccuracy
])
让看看一些最有用的回调函数:
当训练模型时,通常会查看指标来监控模型的表现。如果指标非常高,可以得出模型过拟合的结论;如果指标非常低,则可能是欠拟合。如果指标增加到某个范围以上,可以停止训练以防止过拟合。EarlyStopping回调函数允许做到这一点。
early_stop_cb = tf.keras.callbacks.EarlyStopping(
monitor='val_loss', min_delta=0, patience=0, verbose=0, mode='auto'
)
在这段代码中:monitor
是在训练时想要监控的指标;min_delta
是想要认为比前一个epoch有所改进的指标的最小变化量;patience
是等待指标变化的epoch数,否则停止训练;verbose
控制打印信息的级别;mode
可以是“auto”(自动检测行为),“min”(如果指标停止减少则停止训练),或者“max”(如果指标停止增加则停止训练)。
这个回调函数允许在训练过程中的特定时间调用某些lambda函数。可以在指定的时间传递任何需要执行的lambda函数。以下是参数的含义:
tf.keras.callbacks.LambdaCallback(
on_epoch_begin=None, on_epoch_end=None, on_batch_begin=None, on_batch_end=None,
on_train_begin=None, on_train_end=None, **kwargs
)
在这里,可以在每个epoch的开始和结束时调用函数,以及在每个batch的开始和结束时调用函数。还可以在模型开始训练和训练完成时调用函数。
在训练过程中,改变学习率是一项常见任务。通常,当模型接近损失最小化的最佳拟合时,逐渐开始减小学习率以获得更好的收敛。以下是一个简单的例子,希望每3个epoch减少5%的学习率。这里需要传递一个函数到schedule
参数,该函数指定了学习率变化的逻辑。
def schedule(epoch, lr):
if epoch % 3 == 0:
lr = lr - (lr * 0.05)
return lr
return lr
通过这种方式,可以在训练过程中动态调整学习率,以优化模型的训练效果。
使用这个回调函数以不同的频率保存模型。这允许在中间步骤保存权重,以便在需要时可以加载权重。
tf.keras.callbacks.ModelCheckpoint(
filepath, monitor='val_loss', verbose=0, save_best_only=False,
save_weights_only=False, mode='auto', save_freq='epoch'
)
在这段代码中:filepath
是保存模型的位置;monitor
是监控的指标;save_best_only
决定是否只保存最佳模型;mode
可以是“min”、“max”或“auto”;save_weights_only
决定是否只保存模型权重。
这个回调函数用于在特定指标停止增加并达到平台期时减少训练速率。
tf.keras.callbacks.ReduceLROnPlateau(
monitor='val_loss', factor=0.1, patience=10, verbose=0,
mode='auto', min_delta=0.0001, cooldown=0, min_lr=0, **kwargs
)
在这段代码中:factor
是学习率减少的因子;min_delta
是需要被认为是改进的最小变化量;cooldown
是等待学习率减少的epoch数;min_lr
是学习率不能低于的最小值。
这个回调函数在任何损失变为NaN时停止训练过程。
tf.keras.callbacks.TerminateOnNaN()
Tensorboard允许显示有关训练过程的信息,如指标、训练图表、激活函数直方图和其他梯度分布。要使用tensorboard,首先需要设置一个log_dir
,tensorboard文件将保存在这里。
log_dir="logs"
tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=1, write_graph=True)
在这段代码中:log_dir
是保存文件的目录;histogram_freq
是计算直方图和梯度图的epoch频率;write_graph
决定是否在tensorboard中显示和可视化图表。
class Metrics_Callback(tf.keras.callbacks.Callback):
def __init__(self, x_val, y_val):
self.x_val = x_val
self.y_val = y_val
def on_train_begin(self, logs={}):
self.history = {"auc_score":[], "micro_f1":[]}
def on_epoch_end(self, epoch, logs={}):
auc_score = roc_auc_score(self.y_val, model.predict_proba(self.x_val))
y_true = [0 if x[0]==1.0 else 1 for x in self.y_val]
f1_s = f1_score(y_true, self.model.predict_classes(self.x_val), average='micro')
self.history["auc_score"].append(auc_score)
self.history["micro_f1"].append(f1_s)