keras-team / keras

Deep Learning for humans
http://keras.io/
Apache License 2.0
61.92k stars 19.45k forks source link

Variable shaped input to convolutional layers not working anymore #4449

Closed jitoledo closed 7 years ago

jitoledo commented 7 years ago

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.

carlthome commented 7 years ago

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.

jitoledo commented 7 years ago

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é" notifications@github.com 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 .

carlthome commented 7 years ago

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.

jitoledo commented 7 years ago

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é notifications@github.com:

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 .

carlthome commented 7 years ago

Good. Don't forget to close the issue!

fchollet commented 7 years ago

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...

avinres commented 6 years ago

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

thebeancounter commented 5 years ago

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"])