Kendall Weihe - 1 year ago 798

Python Question

**EDIT** My issue is the width and height of my filter, I misunderstood the API doc... working on correction now

**SOLUTION** Follow deconvolution from here slide 53

I have a similar issue as here but it's a little funkier.

My error is

`Conv2DBackpropInput: Number of rows of out_backprop doesn't match computed: actual = 25, computed = 26`

...so it's off by 1?

Some background...

I have a conv layer with dimensions

`<tf.Tensor 'MaxPool_2:0' shape=(?, 25, 25, 128) dtype=float32>`

The input image is 200x200, and I have 3 maxpool layers -- thus the h = w = 25. I want to add 3 deconv layers so that I return the original resolution (I'm doing image segmentation).

The deconv code looks like:

`temp_batch_size = tf.shape(x)[0]`

# output_shape = tf.pack([temp_batch_size, 50, 50, 64])

output_shape = [temp_batch_size, 50, 50, 64]

conv4 = tf.nn.conv2d_transpose(conv3, weights['wdc1'], output_shape=output_shape, strides=[1,1,1,1], padding="VALID")

# conv4 = tf.nn.local_response_normalization(conv4)

# output_shape = tf.pack([temp_batch_size, 100, 100, 32])

output_shape = [temp_batch_size, 100, 100, 32]

conv5 = tf.nn.conv2d_transpose(conv4, weights['wdc2'], output_shape=output_shape, strides=[1,1,1,1], padding="VALID")

# conv5 = tf.nn.local_response_normalization(conv5)

# output_shape = tf.pack([temp_batch_size, 200, 200, 1])

output_shape = [temp_batch_size, 200, 200, 1]

conv6 = tf.nn.conv2d_transpose(conv5, weights['wdc3'], output_shape=output_shape, strides=[1,1,1,1], padding="VALID")

# conv6 = tf.nn.local_response_normalization(conv6)

(You can see I tried to

`tf.pack()`

`'wdc1' : tf.Variable(tf.random_normal([25, 25, 64,128])),`

'wdc2' : tf.Variable(tf.random_normal([50, 50, 32,64])),

'wdc3' : tf.Variable(tf.random_normal([100, 100, 1,32])),

Some debugging looks like this:

`(Pdb) conv3`

<tf.Tensor 'MaxPool_2:0' shape=(?, 25, 25, 128) dtype=float32>

(Pdb) conv4

<tf.Tensor 'conv2d_transpose:0' shape=(?, ?, ?, ?) dtype=float32>

(Pdb) conv5

<tf.Tensor 'conv2d_transpose_1:0' shape=(?, ?, ?, ?) dtype=float32>

(Pdb) conv6

<tf.Tensor 'conv2d_transpose_2:0' shape=(?, ?, ?, ?) dtype=float32>

I find it odd that because I have the line

`temp_batch_size = tf.shape(x)[0]`

`<tf.Tensor 'conv2d_transpose:0' shape=(10, 50, 50, 64) dtype=float32>`

So maybe that is part of my issue? If I change it back to a constant

`batch_size`

`ValueError: Shapes (10, 101, 101, 32) and (10, 100, 100, 32) are not compatible`

Debugging with this configuration...

`(Pdb) conv4`

<tf.Tensor 'conv2d_transpose:0' shape=(10, 50, 50, 64) dtype=float32>

(Pdb) conv5

<tf.Tensor 'conv2d_transpose_1:0' shape=(10, 100, 100, 32) dtype=float32>

(Pdb) conv6

<tf.Tensor 'conv2d_transpose_2:0' shape=(10, 200, 200, 1) dtype=float32>

Is the issue my number of strides? What should they be (I've tried different variations to no success)

Answer

When using transposed convolutions, you need to think backwards: how would you get your input (`conv3`

of shape `[batch_size, 25, 25, 128]`

) given the output (of shape `[batch_size, 200, 200, 1]`

)?

You would do a succession of 3x3 convolutions and max pooling. Unfortunately, unpooling is not yet available in TensorFlow, so you will just have transposed convolutions.

The filters should have **normal CNN shapes**: like 3x3 convolutions, or 5x5. If you want to increase the output size, you need to use strided transpose convolutions.

```
weights = {
'wdc1' : tf.Variable(tf.random_normal([3, 3, 64, 128])),
'wdc2' : tf.Variable(tf.random_normal([3, 3, 32, 64])),
'wdc3' : tf.Variable(tf.random_normal([3, 3, 1, 32]))
}
```

And the code (don't forget the stride = 2):

```
temp_batch_size = 10
conv3 = tf.zeros([temp_batch_size, 25, 25, 128])
output_shape = [temp_batch_size, 50, 50, 64]
conv4 = tf.nn.conv2d_transpose(conv3, weights['wdc1'], output_shape=output_shape, strides=[1,2,2,1], padding="SAME")
output_shape = [temp_batch_size, 100, 100, 32]
conv5 = tf.nn.conv2d_transpose(conv4, weights['wdc2'], output_shape=output_shape, strides=[1,2,2,1], padding="SAME")
output_shape = [temp_batch_size, 200, 200, 1]
conv6 = tf.nn.conv2d_transpose(conv5, weights['wdc3'], output_shape=output_shape, strides=[1,2,2,1], padding="SAME")
```

**EDIT:**

Just saw your edit. The slides from CS231n are a very good illustration of how to use transposed convolutions, it's even better with the video !

Source (Stackoverflow)