abutremutante abutremutante - 1 year ago 174
Python Question

Python/Keras/SimpleRNN - Wrong number of dimensions on model.fit

I'm trying to run this SimpleRNN:

model.compile(loss="mse", optimizer="sgd")
model.fit(X=predictor_train, y=target_train, batch_size=len(pred_frame.index),show_accuracy=True)

The error is on model.fit, as you can see below:

File "/Users/file.py", line 1496, in Pred
model.fit(X=predictor_train, y=target_train, batch_size=len(pred_frame.index),show_accuracy=True)
File "/Library/Python/2.7/site-packages/keras/models.py", line 581, in fit
shuffle=shuffle, metrics=metrics)
File "/Library/Python/2.7/site-packages/keras/models.py", line 239, in _fit
outs = f(ins_batch)
File "/Library/Python/2.7/site-packages/keras/backend/theano_backend.py", line 365, in __call__
return self.function(*inputs)
File "/Library/Python/2.7/site-packages/theano/compile/function_module.py", line 513, in __call__
File "/Library/Python/2.7/site-packages/theano/tensor/type.py", line 169, in filter
TypeError: ('Bad input argument to theano function with name "/Library/Python/2.7/site-packages/keras/backend/theano_backend.py:362" at index 0(0-based)', 'Wrong number of dimensions: expected 3, got 2 with shape (88, 88).')

Well, the error is telling me it's got the wrong number of dimensions, it should be 3 and it has only got 2. My question is: what are the dimensions it is referring to?

Answer Source

You are trying to run a RNN. This means that you want to include previous time steps in your calculation. In order to do so, you have to preprocess your data before giving it to the SimpleRNN layer.

For simplicity, let us assume that instead of 88 samples with 88 features each you have 8 samples with 4 features each. Now, when using a RNN you will have to decide on a maximum for the backpropagation (i.e. number of previous time steps that are included in the calculation). In this case, you could choose to include a maximum of 2 previous time steps. Therefore, for the calculation of the weights of the RNN you will have to provide at each time step the input of the current time step (with its 4 features) and the input of the 2 previous time steps (with 4 features each). Just like in this visualization:

sequence    sample0  sample1  sample2  sample3  sample4  sample5  sample6 sample7       
   0        |-----------------------|
   1                 |-----------------------|
   2                          |-----------------------|
   3                                   |-----------------------|
   4                                             |----------------------|
   5                                                      |----------------------|

So instead of giving a (nb_samples, nb_features) matrix as an input to the SimpleRNN, you will have to give it a (nb_sequences, nb_timesteps, nb_features) shaped input. In this example, it means that instead of giving a (8x4) input you give it a (5x3x4) input.

The keras Embedding layer might do this job but in this case you can also write a short code for it:

input = np.random.rand(8,4)
nb_timesteps = 3    # 2 (previous) + 1 (current)
nb_sequences = input.shape[0] - nb_timesteps    #8-3=5

input_3D = np.array([input[i:i+nb_timesteps] for i in range(nb_sequences)])