从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 的图像高达几百万张,利用卷积神经网络充分学习浅层的特征,然后在小规模数据集做规模化训练,从而可以达到好的效果。

     所谓fine tune就是用别人训练好的模型,加上我们自己的数据,来训练新的模型。fine tune相当于使用别人的模型的前几层,来提取浅层特征,然后在最后再落入我们自己的分类中。fine tune的好处在于不用完全重新训练模型,从而提高效率,因为一般新训练模型准确率都会从很低的值开始慢慢上升,但是fine tune能够让我们在比较少的迭代次数之后得到一个比较好的效果。在数据量不是很大的情况下,fine tune会是一个比较好的选择。但是如果你希望定义自己的网络结构的话,就需要从头开始了。

  我们可以在ImageNet上1000类分类训练好的参数的基础上,根据我们的分类识别任务进行特定的微调。我们称之为迁移学习,是必不可少的一种技能。

二、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维的特征向量。

      通过 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,采取非极大值抑制,以SVM最高分的区域为基础,剔除掉那些重叠位置的区域。

2.4、训练

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

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

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

      对于所有的region proposal,如果其和真实标注的框的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)四个参数的值,从而得出方框的位置。作者训练了一个线性的回归模型,这个模型能够针对候选区域的 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)

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

    从暂时最优框P到真实框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_{i}\rightarrow t_{i}的对应映射

      这里作为输入的d的并不是框的尺寸x,y,w,h这四个数,而是该框对应的CNN pool5层的features,记为\Phi_{5}(P)。这样,才不是“硬”拟合,如果只是输入P代表的四个数的话,那就是一个CNN外部的统计问题了,CNN在这个Bounding-box regression里面一点作用也没起到,但是仔细想的话,Bounding-box的位置确实应该由CNN计算得到的features来微调。那么目标函数可以表示为 :
                                                               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

from:https://www.jianshu.com/p/2c0995908cc3

四、总结:

                  

步骤一:训练(或者下载)一个分类模型(比如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特征图以及特征图的候选框(根据映射关系,可以由特征图候选框得到对应的原图像候选框)。

stride映射

     如下图所示,在卷积层和全连接层之间加入了SPP layer。此时网络的输入可以是任意尺度的,在SPP layer中每一个池化滤波器会根据输入调整大小,使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: p_i = s_i \cdot p_{i+1} +( (k_i -1)/2 - padding)
  • 对于Neuronlayer(ReLU/Sigmoid/..) : p_I = p_{i+1}

SPP-net的ROI映射做法详解

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

                             

from :https://blog.csdn.net/Summer_lion/article/details/72842851

如何映射?原图左上角的点(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。

第五阶段的特征输入到两个并行的全连层中(称为multi-task)。 
这里写图片描述

   cls_score层用于分类,输出K+1维数组p,表示属于K类和背景的概率。 对每个RoI(Region of Interesting)输出离散型概率分布p=(p_0,p_1,p_2,...p_k):,通常,p由k+1类的全连接层利用softmax计算得出。

  bbox_prdict层:用于调整候选区域位置,输出4*K维数组t,表示分别属于K类时,应该平移缩放的参数 t^k=(t_x^k,t_y^k,t_w^k,t_h^k),k表示类别的索引,t_x^k,t_y^k是指相对于object-proposal尺度不变的平移,t_w^k,t_h^k是指对数空间中相对于objectproposal的高与宽。

                       

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

                                                     

    规定u=0为背景类(也就是负标签),那么艾弗森括号指数函数[u≥1]表示背景候选区域即负样本不参与回归损失,不需要对候选区域进行回归操作。λ控制分类损失和回归损失的平衡。Fast R-CNN论文中,所有实验λ=1。

  • loss_cls层评估分类代价。由真实分类u对应的概率决定:
  • loss_bbox评估检测框定位代价。比较真实分类对应的预测参数t^{u}和真实平移缩放参数为v的差别: 

     g为Smooth L1误差,对outlier不敏感:
                                                     

     smooth L1损失函数曲线如下图9所示,作者这样设置的目的是想让loss对于离群点更加鲁棒,相比于L2损失函数,其对离群点、异常值(outlier)不敏感,可控制梯度的量级使训练时不容易跑飞。

                                              

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

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

                 

SVD ——>减少检测时间

      在目标检测任务中,要处理的RoI数量比较多,几乎有一半的前向计算时间被用于全连接层。就Fast R-CNN而言,RoI池化层后的全连接层需要进行约2k次【每个RoI都要计算】,因此在Fast R-CNN中可以采用SVD分解加速全连接层计算;

①物体分类和bbox回归都是通过全连接层实现的,假设全连接层输入数据为X,输出数据为Y,全连接层权值矩阵为W,尺寸为 u × v ,那么该层全连接计算为:Y = W × X

②若将W进行SVD分解(奇异值分解),并用前t个特征值近似代替,即:

U是 u × t 的左奇异矩阵,Σt 是 t × t 的对角矩阵 ,V是 v × t 的右奇异矩阵。

截断SVD将参数量由原来的 u × v 减少到 t × (u + v) ,当 t 远小于 min(u,v) 的时候降低了很大的计算量。

在实现时,相当于把一个全连接层拆分为两个全连接层,第一个全连接层使用权值矩阵(不含偏置),第二个全连接层使用矩阵U(含偏置);

                 
当RoI的数量大时,这种简单的压缩方法有很好的加速。实验表明,SVD分解全连接层能使mAP只下降0.3%的情况下提升30%的速度,同时该方法也不必再执行额外的微调操作。

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

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

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

基本结构

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

roi_pool层将每个候选区域均匀分成M×N块,对每块进行max pooling。将特征图上大小不一的候选区域转变为大小统一的数据M×N,送入下一层。

cls_score层:用于分类,输出K+1维数组p,表示属于K类和背景的概率。 

bbox_prdict层用于调整候选区域位置,输出4*K维数组t,表示分别属于K类时,应该平移缩放的参数。

详细细节参见: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)。

整体架构

                        

   原图600*1000经CNN卷积后,在CNN最后一层(conv5)得出的是40*60大小的特征图,对应文中说的典型值为2400。若特征图大小为W*H,则需要W*H*K个anchor,本文中需要40*60*9≈2k个

RPN

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

 这里写图片描述

      为了生成region proposals,我们在conv feature map上滑动一个小的网络,这个feature map 是最后一个共享卷积层的输出。这个小网络需要输入卷积feature map的一个n*n窗口。每个滑动窗口都映射到一个低维特征(ZF是256-d,VGG是512-d,后面跟一个ReLU激活函数)。这个特征被输入到两个兄弟全连接层中(一个box-regression层(reg),一个box-classification层(cls))。我们在这篇论文中使用了n=3,使输入图像上有效的接受域很大(ZF 171个像素,VGG 228个像素)。这个迷你网络在下图的位置上进行了说明。注意,由于迷你网络以滑动窗口的方式运行,所以全连接层在所有空间位置共享。这个体系结构是用一个n*n的卷积层来实现的,后面是两个1*1的兄弟卷积层(分别是reg和cls)。

  锚点是用固定的边框置于不同尺寸和比例的图片上,并且在之后目标位置的预测中用作参考边框。

  我们在处理的卷积特征图的尺寸分别是 conv_width×conv_height×conv_depth,因此在卷积图的 conv_width×conv_height 上每一个点都生成一组锚点。很重要的一点是即使我们是在特征图上生成的锚点,这些锚点最终是要映射回原始图片的尺寸

  因为我们只用到了卷积和池化层,所以特征图的最终维度与原始图片是呈比例的。数学上,如果图片的尺寸是 w×h,那么特征图最终会缩小到尺寸为 w/r 和 h/r,其中 r 是次级采样率。如果我们在特征图上每个空间位置上都定义一个锚点,那么最终图片的锚点会相隔 r 个像素,在 VGG 中,r=16。(图片为W*H,送入vgg16,得到feature map(W/16, H/16)),然后feature map上每个点都对应原图上的9个anchor,送入rpn层后输出两个: 这9个anchor前背景的概率以及4个坐标的回归。

Anchors(锚点)

    在每个滑动窗口位置,我们同时预测多个region proposals,其中每个位置的最大可能建议的数量表示为k。所以reg layer层有4k个输出,来编码k个box的坐标(一个角的坐标(x,y)+width+height),cls层输出2 k个分数来估计每个proposal是object的概率或者不是的概率。这k个proposals是k个参考框的参数化,我们把这些proposals叫做Anchors(锚点)。锚点位于滑动窗口中,并与比例、纵横比相关联。默认情况下,我们使用3个尺度和3个纵横比,在每个滑动位置上产生k=9个锚点。对于W *H大小的卷积特性图(通常为2400),总共有W*H*k个锚点。考虑9个可能候选窗口:三种面积{128^2,256^2,512^2}×三种比例{1:1,1:2,2:1} 。这些候选窗口称为anchors,如上图右所示。
      先以左上角(0,0)为例生成9个anchor,然后在向右向下移动,生成整个feature map所有点对应的anchor

 (x1,y1,x2,y2)=
array([[ -83.,  -39.,  100.,   56.],   #2:1
       [-175.,  -87.,  192.,  104.],
       [-359., -183.,  376.,  200.],

       [ -55.,  -55.,   72.,   72.],    #1:1
       [-119., -119.,  136.,  136.],
       [-247., -247.,  264.,  264.],

       [ -35.,  -79.,   52.,   96.],    #1:2
       [ -79., -167.,   96.,  184.],
       [-167., -343.,  184.,  360.]])

          

            

                    

from:https://blog.csdn.net/JNingWei/article/details/78847696

from:Faster R-CNN译文

     RPN 采用卷积特征图并在图像上生成建议。RPN 接受所有的参考框(锚点)并为目标输出一套好的建议。它通过为每个锚点提供两个不同的输出来完成。

  第一个输出是锚点作为目标的概率。可以叫做「目标性得分」。注意,RPN 不关心目标的类别,只在意它实际上是不是一个目标(而不是背景)。我们将用这个目标性得分来过滤掉不好的预测,为第二阶段做准备。第二个输出是边框回归,用于调整锚点以更好的拟合其预测的目标。

from:https://www.cnblogs.com/guoyaohua/p/9488119.html?utm_source=debugrun&utm_medium=referral


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

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

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

1、RPN Loss

                      

上述公式分为两个部分,第一部分为分类损失,第二部分为bbox regression损失。其中:

                                                     

 1、RPN calssification分类损失 :

                                                                 

 其中:

                       

     这是一个这经典的二分类交叉熵损失,对于每一个anchor计算对数损失,然后求和除以总的anchor数量Ncls。在训练RPN的阶段,Ncls = 256,在训练fast rcnn的阶段,Ncls = 128。

2、 bbox regression损失

                                        

其中:1、  是一个向量,表示该anchor预测的偏移量。
2、是与ti维度相同的向量,表示anchor相对于gt实际的偏移量,如下所示:

                                      

3、 
    R是smoothL1 函数。因为绝对损失函数(L1损失)f(x)=|x|,它是随着误差线性增长。但这个函数在0点处导数不存在,因此可能会影响收敛。一个通常的解决办法是,分段函数,在0点附近使用平方函数使得它更加平滑。它被称之为平滑L1损失函数。它通过一个参数σ 来控制平滑的区域。一般情况下σ = 1,在faster rcnn函数中σ = 3。其中

                    

于每一个anchor 计算完部分后还要乘以P*,如前所述,P*有物体时(positive)为1,没有物体(negative)时为0,意味着只有前景才计算损失,背景不计算损失。inside_weights就是这个作用。

from:https://blog.csdn.net/Mr_health/article/details/84970776

 

                                    技术分享图片

      RPN 执行两种不同类型的预测:二进制分类边框回归调整。为了训练,我们把所有的锚 anchor box 分成两类。一类是「前景」,它与真实目标重叠并且其 IoU(Intersection of Union)值大于 0.5;另一类是「背景」,它不与任何真实目标重叠或与真实目标的 IoU 值 小于 0.1。

   对这些锚点随机采样,构成大小为 256 的 mini batch (维持前景锚点和背景锚点之间的平衡比例)。

  RPN 用所有以 mini batch 筛选出来的 anchor box 和二进制交叉熵(binary cross entropy)来计算分类损失。然后它只用那些标记为前景的 mini batch 锚点来计算回归损失。为了计算回归的目标,我们使用前景 anchor box 和最接近的真实目标,并计算将 anchor box 转化为目标所需的正确 Δ。(因为不需要考虑其类别)

  论文中建议使用 Smooth L1 loss 来计算回归误差,而不是用简单的 L1 或 L2 loss。Smooth L1 基本上就是 L1,但是当 L1 的误差足够小,由确定的 σ 定义时,可以认为误差几乎是正确的且损失以更快的速率减小。

 2、Object Detection Loss

                                  

u:真实的类别标签       p:预测的类概率     t 矩阵:真实的ground truth       v 矩阵:预测的bbox 

1、分类用的是softmax函数:

T类  N表示前一层特征层flatten后的数字   fltten后的特征      无限大小的T类                    从0-1的T类向量              

      这张图的等号左边部分就是全连接层做的事,W是全连接层的参数,我们也称为权值,X是输入,也就是特征。从图上可以看出特征X是N*1的向量,这是怎么得到的呢?【答:flat成N*1的向量】这个特征就是由全连接层前面多个卷积层和池化层处理后得到的,假设全连接层前面连接的是一个卷积层,这个卷积层的输出是100个特征(也就是我们常说的feature map的channel为100),每个特征的大小是4*4,那么在将这些特征输入给全连接层之前会将这些特征flat成N*1的向量(这个时候N就是100*4*4=1600)。

     再来看W,W是全连接层的参数,是个T*N的矩阵,这个N和X的N对应,T表示类别数,比如你是7分类,那么T就是7。我们所说的训练一个网络,对于全连接层而言就是寻找最合适的W矩阵。因此全连接层就是执行WX得到一个T*1的向量(也就是图中的logits[T*1]),这个向量里面的每个数都没有大小限制的,也就是从负无穷大到正无穷大。然后如果你是多分类问题,一般会在全连接层后面接一个softmax层,这个softmax的输入是T*1的向量,输出也是T*1的向量(也就是图中的prob[T*1],这个向量的每个值表示这个样本属于每个类的概率),只不过输出的向量的每个值的大小范围为0到1。

softmax的输出向量就是概率,该样本属于各个类的概率!

from:https://blog.csdn.net/e01528/article/details/83795970

2、边框回归

   rpn阶段是两类分类回归,只区分是目标或者不是目标,classifier阶段则是根据实际类别进行分类,比如说针对VOC数据集就分类回归21类。

个人觉得作用是一样的, 但是结果不一样. 因为第二个边框回归的是第一个阶段的输出, 也就是n多个region, 在我看来就像是做了crop的data augmentation, 使得第二个边框回归学习到的分布更加接近真实分布, 达到了refinement的作用.

     在rpn中第一次回归候选框时已经过滤了大部分无意义的负样本,这样最后回归检测框时能做到较大部分one stage方法精确的目的

后处理

  非极大抑制(Non-maximum suppression):由于锚点经常重叠,因此建议最终也会在同一个目标上重叠。为了解决重复建议的问题,我们使用非极大抑制(NMS)。NMS 获取按照分数排序的建议列表并对已排序的列表进行迭代,丢弃那些 IoU 值大于某个预定义阈值的建议,并提出一个具有更高分数的建议。

  虽然这看起来很简单,但对 IoU 的阈值设定一定要非常小心。太低,你可能会丢失对目标的建议;太高,你可能会得到对同一个目标的很多建议。常用值是 0.6

  建议选择:应用 NMS 后,我们保留评分最高的 N 个建议。论文中使用 N=2000,但是将这个数字降低到 50 仍然可以得到相当好的结果。


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

  1. 首先在ImageNet上预训练RPN,并在PASCAL VOC数据集上fine-tuning;
  2. 使用训练的PRN产生的region proposals单独训练一个Fast R-CNN模型,这个模型也先在ImageNet上预训练;
  3. 用Fast R-CNN的CNN模型部分(特征提取器)初始化RPN,然后对RPN中剩余层进行fine-tuning,此时Fast R-CNN与RPN的特征提取器是共享的;
  4. 固定特征提取器,对Fast R-CNN剩余层进行fine-tuning。这样经过多次迭代,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 

 

      我们的特征金字塔可以在速度和准确率之间进行权衡,可以通过它获得更加鲁棒的语义信息,这是其中的一个原因。

      如上图所示,我们可以看到我们的图像中存在不同尺寸的目标,而不同的目标具有不同的特征,利用浅层的特征就可以将简单的目标的区分开来;利用深层的特征可以将复杂的目标区分开来;这样我们就需要这样的一个特征金字塔来完成这件事。图中我们在第1层(请看绿色标注)输出较大目标的实例分割结果,在第2层输出次大目标的实例检测结果,在第3层输出较小目标的实例分割结果。

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

     识别不同大小的物体是计算机视觉中的一个基本挑战,我们常用的解决方案是构造多尺度金字塔。学者们发现我们可以利用卷积网络本身的特性,即对原始图像进行卷积和池化操作,通过这种操作我们可以获得不同尺寸的feature map,类似于在图像的特征空间中构造金字塔。

       实验表明,浅层的网络更关注于细节信息,高层的网络更关注于语义信息,而高层的语义信息能够帮助我们准确的检测出目标,因此我们可以利用最后一个卷积层上的feature map来进行预测。这种方法存在于大多数深度网络中,比如VGG、ResNet、Inception,它们都是利用深度网络的最后一层特征来进行分类。这种方法的优点是速度快、需要内存少。它的缺点是我们仅仅关注深层网络中最后一层的特征,却忽略了其它层的特征,但是细节信息可以在一定程度上提升检测的精度。

        同时利用低层特征和高层特征,分别在不同的层同时进行预测,这是因为我的一幅图像中可能具有多个不同大小的目标,区分不同的目标可能需要不同的特征,对于简单的目标我们仅仅需要浅层的特征就可以检测到它,对于复杂的目标我们就需要利用复杂的特征来检测它。整个过程就是首先在原始图像上面进行深度卷积,然后分别在不同的特征层上面进行预测。它的优点是在不同的层上面输出对应的目标,不需要经过所有的层才输出对应的目标(即对于有些目标来说,不需要进行多余的前向操作),这样可以在一定程度上对网络进行加速操作,同时可以提高算法的检测性能。它的缺点是获得的特征不鲁棒,都是一些弱特征(因为很多的特征都是从较浅的层获得的)。

     讲了这么多终于轮到我们的FPN啦,它的架构如下图所示,整个过程如下所示,首先我们在输入的图像上进行深度卷积,然后对Layer2上面的特征进行降维操作(即添加一层1x1的卷积层),对Layer4上面的特征就行上采样操作,使得它们具有相应的尺寸,然后对处理后的Layer2和处理后的Layer4执行加法操作(对应元素相加),将获得的结果输入到Layer5中去。其背后的思路是为了获得一个强语义信息,这样可以提高检测性能。认真的你可能观察到了,这次我们使用了更深的层来构造特征金字塔,这样做是为了使用更加鲁棒的信息;除此之外,我们将处理过的低层特征和处理过的高层特征进行累加,这样做的目的是因为低层特征可以提供更加准确的位置信息。

利用FPN构建Faster R-CNN检测器步骤:

  • 首先,选择一张需要处理的图片,然后对该图片进行预处理操作;
  • 然后,将处理过的图片送入预训练的特征网络中(如ResNet等),即构建所谓的bottom-up网络;
  • 接着,如图所示,构建对应的top-down网络(即对层4进行上采样操作,先用1x1的卷积对层2进行降维处理,然后将两者相加(对应元素相加),最后进行3x3的卷积操作,最后);
  • 接着,在图中的4、5、6层上面分别进行RPN操作,即一个3x3的卷积后面分两路,分别连接一个1x1的卷积用来进行分类和回归操作;
  • 接着,将上一步获得的候选ROI分别输入到4、5、6层上面分别进行ROI Pool操作(固定为7x7的特征);
  • 最后,在上一步的基础上面连接两个1024层的全连接网络层,然后分两个支路,连接对应的分类层和回归层;

  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并不是按照像素一一对齐,这对bbox的影响不是很大,但对于mask的精度却有很大影响。

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 通过添加第二个金字塔提升了标准特征提取金字塔的性能,第二个金字塔可以从第一个金字塔选择高级特征并传递到底层上。通过这个过程,它允许每一级的特征都可以和高级、低级特征互相结合.

区域建议网络 RPN(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 池化来解决这个问题。

                 

   RoIAlign:RoIPooling的目的是为了从RPN网络确定的ROI中导出较小的特征图( 7x7)。 供分类和定位使用。问题就出在RoI Pooling的输出大小是7x7上,如果RON网络输出的RoI大小是8*8的,那么无法保证输入像素和输出像素是一一对应,首先他们包含的信息量不同(有的是1对1,有的是1对2),其次他们的坐标无法和输入对应起来(1对2的那个RoI输出像素该对应哪个输入像素的坐标?)。这对分类没什么影响,但是对分割却影响很大。RoIAlign的输出坐标使用插值算法得到,不再量化;每个grid中的值也不再使用max,同样使用差值算法。

RoiPooling

  在Faster RCNN中使用RoiPooling,使生成的候选框region proposal映射产生固定大小的feature map。先解释RoiPooling的工作原理   

            

      1)Conv layers使用的是VGG16,feat_stride=32(即表示,经过网络层后图片缩小为原图的1/32),原图800*800,最后一层特征图feature map大小:25*25

      2)假定原图中有一region proposal,大小为665*665,映射到特征图中的大小:665/32=20.78,即20.78*20.78,如果你看过Caffe的Roi Pooling的C++源码,在计算的时候会进行取整操作,进行第一次量化,即映射的特征图大小为20*20

      3)假定pooling后固定成7*7大小的特征图,将上面在 feature map上映射的20*20的 region  proposal划分成49个同等大小的小区域,每个小区域的大小20/7=2.86,即2.86*2.86,此时,进行第二次量化,故小区域大小变成2*2

      4)每个2*2的小区域里,取出其中最大的像素值,作为这一个区域的‘代表’,这样,49个小区域就输出49个像素值,组成7*7大小的feature map

   特征图缩放步长(stride)为32,则该层特征图上0.1个像素的偏差,缩放到原图就是3.2个像素。

     总结,所以,通过上面可以看出,经过两次量化,即将浮点数取整,原本在特征图上映射的20*20大小的region proposal,偏差成大小为14*14的,这样的像素偏差势必会对后层的回归定位产生影响。所以,产生了替代方案RoiAlign。

RoIAlign

      在Mask RCNN中使用ROIAlign,使生成的候选框region proposal映射产生固定大小的feature map。

                                 

   1)Conv layers使用的是VGG16,feat_stride=32(即表示,经过网络层后图片缩小为原图的1/32),原图800*800,最后一层特征图feature map大小:25*25

      2)假定原图中有一region proposal,大小为665*665,这样,映射到特征图中的大小:665/32=20.78,即20.78*20.78,此时没有像RoiPooling的取整操作,保留浮点数

      3)将在 feature map上映射的20.78*20.78的region proposal 划分成49个同等大小的小区域,每个小区域的大小20.78/7=2.97,即2.97*2.97

      4)假定采样点数为4,对于每个2.97*2.97的小区域,平分四份,每一份取其中心点位置,而中心点位置的像素,采用双线性插值法进行计算,得到四个点的像素值,如下图:

                                         

      上图中,四个红色叉叉‘×’的像素值是通过双线性插值算法计算得到的。最后,取四个像素值中最大值作为这个小区域(即:2.97*2.97大小的区域)的像素值,如此类推,同样是49个小区域得到49个像素值,组成7*7大小的feature map。

     总结:RoiPooling和RoiAlign实现原理,在以后的项目中可以根据实际情况进行方案的选择;对于检测图片中大目标物体时,两种方案的差别不大,而如果是图片中有较多小目标物体需要检测,则优先选择RoiAlign,更精准些。

参考:https://cloud.tencent.com/developer/article/1370951

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

分割掩码

      到此为止,我们得到的正是一个用于目标检测的 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

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值