本系列文章由 @yhl_leo 出品,转载请注明出处。
文章链接: http://blog.csdn.net/yhl_leo/article/details/51597496
在深度学习中有一类研究热点,目标检测,从2012年AlexNet到2016年,尤其是2015年开始,深度学习中的深层的卷积神经网络发展迅猛,其中不但衍生出了例如VGG, GoogleNet等越发区域标准化的深层网络,也相继提出一系列检测加速的策略,例如针对快速提取proposal的方法,像selective search, edge box, BING, RPN等,这些方法的发展和完善,使得基于深度学习的目标检测精度越来越高,而且速度越来越快,我整理了这一发展过程,对其中的部分方法进行讲解,准备有限,有不足或者疑问的地方请大家多多指教,其中一些参考文章和网站不在PPT中,但也对相关作者表示感谢。
我讲解的内容主要分为三部分概括为BBS,基于深度学习目标检测的背景,几个近几年的比较经典的卷积神经网络,以及最后的总结。
这里列举了几个经典的CNN网络,需要指出的是,这里除了AlexNet, GoogleNet, VGG外,其他都是可以进行目标检测的,但是作为经典,因此有必要在这里向它致敬,今天演讲的内容主要是这几个网络。14年之前,深度学习虽然也有不少人关注,但是成果相对较少,最重要的一个原因,我个人觉得就是入门门槛太高,除了一些牛逼的实验室和大神能玩得转外,其他人想搞都非常吃力,但是14年之后就是另一番景象,深度学习如同秋风扫落叶般,侵入了计算机视觉的各个领域,一些普通实验室和个人,也能迅速地开展相关的研究。
原因我觉得主要是两个:第一是显卡性能的提升和成本降低,2012年AleXNet训练的时候,引入了两块GTX 580,每块具有1.5G显存,显存频率2GHz,足足训练了五六天,在2014年市面上能见到的较好的显卡还是NVIDIA GTX 800系列,不管是显存大小还是显存频率都不够给力,而大家都知道深度学习后来被推崇的主要原因,就是其速度快,但是当年并不是这样,想要进行该领域的研究,需要更好的专业级显卡,硬件成本要求太高,这一条就将很多人拒之门外;2015年之后新推出GTX 900系列,TITAN 系列等,在计算能力上提升了很多个level,价钱也可以接受,960现在应该不超过2000块,TITAN X国内大概8000多,这里说的GPU主要指的是NVIDIA旗下的,在GPU加速运算这块AMD棋差一招,现在已经没法跟NVIDAI竞争。
而且NVIDIA现在也向学者免费提供显卡,显卡型号是TITAN X,我4月份的时候,向官方递交了申请书,5月初就收到了对方从新加坡寄来的显卡,还是很给力的,有兴趣的同学可以去尝试一下。
第二个原因就是相关的开发包的完善和成熟,例如2014年开源,影响力巨大的caffe深度学习框架,适宜NVIDIA GPU加速运算的开发包CUDA、CUDNN,以及其他编程开发环境对于深度学习的推进例如Python, Matlab和大家常用的开源库OpenCV,Google在caffe公布后,也耐不住寂寞,在2015年也公布了它的深度学习框架TensorFlow。
就目前来看,caffe框架支持C++,Python和Matlab环境,具有较大的用户群,现在开源的大部分工程都是基于caffe框架的,tensorflow主要支持Python环境,目前基于此进行研究的开源工程很少,这两个框架我都进行了研究,所以专门拿出来讲讲,个人建议如果是想要开始学习,直接学习caffe较好,相关的开源demo和文档更多,在GitHub和Stack overflow两大程序员网站上相关的讨论也较多,学习上手较快,还有其他的一些框架,就不再多讲。
现在进入主题,基于深度学习的目标检测问题,是这两年的热点问题之一,首先让我们来看三个概念,Recognition, Detection 和 Segmentation(略)。
就这三类数据,对常用的一些数据集,进行简单的罗列。
以上是三个常见的较大的数据集。
常见的评估方法,IoU, AP, mAP。
这里解释一下经常见到的评价指标,Top-1 / Top-5 error是什么意思。给定一个测试样本,以及正确的label,对模型预测样本属于各个label的概率值进行降序排列,如果预测所属类别可能性比较靠前的N个中没有正确的label,那就认为预测失败。相当于是对预测的要求降低要求,不求可能性最大的那种结果就是正确的,但是至少可能性较大的几种类别里,要含有正确的结果,下面给出的公式相当于是Top-1 error。
这是经典CNN网络AlexNet的结构,包括5层卷积层+3层全连接层,在文章里为了进行分类,还在最后一层全连接层后加了一层softmax层,在第1,2,5层卷积层后加了LRN层和Max Pooling层。这篇论文对于网络框架的一些实现细节,进行了很多论证工作,也是后来很多网络都以此为蓝本,进行新的拓展。
讲述几点作者的主张:不用simgoid和tanh作为激活函数,而用ReLU作为激活函数,原因是:加速收敛。因为sigmoid和tanh都是饱和(saturating)的。何为饱和?可能是他们的导数越接近目标,对应的导数越小,而ReLu的导数对于大于0的部分恒为1。于是ReLU确实可以在BP的时候能够将梯度很好地传到较前面的网络。
LRN操作可以提高网络的泛化能力,降低分类的错误率。论文里降低了2个百分点的错误率,其中,x,y是像素位置,求和含义是,把该位置上n几个临近的卷积核产生的feature map上的值加起来,N是这一层中所有的卷积核数量,K, alpha, beta是一组参数,取值一般都是固定的。
论文中对于pooling时,是否应该存在overlapping,进行讨论,所谓的overlapping就是指pooling窗口在移动的过程中跟前面的窗口要不要保持一定的重叠度,分析后作者认为保持一定的重叠度,可以一定程度上减弱过拟合问题和降低分类误差。
为了避免过拟合,使用了两种策略,一种是数据拓充(Data Augmentation),也使用了两种方法:第一种是随机Crop,训练的时候,将输入的256x256的图像,随机裁剪成为224x224+水平翻转拓展了2048倍,测试阶段,产生5x2个crop, 即便拓展了这么多,其实避免过拟合的程度也很有限,论文里错误率降低了一个百分点,训练关键还是原始数据要多。第二种是对RGB空间做PCA,即主成分分析,然后对主成分做一个轻微的高斯扰动,进一步降低错误率。
另外一种策略称为Dropout,深层网络经常具有大量的参数,虽然对于非线性问题具有较强的描述和学习能力,但是训练过程中过拟合也是很让人头疼的,有人提出将几个不同的网络的预测结果融合在一起,但是分别训练这样的网络代价很大,Dropout方法就解决了这个问题,在训练的过程中把部隐单元drop掉,如果训练过程中设置一组不同的drop组合,就可以在一次训练过程中得到几个不同的网络的叠加效果。
让我们来看,真正开始利用卷积神经网络进行目标检测的R-CNN,缩写的全称是Regions with CNN features, 我在前面讲述过,CNN并不能直接进行目标检测,只能进行识别或者分类,也就是说,给定一个图片或者图片区域,它只能回答你,里面是否含有某类目标的可能性,那怎么样才能进行目标检测呢?最简单的做法就是,我使用一个滑动窗口,把整幅图像都遍历一遍,找出所有类别评分比较高的区域,然后进行标记,但是这种做法,想一想就会发现很大的不足,首先自然场景里图片中目标的大小时不确定的,使用固定大小的滑动窗效果不行,但是搞出更复杂多变的滑动窗,计算量上一下就吃不消,如果能有一种有效的策略,提供较少量的可能存在待检测目标的区域,上面提到的问题就能很好的解决。利用CNN训练的特征对提取的目标候选区进行分类,这就是R-CNN的核心思想。
我们可以把R-CNN的结构分成独立的三块:定位使用的selective search,提取出2k个候选区,特征提取使用的是深层卷积神经网络CNN,文中是去掉最后一层softmax层的AlexNet,分类方法选择了L-SVM,对于每个类别使用NMS非最大抑制方法,舍弃掉部分region,得到检测结果。R-CNN的成功之处在于:a.使用CNN获取更高级别的目标特征取代了人工设计特征提取方法;b.使用类别独立的region proposal提取方法(Selective Search)减少了检测搜索的空间。它指出了一条使用深度学习进行目标检测的可行方案,其后的很多方法,基本都是参照这个流程,在各个子模块进行优化和改进。当然不足也很明显,提取proposal方法较慢(CPU, 2s/img);在检测时,对于提取的proposal全部warp到固定的size然后输入到CNN网络中并不是最佳方法(后来在Fast R-CNN中解决了这一问题)。
关于proposal提取方法,在相当长的一段时间里都是研究的热点,这里引用了15年的一篇论文,它对当时比较流行的一些方法(或者说是可以找到源码的方法)进行了分析和评价,它把这些方法大致分为两类,一种是Grouping,将图像过分割,然后再聚合在一起的,比如R-CNN使用的selective search,另一种是Window scoring 生成大量的窗口并打分,然后过滤掉低分的窗口,还有介于两者之间的例如multibox,这里没有列举;还有一些其他很好的方法,比如Faster R-CNN使用的RPN、HyperNet、YOLO方法等,因为在论文发表之后提出,所以没被列在内。
这是一张基于VOC07和ImageNet 的各种提取proposal方法能力的测试图,作者分析发现:(1)MCG, EdgeBox,SelectiveSearch, Rigor和Geodesic在不同proposal数目下表现都不错;(2)如果只限制小于1000的proposal,MCG,endres和CPMC效果最好;(3)如果一开始没有较好地定位好候选框的位置,随着IoU标准严格,recall会下降比较快的包括了Bing, Rahtu, Objectness和Edgeboxes。其中Bing下降尤为明显;(4)在AR这个标准下,MCG表现稳定;Endres和Edgeboxes在较少proposal时候表现比较好,当允许有较多的proposal时候,Rigor和SelectiveSearch的表现会比其他要好;(5)PASCAL和ImageNet上,各个OP方法都是比较相似的,这说明了这些OP方法的泛化性能都不错。
简单讲解一下Selective search的方法原理,前面已经说了它是一张基于Grouping的方法,首先对图像进行过分割,过分割后的区域块和相邻的区域块之间计算相似度,把相似度最高的两个合并,然后重复上面的过程,直到整幅图像被合并成为一个区域,迭代停止;因此它是一种由粗到细,具有一定层次的方法。
这是层次聚类的算法伪码,很容易理解。
为了使得聚类不单一化,也就是产生尽可能多样的候选区域,文章对于相似度进行了多种描述,颜色空间上进行了多种转换,同时区域的纹理、大小、填充孔洞,以及起始的区域等特征都会影响相似度。总得来说,这种方法还是很不错的,但是就是计算量有点大。
在SPP-net前,由于CNN网络结构的特点,全连接层需要固定长度的输出,因此普遍作法都是使输出图像的大小固定,由于所有图像卷积层操作都是一样的,就可以保证输入到全连接层的向量大小是相同的。有两种方法,第一种是Crop,从原图上按照一定方式裁剪出固定大小的图像,第二种是warp,就是把使用bounding-box标注的目标区域,拉伸成固定大小,这两种方式都具有一定弊端,那就是传入网络训练的图像与原始数据并不一致。
SPP-net的思路就是想要解决样本rescaling问题,提出直接使用任意尺度的图像输入网络进行训练,从而增加尺度不变性,减少过拟合问题。
如果原图输入是224x224,对于conv5出来后的输出,是13x13x256的,可以理解成有256个这样的filter,每个filter对应一张13x13的reponse map。如果像上图那样将reponse map分成4x4 2x2 1x1三张子图,做max pooling后,出来的特征就是固定长度的(16+4+1)x256那么多的维度了。如果原图的输入不是224x224,出来的特征依然是(16+4+1)x256;可以理解成将原来固定大小为(3x3)窗口的pool5改成了自适应窗口大小,窗口的大小和reponse map成比例,保证了经过pooling后出来的feature的长度是一致的。
与R-CNN类似,检测上仍然使用相同的方法,Selective search + SVM,但是做了一些优化,使得速度提升不少,虽然SPP-net提出这种对训练图像大小不做限制的思想,并没有被继续使用,但是spatial pyramid pooling layer的方法,在后来的Fast R-CNN, Faster R-CNN和HyperNet方法中得以延续:RoI Pooling layer,用以把region proposal对应区域的feature map转换成固定大小的feature map,然后输入到全连接层中。
再看卷积神经网络结构上的发展,有影响力比较大的两个深层卷积神经网络GoogleNet 和 VGG,这两个网络结构在ILSVRC 2014年分类挑战赛上分别获得了第一名和第二名的好成绩。这是两篇论文里分别对网络精度的描述。
先看GoogleNet,论文提出了两种基本模式,首先是简单模式,3个使用不同大小卷积核的卷积层和一个pooling层,在一层里,依次分别进行,然后使用concat层把输出连接在一起,另外一个模式是在其中两个卷积层之前和pooling层之后,添加具有更小卷积核的卷积层,然后再用concat层进行连接。
这是整体网络结构的基本框架,这里每个inceptiond都是一个基础模型b,加起来一共有22层深,如果把5个pooling层也算进来,就有27层深(表格中所有的inception都是前面基础模型中的b结构,深度为2)。
这是具体的网络结构图,因为太长了,我把它转成水平。作者总结认为,这种网络结构,相比于较浅的、较窄的网络结构,虽然增加了部分计算量,但是却能取得明显的效果增益。在实际测试中,效果确实也要比传统的网络效果更好。
这是VGG的网络框架,从A到E一共6种,网络深度从11层到19层不等,论文也对卷积核大小进行了探讨,感兴趣的可以阅读原文。相对于这就是2014年之前基于深度学习进行目标检测的主要成果,当然还很多关于数据预处理,检测proposal提取方法,网络结构优化的尝试等没有在上文描述中出现,但是我觉得前面讲述的几个方法在当时已经算是集大成者,各方面性能表现都很惊艳,比传统的机器学习方法优越不少。
现在来讲2015年之后的该领域的一些发展,首先是Fast R-CNN。在R-CNN和SPP-net之后,作者分析他们存在以下三个不足:第一:训练的时候,提取proposal、CNN特征提取,SVM分类,和bbox 回归是分开隔离的,而Fast R-CNN实现了端到端的联合训练(提取proposal除外),这种思路在以后的检测方法中延续;第二,训练时间和内存开销大,R-CNN提取特征给SVM训练时候需要中间要大量的磁盘空间存放特征,Fast R-CNN去掉了SVM这一步,所有的特征都暂存在显存中,不需要额外的磁盘空间;第三,检测速度慢,在测试的时候,需要把提取的proposal(前面提到是2k个)都输入到网络中提取特征,作者测试,如果使用VGG16网络,一张图像在GPU模式下消耗的时间是47s。我们看一下Fast R-CNN的网络结果,输入一张图像和多个proposals,论文里也称为RoI, 经过卷积网络得到feature map,再把这些feature map输入到RoI pooling layer池化成一个固定大小的feature map, 经过全连接层后展开为一个特征向量,然后将特征向量同时应用于softmax和bbox regressor,前者是用于类别概率估计,后者用于对bounding box的位置进行回归。在提取过量proposal的时候,实际中,这些proposal多数都是相互重叠的,因此按照R-CNN的做法,把这些相互重叠的proposal依次输入到网络中打分,就会导致一个很严重的问题,那些重叠部分会被反复计算feature(使用的是同一个网络,就相当于把一张图不同部分反复算了很多遍),这样的计算浪费是很没有必要的,而Fast R-CNN避免了这个问题,它对一张图像只计算一次卷积feature map,而对于proposal对应的图像区域,它把他们在卷积feature map上对应的区域分别取出,通过RoI pooling layer 生成固定大小的feature map,然后进行后面的分类以及bbox回归。这点改变是它速度提升的重要原因之一。
介绍一下RoI pooling layer,前面讲述单层的SPP layer将这个卷积输出的ROI对应的feature map下采样为大小固定的feature map再传入全连接层,方法也很简单,在前面讲述SPP-net的时候,已经讲过为了能够输入任意尺度的图像,在卷积层输出的最后,添加空间金字塔池化层,使输出的特征向量具有固定的大小,这里也是同样的道理,只不过是为了使不同size的RoI区域能够输出统一,方便后面的分类以及bbox 回归。Fast R-CNN只是用了一层spp layer 得到固定大小的feature map,论文里设置的是7x7,为什么不使用更多层,主要是出于两方面的考虑:一个是会增加计算量,降低速度,另一个就是因为在训练时,作者使用了ImageNet预训练结果进行网络参数的初始化,如果把这里的池化层拓展为多个spp layer那些模型的参数就没办法直接使用,就必须重新训练。
关于尺度不变性,论文里引用了SPP-net的方法,brute force, 也就是简单认为object不需要预先resize到类似的scale再传入网络,直接将image定死为某种scale,直接输入网络来训练就好了,然后期望网络自己能够学习到scale-invariance的表达。image pyramids (multi scale),也就是要生成一个金字塔,然后对于object,在金字塔上找到一个大小比较接近227x227的投影版本,然后用这个版本去训练网络。凭感觉可以看出,方法2应该比方法1更加好,作者也在讨论了,方法2的表现确实比方法1好,但是好的不算太多,大概比方法高1个mAP左右,但是时间要慢不少,所以作者实际采用的是第一个策略,也就是single scale。这里,Fast R-CNN测试之所以比SPP-net快,很大原因是因为这里,因为SPP-net用了方法2,而Fast R-CNN用了方法1。
作者分析,在整张图像分类过程中,在计算全连接层上计算花费的时间要比卷积层少,但是对于目标检测来说却是相反的,因为要处理的RoI数量比较多,像图上显示的在forward pass过程程中,fc6和fc7占了44.9%的时间,因此作者提出通过利用SVD分解的方法,将大规模的全连接矩阵缩减到很小的数据量,论文里讲述,将fc6 25088x4096的矩阵压缩为1024个奇异值,fc7 4096x4096 压缩为256个奇异值,虽然在精度上下降了0.3%,但是速度上却提升了30%。
Fast R-CNN 将R-CNN用于分类的分类器,从SVM换成了softmax,但是这两者到底哪一个究竟更好,作者也进行了探讨,这是一组对比试验,其中S,M,L分别都是网络模型,S指的就是AlexNet,M指的是VGG_CNN_M_1024,L指的是VGG16网络深度依次增加,可以看出使用softmax的结果比SVM都要好一些,而且作者指出,在ROI打分的时候,softmax会提供各个类别的score,而svm提供的是one-vs-rest,前者对于分类来说可能更有利。
这是一个R-CNN, SPP-net,Fast R-CNN的速度对比表,可以看出速度提升的还是很明显的。论文就很多其他细节也都进行了讨论,例如网络更新是否应该全部更新还是部分更新问题,数据量的问题等,这里就不做介绍了。
再来看2015年另外一篇论文,Faster R-CNN。 在Fast R-CNN之后,一些研究者也逐渐意识到,提取proposal成为了提升目标检测速度和精度的瓶颈,R-CNN,SPP-net和Fast R-CNN提取proposal的方法都还依赖于selective search。在提取proposal是在CPU中进行的,单幅影像耗时差不多2s,即便经过Fast R-CNN的优化加速后,想要做到视频实时处理,速度仍然还不够。于是Faster R-CNN就提出来,应该把提取proposal也交给CNN来做。在Fast R-CNN中,目标检测是在卷积feature map上基于区域进行的,那是不是也可以直接从卷积feature map上产生proposal呢?答案是肯定的。这就是Faster R-CNN的核心思想:RPN提取proposal+Fast R-CNN分类。图中显示的就是RPN的示意图,其中conv feature map就是卷积层最后输出的feature map,使用滑动窗口,这里给出的3x3的滑动窗口,把其中的高维特征展开降维成256维的低维向量,把得到的特征向量分别输入到两个并列的层里,一个box-regression layer(reg)和一个box-classification layer(cls)。
在RPN网络中,滑动窗口中心所在位置,我们成为sliding position, 在每个sliding position会按照一定的规则产生一系列的box,这些相关的box就被成为anchors,论文里指出每个sliding position 会按照3个不同的尺度,产生3个不同长宽比(1:1, 1:2, 2:1)一共9个anchors, 假设一幅feature map大小是WxH,那么它所产生的anchors数量就是:WHk,在数据处理的时候,作者把图像都rescale 到1000x600大小,得到的卷积feature map为60x40,所以每张图可以产生anchors 有60x40x9约为20k个,这是远远过量的,而且速度很快,通过对IoU进行非最大抑制后,余下2k的anchors投入训练,在检测的时候,这个数目还好降得更低,减为了300个。
速度和精度上的提升效果都比较显著。
这是HyperNet的网络结构。经历了Fast R-CNN和Faster R-CNN后,人们开始重新审视这些算法的检测结果,不难发现,由于深层卷积网络的使用,使得人们能够通过卷积和池化快速得到proposal windows对应的高维特征,但是最后卷积层输出的feature map都是非常粗糙的(feature map上很小的区域,对应到原图上就具有很大的感受野),这就很容易导致定位不准确的问题,当面临检测小物体时,这种弊端就更加突显,往往得到的bbox与ground truth偏差较多。这是HyperNet的考虑,作者觉得有必要提出一种策略降低这种因为conv feature map的过于粗糙而产生的定位偏差,而解决方法就是,既然顶层的conv层缩水太厉害,那就把它在扩大,也就是这里使用的Deconv 对高层特征进行上采样,同时还联合浅层的conv来增加网络判别和定位的能力,从而得到更加精细化的定位。这就是HyperNet的核心思想。
与Fast R-CNN,Faster R-CNN一样在训练时都将训练数据rescale成为1000x600或600x1000。不同卷积层上的feature map融合时,由于具有不同的分辨率,需要统一到相同size,因此对于浅层feature map通过pooling降采样,对于深层feature map通过去卷积化Deconv进行上采样,然后通过LRN操作进行数据归一化,之后通过concat层把数据联接在一起。作者分析这样做的优势有三点:a.多尺度的特征描述; b.得到的feature map大小对于目标检测更为合适(合成的Hyper feature map 大小是250x150,而Faster R-CNN为60x40); c.计算更加高效,没有冗余计算,所有的feature都已经在生成proposal和检测之前完成,之后不需要再进行特征提取。关于proposal提取方法(参考的论文就是Faster R-CNN作者提出的,感觉跟RPN很像,但是效果要好一些)。
加速策略(略)。
速度上比Fast R-CNN快了不少,跟Faster R-CNN差不多,但是精度上比前两者都更高。
还有一些很好的其他算法,这里没有列举出来,但是从这些列出的算法中,可以看出一些内容:
1.目标检测在融入了深度学习后,发展迅速,尤其是近几年,检测的速度不断加快,精度也在不断提高;
2.整体目标虽然是快速高效地完成检测,但研究的热点内容逐渐从如何更好地构建深层神经网络,转变到快速高效地提取proposal,再到如何更准确地定位和实时处理问题;
3.基本的卷积神经网络结构已经在2014年左右奠定了基本格局,由基本网络例如AlexNet, VGG,GoogLeNet等衍生出的检测网络比比皆是;
4.提取proposal的方法,始终都是提高检测速度的关键,逐渐从利用原图信息提取proposal,转变为利用conv feature map提取的方式,例如RPN,HyperNet等;
5.训练测试的pipeline,从特征提取,定位和分类独立进行,转变为全都在神经网络里完成的end-to-end模式;
6.仍然有较大的提升空间,从各种检测方法的评估来看,mAP精度还有不小的提升空间(目前还停留在80%以下),而想要实现实时处理(如YOLO),就要以牺牲精度为代价。