计算机视觉(四)SPP-Net

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-CNN24-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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章