YOLOv11 从零开始详解
目标读者:有 Python 基础、刚开始接触目标检测或想理解 YOLO 系列网络结构的小白。
本文重点:模块原理 + 代码思想 + 尺寸/通道计算 + 小例子。
前置知识(你需要知道的最少东西)
- 什么是卷积神经网络(CNN)基础概念:卷积层、BN、激活函数(如 SiLU/LeakyReLU)、上采样(upsample)、拼接(concat)、残差(skip connection)。
- 有基本 Python / PyTorch 使用经验会更好(但理解模块与伪代码也很够用)。
- 理解“特征图大小(H×W×C)”这个表达:H、W 是高宽,C 是通道数。
为什么要读 YOLOv11?简单一句话
YOLOv11 是 YOLO 系列里以“小而精、模块复用、速度与精度折中”为目标的改进版本。理解它能让你掌握如何用模块化思路去复用、裁剪、并改进网络结构,从而方便做工程和写论文。
先把整体结构看清楚(先记住“骨架”)
YOLOv11 的三个大部分(人人都要会):
Backbone(主干)
提取多层级特征(比如 640×640 输入最后输出 3 个尺度的特征图)。
Neck(颈部 / 特征融合)
对不同尺度做上采样与拼接(concatenate),把低分辨率的语义信息和高分辨率的细节融合起来。
Head(检测头)
把融合后的特征映射到最终的预测(边框坐标 + 置信度 + 分类概率)。
简化流程:输入图像 → Backbone 提取多尺度特征 → Neck 上采样 & 融合 → Head 输出预测。
先看几个常用“基元”(模块)——小白必须清楚的几种积木
下面每个模块都尽量用通俗语言讲,并给出伪代码与注释(容易理解)。
CBS(Conv + BN + SiLU/激活)
作用:最基本的卷积块,负责提取局部特征并做归一化与非线性变换。
伪代码(Python 风格,注释非常详细):
# CBS:基本卷积块
def CBS(input):
# conv: 卷积操作(例如kernel=3, stride=1, padding=1)
x = Conv2d(input, out_channels, kernel_size=3, stride=1, padding=1)
# bn: 批归一化,稳定训练
x = BatchNorm2d(x)
# act: 非线性(SiLU/Swish)
x = SiLU(x)
return x
小结:CBS 就是卷积 + BN + 激活,最常见的基础块。
C3 / C2F / C3K2(残差 / 多分支复用结构)
作用:通过重复的小模块并做跳跃连接,提取更丰富、更深的特征;也降低计算重复代码编写。
直观:C3 里包含多个子层(如若干次 CBS 或 Bottleneck),并且有残差连接把输入与输出相加,这样训练更稳定。
PSA(Position-Sensitive Attention) — 重点模块
直观想法:在每个位置上动态地加强或减弱某些通道/空间响应,让网络更关注有用区域(比如目标边缘或关键特征)。
核心点(小白版):
- 输入 XXX(形状 B×C×H×WB\times C\times H\times WB×C×H×W)
- 经过注意力机制后得 F(X)F(X)F(X)(和 XXX 一样的形状)
- 可能有条件跳跃连接(有个参数 AAA 控制是否相加)
伪代码(彻底注释):
def PSA(X, use_skip=True):
# X: 输入特征图 BxCxHxW
# 首先做一个轻量的通道/空间特征提取(例如 1x1 卷积 + 全局池化)
g = Conv1x1(X) # 压缩通道,提取用于生成注意力的基础特征
g_pool = GlobalAvgPool(g) # 池化到每通道的统计量
attn = MLP(g_pool) # 用小的全连接来生成 attention 权重(每通道或每位置)
attn = Sigmoid(attn) # 归一化到 0~1
# 将注意力与原始特征相乘(逐通道或逐位置)
Y = X * attn.reshape_as(X)
# 可选跳跃连接:输出 = X + Y(或直接 Y)
if use_skip:
return X + Y
else:
return Y
要点总结(小白句子版):
- 注意力是“给每个位置/通道分配重要性分数”;
- PSA 可以增强重要的位置/通道,抑制无关信息;
- 常配合残差(X+F(X)X+F(X)X+F(X))使用,训练更稳定。
C2PSA(把 PSA 复用、分支融合起来)
C2PSA 是基于 PSA 的复合模块,适合在保留浅层细节(A 分支)与提取深层语义(B 分支)之间做融合。
流程(简化):
- 对输入做一次卷积,成为中间特征;
- Split(划分)为 A(浅)和 B(深)两路;
- B 路复用若干 PSA(增强深层语义);
- A 与 B 拼接(concat)或相加后再做卷积输出。
伪代码(带注释):
def C2PSA(X):
x1 = Conv1(X) # CV1,初步提取
A, B = SplitChannels(x1) # 划分通道,例如通道一半一半
# B 分支:通过多个 PSA 模块(复用)
for i in range(n):
B = PSA(B)
# 融合 A 和 B
Y = Concat([A, B]) # 将通道拼起来
Y = Conv2(Y) # CV2,整合通道信息
return Y
小白要点:
- Split 后的 A 保留原始细节,B 用来累积更深的语义;
- 复用 PSA 可减少参数同时增深网络表达。
尺寸与通道计算(举例教你算:输入 640×640,卷积、下采样与上采样)
新手常卡在“尺寸怎么变化”的问题,这里把常见情况列清楚:
1. 单个卷积(kernel = K,stride = S,padding = P)
输出高宽计算公式(Hout,WoutH_{out}, W_{out}Hout,Wout):
Hout=⌊Hin+2P−KS⌋+1
H_{out} = \left\lfloor \frac{H_{in} + 2P - K}{S} \right\rfloor + 1
Hout=⌊SHin+2P−K⌋+1
举例:
- 输入 Hin=640H_{in}=640Hin=640,K=3K=3K=3,S=2S=2S=2,P=1P=1P=1(常见的下采样 3×3 stride2)
Hout=⌊640+2∗1−32⌋+1=⌊6382⌋+1=319+1=320 H_{out} = \left\lfloor \frac{640 + 2*1 - 3}{2} \right\rfloor + 1 = \left\lfloor \frac{638}{2} \right\rfloor + 1 = 319 + 1 = 320 Hout=⌊2640+2∗1−3⌋+1=⌊2638⌋+1=319+1=320
2. 上采样(scale ×2)
上采样通常把 H, W * 2(例如 320→640320 \to 640320→640)。在代码里常见用法:nn.Upsample(scale_factor=2, mode='nearest')。
3. 通道缩放(模型尺度,例如 S 模型的通道倍率 0.5)
如果你的原始通道为 C0C_0C0,S 型会将其变为:
CS=round(C0×0.5)
C_{S} = \text{round}(C_0 \times 0.5)
CS=round(C0×0.5)
例如 C0=64⇒CS=32C_0 = 64 \Rightarrow C_S = 32C0=64⇒CS=32。
以一个小的例子把流程串起来(一步步看数据如何流动)
假设输入:640×640×3640 \times 640 \times 3640×640×3(RGB图片)
- 第一层:CBS,stride=2,输出变成 320×320×32320\times320\times32320×320×32(S 模型通道示例)
- 二层:C3 / C2PSA(提取更多特征),输出 160×160×64160\times160\times64160×160×64
- 继续下采样到 80×80×12880\times80\times12880×80×128,再 40×40×25640\times40\times25640×40×256,以此类推(各层数值依模型 config)
在 Neck:将 40×40×25640\times40\times25640×40×256 上采样到 80×80×12880\times80\times12880×80×128,与 Bottle-neck 上来自 80×80×12880\times80\times12880×80×128 的特征拼接 → 再经过若干层卷积得到融合特征 → 送到 Head。
在 Head:对每个尺度做预测(通常三个尺度),每个位置预测 anchors 的边框与类别。
训练与推理中常见的优化与设计思想(小白也要会)
- 深度可分离卷积(Depthwise Separable Conv):把标准卷积分成 depthwise + pointwise,两步完成,能大幅减少参数与计算量,常用于 Head 的分类分支做轻量化。
- 残差 & 跳跃连接:解决梯度消失、加速训练。
- 注意力模块(如 PSA):提高表达力,定位更精准。
- 模块复用(同一模块重复使用):减少代码重复、节省参数又扩深网络表达深度。
一份“学练结合”的小任务(建议小白按步骤练)
- 在本地用 PyTorch 从头实现一个 简单的 CBS + PSA 模块,把一个 128×128×32 的随机张量传入,观察输出形状是否正确。
- 用 YAML 把一个非常小的“toy YOLOv11” 写出来(例如 backbone 只包含两层),然后把模型用
torchsummary打印形状。 - 把 Head 的分类分支换成深度可分离卷积,比较参数量和推理速度差异(可用
torchinfo或简单的sum(p.numel() for p in model.parameters()))。
需要我帮你写第 1 步的 PyTorch 演示代码吗?(我可以直接给你一段带超详细注释的代码,小白也能跑通。)
常见初学者容易出错的地方(以及怎样避免)
- ** confuse channel 和 spatial**:记住 H×W×C 的 C 是通道,不是宽或者高。
- padding/stride 计算错误:每次改变 stride 必须重新计算 spatial 尺寸。
- 忘记 BatchNorm 在训练/推理模式差异:训练时
model.train(),推理时model.eval()。 - 注意力输出维度要和输入对齐:若做通道注意力,生成的权重维度是 CCC;若做空间注意力,生成的是 H×WH\times WH×W。
- 训练时目标/标签格式不对:YOLO 的标签通常是以归一化后中心点 (cx, cy, w, h) 的格式。
推荐的学习路线(逐步练习)
- 先掌握 CBS、简单卷积、BN、激活函数;
- 学会写残差块与 C3 结构;
- 动手实现 PSA(从 channel-wise 注意力开始,再扩展到 spatial 注意力);
- 把 PSA 嵌入一个小型网络,训练一个 tiny 数据集(比如 VOC 的子集);
- 最后阅读 YOLOv11 的配置 YAML、源码注释(弄懂每一层的输入输出)并尝试改动。
小结(再啰嗦两句帮助记忆)
- YOLOv11 的核心在于模块化 + 注意力复用 + 轻量化设计;
- 理解每个模块的输入输出(尺寸与通道)是读懂任何模型的关键;
- 练习:从实现一个简单 PSA 开始,再逐步把它放进 C2PSA,然后把 C2PSA 放进一个 tiny backbone。

2082

被折叠的 条评论
为什么被折叠?



