Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added 2D Upscaling Methods - Bilinear (#857), Nearest Neighbor, Subpixel Convolution (Phase Shift) #877

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

vvmurthy
Copy link

@vvmurthy vvmurthy commented Sep 1, 2017

This PR:

  • Merges in the added 2D bilinear upscaling from Add 2D bilinear upsampling layer #857 and adds 'bilinear1D' and 'bilinear2D' as modes to the existing Upscale2D class.

  • Adds in a mode for nearest-neighbor interpolation. Not exactly state of the art, but I've been using it to implement BEGAN, so it may be useful to others.

  • I'm aware of Checkerboard artifact free sub-pixel convolution #862 and may attempt to implement it at some point, but from my skimming of the referenced paper, it mentions that the initialization scheme is for subpixel convolution. As Lasagne appears to lack a subpixel convolution option for upscaling included as part of the library, I added in subpixel convolution phase shift based primarily on the second subpixel convolution method here + unit tests with the corresponding numpy implementation based on the algorithm in the paper.

Currently, Nearest neighbor and subpixel convolution are checked in numpy, bilinear convolution is only checked against shape as in #857.

All suggestions are welcome- It'd be good to see some more upscaling methods in Lasagne. If the documentation does not display correctly, I will try to fix it- I've been having a bit of trouble rendering it on my machine.

@vvmurthy
Copy link
Author

vvmurthy commented Sep 1, 2017

Apologies for the several commits- forgot about how Python 3 handles floating-point division.

if b > 1 or a > 1:
output_shape = self.get_output_shape_for(input.shape)
upscaled = T.zeros(shape=output_shape, dtype=input.dtype)
upscaled = T.set_subtensor(upscaled[:, :, ::a, ::b], input)
elif self.mode == 'bilinear2D':
upscaled = T.nnet.abstract_conv.bilinear_upsampling(
input, self.scale_factor[0],
Copy link
Contributor

Choose a reason for hiding this comment

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

I am not sure with the change in this line. Since Bilinear Upsampling doesn't use learnable filters, I think we should be having same number of filters as in the previous layer. Please correct me if I am wrong

Copy link
Contributor

Choose a reason for hiding this comment

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

I got notified by github that i didn't "submit" my comment. Usually, comment(shift + enter) alone is enough. The interface got complicated, I will check it out. Apologise if it has occurred as a repost.

Copy link
Author

Choose a reason for hiding this comment

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

I'm not sure I understand your requested change- Theano handles creation of bilinear upsample filters within bilinear_upsampling, it's not an argument passed into bilinear_upsampling by the change in the PR.

The second input to bilinear_upsampling is the scalar scale factor to upsample the tensor by, not the filters used for convolution as it would be with something like T.nnet.conv2d().

The output of bilinear_upsampling is a 4D tensor of dims [batchsize, num_filters, row * scale_factor, col*scale_factor] , where num_filters is the same as the number of filters of the previous layer- only the dims of the two trailing axes are affected by bilinear_upsampling.

Please do correct me if I'm wrong about any of the above, any feedback is welcome.

Copy link
Contributor

Choose a reason for hiding this comment

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

The second input to bilinear_upsampling is the scalar scale factor to upsample the tensor by, not the filters used for convolution as it would be with something like T.nnet.conv2d().

Yeah, my bad! Had it been the case, it should have been an issue in Theano primarily.

@f0k
Copy link
Member

f0k commented Sep 8, 2017

Hey, sorry for the delay, and thanks for the PR!

adds 'bilinear1D' and 'bilinear2D' as modes to the existing Upscale2D class.

👍

Adds in a mode for nearest-neighbor interpolation.

👍

As Lasagne appears to lack a subpixel convolution option for upscaling included as part of the library

Lasagne has transposed convolution, which subpixel convolution is a special case of (https://arxiv.org/abs/1609.07009, Figure 3). So I guess we can omit this?

@vvmurthy
Copy link
Author

Lasagne has transposed convolution, which subpixel convolution is a special case of (https://arxiv.org/abs/1609.07009, Figure 3). So I guess we can omit this?

Ok- I've removed it from the PR, and squashed the 4 commits into 1- should be ready to merge.

if b > 1 or a > 1:
output_shape = self.get_output_shape_for(input.shape)
upscaled = T.zeros(shape=output_shape, dtype=input.dtype)
upscaled = T.set_subtensor(upscaled[:, :, ::a, ::b], input)
elif self.mode == 'bilinear2D':
upscaled = T.nnet.abstract_conv.bilinear_upsampling(
input, self.scale_factor[0],
Copy link
Contributor

Choose a reason for hiding this comment

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

The second input to bilinear_upsampling is the scalar scale factor to upsample the tensor by, not the filters used for convolution as it would be with something like T.nnet.conv2d().

Yeah, my bad! Had it been the case, it should have been an issue in Theano primarily.

@f0k f0k added this to the v0.3 milestone Feb 19, 2018
@f0k f0k mentioned this pull request Feb 19, 2018
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.

None yet

3 participants