keras-team / keras

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

Simple Convolution1D generating dimension error #1752

Closed thomasj02 closed 7 years ago

thomasj02 commented 8 years ago

I'm sure this is something I'm doing wrong, but I can't figure out what it is.

I can train a simple MLP fine, but I'm having problems when I try to train a 1D CNN:

My data input shape is (1076273, 252), so 1076273 samples of dimension 252

model = Sequential()
model.add(Convolution1D(
        nb_filter=21, 
        filter_length=3, 
        input_dim=1,  # Should this be 1 or 252?
        input_length=input_size,
        activation='relu',
        init='uniform'))
model.add(MaxPooling1D(pool_length=2))
model.add(Dropout(0.2))

model.add(Flatten())
model.add(Dense(64, activation='relu'))

model.add(Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy',
              optimizer='adam',
              class_mode='binary')

history = model.fit(train_data, train_labels, batch_size=128, nb_epoch=1, 
                    validation_data=(validation_data, validation_labels))

This gives:

TypeError: ('Bad input argument to theano function with name "build/bdist.linux-x86_64/egg/keras/backend/theano_backend.py:380" at index 0(0-based)', 'Wrong number of dimensions: expected 3, got 2 with shape (128, 252).')

What am I doing wrong? Why is theano expecting 3 dimensions?

thomasj02 commented 8 years ago

OK, apparently passing train_data.reshape(train_data.shape + (1,)) makes it work. This is not intuitive. This should probably be added to the docs

keunwoochoi commented 8 years ago

Have you checked the document? I don't know if it's intuitive or not, but they are specified in the document, according to which, you should provide either input_dim as 252 or input_shape as (1,252).

thomasj02 commented 8 years ago

Sorry, that comment in the code was not related to the actual issue, it was just something I was playing with to try to debug the problem.

The problem appears to be (I think) that if the first layer is a Convolution1D layer then the input needs to be a 3-dimensional array. This is in contrast to a normal MLP network, where the input can be (must be?) a 2-dimensional array

leocnj commented 8 years ago

@thomasj02 Your understanding is right. CNN-1D needs a 3D tensor as input. In your example, it will be a numpy array shaped as (1076273, 252, 1). You need reshape your input to be such 3D tensor and need use "input_shape = (252,1)" when calling the CNN-1D function.

nalamotse1 commented 8 years ago

Hello guys, I am working on a time series data, fitting it into a 1D convolutional neural network but I seem to not find the right compile model. My net is configured in the following way: model = Sequential()
model.add(Convolution1D(21, 1, 7,activation='relu',init='uniform')) model.add(MaxPooling1D(pool_length=2)) model.add(Dropout(0.2))

model.add(Flatten()) model.add(Dense(7,1, activation='sigmoid'))

nb_timesteps = 7 # 2 (previous) + 1 (current) nb_sequences = input_var.shape[0] - nb_timesteps #8-3=5

input_3D = np.array([input_var[i:i+nb_timesteps] for i in range(nb_sequences)]) model.compile(loss='mean_squared_error', optimizer='adadelta') model.fit(input_3D, targetValue, batch_size=450, nb_epoch=10, validation_split=0.05,show_accuracy=True,verbose = 0)

And I do get this kind of error: model.fit(input_3D, targetValue, batch_size=450, nb_epoch=10, validation_split=0.05,show_accuracy=True,verbose = 0) File "build/bdist.linux-x86_64/egg/keras/models.py", line 490, in fit File "build/bdist.linux-x86_64/egg/keras/models.py", line 211, in _fit File "/usr/local/lib/python2.7/dist-packages/Theano-0.8.0rc1-py2.7.egg/theano/compile/function_module.py", line 871, in call storage_map=getattr(self.fn, 'storage_map', None)) File "/usr/local/lib/python2.7/dist-packages/Theano-0.8.0rc1-py2.7.egg/theano/gof/link.py", line 314, in raise_with_op reraise(exc_type, exc_value, exc_trace) File "/usr/local/lib/python2.7/dist-packages/Theano-0.8.0rc1-py2.7.egg/theano/compile/function_module.py", line 859, in call outputs = self.fn()