zoukankan      html  css  js  c++  java
  • 目标检测--Rich feature hierarchies for accurate object detection and semantic segmentation(CVPR 2014)

    Rich feature hierarchies for accurate object detection and semantic segmentation

    作者: Ross Girshick Jeff Donahue Trevor Darrell Jitendra Malik

    引用: Girshick, Ross, et al. "Rich feature hierarchies for accurate object detection and semantic segmentation." Proceedings of the IEEE conference on computer vision and pattern recognition. 2014.

    引用次数: 2027(Google Scholar, By 2016/11/23).

    项目地址https://github.com/rbgirshick/rcnn (基于MATLAB)

    1 介绍

    这篇文章是2014年CVPR的一篇文章,就是很出名的RCNN(Regions with CNN Features),利用了深度学习的方法来做目标检测.

    本模型主要包含了3 + 1个模块:

    模块一: 生成类别独立的候选区域

    何为类别独立的(category-independent,CI)区域? 比如说我们想识别一张图像上的猫和狗,生成的CI区域不能横跨猫和狗,而只能属于它们之一,或者干脆是背景.在一张图像上生成CI区域的方式有很多,本文采用的是Selective Search的方法,关于这个方法,请参考我的另一篇博文<论文阅读笔记--Selective Search for Object Recognition>.

    模块二: 利用一个大CNN来提取每个候选区域的特征向量

    模块三: 利用CNN特征为每个类别训练一个二分类线性SVMs 

    可选模块: 利用CNN特征来做Bounding-box回归

    2 训练和测试流程图

    2.1 本文模型训练流程图

    训练的过程从前到后可分成五个部分:

    第一部分: 训练集构造(用于对CNN进行微调)

    给定一系列的输入图像,如何构造训练集?我认为也是先用Selective Search的方法在每个图像上生成很多的候选区域(具体多少文中好像没有讲),然后在每张图上依次计算每个候选区域与图中目标的ground-truth box之前的重叠程度(IoU),如果重叠程度大于0.5则标记这个区域为此目标的正样本,否则,为负样本.对所有的训练图像执行这样的操作,可以把得到的所有的候选区域保存下来以备使用.假如说有20个目标,对每个目标我们都有一些属于它这个类的正样本,统称为正样本,其他的不属于任何类的区域图像称之为负样本.

    第二部分: 训练CNN来抽取候选区域深度特征

    CNN采用了AlexNet的网络结构,模型使用Caffe来实现;AlexNet网络的结构如下图所示:中间层我们不关注,我们主要看它的输入和输出.输入是224*224大小的图像,提取到的特征是一个4096维度的特征向量,由于是1000类的分类任务,因此最后一层的节点数目为1000.

    OK,上面回顾了一下典型的AlexNet网络,现在我们看作者是如何借鉴这个网络的.首先是输入,本文的输入当然是第一部分里面提取到的候选区域,但是这些候选区域的大小都是不相同的,因此首先要把每个区域都resize到规定大小(224*224);对于每个区域提取的深度特征的维度依旧是4096维;最后一层的输出要根据任务的不同做出相应的改变,原本AlexNet中最后一层的1000的含义是1000类的分类任务,到了这里,如果是对VOC数据集,则要把最后一层的节点数目设置为20+1(20表示有20个待识别目标,1表示背景类);对ILSVRC2013来说,要设置为200+1.

    假如说对于VOC数据集,第一部分已经把训练数据集构造好了,共有21个类,每个类都有自己对应的样本区域,而且这些区域是类别独立的.然后就可以输入到改进版的AlexNet进行训练了,AlexNet的最后一层依旧是Softmax层,这个时候的训练可以看做有监督地训练一个21-way的图像分类网络.

    CNN网络的具体训练方法是:先用ILSCRC2012数据集对网络进行有监督预训练,然后使用第一部分里面提取的训练集进行微调;微调的时候采用SGD的方法,学习率设置为预训练时候的十分之一(具体为0.001),这样使得网络慢慢地收敛.mini-batch的大小为128(从第一部分保存下来的候选区域里,每次随机抽取32个正样本(在所有类别上),96个负样本(背景类)).

    第三部分: 训练集构造(用于训练多个SVM分类器)

    第一部分介绍了如何构造训练集来对预训练后的CNN进行微调,那里面与GT Boxes之间的IoU重叠程度大于0.5的都被标定为正样本.现在到了这一步,CNN已经训练完成了,我们现在要为每个类别(比如猫,狗,...)单独训练一个二分类SVM分类器,比如"SVM_猫"就是专门来检测猫这个目标,"SVM_狗"就是专门来检测狗这个目标,这时候对每个二分类SVM分类器如何构造它的训练集呢? 以猫这个目标为例,本文的做法就是以每张图像上猫这个目标的GT Boxes作为正样本,然后在图像上生成很多候选区域,考察每个区域与猫目标的GT boxes之间的IoU,如果IoU小于0.3,那么就认定这个区域为负样本,重叠度在0.3~1之间的不用做训练.可以想象,对于训练"SVM_猫"来说,正样本都是包含猫的区域,负样本有可能是背景,也有可能包含了其他目标,比如狗,但是无论怎么样,这个区域只要不包含猫,或者讲包含了一部分猫,但是重叠度小于0.3,都会被标记为负样本.

    第四部分: 为每个类训练一个binary SVM分类器

    假如有20个类,那么就要训练20个binary分类器,第三部分讲述了如何为每一个两分类SVM构造相应的训练集,训练集里面的正样本和负样本都要使用上面已经训练好的CNN来提取各自的4.96维度的特征向量,然后再对分类器进行训练.

    第五部分: 进行Bounding-box回归

    类似于第四部分中为每个类别训练一个二分类SVM,本文这里为每个类别构造一个Bounding-box回归器来提升检测的准确率.

    具体做法:假如下图中的绿色box用P来表示,P=(Px,Py,Pw,Ph),这四个值分别表示这个box的中心点横坐标,中心点纵坐标,box宽度以及box高度.红色框为目标的真实box,设为G,G=(Gx,Gy,Gw,Gh),每个元素的含义和P中相同,现在的目的就是想学习到一种变换,这个变换可以将P映射到G.

    如何对这个变换进行建模? 作者给出了一种变换关系如下图所示:

        

    训练回归器的时候,对于输入: 训练box的P=(Px,Py,Pw,Ph)肯定是要参与的,但是不仅仅是这个.前面我们训练得到了CNN,我们这里可以使用已经训练的CNN计算区域的pool5层的特征(即Φ5(P))来参与训练,w_{x,y,h,w}为待学习的回归器参数,因此,我们的问题变得很直接: 就是通过一定的方法把w_{x,y,h,w}求出来,就得到了回归器.思路讲清楚了,具体的求解过程见论文中所述.

    注意事项:我在想,就比如上面那个检测狼的那张图,真实的边缘box就一个,而候选的box却可能有很多,那么也就是说,对于这张图像上的样本,它们的输入虽然不一样,但是输出确实相同的,这合理吗?但是转念一想,训练的时候图像的数目是很多的,从这些图像上抽取的所有样本一起参与训练,一张图像上的影响可能并不那么大.文中提示我们需要注意的一点也在训练集的构造上面,如果P这个区域距离G太远的话,那么回归可能变得没有意义,一次构造训练集时候要选择哪些距离G比较近的候选区域,怎么考量这个近的程度呢? 当然还是使用IoU了,文章中选择那些与GTbox的IoU在0.6以上的区域来进行回归(0.6这个值使用交叉验证确定的),至于其他的候选区域,直接丢掉就是了. 

    2.2 本文模型测试过程

    测试过程基本上和训练的过程是相同的: 给定一张测试图像 --> 利用SS方法抽取大约2000个候选区域 --> 将每个区域都resize到224*224大小 --> 利用训练好的CNN得到每个区域的深度特征 --> 将每个区域对应的深度特征向量分别送到那几十个训练好的二分类SVM当中,输出每个区域属于每个类的概率(SVM软分类).假如类别数目N=20,就会得到一个2000*20的矩阵,每一行数据表示的是一个候选区域属于20个类的概率值.每一列表示所有的候选区域属于那一列类别的概率值(比如,一张图像上的2000个候选区域属于猫这个类别的概率). --> 对于每一类别(也就是每一列的数据)使用贪婪非最大值抑制的方法来对这些区域进行筛选. --> 对这2000个候选区域,用回归器预测bounding box.

    (问题1: 贪婪非最大值抑制这点还没有完全理解,具体是怎么进行的?)

    (问题2: 最后怎么得到最终结果的?)

    总结

    1. 上面的模型,即使把第三部分和第四部分去掉也能得到检测的结果,也就是说,直接运用CNN的softmax分类器就可以当做是一个目标检测器,那么为什么还要再构造训练集,再训练多个SVM分类器呢? 如果只是用CNN+Softmax来做目标检测器,那么这篇论文的思路就和<论文阅读笔记--Selective Search for Object Recognition>差不多了,就是把Selective Search算法里面的HOG+BOW特征换成了CNN特征,SVM分类器换成了Softmax,这样的话,这篇论文的创新性便不能体现!而且,据作者文中所说,如果只使用第一和第二部分的话,在VOC2007数据集上的表现将从54.2%下降到50.9%.

    每个模型都有自己的优点和缺点,这篇为人所道的缺点就是它需要训练多个SVM分类器,计算复杂度较高,这一点在那些只需要训练一个分类器的文章中经常能看到.

    2. Ross Girshick大神在RCNN改进版<Fast RCNN>里面对RCNN的几个缺点进行了阐述,只要包括:

    (1) RCNN的训练是一个multi-stage pipeline.这句话的意思是说RCNN的三个模块是一条流水线下来,而不是有机地结合在了一起;具体来说就是: RCNN首先利用object proposals样本,借助log loss(Softmax)来微调一个ConvNet --> 然后使用ConvNet的特征来训练多个二分类SVMs --> 最后再训练一个bounding-box回归器.

    (2) 训练在空间和时间上都耗费巨大.RCNN需要训练多个SVM分类器,也要训练多个回归器,训练所用的特征向量都是深度特征向量,维度是很高的,这些特征保存到硬盘上很占空间,而且训练比较耗时.

    (3) 测试的时候速度很慢. 测试的时候,先在图像上生成region proposal,然后提取每个proposal的深度特征,然后再分类,在GPU上测试是47s/image,达不到实时的要求.

    本博文不是对文章的逐字翻译,而是尽量对其思想进行理解,因此难免有一些误解或者不当之处, 敬请留言指教, 谢谢!

    参考文献:

    [1] 项目的MATLAB源码:https://github.com/rbgirshick/rcnn

  • 相关阅读:
    《活着》--余华
    《麦田里的守望者》--[美]杰罗姆·大卫·塞林格
    《平凡的世界》--路遥
    彩色照片转换为黑白照片(Color image converted to black and white picture)
    《戴尔·卡耐基传记》--[美]戴尔·卡耐基
    Maven的第一个小程序
    C# RabbitMQ优先级队列实战项目演练
    控制WinForm中Tab键的跳转
    C#模板引擎NVelocity实战项目演练
    C#隐藏手机号中间四位为*
  • 原文地址:https://www.cnblogs.com/zhao441354231/p/6094990.html
Copyright © 2011-2022 走看看