☰
目标检测二十年:从手工特征到端到端学习的范式革命
2026/10/14 11:23:30 网站建设 项目流程

同一张图摆在面前,2004年要做目标检测,得写几百行C++、调一堆参数、在单核CPU上跑一两分钟出结果;2016年再干这件事,PyTorch里敲十几行代码,GPU上一秒出结果,精度还高出几个量级。这两个时代的分水岭,就是深度学习对计算机视觉的全面接管。目标检测这二十年,本质上是“特征”两个字被彻底重写的过程——从人手工设计特征,到机器自己学特征。这篇文章我把这条线完整捋一遍,重点讲清楚每个阶段的核心思想、为什么当时的设计长那样、又为什么会被迭代掉。如果你是刚入门CV的、或者做过检测但只背过模型名字不知道来龙去脉的,这篇文章应该能帮你把整个技术版图串起来。

1. 前深度学习时代:滑动窗口与手工特征的高成本游戏

目标检测的起点不是深度学习,甚至不是机器学习,而是一连串工程化的暴力搜索。在2012年之前,所有检测器的基本工作流只有三件事:窗口怎么生成、特征怎么描述、分类器怎么判断。后面那些花哨的模型,基本都是在给这三件事做优化。

1.1 Viola-Jones:用积分图和级联把检测推到实时

2001年提出的Viola-Jones检测器,是第一个真正意义上能实时跑的人脸检测方案。它的思路今天看依然很聪明:既然目标在图像里的位置和大小未知,那就在所有位置、所有尺度上穷举窗口,逐窗口判断“是人脸还是非人脸”。

这个思路最核心的两个创新,一个是积分图,一个是级联分类器。普通图像要算一个窗口的特征得反复读取像素,积分图把任意矩形区域的像素和变成四次数组查表,复杂度O(1)。另一个是级联,它让绝大多数窗口在早期就被快速丢弃,只有极少数长得像目标的窗口才会走完整个分类链。整个检测器里包含几千个决策桩,排前面的负责“粗筛”,越往后越苛刻。这就好比在几十万人里找人,先按性别分、再按年龄分、再按身高分,每一层淘汰掉大量无关项,最终留下的候选才做精细判定。

有一件事我必须提:Viola-Jones训练用的特征是从一个巨大的特征池里用Adaboost自动选出来的,不是设计者一根一根画出来的。这个“让算法自己挑特征”的思想,其实是后来深度学习“特征学习”的雏形。只不过当时特征池再大,底层还是人类预先定义好的矩形模板,表达力有限,换个复杂场景就很吃力。

1.2 HOG+SVM:局部梯度方向才是更鲁棒的表象

2005年提出的HOG特征,是继VJ之后又一个里程碑。HOG的直觉很简单:图像里物体的形状,不靠单个像素的亮度值,而靠局部区域里梯度方向的统计分布。你把一个64x128的行人窗口切成一个个小格子(cell),每个格子里统计梯度方向直方图,再在更大的块(block)里做归一化,拼起来就是一个3780维的向量。

这个向量配合SVM分类器,在当年的行人检测上称得上降维打击,因为它对手光照变化和轻微形变都相当鲁棒。但代价也很直观——特征靠人设计,窗口靠滑动,一个典型的多尺度HOG检测器,对一张VGA分辨率图像做全图扫描,大概要评估几万到几十万个窗口,每个窗口都要抽取一次高维特征。这也是为什么当年跑一次检测动辄好几秒,所谓“实时”基本是没法实时的。

我在2010年前后做过一个车牌识别的小项目,用的就是这套思路:HOG提特征、线性SVM分类、滑动窗口扫多尺度。当时最大的痛苦不是分类精度,而是调窗口步长和尺度因子。步长太大目标会漏检,步长太小窗口爆炸;尺度因子取1.05则金字塔层数太多,取1.2则中间尺度的目标直接错过。这些参数全是试出来的,换个场景就得重新调。今天的年轻人完全不用经历这一步,我有时候觉得是幸运,有时候也觉得错过了很多理解检测本质的机会。

1.3 DPM:把“零件”概念引入检测,传统方法的绝唱

DPM(Deformable Part Model)在2008年到2012年之间统治了PASCAL VOC目标检测排行榜。它的核心突破在于承认目标是有结构的,一个行人可以拆成头、躯干、四肢等Parts,每个Parts有各自的HOG模板,同时用弹簧形变模型约束Parts之间相对位置的合理性。

这个设计的行业价值在于:它第一次让检测器不仅回答“这里有没有目标”,还隐式地回答了“目标大致是什么姿态”。在当年的VOC 2007上DPM的mAP能到33%左右,看着不高,但已经是传统方法的绝对巅峰了。

DPM后来也做了大量工程优化,比如特征金字塔缓存、级联式推理、多组件混合模型来覆盖不同视角。即使这样,它的速度依然是个大问题。一个标准的DPM检测器处理一张图需要数秒到数十秒,工程落地场景几乎只适用于离线检测。而且DPM的零件定义和形变模型结构,本质上还是人工设计的,扩展到一个新类别就要重新设计语义部件,可扩展性太差了。2013年以后,这类方法在排行榜上再没抬起头来。

2. 深度学习把“特征工程”改写成“特征学习”

2012年AlexNet在ImageNet图像分类上碾压式夺冠,这件事当时在CV圈造成的冲击,不亚于一次范式革命。很多人第一反应是“分类变准了”,但真正蕴含的隐喻是:如果交给大数据和GPU,模型能自己学出比所有手工设计更好的特征,那人还在那儿废寝忘食地画HOG干嘛?

2.1 检测的迁移困境:分类模型不能直接用

分类模型能识别“图里有什么”,但它不做定位。要做检测,得想办法让模型输出“目标在哪、是什么”。早期粗暴的做法是把分类模型当特征提取器:取掉最后的全连接层,把卷积输出当作特征图,再接到检测头上做分类和回归。这样做的核心收益是,模型从中层视觉特征(边、角、纹理)到高层语义特征(部件、整体结构)全部自动学习,不再依赖人工设计的模板。

但这里遇到一个新问题:目标位置和尺度是任意的,深度学习模型输入尺寸通常是固定的224x224或227x227。直接把目标区域缩放成固定尺寸塞进去没问题,可“目标区域”怎么来?这在当时并不是个显然的问题。

2.2 R-CNN:用候选区域把检测变成“区域分类”

2014年的R-CNN提出了一个非常直白的三段式方案:先用Selective Search生成约2000个候选区域,然后把每个候选区域裁剪出来缩放到固定尺寸,逐个送入CNN提取特征,最后用类别SVM对特征分类,再用回归器精修边界框。

这个方案在PASCAL VOC 2010上把mAP从DPM的33%出头拉到了53%以上,确实惊艳。但代价是灾难性的:一张图2000个候选框,每个框都要做一次完整的前向计算,在当时的GPU上要跑十几秒到几十秒。训练更是要先把所有候选框的特征存到磁盘,动辄几十GB,工程繁琐到令人崩溃。今天回头看,R-CNN的历史意义更多是验证了那条路线能走通,“用CNN自学习的特征代替手工特征”被证明是有效的。

2.3 Fast R-CNN与Faster R-CNN:两次关键的提速手术

R-CNN慢在“每个候选框独立过一遍CNN”。Fast R-CNN解决得干净利落:整张图只过一次卷积,得到整张特征图,然后通过RoI Pooling把每个候选框对应的区域从特征图上抠出来,统一池化成固定尺寸的特征,再送进全连接层做分类和回归。

这一步把整图计算量从几千次前向降到一次前向加极轻量的RoI操作。训练还能做端到端联合优化,不再需要SVM和特征缓存。到了这一步,检测器才真正从“学术玩具”变成了工程上可用、速度上能接受的东西。

接着Faster R-CNN又把候选区域生成这件事也一并学了出来。它引入RPN(Region Proposal Network),在特征图上基于预先铺设的Anchor框做“有没有目标”的二分类和框修正,替代Selective Search。RPN和检测头共享同一个骨干网络,整张图一次前向就能完成候选提议、分类、回归,速度进一步提高到实时边缘,精度也继续上涨。

我一直认为Faster R-CNN是那个时代最有工程智慧的作品。它没有改变R-CNN的骨架,而是把所有子模块统一到“共享卷积特征”这个框架下,每一块都能被梯度信号训练到。从这套设计里延伸出去的Anchor机制、RoI Align、FPN,都成了后面几年无数模型的基座。

3. 一阶段检测器的逆袭:YOLO与SSD如何用“回归”赢回速度

R-CNN系列连续迭代,虽然把速度从秒级推到几十毫秒级,但它始终是两阶段:先提候选框,再对候选框分类。两阶段的精度优势很明显,但工程上人们总想要更直接的做法——能不能一步到位,直接在原始图像上用回归输出所有目标的类别和框?

3.1 YOLO的设计哲学:把检测写成一次全图回归

YOLO v1的思路大胆得几乎粗暴:把输入图划分成S×S的网格,每个网格负责预测固定数量的候选框(含中心坐标、宽高、置信度)和类别概率。整个检测任务被写成一个端到端的回归问题,模型一次性输出所有目标的类别和位置。

这个设计把检测速度推到了45FPS以上,在当年是革命性的。但代价也很明显:每个网格只能预测两个框,网格之间互不通信,导致小目标、密集目标和重叠目标的召回率很差;定位精度也不如两阶段方法。在VOC上YOLO v1的mAP落后Faster R-CNN接近10个点。当时的共识是“YOLO快但糙”,适合实时性优先的场景。

YOLO更大的价值是它打开了一条“单发式”路线。后面的YOLO版本不断吸收各种优化:引入Anchor框、多尺度预测、FPN结构、CSPDarknet骨干、Mosaic数据增强……到v5时代YOLO已经成了工业落地的事实标准。这条进化线证明了一件事:两阶段里积累的很多技术组件,其实可以被一阶段检测器吸收得更好,速度和精度不是铁板一块的对立关系。

3.2 SSD:用多尺度特征图兜住不同大小的目标

SSD和YOLO同一时期提出,但SSD抓住了YOLO召回率差的核心痛点:小目标丢在小网格里。它的解法非常直接——不用最后一层特征图做预测,而是从网络不同深度的多层特征图上分别做检测。浅层特征图分辨率高,感受野小,适合小目标;深层特征图分辨率低,语义强,适合大目标。这个结构后来在两年后被FPN进一步发扬光大。

SSD在当年做到了和Faster R-CNN接近的精度、同时又保持一阶段的实时速度,确实厉害。它给整个行业的启示是:特征金字塔结构的价值不在于某一层“足够好”,而在于不同层之间的互补。后来的FPN在SSD思想基础上加了自顶向下的通路和横向连接,让深层语义信息能回传到浅层,解决了SSD浅层语义不足的问题。

3.3 两阶段与一阶段之争的工程观察

我从业这些年,被问最多的一句话是“检测到底该用两阶段还是一阶段”。我的回答通常不是技术层面的,而是业务层面的:你的目标大小分布如何?实时性要求到多少帧?算力预算在哪?团队有没有部署平台限制?

如果目标是车、人、货物这类中大型目标,实时性要求高,部署硬件一般,YOLO系列几乎总是最优选择。如果目标是医学影像中的微小病灶、卫星图上密密麻麻的小目标,或者极端遮挡密集场景,两阶段方法的候选框机制和RoI细化仍然有明显优势。还有一类场景,比如端侧DSP上部署,精度和模型体积的权衡会让两阶段里的一些轻量方案更合适。这两个范式到今天也不是淘汰关系,而是各自霸占着不同的工程角落。

4. 后Anchor时代的重构:当检测头开始反思自身结构

2017年前后,检测领域的注意力逐渐从外部的数据集刷分转移到模型内部的组件设计上。大家开始追问一些很本质的问题:Anchor到底有多大作用?正负样本不均衡到底靠什么缓解?边界框回归是不是一定要用那么多预设参数?

4.1 Focal Loss与RetinaNet:把训练从“被背景淹没”中救回来

两阶段方法在候选框阶段就把绝大多数背景粗略过滤掉了,所以检测头看到的正负样本比例相对健康。一阶段方法直接对全图所有位置做分类,负样本(背景)数量是正样本的好几百倍,模型被海量简单负样本带偏,学不到真正的目标特征。

RetinaNet的设计正是精准针对这个问题:Focal Loss给置信度高(说明已经学得很好)的样本降低权重,给置信度低、难以分类的样本加大权重。这等于明确告诉模型“别在简单的背景上浪费精力,多啃硬骨头”。配合特征金字塔,RetinaNet在精度上首次追平了两阶段方法,mAP一度超过当时最强的Faster R-CNN变体。这一仗打完,一阶段检测器正式在快的同时也拿到了好精度,后面YOLO的崛起也很大程度上吃了这个红利。

4.2 Anchor-free与FCOS:把规则减到最少

Anchor框架虽然有效,但存在两个让人头疼的问题:一是Anchor的尺寸和比例靠人工调,数据集一换就得重调;二是正负样本分配规则复杂,一个GT框匹配多少Anchor、IoU阈值取多少,这些超参数的经验性太强。

FCOS直接放弃了Anchor,让每个空间位置预测“到目标框四边的距离”,同时用多层特征图把不同尺寸目标分开。它把检测头简化成纯卷积结构,不需要预设框参数,正负样本分配也更自然。后来CenterNet更进一步,直接把目标建模成“中心点+尺寸”,用关键点检测的思路做目标框回归。虽然这些Anchor-free方法最终没能彻底取代YOLO系,但它们在训练简洁性、小目标处理、边缘部署友好度上都打开了新的工程思路,很多优化也被YOLO后续版本吸收进去。

4.3 从这套迭代里学到的工程方法论

这些技术流变里最值得反复揣摩的,并非某个具体模块,而是“问题拆分”的方式。Anchor-free不是凭空长出来的,它是对Anchor机制进行成本分析后的结果——调参成本太高了,于是去参数化。Focal Loss也不是模型结构创新,而是损失函数的重新加权。

做检测落地也一样。很多时候模型效果差,先别急着换更大的网络,先把训练目标分析清楚:是正负样本不平衡?还是目标尺度跨度过大?还是回归分支和分类分支的损失权重没对齐?绝大多数实际问题的解法都在这些细粒度分析里,不在某一个模型名称上。

5. 端到端时代的到来:DETR如何重新定义“检测”

2020年DETR的出现,让整个检测社区又严肃思考了一遍“检测任务的本质到底是什么”。DETR把目标检测定义成一个集合预测问题,不再有Anchor、不再有NMS、不再有候选区域,直接用Transformer的注意力机制学习目标之间的相互关系。

5.1 集合预测与二分图匹配

DETR的思路可以这样理解:模型固定输出N个预测框(N是个远大于典型目标数的常数,比如100),然后和真实的目标集合做二分图匹配,找到最优的匹配组合,让每个预测框都能对应到0个或1个GT框。整个训练过程直接优化集合级损失,预测框与GT框的匹配关系由匈牙利算法动态决定。

因为这个匹配过程是全局最优且一对一对应的,模型天然不会对同一个目标输出多个重复框,所以推理时不再需要NMS。这是第一次真正从结构上把检测的“后处理变前置”,整个pipeline变成了纯粹的编码器-解码器前向传播。

5.2 DETR的代价:收敛慢与对小目标无感

漂亮的公式背后总有不便宜的现实。DETR的训练收敛相当慢,在COCO上需要三百到五百个epoch才能达到较好性能,对比同样效果的传统CNN检测器,训练成本高出好几个量级。原因在于Transformer解码器的注意力机制要从头学习“什么是目标、目标间怎么关联”,没有CNN的局部归纳偏置做初始化,早期训练的匹配过程非常不稳定。

另外DETR在检测小目标上的表现一直不太行,因为注意力机制在高层特征上运行,而小目标在高层特征里的信息响应很弱。后来的Deformable DETR等改进方案通过可变形注意力把特征聚焦到少数关键采样点上,才让端到端路线在训练成本和性能上回到了可竞争的区间。

随着推理引擎对Transformer算子的优化逐步成熟,端到端检测确有成为默认架构的趋势。但至少在当下的工程部署中,传统CNN检测器仍是稳定高效的默认选项,而DETR系代表了一个值得押注、但还没完全兑现的长期选项。

5.3 我对检测未来方向的个人判断

从这二十年的变化里,如果只留一个判断依据,我会用这一条:但凡一个组件里还有需要人工设定的超参数,它就有被另一种更简洁机制替代的可能。Anchor当年被替代是基于这个逻辑,NMS被DETR绕开也是基于这个逻辑。

现在的检测研究已经把焦点从“怎么检测得更准”部分转向“怎么让训练更便宜、部署更灵活”。具体一点说,我看到三个比较明确的方向:一是更高效的自监督预训练,让检测模型不再依赖大规模人工标注;二是在大模型框架下让检测变成多模态理解的一个通用模块,比如直接用视觉语言模型做开放词汇检测;三是推理端对NMS这类后处理做进一步融合,让部署链路更简洁。这些方向都还没有终极答案,但恰恰是工程化最该盯着的增量空间。

我自己的判断未必有多准,但回头复盘这二十年,有个感受是确定无疑的:目标检测——乃至整个CV——的演进,从来不是某个模型横空出世就一锤定音的,而是“精度的提升-效率的妥协-工程性的改良”三股力量反复拉扯出来的结果。谁能把这三股力量捏合得更好,谁就是下一个时代的默认选项。

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

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

立即咨询