YOLO11n 内部结构修改指南
YOLO11n 内部结构修改指南
本文由GPT-5.3-Codex·Medium撰写。
1. 先理解 YOLO11n 是如何被加载的
在这个仓库里,YOLO11n 不是单独一个 yolo11n.yaml 文件,而是通过 yolo11.yaml 里的 scales.n 缩放规则得到。
核心流程:
- 传入 model=yolo11n.yaml 或 yolo11n.pt
- 解析时会统一映射到 ultralytics/cfg/models/11/yolo11.yaml
- 从文件名中提取 scale=n
- 使用 parse_model() 按 YAML 的 backbone/head 构建网络
涉及关键代码:
- ultralytics/nn/tasks.py
- yaml_model_load()
- guess_model_scale()
- parse_model()
- DetectionModel.init()
2. 改结构时通常要改哪些文件
A. 只改网络拓扑(不新增新算子)
只需要改:
- ultralytics/cfg/models/11/yolo11.yaml
建议不要直接覆盖官方 yolo11.yaml,改为新文件,例如:
- ultralytics/cfg/models/11/yolo11n_my.yaml
前提:你用到的模块(如 Conv、C2f、C3k2、SPPF、Detect)已经在 parse_model 中支持。
B. 新增自定义模块(新增算子/Block)
通常至少需要改 3 类文件:
- 模块实现文件
- ultralytics/nn/modules/block.py
- 或 ultralytics/nn/modules/conv.py
- 或 ultralytics/nn/modules/head.py
- 模块导出文件
- ultralytics/nn/modules/init.py
- 模型解析与注册
- ultralytics/nn/tasks.py
- 顶部 import 列表要导入新模块
- parse_model() 里按模块类型处理参数
- 若你的模块是 [c1, c2, …] 这种常规结构块,要加入 base_modules
- 若你的模块支持 repeats,要加入 repeat_modules
C. 如果改了检测头输出定义
还要同步检查:
- ultralytics/nn/modules/head.py
- ultralytics/utils/loss.py
- 推理后处理相关逻辑(如解码、维度约定)
否则可能出现训练正常但推理/导出异常,或 loss 维度不匹配。
3. 示例 1:只改 YAML(推荐先从这里开始)
目标:把骨干某层从 C3k2 改成 C2f,快速验证结构变更流程。
3.1 新建配置文件
复制:
- ultralytics/cfg/models/11/yolo11.yaml
到: - ultralytics/cfg/models/11/yolo11n_my.yaml
然后把其中一层改掉(示例):
1 | # 原来 |
说明:
- C2f 已被 parse_model 支持,通常不需要改 Python 源码。
- 这是最稳妥的“改结构”方式,适合先做 baseline。
3.2 训练验证
1 | yolo detect train model=ultralytics/cfg/models/11/yolo11n_my.yaml data=coco8.yaml imgsz=640 epochs=1 |
4. 示例 2:新增自定义模块 MyBlock
假设你要新增一个模块 MyBlock,并在 YAML 里使用它。
4.1 在模块文件中实现
在 ultralytics/nn/modules/block.py 增加:
1 | class MyBlock(nn.Module): |
4.2 在导出文件注册
在 ultralytics/nn/modules/init.py:
- 从 block import MyBlock
- 把 MyBlock 加入 all
4.3 在 tasks.py 注册给解析器
在 ultralytics/nn/tasks.py:
- 顶部 from ultralytics.nn.modules import (…) 中加入 MyBlock
- 在 parse_model() 的 base_modules 集合加入 MyBlock
- 如果 MyBlock 支持 repeats 参数 n,再加入 repeat_modules
4.4 在 YAML 中使用
例如在 yolo11n_my.yaml 中:
1 | - [-1, 1, MyBlock, [256, 3]] |
5. 高风险注意事项(非常重要)
- 文件命名与 scale 自动识别
- scale 是从文件名里识别的(n/s/m/l/x)。
- 如果命名不规范,可能拿不到期望的缩放系数。
- 推荐命名包含 n/s/m/l/x,例如 yolo11n_my.yaml。
- 通道数和拼接索引必须匹配
- Concat 的输入层索引、输出通道必须和后续层对齐。
- 一旦改动 backbone/head 任意层,后续引用索引都要复核。
- repeats 和参数顺序
- parse_model 会对部分模块自动插入 repeats 到参数中。
- 如果你的模块参数顺序设计不一致,会在构建时报错或 silent shape 错误。
- Detect 头改动要联动 loss 与后处理
- 改检测头输出格式,不仅要改 head,还要改 loss 与 decode 逻辑。
- 预训练权重加载不是全量匹配
- 改结构后常见现象是仅部分权重能迁移,这是正常的。
- 需要关注日志里的 transferred items,确认是否符合预期。
- 先做最小可运行验证
- 建议先用 coco8 做 1 个 epoch 烟雾测试,再跑正式训练。
6. 推荐修改流程(实践版)
- 先只改 YAML,确保能 train + val + predict。
- 再引入自定义模块,逐步加到 parse_model。
- 每改一步都做一次最小训练/推理验证。
- 最后再考虑导出(ONNX/TensorRT)兼容性测试。
7. 快速自检清单
- 是否新建了独立 YAML(避免污染官方配置)
- parse_model 是否能识别你的模块名
- base_modules/repeat_modules 是否注册正确
- Concat/Detect 的输入索引和通道是否一致
- 训练、推理、导出至少各做过一次最小验证
PS:封面图来源:AiRomance
All articles on this blog are licensed under CC BY-NC-SA 4.0 unless otherwise stated.
Comments





