目标检测算法

目标检测算法一般分为两阶段检测和单阶段检测,常见的两阶段的检测方法有滑动窗口、R-CNN系列,SPPNET等,单阶段检测器有YOLO/SSD/Retinanet等,之后将逐一介绍这些算法的核心思想和贡献。

2012年之前,大部分的研究人员一直都在用传统的算法进行目标检测,大多是基于SIFT、HOG特征提取,然后送入分类器。比如滑动窗口的方法。滑动窗口将不同大小的窗口以不同的步长遍历图片每一个角落,将每一个区域都送入分类器中去分类,是一种非常暴力的穷举所有可能性的一种方法。因为遍历了所有的区域,因此会产生大量的冗余的图片,识别速度非常慢。2012年之后,Alexnet的提出,使得CNN网络卷入热潮。R-CNN应运而生,在目标检测的任务上比传统算法提高了百分之30的精度,达到了53.3%。下面首先介绍一下RCNN的核心内容。

1.RCNN

因为我们把region proposal和CNNs结合起来,所以该方法被称为R-CNN:Regions with CNN features。这篇论文将CNN引入到目标检测中来,从下图的第三个步骤可以看出,他使用了CNN对大量的候选框的图片进行特征提取,之后用SVM分类器进行分类,RCNN的目标检测主要分为四个步骤:用下图可以大致表示:

目标检测算法_第1张图片

首先输入一张图片,然后以selective search的方法生成候选区域,大概有两千个候选区域,生成候选区域是基于图像分割任务进行的,是无监督的提取。生成候选框的步骤:1、利用现有的分割方法将图像快速划分为许许多多的小区域 。2、然后基于相似度将相邻的相似度高的区域进行合并。3、不断合并相似的区域,直到整张图像成为一个区域。4在合并的过程中,基于所有产生的区域,都给出相应的矩形框。得到用于目标检测的候选窗口。当这些区域在分类器上呗分类的结果大于某个阈值的时候,相应的框会被标注出来。用下面这张图可以形象的说明到底是怎样生成这个候选区域的。

左边第一张最下面的图是最开始生成的很多很多个小块,然后基于相似度的一种算法,将相似的区域进行合并,直到整张图是一个大的区域,然后中间的图是说,在我生成这些区域的时候,同时画很多框,这些框就是我要检测的对象,在滑动窗口中,每一个窗口就是一个检测对象,同样,RCNN中的每一个候选区域,都要经过CNN进行特征提取,然后提取到底特征进一步分类。

目标检测算法_第2张图片

之后的操作就是用CNN网络进行特征提取,那么对于这么多尺寸不一致的区域,该怎么处理呢?论文中给出了一种放缩的处理方式,就是不论你的候选框是大还是小,统统都放缩到227*227,(当然论文中还提到了一些细节,比如放缩的时候,添加了一个16层的padding)然后送入CNN网络,以最后一个全连接层作为该区域的特征表示。

目标检测算法_第3张图片

最后一步是对提取到的区域的特征表示,进行分类。通常使用SVM和softmax进行分类。论文中用了一种线性变换来对边框的位置进行校准。

目标检测算法_第4张图片

这张图显示了RCNN在两个数据集上的表现,可以看到RCNN明显优于传统算法,和别的深度学习方法。在目标检测的任务上是最好的,然而检测一张图需要花费大量的时间,需要47秒。

2. SPP-Net

SPP-Net(Spatial Pyramid Pooling)是何凯明2014年提出的方法,通过解决传统CNN无法处理不同尺寸输入的问题对RCNN做改进,实验结果表明SPP方法比R-CNN快了近100倍。在RCNN算法中,无论是对候选区域的放缩,还是将2000多张候选区域放入CNN进行特征提取,都需要耗费巨大的时间,这也是RCNN中主要的耗时。

RCNN的问题:1、对候选区域进行放缩或裁剪导致信息丢失或变形。既然会丢失信息,那么为什么要进行resize,调整到一个固定的尺寸呢?那是因为同样大小的图片经过卷积层之后,会产生同样大小的特征图或特征向量,然后送入全连接层,因为全连接层的输入输出大小是固定的,因此,送入卷积层的图片大小也必须是固定的。那么sppnet就想,主要的问题是由于全连接层的输入必须是固定的向量长度,而卷积层的输入是没有限制的,(因为一个大图片和一个小图片经过卷积层之后无非就是卷完的特征图一个大一个小而已)。那么在sppnet中,我对输入的图像没有尺寸限制,然后采用了一种空间金字塔池化的方式来产生特定大小的向量,然后送入全连接层。

目标检测算法_第5张图片

空间金字塔池化方式:假设一个很简单的两层网络,池化的输出尺寸是未知的,全连接的输入要求为21

目标检测算法_第6张图片

在这里SPP一共3层:第一层对特征图像做池化(最大、均值等);第二层将特征图像划分为2*2=4个块,分别做池化;第三层划分为4*4=16个块,分别做池化 
通过以上步骤,最后获得1+4+16=21个特征值,(最后还要乘个通道数)

通过这样的方式,CNN网络可以接受任意尺寸的特征图,而不用考虑最后生成的特征向量的长度。

SPPnet还有一处改进,大大减少了网络耗时。RCNN中,首先生成2k个候选框,然后将2k个框送入CNN中,那么这样以来,一张图片我经历了2K次CNN计算特征,这太耗时了,而且一张图就这么大,计算了两千次,那么也就是说有很多特征都是重复计算的。SPPnet中我首先将一整张图送入网络,然后计算所有的特征,同样的我也有区域候选的步骤,选完了之后,我直接将这些区域通过坐标转换的方式,直接对应到原图的特征图上,也就是说在特征图上找到这些候选区域,然后送进SPPnet进行分类,相当于我跳过了把候选框送入CNN进行特征提取的步骤,通过这样一个技巧,速度提升了一百倍。

最后用一张图来表示一下SPPnet:

目标检测算法_第7张图片

3 Fast RCNN

Fast RCNN保持了sppnet的优势,并进一步简化sppnet为单尺度,文中称作ROI polling,这个操作和空间池化是一样的,只是他只有一个划分模板,具体的关于ROI pooling可以参考这个网址:https://deepsense.ai/region-of-interest-pooling-explained/

改进:引入光滑L1 损失函数:smooth L1 LOSS

                                                  目标检测算法_第8张图片

之前的损失函数通常用的是L2损失函数,而L2损失函数,通常类似二次曲线,在大的地方梯度大,而上面这条曲线则是在绝对值小于1的时候,是二次曲线,大于1的时候是一条直线,所以对于光滑L1损失函数,可以防止在特征较大的时候,梯度突然变得较大。因此具有更好的稳定性。

全连接层加速:将全连接层的权重矩阵分解为两个简单的矩阵,降低复杂度。加快计算速度。讲一个大的全连接层分解为两个小的全连接层。

目标检测算法_第9张图片

a)与SPP类似,它只对整幅图像做一次CNN特征提取,在后面加了一个类似于SPP的ROI pooling layer,其实就是下采样。不过因为不是固定尺寸输入,因此每次的pooling网格大小需要动态调整。
b) 整个的训练过程是端到端的(除去region proposal提取阶段),梯度能够通过RoI Pooling层直接传播,直接使用softmax替代SVM分类,同时利用Multi-task Loss(多任务损失函数)将边框回归和分类一起进行。

目标检测算法_第10张图片

这是论文中使用的损失函数,p和u分别表示类别的概率与真实的样本,t和v表示坐标预测与真实框。

1.multi-loss traing相比单独训练classification确有提升

2.multi-scale相比single-scale精度略有提升,但带来的时间开销更大。一定程度上说明CNN结构可以内在地学习尺度不变性

3.在更多的数据(VOC)上训练后,精度是有进一步提升的

4.Softmax分类器比"one vs rest"型的SVM表现略好,引入了类间的竞争

5.更多的Proposal并不一定带来精度的提升,最开始产生了两千个框,而我通过计算IOU,排除掉大量的阈值低于某个值的框,只计算剩下的300个。大大减少了计算量

这里再说一下Fast R-CNN的主要步骤: 
a) 特征提取:以整张图片为输入利用CNN得到图片的特征层; 
b) region proposal:通过Selective Search等方法从原始图片提取区域候选框,并把这些候选框一一投影到最后的特征层; 
c) 区域归一化:针对特征层上的每个区域候选框进行RoI Pooling操作,得到固定大小的特征表示; 
d) 分类与回归:然后再通过两个全连接层,分别用softmax做多目标分类,用回归模型进行边框位置与大小微调。 
总结:Fast R-CNN确实做得很棒,其缺点在于:region proposal的提取使用selective search,目标检测时间大多消耗在这上面(提region proposal 2~3s,而提特征分类只需0.32s),无法满足实时应用。
 

4.Faster RCNN

上面最后一句话说出了Fast RCNN还有缺点,就是这个region proposal使用的还是selective search,而文章开头说,这个是基于图像分割任务做的,说白了还是含有传统算法的内容,于是FasterRCNN在这方面做了一些改进,使用RPN(region proposal network)来产生候选区域。提出的RPN网络取代Selective Search算法使得检测任务可以由神经网络端到端地完成。这也是FasterRCNN的核心贡献。

让生成候选窗口的CNN和分类的CNN 共享参数。

目标检测算法_第11张图片

首先输入一张图片,然后通过卷积层得到最后一张特征图,用一个滑动窗口来遍历特征图上的每一个点,来生成k个候选窗口,称作anchor box。为了尽量代表所有物体,所以这些anchor box长宽比不同,尺寸大小不同。

因为是对提取的卷积特征图进行处理,因此,在特征图上的每个点创建 anchors. 需要理解的是,虽然 anchors 是基于卷积特征图定义的,但最终的 anchors 是相对于原始图片的。(最后显示出来的是在原图片上的一个框,而不是框在特征图上)

由于只有卷积层和 pooling 层,特征图的维度是与原始图片的尺寸成比例关系的. 即,数学地表述,如果图片尺寸 w×h,特征图的尺寸则是 w/r×h/r. 其中,r 是下采样率(subsampling ratio)你可以理解为缩放率。 如果在卷积特征图空间位置定义 anchor,则最终的图片会是由 r 像素划分的 anchors 集. 在 VGG 中,r=16. 

目标检测算法_第12张图片

目标检测算法_第13张图片

目标检测算法_第14张图片

RPN不关注每个位置到底是什么类别,只关注这个点预测的框是物体还是背景。RPN 是全卷积(full conv) 网络,其采用基础网络输出的卷积特征图作为输入. 首先,采用 512 channel,3×3 kernel 的卷积层,然后是两个并行的 1×1 kernel 的卷积层,该卷积层的 channels 数量取决每个点的 anchors 的数量. 

目标检测算法_第15张图片

k是anchor的数量。

对于分类层,每个 anchor 输出两个预测值:anchor 是背景的 score 和 object 的 score.

对于回归层,也可以叫边界框调整层,每个 anchor 输出 4 个预测值:Δxcenter、Δycenter、Δwidth、Δheight即用于 anchors 来得到最终的 proposals.

根据最终的 proposal 坐标和其对应的 objectness score,即可得到良好的 objects proposals.

Faster R-CNN的主要步骤如下: 
a) 特征提取:同Fast R-CNN; 
b) region proposal:在最终的卷积特征层上利用k个不同的矩形框(Anchor Box)进行region proposal;即对每个Anchor Box对应的区域进行object/non-object二分类,并用k个回归模型(各自对应不同的Anchor Box)微调候选框位置与大小 
c) 区域归一化:同fast R-CNN; 
d) 分类与回归:进行目标分类,并做边框回归(感觉这一块再做一次边框回归是不是有点重复)。 
Faster R-CNN的训练:为了让RPN的网络和Fast R-CNN网络实现卷积层的权值共享,其训练方法比较复杂。

目标检测算法_第16张图片
当然后续还有许多rcnn的改进版本,就不一一介绍了。

下面介绍几种单阶段的检测器

YOLO-1

 

目标检测算法_第17张图片

目标检测算法_第18张图片目标检测算法_第19张图片

目标检测算法_第20张图片

SSD

目标检测算法_第21张图片

 

目标检测算法_第22张图片

目标检测算法_第23张图片

最后会得到(38*38*4 + 19*19*6 + 10*10*6 + 5*5*6 + 3*3*4 + 1*1*4)= 8732个prior box。 

难例挖掘:选择较难的

数据增强:

DSSD:Deconvolutional Single-shot Detector

目标检测算法_第24张图片

目标检测算法_第25张图片

目标检测算法_第26张图片

目标检测算法_第27张图片

参考文章:

视频:https://www.bilibili.com/video/av19359393/?p=2

RCNN :https://blog.csdn.net/v1_vivian/article/details/78599229

SPPNET:https://blog.csdn.net/v1_vivian/article/details/73275259

Fast RCNN:https://blog.csdn.net/weixin_41278720/article/details/81184791

Faster RCNN:https://blog.csdn.net/zziahgf/article/details/79311275

YOLO1: https://blog.csdn.net/hrsstudy/article/details/70305791

你可能感兴趣的:(算法)