Introduction
在一般的CNN结构中,在卷积层后面通常连接着全连接。而全连接层的特征数是固定的,所以在网络输入的时候,会固定输入的大小(fixed-size)。但在现实中,我们的输入的图像尺寸总是不能满足输入时要求的大小。然而通常的手法就是裁剪(crop)和拉伸(warp)。
这样做总是不好的:图像的纵横比(ratio aspect) 和 输入图像的尺寸是被改变的。这样就会扭曲原始的图像。而Kaiming He在这里提出了一个SPP(Spatial Pyramid Pooling)层能很好的解决这样的问题, 但SPP通常连接在最后一层卷基层。
CNN一般结构和SPP结构
SPP 显著特点
1) 不管输入尺寸是怎样,SPP 可以产生固定大小的输出
2) 使用多个窗口(pooling window)
3) SPP 可以使用同一图像不同尺寸(scale)作为输入, 得到同样长度的池化特征。
SPP其它特点
1) 由于对输入图像的不同纵横比和不同尺寸,SPP同样可以处理,所以提高了图像的尺度不变(scale-invariance)和降低了过拟合(over-fitting)
2) 实验表明训练图像尺寸的多样性比单一尺寸的训练图像更容易使得网络收敛(convergence)
3) SPP 对于特定的CNN网络设计和结构是独立的。(也就是说,只要把SPP放在最后一层卷积层后面,对网络的结构是没有影响的, 它只是替换了原来的pooling层)
4) 不仅可以用于图像分类而且可以用来目标检测
The Spatial Pyramid Pooling Layer
为什么会得固定大小的输出?
注意我们上面曾提到使用多个窗口(pooling窗口,上图中蓝色,青绿,银灰的窗口, 然后对feature maps 进行pooling,将分别得到的结果进行合并就会得到固定长度的输出), 这就是得到固定输出的秘密原因。
我们接下来用一个例子来弄懂这张图
Single-size network
我们先假定固定输入图像的尺寸, 而此网络卷积层最后输出256层feature-maps, 且每个feature-map大小为13×13(a=13),全连接层总共256×(9+4+1)个神经元, 即输全连接层输入大小为256×(9+4+1)。即我们需要在每个feature-map得到一个数目为(f=9+4+1)的特征。
由于pooling窗口(w×w)很明显如果我们用一个pooling窗口怎么也很难得到,再加上如果输入图像尺度变化的话,是根本不可能。
这里用了3个pooling窗口(w×w), 而对应的pooling stride 为t, 经多这3个窗口pooling池化得到3个n×n,n=3,2,1的结果。
饼画好了,怎么得到我们的窗口大小ww和stride tt呢?
w=⌈a/n⌉=⌈13/3⌉=5
t=⌊a/n⌋=⌊13/3⌋=4
n=2,n=1以此类推,将3个pooling后的结果合并,很容易发现和我们的期望一致。
举例:
输入层:一张任意大小的图片,假设其大小为(w,h)。
输出层:21个神经元。
也就是我们输入一张任意大小的特征图的时候,我们希望提取出21个特征。空间金字塔特征提取的过程如下:
图片尺度划分
如上图所示,当我们输入一张图片的时候,我们利用不同大小的刻度,对一张图片进行了划分。上面示意图中,利用了三种不同大小的刻度,对一张输入的图片进行了划分,最后总共可以得到16+4+1=21个块,我们即将从这21个块中,每个块提取出一个特征,这样刚好就是我们要提取的21维特征向量。
1) 第一张图片,我们把一张完整的图片,分成了16个块,也就是每个块的大小就是(w/4,h/4);
2) 第二张图片,划分了4个块,每个块的大小就是(w/2,h/2);
3) 第三张图片,把一整张图片作为了一个块,也就是块的大小为(w,h)
空间金字塔最大池化的过程,其实就是从这21个图片块中,分别计算每个块的最大值,从而得到一个输出神经元。最后把一张任意大小的图片转换成了一个固定大小的21维特征(当然你可以设计其它维数的输出,增加金字塔的层数,或者改变划分网格的大小)。
上面的三种不同刻度的划分,每一种刻度我们称之为:金字塔的一层,每一个图片块大小我们称之为:windows size了。如果你希望,金字塔的某一层输出n*n个特征,那么你就要用windows size大小为:(w/n,h/n)进行池化了。
当我们有很多层网络的时候,当网络输入的是一张任意大小的图片,这个时候我们可以一直进行卷积、池化,直到网络的倒数几层的时候,也就是我们即将与全连接层连接的时候,就要使用金字塔池化,使得任意大小的特征图都能够转换成固定大小的特征向量,这就是空间金字塔池化的奥义(多尺度特征提取出固定大小的特征向量)
参考链接: