Spatial Pyramid Pooling in Deep Convolutional Networks for Visual

来源:互联网 发布:mac 如何恢复默认dns 编辑:程序博客网 时间:2024/06/07 05:54

声明:本文所有图片均来自原始文章,自己的理解也未必正确,请查看原图并拍砖

 

本文的两个亮点:

 

1. 多尺度训练CNN。

 

2. 将图像分割后的特征转换为最小计算量,大大加速了detection的速度。

 

关于第一点:我们知道,卷积保留了图像的spatial信息,同时卷积层其实是不受输入图像大小的限制的,之所以在训练CNN时,需要固定图像尺寸,主要是由于全连接层的输入需要固定维度的。但是,如果在进全连接层之前的一层,我们把无论多大的图都转换到相同维度,这样前面其实是不限制图像大小的。SPP在这里就起到了这个作用。这样做一呢,解除了图像大小的限制,二呢,可以多尺度图像同时进行训练CNN。从作者的实验结果来看,确实是效果提升的。而在VGG的工作中,人为random选择输入图像尺寸进行变换,然后再裁图到224X224进行CNN训练,就提高了分类效果。SPP的这种做法是另外一种多尺度吧,和VGG的这种不是很一样其实,如下图所示,在用SPP的效果,以及用了SPP同时采用多尺度的分类效果,多尺度进行训练CNN效果要比之前提高不少。

Spp在cnn中的框架应用图,基本思路就是用spp代替CNN中最后一个pooling层。其实,用更直白的话理解就是,由一个pooling变成了多个scale的pooling了。这种多尺度的应用,必定会给分类带来好处的,这也是这个文章的一个亮点。如下图所示,只是在pooling的时候,需要注意一下,文章中说到的1X1,2X2,…不是pooling的窗口大小,而是pooling后的大小,即pooling后变成了1x1的一个bin,2X2的4个bins,等等,这个就是multi level的过程,而传统的滑动窗口的方式是single level的方式。于是,在pooling过程中,窗口的大小和步长的大小都需要去计算,这样也有个好处,就是进来的conv5的输出无论出来多大维度的信息,都可以将其pooling到同一个维度上。如下图所示,再把1X1,2X2,…等这些信息组合展开作为fc6的输入。


 至此,SPP在CNN中用于分类的效果可见一斑。比较一下,这部分工作还是很牛的,简单的几层CNN,只是多了一个spp ,分类效果提升了不少。对比当今的网络结构,他们只用了最原始的几层CNN,没有做深度加深,就提升了不少效果,速度快,训练起来也是很灵活的,即使你只有CPU也可以,单个GPU也可以,不用去搭建多机多卡什么的,效果就不错了。

上面是SPP在分类中的应用,那么在检测中怎么用呢?其实,很多人赞这篇文章,可能大多数是因为这个(窃以为啊)。我们知道,目前做物体检测的,或者说做视觉的,效果基本上被各种CNN刷新了。检测也是,是基于CNN的R-CNN,也就是region CNN,也是berkely那帮人搞的,原理其实也不算复杂,但是其实相当复杂的。R-CNN的图可以见下图,其流程就是先对一张图用图像分割,比如selective search, random prime, bing等方法分割成若干个小的regions,当然这些regions其实基本上是被视为是一个完整物体的regions,然后将这些regions作为CNN的输入,利用CNN提取这些regions的图像特征,当然是最后一层softmax去掉的,然后进SVM分类器,从而得到这些regions是哪一类,当然由于你已经得到regions了,因而你也能得到这些regions在原始图中的坐标,于是物体检测的任务就完成了。当然,说着是不算复杂,但是仔细分析,其中涉及到几个大模块:1. 分割,regions提取,这个有专门的研究吧,比如selective search, random prime, bing等等,效果下降趋势,当然速度上升趋势。2.Cnn的fine tuning或者训练,你需要用这些待检测或者与检测物体相关的图像做训练数据集,怎么选,这个也会决定其效果的。3. SVM模块,分类器SVM的训练,学问大大的奥。我是菜鸟,不多说了,看原始文章和代码吧https://github.com/rbgirshick/rcnn。


RCNN简直是划时代的出现,刷新了各种物体检测效果。但是,其有个最大问题就是计算量问题。你想啊,那么多regions都进CNN,而根据我们做图像分割的经验,这些regions之间肯定存在重叠的,所以计算量一下子多了太多。Ss的方式,400X500的图,大概有2000多个regions生成啊。

而SPP用在detection中,恰恰就避免了R-CNN重复计算的问题。

其实,之前我们也看过不少文章,比如regionlets等等(文章:Generic Object Detection With Dense Neural Patterns and Regionlets),但是这个方法效果并不是很好,原因是其用直方图的方式将最后卷积层出来的特征统一维度,这样做将CNN中具有spatial的特征全部抹掉了,而且直方图本身也将CNN的良好描述能力抹杀了不少啊。在看看regionlets的文章,我觉得可能有两个原因效果没那么好,一个是图的尺寸太小,另外一个原因是region是随机组合选取的,可能按照selective search等这种方式来选取region再做histogram,我感觉就是average pooling效果应该不错。当时看到regionlets这篇文章时,我们也想用别的组合方式,将最后一层的特征进行组合,但是没想到合适的,水平啊……

SPP用在CNN中用来做detection的框架图如下图所示:


其实,在这里也是要做图像分割的,但是,并不是要所有2000个regions都进CNN提取特征,而是一张原始图进CNN提取特征,这2000个regions不是有坐标吗?因此在conv5之后,也能知道对应的windows是哪里。然后,我们要对这些windows用上面介绍的SPP的方式,用多个尺度的pooling分别进fc层,然后是SVM,从而判断这些windows进而对应的regions是否是某一个目标。这样做能够节省大量计算量,因为在CNN中,其实卷积和pooling占据了80%左右的计算时间,而SPP只是放在最后一个pooling层了,因此,时间节省是大大的,根据作者文章说的,大概快了20-60倍啊。原来我们觉得可能这样以来,就可以工程应用了,但是目前来看,估计时间还是瓶颈,因为其实前面region分割的时间也不少,selective search大约要1s呢。


值得提到的一点是,在文中,作者用的图像大小最小是480的,猜测可能用过小尺寸,但是效果不好。想想也知道,如果用特别小的原始图像,经过一系列conv和pooling后,有些小的region可能会被干掉了。但是把原始图放大了,应该在最后还有保留的。具体原始图像中的坐标怎么和最后conv5出来的对应上,作者文章中给了附录,计算方式和另外一篇文章Generic Object Detection With Dense Neural Patterns and Regionlets中给出的类似,原理就是conv和pooling降维的尺寸一个一个计算。文章第二版的信息量很大,值得好好研读的,细节的东西不少,期待作者早点放出来代码。


代码:https://github.com/ShaoqingRen/SPP_net

 

PS.最近两周多,在自己机器上搭建caffewindows和spp_net,折腾人的很啊,最终还是搞定了。


测试了一下,个人普通台式机,CPU下,多尺度(5个尺度)的spp下,一张pascal的图大概要50s的时间,这个也是可以理解的,毕竟都要cnn卷积一遍,这个是很费时间的。单个尺度的话,10s一张图。实际测试下来,当图片输入是480时,典型的目标已经无法得到了。


另外,由于要求输入的图像可以是大图片的,而且一次性存了不少张,我怀疑我的GPU不够用,在申请空间时,GPU挂掉。CPU比GPU存储大,就没事。

由于之前的大部分CNN模型的输入图像都是固定大小的(大小,长宽比),比如NIPS2012的大小为224X224,而不同大小的输入图像需要通过crop或者warp来生成一个固定大小的图像输入到网络中。这样子就存在问题,1.尺度的选择具有主观性,对于不同的目标,其最适合的尺寸大小可能不一样,2.对于不同的尺寸大小的图像和长宽比的图像,强制变换到固定的大小会损失信息;3.crop的图像可能不包含完整的图像,warp的图像可能导致几何形变。所以说固定输入到网络的图像的大小可能会影响到他们的识别特别是检测的准确率;


而这篇文章中,提出了利用空间金字塔池化(spatial pyramid pooling
SPP)来实现对图像大小和不同长宽比的处理,这样产生的新的网络,叫做SPP-Net,可以不论图像的大小产生相同大小长度的表示特征;这样的网络用在分类和检测上面都刷新的记录;并且速度比较快,快30-170倍,因为之前的检测方法都是采用:1.滑动窗口(慢) 2.对可能的几个目标(显著性目标窗口,可能有几千个)的每一个都进行识别然后再选出最大值作为检测到的目标;

利用这种网络,我们只需要计算完整图像的特征图(
feature maps)一次,然后池化子窗口的特征,这样就产生了固定长度的表示,它可以用来训练检测器;

 

为什么CNN需要固定输入图像的大小,卷积部分不需要固定图像的大小(它的输出大小是跟输入图像的大小相关的),有固定输入图像大小需求的是全连接部分,由它们的定义我们可以知道,全连接部分的参数的个数是需要固定的。综上我们知道,固定大小这个限制只是发生在了网络的深层(高层)处。

 

文章利用了空间金字塔池化(spatial pyramidpooling(SPP))层来去除网络固定大小的限制,也就是说,将SPP层接到最后一个卷积层后面,SPP层池化特征并且产生固定大小的输出,它的输出然后再送到第一个全连接层。也就是说在卷积层和全连接层之前,我们导入了一个新的层,它可以接受不同大小的输入但是产生相同大小的输出;这样就可以避免在网络的输入口处就要求它们大小相同,也就实现了文章所说的可以接受任意输入尺度;
 

文章说这种形式更符合我们的大脑,我们的大脑总不会是说先对输入我们视觉的图像进行切割或者归一化同一尺寸再进行识别,而是采用先输入任意大小的图像,然后再后期进行处理。

 

SSP或者说是空间金字塔匹配(spatial pyramid matching or SPM)是BoW的一个扩展,它把一张图片划分为从不同的分辨率级别然后聚合这些不同分辨率的图像,在深度学习之前SPM取得了很大的成功,然是在深度学习CNN出现之后却很少被用到,SSP有一些很好的特征:1.它可以不论输入数据的大小而产生相同大小的输出,而卷积就不行 2.SPP使用多级别的空间块,也就是说它可以保留了很大一部分的分辨率无关性;3.SPP可以池化从不同尺度图像提取的特征。

 

对比于R-CNNR-CNN更耗时,因为它是通过对图像的不同区域(几千个,通过显著性)提取特征表示,而在这篇文章中,只需要运行卷积层一次(整幅图像,无论大小),然后利用SPP层来提取特征,它提取的特征长度是相同的,所以说它减少了卷积的次数,所以比R-CNN快了几十倍到一百多倍的速度;

池化层(
Poolinglayer)在滑动窗口的角度下,也可以看作为卷积层,卷积层的输出称之为featuremap,它表示了响应的强度和位置信息;

在利用
SPP层替换最后一个卷积层后面的池化层中,
 

在每一个空间块(bin)中,池化每一个滤波器的响应,所以SPP层的输出为256M维度,其中256是滤波器的个数,Mbin的个数(?)(很显然,M是根据不同的图像大小计算出来的),这样不同输入图像大小的输出就可以相同了。
对于给定的输入图像大小,我们可以先计算出它所需要的空间
bin块的多少,计算如下:
比如一张
224*224的图像,它输入到conv5的输出为a*a13*13),当需要n*n级别的金字塔时候,每个采样窗口为win=a/n】步长为【a/n】,当需要l个金字塔的时候,计算出l个这样的采样窗口和步长,然后将这些l个输出的bin连接起来作为第一个全连接层的输出;


0 0
原创粉丝点击