• 卷积输入输出图像大小的计算


    输入输出图像大小的计算

    此段内容引自我翻译的一篇文章 
    上面的内容可能会使你混淆每一层的输出尺寸。 所以我决定使用下面的内容让你能够识别输出尺寸。 在卷积层中,有三个关键控制着输出尺寸的大小

    1. 过滤器的数量 ——输出音量的深度就等于滤波器应用的数量。 每个滤波器(卷积核)可以输出一个图片,卷积核增加,输出图片的数量增加 
      多个卷积核运算效果
    2. 步长 ——控制着卷积核向下移动的像素值。 高步值长时我们跨过的像素值,因此产生较小的输出量。
    3. 补零 ——这有助于我们保持输入图像的大小。 如果只在原始图像周围添加一个补零的层数,并且步长为一,那么输出将保留原始图像的大小。

    我们可以应用一个简单的公式来计算输出尺寸。 输出图像的空间大小可以计算(W-F + 2 p / S)+ 1。 这里,W是输入图片大小,F是卷积核的大小,P是填充应用的数量和S是步长的数量。 假设我们有一个输入图像的大小32 * 32 * 3,我们应用10过滤器的大小3 * 3 * 3,与单步和补零。

    W = 32,F = 3,P = 0和S = 1。 输出深度等于过滤器应用的数量即10。

    输出音量的大小将(32-3 + 0)/ 1 + 1 = 30。 因此,输出音量将30 * 30 * 10。

    转载请标明出处:http://blog.csdn.net/wuzqchom/article/details/74785643



    在用tensorflow写CNN的时候,调用卷积核api的时候,会有填padding方式的参数,找到源码中的函数定义如下(max pooling也是一样):

    def conv2d(input, filter, strides, padding, use_cudnn_on_gpu=None, 
    data_format=None, name=None)

    源码中对于padding参数的说明如下:

    padding: A string from: "SAME", "VALID"
    The type of padding algorithm to use.

    说了padding可以用“SAME”和“VALID”两种方式,但是对于这两种方式具体是什么并没有多加说明。 
    这里用Stack Overflow中的一份代码来简单说明一下,代码如下:

    x = tf.constant([[1., 2., 3.],
                     [4., 5., 6.]])
    
    x = tf.reshape(x, [1, 2, 3, 1])  # give a shape accepted by tf.nn.max_pool
    
    valid_pad = tf.nn.max_pool(x, [1, 2, 2, 1], [1, 2, 2, 1], padding='VALID')
    same_pad = tf.nn.max_pool(x, [1, 2, 2, 1], [1, 2, 2, 1], padding='SAME')
    
    print(valid_pad.get_shape())
    print(same_pad.get_shape())


    最后输出的结果为:

    (1, 1, 1, 1) 
    (1, 1, 2, 1)


    可以看出“SAME”的填充方式是比“VALID”的填充方式多了一列。 
    让我们来看看变量x是一个2x3的矩阵,max pooling窗口为2x2,两个维度的strides=2。 
    第一次由于窗口可以覆盖(橙色区域做max pool操作),没什么问题,如下:

    1 2 3
    4 5 6


    接下来就是“SAME”和“VALID”的区别所在,由于步长为2,当向右滑动两步之后“VALID”发现余下的窗口不到2x2所以就把第三列直接去了,而“SAME”并不会把多出的一列丢弃,但是只有一列了不够2x2怎么办?填充!

    1 2 3 0
    4 5 6 0


    如上图所示,“SAME”会增加第四列以保证可以达到2x2,但为了不影响原来的图像像素信息,一般以0来填充。(这里使用表格的形式展示,markdown不太好控制格式,明白意思就行),这就不难理解不同的padding方式输出的形状会有所不同了。 

    在CNN用在文本中时,一般卷积层设置卷积核的大小为n×k,其中k为输入向量的维度(即[n,k,input_channel_num,output_channel_num]),这时候我们就需要选择“VALID”填充方式,这时候窗口仅仅是沿着一个维度扫描而不是两个维度。可以理解为统计语言模型当中的N-gram。


    我们设计网络结构时需要设置输入输出的shape,源码nn_ops.py中的convolution函数和pool函数给出的计算公式如下:

     If padding == "SAME":
          output_spatial_shape[i] = ceil(input_spatial_shape[i] / strides[i])
    
        If padding == "VALID":
          output_spatial_shape[i] =
            ceil((input_spatial_shape[i] -
                  (spatial_filter_shape[i]-1) * dilation_rate[i])
                  / strides[i]).


    dilation_rate为一个可选的参数,默认为1,这里我们可以先不管它。 
    整理一下,对于“VALID”,输出的形状计算如下: 

     
    new_height=new_width=(WF+1)Snew_height=new_width=⌈(W–F+1)/S⌉

    对于“SAME”,输出的形状计算如下: 
     
    new_height=new_width=WSnew_height=new_width=⌈W/S⌉

    其中,WW为输入的size,FF为filter为size,SS为步长,⌈⌉为向上取整符号。
    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wuzqChom/article/details/747
  • 相关阅读:
    K-Means原理及代码实现
    Windows 10安装Tomcat
    Maven笔记四:在Eclipse中创建java web项目
    Maven笔记三:使用Ecplise创建一个Maven项目
    Maven笔记二:Maven仓库
    Windows 10 安装Eclipse
    Maven笔记一:Maven安装与配置(Windows 10)
    Docker学习笔记五:Dockerfile
    Docker学习笔记五:docker简单实践(Docker部署Java应用)
    Zabbix笔记三:zabbix监控指标
  • 原文地址:https://www.cnblogs.com/adong7639/p/9209909.html
Copyright © 2020-2023  润新知