
红外小目标检测这个方向前前后后做了大半年。最开始想法很简单把YOLOv5拉起来配一套红外数据训练、测试、看结果。结果第一次评估就给我上了一课——整体mAP看着还能接受但把结果逐帧点开远处那架无人机根本没框出来散落在复杂背景里的小目标十个能漏掉七个虚警反而多得很。问题不出在模型能不能收敛而是出在一开始就把通用目标检测的套路直接套到了红外小目标上。之所以要写这篇分享是因为红外小目标检测跟常规可见光目标检测是完全两种玩法。目标小到只有几个像素没有颜色和纹理信息背景噪声又大按通用COCO流程去训YOLOv5天然吃亏。如果你也在做类似的事情用YOLOv5做红外场景下的无人机、车辆或工业异常点检测发现模型对小目标的召回率上不去、误检压不下来那这篇文章应该能帮你省下不少试错时间。下面把我实际踩过的坑、验证过的方案、还有最终留下来有效果的改动一次讲清楚。1. 红外小目标检测为什么这么难先认清三个瓶颈1.1 物理与成像限制目标本身“太小、太淡、太糊”小目标检测的第一道坎不是网络结构而是成像环节已经决定了信息量上限。红外焦平面阵列的空间分辨率普遍不高常见的中波红外探测器也就640×512这个级别。一个距离稍远的无人机目标在图像上可能只占3×3到8×8像素。这跟可见光图像里那种几十上百像素的“小目标”完全不是一个概念——那种目标好歹还有轮廓、纹理可以做红外小目标就是一个亮度稍高的斑点连边缘都是模糊的。更麻烦的是信杂比低。大气衰减、探测器噪声、非均匀性校正残留的条纹都会让目标灰度跟背景灰度混在一起。我拿到的一批数据里很多目标在人工标注时都要放大到满屏、逐帧比对才能确认位置有些目标甚至连人眼都很难第一次就看出来。对比度低、尺寸小、背景乱这三个物理限制叠加起来就是红外小目标难做的根本原因。常规目标检测里常说的“多尺度检测”在红外小目标这里其实非常尴尬不是有没有多尺度检测层的问题而是经过几次下采样之后小目标的响应已经被压到几乎为零。你在骨干网络的高层特征图里根本找不到这个目标。1.2 用数据说话直接套用YOLOv5的基线表现我用的训练集来自几个不同场景的红外样本空中背景下的无人机、地面复杂背景中的车辆、以及一些弱对比度的异常发热区域。图像分辨率在640×512到1024×768之间目标实例的尺寸分布非常极端——最大目标约30×30像素最小目标只有4×3像素中位数大约在12×12像素左右。直接把YOLOv5s按默认配置拉起来训练输入640×640关闭所有额外优化得到的效果很有代表性指标基线实测值mAP0.50.43mAP0.5:0.950.21AP(small)0.086检测概率PD0.61虚警率FA0.4次/帧看起来mAP0.5有0.43好像还行但AP(small)只有0.086说明小目标基本没检测到。PD也说明只有六成目标能被捞回来而且是在虚警率已经高到没法实际用的前提下。这种模型拿去做真实场景监控频繁误报、漏掉真目标完全不合格。1.3 选型逻辑为什么还是以YOLOv5为底座来改有人可能会问既然YOLOv5对小目标这么不友好为什么还要继续用我的选择依据很简单工程交付。YOLOv5有成熟的训练流程、数据增强代码、Anchor处理逻辑和量化部署方案Python侧和推理侧代码都是透明可改的这对需要实际落地到嵌入式设备的项目特别重要。换更复杂的新结构可能指标好看但部署适配成本会成倍上涨。所以我把YOLOv5当作一个“可以深度改造的底座”而不是一个开箱即用的成品。后面所有改动都遵循一个原则在不破坏工程闭环的前提下尽量提升小目标感知能力。你可以把YOLOv5想象成一辆量产车原厂调校适合跑通用目标检测但红外小目标这条路路况特殊改装底盘、换轮胎带来的收益比单纯换发动机大得多。2. 数据侧改造先让模型“见够”小目标再谈结构2.1 传统数据增强里的翻车点Mosaic、HSV与Blur很多人拿到红外小目标数据集第一反应就是把YOLOv5自带的Mosaic、HSV、随机仿射等增强全部打开觉得增强越猛越好。但红外小目标场景下这套默认增强有几个明显的坑。第一个坑是Mosaic。YOLOv5的Mosaic会把四张图随机缩放后拼在一起原本就小的红外目标经过缩放后变得更小甚至直接被拼图边界切掉半个或者整个丢掉。我在训练日志里对比过Mosaic开启概率调成1.0时训练集里真正完整保留的小目标数量反而少了很多模型根本没机会见太多完整的小目标AP(small)上不去。第二个坑是HSV增强。红外图本质是单通道灰度图加载进YOLOv5后通常被复制成三通道。这种情况下做Hue和Saturation扰动会导致三个通道出现互不相关的伪彩色偏移相当于人为给灰度图注入了根本不存在的颜色噪声。我试过开着默认HSV跑了一个完整训练结果模型在真实红外图上出现了很多奇怪的彩色边缘误检。第三个坑是Blur模糊类增强。小目标本身只有几个像素再叠加高斯模糊或运动模糊之后目标灰度和背景完全融在一起标注框里的有效特征基本被抹平了。这类增强对中大型目标问题不大但小目标经不起一点模糊。2.2 Copy-Paste目标复制增强解决实例不足的直给办法既然数据里小目标实例数量不够最直接的办法就是“复制粘贴”。我把标注好的小目标抠出来在同类背景区域随机选择位置粘贴同时自动生成新标注框。这样做的直觉很简单让模型在训练时见到更多“特征清晰但尺寸很小”的目标样本而不是靠概率去猜。实现上我在Dataset层加了一个预处理分支从当前batch里随机抽取一些前景目标按原始尺寸粘贴到当前图像的随机位置粘贴位置避开已有标注框和高亮噪声区域。注意粘贴时不要把目标缩小——很多论文里喜欢仿射变换缩放但红外小目标一旦缩小到3×3以下人眼都分不清模型的区分能力也不可能凭空提升。保留原始尺寸的粘贴效果最好。这项改动的收益非常明显AP(small)从0.086提升到0.12左右而且模型对小目标的定位稳定性变好了。代价是训练数据里会出现一些“理想化”目标——背景差别导致目标可能过于清晰。所以我把Copy-Paste粘贴的目标数量限制在每个样本不超过5个优先级始终低于真实标注避免模型被合成分布带偏。2.3 灰度域增强组合比想象中更有效的几个算子红外目标检测真正该关心的增强应该是模仿探测器自身变化。我在实验里留下了一套灰度域增强组合效果比默认的RGB域增强稳定得多亮度抖动模拟自动增益控制引起的整体明暗变化。对比度随机缩放模拟目标与背景温差变化。Gamma校正改变中间灰度区域的梯度让模型学会在非线性映射下区分目标。高斯噪声模拟探测器噪声增强对低信杂比目标的鲁棒性。实际测试中对比度随机缩放和高斯噪声带来的提升最大。高斯噪声看起来会“污染”图像但反而让模型学会在噪声背景中抓取目标的局部峰值特征——这在真实红外图中非常关键。也要注意一个度的问题。高斯噪声的标准差我控制在8到16之间灰度0-255太大会把目标淹没。亮度抖动控制在±15%以内Gamma范围取0.7到1.4。加得太猛模型会欠拟合具体表现就是训练损失降不下去验证集性能反而更差。3. 模型侧轻量改造把感知力压到低层特征3.1 加一级P2浅层检测头小目标特征不再“半路消失”YOLOv5默认的检测头有三层对应步长为8、16、32的特征图分别来自骨干网络的中层、深层和最深层的输出。一个12×12像素的目标在网络里经过32倍下采样之后在特征图上的尺寸还不到1个像素所以最深的检测层对小目标基本无效。即使步长为8的特征图小目标也只占1到2个像素信息非常脆弱。解决方案是在原有检测头前面再加一级浅层检测头P2对应步长为4的特征图。这一步需要修改检测器的结构配置和网络解析逻辑骨干网络输出新增一个低层特征节点C3后的浅层特征空间尺寸比默认P3大一倍。在颈部网络做一次自上而下的特征融合时把浅层特征纳入融合链先是高层信息向低层传递再把低层特征自下而上补充回去。新增检测头的Anchor数量与原有层级保持一致每个尺度3个框。需要注意P2特征图的分辨率是160×160计算量不可忽视。我在P2路径上控制了通道数不让它进入主干的高通道通路避免显存和延迟倍增。实际测试下来加上P2检测头后小目标AP(small)从0.12提升到0.18以上效果非常明显。3.2 注意力模块的选型与放置位置注意力模块在网络结构里怎么放决定它是帮手还是捣蛋鬼。我把SE、CBAM、CACoordinate Attention和SimAM都试了一遍结论是在小目标场景下轻量且能抑制背景激活的注意力模块好用单纯做通道加权的注意力帮助不大。SE模块只在通道维度做全局池化加权适合区分“有没有某个特征通道”但对红外小目标这种空间位置很敏感的问题来说效果有限。CBAM加了空间注意力但在低信杂比的图像上空间注意力图很容易被大片相似背景主导真正目标位置反而没有得到足够权重甚至可能被抑制。我试过在网络深层加CBAM结果AP(small)反而掉了2个点。最后留下的是SimAM模块它基于神经科学能量函数为每个特征图神经元计算权重没有引入额外参数。它对红外小目标的好处在于可以突出局部峰值目标、抑制均匀背景激活而且计算量小、不破坏部署流程。我把SimAM加在骨干网络最后一个Stage之前和检测头之前AP(small)又提升了3个点左右。3.3 Neck融合的小改进不换结构也能提升融合质量YOLOv5默认用PANet做自顶向下和自底向上的特征融合对小目标来说存在一个问题不同层特征融合时权重是固定的默认是直接相加。浅层特征包含精细的空间细节但信噪比低深层特征语义丰富但对小目标几乎没有感知能力。简单相加容易把只存在于浅层的目标信号淹没。我采用了一种更轻量的融合策略在PANet每个Concat位置引入一组可学习的融合权重每次融合前对不同来源的特征做Softmax加权再相加。这个思路不是我的原创类似BiFPN的加权归纳但改动量小很多。核心代码就几行把Concat换成WeightedConcat权重初始化为均值让网络自己学。最终效果是AP(small)再提升约2个点且推理延迟几乎没有增加。模块不是越多越好。加注意力、加深脖子结构边际收益会递减。我最关键的三个结构改动是P2检测头、SimAM注意力、加权特征融合。后面的改动基本都是在这些基础上叠加增强策略和训练优化没有再动网络骨架。4. 训练策略让loss和anchor向小目标倾斜4.1 Anchor重聚类小目标需要自己的默认框YOLOv5有自动Anchor机制训练开始前会在训练集上跑一次K-Means重新聚类Anchor尺寸。但红外小目标数据集的尺寸分布和COCO完全不同默认的聚类结果可能仍然偏大。我在模型配置里明确关闭了自动Anchor自己用训练集真实框的宽高做了一次聚类。我设置的P2到P5四层Anchor大致如下单位像素P2层对应极小目标(3×4)、(5×5)、(6×8)P3层对应(8×10)、(13×14)、(12×20)P4层对应(18×22)、(27×26)、(25×38)P5层对应(39×42)、(51×63)、(70×56)。这套Anchor分布完全朝小目标方向倾斜训练时正样本的匹配数量大幅增加。用默认Anchor训练时大量小目标匹配不到足够正样本模型容易直接忽略它们换完Anchor之后AP(small)提升了2到3个点。这里要注意Anchor并不是越小越好。如果Anchor尺寸小于3×3IoU计算在数值上非常敏感一个像素的偏移都会导致正样本抖动。最终我最小Anchor取了3×4而不是2×2就是不想引入过多数值不稳定。4.2 Box损失函数替换EIoU/SIoU在小目标上的优势YOLOv5默认使用CIoU作为边界框损失。CIoU考虑了重叠面积、中心点距离和长宽比在大中目标上表现很好。但小目标损失存在一个被低估的问题中心点偏移1个像素对真实框占比很大可是CIoU的惩罚项在数值上偏小梯度不够集中。换句话说是“损失的敏感度不够”。我把面积归一化这一维重新思考后替换成了EIoU强调最小外接框对角线距离和宽高差异后来又试了SIoU加入了框角度对齐约束。实际数据是EIoU在AP(small)上提升约1到2个点SIoU在收敛稳定性上更好。最终保留了SIoU。替换方法很简单找到YOLOv5的bbox_iou函数实现把CIoU分支替换为其他IoU变体的实现即可。需要特别留意的是要同时更新损失计算里的梯度回传路径这部分改动要单测验证否则训练损失会变得异常。4.3 输入分辨率与训练超参的联动调整小目标只有几个像素提升输入分辨率是收益最直接的手段之一。我把训练和推理输入尺寸从640×640提升到1024×1024AP(small)提升幅度接近一半。代价是显存占用和推理时间明显增加所以最终项目里我根据部署设备的算力在640和1024之间做了权衡。训练超参也做了针对性调整初始学习率从默认的0.01降到0.003因为红外数据规模通常小学习率太大容易过拟合训练轮数拉到250个epoch配合EMA指数移动平均让模型充分收敛早停耐心值调大避免小目标还没收敛就被叫停。一个容易忽视的坑是Batch Size。如果显卡显存有限为了上1024分辨率把Batch Size降到2或4BatchNorm的统计量会变得非常不稳定深层特征分布抖动剧烈。我建议在Batch Size过小时冻结骨干网络的BatchNorm层或者改用累积梯度模拟较大Batch实测能避免很多训练震荡问题。5. 消融实验复盘哪些改动真值钱哪些是白费劲5.1 逐项叠加的量化结果我把我认为有价值的改动逐项叠加每加一项在同一组数据上做完整训练和测试过程如下配置mAP0.5mAP0.5:0.95AP(small)相对耗时基线 YOLOv5s 6400.430.210.0861.0× Copy-Paste增强0.470.240.121.0× 灰度域增强0.500.250.141.0× P2检测头0.530.280.181.2× SimAM 加权融合0.560.300.211.3× Anchor重聚类 SIoU0.580.320.241.3× 1024输入分辨率0.650.370.291.9×最终方案相比基线在AP(small)上提升了3倍多。这个结果说明红外小目标性能提升基本是一个综合性系统工程任何一个环节单独改变都只能带来几个点的提升但把数据增强、结构、训练策略和分辨率四方面一起优化量变确实会形成质变。5.2 失败的尝试与原因分析不是所有看起来合理的尝试都能带来收益。我在过程中也做了一些无效甚至负优化的改动总结在下面尝试方向结果失败原因加大骨干网络宽度和深度参数增加约40%AP涨不超1个点推理延迟显著上升小目标瓶颈在浅层特征缺失不在高层语义容量所有C3模块都加CBAMAP(small)反而下降空间注意力被低对比度背景主导误导目标定位把Mosaic概率开到1.0AP(small)下降明显Mosaic裁剪和缩放导致小目标在训练中被切断或缩小到不可分辨直接上1280输入mAP再涨但显存不够训练速度骤降一半以上收益边际递减部署端无法承受在所有位置加更多的注意力模块某些位置掉点半到1个点冗余模块干扰了浅层特征的原始信息这些失败的经历有时比成功的改动更有价值。它们在提醒我红外小目标检测本质上不是把模型“能力变强”而是把模型有限的感知能力引导到最关键的信息维度上。5.3 最终方案的部署与量化验证检测模型最终要跑在边缘设备上所以精度提升之后还有一个重要环节量化部署。我用TensorRT做了FP16和INT8量化测试。带P2检测头的模型在FP16量化下精度损失很小AP(small)从0.29掉到0.28左右完全可用。但INT8量化时P2检测分支对量化非常敏感因为小目标的激活值本身就很小很容易在低比特量化时被截断或量化误差放大。解决方法是做逐层敏感度分析找到P2检测分支的卷积层和融合层单独保持FP16精度或者使用Per-Channel量化方式。最终在保证推理速度的前提下精度损失控制在0.5个点以内。这个部署细节很关键很多模型在训练集上看着很强一到边缘设备就掉点严重往往就是低比特量化这一步没有针对小目标做特殊处理。6. 一些给后人的实操建议如果你也是第一次用YOLOv5做红外小目标检测下面几条经验能让你少走很多弯路第一先花两周时间把数据清理和增强做扎实再研究网络结构。红外小目标数据集普遍很小标注质量参差不齐先解决“样本不够、样本不对”的问题任何结构改进都缺少说服力。第二评估指标要看AP(small)和检测概率PD不能只盯mAP。mAP是容易被大中目标带偏的指标。建议在训练每一个epoch时都记录小目标类别的单独曲线这是判断改动是否有效的重要依据。第三优先加P2检测头再去调整Attention和Neck。P2层带来的收益最直接但计算开销也要算进去。如果你面对的是极轻量部署场景不要急着上P2头先用1024分辨率加数据增强能把性价比顶到最高。第四把实验记录完整。每个改动的超参数、数据随机种子、训练时长都记清楚。这类问题往往在一个模型上有效换一个数据分布就不一定灵。没有完整的消融记录网上讨论经验时只会得到一堆互相矛盾的说法。第五不要迷信某一种新模块。注意力模块、新的IoU损失、加权融合这些都不是万灵药。我在实际对比中发现同样的改动在背景单纯的红外数据上提升明显而背景一杂乱某些模块就会失效。正确的做法是把它们当作工具箱里的备选方案哪个数据上有效就在哪个数据上用哪个前提是有完整的对比实验支撑。这个方向后续还能扩展的内容很多比如把改进后的模型作为教师网络用半监督方式利用海量的无标注红外数据来进一步提升或者针对小目标设计更合适的匹配策略减少正样本匹配时的随机性。不过这些都是后续的话题了先把上面这套改动跑通你的红外小目标检测基线应该已经比默认YOLOv5强出一个台阶了。最后再说一点个人的体会红外小目标检测的工程落地最终看的不是榜单上的mAP而是虚警率可控、检测率达标、延迟满足要求这三点。很多先进结构刷分很漂亮但经不住部署环境的严苛考验。在真实项目里数据质量、结构选择、训练策略和部署优化这几块都不能偏科任何一块掉链子整体性能都会受拖累。按这个思路去调参和改结构哪怕数据形态有变化你也能很快找到更适合自己场景的那套配置。