SPP-Net全名为《Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition》2014【深度卷积网络中用于视觉识别的空间金字塔池化】论文链接:https://arxiv.org/abs/1406.4729
SPP-Net(spatial pyramid pooling空间金字塔池化算法)是一种可以不用考虑图像大小,输出图像固定长度网络结构,并且可以做到在图像变形情况下表现稳定。SSP-net的效果已经在不同的数据集上面得到验证,速度上比R-CNN快24-102倍。在ImageNet 2014的比赛中,此方法检测中第二,分类中第三。受SPP-Net启发,2015年发表Fast R-CNN。
SPP-net的处理方式:不固定图像的大小,直接输入给卷积层处理,卷积出来的特征并不是直接输入给全连接层,而是在spatial pyramid pooling layer提取各个region proposal的特征(具体过程见下段),然后得到一个固定长度的输出传给全连接层,最后输出结果。 理论上说,SPP-net支持直接以多尺度的原始图片作为输入后直接BP训练即可。
SPP层如上图,位于最后一个卷积层(conv5)与全连接层之间。黑色图片代表卷积之后的256个特征图,256-d代表卷积层conv5的层数,接着我们以不同大小的块来提取特征,分别是4*4,2*2,1*1,将这三张网格放到下面这张特征图上,就可以得到16+4+1=21种不同的块(Spatial bins)。
我们从这21个块中,采用max pooling方法从每个块提取出一个特征,最终提取(16+4+1)*256=21*256=5376个神经元,即无论前面的feature map是多大的,经过spp layer处理之后得到固定大小的神经元,然后就可以和全连接层进行矩阵运算了。
SPP层代码
代码中存放的是spp layer中的目标输出大小,代码中bins=[1,2,3]。
import tensorflow as tf
import math
class SPPLayer():
def __init__(self,bins,feature_map_size):
self.strides = []
self.filters = []
# print(type(feature_map_size))
self.a = float(feature_map_size)
self.bins = bins
self.n = len(bins)
def spatial_pyramid_pooling(self,data):
self.input = data
self.batch_size = self.input.get_shape().as_list()[0]
for i in range(self.n):
x = int(math.floor(self.a/float(self.bins[i])))
self.strides.append(x)
x = int (math.ceil(self.a/float(self.bins[i])))
self.filters.append(x)
self.pooled_out = []
for i in range(self.n):
self.pooled_out.append(tf.nn.max_pool(self.input,
ksize=[1, self.filters[i], self.filters[i], 1],
strides=[1, self.strides[i], self.strides[i], 1],
padding='VALID'))
for i in range(self.n):
self.pooled_out[i] = tf.reshape(self.pooled_out[i], [self.batch_size, -1])
self.output = tf.concat(1, [self.pooled_out[0], self.pooled_out[1], self.pooled_out[2]])
return self.output
以224*224的输入为例:在conv5之后的特征图为:13x13(a*a),金字塔层bins:n*n,将pooling层作为slidingwindow pooling。windows_size=[a/n]向上取整 ,stride_size=[a/n]向下取整。
一个正常的深度网络由两部分组成,卷积部分和全连接部分,要求输入图像需要固定size的原因并不是卷积部分而是全连接部分。所以SPP层就作用在最后一层卷积之后,SPP层的输出就是固定大小。SPP-net不仅允许测试的时候输入不同大小的图片,训练的时候也允许输入不同大小的图片,通过不同尺度的图片同时可以防止overfit。相比于R-CNN提取2000个proposal,SPP-net只需要将整个图扔进去获取特征,这样操作速度提升了100倍左右。
参考:
百度百科:SPP-Net https://baike.baidu.com/item/SPP-Net/22701886
简书:SPP-net文章详细解读 https://www.jianshu.com/p/07a573035e43