Skip to content

Conversation

@yanboliang
Copy link
Contributor

@yanboliang yanboliang commented Aug 30, 2018

Summary

I saw the requirements for dilated transposed convolution at several places(#8159, tensorflow/tensorflow#21598). This PR makes Conv2DTranspose supports dilation for all backends.

How to test

Except the unit test I added, I also run the following test. As dilated transposed convolution is equivalent to standard transposed convolution with upsampled kernels with effective size kernel_size + (kernel_size - 1) * (dilation_rate - 1) , produced by inserting dilation_rate - 1 zeros along consecutive elements across the kernel' spatial dimensions. The following code verify these two scenarios that give the same output:

  • kernel_size = 2, dilation_rate = 2
  • kernel_size = 3, kernel is built from the above kernel and insert zeros along consecutive elements.
from keras.layers import Input, Conv2DTranspose
from keras.models import Model
from keras.initializers import Constant
import numpy as np

kernel = np.arange(24).reshape((2, 2, 2, 3))

inputs = Input(shape=(5, 6, 3))
m = Conv2DTranspose(2, kernel_size=2, padding='same', dilation_rate=2, kernel_initializer=Constant(kernel))(inputs)
model = Model(inputs=inputs, outputs=m)
model.summary()

x = np.arange(180).reshape((2, 5, 6, 3)).astype(np.float32)
y = model.predict(x)

print(np.squeeze(y))
print(y.shape)

print("--------------------------------------------------")

kernel = np.arange(24).reshape((2, 2, 2, 3))

# Insert zeros along consecutive elements across the kernel' spatial dimensions
k = np.zeros((3, 3, 2, 3))
k[0, 0, :, :] = kernel[0, 0, :, :]
k[0, 2, :, :] = kernel[0, 1, :, :]
k[2, 0, :, :] = kernel[1, 0, :, :]
k[2, 2, :, :] = kernel[1, 1, :, :]
kernel = k

inputs = Input(shape=(5, 6, 3))
m = Conv2DTranspose(2, kernel_size=3, padding='same', kernel_initializer=Constant(kernel))(inputs)
model = Model(inputs=inputs, outputs=m)
model.summary()

x = np.arange(180).reshape((2, 5, 6, 3)).astype(np.float32)
y = model.predict(x)

print(np.squeeze(y))
print(y.shape)

Related Issues

#8159
tensorflow/tensorflow#21598

PR Overview

  • This PR requires new unit tests [y/n] (make sure tests are included)
  • This PR requires to update the documentation [y/n] (make sure the docs are up-to-date)
  • This PR is backwards compatible [y/n]
  • This PR changes the current API [y/n] (all API changes need to be approved by fchollet)

@yanboliang yanboliang force-pushed the transpose-dilation branch 2 times, most recently from c48d7ff to 351e4fe Compare August 30, 2018 03:17
Copy link
Collaborator

@fchollet fchollet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR! Looks good to me at a high level.

padding='valid',
output_padding=None,
data_format=None,
dilation_rate=(1, 1),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This must be added to the docstring.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docstring has already exist at L671.

'data_format': 'channels_last',
'dilation_rate': (2, 2)},
input_shape=(num_samples, num_row, num_col, stack_size),
fixed_batch_size=True)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need this argument?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not necessary, I just follow the test case above, will remove it.

@keras_test
@pytest.mark.skipif((K.backend() == 'cntk'),
reason='cntk only supports dilated conv transpose on GPU')
def test_conv2d_transpose_dilation():
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this unit test really sufficient?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can specify the input, a constant kernel and check the output, but due to Theano backend need to rotate the kernel which makes the test complicated, and we need to hard code output matrix. The following code is I run for offline test, I will wrap them as a unit test.

from keras.utils.conv_utils import convert_kernel
kernel = np.arange(27).reshape((3, 3, 1, 3))
print(kernel.shape)
# kernel = convert_kernel(kernel) # Enable this line for Theano backend

inputs = Input(shape=(5, 6, 3))
m = Conv2DTranspose(1, kernel_size=3, padding='same', dilation_rate=2, kernel_initializer=Constant(kernel))(inputs)
model = Model(inputs=inputs, outputs=m)
model.summary()

x = np.arange(180).reshape((2, 5, 6, 3)).astype(np.float32)
y = model.predict(x)

print(np.squeeze(y))
print(y.shape)

padding='valid',
output_padding=None,
data_format=None,
dilation_rate=(1, 1),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docstring has already exist at L671.

'data_format': 'channels_last',
'dilation_rate': (2, 2),
'kernel_initializer': 'ones'},
expected_output=expected_output)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a test case here, kernel initialized with ones, then we don't have special handle for Theano backend, and check the output with the given input. The input data's batch size is only one, that we don't need to hard code too big output matrix.

@yanboliang
Copy link
Contributor Author

The PEP-8 check failure is not relevant to this PR, it introduced by #8344 , and I sent a quick fix at #11040 .

@yanboliang yanboliang force-pushed the transpose-dilation branch 3 times, most recently from 80ec2b3 to 3b09507 Compare August 31, 2018 00:14
Copy link
Collaborator

@fchollet fchollet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks

@fchollet fchollet merged commit 6dd087a into keras-team:master Aug 31, 2018
@yanboliang yanboliang deleted the transpose-dilation branch August 31, 2018 19:26
jlherren added a commit to jlherren/keras that referenced this pull request Sep 3, 2018
* keras/master: (327 commits)
  Added in_train_phase and in_test_phase in the numpy backend. (keras-team#11061)
  Make sure the data_format argument defaults to ‘chanels_last’ for all 1D sequence layers.
  Speed up backend tests (keras-team#11051)
  Skipped some duplicated tests. (keras-team#11049)
  Used decorators and WITH_NP to avoid tests duplication. (keras-team#11050)
  Cached the theano compilation directory. (keras-team#11048)
  Removing duplicated backend tests. (keras-team#11037)
  [P, RELNOTES] Conv2DTranspose supports dilation (keras-team#11029)
  Doc Change: Change in shape for CIFAR Datasets (keras-team#11043)
  Fix line too long in mnist_acgan (keras-team#11040)
  Enable using last incomplete minibatch (keras-team#8344)
  Better UX (keras-team#11039)
  Update lstm text generation example (keras-team#11038)
  fix a bug, load_weights doesn't return anything (keras-team#11031)
  Speeding up the tests by reducing the number of K.eval(). (keras-team#11036)
  [P] Expose monitor value getter for easier subclass (keras-team#11002)
  [RELNOTES] Added the mode "bilinear" in the upscaling2D layer. (keras-team#10994)
  Separate pooling test from convolutional test and parameterize test case (keras-team#10975)
  Fix issue with non-canonical TF version name format.
  Allow TB callback to display float values.
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants