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

MaxPooling2d() turns odd input into even numbers, is there anyway to go around this? #4818

Closed
0bserver07 opened this issue Dec 24, 2016 · 5 comments

Comments

@0bserver07
Copy link
Contributor

During MaxPooling2d() the row with odd number [ 45 ] becomes even [ 22 ], this becomes an issue during Deconv or let's say UpSampling2D(), it doesn't count up to the same sizes as it started.

Here is a gist of the full model, but what I'm pointing to is the maxpooling2d_59

block4_conv3 (Convolution2D)     (None, 512, 45, 60)   2359808     activation_299[0][0]             
____________________________________________________________________________________________________
batchnormalization_312 (BatchNorm(None, 512, 45, 60)   120         block4_conv3[0][0]               
____________________________________________________________________________________________________
activation_300 (Activation)      (None, 512, 45, 60)   0           batchnormalization_312[0][0]     
____________________________________________________________________________________________________
maxpooling2d_59 (MaxPooling2D)   (None, 512, 22, 30)   0           activation_300[0][0]             
____________________________________________________________________________________________________
block5_conv1 (Convolution2D)     (None, 512, 22, 30)   2359808     maxpooling2d_59[0][0]            
____________________________________________________________________________________________________
batchnormalization_313 (BatchNorm(None, 512, 22, 30)   60          block5_conv1[0][0]               
____________________________________________________________________________________________________
activation_301 (Activation)      (None, 512, 22, 30)   0           batchnormalization_313[0][0]   

The issue is here, at size 22 to 44, rather 45


convolution2d_42 (Convolution2D) (None, 512, 22, 30)   2359808     activation_305[0][0]             
____________________________________________________________________________________________________
batchnormalization_318 (BatchNorm(None, 512, 22, 30)   60          convolution2d_42[0][0]           
____________________________________________________________________________________________________
activation_306 (Activation)      (None, 512, 22, 30)   0           batchnormalization_318[0][0]     
____________________________________________________________________________________________________
upsampling2d_52 (UpSampling2D)   (None, 512, 44, 60)   0           activation_306[0][0]             
____________________________________________________________________________________________________
convolution2d_43 (Convolution2D) (None, 512, 44, 60)   2359808     upsampling2d_52[0][0]            
____________________________________________________________________________________________________
batchnormalization_319 (BatchNorm(None, 512, 44, 60)   120         convolution2d_43[0][0]           
____________________________________________________________________________________________________
activation_307 (Activation)      (None, 512, 44, 60)   0           batchnormalization_319[0][0]     
____________________________________________________________________________________________________

It causes this error otherwise continuing to a Reshape() .

ValueError: total size of new array must be unchanged

Relevant issues and each seem to solve it a different way:

  1. Unpooling and deconvolution #378
  2. MaxPooling2D fails to utilize last column in odd dimensional input #2094
@thefiddler
Copy link

You can use MaxPooling2D(..., border_mode="same") to create the correct output shape.

@0bserver07
Copy link
Contributor Author

@thefiddler great Thanks, now that solved my first Issue, I realized I have a problem in the UpSampling2D() only doing 11 to 22 to 44

I might add a ZeroPadding()?

@thefiddler
Copy link

thefiddler commented Jan 1, 2017

Indeed, UpSampling2D() only supports integer factors (2x, 3x etc). You can either add the necessary ZeroPadding2D(), or, alternatively, pad your input before you feed it to the network. For example, instead of an image of (h, w) = (360, 480), resize (or pad) your input to the nearest factor that can be evenly divided by 2 until the bottom of your network.

For example, if your network has 7x MaxPooling2D operations, you need to resize (or pad) your input so that it's divisible by 2**7 == 128, i.e. (h, w) = (384, 512). You can do this by adding a single ZeroPadding2D and Cropping2D statement. Conceptually, it looks like this:

input = Input(shape)
x = ZeroPadding2D((12, 12, 16, 16))(input)
# rest of your network here
x = Cropping2D(((12, 12), (16, 16))(x)
model = Model(input, x)

@0bserver07
Copy link
Contributor Author

Thanks a lot for the detailed answer, I'm wondering how would the ZeroPadding effect the model over all.

I'm essentially implementing the full version of Segnet and in the original paper they don't seem to do either cropping or ZeroPadding, but will definitely try this out.
SegNet: A Deep Convolutional Encoder-Decoder Architecture for Image Segmentation

@stale stale bot added the stale label May 23, 2017
@stale
Copy link

stale bot commented May 23, 2017

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs, but feel free to re-open it if needed.

@stale stale bot closed this as completed Jun 22, 2017
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

No branches or pull requests

2 participants