假设我有一个来自上一层的4D张量x,形状为[2, 2, 7, 7, 64],其中有batch = 2,depth = 2,height = 7,width = 7和in_channels = 64。
我想把它上采样成一个形状为[2, 4, 14, 14, 32]的张量。也许下一步是用[2, 8, 28, 28, 16]和[2, 16, 112, 112, 1]等形状来转移它。
我是Tensorflow的新手,我知道CAFFE和Tensorflow之间的转置卷积实现是不同的。我的意思是,在CAFFE中,你可以通过改变内核的步幅来定义输出的大小。然而,在tensorflow中则更为复杂。
那么,我如何使用tf.layers.conv3d_transpose或tf.nn.conv3d_transpose做到这一点呢?
有人能帮我一下吗?谢谢!
发布于 2019-01-23 09:34:20
您可以使用tf.layers.conv3d_transpose和tf.nn.conv3d_transpose进行上采样。
让我们考虑一下你的输入张量:
input_layer = tf.placeholder(tf.float32, (2, 2, 7, 7, 64)) # batch, depth, height, width, in_channels使用tf.nn.conv3d_transpose时,我们需要注意变量(权重和偏差)的创建:
def conv3d_transpose(name, l_input, w, b, output_shape, stride=1):
transp_conv = tf.nn.conv3d_transpose(l_input, w, output_shape, strides=[1, stride, stride, stride, 1], padding='SAME')
return tf.nn.bias_add(transp_conv, b, name=name)
# Create variables for the operation
with tf.device('/cpu:0'):
# weights will have the shape [depth, height, width, output_channels, in_channels]
weights = tf.get_variable(name='w_transp_conv', shape=[3, 3, 3, 32, 64])
bias = tf.get_variable(name='b_transp_conv', shape=[32])
t_conv_layer = conv3d_transpose('t_conv_layer', input_layer, weights, bias,
output_shape=[2, 4, 14, 14, 32], stride=2)
print(t_conv_layer)
# Tensor("t_conv_layer:0", shape=(2, 4, 14, 14, 32), dtype=float32)对于将负责创建权重和偏差的tf.layers.conv3d_transpose,我们使用相同的输入张量input_layer
t_conv_layer2 = tf.layers.conv3d_transpose(input_layer, filters=32, kernel_size=[3, 3, 3],
strides=(2, 2, 2), padding='SAME', name='t_conv_layer2')
print(t_conv_layer2)
# Tensor("t_conv_layer2/Reshape_1:0", shape=(2, 4, 14, 14, 32), dtype=float32) 要获得其他上采样张量,可以根据需要更改步幅来重复此过程:
Tf.layers.conv3d_transpose示例:
t_conv_layer3 = tf.layers.conv3d_transpose(t_conv_layer2, filters=16, kernel_size=[3, 3, 3],
strides=(2, 2, 2), padding='SAME', name='t_conv_layer3')
t_conv_layer4 = tf.layers.conv3d_transpose(t_conv_layer3, filters=8, kernel_size=[3, 3, 3],
strides=(2, 2, 2), padding='SAME', name='t_conv_layer4')
t_conv_layer5 = tf.layers.conv3d_transpose(t_conv_layer4, filters=1, kernel_size=[3, 3, 3],
strides=(1, 2, 2), padding='SAME', name='t_conv_layer5')
print(t_conv_layer5)
# Tensor("t_conv_layer5/Reshape_1:0", shape=(2, 16, 112, 112, 1), dtype=float32)注意:由于tf.nn.conv3d_transpose实际上是tf.nn.conv3d的梯度,因此可以通过考虑与tf.nn.conv3d的正向运算来确保变量output_shape是正确的。
def print_expected(weights, shape, stride=1):
output = tf.constant(0.1, shape=shape)
expected_layer = tf.nn.conv3d(output, weights, strides=[1, stride, stride, stride, 1], padding='SAME')
print("Expected shape of input layer when considering the output shape ({} and stride {}): {}".format(shape, stride, expected_layer.get_shape()))因此,为了产生具有形状2、4、14、14、32的转置卷积,我们可以检查例如步长1和2:
print_expected(weights, shape=[2, 4, 14, 14, 32], stride=1)
print_expected(weights, shape=[2, 4, 14, 14, 32], stride=2)它打印并确认第二个选项(使用步长2)是生成具有我们所需形状的张量的正确选项:
Expected shape of input layer when considering the output shape ([2, 4, 14, 14, 32] and stride 1): (2, 4, 14, 14, 64)
Expected shape of input layer when considering the output shape ([2, 4, 14, 14, 32] and stride 2): (2, 2, 7, 7, 64) https://stackoverflow.com/questions/54123566
复制相似问题