8

My training data has the form (?,15) where ? is a variable length.

When creating my model I specify this:

inp = Input(shape=(None,15))
conv = Conv1D(32,3,padding='same',activation='relu')(inp)
...

My training data has the shape (35730,?,15).

Checking this in python I get:

X.shape

Outputs: (35730,)

X[0].shape

Outputs: (513, 15)

When I try to fit my model on my training data I get the ValueError:

Error when checking input: expected input_1 to have 3 dimensions, but got array with shape (35730, 1)

I can only train my model by using model.train_on_batch() on a single sample.

How can I solve this? It seems like keras thinks the shape of my input data is (35730, 1) when it actually is (35730, ?, 15)

Is this a bug in keras or did I do something wrong?

I am using the tensorflow backend if that matters. This is keras 2

user3537014
  • 115
  • 1
  • 7

1 Answers1

14

(Edited, according to OP's comment on this question, where they posted this link: https://github.com/fchollet/keras/issues/1920)


Your X is not a single numpy array, it's an array of arrays. (Otherwise its shape would be X.shape=(35730,513,15).

It must be a single numpy array for the fit method. Since you have a variable length, you cannot have a single numpy array containing all your data, you will have to divide it in smaller arrays, each array containing data with the same length.

For that, you should maybe create a dictionary by shape, and loop the dictionary manually (there may be other better ways to do this...):

#code in python 3.5
xByShapes = {}
yByShapes = {}
for itemX,itemY in zip(X,Y):
    if itemX.shape in xByShapes:
        xByShapes[itemX.shape].append(itemX)
        yByShapes[itemX.shape].append(itemY)
    else:
        xByShapes[itemX.shape] = [itemX] #initially a list, because we're going to append items
        yByShapes[itemX.shape] = [itemY]

At the end, you loop this dictionary for training:

for shape in xByShapes:
    model.fit(
              np.asarray(xByShapes[shape]), 
              np.asarray(yByShapes[shape]),...
              )

Masking

Alternatively, you can pad your data so all samples have the same length, using zeros or some dummy value.

Then before anything in your model you can add a Masking layer that will ignore these padded segments. (Warning: some types of layer don't support masking)

Community
  • 1
  • 1
Daniel Möller
  • 84,878
  • 18
  • 192
  • 214
  • 1
    Convolutional layers should not require a static input shape (except for number of channels) and my network is fully convolutional. https://github.com/fchollet/keras/issues/1920 you can read more about that stuff here. I need my data to be of variable length. I have previously used convolutional networks with different sized images and it worked flawlessly. Im gonna mess around with it more today, ill reply here if I find a solution! – user3537014 Sep 11 '17 at 12:04
  • That's great to know!! -- Based on this link, I updated my answer. – Daniel Möller Sep 11 '17 at 12:58
  • Thanks a lot! Really appreciate it! I now understand completely why batch training did not work – user3537014 Sep 11 '17 at 14:05
  • So, if this answer is ok, please mark it as answered, so other users can benefit from this question and answer. – Daniel Möller Sep 11 '17 at 14:26
  • @user3537014 Can you please tell me What should be the my number of epochs in this case as data is training on one very less no of samples in my case it is 4 max at a time? – Rehan Apr 01 '20 at 09:32
  • The answer doesn't exist. You need to test. Ideally you put a huge number and use an `EarlyStopping` callback to stop the training when the validation loss stops decreasing. – Daniel Möller Apr 01 '20 at 14:54