计算机视觉之RCNN, Fast RCNN, Faster RCNN, Mask RCNN目标检测

一、目标检测

1.1 概念

  • 定位和分类:对于仅有一个目标的图片,检测出该目标所处的位置及该目标的类别;
  • 目标检测:对于有多个目标的图片,检测出所有目标所处的位置及类别;
  • 下图左侧为定位和分类任务,右侧为目标检测任务;
    在这里插入图片描述

1.2 定位+分类

  • 对于输入图片,定位任务需要返回图片中目标的外界矩阵框,即目标的 ( x , y , w , h ) (x, y, w, h) (x,y,w,h)四元组,四元组的预测可看做回归任务;
  • 分类任务要识别目标的类别;
    在这里插入图片描述
    在这里插入图片描述
  • 定位+分类的具体步骤如下:
    1)训练或下载一个分类模型,例如Alexnet、VGGNet,Resnet;
    2)在分类网络最后一个卷积层的特征层(feature map)上添加"Regression head";
    3)同时训练"Classification head"和"Regression head",为了同事训练分类和回归问题,最终损失函数是分类和定位两个"head"产生的损失的加权和;
    4)最终使用分类和回归的两个"head"得到分类+定位的结果,分类预测的结果是 C C C个类别,回归预测结果分两种:一种与类别无关,输出4个值;一种是类别相关,输出 4 ∗ C 4*C 4C个值。
    在这里插入图片描述

1.3 目标检测

  • 目标检测需要获取图片中所有目标的位置及类别,当图片中只有一个目标时,"Regression head"预测4个值,当图片中有三个目标时,"Regression head"预测12个值,当图片中有多个目标时,"Regression head"要预测较多的值;
  • 基于上述问题,提出两种解决方案:
    1)使用滑窗的方法解决,需要设计大量的不同尺度和长宽比的“滑窗”来使它们通过CNN,此方法计算量巨大,暂不采纳;
    2)使用一种从图片中选出潜在物体候选框(Region of Interest,ROI)的方法selective search,基于此方法提出了RCNN。

1.4 R-CNN(Region-CNN)

  • RCNN训练过程如图所示:
    在这里插入图片描述
  • 训练步骤如下
    1)选出潜在目标候选框ROI:基于selective search方法生成2000个潜在物体候选框ROI,然后对每个候选框Resize成固定大小;
    2)训练一个特征提取器:采用AlexNet、VGGNet、GoolgeNet、ResNet等CNN模型提取一个4096维的特征向量,得到最后一个特征向量;
    为了获得一个较好的特征提取器,一般在模型上做微调,唯一的改动就是将模型的1000个类别输出改为 ( C + 1 ) (C+1) (C+1)个输出,其中 C C C为真实预测的类别数, 1 1 1是背景的类别,新的特征训练方法采用随机梯度下降法SGD进行训练,提取训练好的模型的最后一个特征层;
    衡量正负样本的指标IOU(Intersection Over Union),就是两个矩形面积的交集除以并集,假定两个矩阵框中,1个矩形表示ROI,两一个矩形表示真实的矩形框,当 R O I ≥ 0.5 ROI\ge 0.5 ROI0.5时,认为两个矩形基本相交,认为是正样本;其余为负样本;
    在这里插入图片描述
    至此RCNN的特征提取器就开始训练了,训练过程中要对正负样本进行采样,训练中正样本太少会导致正负样本不平衡,最终提取一个4096维的特征向量;
    3)训练最终分类器:将特征向量送入SVM分类器中,预测出框选区域中多含物体属于每个类的概率值(每个类别单独训练一个SVM,判断是否属于这个类别,属于是positive,反之nagative),RCNN提出者最终选择真实值的矩阵框作为正样本;
    4)训练回归模型:对于每一个类,训练一个线性回归模型,来微调ROI与真实矩形框位置和大小的偏差;
    在这里插入图片描述
  • 计算IOU代码如下所示:
def cal_IOU(boxA, boxB):
    A_xmin = boxA[0]
    A_ymin = boxA[1]
    A_xmax = boxA[2]
    A_ymax = boxA[3]
    A_width = A_xmax - A_xmin
    A_height = A_ymax - A_ymin

    B_xmin = boxB[0]
    B_ymin = boxB[1]
    B_xmax = boxB[2]
    B_ymax = boxB[3]
    B_width = B_xmax - B_xmin
    B_height = B_ymax - B_ymin

    xmin = min(A_xmin, B_xmin)
    ymin = min(A_ymin, B_ymin)
    xmax = max(A_xmax, B_xmax)
    ymax = max(A_ymax, B_ymax)

    A_B_width_and = (A_width + B_width) - (xmax - xmin)  # 宽的交集
    A_B_height_and = (A_height + B_height) - (ymax - ymin)  # 高的交集

    if A_B_width_and <= 0.0001 or A_B_height_and <= 0.0001:
        return 0

    area_and = A_B_width_and * A_B_height_and
    area_or = A_width * A_height + B_width * B_height
    IOU = area_and / (area_or - area_and)

    return IOU

if __name__ == '__main__':
    rect1 = (661, 27, 679, 47)
    rect2 = (662, 27, 682, 47)
    iou = cal_IOU(rect1, rect2)
    print("IOU={:.4f}".format(iou))

#结果
IOU=0.8095
  • 预测步骤如下
    1)使用selective search方法生成2000个ROI;
    2)所有ROI调整为特征提取网络所需的输入大小并进行特征提取,得到与2000个ROI对应的2000个4096维的特征向量;
    3)将2000个特征向量分别输入到SVM中,得到每个ROI预测类别;
    4)通过回归网络微调ROI的位置;
    5)最终使用极大值抑制(Non-MaximumSuppression, NMS)方法对同一类别的ROI进行合并得到最终检测结果。NMS的原理是得到每个矩形框的分数(置信度),如果两个矩形框的IOU超过指定阈值,则仅保留分数大的那个矩形框。

1.5 Fast R-CNN

1.5.1 R-CNN缺点

  • 2000个ROI的CNN特征提取占用大量时间;
  • CNN特征不会因为SVM和回归的调整而更新;
  • R-CNN训练流程复杂,并不是端到端的训练过程(因为R-CNN首先进行2000个ROI的提取,将提取的结果再放进CNN中进行特征提取和后续训练,是2个步骤,并不是端到端的训练);

1.5.2 SPP Net (Spatial Pyramid Pooling空间金字塔池化)

  • 要解决的问题:
    1)一般CNN后接全连接层或者分类器,他们都需要固定的输入尺寸,因此不得不对输入数据进行裁剪,这些预处理会造成数据的丢失或几何的失真。SPP Net的第一个贡献就是将金字塔思想加入到CNN,在卷积层和全连接层之间加入了SPP layer。此时网络的输入可以是任意尺度的,不需要在特征提取前对图像做resize操作,在SPP layer中每一个pooling的filter会根据输入调整大小,而SPP的输出尺度始终是固定的
    在这里插入图片描述
    假设原图输入是224x224,对于conv5出来后的输出是13x13x256的,可以理解成有256个这样的filter,每个filter对应一张13x13的reponse map。如果像上图那样将reponse map分成1x1(金字塔底座),2x2(金字塔中间),4x4(金字塔顶座)三张子图,分别做max pooling后,出来的特征就是(16+4+1)x256 维度。如果原图的输入不是224x224,出来的特征依然是(16+4+1)x256维度。这样就实现了不管图像尺寸如何 池化n 的输出永远是 (16+4+1)x256 维度。
  • 单层sppnet的网络层,叫做ROI Pooling。

1.5.3 Fast R-CNN原理

在这里插入图片描述

  • 训练过程如上图所示,步骤如下:
    1)将整张图片及划分好的ROI直接输入到全卷积的CNN中,此时整张图片进行全卷积操作,不需要对ROI进行全卷积操作,卷积后得到特征层和对应在特征层上的ROI(此时ROI可以根据其集合位置加卷积公式推导得出);
    2)为了保证FCs(全连接层)输入尺寸一致,而特征层上的ROI尺寸大小不一,所以要经过ROI Pooling层处理,经过ROI Pooling层后转换为尺寸一致的特征向量(及调整为 M ∗ N M*N MN);
    3)经过ROI Pooling层后,全部的2000个 M ∗ N M*N MN个训练数据通过全连接层并分别经过2个head:Softmax分类及L2回归,最终损失函数是分类和回归损失函数的加权和。
  • 测试过程如下图所示。
    在这里插入图片描述
    重点:
    1)R-CNN一大缺点:由于每一个候选框都要独自经过CNN,这使得花费的时间非常多。
    解决:共享卷积层,现在不是每一个候选框都当做输入进入CNN了,而是输入一张完整的图片,在第五个卷积层再得到每个候选框的特征
    2)原来的方法:许多候选框(比如两千个)–>CNN–>得到每个候选框的特征–>分类+回归
    现在的方法:一张完整图片–>CNN–>得到每张候选框的特征–>分类+回归
    3)所以容易看见,Fast RCNN相对于RCNN的提速原因就在于:不像RCNN把每个候选区域给深度网络提特征,而是整张图提一次特征,再把候选框映射到conv5上,而SPP只需要计算一次特征,剩下的只需要在conv5层上操作就可以了。

在性能上提升也是相当明显的:
在这里插入图片描述

1.6 Faster R-CNN

1.6.1 Fast R-CNN缺点

  • 选择性搜索selective search,找出所有的候选框,这个也非常耗时。
    解决:加入一个提取边缘的神经网络,即选择候选框ROI的工作也交给神经网络来做了。做这样的任务的神经网络叫做Region Proposal Network(RPN)

1.6.2 RPN网络原理

  • RPN网络具体做法:
      • 将RPN放在最后一个卷积层的后面;
      • RPN直接训练得到候选区域;
  • RPN的核心思想是:构建一个小的全卷积网络,对于任意大小的图片,输出ROI的具体位置及该ROI是否为目标,RPN网络在卷积神经网络的最后一个特征上滑动。
  • 如下图a)所示,最下面灰色的网络为卷积神经网络的特征层,红框表示RPN的输入,大小是 3 ∗ 3 3*3 33,而后连接到256维的向量上。这个 3 ∗ 3 3*3 33的窗口滑动经过整个特征层,并且每次计算都经过256维的向量并最终输出2个结果: 3 ∗ 3 3*3 33滑动窗口中是否有物体,以及该滑动窗口对应物体的矩阵框位置对应的4个值
  • b)图为将网络转化为正向立面进行计算的过程表示;
    在这里插入图片描述
  • 为了适应更多形状的物体,RPN定义了 K K K种不同尺度的滑窗,统一用 3 ∗ 3 3*3 33的滑窗难以满足多种情况,此时定义一个专业名词anchor(anchor:译为锚点,位于 n ∗ n n*n nn窗口的中心处),每个anchor都以特征层(feature map)上的像素点为中心并且根据其尺寸大小进行后续计算的。在Faster R-CNN论文中,滑窗在特征层的每个位置使用3种大小和3种比例,共有 3 ∗ 3 = 9 3*3=9 33=9个anchor,如上图中 n = 9 n=9 n=9
  • 针对分类任务,对于滑窗产生的每一个anchor都计算该anchor与真实标记矩阵框的IOU,当 I O U ≥ 0.7 IOU\ge0.7 IOU0.7时,便认为该anchor包含目标;当 I O U ≤ 0.3 IOU\le0.3 IOU0.3时,便认为该anchor不包含目标;当IOU介于0.3~0.7时,则不参与网络训练的迭代过程。
  • 针对回归任务,需要预测anchor中心点的横、纵坐标以及anchor的宽、高,学习目标为anchor与真实box在四个值上的偏移,RPN为一个全卷机网络,可以用随机梯度下降SGD的方式进行端到端的训练。
  • 需要注意的是,训练过程中与真实目标矩阵框相交的 I O U ≥ 0.7 IOU\ge 0.7 IOU0.7的anchor并不多,绝大多数都是负样本,因此会导致正负样本比例严重失衡。因此在RPN训练过程中,对每个batch进行随机采样(若每个batch样本数为256)并保持正负样本比例为1:1,而当正样本数量小于128时,去全部正样本,其余的则随机使用负样本进行补全。

1.6.3 Faster R-CNN原理

  • Faster R-CNN训练过程如下图所示,训练步骤为:
    1)使用对整张图片输进CNN,得到feature map;
    2)卷积特征输入到RPN,得到候选框的特征信息;
    3)对候选框中提取出的特征,输入ROI Pooling层变换为尺寸大小一致的候选特征;
    4)将变换后的特征使用分类器判别是否属于一个特定类;
    5)对于属于某一特征的候选框,用回归器进一步调整其位置。
    在这里插入图片描述

1.7 总结各大算法步骤

参考网址:https://www.cnblogs.com/skyfsm/p/6806246.html
RCNN:
  1. 在图像中确定约2000个候选框 (使用选择性搜索);
  2. 每个候选框内图像块缩放至相同大小,并输入到CNN内进行特征提取 ;
  3. 对候选框中提取出的特征,使用分类器判别是否属于一个特定类;
  4. 对于属于某一特征的候选框,用回归器进一步调整其位置。

Fast RCNN:
  1. 在图像中确定约2000个候选框 (使用选择性搜索);
  2. 对整张图片输进CNN,得到feature map;
  3. 找到每个候选框在feature map(即经过conv5后的特征层称为feature map)上的映射候选框,将此候选框作为每个候选框的卷积特征输入到SPP layer和之后的层;
  4. 对候选框中提取出的特征,使用分类器判别是否属于一个特定类;
  5. 对于属于某一特征的候选框,用回归器进一步调整其位置。

Faster RCNN:
  1. 对整张图片输进CNN,得到feature map;
  2. 卷积特征输入到RPN,得到候选框的特征信息;
  3. 对候选框中提取出的特征,使用分类器判别是否属于一个特定类;
  4. 对于属于某一特征的候选框,用回归器进一步调整其位置。

1.8 Mask RCNN

  • Mask R-CNN是在Faster R-CNN的基础上进行2处修改,如下图其中黑色部分为原来的Faster-RCNN,红色部分为在Faster-RCNN网络上的修改:
    1)增加预测mask的分支,即添加了并列的FCN层(mask层);
    2)将RoI Pooling 层替换成了RoIAlign层;
    在这里插入图片描述

1.8.1 RoIAlign

  • RoIPooling是从RPN网络输出的ROI中输出较小的特征图(a small feature map,eg 7x7),ROI的大小各不相同,但是RoIPool后都变成了7x7大小。RPN网络会提出若干RoI的坐标以[x,y,w,h]表示,然后输入RoI Pooling,输出7x7大小的特征图供分类和定位使用。
  • 问题就出在RoI Pooling的输出大小是7x7上,如果ROI网络输出的RoI大小是8*8的,那么无法保证输入像素和输出像素是一一对应,首先他们包含的信息量不同(有的是1对1,有的是1对2),其次他们的坐标无法和输入对应起来(1对2的那个RoI输出像素该对应哪个输入像素的坐标?)。这对分类没什么影响,但是对分割却影响很大。
    在这里插入图片描述
  • 如上图所示,在使用ROI Pooling时,原始图像是 800 ∗ 800 800*800 800800,狗的边框是 665 ∗ 665 665*665 665665,在经过VGG16特征提取后,使用了5个 2 ∗ 2 2*2 22的池化,所以图像变为原始的 1 32 \frac{1}{32} 321,对于原始图像变为 ( 800 / 32 ) ∗ ( 800 / 32 ) = 25 ∗ 25 (800/32)*(800/32)=25*25 (800/32)(800/32)=2525,对于边框变为 ( 665 / 32 ) ∗ ( 665 / 32 ) = 20.78 ∗ 20.78 (665/32)*(665/32)=20.78*20.78 (665/32)(665/32)=20.7820.78,结果为浮点数,但像素点是整数,所以做了第一次量化操作(即取整操作)变为 20 ∗ 20 20*20 2020,这一次的量化操作引入了误差;
  • 在feature map层,对于 20 ∗ 20 20*20 2020的ROI输入ROI Pooling层后输出固定尺寸 7 ∗ 7 7*7 77ROI Feature,此时相当于 20 / 7 ∗ 20 / 7 = 2.86 ∗ 2.86 20/7*20/7=2.86*2.86 20/720/7=2.862.86,同样是浮点数,我们进行第二次量化操作,量化为2,这样引入了第二次的量化误差。
  • RoIAlign采用==双线性差值法(ROI crop resize)==规避2次量化误差:
    1)为了计算 P P P点像素值,可分别采用2次线性插值法计算出 R 1 R_1 R1 R 2 R_2 R2的像素点,再使用一次线性插值法计算出 P P P点的像素值;

x 2 − x x 2 − x 1 = Q 21 − R 1 Q 21 − Q 11 \frac{x_2-x}{x_2-x_1}=\frac{Q_{21}-R_1}{Q_{21}-Q_{11}} x2x1x2x=Q21Q11Q21R1
可得到 R 1 R_1 R1的像素点为:
R 1 = x 2 − x x 2 − x 1 Q 11 + x − x 1 x 2 − x 1 Q 21 R_1=\frac{x_2-x}{x_2-x_1}Q_{11}+\frac{x-x_1}{x_2-x_1}Q_{21} R1=x2x1x2xQ11+x2x1xx1Q21
同理可得到 R 2 R_2 R2的像素点为:
R 2 = x 2 − x x 2 − x 1 Q 12 + x − x 1 x 2 − x 1 Q 22 R_2=\frac{x_2-x}{x_2-x_1}Q_{12}+\frac{x-x_1}{x_2-x_1}Q_{22} R2=x2x1x2xQ12+x2x1xx1Q22
最终在y方向上进行线性差值,得到 P P P点像素值为:
P = y 2 − y y 2 − y 1 R 1 + y − y 1 y 2 − y 1 R 2 P=\frac{y_2-y}{y_2-y_1}R_1+\frac{y-y_1}{y_2-y_1}R_2 P=y2y1y2yR1+y2y1yy1R2
在这里插入图片描述

  • 讲解ROI Align操作:
    1)黑色部分为feature map,红色边框表示ROI,为了输出 7 ∗ 7 7*7 77的矩阵框,所以将ROI切分成 7 ∗ 7 7*7 77的单元格,在每个单元格中均匀采样4个点(作者发现将采样点设为4会获得最佳性能),针对单元格中的4个点(将单元格划分为 2 ∗ 2 2*2 22的小单元格),针对每个点及周围已知像素点值为位置,采用双线性差值法得出该点像素点值,最后对4个点的像素点值进行maxpooling,就得到 7 ∗ 7 7*7 77像素点矩阵图,最终得到ROIAlign结果。

在这里插入图片描述

1.8.2 Mask分支

  • Mask RCNN模型损失函数为:
    L o s s = L c l s + L b o x + L m a s k Loss=L_{cls}+L_{box}+L_{mask} Loss=Lcls+Lbox+Lmask
  • 训练网络时输入Mask分支的目标是有RPN提供的,即Proposals(正样本);预测的时候输入Mask分支的目标是有Faster RCNN提供;
  • 训练时:经过RPN得到的Proposal,通过RoIAlign后得到对应的特征信息(shape为14x14xC),进入Mask分支,计算每个类别的logits,通过Faster R-CNN分支正负样本匹配过程我们能够知道该Proposal的GT类别为猫(cat),所以将logits中对应类别猫的预测mask(shape为28x28)提取出来。然后根据Proposal在原图对应的GT上裁剪并缩放到28x28大小,得到图中的GT mask(对应目标区域为1,背景区域为0)。最后计算logits中预测类别为猫的mask与GT mask的BCELoss(BinaryCrossEntropyLoss)即可。
    在这里插入图片描述
  • 预测时:通过Faster R-CNN分支,我们能够得到最终预测的目标边界框信息以及类别信息。接着将目标边界框信息提供给Mask分支就能预测得到该目标的logits信息,再根据Faster R-CNN分支提供的类别信息将logits中对应该类别的Mask信息提取出来,即针对该目标预测的Mask信息(shape为28x28,由于通过sigmoid激活函数,数值都在0到1之间)。然后利用双线性插值将Mask缩放到预测目标边界框大小,并放到原图对应区域。接着通过设置的阈值(默认为0.5)将Mask转换成一张二值图,比如预测值大于0.5的区域设置为前景剩下区域都为背景。现在对于预测的每个目标我们就可以在原图中绘制出边界框信息,类别信息以及目标Mask信息。
    在这里插入图片描述
    最终,Mask RCNN预测的是目标的边界框、目标的类别和目标的阴影区域。
    在这里插入图片描述
    Mask RCNN参考网址:https://blog.csdn.net/qq_37541097/article/details/123754766
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值