一步一步解释逆卷积:
上图中图像大小为2x2,卷积核大小(kernel size)为3x3, 步长(strides)为2,填充(padding)1;
那么逆卷积操作:
将原始图像的一个像素乘上卷积窗,移动一个步长,将重叠的区域作叠加运算。
注意的是:
在卷积中,卷积核大小只影响视野大小,与特征的提取的细腻程度有关系;
而步长决定了卷积后的空间分辨率,而输出通道数决定卷积核的数量。
相反在逆卷积中同样是个道理。步长决定了卷积后的空间分辨率。
因此上述步长为2,相当于原始图像扩大了2倍。但是未经修剪的卷积之后的图像大小为5x5(k+s(N-1)=3+2*(2-1)=5),
从第一个元素开始修剪。
在Tensorflow上验证:
import tensorflow as tf
import numpy as np
def test_conv2d_transpose():
# input batch shape = (1, 2, 2, 1) -> (batch_size, height, width, channels) - 2x2x1 image in batch of 1
x = tf.constant(np.array([[
[[1], [2]],
[[3], [4]]
]]), tf.float32)
# shape = (3, 3, 1, 1) -> (height, width, input_channels, output_channels) - 3x3x1 filter
f = tf.constant(np.array([
[[[1]], [[1]], [[1]]],
[[[1]], [[1]], [[1]]],
[[[1]], [[1]], [[1]]]
]), tf.float32)
conv = tf.nn.conv2d_transpose(x, f, output_shape=(1, 4, 4, 1), strides=[1, 2, 2, 1], padding='SAME')
with tf.Session() as session:
result = session.run(conv)
assert (np.array([[
[[1.0], [1.0], [3.0], [2.0]],
[[1.0], [1.0], [3.0], [2.0]],
[[4.0], [4.0], [10.0], [6.0]],
[[3.0], [3.0], [7.0], [4.0]]]]) == result).all()