空间金字塔池化SPP改进RCNN的重要思想

本文的背景是论文《Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition》,是对RCNN的region proposal要进行大量繁杂计算的重要改进。

空间金字塔池化SPP改进RCNN的重要思想_第1张图片

 

一、R-CNN中region proposal的缺陷

R-CNN的候选框是通过selective search方法得到的,一张图片大概有2k左右个region proposals,然后通过crop/warp进行处理,将每个region proposal送入CNN中进行卷积特征的提取。

R-CNN中,要求输入固定大小的图片,这些图片经过裁切(Crop)或者经过变形缩放(Warp),都在一定程度上导致图片信息的丢失和变形,限制了识别精确度。两种方式如下所示。

空间金字塔池化SPP改进RCNN的重要思想_第2张图片

 

无论是crop还是warp,都无法保证不失真:

- crop:物体可能会被截断,尤其是长宽比大的图片

- warp:物体被拉伸,失去"原形",尤其是长宽比大的图片

这两方面的事实导致以下两个缺陷:

  • 训练时间非常慢,因为一张图片产生2k左右的region proposals,都会进入CNN中进行训练;
  • 识别准确率很低,因为产生的region proposals都会通过crop/warp操作,resize到同一大小送入CNN中进行训练,这样会造成图片信息的缺失或者变形失真,会降低图片识别的正确率。

二、SPP空间金字塔池化的重要思想

本文提出了空间金字塔池化Spatial Pyramid Pooling layer) 来解决这一问题,使用这种方式,可以让网络输入任意的图片,而且还会生成固定大小的输出。这样,整体的结构和之前R-CNN有所不同。

对于第一个问题,我们能不能将一张图片整体送入CNN中进行特征提取,然后将一张图片的多个region proposals映射到最后的特征层上,形成每个region proposal的feature maps,进而加速特征的提取;

对于第二个问题,我们能不能不resize,直接用不同大小的region proposals的feature maps?

实际上,卷积层是不需要输入固定大小的图片的,并且还可以生成任意大小的特征图,只是全连接层需要固定大小的输入。因此,固定长度的约束仅限于全连接层。

分析如下:

CNN大体包含3部分,卷积、池化、全连接。

卷积:卷积操作对图片输入的大小会有要求吗?比如一个5*5的卷积核,输入的图片是30*81的大小,可以得到(26,77)大小的图片,并不会影响卷积操作。输入600*500,它还是照样可以进行卷积,也就是卷积对图片输入大小没有要求。任意大小的图片进入,都可以进行卷积。

池化:池化对图片大小会有要求吗?比如我池化大小为(2,2)我输入一张30*40的,那么经过池化后可以得到15*20的图片。输入一张53*22大小的图片,经过池化后,我可以得到26*11大小的图片。因此池化这一步也没对图片大小有要求。输入任意大小的图片,都可以进行池化。

全连接层:既然池化和卷积都对输入图片大小没有要求,那么就只有全连接层对图片结果有要求了。因为全连接层连接权值矩阵的大小W,经过网络训练后,大小就固定了。比如我们从卷积到全连层,输入和输出的大小,分别是50、30,那么权值矩阵50×30大小的矩阵了。因此空间金字塔池化,要解决的就是从卷积层到全连接层之间的一个过度。

也就是说,在最后一个卷积层与第一个全连接层(fc)之间需要训练一个大小固定的二维数组,这样可以得到的特征更完整一些,提高了定位与识别的准确率。如下图所求:

空间金字塔池化SPP改进RCNN的重要思想_第3张图片

 

三、SPP的具体实现过程

SPP为的就是解决上述的问题,做到的效果为:不管输入的图片是什么尺度,都能够正确的传入网络.

空间金字塔池化SPP改进RCNN的重要思想_第4张图片

 

具体方案如下图所示:

不管最后一个卷积层得到的特征图(feature maps)的大小,都可将其转化为了(4*4+2*2+1*1)*256的全连接层,也就是这些特征图的大小不同,但通道是相同的,那么如何将不同大小的特征图进行spp 呢?

假设输入的大小为a*a*c,然后呢,这些特征图分别被分成了[1*1,2*2,4*4]大小的块,期望的输出为1*1*c,2*2*c,4*4*c,变形为(1*1+2*2+4*4)*c的二维数组,这全部是通过池化操作实现的,不过池化层的size和stride是不同的,具体有如下:

输入为[a,a],输出为[n,n],那么pool_size= n/a ⌉ ,stride=⌊ n/a⌋ ,这样我们就将其转化为了n*n*c的矩阵,例如13*13、10*10要转化为4*4的大小,那么采用[p_s=4,,s=3],[p_s=3,s=2]的池化操作后便可以得到。

如果原图输入是227x227,对于conv5出来后的输出,是13x13x256的,可以理解成有256个这样的filter,每个filter对应一张13x13的激活图。

如果像上图那样将激活图池化成4x4 2x2 1x1三张子图,做max pooling后,出来的特征就是固定长度的(16+4+1)x256那么多的维度了.如果原图的输入不是227x227,出来的特征依然是(16+4+1)x256;直觉地说,可以理解成将原来固定大小为(3x3)窗口的pool5改成了自适应窗口大小,窗口的大小和激活成比例,保证了经过pooling后出来的feature的长度是一致的.

如果要金字塔的某一层输出n x n个特征,只需要用窗口大小为:(w/n,h/n)进行池化即可。

当我们有很多层网络的时候,网络输入的是一张任意大小的图片,这个时候我们可以一直进行卷积、池化,直到即将与全连接层连接的时候,就要使用金字塔池化,使得任意大小的特征图都能够转换成固定大小的特征向量,这就是空间金字塔池化的奥妙之处!

你可能感兴趣的:(卷积神经网络CNN,循环神经网络RNN,LSTM,GRU等)