Callback
回调函数是在设定事件发生时由训练循环调用的函数,例如在每个轮次结束时调用,以添加提前停止、检查点或日志记录功能。
回调是传递给另一段代码的函数;特定事件发生时,那段代码会调用该函数。用户界面中的事件处理程序、异步代码中的完成函数,以及传递给排序例程的比较函数,都属于回调。在深度学习框架中,事件是训练循环中的特定节点,例如训练开始、每个批次或epoch结束,以及验证完成时。为事件注册的回调会在事件发生时运行,并可以访问训练器状态,因此用户无需修改训练循环本身,就能添加针对过拟合的提前停止、检查点保存、学习率调度或日志记录功能。
回调如何接入训练流程#
框架会为每个命名事件维护一个回调列表,并在训练循环到达相应事件时调用列表中的所有回调,同时传入训练器或模型对象,以便回调读取指标并更改设置。Keras在其 keras.callbacks 模块中收集这些回调;PyTorch Lightning 使用 Callback 的子类;Hugging Face Transformers 则使用 TrainerCallback。不同库的方法名称各异,但事件都遵循同一个循环:
由于回调在循环内部运行,因此也可以改变循环行为:将停止标志设为有效的回调会在当前 epoch 结束后终止训练;修改优化器的回调则会影响之后的每一步。同一事件的回调会按注册顺序运行,而批次级回调每个 epoch 会运行数千次,因此上传文件等耗时操作适合放在 epoch 级事件中。在分布式训练中,每个进程都会运行自己的循环副本及其回调;因此,日志记录和检查点回调通常只在主进程(rank 0)上执行,以免多个 GPU 重复写入同一个文件。
常见训练回调#
- 提前停止:如果验证指标连续指定数量的 epoch 未改善,就停止训练;这个数量称为耐心值,可限制过拟合并节省计算资源。Keras 的
EarlyStopping还可以在停止前恢复之前记录到的最佳权重。 - 检查点保存:每个 epoch 或监控指标改善时保存模型,确保最佳权重得以保留,并让崩溃的训练任务能够恢复。Keras 的
BackupAndRestore回调会使用保存的状态自动恢复中断的训练任务。 - 学习率调度:当指标进入平台期时降低学习率,例如 Keras 的
ReduceLROnPlateau所做的那样;也可以采用余弦衰减等固定调度方案。 - 实验跟踪:每个 epoch 结束后,将损失、指标和样例图像发送到 TensorBoard、MLflow 或 Weights & Biases 等工具。
- 超参数调优:将每个 epoch 的分数报告给 Ray Tune等调优器,其调度器会提前停止前景不佳的试验。
编写自定义回调#
Ultralytics YOLO 会在训练、验证、预测和导出期间触发命名事件,例如 on_train_epoch_end 和 on_fit_epoch_end;其用于 MLflow、Comet、ClearML、TensorBoard 和 Ultralytics Platform 的集成也会作为这些事件的回调进行注册。这个回调会在每个 epoch 后读取验证集的 mAP50-95,并在 YOLO26 训练达到目标时立即停止:
from ultralytics import YOLO
def stop_at_target(trainer):
"""Stop training once validation mAP50-95 reaches 0.6."""
score = trainer.metrics["metrics/mAP50-95(B)"]
print(f"Epoch {trainer.epoch + 1}: mAP50-95 {score:.3f}")
if score >= 0.6:
trainer.stop = True # the trainer ends the run after this epoch
model = YOLO("yolo26n.pt")
model.add_callback("on_fit_epoch_end", stop_at_target) # runs after each epoch's validation
model.train(data="coco8.yaml", epochs=20)on_fit_epoch_end 事件会在该 epoch 的训练和验证结束后触发,因此 trainer.metrics 已经包含该 epoch 的得分。设置 trainer.stop 后,训练器会退出 epoch 循环,像往常一样对最佳权重进行最终验证并保存结果;内置的 patience 上限触发时也是如此。
回调与钩子#
这两个词通常指同一概念:PyTorch Lightning 将回调实现的方法称为钩子。在 PyTorch 中,通过 register_forward_hook 或 register_full_backward_hook 注册的模块钩子会连接到单个层的前向或反向传播,而非训练循环事件;这些钩子可用于读取特征图进行可视化,也可用于在反向传播期间检查和修改梯度。










