☰
R-CNN到Faster R-CNN:两阶段检测器演进主线全解
2026/10/13 23:12:42 网站建设 项目流程

想真正理解目标检测这些年几十个模型的来龙去脉,先看这一条主线就够了:R-CNN、Fast R-CNN、Faster R-CNN。这三个名字在论文里挨得很近,在代码里也经常被放在一起对比,但它们并不是三个并列的模型,而是同一条脉络上的三次关键决策。每一步都在解决上一个版本留下的最痛的问题,但每一次选择又会在别处留下新的限制。我当年把这几篇论文和代码对着读了好几遍,才真正体会到什么叫“结构跟着瓶颈走”。这篇就按这条发展线把三代模型拆开讲,讲清楚它们各自怎么工作、为什么必须这样改、改进的代价是什么,也会把我复现和调试过程中的实际体会一并写出来。适合刚入门检测的读者,也适合准备面试、想把两阶段检测器讲明白的人。

1. 检测任务的核心矛盾:先找出“在哪”,再回答“是什么”

1.1 分类与检测:看似相近,任务难度完全不同

图像分类只问一个问题:这张图里最主要是哪个类别。网络看完整张图,输出一个概率分布,哪怕图里同时有五个物体,分类任务也只会挑最主要的那个答案。检测不一样,它要同时回答两个问题:图里有哪些物体,它们各自在什么位置。而且物体的数量不固定、大小不固定、长宽比不固定,一张图里可能只有一个物体,也可能密密麻麻排了几十个。

这两个问题叠加在一起,就把一个看起来很简单的视觉任务变成了一个组合搜索问题。早期很多做法之所以效率低,恰恰是因为它们没有把“找位置”这件事和“认类别”这件事分开处理,而是用蛮力去扫。

1.2 深度学习出现以前,大家都靠什么做检测

在卷积网络大规模应用之前,主流检测方案基本逃不开“滑动窗口+手工特征”这个框架。思路非常朴素:既然不知道物体在哪、有多大,那就把所有可能的位置和尺寸都扫一遍。窗口从左上角开始,按一定步长平移,每换一个位置就把窗口里的图像区域抠出来,提一组手工特征,比如颜色直方图、梯度方向直方图、纹理特征,再丢给一个分类器判断是不是目标。

这个思路在概念上很简单,但算一算就知道有多绝望。一张普通分辨率的图,如果按不同尺度、不同长宽比铺开窗口,数量动辄十几万甚至几十万个。每一个窗口都要重新提一次特征,再做一次分类。早期做行人检测的经典系统,一张图就要跑很久,而且窗口扫过去,大量背景区域被当成候选,误检率也被抬得很高。那个时代的检测器就像在图书馆里找一本书,但方法是把每一排书架从头到尾一格一格打开看。

1.3 卷积网络出现后,大家真正缺的是什么

卷积网络在分类任务上把特征表达能力拉高了一大截,这给了检测一个全新的可能性:能不能用卷积网络提特征来做检测?但这里卡着一个很实际的问题。分类网络是“整图进、标签出”,它天然不知道自己该把注意力放在图的哪个位置。检测需要的是把图中的潜在目标一个个“抠”出来,再逐个判断,这涉及一个后续分类网络不擅长的步骤:怎么找到候选区域。

换句话说,那时候的学术界已经有了非常强的特征提取工具,缺的只是一个合理的“候选区域机制”。谁能把这两个东西优雅地接起来,谁就能把检测带上一个新台阶。R-CNN做的正是这件事,虽然它接得并不优雅。

2. R-CNN:第一次把候选区域喂给卷积网络

2.1 核心思想:与其盲扫,不如先猜一堆“可能的位置”

R-CNN的全称是Region-based CNN,思路可以浓缩成一句话:先找出图上可能包含物体的区域,再对这些区域逐个用卷积网络分类。它和滑动窗口最本质的区别是,不再用穷举的方式扫描整张图,而是先用一个独立的算法生成一批候选区域,通常数量在两千个左右。

这个数量的对比是震撼的:从十几万个暴力扫描窗口降到两千个候选区域,计算量一下子缩小了一两个数量级。当然,两千个也不算少,但已经是可以接受的规模了。这里用的候选区域提取方法是Selective Search,它不依赖深度学习,而是基于图像的颜色、纹理、尺寸等底层线索,把相似的相邻区域不断合并,最后输出一组覆盖不同尺度、不同长宽比的候选框。

我当时第一次看到这个流程时觉得有点分裂:前面提特征用了当时最强的卷积网络,候选区域却还是传统的图像分割算法,像一个机器人用了最先进的芯片,却还在用老式雷达找障碍物。但这恰恰是它成功的地方——先把整体流程跑通,再逐个换掉薄弱环节。

2.2 流程拆解:一张图从输入到输出的完整路径

完整跑一遍R-CNN,流程是这样:

  1. 输入一张图像,用Selective Search生成大约2000个候选区域(region proposal)。
  2. 把每个候选区域从原图中裁剪出来,缩放到统一尺寸。原论文里用的是227×227,缩放时会先在候选框周围留一些padding,避免把物体边缘信息切掉。
  3. 把缩放后的图像块送入一个在ImageNet级别的大规模图像分类数据集上预训练过的卷积网络,再在检测数据集上微调,取最后一个全连接层之前的特征,通常是4096维的向量。
  4. 对每个类别单独训练一个线性SVM二分类器,用这个4096维特征判断“是否属于该类”。
  5. 同时训练一个边界框回归器,对框的位置做精细修正。
  6. 同一目标可能被多个候选框命中,最后用NMS(非极大值抑制)去掉重叠过高的冗余框。

每一步单独看都很直白,但把它拼起来,就能看到一个完整的检测系统雏形:候选区域负责“猜”,卷积网络负责“认”,回归器负责“修”,NMS负责“过滤”。

2.3 为什么分类器选SVM,而不是直接用网络的softmax层

这是很多初学者最容易困惑的地方。卷积网络最后一层明明自带softmax分类,R-CNN为什么还要额外训练2000个候选区域对应的SVM?原因在于两者的正负样本定义不一样,训练目标存在冲突。

微调卷积网络的时候,正样本通常是IoU大于某个较大阈值(比如0.5)的区域,负样本是IoU很低的背景区域,在这种宽松定义下训练的softmax分类器,容错度比较高。而SVM要求更严格:它对“一个区域是不是某类目标”的边界判断更谨慎,原文实验显示,在同样的特征下,把CNN微调阶段的softmax换成语义更清晰的SVM,mAP会更高一些。此外,SVM是在CNN提取出的固定特征上单独训练的,可以针对每个类别做难例挖掘,处理类别不平衡更灵活。

但我自己复现这个思路的时候的感受是:SVM带来的提升其实有限,它更像是一个“工程上更精细的选择”。真正的代价是存储和训练复杂度。

2.4 里程碑意义与让人头疼的代价

R-CNN在当年的公开检测数据集上把mAP提升了一大截,和传统方法相比几乎是碾压式的。这是第一次用实验证明了一件事:用卷积网络提取的深度特征,比任何手工特征都好用,只要给它一个合理的候选区域,它就能完成高质量的检测。

但它的缺点同样明显。第一,训练是多阶段的:候选区域生成、CNN微调、SVM训练、边界框回归器训练,四个阶段要依次进行,每一阶段的结果都会影响后面的效果,调试起来非常麻烦。第二,每张测试图要跑约2000次CNN前向,因为每个候选区域都单独过一遍网络,速度慢得离谱。第三,所有候选区域的特征都要保存到硬盘上供SVM训练使用,我当时算过一次,几千张图的特征动辄几百GB,换块硬盘比调参还刚需。

正因如此,今天几乎没有人再去复现完整的原版R-CNN流程了。但没有任何人能绕过它,因为后面所有改进,本质都是在回答同一个问题:能不能别让每个候选区域都单独过一遍网络?

3. Fast R-CNN:把上千次前向浓缩成一次,训练也变成一条流水线

3.1 突破口:整图只做一次卷积,候选区域映射到特征图上

Fast R-CNN的改进逻辑非常清晰:R-CNN里每个候选区域都要单独送进CNN提取一次特征,实在太浪费了。这些候选区域本来就来自同一张图,图像内容高度重叠,凭什么不能在全图上只做一次卷积,然后把候选区域从原图坐标系映射到卷积后的特征图坐标系,直接在特征图上抠出对应区域?

这个映射关系是固定的:卷积网络每一层输出的特征图,和原图之间保持着确定的位置比例关系。具体到某个候选区域,只需要做一个坐标变换和缩放,就能知道它在特征图上对应哪一块。这样一来,不管图里有多少个候选区域,卷积的骨干网络只需要跑一遍。这一下就把R-CNN最昂贵的计算开销打掉了。

3.2 RoI Pooling:把大小不一的候选区域变成固定尺寸的特征

候选区域的尺寸千差万别,有的又高又窄,有的又宽又扁,映射到特征图上之后,对应的区域也是大小不一的。但后面的全连接分类层要求输入是固定长度的向量,所以必须把不同尺寸的区域统一成一个固定尺寸。

RoI Pooling就是干这个的。它的做法是:把某个候选区域在特征图上对应的区域,划分成一个固定数量的网格,比如原文里常用的7×7,一共49个格子。对每个格子内部的像素做max pooling,取最大值作为这个格子的输出。这样不管原始区域多大,最终都变成一个7×7的输出,接下去就可以送进全连接层了。

用生活里的例子理解:RoI Pooling就像把一堆不同尺寸的照片统一缩放成同一个标准相框,只不过缩放方式不是简单拉伸,而是在每个小格子里挑最重要的像素。这个设计让网络可以在不裁剪、不改变原图信息的情况下处理任意尺寸的候选区域,是很漂亮的一手。

3.3 联合训练与多任务损失:把分类和回归放进同一个网络

Fast R-CNN去掉的还有R-CNN那种多阶段训练。整个网络只剩下两个部件:一个共享的卷积骨干,加上一个检测头。检测头分两支,一支输出各类别的softmax概率,一支输出边界框的回归参数。损失函数是两者的加权和:分类用softmax的交叉熵损失,回归用smooth L1损失。

联合训练带来的好处不只是代码上少写几个模块,更重要的是梯度能同时回传到整个骨干网络。R-CNN里SVM训练阶段是完全独立于CNN的,CNN看不到SVM的错误信号,特征提取的优化方向做不到和检测目标强对齐。Fast R-CNN把这一步打通了,整个网络朝着检测目标一起优化,分类误差和回归误差一起反传,骨干特征会变得更“懂”检测。这是精度能提升的关键原因之一。

另外还有个值得一提的细节:论文里对全连接层的矩阵做了SVD分解,把一个大的权重矩阵拆成两个小矩阵的乘积,推理时降低计算量。放在当时这是很务实的优化手段,放在今天看,这个思路其实已经不太流行了,但它体现了一个原则:能压推理计算的地方都要压,别让分类头成为瓶颈。

3.4 数据流里的工程细节:RoI采样策略

训练时不能把图里所有候选区域都拿来算损失,也没有必要。Fast R-CNN采用的办法是:一个mini-batch里取两张图,每张图随机采样固定数量的RoI,常见配置是一张图采64个RoI,其中和背景的比例大概3:1。正样本是IoU大于0.5的区域,负样本是IoU在0.1到0.5之间的难背景。这个采样策略很关键,它保证了每个batch里既有很多目标框,也有足够有代表性的背景框,分类器不会一边倒。

很多人训练时忽略这个比例,直接拿全部候选区域跑,结果是正负样本失衡,训练半天loss不降。我建议不管用什么框架复现,先确认一下RoI采样逻辑,别默认框架帮你把一切做对了。

3.5 提速的成绩与一个仍然扎眼的瓶颈

Fast R-CNN在论文里的对比数字很能说明问题:训练速度大约是R-CNN的9倍,推理速度大约提升25倍,精度还比R-CNN略高。这个提升让我印象深刻的不是哪个具体数字,而是同一个骨干网络、同一个候选区域来源,仅仅改变计算复用方式,就能带来如此巨大的效率变化。

但只要你跑过一遍就会注意到,速度瓶颈已经不在CNN了,而在候选区域生成这一步。Selective Search本身是传统算法,单张图要跑几百毫秒甚至更久,而且它完全独立于网络,无法根据检测结果调整自己的建议。当主干网络越来越快的时候,这个外部依赖就会成为整个系统里最慢的一环。到了这一步,几乎所有研究者都看到了同一个结论:候选区域也必须变成网络的一部分,不能再靠外面那个“老雷达”了。

4. Faster R-CNN:让网络自己学会“找目标”

4.1 一个关键反问:为什么不能用同一个特征图来预测“哪里可能有目标”

Fast R-CNN的卷积骨干在全图上提取了一次特征,覆盖了整张图的语义信息。这个特征图既包含“这张图里有什么”,从理论上讲,也包含“这些东西大概在哪个位置”。既然RoI Pooling能从特征图里抠出候选区域对应的特征,那就说明特征图里已经完全具备定位线索了。

Faster R-CNN的决定性一步,就是别再让Selective Search在外面猜,而是让这个特征图自己输出一组候选区域。为此论文提出一个新的模块——Region Proposal Network,RPN,区域提议网络。RPN和Fast R-CNN的检测头共享同一个卷积骨干特征图,它做的事情可以理解为:在特征图的每个位置上,同时预测“这里有没有目标”和“目标框大概长什么样”。

4.2 RPN的机制:滑窗加锚点,把“找候选”变成“做回归”

RPN的结构不复杂。它在共享特征图上用一个小的滑窗窗口扫过每个位置,对每个中心位置,同时考虑k种不同尺寸和长宽比的参考框,这些参考框被称为锚点(anchor)。原文默认k为9,也就是3种尺度、3种长宽比,常见配置是面积对应原图约128、256、512平方像素,长宽比取0.5:1、1:1、2:1。这样一张图上的锚点数量加起来可能有几万个。

每个锚点会经过一个小网络输出两组结果:一组是这个锚点代表的位置“是前景还是背景”的二分类分数,另一组是四个回归参数,对锚点框做微调,修正成更精确的候选框。整个过程相当于网络把候选区域的生成从“靠外部算法看颜色纹理”变成了“根据深度特征判断语义+回归坐标”。

我第一次接触anchor概念时觉得它有点抽象,后来换了个视角就理解了:可以把RPN的输出看成“在做一件和检测头非常相似的事情,只不过类别只有前景和背景两类,且对框的质量要求宽松很多”。RPN的作用不是精确框出目标,而是给出一个召回率高、初步紧贴目标的候选集合,精确的分类和回归交给下一阶段的Fast R-CNN检测头来做。

4.3 锚点是怎么学习的:RPN的训练规则

RPN训练时,每个锚点需要打标签。规则是:和某个真实目标框IoU最高的那个锚点标记为正样本;或者任何锚点与某个真实目标框的IoU大于0.7,也标记为正样本。反面规则是,锚点与所有真实目标框的IoU都小于0.3,标记为负样本。介于0.3到0.7之间的锚点不参与训练,因为它们处于模糊地带,既不太像前景,也不太像背景,硬要分类只会给梯度带来噪声。

为了控制正负样本不平衡,训练时不会拿全部锚点算损失,而是随机采样一小部分,比如每张图256个锚点,尽量保证正负样本接近1:1。理论清楚之后,你会发现RPN的训练其实很像一个简化版的小目标检测器,只不过它的目标只有两类:有目标、没目标。

4.4 两个模块怎么共享特征:训练时的几种做法

Faster R-CNN在论文里给出了几种训练策略,理解这个能让你的代码调试少走很多弯路。

第一种是交替训练:先训练RPN,用RPN生成的候选框训练Fast R-CNN检测头,然后再用初始化后的权重重新训练RPN,如此交替迭代。第二种是近似联合训练:把RPN和Fast R-CNN合并成一个大网络一起训练,RPN输出的候选框在训练中被当做一个常数,梯度近似后向传播。第三种是真正的联合训练。

实际操作中,今天的主流框架大多采用类似联合训练的做法,用一个综合的损失函数同时优化RPN和检测头。这里有一个我踩过的坑:如果两部分的收敛速度不一样,直接端到端可能让RPN还没学会“提好框”,检测头就输出了大量噪声框,最终精度反而差。解决办法是先让骨干网络在某一个任务上预热一段,或者用较小学习率启动RPN。

4.5 效果与结构代价

Faster R-CNN在当年的公开检测数据集上,把mAP提升到约73%,在当时的单块GPU上推理速度可以达到每帧5帧左右,虽然是准实时的水平,但已经比Fast R-CNN快了一个数量级,更重要的是整个系统从预处理到最终输出全部进入了网络。从这时开始,“候选区域”不再是外部算法,而是网络自己学习出来的能力,这个范式后来被称为两阶段检测器,统治了检测领域很长一段时间。

代价也很明确:整个系统仍然是一个两阶段的串行结构,RPN先出框,检测头再精修,二者虽然共享骨干,但各自的头部和损失逻辑都还在。计算流程比后来出现的单阶段方法要复杂,这也是后来YOLO和SSD能另立山头的原因——它们想要的是“一次前向直接输出所有框和类别”,不去拆成两个阶段。

4.6 从RPN到检测头:一条完整的数据流

我再把Faster R-CNN推理时的完整数据流串一遍,方便你建立整体直觉。图像送入骨干网络,得到特征图;特征图同时输入RPN,RPN在特征图每个位置根据锚点输出前景分数和修正后的框坐标;对这些框按分数排序,经过NMS过滤掉大量重叠框,留下大约一两百个候选区域;这些候选区域映射到特征图上,经过RoI Pooling取出固定维度特征;最后经过检测头,输出每个候选框的类别分数和精确的边界框坐标;再一次NMS得到最终结果。

可以看到,R-CNN时代的“生成候选、提取特征、分类、回归”四段式流程全部保留了下来,只不过每一个步骤都被换成了可学习的网络模块。这就是Faster R-CNN被称为奠基性工作的原因:它把整个检测流水线统一成了一个端到端可训练的神经网络。

5. 三代模型放在同一张表里看:突破、代价与遗留问题

5.1 一张对比表看清三代的差异

很多资料把三代模型分开讲,读者容易记混。我觉得放一张对比表放在中间,反而能帮读者快速建立起全局视角。表格关注的是实现层面最本质的差异,而不是具体数值。

维度R-CNNFast R-CNNFaster R-CNN
候选区域来源外部算法 Selecta Search外部算法 Selective Search网络内部的RPN
CNN前向次数每个候选区域一次,约2000次整图一次整图一次
训练流程多阶段串联端到端联合训练端到端联合训练(含RPN)
是否端到端否是是
特征提取与分类是否共享共享特征但分类器独立共享,统一损失共享,统一损失
主要瓶颈重复计算、多阶段外部候选区域算法太慢结构复杂,速度不如后续单阶段方法
历史贡献第一次验证深度特征用于检测可行把多次前向改为一次,验证联合训练价值把候选区域也变成网络能力,形成两阶段范式

这张表列的每一行,都对应着一次明确的技术决策。读的时候可以一行一行看:候选区域从外部算法变内部网络,是三代演进最核心的那条线;训练流程从四段式变成统一网络,是工程可复现性的大步提升;前向次数从两千次降为一次,是整个系统速度变化的最直接原因。

5.2 本质主线:把外部依赖一步一步内化成网络能力

如果只记一个结论,我会记这条:三代R-CNN的演进,本质上是在反复做同一件事——把原先靠外部算法、手工规则、分阶段处理完成的环节,一步一步替换成网络内部可学习的模块。R-CNN把特征提取换成了CNN,但候选区域还在外部;Fast R-CNN把候选区域的特征提取统一进了网络,但候选区域本身还在外部;Faster R-CNN终于把候选区域生成也变成了网络的一部分。

这条主线放到今天依然适用。现在的目标检测领域里,anchor是否要手工设计、NMS是否要被替代、多尺度特征是否要手动融合,这些问题本质上都还在延续“把外部规则往网络里搬”的同一个方向。理解了这个逻辑,你再看后面的FPN、OHEM、RoI Align这些改进,就能自动找到它们在主线上的位置。

5.3 对后续检测模型的影响:两阶段范式的扩散与反击

Faster R-CNN把两阶段范式定型之后,后续一大批工作都是在这条路上修修补补。FPN在骨干网络里增加了自顶向下的多尺度特征融合路径,解决了小目标检测中特征图分辨率不足的问题;网络向Mask R-CNN添加了一条分割分支,同样沿用“RPN出框+检测头精修”的结构。可以说,只要一个模型内部还有“先提候选、再精分类”的串行结构,它的血统里就带着Faster R-CNN的基因。

同时,单阶段方法也迅速崛起,YOLO把检测重新定义为“一次回归”,SSD则将多尺度锚点直接铺满特征图,它们换来的是更快的速度,代价是精度往往要弱一点。之后的很多改进,比如RetinaNet用focal loss处理单阶段方法里的极端正负不平衡,本质上都是在跟两阶段方法在精度上掰手腕。看到这里你会发现,单阶段和两阶段的缠斗,根源正是R-CNN这条线里“先提框再分类”与“直接输出”两种设计哲学的对撞。

5.4 学习和面试时可以怎么抓重点

如果是为了学习或准备面试,建议不要背模型介绍,而是背“每个版本解决了什么问题,引入什么新概念,代价是什么”。比如R-CNN的标签是“候选区域+卷积特征”,Fast R-CNN的标签是“RoI Pooling+联合训练”,Faster R-CNN的标签是“RPN+锚点”。当你能够清楚说出每个概念对应的瓶颈时,就说明真的理解了。

面试里还有一个高频追问是“为什么不直接一步到位做端到端”。答案不是技术做不到,而是每一步的跳跃都有风险:如果一开始就把候选区域交给网络学,当网络还没有能力生成合理候选区域时,整个检测系统会完全崩溃。R-CNN线之所以一步一步演进,是因为每次只改一个变量,能更好地定位哪一步带来了提升。这是研究方法的智慧,也是工程上稳健性的体现。

6. 复现过程中的实际体会与调参细节

6.1 别急着从零实现,先用现成框架跑通再改

原版R-CNN的完整流程,今天几乎不会有人复现了——光是把每个候选区域的特征存到硬盘这一步,就足够劝退大部分实验者。我建议学习时这样做:先用主流深度学习框架里的两阶段检测实现,把Faster R-CNN整个训练和推理流程跑起来,再回头对照论文,把R-CNN和Fast R-CNN的差异在代码里标记出来。

跑通后再做一件事:把RPN的中间输出可视化。我当时直接把RPN产生的锚点、NMS之前的候选框、NMS之后的候选框分别画在图上,很快就能看出锚点在密集区域重叠严重、在小目标上覆盖不足的问题。这种直观感受比读十遍论文都强,强烈建议做一遍。

6.2 锚点参数的坑:默认配置并不总是合适

原论文里的锚点是3种尺度、3种长宽比,总面积按原图像素计算。这个配置在当时的公开检测数据集上很好用,但它高度依赖数据集里目标的大小分布。如果你的数据集以小目标为主,比如很多行人检测场景,目标在原图里只占几百个像素,那默认锚点里最顶层的尺度可能完全覆盖不到,最终表现为RPN召回率很低,大量真实目标在第一步就被过滤掉了。

遇到这种情况,常见的调整方向有三种:提高输入图像分辨率,让小目标在特征图上占据更多像素;使用特征金字塔结构,让RPN在多个分辨率上分别出框;调整锚点的尺度和长宽比,让它贴近数据集的真实分布。我记得有一次只把锚点的最小尺度调小了一档,小目标检测的召回率就明显改善,可见锚点和数据集匹配度的影响有多直接。

6.3 NMS阈值和RoI采样比例是两把看不见的刀

NMS虽然只是一个后处理步骤,但它对最终结果的影响经常被低估。RPN阶段的NMS一般建议用0.7,因为这里希望多保留一些候选框,宁可漏掉后面的精修机会;但检测头输出后的NMS,很多框架默认0.3到0.5。如果你发现最终检测结果里同一个物体出现多个框,说明最终的NMS阈值调得太高;反过来,如果一个物体附近明明有很紧的框,却全被抑制掉了,说明阈值太低。

RoI采样比例同样要舍得调。训练时正负样本的比例如果失衡,比如负样本占了95%以上,分类器很容易倾向把所有框都判为背景。我在早期尝试时,为了偷懒把采样逻辑直接删掉,全量RoI参与训练,结果loss下降很快但精度很糟——这就是因为网络在“见大量背景”和“分类准确”之间找到了偷懒的平衡。结论是:采样比例看起来是小配置,但它是整个训练稳定性的地基。

6.4 坐标缩放的一致性、RoI量化误差、预训练权重

复现过程中最容易出的bug往往不神奇,而是“图变了,框没跟着变”。训练时统一把图缩放到了固定尺寸,但标注框还是原图坐标,RoI映射到特征图时如果没做同步缩放,候选框就会集体漂移。建议在数据预处理流水线里,把缩放系数显式传给后续所有阶段,别在某个回调函数里悄悄改了图却忘了改框。

另一个容易踩的是RoI池化中的量化误差。RoI Pooling在映射和分格时会对浮点坐标做取整,偶尔会让框的位置偏移一个像素,在小目标上影响尤其明显。后来出现的RoI Align用双线性插值替代取整,把这个问题基本解决了。但如果你还在基于更早的实现做实验,心里要清楚取整误差是存在而且不可忽略的。

预训练权重也值得多说一句。骨干网络建议先在大规模图像分类数据集上预训练,再拿到检测数据集上微调。直接随机初始化从头训练,检测精度往往会差好几个点,而且收敛慢得多。我在一次赶时间的实验里跳过了预训练,结果模型训了很久还在低频震荡,后来老老实实加载预训练权重,才算找回正常节奏。

6.5 从两阶段到现代检测:这套基本功依然值钱

现在有很多更新的检测方法,有些不再使用锚点,有些把两阶段简化为单阶段,有些用Transformer直接建模目标之间的关系。但回头看,R-CNN这条线留下的几个基础问题——候选区域怎么产生、特征怎么共享、损失怎么联合、采样怎么平衡——依然是设计一个检测器时必须回答的。理解了这些问题,你读任何新论文都不会觉得飘,因为底层框架你已经能搭出来了。

我自己把三代模型一轮一轮对照下来,最大的体会是:技术的演进从来不是靠突然冒出来的新结构,而是靠一针一针把卡脖子的环节替换掉。R-CNN把特征提取这块补上了,Fast R-CNN把计算复用这块补上了,Faster R-CNN把候选区域这块补上了,下一针补哪里,永远是下一个模型的事。这也是这条发展史让人觉得最有意思的地方——它不像一部英雄史,更像一部技术在自我修补中不断变强的进化史。

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

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

立即咨询