什么是 C2f: YOLOv8 中引入的一种高效特征提取模块
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 激活函数
关键点:
- 输入先通过一个卷积,把通道数和基础尺度准备好。
- 之后特征被“拆成多路”:
- 一路(分支 B)基本保持原始信息或做极轻的变换,起到信息直通 / 残差保留的作用;
- 另一路(分支 A)会被送进一串依次相连的小 Bottleneck / 残差块(A₀→A₁→A₂→…)。每一层都会产生一个新的特征输出。
- 最后把所有这些阶段性中间特征和直通分支特征一起 concat(按通道拼接),得到一大堆“多尺度、多语义”的通道堆叠;
- 再用一层卷积(通常是 1×1 或 3×3)把这些拼接后的通道重新压回到期望的通道宽度,输出给下一层。
如果把所有这个串联-拼接-压缩的过程当成一个整体模块,就是 C2f。
3. C2f 内部的细粒度数据流
我们可以用更接近代码/张量的角度描述:
-
输入 X → Conv1 (通常 1×1 卷积) → 得到 X’
-
把 X’ 分成两份:
- X_a (送到堆叠分支)
- X_b (旁路直通分支)
-
在堆叠分支里,我们依次应用若干轻量残差块(可以是 Bottleneck 结构,包含 1×1 降维 + 3×3 卷积 + 残差加法):
- Y₀ = Bottleneck(X_a)
- Y₁ = Bottleneck(Y₀)
- Y₂ = Bottleneck(Y₁)
- …
- Yₖ = Bottleneck(Yₖ₋₁)
这意味着我们并不是只保留最后一个 Yₖ,而是把中间所有阶段输出都留着当“显式特征”。
-
将 {X_b, Y₀, Y₁, Y₂, …, Yₖ} 在通道维上拼接 concat:
- Concat = Concat(X_b, Y₀, Y₁, …, Yₖ)
-
对 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 的位置,我们可以把几代主干模块排个族谱:
-
CSP / CSPDarknet(YOLOv4)
- Cross Stage Partial(跨阶段部分残差)思想:把特征分成两路,一路走残差堆叠,另一路保持相对原样,最后再合并。这可减少重复计算,又保持梯度流动。
-
C3(YOLOv5 家族)
- 基于 CSP 的 Bottleneck 堆叠;在 PyTorch 化实现里叫 C3,是 YOLOv5 主干/颈部的基本块。它也会做通道分支,但中间特征的保留/聚合方式相对固定,聚合点更单一。

- 基于 CSP 的 Bottleneck 堆叠;在 PyTorch 化实现里叫 C3,是 YOLOv5 主干/颈部的基本块。它也会做通道分支,但中间特征的保留/聚合方式相对固定,聚合点更单一。
-
E-ELAN(YOLOv7)
- Efficient Layer Aggregation Networks 的扩展。更激进地把中间层输出聚合在一起,强调“多分支并行 + 多阶段特征显式收集”。E-ELAN 让网络在不增加很多参数的情况下,仍能扩大有效深度和表达力,推动了 YOLOv7 的精度-速度前沿。

- Efficient Layer Aggregation Networks 的扩展。更激进地把中间层输出聚合在一起,强调“多分支并行 + 多阶段特征显式收集”。E-ELAN 让网络在不增加很多参数的情况下,仍能扩大有效深度和表达力,推动了 YOLOv7 的精度-速度前沿。
-
C2f(YOLOv8 起)
- 可以理解成把 CSP 的分流哲学和 ELAN 的“中间特征显式保留”合体,形成一种既轻量又高梯度流效率的模块。
- C2f 更利于 PyTorch/TensorRT 导出,结构规则、重复性高,易于自动扩展成 n/s/m/l/x 多个模型尺度。
-
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}X∈RH×W×C。C2f 模块做几件事:
- 预卷积降维:
X′=g(X) X' = g(X) X′=g(X)
其中 ggg 是一个卷积 + BN + 激活(通常 SiLU)操作,常用 1×1 卷积来重排通道数。 - 通道分流:
[Xa,Xb]=split(X′) [X_a, X_b] = \text{split}(X') [Xa,Xb]=split(X′)
其中 XaX_aXa 进入可堆叠分支,XbX_bXb 走直通分支(或轻处理)。 - 堆叠残差块:
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(Yk−1)
每个 hih_ihi 是一个轻量 Bottleneck/残差块(卷积-归一化-激活的组合+shortcut)。 - 聚合拼接:
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 - 融合卷积:
Z=f(U) Z = f(U) Z=f(U)
其中 fff 通常是卷积+BN+激活,用来把通道重新压回设定的宽度,得到最终输出 ZZZ。
这个结构的本质是:
- 使用分支和串联堆叠来产生多阶段特征 YiY_iYi;
- 使用 concat 来把所有阶段的特征显式暴露给下一层;
- 使用最后一层卷积 fff 来执行“通道重组”和“信息蒸馏”。
7. C2f 对检测网络的好处(尤其是 YOLO 系列)
- 小目标 / 细节保留:
直通分支(X_b)保留了更原始、细颗粒度的空间信息。检测小目标时,这种精细纹理很关键。 - 高层语义 / 关系建模:
逐步堆叠的残差块 (Y₀→Y₁→…→Yₖ) 会逐渐提取更高级别、更加抽象的语义特征。这对分类决策(“这个框到底是猫还是狗”)非常重要。 - 稳训练:
多阶段特征全部直接参与最后的 concat,意味着梯度能从输出端直接反向流向每个阶段。这在深层主干里可以减少梯度消失问题,让大模型/深模型也能在常规训练超参下稳稳收敛。 - 高性价比:
通过 1×1 降维 + 3×3 局部卷积的轻量瓶颈堆叠,C2f 保持了较低的参数量和 FLOPs,但仍能提供多尺度表达。这对于要在中低算力(Jetson、工业相机盒子)上跑实时检测的 YOLOv8/YOLOv9/YOLOv11 家族来说,尤为关键。 - 结构规整,易导出:
C2f 的形状是规则的卷积+拼接+卷积,不需要花哨的动态图算子,非常容易被 ONNX、TensorRT、OpenVINO 等推理框架解析和加速,实现工业部署。
8. 和后续模块的传承关系
在后续版本(比如 YOLOv11 里提到的 C3k2 / C3k 风格块),可以看到两条延续:
- 还在走“分流+堆叠+concat+融合”的老路,只是把堆叠单元变得更轻,卷积核/通道分配更省,进一步压延迟;
- 逐渐在这些块中插入轻量注意力(例如部分通道走空间注意力/显著性强化,其他通道走原始卷积路径),继续提升特征质量但不增加太多算力。这可以被视为 C2f 思想 + 轻注意力的融合。
换句话说,C2f 是 YOLOv8 时代的“主力拼图块”,后续版本在它的思路上继续进化,去追求更高的能效比(相同比特算力换更多 mAP)。
9. 一句话总结
C2f 是 YOLOv8(以及之后的 YOLO 系列)里用来取代旧式 CSP/C3 模块的核心结构单元。它把输入特征拆成多路,一路保持原始/浅层细节,另一路通过一串小残差块逐步提取更深语义;然后把所有阶段的中间输出通通拼接,再用一个卷积统一融合。
它的好处是:
- 梯度流顺滑,训练稳;
- 特征表达多样(既有细节也有高语义);
- 计算效率高,推理友好;
- 结构规整,易部署。
这就是为什么在 YOLOv8 之后,“C2f 块”几乎成了现代 YOLO 的基因之一。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)