查看全课大纲(第 60 / 93 节)
- 1.计算机视觉概述
- 2.计算机视觉应用场景
- 3.困难与挑战
- 4.开源库介绍
- 5.图像显示与存储
- 6.CLAHE
- 7.腐蚀膨胀与开闭运算
- 8.滤波与边缘填充
- 9.各种滤波
- 10.图像金字塔
- 11.傅里叶变换
- 12.短时傅里叶变换与小波变换
- 13.颜色特征与颜色直方图
- 14.几何特征_边缘
- 15.几何特征-角点与斑点
- 16.局部特征-SIFT特征描述子
- 17.局部特征-SURF特征描述子
- 18.局部特征-ORB特征描述子
- 19.其他特征描述子
- 20.传统图像分割技术
- 21.GraphCut
- 22.GrabCut
- 23.人脸检测的传统方法
- 24.行人检测的传统方法HOG+SVM
- 25.行人检测DPM
- 26.人工神经网络的架构
- 27.目标函数与梯度下降
- 28.误差反向传播
- 29.可手算的神经网络
- 30.改进目标函数与克服梯度消散
- 31.神经网络之传统神经网络与深度网络的差异
- 32.各种梯度下降算法
- 33.如何选择合适的梯度下降算法
- 34.避免过适应
- 35.CNN的架构
- 36.CNN的误差反向传播_卷积层
- 37.CNN的误差反向传播_池化层
- 38.分类所用的数据集
- 39.Alexnet详解
- 40.VGG详解
- 41.GoogLeNet_v1
- 42.BatchNormalization
- 43.GoogLeNet_v3v4
- 44.ResNet
- 45.ResNeXt
- 46.CNN设计准则
- 47.图像检索与推土机距离
- 48.基于颜色相似性
- 49.基于形状相似性
- 50.基于纹理相似性
- 51.基于局部特征相似性
- 52.DL的二值哈希编码
- 53.高维空间中检索KDTree
- 54.高维空间中检索LSH
- 55.目标识别任务综述
- 56.RCNN
- 57.SPP-Net
- 58.Fast R-CNN
- 59.Faster R-CNN
- 60.R-CNN系列模型回顾
- 61.R-FCN的设计思路
- 62.R-FCN的实现
- 63.YOLOv1
- 64.YOLOv2_9000
- 65.YOLOv3
- 66.图像分割应用场景与数据集
- 67.上采样的实现方式
- 68.FCN网络架构的由来
- 69.FCN构建细节
- 70.DeepLabv1
- 71.CRF
- 72.DeepLabv2
- 73.DeepLabv3
- 74.特定的医学影像分割任务
- 75.U-Net
- 76.3D U-Net
- 77.V-Net
- 78.DenseNet
- 79.病理切片分析任务及数据集
- 80.病理切片分析
- 81.图说任务及其传统处理方法
- 82.深度语言模型与RNN
- 83.LSTM及其变种
- 84.NIC模型
- 85.SAT模型
- 86.图说的性能指标
- 87.判别模型与生成模型
- 88.KL散度与JS散度
- 89.VAE
- 90.GAN的基本原理
- 91.DCGAN与CGAN
- 92.Wasserstein GAN
- 93.SRGAN
R-CNN系列模型回顾
小象实战讲义 · 基于深度学习的计算机视觉
本节我们将对目标检测领域中经典的R-CNN系列模型进行一次系统的回顾与总结。通过对比R-CNN、SPP-Net、Fast R-CNN和Faster R-CNN这四种模型的演进过程,你将清晰地理解目标检测技术是如何从“多阶段、慢速”走向“端到端、快速”的,并能准确说出每一次改进的核心动机与关键技术。
💡 核心导读
- 模型演进脉络:从R-CNN到Faster R-CNN,模型经历了共享卷积计算、统一损失函数、端到端训练以及区域建议网络化四个关键阶段。
- 核心改进对比:掌握每个模型相比前一代的“变”与“不变”,理解为何要做出这些改变(例如,从逐区域独立卷积到整图共享卷积是为了提升速度)。
- 结构细节辨析:注意R-CNN早期版本与Fast/Faster R-CNN在全连接层输入来源上的关键区别,避免对示意图产生误解。
- 训练流程理解:重点回顾Faster R-CNN独特的四步交替训练法,理解其如何协调区域建议网络(RPN)与检测网络。
模型演进总览
R-CNN系列模型的发展,是一个不断将传统步骤“深度学习化”,并追求更高效率和更好端到端性能的过程。我们可以通过一张演进图来把握其核心脉络:
演进主线:R-CNN -> SPP-Net -> Fast R-CNN -> Faster R-CNN
R-CNN:
- 区域建议特征: Selective Search (传统方法)
- 端到端微调: 无(CNN 可单独微调,但 SVM/回归器分开训练)
- 池化: 普通Max Pooling
- 网络: 独立的CNN+SVM+回归器
SPP-Net:
- 区域建议特征: Selective Search (传统方法)
- 端到端微调: 无(SPP 层本身可微,但每个 RoI 来自不同图片、感受野常覆盖整图,
穿过 SPP 层反传代价过高,实际只能训练全连接层)
- 池化: SPP (空间金字塔池化)
- 网络: 整图卷积 + SPP层 + SVM/回归器
- **核心改进**: 共享卷积计算(整图一次卷积,而非每个候选区域)
Fast R-CNN:
- 区域建议特征: Selective Search (传统方法)
- Fine-tuning: 有(端到端,可微调所有层)
- 池化: RoI Pooling (单尺度)
- 网络: 整图卷积 + RoI Pooling + 多任务头(Softmax+回归)
- **核心改进**: 1. 多任务损失函数统一训练;2. 可端到端反向传播。
Faster R-CNN:
- 区域建议特征: RPN (区域建议网络,深度学习)
- Fine-tuning: 有(端到端)
- 池化: RoI Pooling
- 网络: 共享卷积 + RPN + RoI Pooling + 多任务头
- **核心改进**: 用RPN神经网络替代Selective Search,实现完全深度学习化的区域建议。这个演进过程清晰地展示了目标检测模型优化的几个核心方向:计算共享化、训练端到端化、组件神经网络化。
R-CNN 与 SPP-Net:共享卷积计算的诞生
让我们首先回顾最初的R-CNN和它的第一个重要改进SPP-Net。
R-CNN 的工作流程:
- 输入一张图片。
- 使用 Selective Search 算法生成约2000个候选区域(Region Proposals)。
- 将每个候选区域变形(Warp) 成固定大小(如227x227)。
- 每个变形后的区域分别通过一个卷积神经网络(如AlexNet)提取特征。
- 提取的特征一方面送入SVM进行分类(R-CNN 论文用的是第7层全连接层的4096维向量);另一方面(对于正样本)用更浅的 pool5 卷积特征做边界框回归(Bounding Box Regression) 微调位置——回归头不用 fc7,这一点后文会再次强调。
- 最后应用非极大值抑制(NMS) 去除冗余框。
import numpy as np
import cv2
# 模拟R-CNN中“每个候选区域分别卷积”的耗时过程(概念演示)
# 假设有一张图片和Selective Search生成的N个候选框
# 注意:此为逻辑示意,非真实运行代码
print("R-CNN 流程示意(伪代码):")
print("1. 输入原始图片。")
print("2. Selective Search 生成 ~2000 个候选框。")
print("3. for 每个候选框 in 2000个框:")
print(" a. 裁剪并变形区域为 227x227。")
print(" b. 将该区域输入CNN(如AlexNet)进行前向传播。")
print(" c. 获取第7层全连接特征(4096维)。")
print("4. 用所有区域的特征训练SVM分类器(离线)。")
print("5. 对正类区域进行边界框回归。")
print("6. 应用非极大值抑制(NMS)输出最终检测框。")
print("\n关键瓶颈:步骤3需要执行 ~2000 次CNN前向传播,极其耗时。")R-CNN 流程示意(伪代码):
1. 输入原始图片。
2. Selective Search 生成 ~2000 个候选框。
3. for 每个候选框 in 2000个框:
a. 裁剪并变形区域为 227x227。
b. 将该区域输入CNN(如AlexNet)进行前向传播。
c. 获取第7层全连接特征(4096维)。
4. 用所有区域的特征训练SVM分类器(离线)。
5. 对正类区域进行边界框回归。
6. 应用非极大值抑制(NMS)输出最终检测框。
关键瓶颈:步骤3需要执行 ~2000 次CNN前向传播,极其耗时。SPP-Net 的核心改进: R-CNN的致命瓶颈在于,2000个候选区域需要分别进行完整的CNN前向传播,计算冗余巨大。SPP-Net提出了一个革命性的想法:整图卷积,共享计算。
- 对整张输入图片进行一次完整的卷积操作,得到整图的特征图(例如,VGG16的conv5层输出)。
- 同样使用Selective Search在原图上生成候选区域。
- 将每个候选区域映射到整图特征图上的对应区域。
- 关键步骤:由于不同候选区域在特征图上的大小不同,SPP-Net引入了空间金字塔池化(SPP)层。SPP层将任意大小的特征区域,池化成固定长度的输出(例如,
(4x4, 2x2, 1x1)三个尺度共16+4+1=21个空间块,每个块做Max Pooling;下面为便于演示假设通道数为256,则输出为21*256=5376维;VGG16 实际 conv5 为 512 通道,对应21*512=10752维)。 - 固定长度的SPP层输出送入后续的全连接层和SVM/回归器。
import numpy as np
# 模拟SPP层对单个任意大小区域的特征图进行池化(概念性计算)
# 假设输入特征区域大小为 (h, w, c) = (任意, 任意, 256)
# SPP层设置:金字塔等级为 [4x4, 2x2, 1x1]
print("SPP层计算示意(固定输出维度):")
print("输入特征区域: 高度 h, 宽度 w, 通道数 c=256")
print("SPP金字塔等级: [4x4, 2x2, 1x1]")
print("")
print("对于等级 4x4:")
print(" - 将特征区域网格划分为 4x4=16 个bin。")
print(" - 每个bin内进行Max Pooling,输出一个值(每个通道独立)。")
print(" - 输出形状: (4, 4, 256) -> 展平为 4*4*256 = 4096 维")
print("")
print("对于等级 2x2:")
print(" - 划分为 2x2=4 个bin。")
print(" - 输出形状: (2, 2, 256) -> 展平为 1024 维")
print("")
print("对于等级 1x1:")
print(" - 划分为 1x1=1 个bin(即全局Max Pooling)。")
print(" - 输出形状: (1, 1, 256) -> 展平为 256 维")
print("")
print("最终SPP层输出(拼接): 4096 + 1024 + 256 = 5376 维")
print("无论输入区域(h,w)多大,输出总是固定的5376维。")SPP层计算示意(固定输出维度):
输入特征区域: 高度 h, 宽度 w, 通道数 c=256
SPP金字塔等级: [4x4, 2x2, 1x1]
对于等级 4x4:
- 将特征区域网格划分为 4x4=16 个bin。
- 每个bin内进行Max Pooling,输出一个值(每个通道独立)。
- 输出形状: (4, 4, 256) -> 展平为 4*4*256 = 4096 维
对于等级 2x2:
- 划分为 2x2=4 个bin。
- 输出形状: (2, 2, 256) -> 展平为 1024 维
对于等级 1x1:
- 划分为 1x1=1 个bin(即全局Max Pooling)。
- 输出形状: (1, 1, 256) -> 展平为 256 维
最终SPP层输出(拼接): 4096 + 1024 + 256 = 5376 维
无论输入区域(h,w)多大,输出总是固定的5376维。R-CNN vs SPP-Net 的“变”与“不变”:
- 不变:区域建议仍然使用传统的Selective Search。
- 关键改变:卷积计算方式。R-CNN是“先建议后卷积”,SPP-Net是“先卷积后建议”,实现了巨大的速度提升。
- 遗留问题:SPP 层本身是可微的——它和 RoI Pooling 一样,都是“把区域分成若干 bin、每个 bin 内做 Max Pooling”,梯度会经
argmax回传到前向时取到最大值的位置。SPP-Net 无法对 SPP 层之前的卷积层做端到端微调(Fine-tuning),原因不在可微性,而在训练方式:它的每个 RoI 来自不同的图片,感受野常常覆盖整张图,穿过 SPP 层反传的代价过高,实际只能训练全连接层。因此训练仍是多阶段的(卷积网络预训练、SVM 训练、回归器训练)。
SPP-Net 到 Fast R-CNN:端到端训练的统一
Fast R-CNN 在SPP-Net的基础上,致力于解决端到端训练的问题,并进一步简化流程。
Fast R-CNN 的核心改进:
- RoI Pooling 替代 SPP层:SPP层是多尺度的(如
4x4, 2x2, 1x1),而RoI Pooling是单尺度的(如固定输出7x7)。它将任意大小的候选区域特征图均匀划分成H x W(如7x7)个网格,每个网格内进行Max Pooling。这简化了操作,且是可微的,允许梯度反向传播。 - 多任务损失函数(Multi-task Loss):这是最重要的改进。Fast R-CNN将分类和边界框回归统一到一个网络框架内,并用一个联合损失函数进行端到端训练: 其中:
- 是分类的交叉熵损失,是Softmax输出的概率分布,是真实类别。
- 是回归的Smooth L1损失,用于优化边界框参数。是一个指示函数,仅对前景物体()计算回归损失。是平衡权重。
- 端到端训练:得益于RoI Pooling的可微性和多任务损失,误差信号可以从网络顶部的分类回归头,一直反向传播到底部的卷积层。这意味着整个网络(包括卷积层)都可以在目标检测数据集上进行微调(Fine-tuning),从而让特征提取器更适应检测任务。
SPP-Net vs Fast R-CNN 的“变”与“不变”:
- 不变:区域建议仍然使用Selective Search。整体结构仍是“整图卷积 -> 区域映射 -> 池化 -> 全连接”。
- 关键改变1:池化层从SPP变为RoI Pooling(单尺度、固定输出),并配合按图采样的小批量训练,使穿过池化层反传梯度的代价真正降下来。
- 关键改变2:训练目标从多阶段(SVM+回归器)变为统一的多任务损失函数,实现端到端联合训练。
- 结果:训练更简单,检测精度和速度均有提升。
Fast R-CNN 到 Faster R-CNN:区域建议的神经网络化
尽管Fast R-CNN在检测部分实现了端到端,但其区域建议模块仍然依赖外部、耗时的Selective Search算法。Faster R-CNN的终极目标,就是用神经网络(Region Proposal Network, RPN)替代Selective Search,实现完全端到端的目标检测。
Faster R-CNN 的核心创新:RPN(区域建议网络) RPN是一个小型神经网络,与主干的特征提取网络共享卷积特征。它直接在卷积特征图上滑动一个小窗口(通常为3x3卷积),并为每个滑动窗口中心位置预测多个(如9个)不同尺度和长宽比的锚框(Anchor) 是否为物体以及需要如何调整。
- 共享特征:输入图片经过共享卷积网络(如VGG的conv1-5)得到特征图。
- RPN结构:
- 在特征图上每个点(对应原图的一个区域)应用一个
3x3卷积,进一步融合上下文信息。 - 然后分两个头:
- 分类头(cls):一个
1x1卷积,输出2k个分数(k个锚框,每个框是前景/背景的概率)。 - 回归头(reg):一个
1x1卷积,输出4k个坐标(k个锚框,每个框有(dx, dy, dw, dh)四个调整参数)。
- 分类头(cls):一个
- 在特征图上每个点(对应原图的一个区域)应用一个
- RPN输出:RPN会产生大量的候选框(例如约20000个),经过概率过滤和NMS后,只剩下约300个质量较高的候选框(Region Proposals),提供给后续的Fast R-CNN检测模块(即RoI Pooling + 分类回归头)。
Fast R-CNN vs Faster R-CNN 的“变”与“不变”:
- 不变:检测头(RoI Pooling + 分类回归全连接层)的结构和损失函数基本一致。
- 革命性改变:区域建议模块从Selective Search(传统算法) 变为RPN(神经网络)。RPN与特征提取网络共享卷积计算,几乎不增加额外开销。
- 整体架构:Faster R-CNN = 共享卷积网络 + RPN + Fast R-CNN检测头。实现了“特征提取 -> 区域建议 -> 检测分类”的完全神经网络化。
关于网络结构的特别说明 在对比图示中,需要注意一个细节:在原始的R-CNN和SPP-Net中,分类头和回归头的输入来源是不同的(分类来自更深的全连接层特征,回归来自较浅的卷积层特征)。但在Fast R-CNN和Faster R-CNN中,这个设计被改变了。分类和回归两个头共享同一个全连接层(如FC6, FC7)提取的特征,然后再分叉。课件中的示意图可能用统一的箭头表示这种共享输入的关系,我们在理解时应以实际论文和代码描述为准。
Faster R-CNN 的四步交替训练法
由于RPN和Fast R-CNN检测头需要共享卷积特征,但又相互依赖(RPN提供候选框,检测头需要这些框进行训练),Faster R-CNN论文提出了一种巧妙的四步交替训练法:
四步交替训练的具体流程如下:
- 步骤1:用 ImageNet 预训练权重初始化共享卷积,单独训练 RPN。
- 步骤2:仍用 ImageNet 预训练权重初始化共享卷积,用步骤1的 RPN 生成候选框,训练 Fast R-CNN 检测头(此时共享卷积也被微调)。
- 步骤3:用步骤2得到的共享卷积权重初始化,固定共享卷积,只微调 RPN。
- 步骤4:保持共享卷积固定,用步骤3的 RPN 生成候选框,只微调 Fast R-CNN 检测头。
最终,RPN 与检测头共享同一套卷积特征,形成统一的目标检测网络。这种交替训练策略使二者逐步协调,并各自发挥最佳性能。
📝 动手练一练
- 概念辨析:请简述SPP-Net中的SPP层与Fast R-CNN中的RoI Pooling层的主要区别(至少两点),并说明RoI Pooling如何支持端到端训练。
👉 点击查看参考答案
主要区别:
- 尺度数量:SPP层采用多尺度金字塔池化(如
4x4, 2x2, 1x1),而RoI Pooling是单尺度池化(如固定输出7x7)。 - 设计目的与训练方式:SPP层旨在解决任意大小输入到固定长度输出的问题,结构相对复杂;RoI Pooling把这件事简化成单尺度。两者都是“分 bin + Max Pooling”,本身都可微(梯度经
argmax回传到最大值位置)。真正的差别在训练方式:SPP-Net 的每个 RoI 来自不同图片、感受野常覆盖整图,穿过 SPP 层反传代价过高,实际只能训练全连接层;Fast R-CNN 按图采样小批量 RoI,共享卷积对每张图只算一次,反传才真正可行。
支持端到端训练:RoI Pooling的运算可以分解为两个步骤:(a) 将候选区域在特征图上的对应区域划分为固定数量的网格(如7x7);(b) 对每个网格进行Max Pooling。这个过程可以通过记录每个网格内最大值的位置(argmax)来实现梯度回传。在反向传播时,梯度只回传到前向传播时被选为最大值的位置。这种设计使得梯度能够穿过RoI Pooling层,继续反向传播到更底层的卷积网络;再叠加“同一张图的多个 RoI 共享一次卷积前向”的小批量采样,整个网络的端到端微调(Fine-tuning)才在计算上划算。
- 流程理解:在Faster R-CNN的四步交替训练法中,第二步“训练Fast R-CNN检测头”时,所使用的区域建议(候选框)是从哪里来的?这一步训练会更新网络中哪些部分的权重?
👉 点击查看参考答案
- 区域建议来源:在第二步训练中,所使用的区域建议(候选框)是由第一步训练好的RPN生成的。
- 更新的权重:这一步训练会更新整个Fast R-CNN检测头的权重,具体包括:
- RoI Pooling层之后的所有全连接层(例如FC6, FC7, FC8)。
- 同时,由于实现了端到端反向传播,共享卷积层(conv1-5)的权重也会被更新(微调)。 因此,第二步不仅训练了检测头,也使用检测任务的损失进一步优化了特征提取器。
本章小结
本节我们系统回顾了目标检测R-CNN系列模型的演进之路:
- R-CNN:开创了用CNN提取特征进行目标检测的先河,但速度慢,训练复杂。
- SPP-Net:提出整图卷积和空间金字塔池化(SPP),大幅提升速度,但无法端到端微调卷积层。
- Fast R-CNN:引入RoI Pooling和多任务损失函数,实现了分类与回归的端到端联合训练,可微调所有网络层。
- Faster R-CNN:革命性地提出区域建议网络(RPN),用神经网络替代了传统的Selective Search,实现了从区域建议到检测的完全端到端流程,并通过四步交替训练法有效协调RPN与检测网络。
每一次改进都直指前一代模型的痛点,推动着目标检测技术向着更高效、更统一、更智能的方向发展。
今天,两阶段检测已演进到 Mask R-CNN、Cascade R-CNN 等后续工作,工业界更常用 YOLO 系列、DETR/Transformer 检测器;但 R-CNN 系列确立的“共享卷积 + 区域建议 + RoI 池化 + 多任务损失”仍是理解现代检测器的骨架。
📋 行动清单
- 尝试画出R-CNN、SPP-Net、Fast R-CNN、Faster R-CNN四者的核心数据流图,并标注出关键的不同点。
- 向同伴或自己复述:从R-CNN到Faster R-CNN,区域建议、特征提取、分类回归这三个核心模块分别发生了怎样的变化?
- (进阶)思考:Faster R-CNN的RPN和检测头都包含“分类”和“回归”,这两个部分的“分类”任务有何异同?
—— 小象教研组
配套资料 · 直接下载
课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。