tensorflow中卷积方式SAME和VALID特征图大小计算

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/dcrmg/article/details/82317096

卷积方式SAME后特征图大小计算

卷积方式: SAME(卷积后的特征图大小跟卷积核大小无关,只跟卷积所用的步长有关,当卷积步长是1时,卷积前后特征图大小保持不变
输入特征图大小:W×H
卷积核大小: k×k
卷积步长: s×s
输出特征图大小: W1×H1


W1 = math.ceil(W / s)
H1 = math.ceil(H / s)


其中math.ceil()是向上取整

卷积方式是SAME时,会根据卷积核大小,按需在图像上扩充padding,即在宽度或高度方向上补充若干个0,保证图像上的当前点处于卷积中心。
如果补充的padding个数为偶数会在两侧补充相同个数个0,如果padding为奇数2n+1,会在左侧补n个0,右侧补n+1个0

验证示例:

# coding: utf-8
import tensorflow as tf

# 定义输入图像size
img_size = 256
# 卷积核大小
kernel_size = 7
# 卷积步长
stride_size = 1

# 读入图像文件
image_value = tf.read_file('./661.jpg')
# 图像编码
img = tf.image.decode_jpeg(image_value, channels=3)
# 格式转换
img = tf.to_float(img, name='ToFloat')
# 调整图像大小到定义尺寸
img = tf.image.resize_images(img, [img_size,img_size],method=0)

# 第一个参数1是输入图片数量,最后一个3个RGB3个维度
batch_shape = (1,img_size,img_size,3)
# 维度转换,为卷积做准备(卷积的输入特征图的rank必须是4)
img = tf.reshape(img,batch_shape)

# 卷积核大小5×5,深度是3(跟RGB3个维度保持一致),特征图(卷积核)数量是7
filter = tf.Variable(tf.random_normal([kernel_size,kernel_size,3,7]))
# 步长1
strides_shape=[1,stride_size,stride_size,1]
# 定义卷积操作
op_conv2d = tf.nn.conv2d(img, filter, strides_shape, padding='SAME')

# 创建运行sess
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    out_img= sess.run(op_conv2d)
    print('输入图像维度: {}'.format(img.shape))
    print('输出图像维度: {}'.format(out_img.shape))
    # 输入图像维度: (1, 256, 256, 3)
    # 输出图像维度: (1, 256, 256, 7)
    # 卷积方式为SAME,输出图像大小 W1 = W/stride,向上取整,7是定义的卷积核数量

以上设定kernel_size = 7,stride_size = 1,输出:
输入图像维度: (1, 256, 256, 3)
输出图像维度: (1, 256, 256, 7)

若设定kernel_size = 100,stride_size = 1,输出:
输入图像维度: (1, 256, 256, 3)
输出图像维度: (1, 256, 256, 7)

若设定kernel_size = 7,stride_size = 2,输出:
输入图像维度: (1, 256, 256, 3)
输出图像维度: (1, 128, 128, 7)

验证结论: 卷积方式为SAME时,卷积后的特征图大小跟卷积核大小没关系,只跟卷积所用的步长有关,当卷积步长是1时,卷积前后特征图大小保持不变

卷积方式VALID后特征图大小计算

卷积方式: VALID(根据图片实际大小执行卷积,不对图像边界填充,一般卷积后特征图变小)
输入特征图大小:W×H
卷积核大小: k×k
卷积步长: s×s
输出特征图大小: W1×H1


W1 = math.ceil((W-k+1)) / s
H1 = math.ceil((H-k+1)) / s


其中math.ceil()是向上取整


验证示例:

# coding: utf-8
import tensorflow as tf

# 定义输入图像size
img_size = 256
# 卷积核大小
kernel_size = 7
# 卷积步长
stride_size = 1

# 读入图像文件
image_value = tf.read_file('./661.jpg')
# 图像编码
img = tf.image.decode_jpeg(image_value, channels=3)
# 格式转换
img = tf.to_float(img, name='ToFloat')
# 调整图像大小到定义尺寸
img = tf.image.resize_images(img, [img_size,img_size],method=0)

# 第一个参数1是输入图片数量,最后一个3个RGB3个维度
batch_shape = (1,img_size,img_size,3)
# 维度转换,为卷积做准备(卷积的输入特征图的rank必须是4)
img = tf.reshape(img,batch_shape)

# 卷积核大小5×5,深度是3(跟RGB3个维度保持一致),特征图(卷积核)数量是7
filter = tf.Variable(tf.random_normal([kernel_size,kernel_size,3,7]))
# 步长1
strides_shape=[1,stride_size,stride_size,1]
# 定义卷积操作
op_conv2d = tf.nn.conv2d(img, filter, strides_shape, padding='VALID')

# 创建运行sess
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    out_img= sess.run(op_conv2d)
    print('输入图像维度: {}'.format(img.shape))
    print('输出图像维度: {}'.format(out_img.shape))
    # 输入图像维度: (1, 256, 256, 3)
    # 输出图像维度: (1, 250, 250, 7)
    # 卷积方式为VALID,输出图像大小 W1 = (W-k+1)/stride,向上取整,7是定义的卷积核数量

以上设定kernel_size = 7,stride_size = 1,输出:
输入图像维度: (1, 256, 256, 3)
输出图像维度: (1, 256, 256, 7)

若设定kernel_size = 100,stride_size = 1,输出:
输入图像维度: (1, 256, 256, 3)
输出图像维度: (1, 157, 157, 7)

若设定kernel_size = 7,stride_size = 2,输出:
输入图像维度: (1, 256, 256, 3)
输出图像维度: (1, 125, 125, 7)

验证结论: 卷积方式为VALID时,卷积后的特征图大小跟卷积核大小和卷积步长都有关系

猜你喜欢

转载自blog.csdn.net/dcrmg/article/details/82317096