参数

conv2d_transpose(
inputs,
filters,
kernel_size,
strides=(1, 1),
padding=’valid’,
data_format=’channels_last’,
activation=None,
use_bias=True,
kernel_initializer=None,
bias_initializer=tf.zeros_initializer(),
kernel_regularizer=None,
bias_regularizer=None,
activity_regularizer=None,
kernel_constraint=None,
bias_constraint=None,
trainable=True,
name=None,
reuse=None
)

比较关注的参数:

  • inputs: 输入的张量
  • filters: 输出卷积核的数量
  • kernel_size : 在卷积操作中卷积核的大小
  • strides: (不太理解,我直接理解成放大的倍数)
  • padding : ‘valid’ 或者 ‘same’。

深度学习 tensorflow tf.layers.conv2d_transpose 反卷积 上采样_深度学习

观察之后看到,补0 过程分为两个部分:元素之间和外轮廓

1 、当padding = ‘valid’时:

     元素之间补0:(input_size - 1)×(strides - 1)

     外轮廓补0:(kernel_size - 1)× 2

     output_size = (input_size  + (input_size - 1)×(strides - 1) +(kernel_size - 1)× 2 - kernel_size ) / 1 + 1

2、当padding = ‘same’时:

     output_size = input_size × strides

     他是通过调整外轮廓的补0 数量实现的,如果不够,我个人觉得可能元素之间补0也会减少

img = np.random.randint(0, 255, (5, 16, 16, 32)).astype(np.float32)
img_t = tf.constant(img, tf.float32)
 
transpose_v = tf.layers.conv2d_transpose(inputs=img_t, filters=16, kernel_size=(6, 6), strides=(2, 2), padding='valid')
transpose_s = tf.layers.conv2d_transpose(inputs=img_t, filters=16, kernel_size=(6, 6), strides=(2, 2), padding='same')
print('valid 输出尺寸:', transpose_v.shape)
print('same 输出尺寸: ', transpose_s.shape)
 
 
valid 输出尺寸: (5, 36, 36, 16)
same 输出尺寸:  (5, 32, 32, 16)

反卷积的过程

  • Step 1 扩充: 将 inputs 进行填充扩大。扩大的倍数与strides有关。扩大的方式是在元素之间插strides - 1 个 0
  • Step 2 卷积: 对扩充变大的矩阵,用大小为kernel_size卷积核做卷积操作,这样的卷积核有filters个,并且这里的步长为1(与参数strides无关,一定是1)

举个例子:

  • inputs:[ [1, 1], [2,2] ]
  • strides = 2(扩大2倍)
  • filters = 1
  • kernel_size = 3(假设核的值都是1)
  • padding = ‘same’

Step 1:[2,2] 扩大至 [4,4]

  • 问题描述:一个矩阵XX,通过 3*3 大小的卷积核,以 ‘same’的padding形式,步长为2做卷积,得到 [[1,1],[2,2]],问XX长啥样

    深度学习 tensorflow tf.layers.conv2d_transpose 反卷积 上采样_深度学习_02


    通过填充,让原来2*2的矩阵变成4*4。填充的方式是我自己根据代码给出的结果猜的,大概就是先在元素之间插strides - 1个0,然后在填充边缘使矩阵达到目标尺寸。
    目标尺寸可以根据下面的公式来求:

    深度学习 tensorflow tf.layers.conv2d_transpose 反卷积 上采样_tensorflow_03


    其中 x为目标尺寸,k是卷积核的尺寸, p表示填充的个数, o表示输出的尺寸,s表示步长。
    在这里,k,p,s,o都是已知的,求x即可。但是因为有取整操作,实际上会有两个值符合x,似乎是取大的那个。
    在这个例子中k=3,p=1,s=2,o=2,得到x=4或x=3或x=3,取大的那个,所以x=4

Step 2 : 做卷积,卷积核大小3*3, 步长为1

深度学习 tensorflow tf.layers.conv2d_transpose 反卷积 上采样_tensorflow_04


这一步就是普通的做卷积操作。

 

代码验证

a = np.array([[1,1],[2,2]], dtype=np.float32)
# [[1,1],
#  [2,2]]

# tf.layers.conv2d_transpose 要求输入是4维的
a = np.reshape(a, [1,2,2,1])

# 定义输入
x = tf.constant(a,dtype=tf.float32)
# 进行tf.layers.conv2d_transpose
upsample_x = tf.layers.conv2d_transpose(x, 1, 3, strides=2, padding='same', kernel_initializer=tf.ones_initializer())
with tf.Session() as sess:
    tf.global_variables_initializer().run()
    print(sess.run(upsample_x))
    # [[[[1],[1],[2],[1]],
    #   [[1],[1],[2],[1]],
    #   [[3],[3],[6],[3]],
    #   [[2],[2],[4],[2]]]]

 

深度学习 tensorflow tf.layers.conv2d_transpose 反卷积 上采样_深度学习_05