以yolov5s模型为例解析ultralytics中模型构建代码

一、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()函数中实现的参数映射:

  1. 配置格式为[from, number, module, args]

    • from:表示输入来自哪一层(-1表示前一层)
    • number:表示该模块重复的次数
    • module:模块类型(如Conv)
    • args:传递给模块的参数列表
  2. 对于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)
  3. 关键点在于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中


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小老大MUTA️

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值