spatial pyramid pooling
空间金字塔池化,何凯明的文章。用于解决一个很简单且现实的问题,因为R-CNN网络或者其他的网络,最终需要统一图片的尺寸以及大小,然后继续送入后续的网络中。一般来说,为了得到固定尺寸的图片,有两种做法:1) croping裁剪;2) warping变形。
从上图不难看出,这两种方式都会对原图像产生破坏,具体来说:
- crop 的区域可能没办法包含物体的整体;
- warp操作可能会对目标造成无用的几何失真。
即对于多尺度问题,提前设定好的尺寸大小是不利的。
首先看一下传统的CNN网络为什么需要固定输入图像,一个墨守成规的CNN设计如下图所示:
对其进行解构,即其可以视作两部分:
- convolutional layers
- Fully-connected layers
其实对于卷积层来说,其并没有对输入图片的尺寸有要求,通过滑动窗口的形式如果尺度发生变化依然可以运行,所以使得最终对输入图片的尺寸有着严格要求的原因是FC层的存在。假设输入图片的尺寸不同,那么经过卷积层输出的特征图的尺寸也不同,对于将feature map展开形成的feature vector 来说也不同,输入尺寸的不同直接导致FC层无法正常工作。所以要输入到一个预定义好的全连接层,那么就需要固定输入的尺寸。
使用了spp的网络结构如下,一般来说都是在最后一层的卷积层后添加spp模块,我个人倾向于将本论文工作视作一个trick,yolov3中的spp同该部分是有关系,完成局部特征和全局特征的融合。
作者将这种采用了spp的网络命名为 spp-net,spp layer将最后一层卷积层输出的feature map拉成固定的feature vector,然后将该特征向量输入到FC层中。有两个主要优点“
- 解决proposal region不同尺寸的问题;
- 先计算出 feature map,在表示每个提议区域时候特征图的结果可以共享,节约计算时间。(对于那个时代背景,这一点是毋庸置疑的创新,极大地加快了运算速度)。
原理
原理如上图所示,首先经过卷积运算将最后的卷积层输出的feature map通过spp,具体如下:
- spp将特征图分成三个不同的等级,分别将特征图切分为(4*4)、(2*2)以及(1*1)
- 对每个小格子做max pooling,最终既可以得到(16+4+1)*256固定长度的feature vector
- 这样就可以固定第一个FC层的参数,解决了输入数据大小不同的问题,注意,划分多少块是超参数可自己定义的
上述为spp的运算实例,具体怎么划分见下:
池化后的特征图大小计算公式:
- stride = 1 : ( h + 2 p − f + 1 ) × ( w + 2 p − f + 1 ) (h +2p-f+1) \times (w+2p-f+1) (h+2p−f+1)×(w+2p−f+1)
- stride != 1 : ⌊ h + 2 p − f s + 1 ⌋ × ⌊ w + 2 p − f s + 1 ⌋ \lfloor \frac{h+2p-f}{s}+1\rfloor \times \lfloor\frac{w+2p-f}{s}+1\rfloor ⌊sh+2p−f+1⌋×⌊sw+2p−f+1⌋
那么就有,
- 假设输入数据的尺寸为 ( C , H , W ) (C,H,W) (C,H,W),池化后大小为 ( n , n ) (n , n) (n,n)
则:
- Kernel 尺寸: ⌈ h i n n , w i n n ⌉