YOLOv8之C2f模块——与YOLOv5的C3模块对比

文章对比了YOLOv8中的C2f模块和YOLOv5中的C3模块,两者在初始化参数、源码实现及结构上的差异。C2f模块默认不使用shortcut,而C3模块则默认使用,但两者的shortcut位置在网络结构中相同。C2f设计灵感来源于C3和ELAN,旨在轻量级网络中增强梯度流信息。

一、源码对比

  YOLOv8完整工程代码下载:ultralytics/ultralytic
  C2f模块源码在ultralytics/nn/modules.py下,源码如下:

class C2f(nn.Module):
    # CSP Bottleneck with 2 convolutions
    def __init__(self, c1, c2, n=1, shortcut=False, g=1, e=0.5):  # ch_in, ch_out, number, shortcut, groups, expansion
        super().__init__()
        self.c = int(c2 * e)  # hidden channels
        self.cv1 = Conv(c1, 2 * self.c, 1, 1)
        self.cv2 = Conv((2 + n) * self.c, c2, 1)  # optional act=FReLU(c2)
        self.m = nn.ModuleList(Bottleneck(self.c, self.c, shortcut, g, e=1.0) for _ in range(n))

    def forward(self, x):
        y = list(self.cv1(x).chunk(2, 1))
        y.extend(m(y[-1]) for m in self.m)
        return self.cv2(torch.cat(y, 1))

    def forward_split(self, x):
        y = list(self.cv1(x).split((self.c, self.c), 1))
        y.extend(m(y[-1]) for m in self.m)
        return self.cv2(torch.cat(y, 1))

  YOLOv5的完整工程代码下载:ultralytic/yolov5
  C3模块源码在models/common.py下,源码如下:

class C3(nn.Module):
    # CSP Bottleneck with 3 convolutions
    def __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):  # ch_in, ch_out, number, shortcut, groups, expansion
        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)  # optional act=FReLU(c2)
        self.m = nn.Sequential(*(Bottleneck(c_, c_, shortcut, g, 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))
  • C2f模块和C3模块的对外接口保持一致,都是(ch_in, ch_out, number, shortcut, groups, expansion),方便在yolov5中直接调用C2f模块。
  • C2f模块默认不使用shortcut连接,C3模块默认使用shortcut连接,但二者在网络结构中shortcut的位置无差别,即都是在Backbone中使用shortcut连接,在Head中不使用shortcut连接,代码的调用格式有差别。

二、结构图对比

在这里插入图片描述

图2-1 C3模块结构图

在这里插入图片描述

图2-2 C2f模块结构图
  • C2f模块参考了C3模块以及ELAN的思想进行的设计,让YOLOv8可以在保证轻量化的同时获得更加丰富的梯度流信息。
### C3K2C2F的技术差异分析 #### 技术背景概述 C3K2 和 C2F 是两种不同的模块设计方法,在目标检测领域中被广泛研究和应用。两者均致力于提升模型性能,同时降低计算复杂度和内存消耗。然而,它们的设计理念和技术实现存在显著差异。 --- #### 设计理念对比 - **C3K2** C3K2 结合了深度可分离卷积(Depthwise Separable Convolution, DWConv)以及在线卷积重参数化(OREPA)技术[^4]。其核心在于通过重新定义卷积操作的方式,减少训练过程中的时间和空间开销,从而在保持高性能的同时简化模型架构。 - **C2F** C2F 更加注重多尺度特征提取的能力。它通常采用跨层连接机制(Skip Connection)或者注意力机制(Attention Mechanism),以增强不同层次特征图之间的交互效果[^2]。这种设计使得网络能够在较小的计算代价下捕获更多的上下文信息。 --- #### 计算复杂度比较 - **C3K2 的计算复杂度** 使用深度可分离卷积后,C3K2 的计算复杂度从 \( O(C_{\text{in}} \cdot C_{\text{out}} \cdot K^2 \cdot H \cdot W) \) 下降到 \( O(C_{\text{in}} \cdot K^2 \cdot H \cdot W + C_{\text{in}} \cdot C_{\text{out}} \cdot H \cdot W) \)[^3]。这意味着相比于传统卷积方式,C3K2 能够大幅削减参数量并加速推理过程。 - **C2F 的计算复杂度** C2F 主要依靠轻量化策略来控制整体资源占用情况。尽管引入了额外的操作步骤用于融合高低分辨率数据流,但由于采用了高效的聚合函数形式,因此总体上不会带来过多负担[^2]。 --- #### 应用场景适配性 - 对于实时性强的应用场合而言,比如自动驾驶辅助系统或是视频监控等领域,则更适合选用像 C3K2 这样经过优化后的版本;因为后者不仅具备较高的精度指标而且运行效率也相当可观。 - 如果项目需求侧重于精准捕捉物体边界轮廓或者是处理细粒度分类任务的话,那么基于 C2F 构建出来的解决方案可能会更加理想一些,因为它擅长挖掘局部区域内的细微差别特性[^1]。 --- ```python # 示例代码展示如何集成 C3K2YOLOv11 中 import torch.nn as nn class C3K2(nn.Module): def __init__(self, in_channels, out_channels): super().__init__() self.dw_conv = nn.Conv2d(in_channels=in_channels, out_channels=in_channels, kernel_size=3, padding=1, groups=in_channels) self.pw_conv = nn.Conv2d(in_channels=in_channels, out_channels=out_channels, kernel_size=1) def forward(self, x): x = self.dw_conv(x) x = self.pw_conv(x) return x ``` --- #### 总结评价 综上所述,无论是从理论层面还是实际部署角度来看,C3K2 和 C2F 各自拥有独特的优势所在。具体选择哪一种取决于最终产品的功能定位及其所处环境的具体约束条件等因素综合考量之后再做决定最为妥当。
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

晓shuo

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

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

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

打赏作者

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

抵扣说明:

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

余额充值