Keras: Variable shaped input to convolutional layers not working anymore

Created on 21 Nov 2016  Â·  8Comments  Â·  Source: keras-team/keras

After some months I updated keras (I was using keras 1.0.5 i think) and now my model can no longer work with input images with different shapes.

Take this small code as an example:

import numpy as np
from keras.models import Sequential
from keras.layers import Convolution2D
m = Sequential()
m.add(Convolution2D(1,3,3, input_shape=(1,10,10)))
m.compile(loss="mae", optimizer="sgd")
c = m.predict(np.random.rand(1,1,10,10).astype('float32'))
c = m.predict(np.random.rand(1,1,20,20).astype('float32'))
>>>Exception: Error when checking : expected convolution2d_input_1 to have shape (None, 1, 10, 10) but got array with shape (1, 1, 20, 20)

I managed to find out that a "image_dim_ordering":"th" had to be added to the keras.json so that It could work with an input size matching the defined one, however I am unable to find any way to correct the problem when actual input size is different. This used to work in previous versions, generating an output of the correct shape.

Most helpful comment

It has nothing to do with any new syntax. In your own code, you should use

m.add(Convolution2D(1,3,3, input_shape=(1, None, None)))

instead of m.add(Convolution2D(1,3,3, input_shape=(1, 10, 10)))

Your code could never have worked on variable-size inputs in the first place...

All 8 comments

I don't understand why you think this should work? You're setting an explicit input shape of 10x10 sized images and then predict on 20x20 images. Surely that should raise an exception? Set input_shape to your largest size and use padding for smaller images.

The code is just an example. It worked before I know it does not seem
intuitive but there is not a way that (I know of ) to leave the input shape
unspecified. And for me padding is tremendously inefficient because I can
have images 20 times bigger than others. The thing is CNNs can deal with
this problem by design and keras also used to. But not anymore...

El 21/11/2016 18:22, "Carl Thomé" [email protected] escribió:

I don't understand why you think this should work? You're setting an
explicit input shape of 10x10 sized images and then trying to predict on
20x20 images. Surely that should raise an exception? Set input_shape to
your largest size and use padding for smaller images.

—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/fchollet/keras/issues/4449#issuecomment-262005517, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AKVGnnKfeVqZU0ph-8MXXe9Q1V_4Rh1yks5rAdM_gaJpZM4K4EAi
.

If you want variable sizes use None, like:

import numpy as np
from keras.models import Model
from keras.layers import Input, Conv2D

i = Input((None, None, 1))
o = Conv2D(1, 3, 3)(i)
model = Model(i, o)
model.compile('sgd', 'mse')

print(model.predict(np.random.rand(1, 10, 10, 1)))
print(model.predict(np.random.rand(1, 32, 16, 1)))

Note that I'm assuming image_dim_ordering: 'tf', meaning that the image channel is the last dimension.

So that was the new syntax. It works now and it makes much more sense when
you read the code. Thank you very much!

2016-11-21 19:02 GMT+01:00 Carl Thomé [email protected]:

If you want variable sizes use None, like (note that I'm assuming image_dim_ordering:
'tf'):

import numpy as npfrom keras.models import Modelfrom keras.layers import Input, Conv2D

i = Input((None, None, 1))
o = Conv2D(1, 3, 3)(i)
model = Model(i, o)
model.compile('sgd', 'mse')
print(model.predict(np.random.rand(1, 10, 10, 1)))print(model.predict(np.random.rand(1, 32, 16, 1)))

—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/fchollet/keras/issues/4449#issuecomment-262017275,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AKVGnjhocfktPSBKERMetYbGVu7jramvks5rAdyygaJpZM4K4EAi
.

Good. Don't forget to close the issue!

It has nothing to do with any new syntax. In your own code, you should use

m.add(Convolution2D(1,3,3, input_shape=(1, None, None)))

instead of m.add(Convolution2D(1,3,3, input_shape=(1, 10, 10)))

Your code could never have worked on variable-size inputs in the first place...

None is giving this error : TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'

This is not working when adding a Flatten Layer afterwords, I am getting this error

ValueError: The shape of the input to "Flatten" is not fully defined (got (None, None, 1). Make sure to pass a complete "input_shape" or "batch_input_shape" argument to the first layer in your model.

When using this code

model = Sequential()
I = Input((None, None, 1))
c = Conv2D(filters=1, kernel_size=(1, 1))(I)
f = Flatten()(c)
o = Dense(10, activation="softmax")(f)
m = Model(I, o)
m.compile(loss=categorical_crossentropy, optimizer=SGD(), metrics=["accuracy"])
Was this page helpful?
0 / 5 - 0 ratings