先说结论:2019年的CVPR论文里,目标检测方向并不是在单纯刷新精度榜单,而是把很多“理所当然”的组件重新打开来审问了一年。那段时间我连续啃完主会和若干workshop里和检测相关的文章,最强烈的感受是:大家其实都在围绕三个问题打转——锚框到底该怎么生成、特征金字塔还能不能换一种搭建方式、框回归的损失函数能不能和最终评估指标直接对齐。你现在看到的很多常用技术,比如无锚检测、可搜索特征融合、IoU系列损失,思想源头基本都能在这一年的论文里找到。这篇文章不打算做成论文标题流水账,而是挑几篇影响最大的,把它们到底改了什么、为什么这么改、能用在哪儿讲清楚。它适合刚接触目标检测的初学者,也适合想快速掌握检测器演进脉络的工程师。
1. 2019年这一届检测论文,核心是在质疑什么
1.1 锚框:从“默认配置”变成“被质疑的对象”
在2019年之前,两阶段检测器里,RPN生成候选框时会在每个位置平铺一组预设大小和比例的锚框。这个设计本身很成熟,COCO榜单上刷榜的模型也大多沿用这套逻辑,但问题其实不少。
第一,预设的尺度、比例对数据集敏感。COCO上调好的一组参数,换到遥感、文字检测或者密集小目标场景,效果就会明显变差,你只能重新手工试。第二,大部分锚框和真实目标重叠很低,正负样本严重失衡,训练压力其实被藏在各种采样策略和损失函数里。第三,极端尺度目标下,锚框要么铺得太多导致后处理膨胀,要么稀疏到直接漏检。
2019年那篇 GA-RPN(引导锚框生成)就是在回应这件事。思路很直接:与其在每个位置平铺固定锚框,不如让网络自己预测“哪里应该放锚框”“放到多大合适”。它分成两个分支:位置预测分支输出目标中心概率图,形状预测分支输出每个位置的锚框宽高。训练时用预测出来的稀疏锚框去计算和真实框的IoU,然后做标签分配,整个过程端到端学习。
注意,这篇论文不是彻底抛弃锚框,而是把锚框从超参变成可学习的量。当时无锚检测的想法已经出现,同年前后学术圈已经有无锚检测器直接不要锚框。但GA-RPN两个分支的设计,非常像后来无锚方法里的中心点预测加尺寸回归。从这个意义上看,它是连接两个流派的一座桥,值得反复读。
我在某个超大遥感图检测项目里试过类似思路,把固定锚框换成按目标密度动态生成,最大收益是推理时候选数量能砍掉一大截,NMS的后处理压力明显下降。代价是多了一个分支,训练收敛周期会稍微拉长,前几个epoch的loss曲线会比原来难看一点,需要耐心。
1.2 特征金字塔:从“人手工搭”走向“搜索搭”
检测任务天然要求同时识别大目标和小目标。深度学习里最常用的做法是多尺度特征融合:高层特征语义强,适合大目标;低层特征分辨率高、细节多,适合小目标。
FPN的思路是把高层语义向下逐层融合,让低层的小目标特征也能带上上下文。PANet在FPN基础上多了一条自底向上的路径,把低层位置信息再传回高层。这些结构都是人工设计的,套路基本是“哪层缺什么就补一条路径”。2019年CVPR上的NAS-FPN则换了一个玩法:用搜索算法去找特征融合的结构。
它把“融合操作”抽象成搜索空间,比如两个特征相加、全局池化后再融合,然后让控制器不断生成候选结构,再用子网络在固定训练预算下评估精度,选出最好的拓扑。实验结论是在COCO上实现了比人工设计的FPN变体更高的精度,而且搜索出来的结构里确实出现了多步跨尺度融合,说明人工设计已经快到能力上限了。
读这篇论文,重点不在复现那个搜索过程,而在理解搜索空间是怎么定义的。把feature sum、global pooling这类常见操作组合起来,搜索出的拓扑往往看起来不规则,但精度更好。后来检测骨干网络里的一些稠密连接结构,思路和它有很强的血缘关系。
1.3 框回归损失:从“算位移”到“算几何关系”
检测头最后一件事是回归出精确的框,常用Smooth L1损失来约束偏移量。但这个损失和最终评估指标IoU并不完全对齐。打个比方:位移损失只关心四条边移动了多少,但两个框是否真正贴合,取决于它们的重叠面积,两者并不等价。
GIoU这篇论文把这个“不一致”点破了。它定义了一个新度量:在IoU基础上,再计算最小闭包区域中不属于两个框的那部分面积占比,然后从IoU里减掉。这个惩罚项解决了经典IoU在两个框完全不相交时梯度消失的问题,因为闭包区域能持续提供梯度信号。反过来,当一个框完全包含另一个框时,GIoU又会退化,所以后来才有DIoU、CIoU这些继续补漏洞的工作。
这篇论文的贡献分两层:一层是把框的几何质量直接引入训练目标,另一层是给后续一整套IoU系损失提供了统一框架。你去看后来更精细的框回归损失,几乎都会引用它。
2. 带着问题逐篇拆解:几篇值得反复看的论文
下面按“它想解决什么问题”的角度,把几篇经典论文的机制讲清楚。我不打算翻译摘要,而是拆设计动机和工程价值。
2.1 GA-RPN:锚框不再铺满全图
具体拆开看,GA-RPN有三个关键设计。
第一,位置分支输出物体中心概率图,只有概率高的点才作为锚框中心候选。这相当于先把“哪里可能有目标”筛了一遍,再考虑“怎么放框”。第二,形状分支输出log空间的长宽预测,定义了一个有效采样区域:同一位置上生成的锚框与真实框的IoU要超过阈值才算正样本,这样预测出来的形状天然偏向当前尺度层级。第三,训练是通过feature map上逐位置的IoU来监督形状分支,避免生成一堆和真实目标毫不相干的无效框。
复现时有一个很实际的坑:形状分支的初始化对训练稳定性影响很大。如果初始化分布太宽,前几个epoch生成的框会非常奇怪,可能一片区域全是细长条,导致分类分支也跟着震荡。用原论文的初始化方式,学习率要比常规RPN稍微调低一点,或者加长warmup,能省很多折腾时间。
2.2 Libra R-CNN:把“不平衡”系统性拉平
Libra R-CNN没有提出什么炫酷的新结构,但它的三个贡献全部踩在检测器的痛点上,非常适合工程背景的人先读。
第一个是IoU-balanced Sampling。常规难样本挖掘只按loss排序选负样本,容易让模型被极难样本带偏。IoU-balanced Sampling的思路是先把负样本按IoU区间分组,在每个区间里均匀抽样,保证采样覆盖不同重叠程度的样本,这样模型不会被某一种样本主导。
第二个是Balanced Feature Pyramid。它先把FPN的各层特征缩放到同一尺度并相加,得到一个整合后的特征,再把这个特征回传各层。相比人工设计的逐层融合,这个操作更接近“全局平均背景”的感觉,实现也更简单。
第三个是Balanced L1 Loss。框回归分支的梯度容易被分类分支压制,导致高质量样本对定位的贡献不足。Balanced L1 Loss对平均梯度设了上限,让大梯度难样本不至于淹没高质量样本的梯度。这三个模块都能独立迁移,大部分开源框架里也都有现成实现。
2.3 Grid R-CNN:用热图当空间刻度尺
R-CNN系在得到RoI之后,通常用全连接网络直接回归四个边界偏移。Grid R-CNN换了一种做法:把RoI区域划分为多个格点,用全卷积网络输出每个格点落在目标边界上的概率图,最终的框由这些格点的响应组合出来。
这样做的本质是把定位问题从“全局回归一个向量”变成“逐点投票的空间预测”。对空间信息更敏感,小目标和边界清晰目标的定位精度通常会更好。代价也很明显:计算量更高,候选框数量多的场景推理会变慢。如果你的业务是遥感大图这种十多万候选框的场景,用它要慎重。
2.4 NAS-FPN:把特征融合交给搜索
NAS-FPN既然叫Neural Architecture Search-FPN,核心就是三件事:定义搜索空间、用控制器搜索候选结构、评估后反馈给控制器迭代。
搜索空间里每个cell是一个特征融合操作,输入可以是任意两个层,包括之前搜索生成的层,输出反复叠加,形成特征金字塔结构。评估阶段用固定训练预算训练子网络,返回精度给控制器。最终生成的拓扑里存在不少长距离跳连,这正是人工设计容易忽略的地方:跨层交互的价值可能被低估了。
搜索成本高是这类工作最现实的门槛,在自己机器上从零复现NAS-FPN往往不划算。它的价值更多是产出结构先验,你直接用它搜索出来的结构当neck即可。
2.5 GIoU:损失函数终于瞄着评估指标去优化
GIoU的公式很简洁:GIoU等于IoU减去最小外接闭合区域里不属于两个框的面积占比。两个框不重叠时,IoU为0,但闭合区域能提供梯度;完全包含时,它会退化成接近IoU。
训练时把它写成回归损失:1减GIoU,替换掉原来的Smooth L1分支即可。修改成本很低,这也是它流行开来的重要原因。在很多开源检测框架里,GIoU loss都是现成可选的。实际替换时,我发现它对学习率的敏感度比Smooth L1高一点,建议先用原学习率的0.8倍跑几个epoch观察定位分支的loss,再慢慢加回去。
下面把这一批论文的核心信息整理成一张速查表,方便后面查阅。
| 论文 | 主要解决的问题 | 一句话方案 | 2019年之后的影响 |
|---|---|---|---|
| GA-RPN | 固定锚框超参敏感、数量大 | 让网络预测锚框位置和形状 | 连接两阶段与无锚检测的桥 |
| Libra R-CNN | 检测器训练各环节不平衡 | 采样、特征、损失三项平衡 | 平衡思想被后续检测框架吸收 |
| Grid R-CNN | 回归定位粒度粗糙 | 用格点热图替代直接回归 | 推动了定位分支的精细化设计 |
| NAS-FPN | 手工设计特征融合不可控 | 用搜索找到跨尺度融合拓扑 | 结构搜索在检测器中的典型应用 |
| GIoU | 回归损失与评估指标不一致 | 在IoU基础上加闭包惩罚项 | 后来DIoU/CIoU系列的起点 |
3. 两个容易忽略但很实用的模块
3.1 Mask Scoring R-CNN:给掩膜质量一个分数
如果你的任务涉及实例分割,这篇值得多看一眼。标准的Mask R-CNN存在一个麻烦:分类分支输出的置信度并不能代表mask质量,有时分类分很高,但mask轮廓粗糙,甚至漏掉目标边缘。
Mask Scoring R-CNN就是在Mask分支旁边加了一个MaskIoU预测头,吃进RoI特征和预测出的mask,输出这个mask和真实mask的IoU估计。推理的时候用这个估计去重新调整分类分数。这个模块不大,改造成本也不高,但对实例分割的评测指标提升很直观。做医疗影像分割或者商品轮廓分割这类任务的朋友,很适合从这个思路入手优化结果置信度。
3.2 CARAFE:让上采样也具备感知能力
FPN里特征上采样用的多是最近邻或者双线性插值,操作简单,但对内容一视同仁。CARAFE做的不是插值,而是“内容感知重组”:先用一个小网络预测每个位置对应的重组核,然后对原特征局部加权组合。
它最直观的价值是感受野更大、对内容更敏感。同样是上采样,边缘区域和纹理区域会用到不同的核权重,细节保真度自然会高一些。如果你不想大规模换结构,可以先只把FPN里高层特征上采样这一步替换成CARAFE。我实测下来的感觉是,AP提升可能不算夸张,但框边界会更贴合目标,尤其在细长目标上比较明显。
4. 从论文到工程:哪些技巧可以直接抄
4.1 怎么根据任务挑论文做基线
很多人读论文是每篇都读,读完了不知道该往自己的项目里加什么。这里按任务类型给一个粗略选型表:
| 任务类型 | 优先参考方案 | 依据 |
|---|---|---|
| 通用目标检测,追求精度 | Libra R-CNN + GIoU | 改动有限,训练均衡收益稳定 |
| 小目标、密集目标 | SNIPER或GA-RPN | 多尺度chip策略和稀疏锚框更适合小目标 |
| 实例分割 | Mask Scoring R-CNN | 修正mask与分类置信度失配问题 |
| 算力受限的工业部署 | GIoU + Balanced Feature Pyramid | 尽量不动网络结构,捡能直接在训练侧生效的改动 |
4.2 三个低成本高性价比的修改
第一个是换损失。把BoxHead里的Smooth L1换成GIoU loss,代码量很小,大部分检测框架自带实现,改配置就能完成。建议同时观察定位分支的loss曲线,如果震荡明显,降低回归权重或加长warmup。
第二个是换采样。在RPN阶段用IoU-balanced Sampling替代均匀随机采样,改的是data sampler,不碰网络结构。这个改动对训练稳定性帮助很大,尤其当你的数据集里目标重叠严重时。
第三个是换neck。用Balanced Feature Pyramid替代逐层融合的FPN变体,结构上只是增加了一层全局整合,对已有训练流程的干扰最小。这三个改动互不冲突,可以叠加使用。
4.3 验证效果的实验纪律
从论文到工程,最怕的不是不知道技巧,而是改了没法验证。做消融时一定保持单变量,一次只动一个模块;记录指标时不能只看mAP,还得单独看AP50、AP75和APs,因为很多改进只在小目标或者高IoU阈值下体现价值。固定随机种子,多次运行取均值,这些常规纪律听着啰嗦,但确实能拦住一大半“伪涨点”。
5. 读论文和复现过程中的常见坑
5.1 容易误读的地方
第一,把workshop论文和主会论文混为一谈。CVPR主会和workshop的论文质量差异很大,引用时候要分清楚。
第二,把论文里“涨点”直接等同“你的场景也会涨点”。很多改进是在特定数据集、特定骨干网络下验证的,换到你的业务场景可能不成立。比如NAS-FPN在小数据集上直接移植,效果不一定比人工FPN好。
第三,GIoU在一开始不是万能的。训练早期预测框和真实框多不重叠,闭包惩罚项会提供梯度,但如果不做梯度裁剪,个别极端样本的梯度可能把回归分支带偏。
第四,把结构搜索的成本当成复现的必须步骤。NAS-FPN可以直接用搜索好的结构,不必自己搜。
5.2 一份快速排障速查表
| 现象 | 可能原因 | 建议排查方向 |
|---|---|---|
| 训练loss不降,定位分支不稳 | 回归损失权重过大或初始化不当 | 检查GIoU权重,尝试加长warmup |
| 小目标召回率低 | 特征金字塔多层融合或采样不足 | 参考SNIPER的多尺度chip策略,或改用IoU-balanced采样 |
| mask分数高但mask质量差 | 分类分数和mask质量失配 | 引入MaskIoU头做分数校正 |
| 候选框数量爆炸,NMS太慢 | 固定锚框密度过高 | 参考GA-RPN做稀疏预测 |
| 搜索结构在小数据集上不涨点 | 搜索依赖大数据分布 | 直接用手工FPN变体,换训练策略收益更稳 |
6. 后续演进与我的阅读建议
6.1 这些思想后来去了哪里
2019年这批论文最值得关注的,不是某一个模块本身,而是它们共同确定了一个方向:检测器的各个组件都要“可学习、可对齐、可搜索”。锚框从超参变成预测量,后来无锚检测器直接把锚框取消掉。特征金字塔从手工搭建变成搜索结构,后来Transformer类检测器又把特征交互完全变成注意力机制。回归损失从位移约束变成几何约束,后面DIoU、CIoU在这些基础上进一步精细化。看懂2019年这批论文,就等于拿到了理解后续检测领域演进的一条主线。
6.2 推荐的阅读顺序
给不同基础的朋友两个参考顺序。刚入门的话,建议先从GIoU和Libra R-CNN读起,这两个改动小、可迁移性强,读完能立刻理解训练侧优化的基本逻辑。然后再读GA-RPN和NAS-FPN,这时候你对锚框、特征融合的认知框架已经搭好,读起来会轻松很多。如果是工程经验丰富但时间有限的朋友,直接读Libra R-CNN和GIoU,再把SNIPER的多尺度策略过一遍,基本能满足大多数工业项目的精度优化需求。
最后说点个人感受。我每次重读2019年的这批论文,都会发现当年没注意到的细节。比如GA-RPN里那个形状预测分支,本质上就是一种条件锚框思想,放到后来的查询式检测器里依然能对上号。做检测的人容易追新,但真正耐用的,往往是最朴素的问题定义。如果你现在要搭一套检测基线,我建议先花半天读Libra R-CNN和GIoU,再花一小时看GA-RPN,这几个改起来都不伤筋动骨,但对最终系统精度的影响非常实在。