YoloV11源码解读
1、环境搭建下载yolov11源码https://gitee.com/shuyanRTX/yolov12同时包含v11的配置组件通用下载yolov11模型文件YOLO11 Models by Ultralytics下载yolo11x.pt安装netron用来可视化模型文件。编写代码import netron import time model_name rD:\workspace\github\yolov12\assets\models\yolo11x.pt netron.start(model_name) while True: time.sleep(1)运行程序可以看到整个网络结构点击Sequential可以看到右边的INPUTS - _modules的所有模块信息去重后为ultralytics.nn.modules.conv.Convultralytics.nn.modules.block.C3k2ultralytics.nn.modules.block.SPPFultralytics.nn.modules.block.C2PSAtorch.nn.modules.upsampling.Upsampleultralytics.nn.modules.conv.Concatultralytics.nn.modules.head.Detect接下来部分参考文档YOLOv11改进大全卷积层、轻量化、注意力机制、损失函数、Backbone、SPPF、Neck、检测头全方位优化汇总_yolov11改进方向-CSDN博客2、基础知识1组件功能Conv2d卷积层负责提取图像的局部特征比如边缘、纹理、形状BatchNorm2d批量归一化让训练过程更稳定、更快避免模型学偏SiLU激活函数给特征添加非线性让模型能学复杂规律避免神经元躺平2Conv2d的构造函数torch.nn.Conv2d( in_channels, # 必填 out_channels, # 必填 kernel_size, # 必填注意与上表不同PyTorch 无默认值 stride1, padding0, dilation1, groups1, biasTrue, padding_modezeros, # 可选 reflect, replicate, circular deviceNone, dtypeNone )各个参数的含义参数是否必填默认值通俗解释in_channels✅ 是无输入特征图的通道数如 RGB 图片为 3上一层的输出通道数out_channels✅ 是无卷积核的数量即输出特征图的通道数想要提取多少种特征kernel_size✅ 是无卷积核的大小可填int如3表示 3×3或tuple如(5,3)表示高 5 宽 3决定感受野范围stride❌ 否1卷积核滑动步长。1时输出尺寸不变配合 padding1会下采样宽高缩小padding❌ 否0在输入四周补零的行/列数。可填int或tuple也可填same需 PyTorch 1.9来保持输出尺寸与输入一致dilation❌ 否1膨胀系数控制卷积核各点之间的间距。1时在不增加参数量下扩大感受野空洞卷积groups❌ 否1分组卷积数。groups1为普通卷积groupsin_channels时为深度卷积每个通道独立卷积可大幅减少参数量bias❌ 否True是否添加可学习的偏置项。若后面接 BatchNormBN通常设为False因为 BN 会抵消偏置的作用padding_mode❌ 否zeros填充方式可选zeros补零、reflect反射、replicate复制边缘、circular循环device/dtype❌ 否None指定张量所在的设备CPU/GPU和数据类型一般由框架自动推断无需手动设置输入输出尺寸计算公式非空洞卷积3SiLU层公式4Bottleneck瓶颈结构输入 (256通道) ↓ [压缩] 中间层 (128通道) ← 在这里处理特征 ↓ [扩展] 输出 (256通道)为什么叫Bottleneck因为中间层通道数较少像瓶颈一样。5深度可分离卷积它是一种将标准卷积分解为两步的轻量化卷积技术旨在大幅降低模型参数量和计算量但是又实现了相近的特征提取能力是移动端和嵌入式设备上部署深度学习模型的关键技术。它的核心思想是将标准卷积的“通道间融合”和“空间上提取”两步分开执行逐通道卷积对输入的每个通道单独使用一个卷积核进行空间特征提取逐点卷积使用1*1卷积核将上一步各通道的输出在深度方向上进行加权组合生成新的特征图6标准卷积和深度可分离卷积的工作流程1任务目标输入一张5*5*3的特征图高5宽5通道数3输出一张3*3*4的特征图高3宽3通道数4约束使用3*3卷积核步长1无填充2标准卷积一步到位卷积核配置4个3*3*3的核最后一个3为每个核的深度输入通道数3计算逻辑每个核在输入图上滑动每次同时覆盖3个通道的3*3区域27个值相乘相加得1个数。4个核各扫一遍生成4张3*3图卷积核总参数量4*(3*3*3)108一句话空间和通道同时融合一步出结果3深度可分离卷积分两步走第一步逐通道卷积只管空间卷积核配置3个3*3*1的核每个核深度1只负责1个输入通道计算逻辑红核对红通道绿核对绿通道蓝核对蓝通道各自独立扫一遍输出仍是3个通道空间尺寸变为3*3中间结果3*3*3卷积核参数量3*(3*3*1)27第二步逐点卷积只管通道混合卷积核配置4个1×1×3的核空间只覆盖1个点深度3计算逻辑站在中间特征图的每个像素上把3个通道的数值加权求和得到1个数。4个核生成4张3×3图。最终结果3×3×4参数量4 × (1×1×3) 124类比标准卷积就像全科医生一次问诊同时检查五官和内科效率高但人力成本贵参数多。深度可分离就像专科门诊先让眼科、耳科、内科医生分别检查逐通道再把三份报告汇总给主治医师综合判断逐点卷积。虽然流程长了但每个医生只需精通一个领域总人力成本大幅下降。5代码实现torch.nn没有提供现成的可分离卷积的接口参考实现如下class DepthwiseSeparableConv(nn.Module): def __init__(self, in_channels, out_channels, kernel_size3, stride1, padding1): super().__init__() # 1. 深度卷积groupsin_channels不混合通道 self.depthwise nn.Conv2d(in_channels, in_channels, kernel_size, stride, padding, groupsin_channels) # 2. 逐点卷积1x1卷积混合通道 self.pointwise nn.Conv2d(in_channels, out_channels, 1) def forward(self, x): return self.pointwise(self.depthwise(x))7深度卷积深度卷积和深度可分离卷积的关系深度可分离卷积深度卷积逐点卷积1*1卷积。所以深度卷积就是逐通道卷积每个通道单独配置一个卷积核各通道间无信息交流。核心特性深度卷积仅能提取空间位置/结构信息无法提取语义信息。原因在于它被强制隔离了通道间的交互只能感知单通道内局部像素的排列趋势如边缘朝向、纹理疏密、灰度起伏而无法组合多通道特征形成高阶物体概念。语义信息的生成依赖于后续的1*1逐点卷积完成跨通道组合。所以深度可分离卷积深度卷积编码空间位置逐点卷积构建语义特征81*1卷积1*1卷积在像素点上用一组加权系数把几十个通道融合成几个新通道。融合得多就是升维融合得少就是降维但不管怎么融合原本分散在各通道里的信息都被整合在了一起即跨通道融合了。9MaxPool2d池化概念MaxPool2d是在一个输入数据上滑动的窗口。这个窗口每次会覆盖一个小区域然后只保留这个区域里的最大值其他信息则被丢弃。通过在整个输入上滑动这个窗口最终得到一个尺寸更小、但保留了最主要特征的输出。函数定义torch.nn.MaxPool2d( kernel_size, # 池化窗口大小int或tuple (H, W) strideNone, # 滑动步长默认为kernel_size padding0, # 填充大小int或tuple默认0 dilation1, # 窗口内元素间距默认1 return_indicesFalse, # 是否返回最大值索引用于MaxUnpool2d ceil_modeFalse # 输出尺寸是否向上取整默认向下取整 )输入输出尺寸计算公式非空洞卷积与conv一致。10感受野感受野Receptive Field在卷积神经网络中指的是输出特征图Feature Map上的一个像素点在原始输入图像上映射回的空间区域大小。通俗来说就是输出层的这个点“看到了”输入层的多大范围。如果某个点的感受野是13x13意味着这个像素的值是由输入图像中13x13区域的像素数据共同计算出来的它“管”着这么大一片区域。感受野的计算逻辑RF当前层的感受野大小初始输入层的11Upsample上采样上采样的核心目标将低分辨率的特征图放大到更高分辨率这在图像分割、超分辨率等任务中很常见。它主要通过插值算法来“无中生有”地计算出新增像素点地值。函数定义torch.nn.Upsample( sizeNone, # 目标输出尺寸tuple (H, W)与scale_factor二选一 scale_factorNone, # 放大倍数float或tuple与size二选一 modenearest, # 插值算法可选 nearest/bilinear/bicubic 等 align_cornersNone, # 角点对齐仅对 bilinear 等线性模式有效 recompute_scale_factorNone # 是否重新计算缩放因子通常保持默认 )输入输出逻辑Upsample就是“我说多大就多大size”或“输入多大我就成倍扩多大scale_factor”简单直接没有Conv2d那种复杂的padding、stride计算。3、Conv模块1概念Conv模块是基础的卷积单元也就是CBS模块Conv2d BatchNorm2d SiLU2结构4、C3k2模块1概念C3k2是一个“智能特征提取器”它可以根据配置选择使用简单模式Bottleneck或者复杂模式C3k来提取图像特征。2简单模式结构c3kFalse)输入图像 ↓ [分割成两部分] ↓ ↓ 直接传递 经过Bottleneck处理n次 ↓ ↓ [合并两部分] ↓ 输出特征特点轻量级模型参数少计算快适合移动设备3复杂模式结构c3kTrue1、工作原理 输入图像 ↓ [分割成两部分] ↓ ↓ 直接传递 经过C3k处理n次 ↓ ↓ [合并两部分] ↓ 输出特征 2、C3k内部结构 C3k模块 ↓ [分割成两部分] ↓ ↓ 经过Bottleneck处理 直接传递 ↓ ↓ [合并两部分] ↓ 输出特点参数多特征提取能力强支持可变卷积核大小适合高精度需求4参数配置信息[-1, 2, C3k2, [256, False, 0.25]] │ │ │ │ │ │ │ │ │ │ │ └─ 扩展系数控制仓库大小0.25表示用25%的空间 │ │ │ │ └─────── 模式选择False简单模式True复杂模式 │ │ │ └──────────── 输出通道数最终货物的数量256个 │ │ └────────────────── 模块类型使用C3k2这个工厂 │ └────────────────────── 重复次数这个工厂要运行2次 └────────────────────────── 输入来源-1表示使用上一层的输出1第1个参数表示输入来源-1是上一层其他数字表示使用指定层的输出2第2个参数表示重复次数表示这个模块要重复执行几次。作用增加模型深度提高特征提取能力3输出通道数输出特征图的目标通道数实际输出会经过width缩放缩放的目的是一套代码生成不同体量的模型比如n:0.25\s:0.5\m:0.75\l:1。如果是n则实际为256*0.25644扩展系数控制隐藏层的通道数隐藏通道数输出通道数*扩展系数64*0.25165C3k2中2的含义当c3kTrue时传递给C3k模块的参数n2表示C3k内部包含2个Bottleneck。5、C2PSA模块1概念C2PSAC2 Position-Sensitive Attention它旨在通过引入PSA位置敏感注意力机制来增强特征提取和处理能力。传统的CNN在处理图像时通常对所有位置上的特征一视同仁忽略了不同位置特征的重要性差异。通过自注意力机制模型可以动态地调整不同位置特征地重要性从而更好地捕捉全局和局部信息。C2PSA通过多个PSABlock堆叠实现对空间位置的自适应权重分配每个PSABlock包含多个自注意力机制和前馈网络从而在特征图的不同位置上进行更精细的特征学习兼顾全局与局部信息。2C2PSA结构输入 x (c1) ↓ cv1 1×1 → 分成 a( c ) 与 b( c ) ↓ a 直接保留 ↓ b 经过 n 个 PSABlock 堆叠 ↓ concat(a, b) → 通道 2c ↓ cv2 1×1 → 输出 (c1c2)3PSABlock结构┌─────────────────────────────────────────────────────────────┐ │ 输入特征 x │ └──────────────────────┬──────────────────────────────────────┘ │ ┌──────────┴──────────┐ │ Attention(x) │ ← 自注意力计算 └──────────┬──────────┘ │ ┌───────────┴───────────┐ │ shortcut True ? │ └───────────┬───────────┘ ┌─────┴─────┐ ▼ ▼ ┌────────────┐ ┌────────────┐ │ 相加融合 │ │ 直接替换 │ │ xattn(x) │ │ attn(x) │ └────────────┘ └────────────┘ └─────┬─────┘ ▼ ┌────────────────┐ │ 中间特征 mid │ └────────────────┘ │ ┌──────────┴──────────┐ │ FFN(mid) │ ← 1x1升维 → 1x1降维 └──────────┬──────────┘ │ ┌───────────┴───────────┐ │ shortcut True ? │ └───────────┬───────────┘ ┌─────┴─────┐ ▼ ▼ ┌────────────┐ ┌────────────┐ │ 相加融合 │ │ 直接替换 │ │ midffn │ │ ffn(mid) │ └────────────┘ └────────────┘ └─────┬─────┘ ▼ ┌────────────────┐ │ 输出特征 x │ └────────────────┘结构要点Attention卷积版多头自注意力区别于常规自注意力采用卷积结构实现用于计算不同位置特征之间的关系FFN1*1卷积升维到2c再1*1还原到c第二个卷积无激活用于进一步处理经注意力机制计算后的特征4Attention结构输入 x [B, C, H, W] │ ▼ ┌───────────────────────┐ │ qkv (1×1 Conv) │ 输出通道 C 2×total_qk_dim │ 生成 Q、K、V 的合并 │ └───────────┬───────────┘ │ split ▼ ┌─────┼─────┐ ▼ ▼ ▼ Q K V [B,H, [B,H, [B,H, qk,N] qk,N] dv,N] │ │ │ └──┬──┘ ├──────────────────┐ ▼ │ │ ┌───────────┐ │ │ │ Q^T K │ │ │ │ * scale │ │ │ └─────┬─────┘ │ │ ▼ │ │ ┌───────────┐ │ │ │ Softmax │ │ │ └─────┬─────┘ │ │ │ │ │ └───┬────┘ │ ▼ │ ┌──────────────┐ │ │ V Attn^T │ │ │ 聚合语义信息 │ │ └──────┬───────┘ │ │ │ ▼ ▼ z [B,C,H,W] V重排 [B,C,H,W] │ │ │ ┌─────┴─────┐ │ │ PE (3×3 │ │ │ 深度卷积) │ │ └─────┬─────┘ │ │ └────────┬─────────┘ ▼ 残差相加 () │ ▼ ┌──────────────┐ │ proj (1×1) │ └──────┬───────┘ ▼ 输出 x [B,C,H,W]这里面通过深度卷积来提取位置信息这个技术叫 卷积位置编码。5卷积位置编码概述卷积位置编码CPE采用 3×3 深度卷积groupsdim对特征图进行空间结构编码以替代传统 Transformer 中的正弦或可学习位置编码。其核心思想是利用卷积的局部感受野捕捉像素间的相对排列关系从而隐式编码空间位置信息。为什么深度卷积能编码位置信息局部感受野天然定义“位置”在图像中位置并非绝对坐标而是像素与周围邻居的相对关系。3×3 卷积通过局部感受野感知这种邻域结构输出值天然携带“该像素处于何种局部空间排列”的信息。通道隔离保证“空间纯净”深度卷积groupsdim强制每个通道独立卷积不跨通道混合语义提取出的信息纯粹是空间几何拓扑如边缘走向、灰度起伏而非语义组合。作用于语义特征编码“激活分布”当深度卷积作用于高维特征图v时它编码的是该语义在平面上的空间激活分布——即“什么特征出现在什么位置”等价于传统位置编码的功能。6、SPPF模块1概念SPPF快速空间金字塔池化层Spatial Pyramid Pooling Fast模块是SPP传统空间金字塔池化Spatial Pyramid Pooling模块的优化版本旨在保留多尺度特征提取能力的同时显著提升计算效率。SPP适合需要显示多尺度表示的场景而SPPF更适合实时检测和资源受限的场景。SPPF模块通过串联小池化核如5x5实现等效的大感受野减少计算量并加速推理。SPP同时用3个不同大小的放大镜5x5, 9x9, 13x13观察每个放大镜独立工作SPPF用一个5x5的放大镜连续观察3次每次观察的结果都保存下来最终得到类似的效果但速度更快。2SPP的结构图3SPPF结构4感受野计算假设SPP结构的MaxPool2d的核分别是5、9、13SPPF的MaxPool2d的核是5stride和padding都是1。那么对于SPPF的感受野计算第1次池化后感受野 1 (5-1)*15第2次池化后感受野 5 (5-1)*19第3次池化后感受野 9 (5-1)*113SPPF通过3次小核5x5串联池化累积感受野达到13x13这与SPP中直接使用单次大核13x13池化的感受野范围等价但两者计算方式不同SPPF是逐级递推累积SPP是一次性覆盖7、损失函数1总体框架YoloV11的损失函数由三个核心部分组成分类损失(cls_loss)判断目标属于哪个类别采用多标签二元交叉熵BCE边界框回归损失box_loss)让预测框位置更精准采用CIoU Loss DFL Loss双分支并行置信度损失(obj_loss)判断框内是否真的有物体采用二元交叉熵BCE2分类损失概述让模型回答“框里有什么”并且允许它同时回答多个答案因为一个框里可能有多个东西。传统做法softmax交叉熵softmax会强迫所有类别的概率加起来等于1。这相当于单选题。如果框里同时有“人”和“背包”softmax会让模型在两者之间二选一强行压低另一个的概率导致模型学糊涂了。YoloV11的做法Multi-label BCE多标签二元交叉熵。这套逻辑不要求概率加起来等于1而是让每个类别独立回答“是”或“不是”。具体流程输入模型对每个格子输出一组分数比如80个类别则有80组分数转换把这组分数用Sigmoid函数挨个压成0~1之间的概率真实标签multi-hot比如这个格子有“人”和“背包”那么人的标签是1背包的标签是1其他所有类别都是0损失计算对于“人”这个类别拿预测概率和标签1算一次交叉熵对于“猫”这个类别拿预测概率和标签0算一次交叉熵...把所有类别的误差加起来再求个平均。输出形式[N, C]维度的logitsN为样本数C为类别数经Sigmoid后转为0~1概率损失计算3边界框回归损失包含两个并行分支1.DFL分支预测坐标偏移量的概率分布负责定位精度尤其小目标2.CIoU分支直接回归边界框几何关系负责几何合理性避免形变、重叠1DFL LossDFLDistributed Focal Loss2CIoU LossCIoU Complete IoU Loss公式含义CIoU Loss同时优化三个维度重叠面积IoU、中心点距离第二项、长宽比第三项让预测框在位置、大小、形状上都逼近真实框。4置信度损失置信度损失用于判断预测框内是否真的有物体。公式8、YoloV11整体架构图