tensorflow 中的padding方式“SAME”和“VALID”
因为最近在看一些目标检测的代码,想计算每一层的卷积或者pooling的输出大小,所以把这一块严格看一下,同时有助于自己设计网络,比如什么时候要padd之类的。
tensorflow 中的padding方式“SAME”和“VALID”
在tensorflow里面,这两个计算特征图的输出大小方式不一样,
如果padding的方法为“SAME” ,那么输出特征图的长和宽为:
$$w_out=\frac{w-F+1}{s}$$
其中w表示输入特征图的长/宽,s表示strides,表示卷积核的大小,然后向上取整
$$w_out=\frac{w}/{s}$$
其中w表示输入特征图的长/宽,s表示strides,然后向上取整
我们看一个tensorflow的例子
import tensorflow as tf
import numpy as np
x = tf.reshape(tf.range(0,25*3),[1,5,5,3])
valid_pad = tf.nn.max_pool(x, ksize=[1, 3, 3, 1], strides=[1, 1, 1, 1], padding='VALID')
same_pad = tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 1, 1, 1], padding='SAME')
print("Valid_pad = ",valid_pad.get_shape())
print("Same_pad = ",same_pad.get_shape())
我们看看结果:
Valid_pad = (1, 4, 4, 3)
Same_pad = (1, 5, 5, 3)
结果和公式很吻合,但是需要注意,我这个地方是strides=1,如果我们在草稿纸上自己绘图,移动,会误以为这两个方式一样,其实是不一样的。
那我们在看一种情况:
import tensorflow as tf
import numpy as np
x = tf.reshape(tf.range(0,6*6*3),[1,6,6,3])
valid_pad = tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='VALID')
same_pad = tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
print("Valid_pad = ",valid_pad.get_shape())
print("Same_pad = ",same_pad.get_shape())
结果是:
Valid_pad = (1, 3, 3, 3)
Same_pad = (1, 3, 3, 3)
这下就是输出形状就是一样的了,我们在看看,到底这两个输出值是不是相等
import tensorflow as tf
import numpy as np
x = tf.reshape(tf.range(0,6*6*3),[1,6,6,3])
valid_pad = tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='VALID')
same_pad = tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
with tf.Session() as sess:
valid_pad, same_pad = sess.run([valid_pad,same_pad])
if valid_pad.all() == same_pad.all():
print("equal")
else:
print("unequal")
print(valid_pad)
print(same_pad)
结果是equal,
[[[[ 21 22 23]
[ 27 28 29]
[ 33 34 35]]
[[ 57 58 59]
[ 63 64 65]
[ 69 70 71]]
[[ 93 94 95]
[ 99 100 101]
[105 106 107]]]]
[[[[ 21 22 23]
[ 27 28 29]
[ 33 34 35]]
[[ 57 58 59]
[ 63 64 65]
[ 69 70 71]]
[[ 93 94 95]
[ 99 100 101]
[105 106 107]]]]
这种刚好可以整除的情况就是一样的,我们自己手动滑窗口也是一样,除了strides=1的情况。