CNN处理图片的时候,原图片经过卷积之后尺寸会发生变化,本文总结了卷积之后图片尺寸的变化规律。
1、图片的宽和高在卷积过程中的尺寸变化规律是一致的,因此用的图片来分析,卷积核的尺寸为,两个方向上的步长均为,补零的数量(padding)为,这里的是在某一维度上总的padding数量。
如下图中绿色部分是图片,黄色部分是padding,因此下图所示的图片尺寸是,padding数量在水平维度上等于2,在垂直维度上也等于2。
2、两个方向上的步长均为,输出图片的宽和高相等,如下所示:
ceil表示向上取整
3、在tensorfow的tf.nn.conv2d方法中,padding有两种模式,"VALID"和"SAME",
(1) "VALID"模式下,,使用前面叙述的方法计算输出的尺寸。
(2) "SAME"模式下首先会进行补零操作,然后再卷积。
"SAME"模式卷积输出的尺寸为:
补零的数量为:
将上面的式子综合可以得到补零数量的计算式如下所示:
然后根据前面叙述的方法计算输出的尺寸。
4、如果在左右两边补零总数是偶数,那么左右补零数量相等,如果补零的总数是奇数,那么右侧补零比左侧多一个,同理当上下总共补零为奇数的时候,下侧补零数量比上侧多一个。
例如对的矩阵宽和高方向分别补3个零,那么补零之后的矩阵应该是下面的样子,绿色部分是图片,黄色部分是padding。
5、"VALID"和"SAME"输出尺寸一样的情况
当图片尺寸为,卷积核为,步长为2
(1) 在"VALID"模式下,根据前面的公式可以得知输出的尺寸为
(2) 在"SAME"模式下,根据前面的公式计算得知输出尺寸也是
需要补零的数量为:
下面在tensorflow中验证这两种模式的输出是否一致,从输出可以看出"SAME"和"VALID"的输出确实是一样的。
# tensorflow1.8.0
import tensorflow as tf
import numpy as np
np.random.seed(12)
data = np.random.rand(1,10,10,1)
a = tf.constant(data,dtype=tf.float32)
b = tf.ones([2,2,1,1],dtype=tf.float32)
c1 = tf.nn.conv2d(a,b,strides=[1,2,2,1],padding="SAME")
c2 = tf.nn.conv2d(a,b,strides=[1, 2, 2, 1], padding="VALID")
with tf.Session() as sess:
print(sess.run(c1).squeeze())
print(sess.run(c2).squeeze())
# 输出
[[1.7841241 2.5940151 1.4568073 1.9715514 2.0230098]
[1.8155621 1.5641888 2.5562458 2.8798828 1.8806615]
[2.212563 1.8042688 1.3643253 1.415138 0.9652648]
[2.4231486 1.7592132 2.2874975 1.6366189 2.1969295]
[2.8632264 3.191011 2.286504 2.7619777 1.2597685]]
[[1.7841241 2.5940151 1.4568073 1.9715514 2.0230098]
[1.8155621 1.5641888 2.5562458 2.8798828 1.8806615]
[2.212563 1.8042688 1.3643253 1.415138 0.9652648]
[2.4231486 1.7592132 2.2874975 1.6366189 2.1969295]
[2.8632264 3.191011 2.286504 2.7619777 1.2597685]]