tf1.9版本以上的conv2d函数存在8个输入参数,但是前4个是各种版本中都一直存在的参数,他们是进行卷积计算的重要的输入参数。input为输入的tensor,filter为滤波器的尺寸,strides为滑动距离表示,padding为边缘的处理机制('VALID'和‘SAME’)。
本文着重介绍不同的padding方式,对输出的数据维度的影响。
常规的计算卷积的输入输出的维度变化的公式为:OUT = (IN-F+2*P)/S+1
VALID:边缘处理时,如果边缘不够一个kernel,会将其丢掉,计算公式为OUT=ceil((IN-F+1)/S),向上取整
SAME:边缘处理时,会增加补0的操作,使边缘能满足一个kernel,计算公式为OUT=ceil(IN/S),向上取整
比如下面的示例代码:
import tensorflow as tf
def conv2d_test():
inp = tf.Variable(tf.random_normal([1,7,7,5]))
f = tf.Variable(tf.random_normal([3,3,5,1]))
op = tf.nn.conv2d(inp,f,strides=[1,3,3,1],padding='VALID')
with tf.Session() as sess:
sess.run(tf.initialize_all_variables())
print(sess.run(op).shape)
if __name__ == '__main__':
conv2d_test()
根据VALID公式计算,结果应该为ceil(7-3+1)/3 = 2。运行结果为(1, 2, 2, 1)
下面看padding为SAME的形式:
import tensorflow as tf
def conv2d_test():
inp = tf.Variable(tf.random_normal([1,7,7,5]))
f = tf.Variable(tf.random_normal([3,3,5,1]))
op = tf.nn.conv2d(inp,f,strides=[1,3,3,1],padding='SAME')
with tf.Session() as sess:
sess.run(tf.initialize_all_variables())
print(sess.run(op).shape)
if __name__ == '__main__':
conv2d_test()
根据SAME公式计算,结果应该为ceil (7/3) = 3。运行结果为(1, 3, 3, 1)
这样计算的时候公式还得按照方式不同使用不同的公式,所以是否可以按照一个公式计算,我们考虑常规公式的计算,此时不考虑padding,计算公式为out =(in -F)/ S +1,我们带入上述公式(7-3)/3 +1 = 2.33,所以如果为VALID,结果向下取整;如果为SAME,向上取整(经验公式)。
PS:一般情况下,如果设计网络时为了保证输入输出的数据维度保证不变,一般选择步长为1,padding为‘SAME’。