web-dev-qa-db-fra.com

Pourquoi ai-je une erreur Keras LSTM RNN input_shape?

Je continue à recevoir une erreur input_shape du code suivant.

from keras.models import Sequential
from keras.layers.core import Dense, Activation, Dropout
from keras.layers.recurrent import LSTM

def _load_data(data):
    """
    data should be pd.DataFrame()
    """
    n_prev = 10
    docX, docY = [], []
    for i in range(len(data)-n_prev):
        docX.append(data.iloc[i:i+n_prev].as_matrix())
        docY.append(data.iloc[i+n_prev].as_matrix())
    if not docX:
        pass
    else:
        alsX = np.array(docX)
        alsY = np.array(docY)
        return alsX, alsY

X, y = _load_data(dframe)
poi = int(len(X) * .8)
X_train = X[:poi]
X_test = X[poi:]
y_train = y[:poi]
y_test = y[poi:]

input_dim = 3

Tout ce qui précède fonctionne bien. C'est là que ça tourne mal.

in_out_neurons = 2
hidden_neurons = 300
model = Sequential()
#model.add(Masking(mask_value=0, input_shape=(input_dim,)))
model.add(LSTM(in_out_neurons, hidden_neurons, return_sequences=False, input_shape=(len(full_data),)))
model.add(Dense(hidden_neurons, in_out_neurons))
model.add(Activation("linear"))
model.compile(loss="mean_squared_error", optimizer="rmsprop")
model.fit(X_train, y_train, nb_Epoch=10, validation_split=0.05)

Il retourne cette erreur.

Exception: Invalid input shape - Layer expects input ndim=3, was provided with input shape (None, 10320)

Lorsque je vérifie le site Web il indique de spécifier un tuple "(par exemple (100, pour des entrées de 100 dimensions))."

Cela étant dit, mon ensemble de données est constitué d'une colonne d'une longueur de 10320. J'imagine que cela signifie que je devrais mettre (10320,) dans la forme input_shape, mais j'obtiens quand même l'erreur. Quelqu'un a-t-il une solution?

13
NickTheInventor

Je crois comprendre que votre entrée et votre sortie sont des vecteurs unidimensionnels. L'astuce consiste à les remodeler selon les exigences de Keras:

from keras.models import Sequential
from keras.layers.core import Dense, Activation, Dropout
from keras.layers.recurrent import LSTM
import numpy as np

X= np.random.Rand(1000)
y = 2*X

poi = int(len(X) * .8)
X_train = X[:poi]
y_train = y[:poi]

X_test = X[poi:]
y_test = y[poi:]

# you have to change your input shape (nb_samples, timesteps, input_dim)
X_train = X_train.reshape(len(X_train), 1, 1)
# and also the output shape (note that the output *shape* is 2 dimensional)
y_train = y_train.reshape(len(y_train), 1)


#in_out_neurons = 2 
in_out_neurons = 1

hidden_neurons = 300
model = Sequential()
#model.add(Masking(mask_value=0, input_shape=(input_dim,)))
model.add(LSTM(hidden_neurons, return_sequences=False, batch_input_shape=X_train.shape))
# only specify the output dimension
model.add(Dense(in_out_neurons))
model.add(Activation("linear"))
model.compile(loss="mean_squared_error", optimizer="rmsprop")
model.fit(X_train, y_train, nb_Epoch=10, validation_split=0.05)

# calculate test set MSE
preds = model.predict(X_test).reshape(len(y_test))
MSE = np.mean((preds-y_test)**2)

Voici les points clés:

  • lorsque vous ajoutez votre premier calque, vous devez spécifier le nombre de nœuds masqués et votre forme en entrée. Les calques correspondants ne nécessitent pas la forme en entrée car ils peuvent en déduire à partir des nœuds cachés du calque précédent
  • De même, pour votre couche de sortie, vous seulement spécifiez le nombre de nœuds de sortie

J'espère que cela t'aides.

4
Radix

Quelques informations supplémentaires: lorsque vous utilisez RNN (comme LSTM) avec des séquences de longueur variable, vous devez prendre en compte le format de vos données.

Lorsque vous regroupez des séquences afin de les transmettre à la méthode d’ajustement, keras essaiera de construire une matrice d’échantillons, ce qui implique que toutes les séquences en entrée doivent avoir la même taille, sinon vous n’aurez pas une matrice de la dimension correcte.

Il y a plusieurs solutions possibles:

  1. formez votre réseau à l'aide d'échantillons un à un (en utilisant fit_generator par exemple)
  2. touchez toutes vos séquences pour qu'elles aient la même taille
  3. groupez les séquences par taille (éventuellement en les remplissant) et entraînez votre réseau groupe par groupe (là encore, en utilisant l'ajustement basé sur un générateur)

La troisième solution correspond à la stratégie la plus courante à taille variable. Et si vous complétez des séquences (deuxième ou troisième solution), vous voudrez peut-être ajouter un calque de masquage en entrée.

Si vous n'êtes pas sûr, essayez d’imprimer la forme de vos données (en utilisant l’attribut shape du tableau numpy.)

Vous devrez peut-être consulter: https://keras.io/preprocessing/sequence/ (pad_sequences) et https://keras.io/layers/core/#masking

2
Marwan Burelle

Voici la version de travail avec Keras 2.0.0 , Code de radix modifié

from keras.models import Sequential
from keras.layers.core import Dense, Activation, Dropout
from keras.layers.recurrent import LSTM
import numpy as np

X= np.random.Rand(1000)
y = 2 * X

poi = int(len(X) * .8)
X_train = X[:poi]
y_train = y[:poi]

X_test = X[poi:]
y_test = y[poi:]

# you have to change your input shape (nb_samples, timesteps, input_dim)
X_train = X_train.reshape(len(X_train), 1, 1)
# and also the output shape (note that the output *shape* is 2 dimensional)
y_train = y_train.reshape(len(y_train), 1)

# Change test data's dimension also.
X_test = X_test.reshape(len(X_test),1,1)
y_test = y_test.reshape(len(y_test),1)


#in_out_neurons = 2
in_out_neurons = 1

hidden_neurons = 300
model = Sequential()
# model.add(Masking(mask_value=0, input_shape=(input_dim,)))
# Remove batch_input_shape and add input_shape = (1,1) - Imp change for Keras 2.0.0
model.add(LSTM(hidden_neurons, return_sequences=False, input_shape=(X_train.shape[1],X_train.shape[2])))
# only specify the output dimension
model.add(Dense(in_out_neurons))
model.add(Activation("linear"))
model.compile(loss="mean_squared_error", optimizer="rmsprop")
model.summary()
model.fit(X_train, y_train, epochs=10, validation_split=0.05)

# calculate test set MSE
preds = model.predict(X_test).reshape(len(y_test))
print(preds)
MSE = np.mean((preds-y_test)**2)
print('MSE ', MSE)
2
Shakti

Essayez d'utiliser le calque LSTM sans spécifier la forme en entrée. Laissez Keras faire le travail pour vous. Je pense que vous avez également commenté le masquage parce que vous rencontrez un problème similaire. Je l'ai déjà fait face et il s'avère que input_shape = (time_steps, input_dim). Je pense que cela se produit en raison de la nouvelle inférence de forme automatique de Keras.

0
mxy