☰
YOLOv5红外小目标检测优化实战:从数据增强到P2检测头
2026/10/19 3:23:55 网站建设 项目流程

红外小目标检测这个方向,前前后后做了大半年。最开始想法很简单:把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,关闭所有额外优化,得到的效果很有代表性:

指标基线实测值
mAP@0.50.43
mAP@0.5:0.950.21
AP(small)0.086
检测概率PD0.61
虚警率FA0.4次/帧

看起来mAP@0.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的特征图。这一步需要修改检测器的结构配置和网络解析逻辑:

  1. 骨干网络输出新增一个低层特征节点(C3后的浅层特征,空间尺寸比默认P3大一倍)。
  2. 在颈部网络做一次自上而下的特征融合时,把浅层特征纳入融合链:先是高层信息向低层传递,再把低层特征自下而上补充回去。
  3. 新增检测头的Anchor数量与原有层级保持一致(每个尺度3个框)。

需要注意,P2特征图的分辨率是160×160,计算量不可忽视。我在P2路径上控制了通道数,不让它进入主干的高通道通路,避免显存和延迟倍增。实际测试下来,加上P2检测头后,小目标AP(small)从0.12提升到0.18以上,效果非常明显。

3.2 注意力模块的选型与放置位置

注意力模块在网络结构里怎么放,决定它是帮手还是捣蛋鬼。我把SE、CBAM、CA(Coordinate 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×3,IoU计算在数值上非常敏感,一个像素的偏移都会导致正样本抖动。最终我最小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×1024,AP(small)提升幅度接近一半。代价是显存占用和推理时间明显增加,所以最终项目里我根据部署设备的算力在640和1024之间做了权衡。

训练超参也做了针对性调整:初始学习率从默认的0.01降到0.003,因为红外数据规模通常小,学习率太大容易过拟合;训练轮数拉到250个epoch,配合EMA(指数移动平均)让模型充分收敛;早停耐心值调大,避免小目标还没收敛就被叫停。

一个容易忽视的坑是Batch Size。如果显卡显存有限,为了上1024分辨率把Batch Size降到2或4,BatchNorm的统计量会变得非常不稳定,深层特征分布抖动剧烈。我建议在Batch Size过小时冻结骨干网络的BatchNorm层,或者改用累积梯度模拟较大Batch,实测能避免很多训练震荡问题。

5. 消融实验复盘:哪些改动真值钱,哪些是白费劲

5.1 逐项叠加的量化结果

我把我认为有价值的改动逐项叠加,每加一项在同一组数据上做完整训练和测试,过程如下:

配置mAP@0.5mAP@0.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,而是虚警率可控、检测率达标、延迟满足要求这三点。很多先进结构刷分很漂亮,但经不住部署环境的严苛考验。在真实项目里,数据质量、结构选择、训练策略和部署优化这几块都不能偏科,任何一块掉链子,整体性能都会受拖累。按这个思路去调参和改结构,哪怕数据形态有变化,你也能很快找到更适合自己场景的那套配置。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询