
这是薰风读论文的第 6 篇投稿,其中内容若有问题欢迎讨论~
薰风说
R-CNN的性能瓶颈主要都在区域提议(Region Proposal/RoI)上,而这个系列用了连续用了两篇论文解决了这个问题。
- RoI的获取太麻烦(选择性搜索Selective Search)且正确率感人。
- RoI的特征提取太耗时(先切图片,然后CNN提特征,导致数据无法共享),且中间涉及大量的硬盘读写,数据要在硬盘,内存,现存三者之间来回倒腾。
Fast R-CNN把问题解决了一半(第二个问题),第一个问题还得看Faster RCNN。
顺便一提,因为选择性搜索实在是太菜了……所以我甚至觉得它才是导致RCNN和Fast RCNN没人复现的最主要原因。
最后,如果看完整篇内容(或者大致翻一下),会发现其中有很多我给出的链接。那是很多我前几天写的知识点/论文阅读,因为各个知识点/模型都有很多共通的地方。触类旁通,则事半功倍。
一、太长不看版
R-CNN的主要性能瓶颈在于需要
对每个提议区域独立抽取特征。
由于这些区域通常有大量重叠,独立的特征抽取会导致大量的重复计算。Fast R-CNN对R-CNN的一个主要改进在于只对
整个图像做卷积神经网络的前向计算。
Fast R-CNN示意图
它的主要计算步骤如下。
1. 提取特征
与R-CNN相比,Fast R-CNN用来
提取特征的卷积神经网络的输入是整个图像,而不是各个提议区域。
而且,由于用于提取特征得网络参数可以通过训练更新。
设输入一张图像,将CNN的输出尺寸记为
2. RoI与Roi pooling
假设已经有选择性搜索Selective Search生成了
个提议区域Region Proposal/Region of Interest(RoI)。这些RoI的大小各异,因此需要额外操作提取相同尺寸的特征(假设高和宽为
和
)以便于连结后输出。Fast R-CNN引入兴趣区域池化(region of interest pooling,RoI池化)层,将卷积神经网络的输出和提议区域作为输入,输出连结后的各个提议区域抽取的特征,输出大小为
。
动图往往比文字有效
3. 预测
通过全连接层将输出形状变换为 n×d ,其中超参数 d 取决于模型设计。
• 预测类别时,将全连接层的输出的形状再变换到 n×q 并使用softmax回归(q 为类别个数)。
• 预测边界框时,将全连接层的输出的形状变换为 n×4。(为每个提议区域预测类别和边界框)
Fast R-CNN中提出的兴趣域池化层 Roi Pooling 与我们熟知的各类池化层不同。
- 传统池化层通过设置池化窗口宽度 width 、填充 padding 和步幅 stride 来间接控制输出形状。
- 而 Roi Pooling 层则通过参数设置直接控制输出形状。
二、 引言 Why Fast R-CNN
1. 区域提议的困境
R-CNN的横空出世,让CNN攻下了计算机视觉的另一个堡垒——目标检测,可谓是深度学习解决目标检测任务的开山之作。
薰风初入弦:薰风读论文:R-CNN 深入浅出理解目标检测开山之作zhuanlan.zhihu.com
然而,它本身有着诸多局限,最大的莫过于其中的区域提议“Reigon Proposal”了,和现在我们的常识不同,R-CNN(其实包括Fast R-CNN本身也是)在目标检测的第一步“判断哪可能有东西”时,并没有用到任何“学习”的部分,而单纯的是基于规则的算法(选择性搜索,selective search)。
提高效果需要精确的区域提议 → 但由于区域提议不精确 → 为了确保召回率需要大量的区域提议 → 要处理过多的RoI → 计算量提升。这就是论文开头分析的
复杂度上升困境2. 为何RCNN是个弟弟
一个模型训三轮:
- 第一轮训在Roi上提特征的CNN,用sotfmax分类的log loss(但因为效果太差这里的分类不能用……)
- 第二轮把CNN的softmax分类器换成SVM再分类
- 最后回归边框
特征不能现提现用
由于
即使同一张图片,每个Roi提取特征都是独立的过程。因此提取一个Roi的特征后要先写到硬盘再读出来分类/回归,费时占地。
慢
区域提议困境+一个模型训三轮+特征来回倒=速度贼慢
虽然Fast R-CNN没用从根本上解决区域提议导致的复杂度上升困境。但解决了R-CNN比较弟弟的几个问题。
其中慢的问题是前个问题导致的,而如果可以将训三轮转为“Single-stage train”(论文原文的说法,与SSD Yolo的“one-stage”不是一个东西!),即
一次可以训练特征提取+分类+回归。那么第一个问题就迎刃而解了。而对于第二个特征问题,作者认为这是由于
RCNN前向的各个RoI没有共享计算。一张照片截出来的Roi,为什么不直接共享来自整张图片的特征呢?
2. 贡献
-
-
- 通过多任务损失,变为单阶段训练(一次搞定分类+回归)
- 更新不用分成那么多步了,都在一个大网络上搞,一次更新所有参数
- 采用Roi Pooling,优化minibatch采样策略,提特征就再也没硬盘什么事了
-
三、Fast R-CNN的结构
图像+一堆ROI输入全卷积网络→RoI pooling到固定尺寸→特征图FC到特征向量→两个输出:含背景的分类概率+每个分类的边界框回归偏置
1. 算法输入:
整张图和一堆
区域提议(选择性搜索)
2. 提取全局特征:
通过conv+最大池化,提取输入的整张图片的整个特征图(这个时候没区域提议什么事)
3. 抽取Roi特征:
由于Roi大小不一,所以需要Roi池化来提取特定部分的特征。抽取的每个特征向量过几个fc,就可以连接输出层了。
4. 两兄弟输出层:
-
-
- K+1类(类别数+背景类)softmax概率(就不用什么先softmax后svm了)
- 每个类都有4个实值,对应每个类的边框
-
注:从逻辑上,你可以认为RCNN是
先区域提议后提特征,Fast R-CNN是
先提特征后区域提议。(实际上是Fast R-CNN的区域提议与特征提取解耦了)
四、RoIpooling
ROI是框在conv特征图上的一个方型,用四元组定义(左上顶点r、c,高h和宽w),显然,RoI的大小是各不相同的,(无预处理的情况下)CNN无法处理大小不同的特征。这也是为什么R-CNN想不到共享特征的原因。
那么,我们需要一个将特征图的特定区域改变维度(通常是降维)的工具,这个工具就是我们经常使用的池化(pooling)。
然而,Fast R-CNN中提出的兴趣域池化层 Roi Pooling 与我们熟知的各类池化层不同。
- 传统池化层通过设置池化窗口宽度 width 、填充 padding 和步幅 stride 来间接控制输出形状。
- 而 Roi Pooling 层则通过参数设置直接控制输出形状。
任一子窗口的高和宽要取整,其中的
最大元素作为该子窗口的输出。因此,兴趣区域池化层可从形状各异的兴趣区域中均抽取出形状相同的特征。
下图在4×4的输入上,选取了左上角的3×3区域作为Roi。对Roi做2×2的Roi Pooling 得到2×2的输出。
4个划分后的子窗口分别含有元素(Roi pooling的每个网格大小不一定相等!):
- 0、1、4、5(5最大)
- 2、6(6最大)
- 8、9(9最大)
- 10
2×2兴趣区域池化层
五、特征提取与采样策略
Fast R-CNN的特征提取器依然是CNN,由ImageNet预训练得来,不过预训练的CNN需要进行如下三个转换:
- CNN的最后一个最大值池化换成RoI
- 最后的fc和softmax换成了两个兄弟输出(分类+回归)
- 输入变成俩:图片+(一堆)RoI
由于从头(特征提取)到尾(分类回归),计算的数据都没有脱离CNN得到的特征,因此整个训练过程是连续的整体,一次即可更新所有参数。这大大提高了训练的效率。
而得益于RoI Pooling,前向时为了得到特定的RoI,需要处理更大范围的图片,这变相提高了输入的感受野。
因此,可以认为Fast R-CNN好就好在特征提取与Roipooling部分共享特征与参数了。
而刚刚提到的好处建立在一个基础上:即
每次训练的RoI都是来自同一张图片,因此Fast R-CNN训练时的训练样本需要特定的采样策略。
假设SGD的minibatch有R个输入,涉及N张完整图片,那一个batch里每个图就有R/N个RoI。
N小了,那一个batch就有更多图可以前反向时共享特征,提高处理效率。
除了少图片多RoI这个策略,还有就是控制正负例样本的比值为1:3以及难例挖掘,具体的可以看我的这篇笔记
薰风初入弦:薰风AI知识点:Hard Negative Mining/OHEM 你真的知道二者的区别吗?zhuanlan.zhihu.com
六、输出与多任务损失
每个RoI都有自己的输出:- softmax得出的,K+1维(K是数据集目标类,还有一个背景类)的概率
fastrcnn网络模型_薰风读论文:Fast R-CNN 模型原理/细节/冷知识 - K个物体类的坐标,(大写K是目标类数,小写k是目标类的索引)
fastrcnn网络模型_薰风读论文:Fast R-CNN 模型原理/细节/冷知识
严谨来讲这不是坐标,而是第k类尺度不变的平移和log空间的高/宽位移与输出对应的ground truth:
- 概率 对应的标签类别
fastrcnn网络模型_薰风读论文:Fast R-CNN 模型原理/细节/冷知识 fastrcnn网络模型_薰风读论文:Fast R-CNN 模型原理/细节/冷知识 - 坐标 对应回归目标
fastrcnn网络模型_薰风读论文:Fast R-CNN 模型原理/细节/冷知识 fastrcnn网络模型_薰风读论文:Fast R-CNN 模型原理/细节/冷知识
意味着只考虑真实分类对应的边界框与Ground Truth的误差![]()
fastrcnn网络模型_薰风读论文:Fast R-CNN 模型原理/细节/冷知识
由此我们可以得出多任务的损失函数:
我知道这看起来挺唬人的……那我们拆开来说:
对应颜色对应解释
首先,损失由两个部分组成
一个是分类的负对数损失
,顺带一说,负对数损失就是softmax分类器的标配,具体原因详见softmax的知识点。 薰风初入弦:薰风AI知识点:Softmax与交叉熵的数学意义(信息论与概率论视角)zhuanlan.zhihu.com
就是定位损失啦,它的损失函数采用的是smooth L1损失,具体地说,对四个坐标分别进行smooth L1,然后加起来,就像下面这样:
其中:
相比L2,这种loss对异常值不敏感,L1随随便便就过去了,L2做损失则还需要小心学习率以防梯度爆炸。
λ则负责平衡两个部分的大小,避免出现两个Loss模值相差过大的情况。(如果两边差的不大,或者两个Loss内写了缩放/归一化,那么没有它也可以)
七、 冷知识
这里指一些没什么人提,也的确对后面影响不大的内容。
- 当时已经有人用cnn找proposal了,但作者觉得和本文无瓜(有瓜就没faster r-cnn什么事了)
作者说Fast R-CNN由两个原因获得了尺度不变性(即解决了小目标检测的老大难问题)。一个是因为RoI Pooling本身就涉及对不同大小特征图的放缩,练久了就尺度不变性了。
还有一个说的是,因为它们在测试时还用了“Image Pyramid”,是不是很熟悉,就是我之前笔记里被FPN喷得很惨的那个。
薰风初入弦:薰风读论文:Feature Pyramid Network 详解特征金字塔网络FPN的来龙去脉zhuanlan.zhihu.com
Fast R-CNN在训练时卷积部分最为耗时,而测试时则是全连接层部分耗时。而因为我们说模型快不快通常说的都是测试(前向)速度。因此,Fast R-CNN采用了截断SVD压缩全连接层(几年前流行的办法,现在嘛……)
数学定义上,当t比原矩阵尺寸小很多则压缩效果贼明显。实际测试中RoI很多的时候,加速明显