3. 模型结构解析

做模型剪枝,第一件事是什么?不是调参,不是跑数据。是先把模型结构吃透。

我见过太多人,上来就对着权重文件一顿剪,结果模型直接崩了。为什么?因为他根本不知道哪一层是主干、哪一层是瓶颈、哪一层剪了会断流。

这一章,咱们就把YOLOv11的骨架拆开来看。Backbone、Neck、Head,还有那两个绕不开的模块——C2f和SPPF。我会结合我实际踩过的坑,告诉你哪些地方是剪枝的黄金位置,哪些地方碰都别碰。

3.1 整体架构:三阶段流水线

YOLOv11延续了YOLOv8/v9的经典三段式设计。说白了,就是一条流水线:特征提取 → 特征融合 → 预测输出。

  • Backbone(主干网络):负责从输入图像中提取多尺度特征。输入是3×640×640,输出是三个不同分辨率的特征图。
  • Neck(颈部):负责特征融合。把Backbone输出的浅层细节和深层语义揉在一起,让模型既看得清小目标,也抓得住大目标。
  • Head(头部):负责最终预测。输出边界框、类别概率和置信度。

我个人习惯把这三段比作「眼睛-大脑-嘴巴」。Backbone是眼睛,负责看;Neck是大脑,负责想;Head是嘴巴,负责说。剪枝的时候,眼睛和大脑可以适当精简,但嘴巴最好保持原样——因为输出层的精度太敏感了。

剪枝核心原则:Backbone的深层阶段(P4/P5)和Neck的融合层是剪枝收益最高的区域。Head的检测头尽量不动,或者只做极小幅度的通道缩减。

YOLOv11 三段式架构(Backbone → Neck → Head) Backbone 特征提取 输入: 3×640×640 C2f × N SPPF 输出: P3/P4/P5 Neck 特征融合 FPN + PAN 上采样 / 下采样 C2f 融合层 通道对齐 Head 预测输出 Detect 模块 边界框回归 类别预测 输出: 84×8400 剪枝重点区域:Backbone 深层(P4/P5)和 Neck 融合层 | 谨慎区域:Head 检测头

3.2 Backbone:C2f模块与SPPF模块

Backbone是YOLOv11最核心的部分。它由一堆C2f模块和一个SPPF模块堆叠而成。咱们一个一个说。

3.2.1 C2f模块——跨阶段部分连接

C2f是CSPNet的变体。全称是「Cross Stage Partial with 2 convolutions and f」——嗯,名字有点绕。你只要记住它的核心思想:把输入特征图分成两路,一路直接走,一路经过卷积再走,最后拼起来。

这样做的好处是什么?梯度流更顺畅了。浅层特征能直接传到深层,不会在中间被「稀释」掉。

我的经验:C2f模块中的shortcut连接是剪枝的「保护伞」。如果你剪掉shortcut路径上的通道,模型还能靠残差连接兜底。但如果你剪掉主路径上的关键卷积层,模型精度会断崖式下跌。我在一次剪枝实验中,把C2f中间层的通道从256砍到128,mAP只掉了0.3%;但把输入层的通道砍到128,mAP直接掉了4.2%。

C2f模块的内部结构大致如下:

输入特征图 (c_in, h, w)
    │
    ├── Conv (c_in → c_hidden, 1×1)  ← 压缩通道
    │
    ├── Split → 一路直接传递
    │         └── Bottleneck × n  ← 核心计算
    │
    └── Concat (所有分支拼起来)
    │
    └── Conv (c_out, 1×1)  ← 恢复/调整通道
    │
    输出特征图 (c_out, h, w)

这里有个关键参数:n(Bottleneck数量)。YOLOv11的不同版本,n值不一样。n越大,模型越深,计算量越大。

YOLOv11版本 Backbone中C2f数量 典型通道数(P3/P4/P5) Bottleneck数量(n)
YOLOv11n 5 64 / 128 / 256 1, 1, 1, 1, 1
YOLOv11s 5 128 / 256 / 512 1, 2, 2, 2, 2
YOLOv11m 5 192 / 384 / 768 2, 4, 4, 4, 4
YOLOv11l 5 256 / 512 / 1024 3, 6, 6, 6, 6

避坑指南:我曾经在剪枝时,把C2f模块的shortcut路径上的1×1卷积给剪了。结果模型训练时梯度爆炸了。后来才发现,shortcut路径上的卷积虽然参数少,但它承担着「梯度高速公路」的角色。剪它等于把高速公路封了,所有车都挤到乡间小道上——不堵才怪。

3.2.2 SPPF模块——空间金字塔池化

SPPF是SPP(Spatial Pyramid Pooling)的快速版。它的作用是什么?让模型看到不同尺度的上下文信息。

具体做法:用多个不同大小的池化核(5×5、9×9、13×13)对特征图做池化,然后把结果拼起来。这样,模型既能看清局部细节,也能把握全局轮廓。

YOLOv11用的是SPPF,不是SPP。区别在哪?SPPF把三个池化层串起来了,而不是并行。这样计算量更小,但效果几乎一样。

输入特征图 (c, h, w)
    │
    ├── Conv (c → c//2, 1×1)  ← 通道减半
    │
    ├── MaxPool (5×5)  →  分支1
    ├── MaxPool (5×5)  →  分支2 (等效9×9)
    ├── MaxPool (5×5)  →  分支3 (等效13×13)
    │
    └── Concat (所有分支 + 原始特征)
    │
    └── Conv (c_out, 1×1)  ← 通道恢复
    │
    输出特征图 (c_out, h, w)

剪枝建议:SPPF模块的通道数通常比较大(比如1024),但它的计算量相对集中。我个人建议:SPPF的输入输出通道可以剪掉20%-30%,但池化核大小不要动。动了池化核,感受野就变了,模型对目标尺度的适应性会下降。

3.3 Neck:特征金字塔与路径聚合

Neck是YOLOv11的「融合枢纽」。它用了FPN(特征金字塔网络)+ PAN(路径聚合网络)的组合结构。

为什么要搞这么复杂?你想想看:Backbone输出的P3(小特征图,语义强)、P4(中等)、P5(大特征图,细节多)。如果直接拿P5去做预测,小目标根本看不见。如果只拿P3去做预测,大目标又容易漏掉。

Neck的解决方案是:自上而下传递语义,自下而上传递细节。

  • FPN路径(自上而下):P5 → 上采样 → 与P4融合 → 上采样 → 与P3融合。让浅层特征图获得深层的语义信息。
  • PAN路径(自下而上):P3 → 下采样 → 与P4融合 → 下采样 → 与P5融合。让深层特征图获得浅层的细节信息。

Neck中的C2f模块和Backbone中的略有不同。Neck里的C2f更注重「融合」而非「提取」,所以它的通道数通常和输入保持一致,不会做大幅压缩。

我的习惯:剪枝时,我会优先剪Neck中PAN路径上的C2f模块。因为FPN路径负责语义传递,剪多了模型会「变笨」;而PAN路径负责细节补充,适当剪掉一些冗余通道,模型还能保持不错的精度。我在一个检测任务上试过,把Neck中PAN路径的通道剪掉25%,mAP只掉了0.5%,但推理速度提升了18%。

3.4 Head:解耦检测头

YOLOv11的Head采用了解耦检测头设计。什么意思?就是把分类和回归任务分开,用不同的卷积层去处理。

具体来说:

  • 分类分支:输出每个类别的概率。输出维度 = 类别数。
  • 回归分支:输出边界框的坐标(x, y, w, h)。输出维度 = 4。
  • 置信度分支:输出目标存在的概率。输出维度 = 1。

三个分支共享一个公共的卷积层,然后各自接自己的卷积层。这样做的好处是:分类和回归任务不会互相干扰,训练更稳定。

但问题来了——Head的参数占比其实不大。YOLOv11n的Head参数大约只占总参数的10%-15%。所以,剪枝的重点不应该放在Head上。

避坑指南:我曾经为了追求极致的模型大小,把Head的公共卷积层通道从256剪到了128。结果模型推理时,小目标的召回率直接掉了10%。后来我仔细分析才发现,Head的公共卷积层承担着「特征再提取」的任务,通道太少,信息瓶颈就出现了。从那以后,我给自己定了个规矩:Head的通道剪枝幅度不超过10%。

3.5 通道数与计算量分析

做剪枝,你得知道每一层的「分量」。我整理了一张表,把YOLOv11n各部分的通道数和计算量(FLOPs)列出来了。

模块 输入通道 输出通道 FLOPs(G) 参数量(M)
Backbone (P1) 3 16 0.12 0.01
Backbone (P2) 16 32 0.35 0.03
Backbone (P3) 32 64 0.89 0.08
Backbone (P4) 64 128 2.15 0.21
Backbone (P5) 128 256 5.42 0.52
SPPF 256 256 1.83 0.18
Neck (FPN) 256/128/64 128/64/64 3.21 0.31
Neck (PAN) 64/128/256 128/256/256 4.15 0.40
Head 256 84 1.02 0.12
总计 - - 19.14 1.86

从这张表能看出什么?

  • Backbone的P5阶段:FLOPs最高(5.42G),是剪枝的「头号目标」。剪掉20%的通道,能省下1G以上的计算量。
  • Neck的PAN路径:FLOPs也很大(4.15G),而且冗余度较高,适合剪枝。
  • SPPF:虽然FLOPs不算最高,但它的通道数大,剪枝收益也不错。
  • Head:FLOPs和参数量都很小,剪枝收益有限,风险却不低。

剪枝优先级排序:Backbone P5 → Neck PAN → Backbone P4 → SPPF → Neck FPN → Backbone P3 → Head

3.6 本章小结

这一章我们把YOLOv11的骨架拆了个遍。你记住了什么?

  • C2f模块:核心是跨阶段连接,shortcut路径是「保护伞」,别乱剪。
  • SPPF模块:串行池化,通道可剪,池化核别动。
  • Neck:FPN传语义,PAN传细节。PAN路径冗余多,适合剪枝。
  • Head:解耦设计,参数少,剪枝风险高,幅度控制在10%以内。
  • 计算量分析:Backbone P5和Neck PAN是剪枝的「黄金区域」。