为了更加了解yolo模型的配置过程,我将逐步剖析从YOLO类的构造到模型配置的解析,从任务类型的自动判断到不同模型缩放版本的灵活定义。后续无论是想优化模型性能,还是拓展其应用场景,这篇文章都将让你省去很多困惑的地方。

作为记录,提醒自己文章最后的总结记得要看

介绍一下YOLO检测中涉及的组件,有个基本的框架概念再去debug研究。

组件介绍

  1. DetectionModel

    • 职责:负责定义和加载检测模型的网络结构,包括骨干网络(Backbone)、特征金字塔(Neck)和输出层(Head)。它处理前向推理,输出原始预测结果(如边界框、置信度和类别)。
    • 调用位置:在YOLO类中被定义,在DetectionTrainer中通过get_model()方法实例化。
  2. DetectionTrainer

    • 职责:封装训练逻辑,管理数据加载、损失计算、反向传播和优化器调度。它负责训练过程的循环,并在每个epoch结束时可能调用验证逻辑。
    • 调用位置:在model.train()中生成DetectionTrainer实例,内部会调用DetectionModel进行训练。
  3. DetectionValidator

    • 职责:负责验证逻辑,使用验证集评估模型性能(如mAP、Precision/Recall等)。
    • 调用位置:在DetectionTrainer中,训练过程中可能会定期调用。
  4. DetectionPredictor

    • 职责:负责推理逻辑,加载训练好的模型权重,执行单张或批量图片的推断,并包含后处理(如非最大抑制NMS、坐标映射和结果可视化)。
    • 调用位置:在CLI命令yolo detect predict中被调用。

可以在YOLO类的task_map中看到这些组件

为了便于结合代码进行理解,大部分内容呈现在截图中。
首先创建一个mytrain.py文件,简单的创建一个YOLO模型。

YOLO类的内部构造如下,继承自Model类,进入debug便于显示参数信息。

最后一个条件分支符合,进入父类(Model类)的__init__()查看代码。

Yaml文件加载模型进入if分支,使用_new方法,如果是.pt则使用_load方法。

查看new方法。

self.task根据配置文件中的head部分的参数得到为detect,下面学习self.model的构造,进入self._smart_load函数。

点进去self.task_map之后发现是未定义的函数,如下图

返回子类中查看详细定义

此时的检测模型已经构建好了,本质上通过配置文件中的关键字判断是什么任务,然后调用任务对应的类,如下图:

现在看一下"model": DetectionModel中的内部代码

parse_model才是真正解析文件构造模型,进入内部查看代码:

scales: # model compound scaling constants, i.e. 'model=yolov8n.yaml' will call yolov8.yaml with scale 'n'

  # [depth, width, max_channels]

  n: [0.33, 0.25, 1024] # YOLOv8n summary: 129 layers, 3157200 parameters, 3157184 gradients, 8.9 GFLOPS

  s: [0.33, 0.50, 1024] # YOLOv8s summary: 129 layers, 11166560 parameters, 11166544 gradients, 28.8 GFLOPS

  m: [0.67, 0.75, 768] # YOLOv8m summary: 169 layers, 25902640 parameters, 25902624 gradients, 79.3 GFLOPS

  l: [1.00, 1.00, 512] # YOLOv8l summary: 209 layers, 43691520 parameters, 43691504 gradients, 165.7 GFLOPS

  x: [1.00, 1.25, 512] # YOLOv8x summary: 209 layers, 68229648 parameters, 68229632 gradients, 258.5 GFLOPS

scales字典用于定义不同模型缩放版本的参数。这里的缩放通常指的是模型的深度(depth)、宽度(width)和最大通道数(max_channels),这些参数影响模型的复杂度和性能。在YOLOv8模型的上下文中,scales 字典定义了不同大小的模型版本,如YOLOv8n、YOLOv8s、YOLOv8m、YOLOv8l和YOLOv8x。

下面是一系列的判断

之后通过遍历构建配置文件中backbone和head的各个层。

最终构建好了一个完整的网络。

总结一下:
1.加载模型

model = YOLO("ultralytics/cfg/models/v8/yolov8.yaml")
  • 调用:首先调用 YOLO 类(通常是 DetectionModel 的一个实例),并传入模型配置文件的路径("ultralytics/cfg/models/v8/yolov8.yaml"),返回一个网络模型
  • 作用:负责定义和加载检测模型的网络结构,包括骨干网络(Backbone)、特征金字塔(Neck)和输出层(Head)。它处理前向推理,输出原始预测结果(如边界框、置信度和类别)。

2.训练模型

model.train(data="ultralytics/cfg/datasets/coco128-hds.yaml", epochs=2)
  • 调用:接着调用 model 对象的 train 方法,这个方法通常是由 DetectionTrainer 类实现的)。
  • 模型构建:在trainer.train()DetectionTrainer.get_model() 被调用,返回一个 DetectionModel 实例(并加载预训练权重或断点)。调用DetectionModel进行前向推理、计算损失、反向传播和优化。在设定的验证周期结束后,内部调用DetectionValidator对当前模型进行验证。
├─ train ──▶ DetectionTrainer ───▶ get_model() ──▶ DetectionModel ──▶ forward/backward  
│                                    │  
│                                    └─▶ (定期)▶ Validation ──▶ DetectionValidator ──▶ DetectionModel  
│  
├─ val ────▶ DetectionValidator ───▶ DetectionModel ──▶ forward → eval metrics  
│  
└─ predict ▶ DetectionPredictor ──▶ DetectionModel ──▶ forward → NMS → 保存/可视化

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐