• CNN之池化层tf.nn.max_pool | tf.nn.avg_pool | tf.reduce_mean | padding的规则解释


    摘要:池化层的主要目的是降维,通过滤波器映射区域内取最大值、平均值等操作。

    均值池化:tf.nn.avg_pool(input,ksize,strides,padding)

    最大池化:tf.nn.max_pool(input,ksize,strides,padding)

    input:通常情况下是卷积层输出的featuremap,shape=[batch,height,width,channels]

                    

      假定这个矩阵就是卷积层输出的featuremap(2通道输出)  他的shape=[1,4,4,2]

    ksize:池化窗口大小    shape=[batch,height,width,channels]    比如[1,2,2,1]

    strides: 窗口在每一个维度上的移动步长 shape=[batch,stride,stride,channel]  比如[1,2,2,1]

    padding:“VALID”不填充  “SAME”填充0

    返回:tensor        shape=[batch,height,width,channels]

    上图是采用的最大池化,取红色框内最大的一个数。

    import tensorflow as tf
    feature_map = tf.constant([
        [[0.0,4.0],[0.0,4.0],[0.0,4.0],[0.0,4.0]],
        [[1.0,5.0],[1.0,5.0],[1.0,5.0],[1.0,5.0]],
        [[2.0,6.0],[2.0,6.0],[2.0,6.0],[2.0,6.0]] ,
        [[3.0,7.0],[3.0,7.0],[3.0,7.0],[3.0,7.0]]
        ])
    feature_map = tf.reshape(feature_map,[1,4,4,2])##两通道featuremap输入
    
    ##定义池化层
    pooling = tf.nn.max_pool(feature_map,[1,2,2,1],[1,2,2,1],padding='VALID')##池化窗口2*2,高宽方向步长都为2,不填充
    pooling1 = tf.nn.max_pool(feature_map,[1,2,2,1],[1,1,1,1],padding='VALID')##池化窗口2*2,高宽方向步长都为1,不填充
    pooling2 = tf.nn.avg_pool(feature_map,[1,4,4,1],[1,1,1,1],padding='SAME')##池化窗口4*4,高宽方向步长都为1,填充
    pooling3 = tf.nn.avg_pool(feature_map,[1,4,4,1],[1,4,4,1],padding='SAME')##池化窗口4*4,高宽方向步长都为4,填充
    ##转置变形(详细解释参考另一篇博文)
    tran_reshape = tf.reshape(tf.transpose(feature_map),[-1,16])
    pooling4 = tf.reduce_mean(tran_reshape,1)    ###对行值求平均
    with tf.Session() as sess:
        print('featuremap:
    ',sess.run(feature_map))
        print('*'*30)
        print('pooling:
    ',sess.run(pooling))
        print('*'*30)
        print('pooling1:
    ',sess.run(pooling1))
        print('*'*30)
        print('pooling2:
    ',sess.run(pooling2))
        print('*'*30)
        print('pooling3:
    ',sess.run(pooling3))
        print('*'*30)
        print('pooling4:
    ',sess.run(pooling4))
    '''
    输出结果:
    featuremap:
     [[[[ 0.  4.]
       [ 0.  4.]
       [ 0.  4.]
       [ 0.  4.]]
    
      [[ 1.  5.]
       [ 1.  5.]
       [ 1.  5.]
       [ 1.  5.]]
    
      [[ 2.  6.]
       [ 2.  6.]
       [ 2.  6.]
       [ 2.  6.]]
    
      [[ 3.  7.]
       [ 3.  7.]
       [ 3.  7.]
       [ 3.  7.]]]]
    ******************************
    pooling:
     [[[[ 1.  5.]
       [ 1.  5.]]
    
      [[ 3.  7.]
       [ 3.  7.]]]]
    ******************************
    pooling1:
     [[[[ 1.  5.]
       [ 1.  5.]
       [ 1.  5.]]
    
      [[ 2.  6.]
       [ 2.  6.]
       [ 2.  6.]]
    
      [[ 3.  7.]
       [ 3.  7.]
       [ 3.  7.]]]]
    ******************************
    pooling2:
     [[[[ 1.   5. ]
       [ 1.   5. ]
       [ 1.   5. ]
       [ 1.   5. ]]
    
      [[ 1.5  5.5]
       [ 1.5  5.5]
       [ 1.5  5.5]
       [ 1.5  5.5]]
    
      [[ 2.   6. ]
       [ 2.   6. ]
       [ 2.   6. ]
       [ 2.   6. ]]
    
      [[ 2.5  6.5]
       [ 2.5  6.5]
       [ 2.5  6.5]
       [ 2.5  6.5]]]]
    ******************************
    pooling3:
     [[[[ 1.5  5.5]]]]
    ******************************
    pooling4:
     [ 1.5  5.5]
    
    '''
    池化层常用函数及参数

    现在我们对代码中的内容加以解释:

    padding的规则

    •   padding=‘VALID’时,输出的宽度和高度的计算公式(下图gif为例)

              

        输出宽度:output_width = (in_width-filter_width+1)/strides_width  =(5-3+1)/2=1.5【向上取整=2】

        输出高度:output_height = (in_height-filter_height+1)/strides_height  =(5-3+1)/2=1.5【向上取整=2】

        输出的形状[1,2,2,1]

            

        
    import tensorflow as tf
    image = [0,1.0,1,2,2,0,1,1,0,0,1,1,0,1,0,1,0,1,1,1,0,2,0,1,0]
    input = tf.Variable(tf.constant(image,shape=[1,5,5,1]))  ##1通道输入
    fil1 = [-1.0,0,1,-2,0,2,-1,0,1]
    filter = tf.Variable(tf.constant(fil1,shape=[3,3,1,1]))  ##1个卷积核对应1个featuremap输出
    
    op = tf.nn.conv2d(input,filter,strides=[1,2,2,1],padding='VALID')  ##步长2,VALID不补0操作
    
    init = tf.global_variables_initializer()
    
    with tf.Session() as  sess:
        sess.run(init)
        # print('input:
    ', sess.run(input))
        # print('filter:
    ', sess.run(filter))
        print('op:
    ',sess.run(op))
    
    ##输出结果
    '''
     [[[[ 2.]
       [-1.]]
    
      [[-1.]
       [ 0.]]]]
    '''
    tensorflow中实现(步长2)

        如果strides=[1,3,3,1]的情况又是如何呢?   

        输出宽度:output_width  = (in_width-filter_width+1)/strides_width  =(5-3+1)/3=1

        输出高度:output_height = (in_height-filter_height+1)/strides_height  =(5-3+1)/3=1

        输出的形状[1,1,1,1],因此输出的结果只有一个

        

        
    import tensorflow as tf
    image = [0,1.0,1,2,2,0,1,1,0,0,1,1,0,1,0,1,0,1,1,1,0,2,0,1,0]
    input = tf.Variable(tf.constant(image,shape=[1,5,5,1]))  ##1通道输入
    fil1 = [-1.0,0,1,-2,0,2,-1,0,1]
    filter = tf.Variable(tf.constant(fil1,shape=[3,3,1,1]))  ##1个卷积核对应1个featuremap输出
    
    op = tf.nn.conv2d(input,filter,strides=[1,3,3,1],padding='VALID')  ##步长2,VALID不补0操作
    
    init = tf.global_variables_initializer()
    
    with tf.Session() as  sess:
        sess.run(init)
        # print('input:
    ', sess.run(input))
        # print('filter:
    ', sess.run(filter))
        print('op:
    ',sess.run(op))
    
    ##输出结果
    '''
    op:
     [[[[ 2.]]]]
    '''
    tensorflow中实现(步长3)

         padding=‘SAME’时,输出的宽度和高度的计算公式(下图gif为例)

        

        输出宽度:output_width  = in_width/strides_width=5/2=2.5【向上取整3】

        输出高度:output_height = in_height/strides_height=5/2=2.5【向上取整3】

        则输出的形状:[1,3,3,1]

        那么padding补0的规则又是如何的呢?【先确定输出形状,再计算补多少0】

        pad_width = max((out_width-1)*strides_width+filter_width-in_width,0)=max((3-1)*2+3-5,0)=2

        pad_height = max((out_height-1)*strides_height+filter_height-in_height,0)=max((3-1)*2+3-5,0)=2

        pad_top = pad_height/2=1

        pad_bottom = pad_height-pad_top=1

        pad_left = pad_width/2=1

        pad_right = pad_width-pad_left=1

        

        
    import tensorflow as tf
    image = [0,1.0,1,2,2,0,1,1,0,0,1,1,0,1,0,1,0,1,1,1,0,2,0,1,0]
    input = tf.Variable(tf.constant(image,shape=[1,5,5,1]))  ##1通道输入
    fil1 = [-1.0,0,1,-2,0,2,-1,0,1]
    filter = tf.Variable(tf.constant(fil1,shape=[3,3,1,1]))  ##1个卷积核对应1个featuremap输出
    
    op = tf.nn.conv2d(input,filter,strides=[1,2,2,1],padding='SAME')  ##步长2,VALID不补0操作
    
    init = tf.global_variables_initializer()
    
    with tf.Session() as  sess:
        sess.run(init)
        # print('input:
    ', sess.run(input))
        # print('filter:
    ', sess.run(filter))
        print('op:
    ',sess.run(op))
    
    ##输出结果
    '''
    op:
     [[[[ 3.]
       [ 1.]
       [-4.]]
    
      [[ 3.]
       [ 0.]
       [-3.]]
    
      [[ 4.]
       [-1.]
       [-3.]]]]
    '''
    SAME步长2

        如果步长为3呢?补0的规则又如何?

        输出宽度:output_width  = in_width/strides_width=5/3=2

        输出高度:output_height = in_height/strides_height=5/3=2

        则输出的形状:[1,2,2,1]

        那么padding补0的规则又是如何的呢?【先确定输出形状,再计算补多少0】

        pad_width = max((out_width-1)*strides_width+filter_width-in_width,0)=max((2-1)*3+3-5,0)=1

        pad_height = max((out_height-1)*strides_height+filter_height-in_height,0)=max((2-1)*3+3-5,0)=1

        pad_top = pad_height/2=0【向下取整】

        pad_bottom = pad_height-pad_top=1

        pad_left = pad_width/2=0【向下取整】

        pad_right = pad_width-pad_left=1

            

        
    import tensorflow as tf
    print(3/2)
    image = [0,1.0,1,2,2,0,1,1,0,0,1,1,0,1,0,1,0,1,1,1,0,2,0,1,0]
    input = tf.Variable(tf.constant(image,shape=[1,5,5,1]))  ##1通道输入
    fil1 = [-1.0,0,1,-2,0,2,-1,0,1]
    filter = tf.Variable(tf.constant(fil1,shape=[3,3,1,1]))  ##1个卷积核对应1个featuremap输出
    
    op = tf.nn.conv2d(input,filter,strides=[1,3,3,1],padding='SAME')  ##步长2,VALID不补0操作
    
    init = tf.global_variables_initializer()
    
    with tf.Session() as  sess:
        sess.run(init)
        # print('input:
    ', sess.run(input))
        # print('filter:
    ', sess.run(filter))
        print('op:
    ',sess.run(op))
    
    ##输出结果
    '''
    op:
     [[[[ 2.]
       [-3.]]
    
      [[ 0.]
       [-3.]]]]
    '''
    SAME步长3

        这里借用的卷积中的padding规则,在池化层中的padding规则与卷积中的padding规则一致   

  • 相关阅读:
    UVA 558 Wormholes
    HDU 1565 方格取数(1)
    poj2607
    poj2552
    poj2491
    poj2502
    poj2613
    .NET Framework 4 与 .NET Framework 4 Client Profile的区别与联系
    .Net Framework 4.0 和 2.0/3.0/3.5
    企业IT系统
  • 原文地址:https://www.cnblogs.com/liuhuacai/p/12003697.html
Copyright © 2020-2023  润新知