转 TensorFlow中CNN的两种padding方式“SAME”和“VALID”

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

 

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

<span style="color:#000000"><code class="language-python"><span style="color:#000088">def</span> <span style="color:#009900">conv2d</span><span style="color:#4f4f4f">(input, filter, strides, padding, use_cudnn_on_gpu=None,
           data_format=None, name=None)</span></code></span>
  • 1
  • 2

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

<span style="color:#000000"><code class="language-python">padding: A `string` <span style="color:#000088">from</span>: `<span style="color:#009900">"SAME"</span>, <span style="color:#009900">"VALID"</span>`.
      The type of padding algorithm to use.</code></span>
  • 1
  • 2

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

<span style="color:#000000"><code class="language-python">x = tf.constant([[<span style="color:#006666">1.</span>, <span style="color:#006666">2.</span>, <span style="color:#006666">3.</span>],
                 [<span style="color:#006666">4.</span>, <span style="color:#006666">5.</span>, <span style="color:#006666">6.</span>]])
x = tf.reshape(x, [<span style="color:#006666">1</span>, <span style="color:#006666">2</span>, <span style="color:#006666">3</span>, <span style="color:#006666">1</span>])  <span style="color:#880000"># give a shape accepted by tf.nn.max_pool</span>

valid_pad = tf.nn.max_pool(x, [<span style="color:#006666">1</span>, <span style="color:#006666">2</span>, <span style="color:#006666">2</span>, <span style="color:#006666">1</span>], [<span style="color:#006666">1</span>, <span style="color:#006666">2</span>, <span style="color:#006666">2</span>, <span style="color:#006666">1</span>], padding=<span style="color:#009900">'VALID'</span>)
same_pad = tf.nn.max_pool(x, [<span style="color:#006666">1</span>, <span style="color:#006666">2</span>, <span style="color:#006666">2</span>, <span style="color:#006666">1</span>], [<span style="color:#006666">1</span>, <span style="color:#006666">2</span>, <span style="color:#006666">2</span>, <span style="color:#006666">1</span>], padding=<span style="color:#009900">'SAME'</span>)

print(valid_pad.get_shape())
print(same_pad.get_shape())</code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9


最后输出的结果为:

<span style="color:#000000"><code>(<span style="color:#4f4f4f">1</span>,<span style="color:#006666"> 1</span>,<span style="color:#006666"> 1</span>,<span style="color:#006666"> 1</span>)
(<span style="color:#4f4f4f">1</span>,<span style="color:#006666"> 1</span>,<span style="color:#006666"> 2</span>,<span style="color:#006666"> 1</span>)</code></span>
  • 1
  • 2


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

 


 



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


 



如上图所示,“SAME”会增加第四列以保证可以达到2x2,但为了不影响原来的图像像素信息,一般以0来填充。这就不难理解不同的padding方式输出的形状会有所不同了。 

 

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


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

<span style="color:#000000"><code class="language-python"> If padding == <span style="color:#009900">"SAME"</span>:
      output_spatial_shape[i] = ceil(input_spatial_shape[i] / strides[i])

    If padding == <span style="color:#009900">"VALID"</span>:
      output_spatial_shape[i] =
        ceil((input_spatial_shape[i] -
              (spatial_filter_shape[i]-<span style="color:#006666">1</span>) * dilation_rate[i])
              / strides[i]).</code></span>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8


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

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


对于“SAME”,输出的形状计算如下: 

new_height=new_width=⌈WS⌉new_height=new_width=⌈WS⌉


其中,WW为输入的size,FF为filter为size,SS为步长,⌈⌉⌈⌉为向上取整符号。

猜你喜欢

转载自blog.csdn.net/jn10010537/article/details/81915646