I'm trying to stack 2 layers of tf.nn.conv2d_transpose()
to up-sample a tensor. It works fine during feed forward, but I get an error during backward propagation:
ValueError: Incompatible shapes for broadcasting: (8, 256, 256, 24) and (8, 100, 100, 24)
.
Basically, I've just set the output of the first conv2d_transpose
as the input of the second one:
convt_1 = tf.nn.conv2d_transpose(...)
convt_2 = tf.nn.conv2d_transpose(conv_1)
Using just one conv2d_transpose
, everything works fine. The error only occurs if multiple conv2d_transpose
are stacked together.
I'm not sure of the proper way of implementing multiple layer of conv2d_transpose
. Any advice on how to go about this would be very much appreciated.
Here's a small code that replicates the error:
import numpy as np
import tensorflow as tf
IMAGE_HEIGHT = 256
IMAGE_WIDTH = 256
CHANNELS = 1
batch_size = 8
num_labels = 2
in_data = tf.placeholder(tf.float32, shape=(batch_size, IMAGE_HEIGHT, IMAGE_WIDTH, CHANNELS))
labels = tf.placeholder(tf.int32, shape=(batch_size, IMAGE_HEIGHT, IMAGE_WIDTH, 1))
# Variables
w0 = tf.Variable(tf.truncated_normal([3, 3, CHANNELS, 32]))
b0 = tf.Variable(tf.zeros([32]))
# Down sample
conv_0 = tf.nn.relu(tf.nn.conv2d(in_data, w0, [1, 2, 2, 1], padding='SAME') + b0)
print("Convolution 0:", conv_0)
# Up sample 1. Upscale to 100 x 100 x 24
wt1 = tf.Variable(tf.truncated_normal([3, 3, 24, 32]))
convt_1 = tf.nn.sigmoid(
tf.nn.conv2d_transpose(conv_0,
filter=wt1,
output_shape=[batch_size, 100, 100, 24],
strides=[1, 1, 1, 1]))
print("Deconvolution 1:", convt_1)
# Up sample 2. Upscale to 256 x 256 x 2
wt2 = tf.Variable(tf.truncated_normal([3, 3, 2, 24]))
convt_2 = tf.nn.sigmoid(
tf.nn.conv2d_transpose(convt_1,
filter=wt2,
output_shape=[batch_size, IMAGE_HEIGHT, IMAGE_WIDTH, 2],
strides=[1, 1, 1, 1]))
print("Deconvolution 2:", convt_2)
# Loss computation
logits = tf.reshape(convt_2, [-1, num_labels])
reshaped_labels = tf.reshape(labels, [-1])
cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits, reshaped_labels)
loss = tf.reduce_mean(cross_entropy)
optimizer = tf.train.GradientDescentOptimizer(0.5).minimize(loss)
I guess you need to change your 'stride' paramter in conv2d_transpose. conv2d_transpos
is like conv2d
but input and output are reversed.
For conv2d
, the stride
and input shape will decide the output shape. For conv2d_transpose
, the stride
and output shape will decide the input shape. Now your stride is [1 1 1 1], which means output and input of conv2d_transpose
is about same (ignoring boundary effect).
For input H = W = 100, stride = [1 2 2 1]
, the output of conv2d_tranpose
should be 200. (reversed of conv2d
), if you set the padding
to SAME. In short, input, output and stride need to be compatible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With