tensorflow的金字塔池化SPP_pool_layer:代码实现

空间金字塔池化

空间金字塔池化,使得任意大小的特征图都能够转换成固定大小的特征向量,这就是空间金字塔池化的意义(多尺度特征提取出固定大小的特征向量),送入全连接层。


tensorflow的金字塔池化SPP_pool_layer:代码实现_第1张图片
tensorflow的金字塔池化SPP_pool_layer:代码实现_第2张图片

首先是输入层(input image),其大小可以是任意的
进行卷积运算,到最后一个卷积层(图中是(conv_5))输出得到该层的特征映射(feature maps),其大小也是任意的
下面进入SPP层
我们先看最左边有16个蓝色小格子的图,它的意思是将从(conv_5)得到的特征映射分成16份,另外16X256中的256表示的是channel,即SPP对每一层都分成16份(不一定是等比分,原因看后面的内容就能理解了)。
中间的4个绿色小格子和右边1个紫色大格子也同理,即将特征映射分别分成4X256和1X256份
那么将特征映射分成若干等分是做什么用的呢? 我们看SPP的名字就是到了,是做池化操作,一般选择MAX Pooling,即对每一份进行最大池化。

我们看上图,通过SPP层,特征映射被转化成了16X256+4X256+1X256 = 21X256的矩阵,在送入全连接时可以扩展成一维矩阵,即1X10752,所以第一个全连接层的参数就可以设置成10752了,这样也就解决了输入数据大小任意的问题了。

注意上面划分成多少份是可以自己是情况设置的,例如我们也可以设置成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论文详解

你可能感兴趣的:(tensorflow的金字塔池化SPP_pool_layer:代码实现)