Ultralytics YOLO27:

回调函数#

Ultralytics 框架支持回调,这些回调在 trainvalexportpredict 模式的关键阶段充当切入点。每个回调接受一个 TrainerValidatorPredictor 对象,具体取决于操作类型。这些对象的所有属性都在 BaseTrainerBaseValidatorBasePredictor 参考页面中详细说明。



Watch: How to use Ultralytics Callbacks | Predict, Train, Validate and Export Callbacks | Ultralytics YOLO🚀

示例#

在预测时返回附加信息#

在这个示例中,我们展示了如何随每个结果对象一起返回原始帧:

from ultralytics import YOLO

def on_predict_batch_end(predictor):
    """Combine prediction results with corresponding frames."""
    _, image, _ = predictor.batch

    # Ensure that image is a list
    image = image if isinstance(image, list) else [image]

    # Combine the prediction results with the corresponding frames
    predictor.results = zip(predictor.results, image)

# Create a YOLO model instance
model = YOLO("yolo26n.pt")

# Add the custom callback to the model
model.add_callback("on_predict_batch_end", on_predict_batch_end)

# Iterate through the results and frames
for result, frame in model.predict():  # or model.track()
    pass

在训练前注册 PyTorch 前向钩子#

model.train() 根据模型配置构建训练模型,并将加载的权重传输到其中。在此调用之前直接在 model.model 上注册的 PyTorch 钩子属于运行时状态,因此重建的训练模型不会继承它们。请在模型设置完成后,于 on_pretrain_routine_end 中注册训练钩子:

from ultralytics import YOLO
from ultralytics.utils.torch_utils import unwrap_model

def preprocess_input(module, inputs):
    """Center each input channel before the first model layer."""
    images = inputs[0]
    return (images - images.mean(dim=(-2, -1), keepdim=True),)

def register_forward_pre_hook(trainer):
    """Attach preprocessing to the active training model."""
    train_model = unwrap_model(trainer.model)
    train_model.model[0].register_forward_pre_hook(preprocess_input)

model = YOLO("yolo26n.pt")
model.add_callback("on_pretrain_routine_end", register_forward_pre_hook)
model.train(data="coco8.yaml", epochs=1)

unwrap_model() 同时处理单设备和 DistributedDataParallel 训练。请不要将本地定义的钩子附加到 trainer.ema.ema,因为训练检查点会序列化 EMA 模型,并且另一个进程在加载检查点时可能无法导入该回调。如果在训练验证期间必须运行相同的预处理,请将其实现为可导入的模型组件,而不是运行时钩子。

独立运行的 model.val() 会为每次调用复制加载的模型。预测会在首次调用时创建并缓存一个副本,因此请在第一次 model.predict()model.track() 调用之前在 model.model 上注册钩子;随后添加的钩子无法触及缓存的预测器。在新进程中加载检查点后,请再次注册运行时钩子。

使用 on_model_save 回调函数访问模型指标#

这个示例展示了如何在使用 on_model_save 回调函数保存检查点后,检索训练详情,例如 best_fitness 分数、total_loss 以及其他指标。

from ultralytics import YOLO

# Load a YOLO model
model = YOLO("yolo26n.pt")

def print_checkpoint_metrics(trainer):
    """Print trainer metrics and loss details after each checkpoint is saved."""
    print(
        f"Model details\n"
        f"Best fitness: {trainer.best_fitness}, "
        f"Loss names: {trainer.loss_names}, "  # List of loss names
        f"Metrics: {trainer.metrics}, "
        f"Total loss: {trainer.tloss}"  # Total loss value
    )

if __name__ == "__main__":
    # Add on_model_save callback.
    model.add_callback("on_model_save", print_checkpoint_metrics)

    # Run model training on custom dataset.
    results = model.train(data="coco8.yaml", epochs=3)

所有回调函数#

以下是所有支持的回调函数。有关更多详细信息,请参阅回调函数的源代码

训练器回调函数#

回调函数描述
on_pretrain_routine_start在预训练例程开始时触发,位于数据加载和模型设置之前。
on_pretrain_routine_end在预训练例程结束时触发,位于数据加载和模型设置完成之后。
on_train_start在训练开始时触发,位于第一个轮次开始之前。
on_train_epoch_start在每个训练轮次开始时触发,位于批次迭代开始之前。
on_train_batch_start在每个训练批次开始时触发,位于前向传播之前。
optimizer_step在优化器步骤期间触发。保留用于自定义集成;默认训练循环不会调用它。
on_before_zero_grad在梯度清零之前触发。保留用于自定义集成;默认训练循环不会调用它。
on_train_batch_end在每个训练批次结束时触发,位于反向传播之后。由于梯度累积,优化器步骤可能会被推迟。
on_train_epoch_end在每个训练轮次结束时触发,在处理完所有批次之后但在验证之前。验证指标和适应度可能尚未可用。
on_model_save在保存模型检查点时触发,位于验证之后。
on_fit_epoch_end在每个拟合轮次(训练 + 验证)结束时触发,在验证和任何检查点保存之后。验证指标可用,并且适应度可用于每轮训练调用。此呼叫也在最终最佳模型评估期间调用,此时不会发生检查点保存,且适应度可能不存在。
on_train_end在训练过程结束时触发,位于对最佳模型进行最终评估之后。
on_params_update在模型参数更新时触发。保留用于自定义集成;默认训练循环不会调用它。
teardown在清理训练过程时触发。

验证器回调函数#

回调函数描述
on_val_start在验证开始时触发。
on_val_batch_start在每个验证批次开始时触发。
on_val_batch_end在每个验证批次结束时触发。
on_val_end在验证结束时触发。

预测器回调函数#

回调函数描述
on_predict_start在预测过程开始时触发。
on_predict_batch_start在每个预测批次开始时触发。
on_predict_postprocess_end在预测后处理结束时触发。
on_predict_batch_end在每个预测批次结束时触发。
on_predict_end在预测过程结束时触发。

导出器回调函数#

回调函数描述
on_export_start在导出过程开始时触发。
on_export_end在导出过程结束时触发。

常见问题#

  • Ultralytics 回调是在模型操作(例如训练、验证、导出和预测)的关键阶段触发的专用切入点。这些回调在流程的特定点启用自定义功能,从而允许对工作流进行增强和修改。每个回调接受一个 TrainerValidatorPredictor 对象,具体取决于操作类型。有关这些对象的详细属性,请参考 BaseTrainerBaseValidatorBasePredictor 参考页面。

    要使用回调函数,请定义一个函数并使用 model.add_callback() 方法将其添加到模型中。以下是在预测期间返回附加信息的示例:

    from ultralytics import YOLO
    
    def on_predict_batch_end(predictor):
        """Handle prediction batch end by combining results with corresponding frames; modifies predictor results."""
        _, image, _ = predictor.batch
        image = image if isinstance(image, list) else [image]
        predictor.results = zip(predictor.results, image)
    
    model = YOLO("yolo26n.pt")
    model.add_callback("on_predict_batch_end", on_predict_batch_end)
    for result, frame in model.predict():
        pass
  • 通过在训练过程的特定阶段注入逻辑来自定义 Ultralytics 训练例程。Ultralytics YOLO 提供了各种训练回调函数,例如 on_train_starton_train_endon_train_batch_end,它们允许你添加自定义指标、处理或日志记录。

    以下是在使用回调函数冻结层时如何冻结 BatchNorm 统计信息的方法:

    from ultralytics import YOLO
    
    # Add a callback to put the frozen layers in eval mode to prevent BN values from changing
    def put_in_eval_mode(trainer):
        n_layers = trainer.args.freeze
        if not isinstance(n_layers, int):
            return
    
        for i, (name, module) in enumerate(trainer.model.named_modules()):
            if name.endswith("bn") and int(name.split(".")[1]) < n_layers:
                module.eval()
                module.track_running_stats = False
    
    model = YOLO("yolo26n.pt")
    model.add_callback("on_train_epoch_start", put_in_eval_mode)
    model.train(data="coco.yaml", epochs=10)

    有关有效使用训练回调函数的更多详细信息,请参阅训练指南

  • 在 Ultralytics YOLO 的验证期间使用回调函数可以通过启用自定义处理、日志记录或指标计算来增强模型评估。像 on_val_starton_val_batch_endon_val_end 这样的回调函数提供了注入自定义逻辑的切入点,确保了详细且全面的验证过程。

    例如,若要绘制所有验证批次而不是仅绘制前三个批次:

    import inspect
    
    from ultralytics import YOLO
    
    def plot_samples(validator):
        frame = inspect.currentframe().f_back.f_back
        v = frame.f_locals
        validator.plot_val_samples(v["batch"], v["batch_i"])
        validator.plot_predictions(v["batch"], v["preds"], v["batch_i"])
    
    model = YOLO("yolo26n.pt")
    model.add_callback("on_val_batch_end", plot_samples)
    model.val(data="coco.yaml")

    有关将回调函数纳入验证过程的更多见解,请参阅验证指南

  • 要在 Ultralytics YOLO 中为预测模式附加自定义回调函数,请定义一个回调函数并将其注册到预测过程中。常见的预测回调函数包括 on_predict_starton_predict_batch_endon_predict_end。这些函数允许修改预测输出并集成其他功能,例如数据日志记录或结果转换。

    下面是一个示例,其中自定义回调函数根据是否存在特定类的对象来保存预测:

    from ultralytics import YOLO
    
    model = YOLO("yolo26n.pt")
    
    class_id = 2
    
    def save_on_object(predictor):
        r = predictor.results[0]
        if class_id in r.boxes.cls:
            predictor.args.save = True
        else:
            predictor.args.save = False
    
    model.add_callback("on_predict_postprocess_end", save_on_object)
    results_stream = model("pedestrians.mp4", stream=True, save=True)
    
    for result in results_stream:
        pass

    有关更全面的用法,请参考预测指南,其中包含详细说明和附加自定义选项。

  • Ultralytics YOLO 支持各种实际的回调函数实现,以增强和自定义不同的阶段,例如训练、验证和预测。一些实际示例包括:

    • 记录自定义指标:在不同阶段(例如训练或验证轮次结束时)记录附加指标。
    • 数据增强:在预测或训练批次期间实现自定义数据转换或增强。
    • 中间结果:保存中间结果(例如预测或帧),以便进行进一步分析或可视化。

    示例:在预测期间使用 on_predict_batch_end 将帧与预测结果组合:

    from ultralytics import YOLO
    
    def on_predict_batch_end(predictor):
        """Combine prediction results with frames."""
        _, image, _ = predictor.batch
        image = image if isinstance(image, list) else [image]
        predictor.results = zip(predictor.results, image)
    
    model = YOLO("yolo26n.pt")
    model.add_callback("on_predict_batch_end", on_predict_batch_end)
    for result, frame in model.predict():
        pass

    探索回调源代码以获取更多选项和示例。

评论