近些年深度学习在图像领域大放光彩,这篇文章先对目标检测领域深度学习的发展做一个总结,再结合一个例子对tensorflow model zoo中的目标检测API使用做一个说明。
本文内容如下(会分几次发出来):
目标检测的任务
深度学习在目标检测中的应用
(一)目标检测的任务
为了说明什么是目标检测任务,我举两个例子来说明。
第一个VOC数据集,VOC2007数据集是一个训练目标检测的数据集,其图片中一共有二十个种类的物体,包括 ‘aeroplane’, ‘bicycle’, ‘bird’等一共20个种类的物体,我们的任务就是在图中把这些物体给找到,框出这些物体,并说明框住的物体是这二十个类别里的哪一类,就像下面这样:
对照上面的图片,可以看出目标检测主要是在做两件事,一是确定图片中有没有你要找的东西,二是这东西在哪。
下面还有另外一个例子,数据集在这http://www.robots.ox.ac.uk/~vgg/data/scenetext,是一份场景文字数据集,这个数据集一共有80万的图片,每张图片中都嵌入了文字,任务是找到图片中的文字,把文字框出来,如下:
对于这样的目标识别任务,训练数据集的输入是一张图片,加上图片中每个物体框的左上角坐标以及右下角坐标。
(二)深度学习在目标检测中的应用
深度学习在目标检测中的应用主要分为两个路子的方法:
相对来说faster RCNN和RFCN的精度是比较高的,但因为分两步走,所以检测的耗时偏长,yoloV2和SSD的精度较faster RCNN和RFCN略微偏低,但可以速度快,可以满足实时性要求。
关于几种方法的对比,可以参考谷歌最近出的一篇论文,里面详细比较了faster RCNN,RFCN和SSD的精度和性能,链接:https://arxiv.org/abs/1611.10012
下面我们一一说明每种方法的步骤和原理,这部分会假设读者已经了解像VGG,ResNet这样的卷积神经网络,不然就会云里雾里了。此外这是一份总结,会给出每个算法的框架和其中一些不易理解的点,但不会详细描述具体的网络细节,关于网络细节在网上已经有很多很好的博客可以参考。
先从把深度学习带入目标检测的开山之作RCNN系列开始。
RCNN,fast RCNN,faster RCNN这三种方法是一脉相承的,从名字就可以看出,速度越来越快,同时准确度也越来越高。
下面是一张RCNN的整体架构图:
VOC数据集中的图片是大小不一的,所以在RCNN中首先会把图片缩放到固定尺寸(227x227),接着通过selective search的方法找到图片中有可能是物体的2K个候选框(ROI),再把这些候选框依次送入CNN进行特征提取输出固定长度的向量,把这些向量输入SVM分类器,注意这里有20个SVM的二分类器,用来判断这个ROI是某一类还是背景,并且会对这个ROI的bbox进行回归,以精修位置(下面细说),最后通过非极大抑制去除重复框住物体的框,留下最准确的框。
RCNN的步骤十分清晰,每一步要做什么也很明白。
对selective search感兴趣的话可以查看相关论文,这里不做解释,因为这个方法在faster RCNN中就已经不用了。这里只要知道它输入是一张图片,输出是一堆这张图片中有可能是物体的候选框。
CNN提取特征部分是把每个ROI作为输入,经过一系列卷积+pooling后接一个全连接层把不同大小的ROI计算成一个固定长度的向量。
对每个ROI使用SVM进行分类时,这里SVM的训练数据和前面CNN的训练数据是不一样的,因为训练CNN需要大量数据,所以对候选框的选择设定了一个比较宽泛的范围,比如把和真实框(GT:ground truth)IOU大于0.3的都设定为正样本,而在训练SVM分类器时,由于传统算法对数据中的噪音比较敏感,所以把和GT的IOU大于0.5的作为正样本,设定了一个更严格的阈值。
至于为什么用SVM而不用softmax,作者认为这样准确率更高,但在后续的算法中都不再使用SVM了。
对于边界回归(bbox-rg),可以看下面这张图,图中P框(蓝色)为经过selective search输出的一个预测框,G为真实框(红色), G^ 为经过回归后更接近真实框的最终预测输出框(黑色)。
边界回归就是要把P框回归到 G^ 框。要做到这样的变换,只需要两步:平移和缩放,操作如下:
记这三个框为: P:(Px,Py,Pw,Ph) , G:(Gx,Gy,Gw,Gh) , G^:(G^x,G^y,G^w,G^h) ,这里的下标x,y表示目标框中点的坐标,w,h表示目标框的宽度和高度,对于G需要根据数据集中的label给定的顶点坐标做转换。
第一步平移,记横向和纵向的平移量分别为 Δx 和 Δy ,可以用如下公式来表示:
RCNN的步骤很繁琐,但每一步要做的事很简单。这里面在用selective search生成2K个候选框后,里面会有大量的重叠,这样的话在CNN部分就会有很多重复的操作,极大的浪费了时间,于是fast RCNN在这方面做了优化。
fast RCNN的第一步生成候选区和RCNN一样,使用了selective search的方法,和RCNN不一样的是CNN部分不是把每个ROI依次输入网络,而是把整张图片一次性输入网络,这样重叠的ROI只会进行一次卷积操作,节省了时间,整体架构如下图:
从以上流程图可以看出,理解fast RCNN的关键就在第三个框,经过第二步后我们得到的是图片经过卷积的feature map,此时根据selective search输出的2K个ROI,找到feature map上对应的区域,这部分ROI的大小是不一样的,而后面要连接的是全连接层,因此必须把尺寸做到一样大,所以使用了ROI pooling技术。
先看ROI pooling,稍后会解释每个ROI传递给后面的全连接层这部分的反向传播是怎么做的。
ROI pooling 一点都不神秘,pooling的过程和常规的2x2 pooling或者3x3 pooling是一样的,只不过这个2和3在变,比如说pooling后你要得到7x7xchannel的尺寸,当前这个ROI对应到feature map上的尺寸为14x14xchannel,那么就对这个ROI做2x2的pooling,如果是21x21xchannel就是3x3的pooling,依次类推。
对比RCNN,RCNN把一个ROI编码到一个固定长度的向量,送入SVM做分类,并作box-rg,fast RCNN也有这样的操作,只不过是通过ROI pooling把一个ROI做成一个固定大小的feature map,接下来的操作类似,在这个固定大小的feature map后连接全连接层。这个全连接网络是一个学习多任务的网络,输出当前ROI中的类别并作bbox-rg。
这里的多任务学习最后分出两个任务,一个softmax,用以区别当前这个ROI是什么东西,另一个任务是box-rg.
多任务的学习就要用到多任务的损失函数,我们用损失函数来解释这个多任务是怎么做的,fast RCNN的损失函数设置如下: