查看全课大纲(第 59 / 93 节)
  1. 1.计算机视觉概述
  2. 2.计算机视觉应用场景
  3. 3.困难与挑战
  4. 4.开源库介绍
  5. 5.图像显示与存储
  6. 6.CLAHE
  7. 7.腐蚀膨胀与开闭运算
  8. 8.滤波与边缘填充
  9. 9.各种滤波
  10. 10.图像金字塔
  11. 11.傅里叶变换
  12. 12.短时傅里叶变换与小波变换
  13. 13.颜色特征与颜色直方图
  14. 14.几何特征_边缘
  15. 15.几何特征-角点与斑点
  16. 16.局部特征-SIFT特征描述子
  17. 17.局部特征-SURF特征描述子
  18. 18.局部特征-ORB特征描述子
  19. 19.其他特征描述子
  20. 20.传统图像分割技术
  21. 21.GraphCut
  22. 22.GrabCut
  23. 23.人脸检测的传统方法
  24. 24.行人检测的传统方法HOG+SVM
  25. 25.行人检测DPM
  26. 26.人工神经网络的架构
  27. 27.目标函数与梯度下降
  28. 28.误差反向传播
  29. 29.可手算的神经网络
  30. 30.改进目标函数与克服梯度消散
  31. 31.神经网络之传统神经网络与深度网络的差异
  32. 32.各种梯度下降算法
  33. 33.如何选择合适的梯度下降算法
  34. 34.避免过适应
  35. 35.CNN的架构
  36. 36.CNN的误差反向传播_卷积层
  37. 37.CNN的误差反向传播_池化层
  38. 38.分类所用的数据集
  39. 39.Alexnet详解
  40. 40.VGG详解
  41. 41.GoogLeNet_v1
  42. 42.BatchNormalization
  43. 43.GoogLeNet_v3v4
  44. 44.ResNet
  45. 45.ResNeXt
  46. 46.CNN设计准则
  47. 47.图像检索与推土机距离
  48. 48.基于颜色相似性
  49. 49.基于形状相似性
  50. 50.基于纹理相似性
  51. 51.基于局部特征相似性
  52. 52.DL的二值哈希编码
  53. 53.高维空间中检索KDTree
  54. 54.高维空间中检索LSH
  55. 55.目标识别任务综述
  56. 56.RCNN
  57. 57.SPP-Net
  58. 58.Fast R-CNN
  59. 59.Faster R-CNN
  60. 60.R-CNN系列模型回顾
  61. 61.R-FCN的设计思路
  62. 62.R-FCN的实现
  63. 63.YOLOv1
  64. 64.YOLOv2_9000
  65. 65.YOLOv3
  66. 66.图像分割应用场景与数据集
  67. 67.上采样的实现方式
  68. 68.FCN网络架构的由来
  69. 69.FCN构建细节
  70. 70.DeepLabv1
  71. 71.CRF
  72. 72.DeepLabv2
  73. 73.DeepLabv3
  74. 74.特定的医学影像分割任务
  75. 75.U-Net
  76. 76.3D U-Net
  77. 77.V-Net
  78. 78.DenseNet
  79. 79.病理切片分析任务及数据集
  80. 80.病理切片分析
  81. 81.图说任务及其传统处理方法
  82. 82.深度语言模型与RNN
  83. 83.LSTM及其变种
  84. 84.NIC模型
  85. 85.SAT模型
  86. 86.图说的性能指标
  87. 87.判别模型与生成模型
  88. 88.KL散度与JS散度
  89. 89.VAE
  90. 90.GAN的基本原理
  91. 91.DCGAN与CGAN
  92. 92.Wasserstein GAN
  93. 93.SRGAN

Faster R-CNN

小象实战讲义 · 基于深度学习的计算机视觉

在上一节我们学习了Fast R-CNN,它通过RoI池化和多任务损失实现了端到端训练,大幅提升了效率。然而,Fast R-CNN仍然依赖一个离线的传统模块——Selective Search来生成候选区域(Region Proposals),这成为了整个检测流程的性能瓶颈。本节我们将介绍Faster R-CNN,它用一个全新的、可学习的区域提议网络(Region Proposal Network, RPN) 完全取代了Selective Search,首次把候选区域生成也纳入同一个网络,使推理阶段从输入图像直达检测结果(训练方式仍是四步交替优化,见后文),在保持高精度的同时,速度提升了十倍以上。

💡 核心导读

  • RPN的动机:理解为何Selective Search成为性能瓶颈,以及用深度学习模块取代它的必要性。
  • Anchor Box机制:掌握RPN如何通过预设的“锚框”在特征图的每个位置上生成多尺度、多宽高比的候选区域。
  • RPN的网络结构与损失函数:学习RPN如何并行输出“目标/非目标”的分类得分和候选框的位置微调量。
  • 四步交替训练法:掌握Faster R-CNN中RPN与Fast R-CNN模块如何通过四步训练实现参数共享和协同优化。
  • 性能飞跃:了解Faster R-CNN在PASCAL VOC 2007上单图测试时间从2.0s降到0.198s、mAP由66.9%提升到69.9%的表现。

从Fast到Faster:解决最后的瓶颈

回顾Fast R-CNN的流程:输入图像首先经过一个深度卷积网络(如VGG16)提取特征图,然后由Selective Search算法离线生成约2000个候选区域(Region Proposals),这些区域被映射到特征图上,通过RoI池化层统一尺寸,最后送入两个全连接分支分别进行分类和边界框回归。

Fast R-CNN已经对R-CNN和SPP-Net进行了大量优化,但其Region Proposal的生成环节仍然采用传统的Selective Search算法。这个算法基于图像的颜色、纹理等底层特征进行区域合并,计算过程与后续的深度学习检测网络完全割裂,无法进行端到端的优化。更重要的是,在GPU加速的深度学习时代,这个运行在CPU上的传统算法成为了整个系统的速度瓶颈。

Faster R-CNN的核心贡献,就是提出了区域提议网络(RPN),一个全卷积的小型网络,直接集成到整个检测系统中。RPN共享主卷积网络提取的特征,直接在特征图上预测候选区域的位置以及这些区域是“目标”还是“背景”的概率。这样一来:

  1. Region Proposal的生成从“离线”变为“在线”,与检测网络融为一体。
  2. 计算被极大共享,RPN几乎不增加额外计算开销。
  3. 整个系统在推理时端到端:输入图像直达检测结果;训练则采用四步交替优化(见后文),并非一次联合反向传播。

论文中提到,RPN是一种“注意力”机制,它告诉Fast R-CNN网络“应该关注哪里”。请注意,这里的“注意力”是广义上的引导关注,并非后来在自然语言处理和图像描述中流行的、具有明确权重分配的Attention机制。

Region Proposal Network (RPN) 详解

RPN的网络结构

RPN是一个轻量级的全卷积网络。它的输入是主干卷积网络(如VGG16的conv5层)输出的特征图。假设输入图像尺寸为 M×N。VGG16 的共享卷积部分是 conv1_1~conv5_3 共13个卷积层,其间只有 pool1~pool4 这4次步长为2的最大池化(pool5 不在共享主干内,RPN 直接接在 conv5_3 上),因此总步长为 2^4 = 16,conv5 特征图的尺寸为 (M/16) × (N/16),通道数为512。

RPN的操作如下:

  1. 在conv5特征图上,首先应用一个3×3的卷积层(滑动窗口),输出512个通道的特征(论文中 VGG16 为 512 维,ZF 网络为 256 维;课件按 ZF 口径写作 256)。这个3×3卷积的作用是对每个位置的特征进行编码,融合其周围上下文信息。
  2. 对于这个3×3卷积输出的每个空间位置(共 (M/16)×(N/16) 个),我们将其映射到一个512维的向量(VGG16)。
  3. 这个512维的向量被送入两个并行的1×1卷积层(相当于全连接层),形成两个分支:
    • 分类分支(cls layer):输出 2k 个分数。k 是每个位置预设的“锚框”(Anchor Box)数量。2k 表示每个锚框对应两个分数:是目标的概率(foreground score)和是背景的概率(background score)。
    • 回归分支(reg layer):输出 4k 个坐标偏移量。4k 表示每个锚框对应4个值 (dx, dy, dw, dh),用于微调锚框的位置和大小,使其更接近真实物体框。
import numpy as np
import cv2

# 模拟RPN在单个位置上的前向计算(概念演示)
# 假设conv5特征图在某个位置的特征向量(VGG16为512维)
np.random.seed(42)
feature_vector = np.random.randn(512) * 0.1

# 模拟分类分支的权重(2k x 512),此处k=9
W_cls = np.random.randn(18, 512) * 0.01  # 2*9=18
b_cls = np.zeros(18)
cls_scores = np.dot(W_cls, feature_vector) + b_cls
# 通常会对这2k个分数应用softmax,得到前景/背景概率
cls_scores_reshaped = cls_scores.reshape(2, 9)
# 简单softmax
exp_scores = np.exp(cls_scores_reshaped - np.max(cls_scores_reshaped, axis=0, keepdims=True))
cls_probs = exp_scores / np.sum(exp_scores, axis=0, keepdims=True)
# 取前景概率(第0行)
foreground_probs = cls_probs[0, :]

# 模拟回归分支的权重(4k x 512),此处k=9
W_reg = np.random.randn(36, 512) * 0.01  # 4*9=36
b_reg = np.zeros(36)
reg_deltas = np.dot(W_reg, feature_vector) + b_reg  # 形状 (36,)

print("该位置9个锚框的前景概率(示例值):")
print(foreground_probs)
print("\n该位置第一个锚框的回归偏移量 (dx, dy, dw, dh)(示例值):")
print(reg_deltas[:4])
该位置9个锚框的前景概率(示例值):
[0.50206369 0.50911092 0.50069063 0.4975639  0.49870078 0.50817936
 0.50336444 0.50864925 0.49804658]

该位置第一个锚框的回归偏移量 (dx, dy, dw, dh)(示例值):
[-0.01759878 -0.0022231   0.03017764  0.0212929 ]

Anchor Box:候选框的生成基础

关键问题:RPN如何为特征图上的每个位置生成多个不同形状和尺寸的候选框?答案就是 Anchor Box(锚框)。

对于conv5特征图上的每一个像素点(对应原图上一个16×16的区域,因为总步长为16),我们以这个点为中心,预先定义 k 个不同尺寸(scale)和宽高比(aspect ratio)的矩形框,这些框就是锚框。它们是候选框的初始猜测。

在Faster R-CNN的原论文中,作者设置了 k=9 个锚框,由3种尺度(128, 256, 512)和3种宽高比(1:1, 1:2, 2:1)组合而成。这些尺寸是相对于原图的尺寸。这里统一约定“宽高比”指宽:高:一个“尺度256、宽高比1:2”的锚框,指的是面积为 256²、宽:高 = 1:2 的矩形,在原图中的大小约为 181(宽)× 362(高)。

9个Anchor Box的构成(下表中 “A x B” 按 宽×高 记):
尺度 (Scale): 128,           256,           512
宽高比 (Aspect Ratio,宽:高): 1:1, 1:2, 2:1

组合:
1. 128x128 (1:1)
2. 128x256 (1:2) -> 实际约为90x181 (保持面积128^2)
3. 256x128 (2:1) -> 实际约为181x90
4. 256x256 (1:1)
5. 256x512 (1:2) -> 实际约为181x362
6. 512x256 (2:1) -> 实际约为362x181
7. 512x512 (1:1)
8. 512x1024 (1:2) -> 实际约为362x724
9. 1024x512 (2:1) -> 实际约为724x362

说明:这里的“尺度”指锚框面积的开方(128/256/512 分别对应面积 128²、256²、512²),宽高比决定长宽如何分配;步长16只决定相邻锚点之间的间距,并不改变锚框本身的尺寸。

为什么要用 512 这么大的框?论文在预处理时会把输入图像统一缩放,使短边为 600 像素(PASCAL VOC 原图的短边多在 375~500 像素);缩放之后 512 的框仍小于图像边长,才是有意义的。若换成 ImageNet 那种 256×256 的小图,512 的框已经达到图像边长的两倍,就失去了意义。

因此,对于一张输入图像,RPN会生成总共 (M/16) × (N/16) × 9 个锚框。这些锚框覆盖了原图上不同位置、不同大小和形状的区域,理论上能够涵盖图像中可能出现的各种物体。

RPN的损失函数

RPN需要被训练来完成两个任务:1) 判断锚框是目标还是背景(二分类);2) 调整锚框的位置和大小使其更接近真实物体(回归)。

其损失函数定义为: L({pi},{ti})=1Ncls∑iLcls(pi,pi∗)+λ1Nreg∑ipi∗Lreg(ti,ti∗)L(\lbrace p_i\rbrace , \lbrace t_i\rbrace ) = \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^*)

  • ii 是一个mini-batch中锚框的索引。
  • pip_i 是RPN预测的锚框 i 是目标的概率。
  • pi∗p_i^* 是锚框 i 的真实标签。如果锚框与任意真实物体框的IoU > 0.7,则 pi∗=1p_i^*=1(正样本);如果与所有真实物体框的IoU < 0.3,则 pi∗=0p_i^*=0(负样本);IoU在[0.3, 0.7]之间的锚框不参与训练。
  • tit_i 是RPN预测的边界框回归参数,是一个4维向量 (dx,dy,dw,dh)(dx, dy, dw, dh)。
  • ti∗t_i^* 是锚框 i 到与其IoU最大的真实物体框的真实回归参数。
  • LclsL_{cls} 是分类损失,使用二分类交叉熵损失:Lcls(pi,pi∗)=−log⁡[pi∗pi+(1−pi∗)(1−pi)]L_{cls}(p_i, p_i^*) = -\log [p_i^* p_i + (1 - p_i^*)(1 - p_i)]。
  • LregL_{reg} 是回归损失,使用平滑L1损失(Smooth L1 Loss),定义与Fast R-CNN中相同。只有正样本(pi∗=1p_i^*=1)才计算回归损失,负样本的回归损失为0。
  • NclsN_{cls} 和 NregN_{reg} 是归一化项,通常取mini-batch的大小和锚框位置的数量。λ\lambda 是平衡两个损失项的权重参数,论文中默认设为10。

这个损失函数的设计非常巧妙:分类部分确保RPN能区分前景和背景;回归部分则对可能是前景的锚框进行精细的位置调整。

训练时的一个细节:RPN 的一个 mini-batch 只从同一张图片上采样 256 个锚框——RPN 要回答的正是“这张图的哪些位置有目标”,混入多张图片反而没有意义。标签分配有两条并列且无条件生效的规则:① 与任一真实框 IoU>0.7 的锚框为正样本;② 对每个真实框,取与其 IoU 最大的锚框为正样本(保证每个 GT 至少有一个正样本)。这两条规则与 128 的配额无关。采样时正负样本尽量按 1:1 配比(各 128 个),正样本不足 128 时用 IoU<0.3 的负样本补齐。

从锚框到候选区域(Proposal)

在训练和测试时,RPN网络会为成千上万个锚框输出前景分数和回归偏移量。我们需要从中筛选出高质量的候选区域送给后续的Fast R-CNN检测头。流程如下:

  1. 应用回归偏移量:对所有锚框,利用预测的 (dx,dy,dw,dh)(dx, dy, dw, dh) 调整其位置和大小,得到修正后的候选框。
  2. 按前景分数排序:根据修正后候选框的“是目标”的分数(即 pip_i)从高到低排序。
  3. 非极大值抑制(NMS):为了减少冗余,对排序后的候选框应用NMS(IoU阈值通常设为0.7)。这一步会剔除那些与更高分数候选框高度重叠的框。
  4. 选取Top-N:在NMS之后,选取分数最高的前N个候选框(训练时N=2000,测试时N=300)作为最终的Region Proposals,输出给Fast R-CNN模块。

经过RPN筛选后,候选区域的数量从Selective Search的约2000个减少到约300个,并且质量(精准率)显著提高,因为很多明显是背景的锚框在第一步就被低分过滤掉了。

Faster R-CNN的训练策略

Faster R-CNN包含RPN和Fast R-CNN两个模块,它们共享前面的卷积层。如何训练这样一个共享参数的联合网络是一个挑战。论文提出了一个四步交替训练法:

Step 1: 训练RPN
    - 用ImageNet预训练模型初始化共享卷积层参数。
    - 在目标数据集上端到端训练RPN:共享卷积层随RPN一起微调,而不是只训练3x3卷积和两个1x1分支。

Step 2: 训练Fast R-CNN
    - 仍然用ImageNet预训练模型初始化共享卷积层参数(注意,此时不沿用Step1训练过的卷积层)。
    - 使用Step1训练好的RPN生成的候选区域,来训练一个独立的Fast R-CNN检测网络。
    - 此时,RPN和Fast R-CNN的卷积层是分别初始化和训练的,没有共享。

Step 3: 再次训练RPN(调优)
    - 用Step2训练好的Fast R-CNN的共享卷积层参数来初始化RPN的共享卷积层。
    - 固定(冻结)这些共享卷积层的参数,只对RPN特有的层(3x3卷积和两个1x1分支)进行微调(fine-tune)。
    - 此时,RPN的卷积层与Fast R-CNN的卷积层实现了参数共享。

Step 4: 再次训练Fast R-CNN(调优)
    - 保持共享卷积层的参数固定(来自Step3调优后的状态)。
    - 使用Step3调优后的RPN生成的候选区域,仅对Fast R-CNN特有的层(全连接层等)进行微调。

通过这四步训练,RPN和Fast R-CNN最终共享了一套优化过的卷积特征提取器,并且两者协同工作,达到了最佳性能。从Step 3开始,卷积层参数实现共享,这是整个系统高效且有效的关键。

性能对比与总结

在PASCAL VOC 2007测试集上的结果令人印象深刻:

模型单图测试时间mAP (%)
R-CNN~50.0s66.0
Fast R-CNN~2.0s66.9
Faster R-CNN~0.198s69.9

口径说明:R-CNN 行取 VOC 2007+2012 训练(07+12)口径,Fast R-CNN 与 Faster R-CNN 行为 VOC 2007 trainval 训练、VOC 2007 test 测评,主干均为 VGG16。Fast R-CNN 的 ~2.0s 含 Selective Search 提议生成(不含提议生成、只计网络前向约 0.32s,见 9.4 节的表);Faster R-CNN 的 0.198s 是全流程(RPN + 检测头)单图耗时,约合 5 fps,与论文摘要口径一致。

Faster R-CNN将检测速度提升了一个数量级(相比Fast R-CNN快了约10倍),同时把精度从 66.9% 提升到 69.9%。这主要归功于:

  1. RPN取代Selective Search:将Region Proposal生成时间从秒级(CPU)降低到毫秒级(GPU),并与检测网络共享计算。
  2. 推理端到端:测试时输入图像直达检测结果,RPN 与检测头共享同一份卷积特征;训练上则用四步交替优化,不能简单理解为一次联合反向传播。

至此,R-CNN系列模型在Faster R-CNN这里达到了一个里程碑:它提供了一个精度高、速度相对较快的两阶段(Two-Stage) 目标检测框架范式(先提议,再检测),这一范式影响了后续许多工作。

📝 动手练一练

  1. 概念辨析:Faster R-CNN中的“注意力机制”与Transformer或图像描述模型中常用的“Attention机制”有何本质区别?
👉 点击查看参考答案

Faster R-CNN论文中提到的“注意力机制”是一种广义上的、任务导向的注意力。RPN网络的作用是告诉后续的Fast R-CNN检测头“图像中哪些区域可能包含物体,值得重点关注”。它实现的方式是通过生成候选区域(Region Proposals)来缩小检测范围。这是一种硬注意力或基于区域的注意力,输出的是一个具体的、离散的区域列表。

而Transformer或图像描述模型中的“Attention机制”通常指软注意力或自注意力。它通过计算查询(Query)、键(Key)、值(Value)之间的相似度权重,动态地、连续地加权融合不同位置的特征。其输出是一个加权和后的特征向量,权重反映了不同部分的重要性。这种机制更灵活,能够捕捉长距离依赖和复杂的上下文关系。

简言之,RPN的“注意力”是生成待检测的候选框;Transformer的Attention是对特征进行动态加权融合。

  1. Anchor计算:假设输入图像尺寸为 600×800,使用VGG16作为主干网络(卷积部分包含4个最大池化层,步长均为2)。请问conv5特征图的尺寸是多少?如果每个位置设置9个Anchor Box,RPN一共会生成多少个初始锚框?
👉 点击查看参考答案

VGG16 用于 Faster R-CNN 的共享卷积部分是 conv1_1~conv5_3(共13个卷积层),其间只有 pool1~pool4 这4次步长为2的最大池化,因此总步长为 2^4 = 16;pool5 不在共享主干内,RPN 直接接在 conv5_3 上(讲义正文按论文口径把这一层称为“conv5”)。

  • 输入图像尺寸:600 × 800
  • 特征图高:600 / 16 = 37.5,最大池化逐次向下取整(600→300→150→75→37),得 H = 37
  • 特征图宽:800 / 16 = 50,得 W = 50
  • 每个位置有 k = 9 个锚框
  • 初始锚框总数:37 × 50 × 9 = 16650

即约1.66万个初始锚框,经过打分、NMS 和 Top-N 筛选后只保留约300个候选区域。这个量级与论文给出的参考一致:1000×600 的图约 62 × 37 × 9 ≈ 2万 个锚框,论文正文也写作“约2万个”。

本章小结

本节我们深入剖析了Faster R-CNN,它是两阶段目标检测器的经典之作,通过引入区域提议网络(RPN) 把候选区域生成并入网络,实现了检测流程(推理)的端到端化。RPN利用Anchor Box机制在特征图上密集生成多尺度候选框,并通过一个轻量级网络并行预测其前景背景概率和位置回归量。独特的四步交替训练法解决了RPN与检测网络共享卷积层的优化难题。最终,Faster R-CNN在速度上相比Fast R-CNN取得了十倍提升,同时保持了高精度,标志着目标检测技术进入了一个新的阶段。

需要说明的是,Faster R-CNN 发表于 2015 年,属于两阶段检测的奠基性工作;在今天的端到端范式(DETR 系列)与持续迭代的单阶段检测器(YOLO 系列)面前,它更多是理解“提议+检测”范式和锚框机制的经典教材模型(见下文「2026 视角」)。

📋 行动清单

  • 在脑海中复述Faster R-CNN的完整流程:图像 -> 共享卷积特征 -> RPN生成候选区域 -> RoI池化 -> 分类与回归。
  • 理解Anchor Box的尺度和宽高比是如何定义的,并能够计算一张给定图像上初始锚框的大致数量。
  • 回顾四步训练法的每一步目的,理解为何Step 3和Step 4实现了卷积层的参数共享。

2026 视角

自2015年Faster R-CNN提出以来,两阶段检测器因其高精度在学术界和工业界被广泛使用和改进。然而,其固有的复杂性(如Anchor设计、NMS后处理)也促使研究者寻找更简洁的范式。

  1. 端到端检测的兴起:2020年,Facebook AI提出的DETR首次将Transformer成功应用于目标检测,完全摒弃了Anchor和NMS。它使用一组可学习的物体查询(object queries)与全局图像特征进行交互,通过二分图匹配损失直接输出最终的检测集合。DETR展现了强大的概念简洁性和性能潜力,但其训练收敛慢、对小物体检测不佳的问题也催生了如Deformable DETR等一系列改进工作。

  2. YOLO系列的持续进化:作为单阶段检测器的代表,YOLO系列在工程效率上始终领先。YOLOv4/v5在速度和精度上取得了更好平衡,并通过大量工程技巧(如马赛克数据增强、自适应锚框计算)优化了训练。2023年发布的YOLOv8进一步统一了分类、检测、分割任务接口,并提供了极其易用的训练和部署流程,成为当前工业界实际应用最广泛的检测框架之一。

  3. 两阶段检测器的演进与定位:Faster R-CNN的后续改进如Mask R-CNN(增加实例分割分支)、Cascade R-CNN(级联优化检测头)等,在需要极高精度的场景(如学术竞赛、自动驾驶精细感知)中仍有价值。同时,其“提议+检测”的思想也被一些视觉语言大模型(如Grounding DINO)所借鉴,用于开放词汇检测任务。

  4. 当前趋势:如今的目标检测领域呈现出多元化态势。对于极致效率的端侧应用,YOLO系列及其变种是首选。对于研究前沿和新任务探索,基于Transformer的端到端模型(如DETR家族)提供了更灵活和统一的框架。而经典的Faster R-CNN及其变体,作为理解两阶段检测原理和许多后续工作基础的“教科书式”模型,其历史地位和设计思想依然至关重要。学习Faster R-CNN,不仅是学习一个模型,更是理解现代目标检测技术演进脉络的关键一环。

—— 小象教研组