模型 YAML 配置
模型 YAML 配置文件是Ultralytics 神经网络的架构蓝图。它定义了层与层之间的连接方式、每个模块使用的参数,以及整个网络在不同模型尺寸下的扩展方式。
配置结构
模型 YAML 文件分为三个主要部分,它们共同定义了架构。
参数部分
参数部分规定了模型的总体特征和缩放行为:
# Parameters
nc: 80 # number of classes
scales: # compound scaling constants [depth, width, max_channels]
n: [0.50, 0.25, 1024] # nano: shallow layers, narrow channels
s: [0.50, 0.50, 1024] # small: shallow depth, standard width
m: [0.50, 1.00, 512] # medium: moderate depth, full width
l: [1.00, 1.00, 512] # large: full depth and width
x: [1.00, 1.50, 512] # extra-large: maximum performance
kpt_shape: [17, 3] # pose models only
nc
设置模型预测的类别数。scales
定义复合缩放因子,调整模型深度、宽度和最大通道,生成不同尺寸的变体(纳米级到超大型)。kpt_shape
适用于姿势估计 模型。它可以[N, 2]
用于(x, y)
关键点或[N, 3]
用于(x, y, visibility)
.
减少冗余 scales
字段 scales
参数可以让你从一个基础 YAML 生成多个模型尺寸。例如,当您加载 yolo11n.yaml
,Ultralytics 读取基数 yolo11.yaml
并应用 n
缩放因子 (depth=0.50
, width=0.25
)来制造纳米变体。
nc
和 kpt_shape
取决于数据集
如果您的数据集指定了不同的 nc
或 kpt_shape
因此,Ultralytics 会在运行时自动覆盖模型配置,以匹配数据集 YAML。
主干和头部架构
模型架构由主干(特征提取)和头部(特定任务)两部分组成:
backbone:
# [from, repeats, module, args]
- [-1, 1, Conv, [64, 3, 2]] # 0: Initial convolution
- [-1, 1, Conv, [128, 3, 2]] # 1: Downsample
- [-1, 3, C2f, [128, True]] # 2: Feature processing
head:
- [-1, 1, nn.Upsample, [None, 2, nearest]] # 6: Upsample
- [[-1, 2], 1, Concat, [1]] # 7: Skip connection
- [-1, 3, C2f, [256]] # 8: Process features
- [[8], 1, Detect, [nc]] # 9: Detection layer
层规范格式
每一层都遵循一致的模式: [from, repeats, module, args]
组件 | 目的 | 实例 |
---|---|---|
从 | 输入连接 | -1 (上一页)、 6 (第 6 层)、 [4, 6, 8] (多输入) |
重复 | 重复次数 | 1 (单人)、 3 (重复 3 次) |
模块 | 模块类型 | Conv , C2f , TorchVision , Detect |
参数 | 模块参数 | [64, 3, 2] (通道、内核、步长) |
连接模式
字段 from
字段可在整个网络中创建灵活的数据流模式:
- [-1, 1, Conv, [64, 3, 2]] # Takes input from previous layer
- [[-1, 6], 1, Concat, [1]] # Combines current layer with layer 6
- [[4, 6, 8], 1, Detect, [nc]] # Detection head using 3 feature scales
图层索引
图层索引从 0 开始。-1
= 上一层),而正指数则通过其位置参考特定层。
模块重复
字段 repeats
参数创建更深的网络部分:
- [-1, 3, C2f, [128, True]] # Creates 3 consecutive C2f blocks
- [-1, 1, Conv, [64, 3, 2]] # Single convolution layer
实际重复次数将乘以模型尺寸配置中的深度缩放因子。
可用模块
模块按功能分类,并定义在Ultralytics 模块目录中。下表按类别列出了常用模块,源代码中还有更多可用模块:
基本操作
模块 | 目的 | 来源 | 参数 |
---|---|---|---|
Conv |
卷积 + 批量规范 + 激活 | conv.py | [out_ch, kernel, stride, pad, groups] |
nn.Upsample |
空间上采样 | PyTorch | [size, scale_factor, mode] |
nn.Identity |
直通运行 | PyTorch | [] |
复合块
模块 | 目的 | 来源 | 参数 |
---|---|---|---|
C2f |
2 次卷积的 CSP 瓶颈 | block.py | [out_ch, shortcut, expansion] |
SPPF |
空间金字塔集合(快速) | block.py | [out_ch, kernel_size] |
Concat |
通道连接 | conv.py | [dimension] |
专业模块
模块 | 目的 | 来源 | 参数 |
---|---|---|---|
TorchVision |
加载任何火炬视觉模型 | block.py | [out_ch, model_name, weights, unwrap, truncate, split] |
Index |
从列表中提取特定tensor | block.py | [out_ch, index] |
Detect |
YOLO 检测头 | head.py | [nc, anchors, ch] |
完整模块列表
这只是可用模块的一个子集。有关模块及其参数的完整列表,请访问模块目录。
高级功能
集成 TorchVision
TorchVision 模块可将任何TorchVision 型号作为主干进行无缝集成:
from ultralytics import YOLO
# Model with ConvNeXt backbone
model = YOLO("convnext_backbone.yaml")
results = model.train(data="coco8.yaml", epochs=100)
backbone:
- [-1, 1, TorchVision, [768, convnext_tiny, DEFAULT, True, 2, False]]
head:
- [-1, 1, Classify, [nc]]
参数细目:
768
:预期输出通道convnext_tiny
:模型结构 (可用型号)DEFAULT
:使用预先训练的权重True
:移除分类头2
:截断最后 2 层False
:返回单一tensor (非列表)
多尺度功能
将最后一个参数设置为 True
以获得多尺度检测的中间特征图。
特征选择索引模块
在使用输出多个特征图的模型时,索引模块会选择特定的输出:
backbone:
- [-1, 1, TorchVision, [768, convnext_tiny, DEFAULT, True, 2, True]] # Multi-output
head:
- [0, 1, Index, [192, 4]] # Select 4th feature map (192 channels)
- [0, 1, Index, [384, 6]] # Select 6th feature map (384 channels)
- [0, 1, Index, [768, 8]] # Select 8th feature map (768 channels)
- [[1, 2, 3], 1, Detect, [nc]] # Multi-scale detection
模块分辨率系统
了解Ultralytics 是如何定位和导入模块的,这对定制至关重要:
模块查询过程
Ultralytics 在以下方面采用了三层系统 parse_model
:
# Core resolution logic
m = getattr(torch.nn, m[3:]) if "nn." in m else getattr(torchvision.ops, m[4:]) if "ops." in m else globals()[m]
- PyTorch 模块:以
'nn.'
→torch.nn
命名空间 - 火炬视觉业务:以
'ops.'
→torchvision.ops
命名空间 - Ultralytics 模块:所有其他名称 → 通过导入的全局名称空间
模块导入链
标准模块可通过 tasks.py
:
from ultralytics.nn.modules import ( # noqa: F401, E501
SPPF,
C2f,
Conv,
Detect,
# ... many more modules
Index,
TorchVision,
)
自定义模块集成
修改源代码
修改源代码是集成自定义模块的最通用方法,但可能比较麻烦。要定义和使用自定义模块,请按照以下步骤操作:
-
定义模块 在
ultralytics/nn/modules/block.py
:class CustomBlock(nn.Module): def __init__(self, c1, c2): super().__init__() self.layers = nn.Sequential(nn.Conv2d(c1, c2, 3, 1, 1), nn.BatchNorm2d(c2), nn.ReLU()) def forward(self, x): return self.layers(x)
-
在软件包级别公开模块 在
ultralytics/nn/modules/__init__.py
:from .block import CustomBlock # noqa makes CustomBlock available as ultralytics.nn.modules.CustomBlock
-
添加到进口 在
ultralytics/nn/tasks.py
:from ultralytics.nn.modules import CustomBlock # noqa
-
处理特殊参数 内
parse_model()
在ultralytics/nn/tasks.py
:elif m is CustomBlock: c1, c2 = ch[f], args[0] # input channels, output channels args = [c1, c2, *args[1:]]
-
在模型 YAML 中使用该模块:
# custom_model.yaml nc: 1 backbone: - [-1, 1, CustomBlock, [64]] head: - [-1, 1, Classify, [nc]]
-
检查 FLOP,确保前传正常:
from ultralytics import YOLO model = YOLO("custom_model.yaml", task="classify") model.info() # should print non-zero FLOPs if working
配置示例
基本检测模式
# Simple YOLO detection model
nc: 80
scales:
n: [0.33, 0.25, 1024]
backbone:
- [-1, 1, Conv, [64, 3, 2]] # 0-P1/2
- [-1, 1, Conv, [128, 3, 2]] # 1-P2/4
- [-1, 3, C2f, [128, True]] # 2
- [-1, 1, Conv, [256, 3, 2]] # 3-P3/8
- [-1, 6, C2f, [256, True]] # 4
- [-1, 1, SPPF, [256, 5]] # 5
head:
- [-1, 1, Conv, [256, 3, 1]] # 6
- [[6], 1, Detect, [nc]] # 7
TorchVision 主干网型号
# ConvNeXt backbone with YOLO head
nc: 80
backbone:
- [-1, 1, TorchVision, [768, convnext_tiny, DEFAULT, True, 2, True]]
head:
- [0, 1, Index, [192, 4]] # P3 features
- [0, 1, Index, [384, 6]] # P4 features
- [0, 1, Index, [768, 8]] # P5 features
- [[1, 2, 3], 1, Detect, [nc]] # Multi-scale detection
分类模型
# Simple classification model
nc: 1000
backbone:
- [-1, 1, Conv, [64, 7, 2, 3]]
- [-1, 1, nn.MaxPool2d, [3, 2, 1]]
- [-1, 4, C2f, [64, True]]
- [-1, 1, Conv, [128, 3, 2]]
- [-1, 8, C2f, [128, True]]
- [-1, 1, nn.AdaptiveAvgPool2d, [1]]
head:
- [-1, 1, Classify, [nc]]
最佳做法
建筑设计技巧
从简单开始:在定制之前,先从经过验证的架构开始。使用现有的YOLO 配置作为模板,逐步修改,而不是从头开始。
逐步测试:逐步验证每次修改。每次添加一个自定义模块,并在进行下一步修改前验证其是否有效。
监控频道:确保连接层之间的通道尺寸一致。输出通道 (c2
)必须与输入通道 (c1
)的下一层。
使用跳过连接:利用 [[-1, N], 1, Concat, [1]]
模式。这些连接有助于梯度流动,并使模型能够结合不同尺度的特征。
规模适当:根据计算限制选择模型比例。使用纳米 (n
)的边缘设备,小(s
)来平衡性能,而更大比例尺 (m
, l
, x
),以达到最高精度。
性能考虑因素
深度与宽度:深度网络通过多个转换层捕捉复杂的层次特征,而宽度网络则在每一层并行处理更多信息。根据您的任务复杂度来平衡这两者。
跳过连接:在训练过程中改善梯度流,实现整个网络的特征重用。在更深的架构中,它们对防止梯度消失尤为重要。
瓶颈区块:降低计算成本,同时保持模型的表现力。模块,如 C2f
在保持特征学习能力的同时,使用的参数比标准卷积少。
多尺度功能:对于检测同一图像中不同大小的物体至关重要。使用具有不同尺度多个检测头的特征金字塔网络 (FPN) 模式。
故障排除
常见问题
问题 | 原因 | 解决方案 |
---|---|---|
KeyError: 'ModuleName' |
未导入模块 | 添加到 tasks.py 进口 |
通道尺寸不匹配 | 不正确 args 规格 |
验证输入/输出通道兼容性 |
AttributeError: 'int' object has no attribute |
参数类型错误 | 检查模块文档,了解正确的参数类型 |
模型无法建立 | 无效 from 参照 |
确保存在引用图层 |
调试技巧
在开发定制架构时,系统调试有助于及早发现问题:
使用身份识别头进行测试
用 nn.Identity
以隔离骨干网问题:
nc: 1
backbone:
- [-1, 1, CustomBlock, [64]]
head:
- [-1, 1, nn.Identity, []] # Pass-through for debugging
这样就可以直接检查主干输出:
import torch
from ultralytics import YOLO
model = YOLO("debug_model.yaml")
output = model.model(torch.randn(1, 3, 640, 640))
print(f"Output shape: {output.shape}") # Should match expected dimensions
模型架构检查
检查 FLOPs 计数并打印出每一层也有助于调试自定义模型配置的问题。对于一个有效的模型,FLOPs 计数不应为零。如果为零,则可能是前向传递出了问题。运行一个简单的前向通滤波应该可以显示出遇到的确切错误。
from ultralytics import YOLO
# Build model with verbose output to see layer details
model = YOLO("debug_model.yaml", verbose=True)
# Check model FLOPs. Failed forward pass causes 0 FLOPs.
model.info()
# Inspect individual layers
for i, layer in enumerate(model.model.model):
print(f"Layer {i}: {layer}")
逐步验证
- 从最简单的开始:先用最简单的架构进行测试
- 逐步增加:逐层增加复杂性
- 检查尺寸:验证通道和空间尺寸的兼容性
- 验证缩放:使用不同的模型比例进行测试 (
n
,s
,m
)
常见问题
如何更改模型中的类的数量?
设置 nc
参数,以匹配数据集的类数。
nc: 5 # 5 classes
我可以在模型 YAML 中使用自定义骨干网吗?
可以。您可以使用任何支持的模块,包括 TorchVision 骨干模块,或者定义您自己的自定义模块,然后按照自定义模块集成中的说明导入。
如何根据不同尺寸(纳米、小型、中型等)对模型进行缩放?
使用 scales
部分 来定义深度、宽度和最大通道的缩放因子。当您加载带有缩放比例附加到文件名的基础 YAML 文件时,模型将自动应用这些缩放比例(例如:......)、 yolo11n.yaml
)。
什么是 [from, repeats, module, args]
格式是什么意思?
该格式规定了每个图层的构建方式:
from
:输入源repeats
:重复模块的次数module
:图层类型args
:模块的参数
如何排除通道不匹配错误?
检查一层的输出通道是否与下一层的预期输入通道相匹配。使用 print(model.model.model)
来检查模型的结构。
在哪里可以找到可用模块及其参数的列表?
查看 ultralytics/nn/modules
目录下 的所有可用模块及其参数。
如何在 YAML 配置中添加自定义模块?
在源代码中定义模块,如源代码修改所示导入模块,并在 YAML 文件中引用模块名称。
能否使用自定义 YAML 中的预训练权重?
是的,您可以使用 model.load("path/to/weights")
来加载预训练检查点的权重。不过,只有匹配层的权重才能成功加载。
如何验证我的模型配置?
使用 model.info()
来检查 FLOPs 计数是否不为零。一个有效的模型应该显示非零的 FLOPs 计数。如果是零,请按照 调试技巧 找到问题所在。