YOLO26小目标检测改进:用SPD-Conv替换下采样卷积实战指南

发布时间:2026/10/18 18:50:40
YOLO26小目标检测改进:用SPD-Conv替换下采样卷积实战指南 上个月我在做航拍画面里的小目标检测项目屏幕上密密麻麻的行人和屋顶设备让默认的YOLO26模型漏检了一大半。最初我以为是训练数据不够或者anchor策略没调对折腾了好几天后来把backbone里所有承担降采样任务的stride2卷积换成SPD-Conv空间深度转换卷积之后小目标的平均精度直接涨了两个多百分点。这篇文章就把那一轮改造的完整思路、实现细节和踩过的坑写出来给正在用YOLO26做小目标检测改进的朋友一个可以直接参考的样本。1. 小目标检测的病灶下采样是如何把目标吃掉的1.1 检测骨干的基本套路现在主流的目标检测模型基本都会把输入图片经过一个不断缩分辨率、扩通道的骨干网络。YOLO26也不例外从输入开始每个Stage由若干个卷积块和一个步长2的下采样卷积组成空间尺寸逐级减半从原始输入到最终特征图通常会缩小32倍。这么设计的目的很明确用更少的空间位置承载更抽象、更具语义的特征好让网络在高层看全局。表面上这套逻辑没问题但每做一次stride2卷积或池化其实就是对空间信息做一次不可逆的压缩。输出特征图上每个像素的计算要覆盖输入上的一个2x2甚至更大的区域对尺寸本身就小的目标来说它可能只占这个2x2区域里的很小一部分。很多教程都在强调感受野越大越好却很少提醒你对小目标来说下采样阶段每走一步特征都在被抹掉的边缘。1.2 一个直观的尺度推演拿常见的输入尺寸举例。假设输入是1024x1024一个行人原图里可能只占16x16像素。经过一次stride2下采样变成8x8第二次变成4x4第三次变为2x2。到这一步信息只剩几个像素再往下采样一次4个像素被并成1个像素如果周边背景比较强这个小目标的响应很容易被背景平均掉。目标原始尺寸1/2下采样后1/4下采样后1/8下采样后1/16下采样后1/32下采样后64x6432x3216x168x84x42x232x3216x168x84x42x21x116x168x84x42x21x1消失8x84x42x21x1消失消失缩到1/8尺度时16x16的目标至少还有2x2像素理论上能定位缩到1/16就只剩一个点基本退化成无法区分的响应再往后完全不可用。对64x64这种中等偏小的目标更残酷1/4尺度后只剩16x16如果目标纹理简单到高层早就混进背景了。1.3 问题真正坏在哪里你可能会说网络不是有FPN/PAN特征融合吗高层下采样信息丢了低层特征还在啊。问题在于低层特征语义较弱而且样本里小目标往往靠得很近低层特征又容易把相邻目标黏成一片。所以单靠FPN补救远远不够真正的解题思路应该回到backbone的下采样路径上想办法少丢信息。这也是我决定换SPD-Conv的直接动机。2. 空间深度转换卷积SPD-Conv原理与实现2.1 空间转换到通道不是压缩只是重排要理解SPD-Conv先理解Space-to-Depth。这个概念最早在超分和交通标志检测里用得比较多做的事非常简单把特征图按2x2的邻域切成四组再把这四组分别放到通道维度上。举个例子一张4x4x3的特征图经过scale2的space-to-depth之后会变成2x2x12。空间分辨率降一半通道数翻4倍但所有像素一个都没丢。这种变换没有可学习参数也不做任何加权平均纯粹是几何重排。它最朴素的意义在于既然下采样注定要缩分辨率那就先把每个空间位置的信息挪到通道维度里保存起来让后面的卷积仍然能访问原来的像素级细节。相比直接用stride2卷积去加权平均它没有把信息抹掉。2.2 SPD-Conv的完整路径SPD-Conv不是单个卷积而是一个两步走的模块通常用于替换网络中某个stride2卷积的位置第一步对输入特征做space-to-depth变换尺度从(H, W, C)变成(H/2, W/2, 4C)。这一步没有参数纯粹是张量重排。第二步在这个4C通道的特征上做一次stride1的标准卷积将通道压缩到期望的输出通道数比如与原始结构保持一致空间尺寸维持H/2不变。注意这里必须用stride1因为降采样已经由space-to-depth完成了卷积不再承担降维任务也就不会因为跨步导致信息漏采。2.3 代码实现下面是一段基于主流深度学习框架Tensor接口的伪代码实现核心逻辑适用于常见框架只要把reshape、permute这类接口换成对应框架的写法即可# 输入 x 的形状: (batch_size, channels, height, width) # 目标: 将空间维度 block_size x block_size 重排到通道维度 def space_to_depth(x, block_size2): B, C, H, W x.shape # 先按行和列切成 block 块 x x.reshape(B, C, H // block_size, block_size, W // block_size, block_size) # 调整维度顺序为: batch, channels, block_row, block_col, new_H, new_W x x.permute(0, 1, 3, 5, 2, 4).contiguous() # 合并通道维度 x x.reshape(B, C * block_size * block_size, H // block_size, W // block_size) return x def spd_conv_block(x, out_channels, kernel_size3): # 1. space-to-depth: 得到 B, 4C, H/2, W/2 x space_to_depth(x, block_size2) # 2. 非步长卷积保持 H/2, W/2 不变 x conv3x3_s1(x, out_channels) # conv bn act return x实际落地时SPDConv模块内部会再做一次通道降维因为space-to-depth后通道数变成原来的4倍如果直接接一层3x3卷积输出256通道参数量和计算量会涨得很厉害。比较稳妥的做法是先用1x1卷积把4C压到2C再用3x3卷积从2C输出到期望通道这样精度损耗很小显存压力却小得多。2.4 为什么对小目标有效信息视角的解释从信息论的角度看普通stride2卷积相当于一次不可逆的降维映射冗余和细节被一起丢弃space-to-depth则是可逆的置换操作信息无损。后面的stride1卷积虽然也是在混合通道、提取特征但它在每个空间位置上都同时看过4C份通道里的全部细节所以网络有机会保留细粒度空间信息。与此同时由于空间分辨率确实减半了高层语义操作依然成立不会破坏YOLO26原本的层级结构。这正是小目标检测最需要的低层细节不丢高层语义照常。3. 把SPD-Conv嵌入YOLO26骨架的完整打法3.1 先定位要改的下采样点打开YOLO26的backbone配置就可以看到除了第一个下采样模块会把输入快速缩小后续每个Stage开头都有一个stride2卷积负责把分辨率进一步减半。要做替换的就是这些位置。一个容易记住的规则凡是承担缩小空间尺寸任务的卷积都可以考虑换成SPD-Conv没有承担下采样任务的3x3卷积不要动否则只会白白增加计算量对小目标没有任何额外收益。特征融合分支里那些上采样或1x1卷积也不要动它们负责通道对齐改了容易出结构错误。3.2 配置文件改造示例以YOLO26常见的yaml风格配置为例改造后backbone可以这样写示意配置具体参数以你自己的模型定义为准backbone: - [-1, 1, Conv, [64, 3, 1]] # stem 卷积保持尺寸 - [-1, 1, SPDConv, [128, 3]] # 替换第一个 stride2 下采样卷积 - [-1, 1, C2f, [128, True, 3]] - [-1, 1, SPDConv, [256, 3]] # 替换第二个 stride2 下采样卷积 - [-1, 1, C2f, [256, True, 3]] - [-1, 1, SPDConv, [512, 3]] # 替换第三个 stride2 下采样卷积 - [-1, 1, C2f, [512, True, 3]]同时要在模型注册表中加入SPDConv的定义让配置文件能够正常解析。SPDConv的参数列表里我习惯写成[输出通道, 卷积核大小]输入通道自动取上一层的输出。因为space-to-depth不会改变输入通道以外的结构所以这里没必要手写输入通道。3.3 最容易踩的两个结构错误第一是空间奇偶问题。space-to-depth要求输入特征图的高和宽都是block_size的整数倍对于常规的YOLO部署尺寸这个问题一般不会出现但如果你用了特殊输入尺寸比如非16倍数的图片等宽高缩放到深层时可能会出现奇数尺寸那时候space-to-depth会直接报错。稳妥的做法是在主干入口做一次整尺寸补边保证所有特征图都是偶数尺寸。第二是通道对齐问题。space-to-depth后中间特征通道会变成4C这个中间状态只存在于模块内部输出通道必须严格对齐后续C2f的期望通道。如果输出通道写错模型加载阶段不会有明显报错但训练到一半会出现维度不匹配。建议先用一个小输入跑一遍forward检查所有层的输出shape。3.4 预训练权重的处理直接把SPD-Conv塞进原有网络最直接的影响是预训练权重没法完全复用因为新增模块没有对应权重原有下采样卷积也被替换掉了。我试过三种处理方式最后稳定使用的是A方案。方案A保留所有未改动层的权重只把新增SPDConv模块的卷积和BN参数随机初始化。缺点是最初几个epoch训练波动大一点但收敛后效果最好。方案B尝试把原stride2卷积的权重按空间块关系重排到SPD模块的卷积里理论上可行但实际中权重语义不完全对得上反而拖累收敛。方案C直接用较小的学习率从头训练整个模型成本太高不建议。所以我的建议是加载YOLO26预训练权重时写一个按shape匹配的加载脚本对不上shape的层自动跳过不要因为一个模块不匹配就把整个backbone都随机初始化。4. 实测对比精度提升多少付出了什么代价4.1 实验环境与超参设置我这边实验用的是一份脱敏后的航拍检测数据包含约8000张图像其中有大量小尺寸目标物体最小约12x12像素。训练分两组Baseline是标准YOLO26实验组是把前三个下采样卷积替换为SPD-Conv。硬件使用单张主流GPU优化器选择常用的权重衰减优化器batch size设为16初始学习率0.001使用EMA训练180轮输入尺寸统一到1024。两组实验用的数据增强策略完全一致包括mosaic、随机旋转、尺度扰动就是为了保证对比只反映结构改动带来的差异。4.2 结果对比以下是验证集上的结果数值做了脱敏处理但相对趋势是真实的方案mAP50mAP50:95小目标AP模型参数量单张推理耗时YOLO26 Baseline51.633.222.4约29M21msYOLO26 SPD-Conv53.835.124.5约34M24ms小目标AP从22.4涨到24.5提升约2.1个点整体mAP50提升2.2个点。推理耗时增加了约3ms参数量增加约5M。这个代价在小目标场景下可以接受因为换来的召回率提升非常明显航拍场景里多检出的那些小目标往往就是实际业务最需要的。4.3 收益来源分析把结果按目标尺寸拆分看会更清楚小目标AP提升最明显中等目标基本持平大目标AP略微下降0.4个点。大目标下降的原因是SPD-Conv在深层保留了太多局部细节网络被这些细枝末节牵扯了一部分表达能力对全局语义的抽象会有轻微干扰。整体权衡下来利远远大于弊。4.4 渐进式替换的消融结果我还分别测试了只替换第一个下采样点、替换前两个、替换前三个、全部替换四种情况。结论是只替换第一个下采样点小目标AP就能提升1.2个点左右性价比最高继续替换第二、第三个增益继续累积但边际收益递减替换到第四个深层下采样点时小目标AP基本不动计算量和显存反而增加。所以实际操作中我建议不要盲目全部替换一般替换前三个下采样点就够了。4.5 速度与显存的代价SPD-Conv不是免费午餐。space-to-depth产生的4C通道中间特征会让激活值显存明显变大我原方案batch size可以开到32替换后单卡只能开到24。实在显存紧张可以用梯度累积或者自动混合精度来解决但这些都属于工程优化不影响精度。5. 踩坑记录与实战调优建议5.1 显存不够怎么办SPD-Conv最大的工程问题就是中间通道膨胀带来的显存压力。解决思路有三个第一在SPD模块内部加1x1瓶颈层把4C先压到2C甚至1.5C显存占用会明显回落第二开启混合精度训练激活值显存几乎减半第三用梯度累积模拟更大的有效batch size防止BN统计量因为batch变小而抖动。5.2 BN统计量不稳定这是我最开始没料到的问题。新加的SPD模块是随机初始化的前几个epoch的输出分布和原网络完全不同导致主干里其他层的BN统计量也被带偏训练初期验证集mAP会长时间在低位震荡。解决方法很简单把学习率预热从默认的3个epoch拉长到10个epoch给新模块足够的时间稳定下来。另外一个技巧是给SPD模块内部的BN层单独设稍大的momentum让统计量更快适应新的特征分布。5.3 不要只盯着总mAP如果你改完模型后只去看总mAP很可能会觉得提升不明显然后误判SPD-Conv无效。因为总mAP会被大目标和中目标主导而小目标数量占比不高时它们的AP变化很难在总指标里体现出来。建议在验证脚本里增加按目标尺寸分组统计的逻辑把检测结果按ground truth的绝对像素尺寸分成小、中、大三类分别计算AP。我习惯的划分是小于32x32算小目标32x32到96x96算中目标其余算大目标。5.4 什么时候不建议用SPD-Conv如果你面临的是纯大目标场景比如车辆检测、行人正面抓拍这类目标往往本身就占几十上百像素下采样丢失的那部分信息基本不影响最终检测结果这时候引入SPD-Conv只会增加参数量和推理耗时。另一个极端是移动端或低算力设备部署模型推理时间每增加1ms都会被放大SPD-Conv的通道膨胀对实时性影响明显这类场景可以只在第一个下采样点轻量替换或者干脆不用。5.5 数据增强先做好结构改进才有效我必须说一句实话SPD-Conv是保真而不是无中生有。它对小目标有效的前提是原始输入中确实保存着小目标的纹理、边缘和颜色信息。如果因为图像压缩、目标过小本身只有4x4像素再怎么改结构也救不回来。所以我的处理顺序是先做mosaic增强、多尺度训练、输入分辨率提升把这些能带来稳定收益的操作都加上再引入SPD-Conv做结构上的叠加。我个人做这轮改造最大的体悟是解决小目标问题不要总想着在输出端加多少层检测头先把骨干网络的下采样环节守住再谈后面的特征融合和优化。SPD-Conv不是银弹但它确实是我在航拍小目标场景里最省事、最有效的一步。如果你也在YOLO26上被小目标折磨不妨先动这一刀。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询