为什么你的检测/分割模型涨不上去:从 Bad Case 开始,而不是从注意力模块开始
前言
很多项目到了瓶颈期,大家第一反应往往是:
更换Backbone
增加注意力模块
引入新的Neck结构
尝试最新论文模型
这些方法并非无效,但在实际工程中,性能瓶颈往往首先来自数据、目标尺度、特征分辨率、标注质量和训练策略,而非模型结构本身。
但实际工程中,大部分性能问题并不是因为模型缺少某个注意力机制,而是因为根本没有分析模型到底错在哪里。
正确流程应该是:
训练模型
↓
收集Bad Case
↓
分析错误规律
↓
定位瓶颈
↓
针对性修改
而不是:
训练模型
↓
换模块
↓
再训练
↓
再换模块
而不是直接进行模型堆叠。
第一部分:目标检测任务
第一步:收集 Bad Case
训练结束后,先在验证集或测试集上完整推理。
把以下样本全部保存:
漏检(FN)
真实存在目标,但模型没检测出来。
常见表现:
小目标漏检
远距离目标漏检
遮挡目标漏检
低对比度目标漏检
例如:
GT: Person
Pred: None
误检(FP)
真实不存在目标,但模型检测出来。
常见表现:
相似物体误判
复杂背景误判
夜间场景误判
例如:
GT: None
Pred: Person
定位错误
检测到了目标,但框偏差很大。
常见表现:
框偏大
框偏小
框中心偏移
例如:
IoU < 0.5
建立如下目录:
badcase/
├── miss/
├── false_positive/
└── localization/
然后逐张查看。
第二步:寻找规律
不要看十张。
至少看:
100~300张
你会发现错误往往是成批出现的。
例如:
现象1:小目标基本全漏
表现:
无人机车辆
交通标志
遥感目标
PCB缺陷
大量漏检。
原因通常是:
目标太小
↓
特征图分辨率不足
↓
目标信息消失
例如:
输入:
640×640
目标:
12×12
映射到:
P3(stride=8)
12 / 8 = 1.5
目标只剩1~2个特征点。
此时:
增加改进模块
几乎解决不了问题。
更有效的方法:
增加P2检测头
提高输入分辨率
切图训练
现象2:远距离目标漏检
表现:
近处车辆检测正常
远处车辆大量漏检
本质仍然是:
有效目标尺寸过小
优先考虑:
1024输入
1280输入
Tile推理
而不是换改进模块。
现象3:遮挡目标漏检
表现:
半个人
半辆车
部分缺陷
原因:
训练样本不足
解决方案:
Copy-Paste
Mosaic
Occlusion Augmentation
现象4:特定类别始终效果差
表现:
Person 95%
Car 94%
Helmet 70%
首先检查:
类别数量是否平衡
标注是否一致
类别定义是否明确
很多时候根本不是模型问题。
第三步:检测任务常见问题与解决方案
| 现象 | 优先排查 |
|---|---|
| 小目标漏检 | P2、输入尺寸、切图 |
| 远距离漏检 | 输入分辨率 |
| 遮挡漏检 | 数据增强 |
| 类别混淆 | 数据标注 |
| 框偏移严重 | Label质量 |
| 夜间效果差 | 数据分布 |
| 误检严重 | 负样本不足 |
第二部分:图像分割任务
分割任务的主要误差来源
相比检测任务,分割任务对空间信息更加敏感。
常见错误包括:
漏分
目标区域未被分割出来。
过分
背景被错误划入目标区域。
边界误差
目标主体正确,但轮廓不准确。
结构断裂
细长结构无法连续预测。
第一步:收集 Bad Case
除了看指标:
mIoU
Dice
Pixel Acc
更重要的是直接看预测Mask。
保存:
GT Mask
Pred Mask
Overlay
逐张分析。
第二步:寻找规律
现象1:小目标全部漏分
例如:
小缺陷
小病灶
小器件
原因:
目标经过Resize后太小
例如:
原图:
1024×1024
训练:
640×640
目标:
16×16
Resize后:
10×10
最终Mask:
10 / 8 ≈ 1.25
已经接近不可分割状态。
解决方案:
提高输入尺寸
切图训练
高分辨率Decoder
现象2:细长结构断裂
例如:
裂纹
道路
血管
电线
表现:
预测结果断断续续
原因:
下采样过多
解决方案:
减少Stride
保留浅层特征
UNet Skip Connection
现象3:边界粗糙
表现:
主体正确
边缘很差
解决方案:
Boundary Loss
PointRend
HRNet
高分辨率解码器
现象4:小孔洞大量出现
表现:
Mask内部全是洞
原因:
噪声
训练不足
类别边界模糊
解决方案:
后处理
CRF
Morphology
更多训练数据
第三步:分割任务常见问题与解决方案
| 现象 | 优先排查 |
|---|---|
| 小目标漏分 | 输入分辨率 |
| 裂纹断裂 | 下采样倍率 |
| 边界粗糙 | Decoder设计 |
| 孔洞过多 | 后处理 |
| 某类效果差 | 数据分布 |
| 过拟合 | 数据增强 |
| 泛化差 | 数据质量 |
第四部分:一个工程师应该优先看的东西
很多项目的收益排序通常是:
数据质量
>
Bad Case分析
>
输入分辨率
>
数据增强
>
训练策略
>
模型结构
>
注意力模块
而很多人的实际顺序却是:
注意力模块
>
注意力模块
>
注意力模块
>
数据
这也是为什么经常出现:
CBAM → SE → CA
折腾三个月,
最后提升:
+0.2%
而一次正确的Bad Case分析后:
增加P2检测头
提高输入尺寸
切图训练
可能直接获得:
+3% ~ +10%
的收益。
结论
检测和分割任务中,最重要的能力不是“会堆模块”,而是“会看错误”。
真正有效的工程流程是:
训练
↓
收集Bad Case
↓
找规律
↓
定位原因
↓
针对性修改
↓
验证效果
先回答:
“模型为什么错?”
再回答:
“模型应该怎么改?”
否则大概率只是从一个注意力模块换到另一个注意力模块,而没有解决真正的问题。