tensorflow的金字塔池化SPP_pool_layer:代碼實現(xiàn)

空間金字塔池化

空間金字塔池化,使得任意大小的特征圖都能夠轉(zhuǎn)換成固定大小的特征向量,這就是空間金字塔池化的意義(多尺度特征提取出固定大小的特征向量),送入全連接層。


首先是輸入層(input image),其大小可以是任意的
進行卷積運算,到最后一個卷積層(圖中是(conv_5))輸出得到該層的特征映射(feature maps),其大小也是任意的
下面進入SPP層
我們先看最左邊有16個藍色小格子的圖,它的意思是將從(conv_5)得到的特征映射分成16份,另外16X256中的256表示的是channel,即SPP對每一層都分成16份(不一定是等比分,原因看后面的內(nèi)容就能理解了)。
中間的4個綠色小格子和右邊1個紫色大格子也同理,即將特征映射分別分成4X256和1X256份
那么將特征映射分成若干等分是做什么用的呢? 我們看SPP的名字就是到了,是做池化操作,一般選擇MAX Pooling,即對每一份進行最大池化。

我們看上圖,通過SPP層,特征映射被轉(zhuǎn)化成了16X256+4X256+1X256 = 21X256的矩陣,在送入全連接時可以擴展成一維矩陣,即1X10752,所以第一個全連接層的參數(shù)就可以設(shè)置成10752了,這樣也就解決了輸入數(shù)據(jù)大小任意的問題了。

注意上面劃分成多少份是可以自己是情況設(shè)置的,例如我們也可以設(shè)置成3X3等,但一般建議還是按照論文中說的的進行劃分。

# -*- coding: utf-8 -*-
"""
Created on Thu Sep 20 18:13:52 2018

@author: yanghe
"""

import tensorflow as tf
import numpy as np
import pandas as pd

def spp_layer(input_, levels=4, name = 'SPP_layer',pool_type = 'max_pool'):

    '''
    Multiple Level SPP layer.
    
    Works for levels=[1, 2, 3, 6].
    '''
    
    shape = input_.get_shape().as_list()
    
    with tf.variable_scope(name):

        for l in range(levels):
        
            l = l + 1
            ksize = [1, np.ceil(shape[1]/ l + 1).astype(np.int32), np.ceil(shape[2] / l + 1).astype(np.int32), 1]
            
            strides = [1, np.floor(shape[1] / l + 1).astype(np.int32), np.floor(shape[2] / l + 1).astype(np.int32), 1]
            
            if pool_type == 'max_pool':
                pool = tf.nn.max_pool(input_, ksize=ksize, strides=strides, padding='SAME')
                pool = tf.reshape(pool,(shape[0],-1),)
                
            else :
                pool = tf.nn.avg_pool(input_, ksize=ksize, strides=strides, padding='SAME')
                pool = tf.reshape(pool,(shape[0],-1))
            print("Pool Level {:}: shape {:}".format(l, pool.get_shape().as_list()))
            if l == 1:

                x_flatten = tf.reshape(pool,(shape[0],-1))
            else:
                x_flatten = tf.concat((x_flatten,pool),axis=1)
            print("Pool Level {:}: shape {:}".format(l, x_flatten.get_shape().as_list()))
            # pool_outputs.append(tf.reshape(pool, [tf.shape(pool)[1], -1]))
            

    return x_flatten


#x  = tf.ones((4,16,16,3))
#x_sppl = spp_layer(x,4)


參考:

SPP-Net論文詳解

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容