论文信息
- 标题:Faster R-CNN: Towards Real-Time Object Detection with Region Proposal Networks
- 会议:NeurIPS 2015
- 单位:Microsoft Research、Facebook AI Research、University of Science and Technology of China
- 代码:https://github.com/ShaoqingRen/faster_rcnn
- 论文:https://arxiv.org/pdf/1506.01497.pdf
前言
在Faster R-CNN出现之前,目标检测一直被候选区域生成 拖慢速度------Selective Search在CPU上跑1张图要1~2秒,比检测网络还慢。这篇论文直接用RPN区域提议网络替代传统候选区域算法,和Fast R-CNN共享卷积特征,让候选区域生成几乎"零成本",首次实现GPU上接近实时的高精度检测,成为两阶段检测的绝对标杆。
一、核心创新点
Faster R-CNN只做了一件大事,但彻底改变检测流程:
- 提出RPN区域提议网络:全卷积结构,在共享特征图上直接生成候选框
- RPN与Fast R-CNN共享卷积特征:消除重复计算,候选区域耗时从秒级降到10ms
- Anchor机制:用多尺度、多长宽比锚点框解决目标尺度问题,不用图像金字塔
- 4步交替训练:让两个网络完美共享权重,统一成一个端到端模型
二、整体架构:RPN + Fast R-CNN 统一网络
Faster R-CNN是单网络、两模块的结构,共享全部卷积层。

图 1:针对不同尺度和大小的处理方案。(a)构建图像和特征图的金字塔,并在所有尺度下运行分类器。(b)在特征图上运行具有多种尺度/大小的滤波器金字塔。(c)在回归函数中使用参考框的金字塔。
分析: backbone卷积层提取共享特征 → RPN生成候选框 → RoI Pooling采样特征 → 分类+回归输出结果。RPN相当于网络的"注意力",告诉模型该看哪里。
三、核心模块1:RPN 区域提议网络
3.1 RPN工作流程

图 2:Faster R-CNN 是一个用于物体检测的单一、统一的网络。RPN 模块在此统一网络中充当"注意力"角色。
-
在共享卷积特征图上,用3×3卷积 滑动窗口提取特征
-
接两个1×1卷积层,分别做前景背景分类 和框回归
-
每个滑动窗口位置,预设k个Anchor框 (默认9个)
-
用NMS筛选高分候选框,送给Fast R-CNN
3.2 Anchor 锚点机制(最核心设计)

图 3:左图:区域提议网络(RPN)。右图:使用 RPN 提出的候选区域在 PASCAL VOC 2007 测试集上的示例检测结果。我们的方法能够检测到各种大小和比例的物体。
Anchor是固定尺寸、固定长宽比的参考框,解决多尺度目标检测问题。
- 默认配置:3种尺度 (128²、256²、512²) + 3种长宽比(1:1、1:2、2:1)
- 每个特征点:9个Anchor
- 特性:平移不变性 、参数量极小 、无需图像金字塔
通俗解释:Anchor就是提前在图上"撒"一堆不同大小形状的框,让网络只需要学习偏移量,不用从零预测框。
3.3 RPN损失函数(多任务损失)
总损失由分类损失 +回归损失 加权组成:
L ( { p i } , { t i } ) = 1 N c l s ∑ i L c l s ( p i , p i ∗ ) + λ 1 N r e g ∑ i p i ∗ L r e g ( t i , t i ∗ ) L(\{p_i\},\{t_i\})=\frac{1}{N_{cls}}\sum_i L_{cls}(p_i,p_i^*)+\lambda\frac{1}{N_{reg}}\sum_i p_i^*L_{reg}(t_i,t_i^*) L({pi},{ti})=Ncls1i∑Lcls(pi,pi∗)+λNreg1i∑pi∗Lreg(ti,ti∗)
- L L L:总损失
- p i p_i pi:Anchor i 预测为物体的概率
- p i ∗ p_i^* pi∗:真实标签(正样本=1,负样本=0)
- t i t_i ti:预测框的4个归一化偏移量
- t i ∗ t_i^* ti∗:真实框的4个归一化偏移量
- N c l s N_{cls} Ncls:分类归一化项(batch大小,256)
- N r e g N_{reg} Nreg:回归归一化项(Anchor数量,约2400)
- λ \lambda λ:平衡系数,默认10
- L c l s L_{cls} Lcls:二分类交叉熵损失
- L r e g L_{reg} Lreg:Smooth L1 回归损失
框回归公式(归一化偏移)
t x = ( x − x a ) / w a , t y = ( y − y a ) / h a t w = log ( w / w a ) , t h = log ( h / h a ) t_x=(x-x_a)/w_a,\quad t_y=(y-y_a)/h_a \\ t_w=\log(w/w_a),\quad t_h=\log(h/h_a) tx=(x−xa)/wa,ty=(y−ya)/hatw=log(w/wa),th=log(h/ha)
- x / y / w / h x/y/w/h x/y/w/h:预测框中心、宽、高
- x a / y a / w a / h a x_a/y_a/w_a/h_a xa/ya/wa/ha:Anchor框中心、宽、高
- t x / t y / t w / t h t_x/t_y/t_w/t_h tx/ty/tw/th:网络输出的归一化偏移
四、核心模块2:RPN 正负样本定义
训练RPN必须严格划分正负样本,否则无法收敛:
- 正样本 (2种)
- 与真实框IoU最高的Anchor
- 与任意真实框IoU > 0.7
- 负样本
- 与所有真实框IoU < 0.3
- 忽略样本
- 不属于正/负,不参与损失计算
Batch采样:每张图随机采256个Anchor,正负比例≈1:1。
五、训练策略:4步交替训练法
为了让RPN和Fast R-CNN共享权重,论文提出4步交替训练:
- 训练RPN:用ImageNet预训练权重初始化,训RPN
- 训练Fast R-CNN:用RPN生成的候选框,训独立检测网络
- 用检测网络初始化RPN:固定共享卷积层,只微调RPN独有层
- 固定共享层,微调Fast R-CNN:两个网络完全共享权重,统一模型
六、实验结果与分析
6.1 速度对比(最震撼的提升)
表格1 检测速度对比(VGG-16,K40 GPU)
| 系统 | 卷积耗时 | 候选区域耗时 | 检测后续耗时 | 总耗时 | 帧率 |
|---|---|---|---|---|---|
| SS+Fast R-CNN | 146ms | 1510ms | 174ms | 1830ms | 0.5fps |
| Faster R-CNN | 141ms | 10ms | 47ms | 198ms | 5fps |
表格1 出处 :Faster R-CNN原文
分析 :候选区域从1510ms→10ms,速度提升9倍,精度还更高。
6.2 VOC 2007 检测精度
表格2 VOC 2007 测试集mAP
| 方法 | 候选区域数 | 训练数据 | mAP(%) |
|---|---|---|---|
| SS+Fast R-CNN | 2000 | VOC07 | 66.9 |
| Faster R-CNN(不共享) | 300 | VOC07 | 68.5 |
| Faster R-CNN(共享) | 300 | VOC07 | 69.9 |
| Faster R-CNN(共享) | 300 | VOC07+12 | 73.2 |
表格2 出处 :Faster R-CNN原文
分析:只用300个候选框,mAP超过2000个框的Selective Search。
6.3 Anchor 消融实验
表格3 Anchor设置对mAP影响
| 设置 | 尺度 | 长宽比 | mAP(%) |
|---|---|---|---|
| 1尺度1比 | 128² | 1:1 | 65.8 |
| 1尺度3比 | 128² | 3种 | 68.8 |
| 3尺度1比 | 3种 | 1:1 | 69.8 |
| 3尺度3比 | 3种 | 3种 | 69.9 |
表格3 出处 :Faster R-CNN原文
分析:多尺度Anchor提升最明显,多长宽比进一步小幅增益。
七、核心代码实现(PyTorch简化版)
python
import torch
import torch.nn as nn
import torch.nn.functional as F
# --------------------------
# 1. RPN 网络结构
# --------------------------
class RPN(nn.Module):
def __init__(self, in_channels=512, mid_channels=512, n_anchor=9):
super().__init__()
# 3x3 滑动窗口特征提取
self.conv = nn.Conv2d(in_channels, mid_channels, 3, 1, 1)
# 分类:前景/背景 2*9
self.cls = nn.Conv2d(mid_channels, 2 * n_anchor, 1)
# 回归:4*9 坐标偏移
self.reg = nn.Conv2d(mid_channels, 4 * n_anchor, 1)
def forward(self, x):
x = F.relu(self.conv(x))
cls_score = self.cls(x) # [B, 18, H, W]
reg_offset = self.reg(x) # [B, 36, H, W]
return cls_score, reg_offset
# --------------------------
# 2. Smooth L1 损失(RPN回归用)
# --------------------------
def smooth_l1_loss(x, target, beta=1.0):
diff = torch.abs(x - target)
loss = torch.where(diff < beta, 0.5 * diff **2 / beta, diff - 0.5 * beta)
return loss.mean()
# --------------------------
# 3. IoU 计算
# --------------------------
def iou(box1, box2):
# 转成 (x1,y1,x2,y2)
b1_x1, b1_y1 = box1[:,0]-box1[:,2]/2, box1[:,1]-box1[:,3]/2
b1_x2, b1_y2 = box1[:,0]+box1[:,2]/2, box1[:,1]+box1[:,3]/2
b2_x1, b2_y1 = box2[:,0]-box2[:,2]/2, box2[:,1]-box2[:,3]/2
b2_x2, b2_y2 = box2[:,0]+box2[:,2]/2, box2[:,1]+box2[:,3]/2
inter_x1 = torch.max(b1_x1, b2_x1)
inter_y1 = torch.max(b1_y1, b2_y1)
inter_x2 = torch.min(b1_x2, b2_x2)
inter_y2 = torch.min(b1_y2, b2_y2)
inter = torch.clamp(inter_x2-inter_x1, 0) * torch.clamp(inter_y2-inter_y1, 0)
union = box1[:,2]*box1[:,3] + box2[:,2]*box2[:,3] - inter
return inter / union
八、全文总结
- Faster R-CNN = RPN + Fast R-CNN,共享卷积特征,实现实时检测
- RPN:全卷积、Anchor驱动、零成本候选区域,替代传统Selective Search
- Anchor:多尺度+多长宽比,完美解决目标尺度变化问题
- 速度革命:从0.5fps→5fps(VGG-16),精度同时大幅提升
- 历史地位:两阶段目标检测的基石,后续Mask R-CNN、Cascade R-CNN全部基于它扩展