Die Eingabe der Layersequenz ist nicht mit dem Layer: Shapes-Fehler in LSTM kompatibel
Ich bin neu in neuronalen Netzen und möchte sie verwenden, um sie mit anderen Methoden des maschinellen Lernens zu vergleichen. Ich habe multivariate Zeitreihendaten mit einem Bereich von ungefähr zwei Jahren. Ich möchte 'y' für die nächsten Tage basierend auf den anderen Variablen unter Verwendung von LSTM vorhersagen. Der letzte Tag meiner Daten ist der 31.07.2020.
df.tail()
y holidays day_of_month day_of_week month quarter
Date
2020-07-27 32500 0 27 0 7 3
2020-07-28 33280 0 28 1 7 3
2020-07-29 31110 0 29 2 7 3
2020-07-30 37720 0 30 3 7 3
2020-07-31 32240 0 31 4 7 3
Um das LSTM-Modell zu trainieren, habe ich die Daten auch in Zug- und Testdaten aufgeteilt.
from sklearn.model_selection import train_test_split
split_date = '2020-07-27' #to predict the next 4 days
df_train = df.loc[df.index <= split_date].copy()
df_test = df.loc[df.index > split_date].copy()
X1=df_train[['day_of_month','day_of_week','month','quarter','holidays']]
y1=df_train['y']
X2=df_test[['day_of_month','day_of_week','month','quarter','holidays']]
y2=df_test['y']
X_train, y_train =X1, y1
X_test, y_test = X2,y2
Da ich mit LSTM arbeite, ist eine gewisse Skalierung erforderlich:
scaler = MinMaxScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
Nun zum schwierigen Teil: dem Modell.
num_units=50
activation_function = 'sigmoid'
optimizer = 'adam'
loss_function = 'mean_squared_error'
batch_size = 10
num_epochs = 100
# Initialize the RNN
regressor = Sequential()
# Adding the input layer and the LSTM layer
regressor.add(LSTM(units = num_units, return_sequences=True ,activation = activation_function,
input_shape=(X_train.shape[1], 1)))
# Adding the output layer
regressor.add(Dense(units = 1))
# Compiling the RNN
regressor.compile(optimizer = optimizer, loss = loss_function)
# Using the training set to train the model
regressor.fit(X_train_scaled, y_train, batch_size = batch_size, epochs = num_epochs)
Ich erhalte jedoch den folgenden Fehler:
ValueError: Input 0 of layer sequential_11 is incompatible with the layer: expected ndim=3, found
ndim=2. Full shape received: [None, 5]
Ich verstehe nicht, wie wir die Parameter oder die Form der Eingabe auswählen. Ich habe einige Videos gesehen und einige Github-Seiten gelesen, und jeder scheint LSTM auf eine andere Art und Weise auszuführen, was die Implementierung noch schwieriger macht. Der vorherige Fehler kommt wahrscheinlich von der Form, aber ansonsten ist alles andere richtig? Und wie kann ich das beheben, um zu funktionieren? Vielen Dank
EDIT: Diese ähnliche Frage löst mein Problem nicht. Ich habe die Lösung von dort versucht
x_train = X_train_scaled.reshape(-1, 1, 5)
x_test = X_test_scaled.reshape(-1, 1, 5)
(Mein X_test und y_test haben nur eine Spalte). Und die Lösung scheint auch nicht zu funktionieren. Ich erhalte jetzt diesen Fehler:
ValueError: Input 0 is incompatible with layer sequential_22: expected shape=
(None, None, 1), found shape=[None, 1, 5]
Antworten
EINGANG:
Das Problem ist, dass Sie beim Modell eine 3D-Eingabe der Form erwarten, (batch, sequence, features)
aber X_train
tatsächlich ein Teil des Datenrahmens ist, also ein 2D-Array:
X1=df_train[['day_of_month','day_of_week','month','quarter','holidays']]
X_train, y_train =X1, y1
Ich gehe davon aus, dass Ihre Spalten Ihre Features sein sollen. Normalerweise würden Sie also "Slices" Ihres df stapeln, damit Sie ungefähr so X_train
aussehen:
Hier ist ein Dummy-2D-Datensatz der Form (15,5)
:
data = np.zeros((15,5))
array([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]])
Sie können es umformen, um eine Stapeldimension hinzuzufügen, zum Beispiel (15,1,5)
:
data = data[:,np.newaxis,:]
array([[[0., 0., 0., 0., 0.]],
[[0., 0., 0., 0., 0.]],
[[0., 0., 0., 0., 0.]],
[[0., 0., 0., 0., 0.]],
[[0., 0., 0., 0., 0.]],
[[0., 0., 0., 0., 0.]],
[[0., 0., 0., 0., 0.]],
[[0., 0., 0., 0., 0.]],
[[0., 0., 0., 0., 0.]],
[[0., 0., 0., 0., 0.]],
[[0., 0., 0., 0., 0.]],
[[0., 0., 0., 0., 0.]],
[[0., 0., 0., 0., 0.]],
[[0., 0., 0., 0., 0.]],
[[0., 0., 0., 0., 0.]]])
Gleiche Daten, aber anders dargestellt. Nun, in diesem Beispiel, batch = 15
und sequence = 1
ich weiß nicht, wie lang die Sequenz in Ihrem Fall ist, aber es kann alles sein.
MODELL:
keras
input_shape
Erwarten (batch, sequence, features)
Sie jetzt in Ihrem Modell , wenn Sie dies bestehen:
input_shape=(X_train.shape[1], 1)
Folgendes sieht Ihr Modell: Dies gilt (None, Sequence = X_train.shape[1] , num_features = 1)
None
für die Batch-Dimension. Ich denke nicht, dass Sie dies versuchen, sobald Sie sich umgeformt haben, sollten Sie auch korrigieren input_shape
, um mit dem neuen Array übereinzustimmen.
Es ist ein multivariates Regressionsproblem, das Sie mit LSTM lösen. Bevor Sie in den Code springen, lassen Sie uns sehen, was es bedeutet
Problemstellung:
- Sie haben tagelang
5
Funktionholidays, day_of_month, day_of_week,month,quarter
pro Tagk
- Für jeden Tag n möchten Sie angesichts der Merkmale der letzten 'm' Tage
y
denn
Tag des Tages vorhersagen
Fensterdatensatz erstellen:
- Wir müssen zunächst entscheiden, wie viele Tage wir unserem Modell zuführen möchten. Dies wird als Sequenzlänge bezeichnet (in diesem Beispiel können wir sie auf 3 festlegen).
- Wir müssen die Tage der Sequenzlänge aufteilen, um den Zug- und Testdatensatz zu erstellen. Dies erfolgt mithilfe eines Schiebefensters, bei dem die Fenstergröße der Sequenzlänge entspricht.
- Wie Sie sehen können, sind für die letzten
p
Datensätze keine Vorhersagen verfügbar, bei denenp
es sich um die Sequenzlänge handelt. - Wir werden die Fenster-Dataset-Erstellung mit der
timeseries_dataset_from_array
Methode durchführen. - Für weitere Informationen folgen Sie den offiziellen tf- Dokumenten .
LSTM-Modell
Das Bild, was wir erreichen wollen, ist unten dargestellt:

Für jedes Abrollen der LSTM-Zelle übergeben wir die 5 Merkmale des Tages und rollen uns in der m
Zeit ab, in der m
sich die Sequenzlänge befindet. Wir sagen y
den letzten Tag voraus .
Code:
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers, models
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
# Model
regressor = models.Sequential()
regressor.add(layers.LSTM(5, return_sequences=True))
regressor.add(layers.Dense(1))
regressor.compile(optimizer='sgd', loss='mse')
# Dummy data
n = 10000
df = pd.DataFrame(
{
'y': np.arange(n),
'holidays': np.random.randn(n),
'day_of_month': np.random.randn(n),
'day_of_week': np.random.randn(n),
'month': np.random.randn(n),
'quarter': np.random.randn(n),
}
)
# Train test split
train_df, test_df = train_test_split(df)
print (train_df.shape, test_df.shape)\
# Create y to be predicted
# given last n days predict todays y
# train data
sequence_length = 3
y_pred = train_df['y'][sequence_length-1:].values
train_df = train_df[:-2]
train_df['y_pred'] = y_pred
# Validataion data
y_pred = test_df['y'][sequence_length-1:].values
test_df = test_df[:-2]
test_df['y_pred'] = y_pred
# Create window datagenerators
# Train data generator
train_X = train_df[['holidays','day_of_month','day_of_week','month','month']]
train_y = train_df['y_pred']
train_dataset = tf.keras.preprocessing.timeseries_dataset_from_array(
train_X, train_y, sequence_length=sequence_length, shuffle=True, batch_size=4)
# Validation data generator
test_X = test_df[['holidays','day_of_month','day_of_week','month','month']]
test_y = test_df['y_pred']
test_dataset = tf.keras.preprocessing.timeseries_dataset_from_array(
test_X, test_y, sequence_length=sequence_length, shuffle=True, batch_size=4)
# Finally fit the model
regressor.fit(train_dataset, validation_data=test_dataset, epochs=3)
Ausgabe:
(7500, 6) (2500, 6)
Epoch 1/3
1874/1874 [==============================] - 8s 3ms/step - loss: 9974697.3664 - val_loss: 8242597.5000
Epoch 2/3
1874/1874 [==============================] - 6s 3ms/step - loss: 8367530.7117 - val_loss: 8256667.0000
Epoch 3/3
1874/1874 [==============================] - 6s 3ms/step - loss: 8379048.3237 - val_loss: 8233981.5000
<tensorflow.python.keras.callbacks.History at 0x7f3e94bdd198>