从R-CNN到Faster R-CNN漫谈

    本文相当长。。。。。。。。。

    object detection,就是在给定的图片中精确找到物体所在位置,并标注出物体的类别。object detection要解决的问题就是物体在哪里,是什么这整个流程的问题。然而,这个问题可不是那么容易解决的,物体的尺寸变化范围很大,摆放物体的角度,姿态不定,而且可以出现在图片的任何地方,更何况物体还可以是多个类别。

    R-CNN系列论文(R-CNN,fast-RCNN,faster-RCNN)是使用深度学习进行物体检测的鼻祖论文,其中fast-RCNN 以及faster-RCNN都是沿袭R-CNN的思路。

从图像识别的任务说起

这里有一个图像任务:既要把图中的物体识别出来,又要用方框框出它的位置。

         

简单来说,分类、定位和检测的区别如下: 
classify:是什么? 
localization:在哪里?是什么?(单个目标) 
detection:在哪里?分别是什么?(多个目标)

图像识别(classification):                                                定位(localization):
输入:图片                                                                           输入:图片
输出:物体的类别                                                                输出:方框在图片中的位置(x,y,w,h)
评估方法:准确率                                                                评估方法:检测评价函数 intersection-over-union ( IOU ) 

     

1、定位问题

   与图像分类不同的是检测需要定位一个图像内的许多物体。一个方法是将框定位看做是回归问题。但Szegedy等人的工作说明这种策略并不work。也就是说将定位问题单纯作为回归解决效果并不好。另一个可替代的方法是使用滑动窗口探测器,通过这种方法使用CNNs至少已经有20年的时间了,通常用于一些特定的种类如人脸,行人等。为了获得较高的空间分辨率,这些CNNs都采用了两个卷积层和两个池化层。作者本来也考虑过使用滑动窗口的方法,但是由于网络层次更深,输入图片有非常大的感受野(195×195)and 步长(32×32),这使得采用滑动窗口的方法充满挑战。 

      最终作者是通过操作”recognition using regions”范式,解决了CNN的定位问题:

  1. 给定一张输入图片,从图片中提取 2000 个类别独立的候选区域region proposal。
  2. 对于每个区域利用 CNN 抽取一个固定长度的特征向量。
  3. 借助专门针对特定类别数据的线性SVM,对每个区域 进行目标分类。

我们不考虑region的大小,对每个不同形状的region proposal产生一个固定长度的特征向量,作为CNN输入(也就是把不同大小的proposa缩放到统一尺寸。由于我们结合了Region proposals和CNNs,所以起名R-CNN:Regions with CNN features。

2、标注数据缺乏

     检测中面对的第二个挑战是标签数据太少,现在可获得的数据远远不够用来训练一个大型卷积网络。传统方法多是采用无监督与训练,再进行有监督调优。R-CNN的第二个核心贡献是在辅助数据集(ILSVRC)上进行有监督预训练,再在小数据集上针对特定问题进行调优。这是在训练数据稀少的情况下一个非常有效的训练大型卷积神经网络的方法。

       我们采用在 ImageNet 上已经训练好的模型,然后在 PASCAL VOC 数据集上进行 fine-tune,因为 ImageNet 的图像高达几百万张,利用卷积神经网络充分学习浅层的特征,然后在小规模数据集做规模化训练,从而可以达到好的效果。

现在,我们称之为迁移学习,是必不可少的一种技能。

二、R-CNN做物体检测

     物体检测系统有三个模块构成:

  1. 产生类别独立的候选区域region proposal,定义了一个候选检测区域的集合,其中包含了 R-CNN 最终定位的结果。
  2. 一个大型卷积神经网络,用于从每个候选区域提取固定长度的特征向量。
  3. 一系列的指定类别的线性SVM分类器。

2.1、区域推荐(region proposal) 

产生类别无关区域的方法有很多。比如: objectness(物体性),selective search(选择性搜索),category-independent object proposals(类别无关物体推荐),constrained parametric min-cuts(受限参最小剪切, CPMC)。由于R-CNN对特定区域算法是不关心的,所以我们采用了selective search。

2.2、特征提取(Feature extraction) 

      采用 Alexnet的一个Caffe实现版本,对每个候选区域抽取一个4096维度的特征向量。需要注意的是 Alextnet 的输入图像大小为277*277大小的图片,通过五个卷积层和两个全连接层进行前向传播,最终得到一个4096-D的特征向量。

      通过 Selective Search 产生的候选区域大小不一,我们首先要对候选区域图像进行转换,使得它符合R-CNN的输入(277*277),R-CNN 采用了非常暴力的手段,那就是无视候选区域的大小和形状,统一变换到 227*227 的尺寸。具体的有一个细节,在对 Region 进行变换的时候,首先在候选框周围加上16的padding,即在框周围附加了 16 个像素,也就是人为添加了边框。再进行缩放。这种形变使得mAp提高了3到5个百分点。

2.3、测试阶段

      在测试阶段,R-CNN 在每张图片上抽取近 2000 个候选区域。然后将每个候选区域进行尺寸的修整变换,送进神经网络以读取特征,然后用 SVM 进行类别的识别,并产生分数。

      候选区域有 2000 个,所以很多会进行重叠。针对每个类,通过计算 IoU 指标,采取非极大值抑制,以最高分的区域为基础,剔除掉那些重叠位置的区域。

2.3、训练

      前面已经提到过 R-CNN 采取迁移学习。提取在大型辅助训练集ILSVRC 2012 的模型和权重,然后在 VOC 上进行 fine-tune。需要注意的是,这里在 ImageNet 上训练的是模型识别物体类型的能力,而不是预测 bbox 位置的能力。

     为了让我们的CNN适应新的任务(即检测任务)和新的领域(变形后的推荐窗口)。我们只使用变形后的推荐区域对CNN参数进行SGD训练。假设要检测的物体类别有N类,那么我们就需要把CNN模型的最后一层给替换成N+1个输出的神经元(加1,表示还有一个背景),然后这一层直接采用参数随机初始化的方法,其它网络层的参数不变。

    例如:ImageNet 的训练当中需要预测 1000 个类别,我们替换掉了ImageNet专用的1000-way分类层,换成了一个随机初始化的21-way分类层,(这是 VOC 规定的 20 个类别加上背景这个类别。)卷积部分都没有改变。

      我们对待所有的推荐区域,如果其和真实标注的框的IoU>= 0.5就认为是正例,否则就是负例。SGD开始的learning_rate为0.001(是初始化预训练时的十分之一),这使得调优得以有效进行而不会破坏初始化的成果。每轮SGD迭代,我们统一使用32个正例窗口(跨所有类别)和96个背景窗口,即每个mini-batch的大小是128(即一次迭代我们输入128个图像)。另外我们倾向于采样正例窗口,因为和背景相比他们很稀少。

目标种类分类器 

      思考一下检测汽车的二分类器。很显然,一个图像区域紧紧包裹着一辆汽车应该就是正例。同样的,没有汽车的就是背景区域,也就是负例。但是,比较难确认的是,如果一个方框,只有一部分与汽车重叠,那么如何标注这个方框呢?我们使用IoU重叠阈值来解决这个问题,低于这个阈值的就是负例。这个阈值我们选择了0.3,是在验证集上基于{0, 0.1, … 0.5}通过网格搜索得到的。我们发现这个阈值很重要。如果设置为0.5,可以提升mAP5个点,设置为0,就会降低4个点。正例就严格的是标注的框。一旦特征提取出来,并应用标签数据,我们优化了每个类的线性SVM。由于训练数据太大,难以装进内存,我们选择了标准的hard negative mining method

框架精简

AlexNet网络共有:卷积层 5个,池化层 3个,全连接层:3个(其中包含输出层)。哪些层是关键指标呢?哪些层可有可无呢?

      fc6 与MAX-POOL 构成全连接,为了计算 feature 它会乘以一个 4096x9216 的权重矩阵,然后在与一组 bias 相加,所以它有 3700 多万的参数。fc7 是最后一层,它的权重矩阵是 4096x409,它的参数有 1678 万多的参数。但经过作者在 PASCAL 上不做 fine-tune 处理,直接测试,可以发现 fc7 的意义没有 fc6 大,甚至移除它之后,对于 mAP 结果指标没有影响。移除 fc7 就表示可以减少将近 1800 万个参数。更惊喜的事情是,同时移除 fc6 和 fc7 并没有多大的损失,甚至结果还要好一点点。所以,神经网络最神奇的力量来自卷积层,而不是全连接层。

上面说的是没有 fine-tune 的情况,那么在 fine-tune 的情况是什么呢?

      结果证明,fine-tune 后 fc6 与 fc7 提升的效果明显。所以结论就是,pool5 从 ImageNet 训练集中学习了物体的泛化能力,而能力的提升则是通过特定领域的 fine-tune。举个例子,神经网络在 ImageNet 数据集中学习到了 100 种猫的特征,而我自己的数据集只有两种猫,经过 fine-tune 训练后,这个神经网络可以更准确识别这两种猫了。

三、bbox 回归

     bbox 的值其实就是物体方框的位置,预测它就是回归问题,而不是分类问题。我们需要预测出(x,y,w,h)四个参数的值,从而得出方框的位置。受 DPM 的启发,作者训练了一个线性的回归模型,这个模型能够针对候选区域的 pool5 数据预测一个新的 box 位置。

     注意当输入的 Proposal 与 Ground Truth 相差较小时(RCNN 设置的是 IoU>0.6), 可以认为这种变换是一种线性变换, 那么我们就可以用线性回归来建模对窗口进行微调, 否则会导致训练的回归模型不 work(当 Proposal跟 GT 离得较远,就是复杂的非线性问题了,此时用线性回归建模显然不合理)

1、为啥要回归

    首先,原始的Bounding-box是用selective research选出来的,这相当于是外部的算法,硬加到了CNN中。当然,经过一大堆的过滤和NMS(非最大值抑制),我们可以认为一张图就得到了一个“暂时最优”的Bounding-box。也就是detection暂时的工作结果:

                             

     红色框是我们预先propose出来的。绿色的框是Ground truce,也就是label,是最优的。这两个框显然不太重合。如果有一种办法,能够让我们在经过了一大堆CNN计算之后,得到的这个“暂时最优” 的框“挪动” 那么一下,更接近Ground truce,岂不美哉!

2、边框回归是什么?

    对于窗口一般使用四维向量(x,y,w,h)来表示, 分别表示窗口的中心点坐标和宽高。 对于下图, 红色的框 P代表原始的Proposal, 绿色的框 G 代表目标的 Ground Truth, 我们的目标是寻找一种关系使得输入原始的窗口 P 经过映射得到一个跟真实窗口 G 更接近的回归窗口\hat G

                      

     我们发现, 边框回归学习就是d_{x} (P),d_{y} (P),d_{w} (P),d_{h} (P)这四个变换。下一步就是设计算法得到这四个映射。线性回归就是给定输入的特征向量 X, 学习一组参数 W, 使得经过线性回归后的值跟真实值 Y(Ground Truth)非常接近. 即Y≈WX 。 那么 Bounding-box 中我们的输入以及输出分别是什么呢?

Input:
,这个是什么? 输入就是这四个数值吗?其实真正的输入是这个窗口对应的 CNN 特征,也就是 R-CNN 中的 Pool5 feature(特征向量)。 (注:训练阶段输入还包括 Ground Truth, 也就是下边提到的t∗=(tx,ty,tw,th)t∗=(tx,ty,tw,th))

Output:
需要进行的平移变换和尺度缩放d_{x} (P),d_{y} (P),d_{w} (P),d_{h} (P), 或者说是\Delta x,\Delta y,S_{w},S_{h}。 我们的最终输出不应该是 Ground Truth 吗? 是的, 但是有了这四个变换我们就可以直接得到 Ground Truth, 这里还有个问题,我们可以知道, P 经过 d_{x} (P),d_{y} (P),d_{w} (P),d_{h} (P)得到的并不是真实值 G, 而是预测值\hat G。 的确, 这四个值应该是经过 Ground Truth 和 Proposal 计算得到的真正需要的平移量(t_{x},t_{y})和尺度缩放(t_{w},t_{h})

观察上述的G和\hat G的公式,我们看到一个d(一个d其实是一个向量,包含{x,y,w,h})对应着一个t,用i表示一张图片的序号:d_{i}\rightarrow t_{i}

      正如上面说的,得到d的输入并不是P这四个数,而是CNN pool5层的features,记为\Phi_{5}(P)。这样,才不是“硬”拟合,如果只是输入P代表的四个数的话,那就是一个CNN外部的统计问题了,CNN在这个Bounding-box regression里面一点作用也没起到,但是仔细想的话,Bounding-box的位置确实应该由CNN计算得到的features来fine-tune。那么目标函数可以表示为 :

                                                               d_{*}(P)=w_{*}^{T}\Phi _{5}(P)

\Phi_{5}(P)是输入 Proposal 的特征向量,w_{*}是要学习的参数(*分别表示 x,y,w,h, 也就是每一个变换(x平移,y平移,框缩放,高缩放,这4种变换??)对应一个目标函数) ,d_{*}(P)是得到的预测值。 我们要让预测值跟真实值t_{*}=(t_x,t_y,t_w,t_h)差距最小, 得到损失函数为:

                                                             Loss=\sum_{i}^{N}(t_{*}^{i}-w_{*}^{T}\Phi _{5}(P^{i})) ^{2}
函数优化目标为:
                                               

最优一项是一个惩罚项,可能是为了防止过拟合。这就简单了,用最小二乘法解就可以了。这样的话,如果在test模型的时候,经过一堆CNN和其他的计算,我们得到了一个“暂时最优”的Bounding-box。经过我们在训练时候Bounding-box regression得到的那个变换w_{*},对pool5得到的feature操作一下,就得到了一个变换d,再用这个d对我们测试用图propose出来的Bounding-box进行优化。

from:https://blog.csdn.net/zijin0802034/article/details/77685438

四、总结:

                  

步骤一:训练(或者下载)一个分类模型(比如AlexNet)  
         
步骤二:对该模型做fine-tuning
  • 将分类数从1000改为21
  • 去掉最后一个全连接层

        
步骤三:特征提取
  • 提取图像的所有候选框(选择性搜索)
  • 对于每一个区域:修正区域大小以适合CNN的输入,做一次前向运算,将第五个池化层的输出(就是对候选框提取到的特征)存到硬盘

        

步骤四:训练一个SVM分类器(二分类)来判断这个候选框里物体的类别。每个类别对应一个SVM,判断是不是属于这个类别,是就是positive,反之nagative。比如下图,就是狗分类的SVM。

            

步骤五:使用回归器精细修正候选框位置:对于每一个类,训练一个线性回归模型去判定这个框是否框得完美。

               

RCNN存在四个明显的问题:

  1)多个候选区域对应的图像需要预先提取,占用较大的磁盘空间;

  2)针对传统CNN需要固定尺寸的输入图像,crop/warp(归一化)产生物体截断或拉伸,会导致输入CNN的信息丢失;

  3)每一个ProposalRegion都需要进入CNN网络计算,上千个Region存在大量的范围重叠,重复的特征提取带来巨大的计算浪费。

  4)方法中的三个模型是分别训练的——CNN提取图像特征、分类器预测类别、回归模型tighten bounding box的边界,这也导致流程不易训练。

SPPNet 

   SPP:Spatial Pyramid Pooling(空间金字塔池化),在RCNN的基础上做了实质性的改进:

  (1)取消了crop/warp图像归一化过程解决图像变形导致的信息丢失以及存储问题

  在R-CNN中,由于每个候选区域大小是不同,所以需要先resize成固定大小才能送入CNN网络,SPP-net正好可以解决这个问题。采用空间金字塔池化(SpatialPyramid Pooling )替换了全连接层之前的最后一个池化层。为了适应不同分辨率的特征图,定义一种可伸缩的池化层,不管输入分辨率是多大,都可以划分成m*n个部分。这是SPP-net的第一个显著特征,它的输入是conv5特征图 以及特征图候选框(找到每个候选框在feature map上的映射patch,原图候选框通过stride映射得到)。

stride映射????

如下图所示,在卷积层和全连接层之间加入了SPP layer。此时网络的输入可以是任意尺度的,在SPP layer中每一个pooling的filter会根据输入调整大小,而SPP的输出尺度始终是固定的。

                                           

  SPP层原理如下所示,假定CNN层得到的特征图大小为a×a(比如13×13,随输入图片大小而变化),设定的金字塔尺度为n×n bins(对于不同大小图片是固定的),那么SPP层采用一种滑动窗口池化,窗口大小win_size=a/n,步为stride=a/n,采用max pooling,本质上将特征图均分为n×n个子区域,然后对各个子区域max pooling,这样不论输入图片大小,经过SPP层之后得到是固定大小的特征。一般设置多个金字塔级别,文中使用了4×4,2×2和1×1三个尺度。每个金字塔都得一个特征,将它们连接在一起送入后面的全连接层即可,这样就解决了变大小图片输入的问题了。

          技术分享图片

(2)只对原图提取一次特征:SPP的位置,放在所有的卷积层之后,有效解决了卷积层的重复计算问题(速度提高了24~102倍),这是论文的核心贡献。

  R-CNN每次都要挨个使用CNN模型计算各个候选区域的特征,这是极其费时的,不如直接将整张图片送入CNN网络,然后抽取候选区域的对应的特征区域,采用SPP层,这样可以大大减少计算量,并提升速度。基于SPP层的R-CNN模型在准确度上提升不是很大,但是速度却比原始R-CNN模型快24-102倍。

                  技术分享图片

尽管SPP-Net贡献很大,仍然存在很多问题:

  (1)和RCNN一样,训练过程仍然是隔离的,提取候选框 | 计算CNN特征| SVM分类 | Bounding Box回归独立训练,大量的中间结果需要转存,无法整体训练参数

  (2)SPP-Net在无法同时Tuning在SPP-Layer两边的卷积层和全连接层,很大程度上限制了深度CNN的效果;

  (3)在整个过程中,Proposal Region仍然很耗时

原始图片中的ROI如何映射到到feature map?

     找了张图是这样画的:从前向后推出各个层的感受野。

             

先说说感受野的计算】

隐藏层边长(输出的边长) = (W - K + 2P)/S + 1 
(其中 W是输入特征的大小,K是卷积核大小,P是填充大小,S是步长(stride))

为了理解方便把公式用英文写一下:

output field size = ( input field size - kernel size + 2*padding ) / stride + 1

(output field size 是卷积层的输出,input field size 是卷积层的输入)

反过来问你: 卷积层的输入(也即前一层的感受野) = ?

答案必然是: input field size = (output field size - 1)* stride - 2*padding + kernel size

     重申一下:卷积神经网络CNN中,某一层输出结果中一个元素所对应的输入层的区域大小,被称作感受野receptive field,如下图。感受野的大小是由kernel size,stride,padding , outputsize 一起决定的。

                  

对于Convolution/Pooling layer

                                                  r_i = s_i \cdot (r_{i+1} - 1) + k_i -2 \cdot padding

对于 Neuronlayer(ReLU/Sigmoid/..) :

                                                                    r_I = r_{i+1} 

上面只是给出了前一层在后一层的感受野,如何计算最后一层在原始图片上的感受野呢? 从后向前级联一下就可以了(先计算最后一层到倒数第二层的感受野,再计算倒数第二层到倒数第三层的感受野,依次从后往前推导就可以了)。

感受野上面的坐标映射 (Coordinate Mapping)】

通常,我们需要知道网络里面任意两个feature map之间的坐标映射关系(一般是中心点之间的映射),如上图,我们想得到map 3上的点p3映射回map 2所在的位置p2(红色框的中心点)

计算公式:

  • 对于 Convolution/Pooling layer: pi = s_i \cdot p_{i+1} +( (k_i -1)/2 - padding)
  • 对于Neuronlayer(ReLU/Sigmoid/..) : p_I = p_{i+1}

如果是计算任意feature map之间的关系,只需要用简单的组合就可以得到,下图是一个简单的例子:

SPP-net的ROI映射做法详解

SPP-net 是把原始ROI的左上角和右下角 映射到 feature map上的两个对应点。 有了feature map上的两对角点就确定了对应的 feature map 区域(下图中橙色)。

                         

如何映射?

左上角的点(x,y)映射到 feature map上的(x',y') : 使得 (x',y') 在原始图上感受野(绿色框)的中心点与(x,y)尽可能接近

对应点之间的映射公式是啥?

  1. 就是前面每层都填充padding/2 得到的简化公式 : p_i = s_i \cdot p_{i+1}
  2. 需要把上面公式进行级联得到  p_{0}=S*p_{i+1},其中 S=\prod_{0}^{i}s_{i}  
  3. 对于feature map 上的 (x',y') 它在原始图的对应点为 (x,y)=(S*x^{'},S*y^{'})
  4. 论文中的最后做法:把原始图片中的ROI映射为 feature map中的映射区域(上图橙色区域)其中 左上角取:x' =  \lfloor x/S \rfloor +1  ,\; y' =  \lfloor y/S \rfloor +1, ;右下角的点取: 界取y'的x值:x' =  \lceil x/S \rceil - 1  ,\; y' =  \lceil y/S \rceil - 1。 下图可见 \lfloor x/S \rfloor +1 , \lceil x/S \rceil - 1 的作用效果分别是增加和减少。也就是 左上角要向右下偏移,右下角要想要向左上偏移。个人理解采取这样的策略是因为论文中的映射方法(左上右下映射)会导致feature map上的区域反映射回原始ROI时有多余的区域(下图左边红色框是比蓝色区域大的)

    

                

Fast RCNN

      继2014年的RCNN之后,Ross Girshick在15年推出Fast RCNN,Fast R-CNN就是在R-CNN的基础上采纳了SPP Net方法,对R-CNN作了改进,使得性能进一步提高。。在Github上提供了源码。同样使用最大规模的网络,Fast RCNN和RCNN相比,训练时间从84小时减少为9.5小时,测试时间从47秒减少为0.32秒。在PASCAL VOC 2007上的准确率相差无几,约在66%-67%之间.

 1、Fast R-CNN目标检测流程介绍

注意:Fast R-CNN的RegionProposal是在feature map之后做的,这样可以不用对所有的区域进行单独的CNN Forward步骤。

     与R-CNN框架图对比,可以发现主要有两处不同:一是最后一个卷积层后加了一个ROI pooling layer,二是损失函数使用了多任务损失函数(multi-task loss),将边框回归Bounding Box Regression直接加入到CNN网络中训练(关于什么是边框回归,请参:https://www.julyedu.com/question/big/kp_id/26/ques_id/2139)。

(1) ROI pooling layer实际上是SPP-NET的一个精简版,SPP-NET对每个proposal使用了不同大小的金字塔映射,而ROI pooling layer只需要下采样到一个7x7的特征图(可以看做单层sppnet的网络层)。对于VGG16网络conv5_3有512个特征图,这样所有region proposal对应了一个7*7*512维度的特征向量作为全连接层的输入。输入一张完整的图片,再把候选框映射到conv5上,得到每个候选框的特征。提出简化版的ROI池化层(注意,没用金字塔)。

                            技术分享图片

      换言之,这个网络层可以把不同大小的输入映射到一个固定尺度的特征向量,而我们知道,conv、pooling、relu等操作都不需要固定size的输入,因此,在原始图片上执行这些操作后,虽然输入图片size不同导致得到的feature map尺寸也不同,不能直接接到一个全连接层进行分类,但是可以加入这个神奇的ROI Pooling层,对每个region都提取一个固定维度的特征表示,再通过正常的softmax进行类型识别。

(2) R-CNN训练过程分为了三个阶段,而Fast R-CNN直接使用softmax替代SVM分类,同时利用多任务损失函数边框回归也加入到了网络中,这样整个的训练过程是端到端的(除去region proposal提取阶段)。把类别判断和位置精调统一用深度网络实现,不再需要额外存储。

  在实现上是使用两个不同的全连接层,第一个全连接层有N+1个输出(N是类别总数,1是背景),表示各个类别的概率值;第二个全连接层有4N个输出,表示坐标回归值(tx,ty,tw,th),这个与R-CNN是一样的,每个类别都预测4个位置坐标值。Fast R-CNN采用了softmax分类器而不是SVM分类器,定位误差采用smooth L1 而不是R-CNN中的L2。

        技术分享图片

总代价为两者加权和,如果分类为背景则不考虑定位代价。损失函数:

 技术分享图片   技术分享图片

      也就是说,之前R-CNN的处理流程是先提proposal,然后CNN提取特征,之后用SVM分类器,最后再做box regression,而在Fast R-CNN中,作者巧妙的把box regression放进了神经网络内部,与region分类和并成为了一个multi-task模型,实际实验也证明,这两个任务能够共享卷积特征,并相互促进。

      所以,Fast-RCNN很重要的一个贡献是成功的让人们看到了Region Proposal + CNN这一框架实时检测的希望,原来多类检测真的可以在保证准确率的同时提升处理速度,也为后来的Faster R-CNN做下了铺垫。可以看见,Fast RCNN相对于RCNN的提速原因就在于:不过不像RCNN把每个候选区域给深度网络提特征,而是整张图提一次特征,再把候选框映射到conv5上,而SPP只需要计算一次特征,剩下的只需要在conv5层上操作就可以了。

Fast RCNN方法解决了RCNN方法两个问题:

问题一:运行速度慢 
RCNN一张图像内候选框之间大量重叠,提取特征操作冗余。 
Fast RCNN将整张图像归一化后直接送入深度网络。在邻接时,才加入候选框信息,在末尾的少数几层处理每个候选框。

问题二:训练所需空间大 
RCNN中独立的分类器和回归器需要大量特征作为训练样本。 
Fast RCNN把类别判断和位置精调统一用深度网络实现,不再需要额外存储。

基本结构

图像归一化为224×224直接送入网络。前五阶段是基础的conv+relu+pooling形式,在第五阶段结尾,输入P个候选区域(图像序号×1+几何位置×4,序号用于训练)?。 
这里写图片描述

详细细节参见:https://blog.csdn.net/shenxiaolu1984/article/details/51036677

Faster R-CNN

      Fast R-CNN存在的问题:选择性搜索找出所有的候选框,这个非常耗时。

       解决:加入一个提取边缘的神经网络,也就说找到候选框的工作也交给神经网络来做了。Faster R-CNN的主要贡献就是设计了提取候选区域的网络RPN,代替了费时的选择性搜索Selective Search,使得检测速度大幅提高。

       所以在Fast R-CNN中引入Region Proposal Network(RPN)替代Selective Search,同时引入anchor box应对目标形状的变化问题(anchor就是位置和大小固定的box,可以理解成事先设置好的固定的proposal)。

     具体做法:将RPN放在最后一个卷积层的后面;RPN直接训练得到候选区域。RPN网络的特点在于通过滑动窗口的方式实现候选框的提取,在feature map上滑动窗口,每个滑动窗口位置生成9个候选窗口(不同尺度、不同宽高),提取对应9个候选窗口(anchor)的特征,用于目标分类和边框回归,与FastRCNN类似,建一个神经网络用于物体分类+框位置的回归。目标分类只需要区分候选框内特征为前景或者背景,滑动窗口的位置提供了物体的大体位置信息,边框回归确定更精确的目标位置。  

  

一种网络,四个损失函数;

•RPN calssification(anchor good.bad)                                 •RPN regression(anchor->propoasal)

•Fast R-CNN classification(over classes)                            •Fast R-CNN regression(proposal ->box)

                                    技术分享图片

Faster R-CNN模型采用一种4步迭代的训练策略:

  1. 首先在ImageNet上预训练RPN,并在PASCAL VOC数据集上finetuning;
  2. 使用训练的PRN产生的region proposals单独训练一个Fast R-CNN模型,这个模型也先在ImageNet上预训练;
  3. 用Fast R-CNN的CNN模型部分(特征提取器)初始化RPN,然后对RPN中剩余层进行finetuning,此时Fast R-CNN与RPN的特征提取器是共享的;
  4. 固定特征提取器,对Fast R-CNN剩余层进行finetuning。这样经过多次迭代,Fast R-CNN可以与RPN有机融合在一起,形成一个统一的网络。

  其实还有另外一中近似联合训练策略,将RPN的2个loss和Fast R-CNN的2个loss结合在一起,然后共同训练。注意这个过程,Fast R-CNN的loss不对RPN产生的region proposals反向传播,所以这是一种近似。应该来说,联合训练速度更快,并且可以训练出同样的性能。

最后总结一下各大算法的步骤:

  • RCNN解决的是,“为什么不用CNN做classification呢?”
  • Fast R-CNN解决的是,“为什么不一起输出bounding box和label呢?”
  • Faster R-CNN解决的是,“为什么还要用selective search呢?

RCNN

1.在图像中确定约1000-2000个候选框 (使用选择性搜索Selective Search)

2.每个候选框内图像块缩放至相同大小,并输入到CNN内进行特征提取

3.对候选框中提取出的特征,使用SVM分类器判别是否属于一个特定类

4.对于属于某一类别的候选框,用回归器进一步调整其位置

Fast R-CNN

1.在图像中确定约1000-2000个候选框 (使用选择性搜索)

2.对整张图片输进CNN,得到feature map

3.找到每个候选框在feature map上的映射patch,将此patch作为每个候选框的卷积特征输入到SPP layer和之后的层

4.对候选框中提取出的特征,使用softmax函数判别是否属于一个特定类

5.对于属于某一类别的候选框,用回归器进一步调整其位置

Faster R-CNN

1.对整张图片输进CNN,得到feature map

2.卷积特征输入到RPN,得到候选框的特征信息

3.对候选框中提取出的特征,使用分类器判别是否属于一个特定类

4.对于属于某一类别的候选框,用回归器进一步调整其位置

简言之:

R-CNN(Selective Search + CNN + SVM)

SPP-net(ROI Pooling)

Fast R-CNN(Selective Search + CNN + ROI)

Faster R-CNN(RPN + CNN + ROI)

                   技术分享图片  

       总的来说,从R-CNN, SPP-NET, Fast R-CNN, Faster R-CNN一路走来,基于深度学习目标检测的流程变得越来越精简,精度越来越高,速度也越来越快。可以说基于region proposal的R-CNN系列目标检测方法是当前目标检测技术领域最主要的一个分支。

FPN 

  原有的目标检测算法通常都是只采用顶层特征做检测,原因是网络顶层特征的语义信息比较丰富。然而,虽顶层特征的语义信息丰富,但其中的目标位置信息却比较粗略,不利于目标包围框的准确定位;相反,虽然底层特征的语义信息比较少,但其中目标的位置信息却非常准确。

  FPN 主要解决的是物体检测中的多尺度问题,通过简单的网络连接改变,在基本不增加原有模型计算量情况下,大幅度提升了小物体检测的性能一个自底向上的线路,一个自顶向下的线路,横向连接(lateral connection)。侧向连接通过 1x1 的卷积进行连接(减少特征图维度同时保证尺寸不变),通过 Add 操作进行 Merge。同时利用低层特征高分辨率和高层特征的高语义信息,通过融合这些不同层的特征达到预测的效果。并且预测是在每个融合后的特征层上单独进行的

                                                    技术分享图片  

Mask R-CNN

代码(包括作者构建的数据集和已训练的模型):https://github.com/matterport/Mask_RCNN/tree/master/samples/balloon

什么是实例分割?

实例分割是一种在像素层面识别目标轮廓的任务,相比其他相关任务,实例分割是较难解决的计算机视觉任务之一:

                       

  • 分类:这张图像中有一个气球。
  • 语义分割:这些全是气球像素。
  • 目标检测:这张图像中的这些位置上有 7 个气球。
  • 实例分割:这些位置上有 7 个气球,并且这些像素分别属于每个气球。

   Mask RCNN以Faster RCNN原型,增加了一个分支用于分割任务。 对每一个目标物体,不仅给出其边界框,并且对边界框内的各个像素是否属于该物体进行标记。主要贡献其实就是RoIAlign以及加了一个mask分支。 RoIAlign,是将RoIPooling的插值方式,从最近邻插值(INTER_NEAREST)方式变为双线性插值。通过双线性插值来计算每个子区域输入特征的准确值。

      Mask R-CNN 是一个两阶段的框架,第一个阶段扫描图像并生成proposals(即有可能包含一个目标的区域),第二阶段分类proposals并生成边界框和掩码。Faster R-CNN 是一个流行的目标检测框架,Mask R-CNN 将其扩展为实例分割框架

               

     
     Mask RCNN是Faster RCNN的扩展,对于Faster RCNN的每个Proposal Box都要使用FCN进行语义分割,分割任务与定位、分类任务是同时进行的。
     引入了RoI Align代替Faster RCNN中的RoI Pooling。因为RoI Pooling并不是按照像素一一对齐的(pixel-to-pixel alignment),也许这对bbox的影响不是很大,但对于mask的精度却有很大影响。
     RoIAlign:RoIPooling的目的是为了从RPN网络确定的ROI中导出较小的特征图( 7x7)。RPN网络会提出若干RoI的坐标以[x,y,w,h]表示,然后输入RoI Pooling,输出7x7大小的特征图供分类和定位使用。问题就出在RoI Pooling的输出大小是7x7上,如果RON网络输出的RoI大小是8*8的,那么无法保证输入像素和输出像素是一一对应,首先他们包含的信息量不同(有的是1对1,有的是1对2),其次他们的坐标无法和输入对应起来(1对2的那个RoI输出像素该对应哪个输入像素的坐标?)。这对分类没什么影响,但是对分割却影响很大。RoIAlign的输出坐标使用插值算法得到,不再量化;每个grid中的值也不再使用max,同样使用差值算法。

RoIAlign可参考:https://blog.csdn.net/xiamentingtao/article/details/78598511

Mask RCNN主要包含以下几个结构:

骨干网络(Backbone Network):

      基于FPN(feature pyramid network)的层级化图像特征提取。为进一步精确定位小物体,通过top-down结构与旁支网络将顶层的语义特征信息结合底层的图形特征信息传递到区域建议网络。考虑一个简单的基于ResNet架构的Mask RCNN通常先在stem层下采样到1/4大小,每个module以步长2的梯度下降,同时在FPN网络的顶层可再进行一次下采样,输出 [1/4, 1/8, 1/16, 1/32, 1/64] 的金字塔式的特征图谱。

如图(d),FPN 通过添加第二个金字塔提升了标准特征提取金字塔的性能,第二个金字塔可以从第一个金字塔选择高级特征并传递到底层上。通过这个过程,它允许每一级的特征都可以和高级、低级特征互相结合.

区域建议网络 (Region Proposal Network):

                                           

       RPN 是一个轻量的神经网络,它用滑动窗口来扫描图像,并寻找存在目标的区域。RPN 扫描的区域被称为 anchor,这是在图像区域上分布的矩形,如上图所示。这只是一个简化图。实际上,在不同的尺寸和长宽比下,图像上会有将近 20 万个 anchor,并且它们互相重叠以尽可能地覆盖图像。

      RPN 扫描这些 anchor 的速度有多快呢?非常快。滑动窗口是由 RPN 的卷积过程实现的,可以使用 GPU 并行地扫描所有区域。此外,RPN 并不会直接扫描图像,而是扫描主干特征图。这使得 RPN 可以有效地复用提取的特征,并避免重复计算。通过这些优化手段,RPN 可以在 10ms 内完成扫描。在 Mask R-CNN 中,我们通常使用的是更高分辨率的图像以及更多的 anchor,因此扫描过程可能会更久。

RPN 为每个 anchor 生成两个输出:

  1. anchor 类别:前景或背景(FG/BG)。前景类别意味着可能存在一个目标在 anchor box 中。
  2. 边框精调:前景 anchor(或称正 anchor)可能并没有完美地位于目标的中心。因此,RPN 评估了 delta 输出(x、y、宽、高的变化百分数)以精调 anchor box 来更好地拟合目标。

                         

使用 RPN 的预测,我们可以选出最好地包含了目标的 anchor,并对其位置和尺寸进行精调。如果有多个 anchor 互相重叠,我们将保留拥有最高前景分数的 anchor,并舍弃余下的。然后我们就得到了最终的区域建议,并将其传递到下一个阶段。

ROI 分类器和边界框回归器

这个阶段是在由 RPN 得到的 ROI 上运行的。它为每个 ROI 生成了两个输出:

                

  1. 类别:ROI 中的目标的类别。和 RPN 不同(两个类别,前景或背景),这个网络更深并且可以将区域分类为具体的类别(人、车、椅子等)。它还可以生成一个背景类别,然后就可以弃用 ROI 了。
  2. 边框精调:和 RPN 的原理类似,它的目标是进一步精调边框的位置和尺寸以将目标封装。

ROIAlign

      分类器并不能很好地处理多种输入尺寸。它们通常只能处理固定的输入尺寸。但是,由于 RPN 中的边框精调步骤,ROI 框可以有不同的尺寸。因此,我们需要用 ROI 池化来解决这个问题。

      ROI 池化是指裁剪出特征图的一部分,然后将其重新调整为固定的尺寸。这个过程实际上和裁剪图片并将其缩放是相似的。Mask R-CNN 使用 ROIAlign,在特征图的不同点采样,并应用双线性插值。在我们的实现中,为简单起见,我们使用 TensorFlow 的 crop_and_resize 函数来实现这个过程。

分割掩码

到此为止,我们得到的正是一个用于目标检测的 Faster R-CNN。而分割掩码网络正是 Mask R-CNN 的论文引入的附加网络。

               

       掩码分支是一个卷积网络,取 ROI 分类器选择的正区域为输入,并生成它们的掩码。其生成的掩码是低分辨率的:28x28 像素。但它们是由浮点数表示的软掩码,相对于二进制掩码有更多的细节。掩码的小尺寸属性有助于保持掩码分支网络的轻量性。在训练过程中,我们将真实的掩码缩小为 28x28 来计算损失函数,在推断过程中,我们将预测的掩码放大为 ROI 边框的尺寸以给出最终的掩码结果,每个目标有一个掩码。

Mask-RCNN更详细请参见:https://baijiahao.baidu.com/s?id=1595621180643410921&wfr=spider&for=pc

from:https://www.cnblogs.com/skyfsm/p/6806246.html

from:https://cloud.tencent.com/developer/news/281788

from:https://www.cnblogs.com/skyfsm/p/6806246.html

from:http://www.mamicode.com/info-detail-2305694.html

猜你喜欢

转载自blog.csdn.net/qq_30815237/article/details/89379517