計算機視覺(四)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

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