写在前面
计算机视觉共有三大核心任务,图像分类目标检测图像分割。今天我们来讲下目标检测领域所用基本框架。
目标检测领域算法目前可分为两部分。
两步走(two-stage)算法:先产生候选区域然后再进行CNN分类。其中包括RCNN、FastRCNN,Faster RCNN,MASKRCNN。
一步走(one-stage)算法:直接对输入图像应用算法并输出类别和相应的定位。其中包括YOLO算法系列和SSD算法系列。
本专题将按照从两步走(two-stage)算法到一步走(one-stage)算法的顺序依次讲下去。
限于篇幅,本章主要涉及到的内容会有3个,分别是RCNN、Fast RCNN和Faster RCNN。Faster RCNN的补充FPN和Mask RCNN会放到第二篇,YOLO系列会放到第三篇,SSD系列会放到第四篇。共分四个章节将目标检测领域的常用结构讲清楚。
由RCNN到Fast RCNN,再到Faster RCNN,本质上是对目标检测算法不断改进的过程。以RCNN为基点,先是提出了金字塔池化网络SPP对CNN提取特征时图像的缩放提出了改进,再到RCNN中提出了ROI Pooling对金字塔池化网络进行改进,最后到Faster RCNN中提出RPN对Selective Search算法进行改进(以上名词,后面文章中均会有讲解)。
因此,本文在讲解过程中会以RCNN为母体,一路重点讲解这些网络发展过程中的改进算法。读者看完文章后可以再回过来看开头这些话,相信你会有不少的领悟。
本篇文章前后共历经十余次修改,反复修改的目的是为了能尽可能地向读者通俗易懂讲解,这才是写文章的意义。

一 RCNN

RCNN作为将深度学习引入目标检测算法的开山之作。是two-stage算法的代表之作。R是指Region(区域)。
R-CNN采用的是selective search的方法来预先提取一些较可能是目标物体的候选区域。方法可分为四个步骤:

  1. 生成候选区域
  2. 对候选区域使用CNN进行特征提取
  3. 将提取的特征送入SVM分类器
  4. 最后使用回归器对目标位置进行修正

    下面将从上面四个步骤依次解读RCNN。

生成候选区域–selective search

Q1:什么是selective search?

讲selective search之前,先讲下比selective search方法更原始的滑窗法。

滑窗法是最原始的生成图片候选框的方法,实现起来原理也非常简答,可以理解为使用两重for循环实现。第一重循环遍历图片中所有位置,第二重循环遍历所有的窗口大小(可预先设置好)。很显然,滑窗法的效率非常低下,运算量特别大。于是,RCNN采用选择性搜索的方法生成候选区域,基本步骤可分为3步。

(1)先通过简单的区域划分算法,将图片划分成很多小区域,划分方法参照论文《Efficient Graph-Based Image Segmentaion》;

(2)再通过相似度和区域大小(小的区域先聚合,这样是防止大的区域不断的聚合小区域,导致层次关系不完全)不断聚合相邻小区域,类似于聚类的思路,最后得到需要的候选框;

(3)通过不停的迭代,候选区域列表中的区域越来越大,可以说我们通过自底向下的方法创建了越来越大的候选区域。最后选取其中1000-2000个作为候选框。这样一来大大减少了计算量。

下面从另一篇文章中扒了一张图(参考资料1),让大家感受下selective research方法的效果。

怎么样将fasterrcnn和yolo结合起来 yolo与rcnn_机器学习


注意,利用selective search方法得到候选框后不能直接拿来进行CNN特征提取,因为CNN对输入图片有着统一的尺寸要求,因此还需对生成的候选框进行统一的缩放处理。缩放处理方法有2种,一种是各项异性缩放(anisotropically scales):不论候选框的长宽比例,直接进行缩放。第2种是各项同性缩放:即如果候选框存在长宽比例不一致的情况,则进行裁剪和填充使得比例一致。

CNN特征提取

候选框生成完毕后则利用CNN结构对输入候选框进行特征提取。在标注的训练数据不足的情况下,可利用预训练模型进行迁移学习。论文给出了2种CNN网络结构,即AlexNet和VGG16。VGG16的网络结构较AlexNet更为复杂,但模型效果相对更好。
这里要注意的是,selective search会产生1-2k个候选框,然而这1-2k个候选框与人工标注的候选框一般不会完全重合,所以我们要利用CNN为这些候选框进行打标,根据交并比IOU来选择。当selective search搜索出的候选框与人工标注的候选框IOU达到0.5(默认值)以上时,这个候选框就是目标物体(正样本),其他的标注为负样本。

SVM分类器进行分类

将CNN提取的特征利用SVM进行分类,输出正样本的类别。

线性回归器进行边界框回归

SVM对正样本进行分类得出类别标签之后,再将边界框(4个值,分别为左上角坐标,右上角坐标)利用回归器进行回归。

改进:什么是金字塔池化网络SPP-Net?

我们前面提到,在CNN进行特征提取之前,需要将候选框缩放成统一大小的固定尺寸,这个过程同样非常花费时间。为了解决这个问题,何恺明等提出了金字塔池化网络(Spatial Pyramid Pooling Net)。

这里再解释一下为何在CNN进行特征提取之前需要将候选框放缩成统一大小的固定尺寸。

通常一个CNN包括两个部分:卷积层和全连接层,参数是事先设置好的。我们直接定位到网络的最后一个卷积层和全连接层中间,假如进入CNN的候选框大小不一致,那么经过卷积层后输出大小必然也不一致。而全连接层的输入大小却是固定的,这样会造成全连接层的输入错误。看到这里就明白了这个问题。

那么SSP为何能解决这个问题呢?我们来看SSP是如何实现的?

SPP的实现是在卷积层和全连接层加上一个空间金字塔池化层。或者说将最后一个卷积层之后的池化层替换成空间金字塔池化层。所谓的空间金字塔池化就是池化操作从底端一层一层往上做池化,像金字塔的形状一样,故而称为空间金字塔池化。

假设原图输入大小224x224,到第5层卷积后的特征图大小为13x13x256,如下图所示。

怎么样将fasterrcnn和yolo结合起来 yolo与rcnn_人工智能_02


将特征图分成1x1(金字塔底),2x2(金字塔中间)和4x4(金字塔顶)三张图,分别对三张子图做最大池化。输出的特征图就是(16+4+1)x256的大小。即使原图输入尺寸不是224x224,在经过空间金字塔池化之后输出维度依然会是(16+4+1)x256的大小,因而就消除了输入图像尺寸不一致的问题。讲到这里,有部分读者可能还是难以理解SSP到底是如何实现的。其实把上图的过程这样理解就会明白:最右边的1x1(金字塔底)的作用过程是将原图直接取最大值,由13x13x256特征图得到1x256特征图。中间是将特征图平均分成4份后,再取最大池化。将13x13x256特征图变成4x256的特征图。最左边的过程依次类推。这样便实现输入是三维(1313256),最后输出变为了两维(21*256)的过程。维度变化是关键

在实际设计网络结构时,只需要根据全连接层的输入维度设计好空间金字塔的结构即可。总而言之,SPP层的作用就是在卷积层和全连接层之间对卷积层的输出信息进行某种汇总,这样可以避免一开始就对图像进行裁剪和缩放。

SSP-Net的不足

SSP-Net尽管解决了RCNN中所存在的输入CNN的候选框大小不一致的问题,SSP-Net仍存在一些不足之处。最大的缺点在于网络在反向传播过程中不能更新金字塔池化层之前的卷积层权重。

这个问题在FastRCNN中通过使用ROI Pooling的方式得到了解决。

二 Fast RCNN

Fast RCNN相对于RCNN,最大的改进来自于RoI(兴趣区域),本质上即是特征图种的候选框。这里用图片说明什么是ROI。
这里需要先说清楚两个概念。
Q1:什么是ROI?
Answer:ROI是Region of Interest的简写,意思是“特征图上的框”。在Fast RCNN中,ROI指的是Selective Search完成后得到的 “候选框” 在特征图上的映射,如下图所示。
Q2:什么是RoI Pooling?
Answer:RoI Pooling,顾名思义,是Pooling层的一种,而且是针对ROIs的Pooling,特点是输入特征图尺寸不固定,但是输出特征图尺寸固定。和前面讲的金字塔池化网络有一样的效果。
RoI Pooling的输入:由两部分组成。
(1)特征图,指的是下图中所示的CNN提取的特征图。在Fast RCNN中,位于RoI Pooling之前;
(2)ROIs,在Fast RCNN中,指的是Selective Search的输出,一堆矩形候选框,形状为1x5x1x4(4个坐标+ 索引index),其中值得注意的是,坐标的参考系不是针对feature map这张图的,而是针对原图的(神经网络最开始的输入)。
RoI Pooling的输出:输出是batch个vector,其中batch的值等于ROI的个数,vector的大小为channel * w * h,RoI Pooling的过程,就是将一个个大小不同的box矩形框,都映射成大小固定的(w*h)的矩形框。

怎么样将fasterrcnn和yolo结合起来 yolo与rcnn_pytorch_03

总结:ROI池化层将特征图中的每个候选框划分为H*W个子特征图,其中H和W为整个算法的超参数,独立于任何ROI。然后在每个子特征图上进行最大池化即可。子特征图的划分方法也是简单粗暴,直接用特征图除以子特征图数量就好。

在网络中,ROI是一个矩形窗口,每个ROI由左上角(r,c)和宽度高度(w,h)的四元组定义。ROI最大池化通过将大小为h x w的ROI窗口分割成H x W个网格,子窗口大小为h/H x w/W,然后对每个窗口执行最大池化。

到这里就算讲清楚了ROI Pooling,懂了ROI Pooling也就理解了Fast RCNN的精髓。

Fast RCNN和RCNN的异同

怎么样将fasterrcnn和yolo结合起来 yolo与rcnn_算法_04


怎么样将fasterrcnn和yolo结合起来 yolo与rcnn_pytorch_05


讲完FastRCNN和FasterRCNN异同之后,还需要再讲明白,为何ROI Pooling可以尺寸不固定的特征图转化为尺寸固定的输出特征图呢?这里就涉及到一个反推的过程。

怎么样将fasterrcnn和yolo结合起来 yolo与rcnn_pytorch_06


我们需要根据输出特征图中的一个点去反推原图中的bin有多大。每次输入一张图片,我们都需要依次这样的“反推”过程。

讲到这里,我相信大家应该对FastRCNN有了充分的了解了。

三 Faster RCNN

终于讲到了本章的重点,Faster RCNN。Faster RCNN是本章的一个终点,也是目标检测领域的一个起点,是物体检测最常用的框架之一。
RCNN和FastRCNN遗留下的痛点问题是,使用选择性搜索的方法生成候选框,使得网络检测的整体性能依然不高。
在Faster RCNN网络种,提出了用RPN网络的方法解决选择性搜索的痛点问题,使得两阶段的目标检测算法速度变得更快。Faster RCNN可以说是真正意义上将物体检测整个流程融入到了一个神经网络中。也正是RPN将FasterRCNN和之前的FastRCNN和RCNN彻底区别开来。FasterRCNN的网络结构可以归纳为 RPN+Fast RCNN结构。因此,本小节只需重点将RPN网络讲清楚来即可。

Q:什么是RPN?
(注:这里主要是参考另一篇文章参考资料6,大家感兴趣可以去下面找。文章中就不放链接了,一方面是担心影响读者的阅读思路,另一方面是作者已经通俗易懂的将这篇文章移植了过来)。
RPN:Region Proposal Net 区域候选网络,Proposal的中文意思是“区域选取”,因此RPN就是用来提取候选框的网络(功能和Selective Search相当)。利用输入图形进行整体卷积形成的特征图再次进行卷积来生成候选区域。注意,RPN的卷积层与检测网络FasterRCNN共享,使得FasterRCNN的检测速度大为提升。

RPN直观理解

怎么样将fasterrcnn和yolo结合起来 yolo与rcnn_算法_07


观察上图可以发现,在第2步的粗箭头标注“RPN”,在经过第二步后,原图中的1个红色矩形框变成了3个。因此可以直观理解RPN的作用是在原图中提取合适的候选框RPN具体过程

怎么样将fasterrcnn和yolo结合起来 yolo与rcnn_pytorch_08


上图是Faster RCNN原论文中的图片。一个特征图经过了sliding window处理,得到256维特征,然后通过2次全连接得到结果2k个分数和4k个坐标。下面分4个步骤给大家具体讲解一下其中的过程。

怎么样将fasterrcnn和yolo结合起来 yolo与rcnn_机器学习_09

(1)RPN的输入特征图主要是上图中FasterRCNN的公共FeatureMap,也称共享FeatureMap,主要用以RPN和ROIPooling共享。
(2)为什么是sliding windows呢,文中不是说用CNN吗?我们可以把3x3的slidingwindow看作是对特征图进行了一次3x3的卷积操作,最后得到了一个channel数目是256的特征图,尺寸和公共特征图相同,我们假设是256x(HxW)。
(3)256维特征是如何获得的?我们可以近似的把这个特征图看作有HxW个向量,每个向量是256维。那么图中的256维就是其中一个向量,然后我们要对每个向量做同样的全连接操作,等同于对整个特征图做两次1x1的卷积,得到一个2xHxW和4xHxW大小的特征图,换句话说,有HxW个结果,每个结果包含两个分数和四个坐标。
这里解释一下,2个分数指的是什么。因为RPN是提取候选框,因此只要求区分是不是物体就行。那么就有2个分数,前景(物体)的分数和背景的分数。4个坐标指的是针对原图坐标的偏移,首先一定要记住是原图

这里的疑问是,原图哪里来的坐标呢?我们接着讲。

(4)首先我们知道有HxW个结果,我们随机取一点,它和原图肯定有一个一一映射的关系。由于原图和特征图大小不同,所以特征图上的一个点对应原图肯定一个框,然而这个框很小,比如说8x8,这里的8指的是原图和特征图的比例。不妨把左上角或者框的中心点作为锚点(Anchor),然后想象出一堆框,具体是多少呢?K个。这也就是图中所说的 K anchor boxes(由锚点产生的K个框);换句话说,HxW个点,每个点对应原图有K个框,那么在原图中会有HxWxK个,那么RPN的结果就是判断这些框是不是物体以及它们的偏移,这里可以解答前面关于“原图”的疑问。那么这个框到底有多大呢,长宽比是多少呢?这里是预先设定好的,共有9种组合,所以K等于9.最后我们的结果是针对这9种组合的,所以有HxWx9个结果,也就是18个分数和36个坐标。可以结合下图进行理解。

怎么样将fasterrcnn和yolo结合起来 yolo与rcnn_计算机视觉_10


RPN流程回顾:

我们最后再把RPN的流程走一遍,首先通过一系列卷积得到公共特征图,假设他的大小是N * 16 * 16,然后我们进入RPN阶段,首先经过一个3*3的卷积,得到一个256x16x16的特征图,也可以看作是16x16个256维特征向量,然后经过2次1x1的卷积,分别得到一个18x16x16的特征图和一个35x16x16的特征图,也就是16x16x9个结果,每个结果包含2个分数和4个坐标(注意这里是针对原图坐标的偏移量)。再结合预先定义的anchors,经过后处理,就可得到候选框,整个流程如下图。

怎么样将fasterrcnn和yolo结合起来 yolo与rcnn_人工智能_11


这里最后再讲下上图中“后处理”是怎样一个过程。

后处理主要包括三个步骤:

(1)删除背景框(16x16x9);

(2)非极大值抑制(NMS),去除重合度大的框中分数低的那个;

(3)取分数最大的K(Top-K)个框(论文中K设置为300)。

讲到这里相信大家也对RPN有了一个深刻的认识了

可以认为FasterRCNN的综合性能是要优于之前的RCNN和FastRCNN,大家对于FastRCNN和RCNN可以重点去了解原理,对于FasterRCNN可以重点进行学习和实践。。