先把文章地址放在这Rich feature hierarchies for accurate object detection and semantic segmentation
代码地址也放在这code
作者在摘要中说这个方法主要有两个创新:一是可以在候选区域Region Proposal上用大容量的卷积神经网络对目标进行定位和分割;二是当标记训练数据少时,使用辅助的预训练和特定区域的微调(fine-tuning),可以达到很好的效果。
之前的目标检测大多数基于SIFT(Scale-invariant feature transform)和HOG(Histogram of Oriented Gradient),但是在PASCAL VOC这个比较权威的数据集上,这两者效果并不显著。SIFT和HOG是块状直方图,但是识别发生在比较下游的阶段(作者说的比较模糊),说明识别是分级的,是有多个阶段的,在这些层次中有可能有对识别更有效的信息,SIFT和HOG将其忽略了。
作者也介绍了其他人的一些方法,比如Fukushima的neocognitron和Lecun等人的CNN,还有SVM(支撑向量机,这个概念还是很重要的)。CNN在ImageNet上取得了很好的成绩,那能不能运用到PASCAL VOC这个数据集上做目标检测呢?主要是解决两个问题:用深度网络定位目标和在小规模的标注数据集上做大规模的模型训练。
目标检测与分类不同的地方就是需要做目标定位,有一种对区域进行识别的方法recognition using regions在目标检测和语义分割上都有很好的效果,本文就是用了这种方法。在测试的时候,对于一幅图像,我们的方法可以生成2000个独立的候选区域region proposals,对于每一个区域,我们用CNN得到一个固定长度的特征向量,然后用线性SVM对区域进行分类。这个方法结合了Region和CNN,所以称为R-CNN:Regions with CNN features。下图显示了这个方法的主要步骤:
第二个挑战就是标注数据集太少,不够训练一个大型CNN,传统方法是使用无监督预训练,之后跟有监督微调(fine-tuning)。这篇论文的主要贡献就是说明了:在大的辅助训练集ILSVRC上的有监督预训练,之后跟着在小训练集PASCAL上的对特定领域的微调,是一种在数据很小的时候的非常有效的方式。
Object detection with R-CNN
结构上来说主要分三个模块:生成独立分类的候选区域;对每个区域用大规模CNN网络抽取固定长度的特征向量;指定类别的线性SVM。
第一个模块,之前有很多不同的方法来选取候选区域,这里作者采用了selective search这个方法,参考论文Selective Search for Object Detection
第二个提取特征模块,我们对每个候选区域提取一个4096维的特征向量,框架是Caffe,网络结构是我上一篇说的Krizhevsky的那篇文章,5层卷积层和两层全连接层。首先要把候选区域转化成适合CNN的尺寸227* 227,不管一个区域的长宽比,我们将环绕这个区域的边框(bounding box)变形成需要的尺寸,在变形之前,我们先放大边框,使得变形之后的边框周围有一圈16个像素环绕在原始边框外。(啊好绕口,这句话我读了好几遍还是有点懵,原话:Prior to warping, we dilate the tight bounding box so that at the warped size there are ex- actly p pixels of warped image context around the original box (we use p = 16)。我放一张图片大家体会一下:
第三个就是对每个特征向量使用SVM进行训练。在此过程中,我们使用非最大值抑制,就是如果一个区域与那些高于一个阈值并且得分很高的区域有交叉重叠,则这个区域就被抑制。
有两点可以加快速度:首先对于所有分类,CNN的参数是共享的;其次就是CNN提取出的特征向量是低维的。主要需要计算的特征和SVM参数之间的点乘和非最大值抑制。
Training
刚开始的预训练就是使用ILSVRC2012 classification作为辅助集,这个CNN取得了跟Krizhevsky差不多的成绩,top-1错误率高了2.2%,因为训练的时候有一些简化的步骤。
之后的针对特定区域(region proposals)的训练,我们继续使用随机梯度下降算法,网络其他的结构不变,唯一改变的是最后的1000维输出层改成了随机初始化的(N+1)维输出层,N是目标分类个数,1是背景。比如VOC数据集,N=20,ILSVRC2013的N=200。
比如说定位汽车,有一个框把汽车包围起来很显然应该标定为真,有的框完全是背景应该被标定为假,但是如果有的框有一部分是汽车,有一部分是背景呢?这种情况下我们设定一个阈值,这个阈值表明了这个框和真实汽车的重合度,高于这个阈值即为真,低于则为假。设定0.3IoU(Intersection over Union)为阈值,这个是经过多次试验才决定的,比如作者说设为0.5的时候mAP降低了5%,设为0的时候mAP降低了4%。
Visualizing learned features
第一层卷积层就是直接检测边缘和颜色,很好理解,对于之后的几层,作者介绍了一种方法来理解它们的作用,单独挑出一个单元,这里单元可以理解成为特征,将这个单元本身当做一个目标检测器来使用,即,首先计算这个单元对于一个大规模候选区域的激活值(proposals可以达到1000万),然后这些区域根据激活值从高到低进行排列,应用非最大值抑制,然后显示得分最高的区域。这种方法可以让这个特定单元显示其对哪些输入有响应。
这些单元从第五层卷积层之后的池化层pool5挑出,回忆一下上一篇说的网络结构,前五层是卷积层,后三层是全连接层,我们就在卷积完全结束之后的那一层挑出特殊的特征。注意在195* 195的感受野中,中心的单元有比较全面的视角,而越靠近边上给出的信息就越少。
每一行都是每一类中激活值最高的前16名,每一行几乎都可以精准的定位一个类别。这就是网络所学习的特征。
Finetuning
这一小节讲了有微调和无微调时每一层的性能。首先说明一下什么是微调finetune,我们上面说过,这个论文有一个挑战是在比较小的数据集上训练,但是对于一个需要千万级的数据的网络,只给几万级或者几千级的数据集来训练是肯定不够的。此时我们就不从全新的网络开始训练,我们使用别人已经训练好的模型,然后再加上自己的小数据集进行训练,这个训练过程被称为微调。
如果训练一个全新的模型,正确率肯定是从很低慢慢往上升,这样正确率还没有升上来数据就训练完了,但是如果用别人已经训练好的模型,刚开始进行训练就可以达到一个可以接受的正确率。微调的意义就是这个。
无微调时的性能分析:第五层上面已经说过了,其特征图是一个6* 6* 256=9216维的向量,这个向量是通过逐组半波整流得到的,即x ← max(0, x),而第六层是一个全连接层,它将一个4096* 9216的矩阵与第五层得到的9216维向量相乘,并加上一个偏置项。第七层则是将第六层得到的向量与一个4096* 4096矩阵相乘然后添加偏置项。
截取了pool5、fc6、fc7三层的结果,可以看到,在没有微调时,fc7的mAP反而下降了,这意味着29%的参数可以被移除而不会降低正确率,当我们将六七两层都移除时,只使用6%的参数(前五层)也得到了非常好的结果,意味着其实大多数工作是被卷积层干了的。
有微调时性能分析:
在这里,微调将最后的结果正确率大大提高,到了54.2%,六七两层的进步远远比第五层要大。
说到这里我觉得这篇论文最重点的部分已经结束了,之后是一些对于数据集的介绍和与其他目标检测方法的对比。
撒花~下一篇应该是Fast R-CNN。