目标检测是计算机视觉领域最经典最重要的任务之一,经过十几年的发展,目标检测已经日趋成熟。在2005年,有人将基于方向梯度直方图(HOG)的特征提取和基于支持向量机(SVM)的分类方法结合起来,创建了一种目标检测的方法,在行人识别上获得了很大的成功。后来,由于AlexNet(2012)的出现,学术界开始出现构建大型卷积神经网络的潮流,目标检测任务也在这个时间段蓬勃发展了起来,在速度、检测准确率等方面都得到了很大的进步。
关于目标检测,它的主要任务是在图片中检测出物体。一般我们看到的形式,大多是在一张图片上,用一个矩形框框出图片中的物体,并标注这个物体属于哪个类别。实际上,目标检测任务共有四个不同的方案,如下图所示。
1. 第一种是给定含有单个物体的图片,对于整张图片给出一个分类结果:图片中的物体属于哪种类别。这属于比较简单的工作,在实际应用中,往往是收集只含有一个对象并几乎占满整张图片的图片作为训练集,训练模型,并且把模型用作目标检测的一部分。 2. 第二种和第三种都是在给定图片中,**对于每一个物体都要框出物体所属的区域,并且给出每个框中识别到的物体的类别**。这种在实际应用中最为常用,本文介绍的目标检测就是要实现这样的效果。 3. 第四种是对图片中的对象进行实例边缘分割,要求将图像精确的轮廓描绘出来。在实际应用中,往往只有特别精细的检测才需要完成这种任务,本文不讨论这种情况。接下来介绍依次改进的三种目标检测方法:R-CNN,Fast R-CNN,Faster R-CNN.
对于目标检测问题,首先我们来分析一下简单的实现方案。
以人脸识别为例,假设我们有很多很多类似证件照的人脸图片,每张图片的大小都相同。我们现在需要实现一种算法,使得在一张普通的图片中也能检测出人脸。
我们有了许多的人脸数据,那么就很容易训练出一个检测人脸的模型,去判断一张固定大小的图与人脸的相似度如何,判断它属不属于人脸。然后对于一张一般的图,我们使用一个滑动窗口去遍历图像的每一部分,输入检测模型去判断这个方框内是否存在人脸。然后对于检测出人脸的边框,利用一些算法将它们相近的几个整合成一个边框,从而达到识别出物体(人脸)的效果。
HOG+SVM的行人识别和基于区域的卷积神经网络(R-CNN)用的都是这种思想。这种目标检测的思想主要分为三个步骤:
R-CNN的解决方案实际上效果也很不错,但是也存在着许多缺点:
于是,从改进这两点的角度出发,Fast-R-CNN出现了。
Fast R-CNN,顾名思义,就是在R-CNN基础上发展起来的检测速度更快的解决方案。由于R-CNN产生的候选区域之间可能有很多重叠的部分,在使用卷积神经网络进行特征提取时,有重叠的候选部分区域的特征图之间也会有很大部分重叠,这就会导致对于一张图片的某一部分进行多次特征提取,浪费时间和空间资源。
从这个角度出发,我们是否可以先对图像进行特征提取,再选出候选区域呢?这显然是可行的。但也存在这一个问题:对于卷积神经网络中的层次来说,我们都必须要保证所有图片到达每个层次的尺寸是一样的,例如AlexNet的输入必须都是(224,224,3),而选择性搜索产生的候选区域可能是大小不一的,经过卷积神经网络提取特征后的映射部分也同样是大小不一的,这样,普通的卷积神经网络就无法再进行下一步的操作了。在R-CNN中,这个问题的解决方案是对于选出的候选区域进行resize,但卷积操作后的特征图已经没有了图像原本的特征,不能进行resize。针对这个问题,Fast R-CNN使用了一种称为感兴趣区域(RoI)池化层的神经网络层次,解决了这个问题。
RoI池化层是将一张任意大小的图像,均匀分成 X × Y X\times Y X×Y个部分,然后在每个部分中使用最大或平均池化,这样就可以将不同大小的特征图在充分保留其特征的前提下,达到输入特征图尺寸相同的目的。
另外,Fast R-CNN还使用了一种微调候选框的一种方法:边界框回归。我们首先要在图片中精准地标出物体的真实位置,然后用回归的思想,利用提取出的特征图去拟合这个真实位置,达到微调候选框的效果。当然,也不能少了分类模块。因此进行RoI池化后的特征图,先经过几层共用的全连接层进一步提取特征后,一部分送给全连接层+softmax进行分类工作,另一部分送入边界框回归模块执行定位操作。如下图所示。
比起R-CNN,Fast R-CNN有如下优点:Fast R-CNN较之R-CNN在速度和精度方面已经有了很大提升,但生成区域建议的算法需要在CPU上运行,限制了速度的提高。从这个角度出发,将生成区域建议的算法进行改进,就产生了Faster R-CNN.
Faster R-CNN最大的创新点在于引入了区域建议网络(RPN),将生成区域建议的步骤也放入了神经网络中,在端到端学习方式中实现了一种几乎无成本的区域建议算法。Faster R-CNN的网络架构如下图所示:
从图中可以看出,Faster R-CNN其实就是在Fast R-CNN基础上加入了RPN。细分下来,Faster R-CNN可以认为由五个模块组成:训练时,利用预训练的VGGnet-16模型初始化网络,随机初始化RPN,利用标注数据训练RPN;接下来使用训练好的区域建议网络训练单独的一个快速R-CNN网络,这两步中的卷积层不共享;再保持共享卷积层固定,微调RPN的特定层;最后再调整后续的全连接层参数。
对于各种目标检测算法的速度,可以详见下图。