1. C2f 是什么

C2f 是 YOLOv8 系列(以及后续一些 YOLO 变体)中引入的一种高效特征提取模块,名字常被解释为 “C2-fusion” 或 “C2 with better gradient Flow”。它属于 CSP(Cross Stage Partial,跨阶段部分残差连接)家族的改良版本,用来取代 YOLOv5/YOLOv7 风格的 C3 / BottleneckCSP 模块。

通俗说:C2f 是一个“把输入特征拆多路、依次加工、再把所有中间特征拼回来然后压缩融合”的结构。它的目标是:

  • 强化梯度流(gradient flow),让很深的网络也好训;
  • 提高特征多样性(多分支、多阶段特征同时保留);
  • 降低参数量和计算量(FLOPs),尤其在中小模型里;
  • 保持导出友好(ONNX/TensorRT),适合工业部署。

C2f 最常出现的位置是 YOLOv8 的 Backbone(主干)和 Neck(特征融合颈部)中的主堆叠单元。你可以把它当成 YOLOv8 的“主力积木块”。


2. C2f 的大体结构

先看一个抽象结构图。设输入特征是 X。

在这里插入图片描述

CBS:C = Conv,B = BatchNorm,S = SiLU。也就是:卷积层 (Conv) → 批归一化 (Batch Normalization) → SiLU 激活函数

关键点:

  1. 输入先通过一个卷积,把通道数和基础尺度准备好。
  2. 之后特征被“拆成多路”:
    • 一路(分支 B)基本保持原始信息或做极轻的变换,起到信息直通 / 残差保留的作用;
    • 另一路(分支 A)会被送进一串依次相连的小 Bottleneck / 残差块(A₀→A₁→A₂→…)。每一层都会产生一个新的特征输出。
  3. 最后把所有这些阶段性中间特征和直通分支特征一起 concat(按通道拼接),得到一大堆“多尺度、多语义”的通道堆叠;
  4. 再用一层卷积(通常是 1×1 或 3×3)把这些拼接后的通道重新压回到期望的通道宽度,输出给下一层。

如果把所有这个串联-拼接-压缩的过程当成一个整体模块,就是 C2f。


3. C2f 内部的细粒度数据流

我们可以用更接近代码/张量的角度描述:

  1. 输入 X → Conv1 (通常 1×1 卷积) → 得到 X’

  2. 把 X’ 分成两份:

    • X_a (送到堆叠分支)
    • X_b (旁路直通分支)
  3. 在堆叠分支里,我们依次应用若干轻量残差块(可以是 Bottleneck 结构,包含 1×1 降维 + 3×3 卷积 + 残差加法):

    • Y₀ = Bottleneck(X_a)
    • Y₁ = Bottleneck(Y₀)
    • Y₂ = Bottleneck(Y₁)
    • Yₖ = Bottleneck(Yₖ₋₁)

    这意味着我们并不是只保留最后一个 Yₖ,而是把中间所有阶段输出都留着当“显式特征”。

  4. 将 {X_b, Y₀, Y₁, Y₂, …, Yₖ} 在通道维上拼接 concat:

    • Concat = Concat(X_b, Y₀, Y₁, …, Yₖ)
  5. 对 Concat 再做一个卷积 Conv2(通常 1×1 用于通道融合,或者带 3×3 让它再提炼一下局部空间信息)得到最终输出 Z。

即:
Z=Conv2([Xb,Y0,Y1,…,Yk]) Z = \text{Conv2}([X_b, Y_0, Y_1, \ldots, Y_k]) Z=Conv2([Xb,Y0,Y1,,Yk])
其中 [⋅][\cdot][] 表示通道拼接。

这个收集中间层输出再统一融合的套路,类似于 ELAN / E-ELAN 家族(YOLOv7 里提出的高效层聚合思想),也类似 DenseNet 的“密集连接”精神:保留每个阶段的中间特征,而不是只拿最后一层。


4. 为什么要这样堆?

C2f 的设计解决了三个典型痛点:

4.1 梯度流动(Gradient Flow)

深网络训练时,越后面的层越难把梯度有效地传回前面。如果所有中间特征都在最终 concat 里出现,那么早期的小残差块 (Y₀, Y₁, …) 对最终输出有“直接话语权”,它们的梯度会直接回传,而不会被长链条稀释。

这就像在很长的传话链上,每个人都能直接对老板说话,而不是只能悄悄跟下一个人说,指望消息能一路传到老板耳朵里。

相比之下,传统的层-接-层-接-层结构,最前面几层离最终输出很远,梯度可能在中途衰减。

4.2 特征多样性(Multi-scale / Multi-stage Features)

Concat([X_b, Y₀, Y₁, …]) 相当于把不同“深度级别”的表达并列放在一起:

  • Y₀ 可能更偏局部/低级纹理;
  • Y₅(比如某个后层)可能更偏高语义/抽象概念;
  • X_b 是几乎未破坏的原始信息通道,保存细节。

模型后续就可以自由在这些“老照片+新照片”的堆叠里挑它想要的特征,而不是被迫只依赖“最新那张照片”。

这跟 DenseNet 的思路很像:把不同深度的特征一起当资源池。

4.3 计算效率(Parameter / FLOPs Efficiency)

C2f 利用的是:

  • 小瓶颈块(Bottleneck)重复堆叠,而不是每一层都用大胖卷积;
  • 1×1 卷积先降维、后融合,减少大通道数下的 3×3 卷积开销;
  • 通道分流 + 部分残差,使得不是所有分支都要全算一遍重型操作。

结果:在同等、甚至更高的精度下,C2f 往往能比 YOLOv5 的 C3 模块或 YOLOv4 的 CSPDarknet 模块更省参数、更省算力,尤其是在小中等模型(n/s/m 级别)里性价比明显。


5. 与 CSP / C3 / ELAN / C3k2 的关系

为了看清 C2f 的位置,我们可以把几代主干模块排个族谱:

  1. CSP / CSPDarknet(YOLOv4)

    • Cross Stage Partial(跨阶段部分残差)思想:把特征分成两路,一路走残差堆叠,另一路保持相对原样,最后再合并。这可减少重复计算,又保持梯度流动。
  2. C3(YOLOv5 家族)

    • 基于 CSP 的 Bottleneck 堆叠;在 PyTorch 化实现里叫 C3,是 YOLOv5 主干/颈部的基本块。它也会做通道分支,但中间特征的保留/聚合方式相对固定,聚合点更单一。
      在这里插入图片描述
  3. E-ELAN(YOLOv7)

    • Efficient Layer Aggregation Networks 的扩展。更激进地把中间层输出聚合在一起,强调“多分支并行 + 多阶段特征显式收集”。E-ELAN 让网络在不增加很多参数的情况下,仍能扩大有效深度和表达力,推动了 YOLOv7 的精度-速度前沿。
      在这里插入图片描述
  4. C2f(YOLOv8 起)

    • 可以理解成把 CSP 的分流哲学和 ELAN 的“中间特征显式保留”合体,形成一种既轻量又高梯度流效率的模块。
    • C2f 更利于 PyTorch/TensorRT 导出,结构规则、重复性高,易于自动扩展成 n/s/m/l/x 多个模型尺度。
  5. C3k2 / C3k(YOLOv11 等后续演进)

    • 在后续版本中,有的架构会进一步把 C2f/C3 系列再瘦身,强调小卷积核、多次堆叠、轻量残差,继续压 FLOPs。这可以被视为“C2f 思想的下一代进化”:同样想保留信息流和多级特征,但更狠地挤掉冗余计算。

从这个族谱你可以看出:

  • C2f 是在 YOLOv7(E-ELAN)思路和 YOLOv5(C3/CSP)思路之间的折中:它保留“显式多阶段特征聚合 + 强梯度流”,但努力把它做得更规整、更轻、更适合自动缩放。

6. 数学/张量角度进一步形式化

为了更精确,我们可以把上面描述转成符号。

设输入张量为 X∈RH×W×CX \in \mathbb{R}^{H \times W \times C}XRH×W×C。C2f 模块做几件事:

  1. 预卷积降维:
    X′=g(X) X' = g(X) X=g(X)
    其中 ggg 是一个卷积 + BN + 激活(通常 SiLU)操作,常用 1×1 卷积来重排通道数。
  2. 通道分流:
    [Xa,Xb]=split(X′) [X_a, X_b] = \text{split}(X') [Xa,Xb]=split(X)
    其中 XaX_aXa 进入可堆叠分支,XbX_bXb 走直通分支(或轻处理)。
  3. 堆叠残差块:
    Y0=h0(Xa),Y1=h1(Y0),Y2=h2(Y1),…,Yk=hk(Yk−1) Y_0 = h_0(X_a), \quad Y_1 = h_1(Y_0), \quad Y_2 = h_2(Y_1), \dots, \quad Y_k = h_k(Y_{k-1}) Y0=h0(Xa),Y1=h1(Y0),Y2=h2(Y1),,Yk=hk(Yk1)
    每个 hih_ihi 是一个轻量 Bottleneck/残差块(卷积-归一化-激活的组合+shortcut)。
  4. 聚合拼接:
    U=Concat(Xb,Y0,Y1,…,Yk)∈RH×W×CU U = \text{Concat}(X_b, Y_0, Y_1, \ldots, Y_k) \in \mathbb{R}^{H \times W \times C_U} U=Concat(Xb,Y0,Y1,,Yk)RH×W×CU
  5. 融合卷积:
    Z=f(U) Z = f(U) Z=f(U)
    其中 fff 通常是卷积+BN+激活,用来把通道重新压回设定的宽度,得到最终输出 ZZZ

这个结构的本质是:

  • 使用分支和串联堆叠来产生多阶段特征 YiY_iYi
  • 使用 concat 来把所有阶段的特征显式暴露给下一层;
  • 使用最后一层卷积 fff 来执行“通道重组”和“信息蒸馏”。

7. C2f 对检测网络的好处(尤其是 YOLO 系列)

  1. 小目标 / 细节保留
    直通分支(X_b)保留了更原始、细颗粒度的空间信息。检测小目标时,这种精细纹理很关键。
  2. 高层语义 / 关系建模
    逐步堆叠的残差块 (Y₀→Y₁→…→Yₖ) 会逐渐提取更高级别、更加抽象的语义特征。这对分类决策(“这个框到底是猫还是狗”)非常重要。
  3. 稳训练
    多阶段特征全部直接参与最后的 concat,意味着梯度能从输出端直接反向流向每个阶段。这在深层主干里可以减少梯度消失问题,让大模型/深模型也能在常规训练超参下稳稳收敛。
  4. 高性价比
    通过 1×1 降维 + 3×3 局部卷积的轻量瓶颈堆叠,C2f 保持了较低的参数量和 FLOPs,但仍能提供多尺度表达。这对于要在中低算力(Jetson、工业相机盒子)上跑实时检测的 YOLOv8/YOLOv9/YOLOv11 家族来说,尤为关键。
  5. 结构规整,易导出
    C2f 的形状是规则的卷积+拼接+卷积,不需要花哨的动态图算子,非常容易被 ONNX、TensorRT、OpenVINO 等推理框架解析和加速,实现工业部署。

8. 和后续模块的传承关系

在后续版本(比如 YOLOv11 里提到的 C3k2 / C3k 风格块),可以看到两条延续:

  • 还在走“分流+堆叠+concat+融合”的老路,只是把堆叠单元变得更轻,卷积核/通道分配更省,进一步压延迟;
  • 逐渐在这些块中插入轻量注意力(例如部分通道走空间注意力/显著性强化,其他通道走原始卷积路径),继续提升特征质量但不增加太多算力。这可以被视为 C2f 思想 + 轻注意力的融合。

换句话说,C2f 是 YOLOv8 时代的“主力拼图块”,后续版本在它的思路上继续进化,去追求更高的能效比(相同比特算力换更多 mAP)。


9. 一句话总结

C2f 是 YOLOv8(以及之后的 YOLO 系列)里用来取代旧式 CSP/C3 模块的核心结构单元。它把输入特征拆成多路,一路保持原始/浅层细节,另一路通过一串小残差块逐步提取更深语义;然后把所有阶段的中间输出通通拼接,再用一个卷积统一融合。

它的好处是:

  • 梯度流顺滑,训练稳;
  • 特征表达多样(既有细节也有高语义);
  • 计算效率高,推理友好;
  • 结构规整,易部署。

这就是为什么在 YOLOv8 之后,“C2f 块”几乎成了现代 YOLO 的基因之一。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐