利用tf.nn.conv2d_transpose实现图片分辨率按指定倍数扩展

时间:2023-02-08 17:35:25

我有输入尺寸为 64x64x3 的图片,即高64, 宽64, 通道数3
我想通过transposed convolution 来使图片的高宽放大到2倍,即 128x128

import tensorflow as tf
import numpy as np

# 64 64 高宽, 通道数3
x = np.ones((1, 64, 64, 3), dtype=np.float32)
# 卷积尺寸, 5x5 ,第一个3代表输出通道数, 第二个3代表输入通道数
w = np.ones((5, 5, 3, 3), dtype=np.float32)
out = tf.nn.conv2d_transpose(x, w, (1, 128, 128, 3), [1, 2, 2, 1], padding='SAME')

sess = tf.Session()
a = sess.run(out)
print(a)
print(a.shape)

上述代码运行后,会使输入高宽放大至2倍, 128x128;
如果你想让图片放大至多少倍,则 可以修改strides参数,

conv2d_transpose(
value,
filter,
output_shape,
strides,
padding='SAME',
data_format='NHWC',
name=None
)

如上我的代码中 strides
out = tf.nn.conv2d_transpose(x, w, (1, 128, 128, 3), [1, 2, 2, 1], padding='SAME')
用的是 [1 , 2 , 2, 1], 这个2就相当于代表了放大倍数(实际上,这是滤波器的滑动步长)
你可以用[ 1, 3, 3, 1] 来实现图片放大至3倍的效果。

实际上,你可以用相对应的tf.nn.conv2d来验证output_shape是否设置的合理
因为,conv2d_transpose 的效果相当于是将conv2d反过来一样,由conv2d的输出到它的输入
如,

# 这个out代表上述具有output_shape形状的输出
out = tf.constant(1, shape=[1, 128, 128, 3])
expected_x = tf.nn.conv2d(out, w, strides=[1, 2, 2, 1], pading='SAME')

运行完上面这段代码,你可以通过比较expected_x的尺寸和 x 的是否一样,来判断conv2d_transpose的output_shape参数设置是否正确


还有一种实现尺寸扩大的方法,注:这里不考虑用线性插值的方法!!!!!
如一图片数据的尺寸, H x W x C 我想让它尺寸扩大

首先,利用卷积的方法,扩展其输出通道至r*r倍,但图像的高宽尺寸不变,
则输出的图片输出尺寸为 H x W x C*r*r

然后,用像素重新排列的方法使图片变为 H*r x W*r x C,达到了尺寸放大r倍的效果

注:这里提到的像素重新排列方法可参考论文 Real-Time Single Image and Video Super-Resolution Using an Efficient Sub-Pixel Convolutional Neural Network

我还没有实现这个像素重排列的过程,当以后用到再说