原文地址:Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition
SppNet的贡献主要有两个:
以上就是SPP和传统的CNN的区别。传统的CNN需要对图像就行截取或者填充,会导致信息丢失或者图像形变。街区可能会导致没有包含到整个物体,而填充会导致不希望看到的几何形变。然而对于CNN而言,其实卷积层是不需要进行固定大小的输入的,只是到了后来的全连阶层,如果大小不固定,甚至连全连接层的参数个数都没法确定。
SPPNet通过可视化Conv5层特征,发现卷积特征其实保存了空间位置信息(数学推理中更容易发现这点),并且每一个卷积核负责提取不同的特征,比如C图175、55卷积核的特征,其中175负责提取窗口特征,55负责提取圆形的类似于车轮的特征。我们可以通过传统的方法聚集这些特征,例如词袋模型或是空间金字塔的方法。
SPP的处理过程时,输入时不对图像进行任何处理,到了最后一个卷积层的后面,将所有得到的feature map处理到相同大小。类似于pooling窗口的尺寸及步伐设置为相对值,也就是输出尺寸的一个比例值,这样对于任意输入经过这层后都能得到一个固定的输出。具体做法是:
如果使用三层的金字塔池化层pooling,分别设置图片切分成多少块,论文中设置的分别是(1,4,16),然后按照层次对这个特征图feature A进行分别处理(用代码实现就是for(1,2,3层))。
然后将这 (1+4+16)×256=21×256 ( 1 + 4 + 16 ) × 256 = 21 × 256 个特征输入到全连接层,进行权重计算. 当然了,这个层数是可以随意设定的,以及这个图片划分也是可以随意的,只要效果好同时最后能组合成我们需要的特征个数即可。
作者分别进行了单尺度训练,多尺度训练法。对于每个feature map,如果有 l l 层。则我们进行window pooling时,分别设置窗口大小为: win=[a/n] w i n = [ a / n ] , 滑窗大小: str=[a/n] s t r = [ a / n ] ,其中 [a/n] [ a / n ] 分别为向上向下取整。 n n 为pyramid中bin的大小,例如文中作者分别试用了 1×1,2×2,4×4 1 × 1 , 2 × 2 , 4 × 4 的bin。
除此之外,作者分别尝试了多尺度训练。这样的好处是,先在一个尺度上训练好模型之后,然后使用另外一个尺度继续对模型进行调整。此外,还有多层次的金字塔来训练。
在Object Detection中, 由于每张图片都会提取出2K+的Region, 每个Region的大小都不一样。一来需要进行缩放, 二来需要对每个框都进行一次卷积运算。而其实每个框之间有很多的信息都是相同的。存在着很多重复计算的过程。(这里不考虑crop, 因为crop本质上是一个数据增强的过程,如果数据量不够的话还是应该进行crop操作)。
因此作者采用的方法是,只训练一张图片,但是最后提取Region Proposal在feature map上对应的区域即可。Region Proposal提取左上角和右下角的坐标,然后构建相应的映射函数即可。因为原图片中的像素点最后被弄到了feature map中的哪个位置是固定的。具体的映射函数为:
假设每一层的 padding p a d d i n g 都是 p2 p 2 , p p 为卷积核大小。从第一个卷积层到最后一个卷积层,包括中间的池化层,计算各个层 stride s t r i d e 的乘积 s s ; (x′,y′) ( x ′ , y ′ ) 表示特征图上的坐标点, (x,y) ( x , y ) 表示原输入图片上的坐标点,那么每个矩形候选框的左上角、右下角在特征图上的对应点:
左上角: