第二篇我们介绍了目标检测中传统的算法和目标检测的方式,第三篇我们对传统的目标检测算法和深度学习目标检测算法简单做了比较,此篇记录了深度学习目标检测算法内容,深入讲述一下深度学习算法在目标检测的原理和效果。而深度学习算法在目标检测分为类两个阶段:
我们首先对Two-stage进行介绍。
Two-stage的目标检测算法主要是通过一个完整的卷积神经网络
来完成目标检测的过程,进行目标检测时用到的特征就是CNN的特征,也就是通过一个CNN卷积神经网来提取对候选区域目标的特征的描述。
对于Two-stage的目标检测算法最典型的代表就是2014年提出的提出R-CNN到faster RCNN的一系列算法。
在训练过程中需要两个步骤:训练RPN网络、目标区域的网络训练。相对于传统的目标检测算法,不需要再进行训练分类器,不需要再做特征表示这个过程。整个过程都是从A到B的一个完整的卷积神经网络完成,同时精度得到提升。不过相比于one-stage慢些。
上述描述可以总结为以下几点:
输入图片------对图片进行深度特征的提取(主干神经网络)------RPN网络完成滑动窗口所完成的任务,也就是产生候选区域,完成候选区域分类(背景和目标)对目标的位置进行初步定位-------为了不重复的计算CNN特征,通过roi_pooling完成抠图操作-----fc全连接层对候选区域进行表示----分类和回归对候选目标的类别判定和位置精修(得到物体的真实类别)
详细流程:
首先输入一张图片,然后图片进行深度特征提取,也就是一幅图作为输入经过一个卷积神经网络,通常将其称为主干网络,典型的主干网络包括VGG、ResNet等一些经典的卷积神经网络,再然后通过一个RPN网络来完成传统目标检测算法中滑动窗口所完成的任务,也就是产生候选区域。在进行候选框区域提取的同时对候选框区域分类(分类过程中将候选框区域分类为背景和目标两种不同类别)。在RPN网络产生候选区域的时候也会对目标的位置进行初步的预测,意味着RPN网络同时完成区域分类和位置精修两个环节。在得到候选区域之后,通过roi_pooling层对候选区域进一步精确进行位置回归和修正,可以将roi_pooling理解为抠图,接下来得到候选目标对应到feature map上的特征后,会通过一个fc层,来进一步对候选区域的特征进行表示,接下来通过分类和回归来分别完成对候选目标的类别的判定以及候选目标位置的精修,这里的类别不同于RPN网络的类别,这里通常会得到物体真实的类别,回归主要得到当前目标具体的坐标位置,通常表示为一个矩形框,即四个值(x,y,w,h)。
Two-stage有两个重要的核心组件是:
简单的网络结构:比较经典的就是LeNet(具有一个输入层,两个卷积层,两个池化层,3个全连接层,但LeNet在大规模的任务中网络表达能力和抽象能力就相对弱一些)
复杂的网络结构:经过LeNet又出现了LSNet、Resnet、Vgg等复杂的网络结构,这些网路结构往往是用来增加网络的深度,因为网络越深,非线性表达能力越强,得到物体更加抽象的表达,对于图像的变化敏感度越不敏感,鲁棒性越强,解决非线性任务能力越强,同时也会导致梯度消失或梯度弥散。其中最典型的是Resnet可是达到100多层的深度,再经典的就是GoogleNet。
在设计时候考虑性能和模型大小,此时就需要用到轻量级的CNN网络,如经典的ShuffleNet、MobileNet等。
在了解RPN网络前我们先了解一些相关概念区域推荐(Anchor机制)。
往往,图片上的每一处位置都有可能出现目标物体,并且目标的大小是不确定的。那有什么办法能检出所有的物体呢?最容易想到的办法就是,以一个像素为中心截取很多个不同宽高比和大小的小块,每个小块都检测一下包不包含物体,如果包含物体,该物体的位置就是刚刚截取的这个小块的位置,同时再预测一下它的类别是什么。这样就可以做到不漏掉当前这个像素上的任何宽高比和大小的物体了;那刚刚截取的这个小块就是一个anchor box。
为了检出图像中不同位置的物体,使用滑动窗口的方式,从左到右,从上到下,把图像扫描一遍,每个像素点上都取很多小块进行检测,这样就可以保证不同位置、不同大小的物体都不漏掉了。Fig. 1是一个扫描检查的示例。
这种方法容易理解并且确实有效,但是缺点也是突出的----计算量太大了。假如一张图片的特征图大小为640*640,在图像中每一个像素上取10个不同宽高比不同大小的框做检测,则需要检测的框就会有640 x 640 x 10 = 4096000,太多了,如下图。那怎么改进呢?
其实,对于上面的问题有两个明显可以改善的点:
所以,设法在保证覆盖整张图的基础上,略去重叠太严重的框,避开背景框,找高质量的、可能包含目标物体的候选框进行检测就显得尤为重要,可以以此来降低运算量,提高检测速度。
anchor boxes就是我们在检测之前确定的一系列候选框。我们默认,图片上会出现的所有物体,都会被我们设定的anchor boxes所覆盖。anchor box选择的好坏直接关系到两个方面:
所以anchor box的设定非常重要,既关系到精度的好坏,又关系到速度的快慢(速度仅就以上所说的扫描法而言)。
使用设定的anchor boxes进行降低运算量,提高检测速度。anchor boxes如何设定呢?我们通过以下步骤完成:
举例来说明:假如要在一个数据集上做物体检测, 该数据集的图片分辨率均为256 x 256 , 数据集里绝大多数数目标物体的尺寸为 40 x 40或80 x 40。
高宽比(aspect ratio)的确定
因为绝大多数 数据集里目标物体的尺寸为 40 *40或80* 40,这说明数据集中绝大多数物体的真值边框的高宽比为1:1和2:1。 根据这个信息就可以确定锚框的高宽比信息,为这个数据集设计anchor boxes时其高宽比至少需要包括1:1和2:1。 这里举例为方便就只取1:1和2:1。
尺度是指物体的高或宽与图片的高或宽之间的比值。例如图片的宽为256px,图片中物体的宽为40px,则该物体的尺度为40/256=0.15625,也就是说该物体占了图片15.62%的宽度。
为了选一组能更好的代表数据集里目标的尺度,我们应该以数据集中目标物体的最大尺度值和最小尺度值为上下限。如,数据集中物体的尺度的最小值和最大值分别为0.15625和0.3125,我们准备在这个范围内设置3种scale,则可以选择 {0.15625, 0.234375, 0.3125}。
我们的scales(尺度)为 {0.15625, 0.234375, 0.3125},高宽比 aspect ratios为{1:1, 2:1}, 则每一个锚点上的一组锚框的数量为3x2 = 6个。如下图所示,即有3种{0.15625, 0.234375, 0.3125}大小,每一种大小都有两种高宽比{1:1, 2:1}。
按照以上方法所说,锚点是指256x256图像中的每一个像素,按基于anchor的神经网络目标检测来讲,锚点为网络最终输出特征图上的每一个点。
在网络中anchor boxes是被用来编码目标物体的位置。目标检测一般是不会直接检测物体边框的绝对坐标的,而是检测其相对某一个锚框的偏移量,如下图中绿色真值框对蓝色边框的偏移。数据集中所有的目标均会被编码成对anchor boxes的偏移。如1.1问题引入中的图片, 锚框有非常多个,对一张图片来说,可能包含多个物体,有非常多个anchor boxes, 那怎么用anchor boxes对真值进行编码呢?
编码之后,物体检测类网络的回归目标变成回归编码好的偏移量了。网络的输入为图片,输出为每一锚框的分类和偏移量。网络最终输出的特征图上的每一个像素都有一组锚框(假如一组锚框的数量为6个,宽高比为2:1和1:1, 尺度为0.15625, 0.234375, 0.3125,如图),设网络最终输出的特征图分辨率为7*7,则该回归网络中的锚框数量总数为7x7x6=296个。网络接收到的真值为这296个anchor box是否为背景的分类信息(如果包含物体,则分离为物体类别)和每个anchor到目标物体bounding box的偏移量(含糊框和背景框的偏移量为0),网络的输出为296个框的偏移量和分类信息。
对一个训练好的网络,其输出中,只包含背景的锚框的分类为背景,偏移为0;包含物体的锚框,其分类为物体的类别,偏移为锚框与物体真实边框之间的偏移
神经网络的特性之一是位移不变性。例如对一张包含树的照片,不管树在这张图片的左上角还是右下角,网络输出的分类都是树,分类结果不会因为树在照片中位置的变化而变化。所以,对于一棵树,不管它在图片中的位置是什么,回归网络都偏向于为它输出相同的位置坐标,可见位移不变性和我们需要的位置坐标变化是冲突的,这显然是不行的。转而回归偏移的话,不管树在图像中的什么位置,其对它所在的锚框的偏移量基本是一致的,更加适合神经网络回归。
锚框不是应该放在输入图上吗,为什么说输出特征图上的每一个点一组锚框?
如图所示,输出特征图(最右边3 x 3的小特征图)上的任何一个点都可以映射到输入图片上(感受野的意思),也就是说按照比例和网络的下采样,对输出特征图上的任意一点,在输入图片上都可以成比例找到它的对应位置。例如,在输出特征图上(0, 0)的点在输入图片上的对应位置为(2, 2), 网络的输出特征维度为3 3 84 ( = 3 3 6 14),则输出特征图上点(0, 0)处的84个通道对应的值为输入图(2, 2)位置上6个锚框的偏移量和分类值。3 3 84 = 3 3 6 14中的6为6个anchor box, 14中的4为(x,y,w,h)的偏移量,14中的10为类别数。
通过这样的隐式映射关系,将所有的anchor box都放在了输入图片上。
Anchor 的本质是 SPP(spatial pyramid pooling) 思想的逆向。而SPP本身是将不同尺寸的输入 resize 成为相同尺寸的输出,所以SPP的逆向就是,将相同尺寸的输出,倒推得到不同尺寸的输入。
区域推荐:称为Anchor机制,即n*c*w*h ,其中n代表样本数,c代表通道数,w和h代表图像高度和宽度
将w*h区域内的每个1个点作为候选区域中心点,进行提取候选区域,这样的每个点都称为Anchor。
以某个点为候选区域中心点进行提取候选区域时候,通常会按照一定的比例来提取。例如fastRCN中每个中心点提取9个候选区域。因此1个w*h的区域需要提取候选区域为 w*h*9个。
针对这些候选区域和真值(GT),利用真值来对这些后续区域进行筛选,经过筛选后得到正负样本,
其中正样本就是包含了候选目标的区域,而是否包含则通常是通过IOU进行判断,即真值与候选区域的重叠的覆盖面积判断,
如果真值和后续区域重叠的面积超过70%,就是正样本。如果小于30%就是负样本。
这里的0.7和0.3都是超参,可自行设定。
RPN网络对主干网络(VGG、ResNet等其中之一)输出的feature map进行处理,产生多个可能含有目标的建议区域。它由两个卷积分支构成,其中一个分支通过对坐标的回归,定位目标在图片中的大概位置,另一个分支通过二分类处理,找出包含目标的前景区域。RPN的网络结构如图所示:
RPN的输入特征图就是图1中由主干网络提取的Feature Maps,也称共享Feature Maps,其尺度为H(高)× W(宽)× C(通道数)。在这个特征参数的基础上,通过一个3×3的滑动窗口,在这个H×W的区域上进行滑动,可以得到H×W个3×3的窗口。每个3×3的窗口的中心点都对应原始图片中一个目标区域的中心点。
然后对每个特征向量做两次全连接操作,一个分支得到2个分数(前景和背景的置信度),另一个分支得到4个坐标(目标的坐标框信息),4个坐标是指针对原图坐标的偏移。由于要对每个向量做同样的全连接操作,等同于对整个特征图做两次1 × 1的卷积,得到一个2 × H × W和一个4 × H × W大小的特征图。最终再结合预先定义的Anchors,完成后处理操作,得到候选框。
整体上RPN客户以整理成以下几点: