一、yaml文件
在 ultralytics/cfg/models/v5/yolov5.yaml 文件中,是yolov5模型的整体结构。这部分不详细解释,具体可看YOLOv5源码逐行超详细注释与解读(5)——配置文件yolov5s.yaml_yolov5的超参数配置文件介绍-CSDN博客
二、backbone部分
2.1 conv
第一层
- from=-1: 表示输入来自上一层 c1 3
- number=1: 表示这个模块重复1次
- module=Conv: 表示使用 Conv 模块
- args=[64, 6, 2, 2]: 表示初始化参数列表
- 64: 输出通道数 c2
- 6: 卷积核大小 k
- 2: 步长 s
- 2: 填充 p
Conv模块的定义在:ultralytics\nn\modules\conv.py
class Conv(nn.Module):
def __init__(self, c1, c2, k=1, s=1, p=None, g=1, d=1, act=True):
super().__init__()
self.conv = nn.Conv2d(c1, c2, k, s, autopad(k, p, d), groups=g, dilation=d, bias=False)
self.bn = nn.BatchNorm2d(c2)
self.act = nn.SiLU() if act is True else (act if isinstance(act, nn.Module) else nn.Identity())
def forward(self, x):
return self.act(self.bn(self.conv(x)))
注意这里的args参数是从c2开始传递,c1是通过from确认,具体在ultralytics\nn\tasks.py的parse_models()函数中实现的参数映射:
配置格式为
[from, number, module, args]
:
from
:表示输入来自哪一层(-1表示前一层)number
:表示该模块重复的次数module
:模块类型(如Conv)args
:传递给模块的参数列表对于
Conv
模块,参数映射是这样的:if m in base_modules: c1, c2 = ch[f], args[0] if c2 != nc: # if c2 not equal to number of classes (i.e. for Classify() output) c2 = make_divisible(min(c2, max_channels) * width, 8)
关键点在于
c1 = ch[f]
:
ch
是一个列表,保存了每一层的输出通道数f
是当前层的输入层索引(在第一层中是-1,表示前一层)- 因此
c1
是通过查找前一层的输出通道数来确定的
- 输入: 假设输入图像是 640x640x3
- 输出: 320x320x64 (因为步长为2,所以尺寸减半)
第二层
- from=-1: 输入来自上一层(第一层Conv的输出--64)
- number=1: 重复1次
- module=Conv: 使用Conv模块
- args=[128, 3, 2]:
- 128: 输出通道数 c1
- 3: 卷积核大小 k
- 2: 步长 s
没有填充p
- 输入: 320x320x64 (来自第一层Conv)
- 输出: 160x160x128 (因为步长为2,尺寸再减半)
2.2 c3模块
第三层
- from=-1: 输入来自上一层(第二层Conv的输出)c1
- number=3: 重复3次
- module=C3: 使用C3模块
- args=[128]: 输出通道数为128 c2
C3模块的定义在ultralytics\nn\modules\block.py中
class C3(nn.Module):
def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):
super().__init__()
c_ = int(c2 * e) # hidden channels
self.cv1 = Conv(c1, c_, 1, 1)
self.cv2 = Conv(c1, c_, 1, 1)
self.cv3 = Conv(2 * c_, c2, 1)
self.m = nn.Sequential(*(Bottleneck(c_, c_, shortcut, g, k=((1, 1), (3, 3)), e=1.0) for _ in range(n)))
def forward(self, x):
return self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), 1))
C3
模块是 YOLOv5 中的一个关键组件,它基于 CSP(Cross Stage Partial)架构,包含 3 个卷积层和一个 Bottleneck 模块(通过两个卷积层和 shortcut 连接)堆叠。它的主要作用是通过减少计算量和参数数量来提高模型的效率,同时保持特征提取的能力。
BottleNeck定义在ultralytics\nn\modules\block.py中