当前位置:   article > 正文

R-CNN系列算法解读_r-cnn算法

r-cnn算法

R-CNN系列

from R-CNN to Mask-RCNN

  • R-CNN
  • Fast R-CNN
  • Faster R-CNN
  • FPN
  • FPN + RPN + Fast R-CNN
  • FPN + RPN + Fast R-CNN + Mask Prediction

sliding windows detector

  • 滑动窗口是最开始用的一种目标检测的方法,是一种比较暴力的方法
    在这里插入图片描述

  • 过程:输入一张图片,设置多种尺度的BBox,对输入图片从左到右、从上到下进行滑动BBox,裁剪出BBox_img,然后输入到CNN中进行识别判断。

  • 缺点:暴力搜索,非常耗时

Selective search

  • 为了解决暴力搜索太耗时的问题,R-CNN使用选择性搜索的方法,生成候选区域。
  • 生成候选区域的方法有很多种,作者选着了selective search方法,因为R-CNN检测图像时,是不知道这个图像中有什么的,也就没法针对某种目标来生成候选区域,selective search方法是以颜色,纹理等特征的相似度将像素点合并成区域的算法,相比于滑动窗口的方法复杂度更低。
  • 选择性搜索方法,进行区域建议,在输入图片中对像素进行“聚类”处理(相似的区域进行融合,得到bbox),得到很多ROIs,然后将ROIs输入到CNN中进行识别。
    在这里插入图片描述

R-CNN

  • 整体框架
    在这里插入图片描述

在这里插入图片描述

  • 整体描述:①输入图片首先经过 Region proposal ,使用 selective search 方法得到2000 ROIs;生成的ROIs可能大小不一样,然后resize成相同大小ROI;②接着将相同尺寸的ROIs输入到CNN网络进行特征提取;③最后将特征送入每一类的SVM 分类器,判别是否属于该类;④并且进行位置精修,即使用回归器(边框回归)精细修正候选框位置。注意:为什么要进行边框回归,因为Selective search得到的ROIs应该是不准确的,所以需要回归!

  • 具体说:
    区域候选框的生成: Selective Search 的前期工作就是利用Graph-Based Image Segmentation的分割算法产生初始的分割区域,然后使用相似度计算方法合并一些小的区域,参考
    (CNN)特征提取:采用的是AlexNet,由五个卷积层,两个全连接层组成,输出的特征是4096维的向量。由于这个网络要求的输入格式是227x227的RGB图像,所以将候选区域全部resize成227x227(最简单的变换方法),然后减均值输入到网络中。注意,resize前,在边框四周填充16个像素,再进行 各向异性 缩放, 这种形变使得mAp提高了3到5个百分点。
    关于ROI缩放到固定尺寸的方法: 主要分为各向异性和各向同性两种方法,参考。结合下图讲,其中各向异性就是最简单的变换,就是不管图片的长宽比例,管它是否扭曲,进行缩放就是了(D)。因为图片扭曲后,估计会对后续CNN的训练精度有影响,作者也测试了“各向同性缩放”方案,有两种办法:①先扩充后裁剪(B);②先裁剪后扩充(C)。文献还有个padding处理,下面的示意图中,每个例子,上面的行采用padding=0,下面一行采用padding=16。经过最后的试验,作者发现采用各向异性缩放、padding=16的精度最高。请添加图片描述

  • 边框回归怎么做(重点,目标检测中都用)
    在这里插入图片描述

  1. 蓝色框是经过Selective search得到的ROI,也就是Region Proposal得到的结果,表示为 Px、Py、Pw、Ph;
  2. 红色框是我们实际的汽车BBox(训练模型时,人工标注),Ground truth,表示为 Gx、Gy、Gw、Gh;
  3. 很明显,Proposal 和 Ground truth之间是有差距的,因此,我们的目的就是学习将Proposal变成Ground truth的一种变换,变换也就是dx(P)、dy(P)、dw(P)、dh(P);
  4. 具体的变换计算公式如Mapping 和 Target:
    (1)对于x和y,使用偏移变换,那么为什么要用 Pw * dx(P)来表示,而不直接用 △x 来表示,即Gx = Px + △x? 因为,这个偏移值应当跟BBox的宽高有关系,比如:对于一个很小的物体,偏移几个像素,可能变化就很大了,对于一个较大的物体,偏移几个像素可能变化不大。
    (2)对于宽和高的变换,使用缩放变换
    (3)最后我们预测的并不是Ground truth ,而是预测Proposal到Ground truth的变换,即 tx、ty、tw、th。
  5. 解码时的指数函数能够确保宽高的缩放比例大于0,所以 tw 和 th 的标签使用了log函数。
  • 边框回归损失函数定义:
    在这里插入图片描述
  • 分类器和回归器的输入: 分类器的输入是特征提取器AlexNet的fc6的输出结果,回归器的输入是特征提取器AlexNet的pool5的输出结果。之所以这样取输入,是因为,分类器不依赖坐标信息,所以取fc6全连接层的结果是没有问题的。但是回归器依赖坐标信息(要输出坐标的修正量),必须取坐标信息还没有丢失前的层。而fc6全连接层已经丢失了坐标信息。
  • 具体在训练的时候必须考虑正负样本的问题: 正负样本是必须要考虑的问题。论文的做法是每个batch所采样的正负样本比为1:3。当然这个比例是可以变化的,这个系列的后续改进就把正负样本比变为了1:1。如果之前没有接触过类似问题的话,是比较容易想当然地认为训练特征提取器、分类器、回归器时,就是把候选区域生成阶段的所有候选区域都放入训练,这样的思路是错的。对于目标检测问题,一张图片中,背景占了绝大多数地方,这样就导致训练用的正样本远远少于负样本,对训练不利。 正确的做法是对所有候选区域进行随机采样,要求采样的结果中正样本有x张,负样本y张,且保证x与y在数值上相近。(对于一些问题,不大容易做到x:y = 1:1,但至少x与y应该在同一数量级下)。关于正负样本的定义参考:正负样本问题
    RCNN中正负样本的定义 :一张照片我们得到了2000个候选框。然而人工标注的数据一张图片中就只标注了正确的bounding box,我们搜索出来的2000个矩形框也不可能会出现一个与人工标注完全匹配的候选框。因此在CNN阶段我们需要用IOU为2000个bounding box打标签。如果用selective search挑选出来的候选框与物体的人工标注矩形框(PASCAL VOC的图片都有人工标注)的重叠区域IoU大于0.5,那么我们就把这个候选框标注成物体类别(正样本),否则我们就把它当做背景类别(负样本)。
  • 训练阶段: RCNN的网络架构,注定了它不能像其他网络那样进行端到端(end-to-end)的训练。 前面提到RCNN分为4个阶段:Proposal阶段、特征提取阶段、分类阶段、回归阶段。这4个阶段都是相互独立训练的。

Fast R-CNN

  • R-CNN很明显还是比较慢,检测一张图片大概20s的时间,Fast R-CNN直接在feature map上生成ROIs,而不是在输入图片上Selective 2000个ROIs。

  • 要解决的问题:
    在这里插入图片描述

  • Fast RCNN直接改进:
    在这里插入图片描述

  • 整体框架
    在这里插入图片描述

在这里插入图片描述

  • 整体描述:①输入图片经过 CNN 得到 Feature map,同时 Selective search 在输入图片上生成2000ROIs;②然后将Selective 的ROIs,对应的在Feature map上切出 Feature map中的ROIs,相当于将原图的ROIs映射到Feature map上;③接着通过ROI Pooling将 Feature map ROIs resize成相同尺寸;④最后输入到FC中进行分类和边框回归。
  • 具体说:
    CNN特征提取: Fast RCNN中采用VGG作为backbone进行特征提取。从预训练网络进行初始化,使用三个经过预训练的ImageNet网络进行实验,每个网络具有五个最大池化层以及五个到十三个conv层。当预训练的网络初始化Fast R-CNN网络时,它将经历三个转换。首先,最后一个最大池化层被RoI池化层代替,该RoI池化层通过将H和W设置为与网络的第一个完全连接层兼容(例如,对于VGG16,H = W = 7)进行配置。其次,将网络的最后一个完全连接层和softmax替换为先前描述的两个同级层(K + 1类的完全连接层和softmax以及特定于类别的bounding-box regressors)。第三,修改网络以获取两个数据输入:图像和这些图像的RoI。
    ROI Pooling: 将 Feature map 中的 ROIs 变换成固定尺寸使用的是ROI Pooling 的方法。
    在这里插入图片描述
    ROI pooling对齐误差分析: 如下图,假设输入图片800x800,原图中的 region proposal 为650x650,CNN对原图进行特征提取后尺寸缩小32倍,要求固定的fixed size ROI为7x7;可以看出主要有两次量化操作(蓝色标注),经过两次量化(第一次在映射过程中,第二次在池化过程中),即将浮点数取整,原本在特征图上映射的20x20大小的 region proposal,偏差成大小为14x14的,这样的像素偏差势必会对后层的回归定位产生影响,不过虽然有误差,但是边框回归对精度要求没有那么强烈!
    在这里插入图片描述
    损失函数的定义,multi-task loss: 损失主要包括两部分:分类损失 + 边界框回归损失
    在这里插入图片描述
    分类损失:p是分类器预测的softmax概率分布p={p0,p1, …,pk};u是目标真实类别标签
    在这里插入图片描述
    边界框回归损失:tu是边界框回归器预测的对应类别u的回归参数txu,tyu,twu,thu;v是真实目标的边界框回归参数vx,vy,vw,vh
    在这里插入图片描述
  • 与RCNN相比快在(Fast)哪里:
    ①将特征提取器、分类器、回归器合并,使得训练过程不需要再将每阶段结果保存磁盘单独训练,可以一次性完成训练,加快了训练速度。这是Fast之一;
    ②对整张图片进行特征提取,用ROI层处理候选区域的特征,使得原本每一个候选区域都要做一次特征提取,变为了现在一整张图片做一次特征提取。训练速度(8.8倍)和测试速度(146倍)都大大加快,这是Fast之二;
  • 缺点:虽然测试比RCNN快200倍左右,但是候选区域的选取还是通过selective search,并且只能在CPU中运行这个算法,所以这个阶段浪费了大量时间。Fast RCNN也还不是真正意义上的 end-to-end。

Faster R-CNN

  • 最直接的改进: Faster-RCNN 引入了RPN网络(region proposal network)来代替 selective-search,这使得整个网络实现了端到端。
    Faster R-CNN算是RCNN系列算法的最杰出产物,也是two-stage中最为经典的物体检测算法。

  • 整体框架
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述

  • 整体描述: ①输入图片经过CNN进行特征提取得到Feature map;②Feature map 经过RPN网络得到Feature map中的ROIs;③将Feature map中的ROIs进行ROI pooling 得到固定尺寸;④最后将固定尺寸的ROIs输入到后续FC中进行分类和边框回归。

  • 具体说:
    CNN特征提取: Faster RCNN 只使用了VGG16的前30层作为特征提取器,所以每一张图片在经过特征提取后,尺寸会变为原来的1/16,根据前文的假设,一张800x600的图片变为50x37的 Feature map,而且通道数从原来的3变为512。
    Anchor的概念: 将FeatureMap中的每一点按照视野域找到原图中对应的位置,称为Anchor;每个Anchor生成不同大小不同长宽比的多个候选区域。Selective-search方法的候选区域生成方式,它是按照颜色和纹理不断合并得到候选区域的,候选区域的产生没有规律,而RPN是每个Anchor都有对应的固定数量的候选区域,规律很明显。
    在这里插入图片描述
    结合Faster R-CNN深刻理解 Anchor: 预测阶段(预测阶段的anchor都是训练好的,用来直接预测物体BBox),例如下图左边,是特征图上的一个特征点,这个特征点对应有9个训练好的Anchor,不同尺度,可以看出这个特征点对应原图片的人这个类别,而且anchor也覆盖了原图片人的区域,见下图中间,如果将所有特征点的所有Anchor绘制出来,可以看出完全覆盖整幅图片,见下图右边。训练阶段:训练阶段每个特征点会有初始的生成的9个Anchor,然后通过训练对其进行微调,例如:如果这个特征点的类别是一个人,然后将9个Anchor与人的GT BBox算IOU,选择IOU最大的那个Anchor来预测人的BBox,从而对选中的Anchor计算回归损失,完成训练。
    在这里插入图片描述
    在原图中生成anchor主要分为三步:参考
    RPN网络: RPN网络是Faster RCNN的精髓所在,将传统的候选区域生成方法使用卷积运算来代替,而且根据原文作者所说,使用卷积来生成候选区域使得RPN具有一定注意力机制,效果与前几代的RCNN相比,提升明显。首先,RPN网络接受任意尺寸大小的 Feature map 作为输入,然后会生成9K个anchor,并且RPN有两个输出,一个是anchor的类别信息,也就是该anchor是背景还是前景(只要有要识别的物体就属于前景),还有一个输出是该anchor的位置偏移信息(如果该anchor是背景,则该输出不重要),下图是RPN网络结构:
    在这里插入图片描述RPN网络从接入vgg 提取的特征,到RPN网络如何识别每一个anchor的类别,注意这边进行的是二分类,即判断anchor的内容是背景还是前景;到RPN网络是如何对anchor位置进行修正的,详细过程参考:参考1参考2,RPN网络详细结构如下(红色部分):
    在这里插入图片描述
    对Anchor的筛选工作: 现在我们已经有一堆经过修正后的anchor,并且也知道了每一个anchor属于前景的概率,但我们细想一下,现在anchor的数量是不是太多了,我们只用了一张800x600的图像作为输入就生成了16650个anchor,如果全部作为RoI(Region of Intererst,也就是感兴趣区域或者说候选区域)输入到后续网络中,这计算量属实有点大,所以就需要进行一些筛选工作,这其实也就是 RPN 网络中Proposal层所做的工作。
    首先 ,现在我们的anchor有许多因为是在边缘生成的,所以它们的坐标可能是负值,或者简单来说就是超出了图片的范围,那么就需要对这些anchor进行裁剪,把它们统一裁剪到图片范围内,也就是将anchor左上角坐标小于0的值用0代替,右下角坐标的X轴数值大于W就用W代替,Y轴数值大于H的用H代替。经过上一步的裁剪工作,就会有许多anchor会变得很小,这里我们设定一个阈值,凡是小于16*16的anchor,我们都把它丢弃掉。
    接着 ,因为我们已经有了每一个anchor属于前景的概率,那么很明显如果一个anchor属于前景的概率太小,那么也没有留着的必要性,所以对这些anchor的前景概率从大到小进行argsort,得到每一个anchor的排序索引,只取前6000个,到这一步anchor还是很多,但此时不能再鲁莽的去除anchor,因为有可能会有误判(毕竟这个前景概率只是rpn的预测,并不是真实的),此时需要用NMS方法把IoU大于0.7的进行合并,对于合并完的anchor再取前300个,这样就把输入到RoI网络的anchor的数量大大减少了。
    注:需要注意的是,此处的6000以及300是测试阶段的配置,训练与此处不一样。
    RPN总结: RPN部分内容比较多,第一次了解可能会被绕晕,做一个简单的小结如下图。在作者代码中,主要把RPN主要分成了两部分,一个是RPN Head,另一个是Proposal,RPN Head主要负责anchor的生成、anchor位置偏移量预测以及anchor的类别判断;Proposal负责对生成的anchor进行进一步的筛选,将筛选后的anchor作为RoI输入到后续的网络中。需要注意的是,因为不管是anchor的类别预测还是位置偏移量预测,这些都是在channel里面的,所以对这两个输出都需要使用 pytorch 的 permute 函数来将维度进行换位。
    在这里插入图片描述
    ROI Head 部分: 与Fast RCNN 类似,固定ROI尺寸的方法也是使用ROI Pooling 的方法。
    在这里插入图片描述
    训练部分: Faster RCNN 有三个部分需要训练,分别是特征提取器VGG16RPN以及RoIHead。其中特征提取器一般是采用预训练模型进行微调,重点是 RPN 的训练以及 RoI 的训练,虽然原论文中Faster RCNN是将这两部分分开训练的,但现在大多数实现都是进行联合训练的方式。具体训练过程参考:参考

  • 思考一个问题? 为什么要生成一堆anchor,再对它们进行修正,而不是一开始直接预测候选区域的坐标?其实 YOLO v1 就是没有使用anchor,直接对候选区域的坐标进行预测,但作者发现,效果并不好,主要是因为网络很难收敛,训练难度较大,所以 YOLO 的作者后来就将 Faster RCC 的 RPN 进行了相关的修改,将 anchor 加入到了YOLO v2中,效果有了显著的提高。

  • 比Fast rcnn 快在哪里: 容易想到,现在RPN网络可以与其他3个阶段共用同一个特征提取结果了,省掉了 selective-search 的时间。而事实上,selective-search是非常慢的,所以叫Faster。

FPN

  • 单尺度训练弊端:注意到,Fast R-CNN是单尺度进行训练的,即:对于224x224的原图,生成7x7的Feature map,缩小的倍数非常大,最后一层Feature map 的感受野非常大,因此对于小物体检测效果非常差。
  • 考虑: FPN网络考虑利用浅层的Feature map来进行预测,但是浅层的信息虽然感受野比较小,位置信息很明确,但是浅层的Feature map语义信息比较弱,也就是不利于最后的分类。所以这里是一个矛盾的问题?怎么解决呢?融合呗!!!
  • FPN就能很好的解决这一个矛盾的问题!!!!
  • 尺度常见方法:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述

  • FPN网络结构:
    思想: 将高层的特征通过上采样与低层的特征进行融合,这样每一层的语义信息和位置信息都比较好。
    在这里插入图片描述
  • 整体描述: 首先是从底到上的特征提取过程(vgg、resNet等都可以用);然后是从上到下的过程(进行上采样,方法可以是双线性插值、反卷积等等);以及从左到右的横向连接(融合特征),最后为了解决融合的一种混叠效应,一般都又进行3x3卷积特征提取,得到最终的特征层。注意:FPN是一种思想,而不是某一种具体的网络,结合其他具体的网络可以形成特定的FPN网络,比如ResNet-FPN等等。
  • FPN的优势: 精准的定位+很强的语义信息。
  • ResNet-FPN:
    在这里插入图片描述
    在这里插入图片描述
    注意:FPN还可能输出一个P6,这个P6作为RPN的输入。
    在这里插入图片描述
  • FPN+RPN+Fast RCNN = Faster RCNN
    在这里插入图片描述
  • 抛出一个疑问 ?如果使用FPN的话,我们的ROI到底要去哪一个Feature map上切呢????之前的Fast RCNN 我们是只有一个Feature map的,但是多尺度训练,怎么选择多个Feature map的哪一个呢?
    做法:使用公式计算,主要根据ROI的宽高来进行确定,例如宽高越大的ROI,应该从更高层的Feature map去切!因为高层感受野大嘛!
    在这里插入图片描述

Mask-RCNN

  • FPN+RPN+Fast RCNN+Mask predition = Mask RCNN
  • 整体结构
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述

  • 整体描述: ①首先输入图片经过FPN网络得到多尺度特征图;②然后将多尺度特征图的P6特征层输入到RPN网络中生成对应原图的ROIs,并且在步骤1中生成的多尺度特征图上切出对应的Feature map的ROIs;③然后将ROIs进行ROI Align操作固定到同一尺寸;④最后将固定尺寸的ROIs输入到FC中进行分类和边框回归,同时输入到mask分支进行mask预测。
  • 具体说:
    特征提取: Mask RCNN采用ResNet-FPN作为backbone进行特征提取,输出多尺度特征图。
    mask分支: Faster-RCNN网络的最后分别是分类网络和回归网络两条路并行,Mask-RCNN则是再加一条Mask网络与它们并行。结构如下图:(使用全卷积网络FCN)注意不管物体的大小是多少,返回的都是28x28x80的结果,返回原图得根据proposal进行变换。
    在这里插入图片描述
    ROI Align:
    类似于ROI Pooling,使得所有的Feature map RoIs的尺寸固定(fixed size feature map),进而输入到后续网络进行分类、边框回归和Mask预测。对于尺寸变换操作,由于RoI Pooling进行 两次量化操作(前面有误差分析) ,使得特征图对应位置不准,带来较大的精度损失问题,因此使用RoIAlign算法,提高RoI与原图的对齐精度。对齐问题在分类和框选时影响不大,但在语义分割需要严格依赖每个像素点的坐标时,影响会很大。 ROIAlign能够解决对齐问题。图像处理中常用双线性插值对颜色进行采样,RoIAlign使用双线性插值的方法解决获得浮点数坐标点上的特征值。双线性插值原理如图3.8所示,红色点Q11,Q12,Q21,Q22为已知的4个像素点,首先进行X方向的线性插值,在Q12,Q22中插入蓝色点R2,Q11,Q21中插入蓝色点R1,然后进行Y方向的线性插值,通过第一步计算出的R1与R2在Y方向上插值计算出插值P点。
    在这里插入图片描述
    如下图所示,虚线网格表示 5x5 的特征图,实线的矩形框表示在特征图上的 H x W 的RoI,输出为 2x2 的实线网格。对于输出 2x2 的每一个cell又分成四个小网格,并取每一个小网格的中心点,每个中心点的值又通过邻近的特征图点进行双线性插值得到,最后每个cell的值为四个小网格的最大值或者平均值。
    在这里插入图片描述
    ROI Align保留了两次的浮点数,因此对齐精度大大提高。ROI Pooling / Align 详细分析参考
    在这里插入图片描述
    注意:还有第三种池化的方法:ROI Warp参考 RoIWarp的想法和RoIAlign差不多,唯一的区别是 ROI Warp是将ROI量化到 Feature map上。
    损失函数定义: 训练过程中,损失函数L的定义如下式所示,由分类损失函数L_cls、定位损失函数L_box和分割损失函数L_mask三部分共同构成。
    在这里插入图片描述
    Lcls和Lbox: 分类误差和检测误差与 farster R-CNN基本一致。
    Lmask:
    ①训练的时候:结合下图,mask分支预测的7x7的特征图,对于每一个特征点都预测一个向量,向量的维度为类别总数。Lmask对于每一个像素使用二值的sigmoid交叉熵损失,这与一般的分类使用交叉熵损失有区别。对于每一个像素,都是用sigmod函数进行求相对熵,得到平均相对熵误差Lmask。对于每一个ROI,如果检测得到ROI属于哪一个分类,就只使用哪一个分支的相对熵误差作为误差值进行计算。(举例说明:分类有3类(猫,狗,人),检测得到当前ROI属于“人”这一类,那么所使用的Lmask为“人”这一分支的mask。)这样的定义使得我们的网络不需要去区分每一个像素属于哪一类,只需要去区别在这个类当中的不同分别小类。最后可以通过与阈值0.5作比较输出二值mask(预测时)。这样避免了类间的竞争,将分类的任务交给专业的classification分支。
    在这里插入图片描述
    ②预测的时候:假设有三种类别(猫、狗和气球),首先是得到图片中物体的检测框BBox和类别名,例如类别是气球,然后对BBox框里面的每一个像素值取相应的狗的类别的 mask 结果,通过与阈值0.5作比较输出二值mask:0 或者 1,这样就绘制了气球的掩码!示意图如下:
    在这里插入图片描述
  • Mask RCNN应用:
    实例分割
    目标检测也可以(屏蔽mask分支)
    人体姿态估计:简单修改,将mask分支的类别改为人体关键部位。
    6-D姿态估计:给一个二维图片,画出物体在三维空间中的BBox。mask rcnn + pose分支!!!
    在这里插入图片描述
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/652101
推荐阅读
相关标签
  

闽ICP备14008679号