目标检测——两阶段与单阶段那场打了十年的仗 📅 2026/7/24 9:45:55 要说视觉识别里哪个方向最卷检测认第二没人敢认第一。语义分割好歹还是像素级的精细活儿检测可是要在整张图里回答有没有、是什么、在哪儿三个问题——框出来还不算还得分类。这事儿你要是让我手动去标一张拥挤的街景图能标到眼瞎让机器做那就是难上加难。检测领域最大的悬案就是两阶段Two-stage和单阶段One-stage到底谁更牛。这场仗打了十年了到现在也没消停而且每隔几年就有人跳出来说终结了结果发现谁也终结不了谁。咱们先从头捋。最早的现代检测框架是R-CNN2014 年 Ross Girshick 那帮人搞出来的。思路粗暴得可爱——先用 Selective Search 在图上挖出两千个候选框Region Proposals然后每个框缩放到固定尺寸分别送进 CNN 提取特征最后用 SVM 分类用线性回归精调框的位置。这方法在当时算是石破天惊但缺点也明显到离谱两千个候选框各跑一遍 CNN一张图处理时间几十秒你让自动驾驶用这个车都绕地球一圈了。于是 Ross 自己都觉得看不下去了第二年甩出了Fast R-CNN。最大改进就是不再对每个候选框单独过 CNN而是整张图只过一次 CNN得到特征图然后在特征图上映射候选框的位置用 RoI Pooling 把不同大小的框统一成固定尺寸的特征向量再接全连接层分类和回归。速度直接提升了一个数量级。但这玩意儿还是有瓶颈——候选框还是 Selective Search 生成的这是 CPU 上的活儿快不起来。紧接着Faster R-CNN横空出世彻底把候选框生成也塞进了神经网络——这就是大名鼎鼎的Region Proposal NetworkRPN。RPN 在特征图上滑动一堆 anchor boxes锚框每个位置输出这里有没有物体的二分类分数和框的偏移量。自此检测真正实现了端到端速度达到了 5-10 FPS精度在 COCO 上成了当时的 SOTA。两阶段检测器的基本范式也定了下来第一阶段 RPN 生成稀疏的高质量候选框第二阶段 RoI Head 对这些候选框做精细分类和回归。两阶段的优势在于先粗筛再细筛候选框质量高精度有保证尤其对小目标友好——因为 RPN 的 anchor 可以设计得密集一些小物体不容易漏掉。但有些人就是嫌两阶段慢于是YOLOYou Only Look Once在 2016 年问世了。这名字取得好只看一眼直接把检测当作回归问题来干——整张图划分成 SxS 的网格每个网格预测 B 个框和对应的类别概率。一张图只过一次 CNN45 FPS 跑起来跟飞一样。但初代 YOLO 的精度惨不忍睹定位误差大得很小目标基本全漏。后来 YOLOv2、v3 一路迭代引入了 anchor boxes、多尺度预测、Darknet 架构精度慢慢追了上来但始终和 Faster R-CNN 有差距。于是学术界就形成了两个阵营两阶段派强调精度单阶段派强调速度。你要是投 CVPR 的检测论文审稿人首先问的就是你在 COCO 上的 AP 是多少至于速度那是工程问题学术圈不关心。这就导致一种畸形——大家拼命堆两阶段的复杂模块精度刷到 50 多 AP 了模型大到几百 MB推理一张图要几百毫秒根本没法落地。转折点出现在 2017 年的 RetinaNet。何恺明他们发现单阶段检测器精度上不去的根本原因不是架构不行而是正负样本极度不平衡——一张图里 anchor 有几万个真正包含物体的正样本可能不到一百个剩下的全是背景负样本。这些海量负样本的 loss 把梯度方向带偏了模型光顾着学如何判断背景根本没精力学如何分辨不同物体。于是他们提出了Focal Loss给易分类的负样本降权给难分类的正样本升权训练时模型被迫聚焦在那些模糊的、难分的样本上。就这么一个 loss 的改动单阶段检测器首次在 COCO 上追平了两阶段的精度还保持了更快的速度。Focal Loss 出来之后两阶段 vs 单阶段的争论才算稍微消停了一点因为大家发现问题的核心不在于是两个阶段还是一个阶段而在于你怎么处理样本不平衡。两阶段天生就不太受这个困扰因为 RPN 已经筛掉了一大批负样本单阶段就得靠 Focal Loss 这类机制来人工纠偏。从那以后检测的演进方向就多元化了。Anchor-Free那一派跳出来说Anchor 这东西就是个历史包袱你得手工设计尺寸、长宽比、密度调参调到怀疑人生。于是 CornerNet 用关键点检测的思路来干——直接预测左上角和右下角两个角点再配对成框。CenterNet 更进一步预测中心点和框的宽高。这类方法在 2019-2020 年火了一阵精度不输 anchor-based而且设计更简洁。但后来大家发现 anchor-free 对中心点偏移特别敏感而且后处理配对那一步也挺耗时并没有想象中那么美好。然后是DETR这玩意儿直接把检测当成了集合预测问题——用 Transformer 的编码器-解码器结构输入图像特征输出一组固定数量的框和类别直接用二分图匹配算 loss。DETR 最大的贡献是彻底去掉了 anchor、NMS 这些手工设计的部件让整个检测 pipeline 变得极其干净。但代价是收敛极慢需要 500 个 epoch 才能训好而且对小目标的检测效果差得离谱因为 Transformer 在高分辨率特征图上的计算复杂度太高DETR 只能用低分辨率特征图小目标的细节全丢了。后来 Deformable DETR 用可变形的注意力机制解决了收敛慢的问题DINO 又把性能拉到了一个新高度。但说句实话Transformer-based 检测器至今在工业界落地还很少——推理太慢了而且部署到嵌入式设备上几乎不可能。你让一个 YOLOv8 跑在手机上都有点吃力更别提 DETR 了。所以你看绕了一大圈工业界现在用得最多的反而还是 YOLO 系列。从 YOLOv5 到 v8 再到 v9Ultralytics 那帮人把工程优化做到了极致——架构不断小改训练策略不断打磨数据增强越来越花推理框架和导出格式支持得极其完善。精度上虽然比不过那些重型的 Transformer 检测器但人家能在 30 FPS 以上稳定运行部署极其方便社区生态极其丰富。这就是工业界的现实——不是所有人都玩得起 A100 的。说到这儿我得吐槽一个现象。现在很多论文里的检测模型在 COCO 上测着 AP 很高但你看它的推理速度从来只用毫秒来报不敢报 FPS因为一报 FPS 就露馅了——可能只有 2 帧。而且他们测速用的是 batch inference一次送 8 张图进去算平均时间。这在实际应用里完全是作弊因为大多数场景是单图流式处理batch 根本堆不起来。真正有价值的检测器是在单卡、单图、FP16 精度下能跑到 30 FPS 以上的那种。刷 AP 这事儿玩玩就行了别当真。再聊两个检测里要命的实战问题。第一个是小目标检测。COCO 里小目标的定义是面积小于 32x32 像素。你想想32x32 在特征图里下采样 32 倍之后就只剩 1 个像素点了什么信息都没了。这就是为什么大多数检测器在小目标上 AP 低得可怜。解决方案无非几条高分辨率输入计算量暴增、多尺度特征融合FPN 那一套、专门在小目标数据上过采样训练。但实话实说没有一个方案能完美解决。有时候物理限制就在那儿像素不够就是不够你算法再强也没法无中生有。第二个是密集场景下的遮挡。一群人有说有笑站在一块儿框叠着框NMS 一搞就容易把真正的物体框给误删了。现在有做NMS-free的用 Transformer 直接输出集合避免了 NMS 带来的误伤但这又回到了算力和收敛的问题上。工程上更务实的做法是调低 NMS 的 IoU 阈值宁可多留几个冗余框也别把真的漏了反正后面还有跟踪模块或者人工确认环节。最后说一句掏心窝子的话——检测这个领域真正卡脖子的不是模型架构而是数据标注的质量。你花了几个月调模型、改 loss、换 backbone最后发现精度上不去了翻开标注数据一看——框歪了 10 个像素、标签标错了 5%、漏标了十几个小物体。这些标注噪声就像鞋里的沙子你模型再强大也跑不快。所以我现在做项目花在审核标注质量上的时间比调模型还多。标注公司给的数据你信不过的必须自己抽检、自己订正。检测的事儿三天三夜说不完但核心就这么几条锚框可以不卷了、Focal Loss 是救星、Transformer 是未来但还不是现在、工业界只认 YOLO、数据质量是命根子。行了下一篇聊实例分割和全景分割Mask R-CNN 之后那叫一个百花齐放又群魔乱舞。