Masukan urutan lapisan tidak sesuai dengan kesalahan lapisan: bentuk di LSTM
Saya baru mengenal jaringan neural dan ingin menggunakannya untuk membandingkan dengan metode pembelajaran mesin lainnya. Saya memiliki data deret waktu multivariat dengan rentang waktu sekitar dua tahun. Saya ingin memprediksi 'y' untuk beberapa hari ke depan berdasarkan variabel lain menggunakan LSTM. Hari terakhir data saya adalah 2020-07-31.
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
Untuk melatih model LSTM saya juga membagi data menjadi data train dan test.
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
Karena saya bekerja dengan LSTM, diperlukan beberapa penskalaan:
scaler = MinMaxScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
Sekarang, ke bagian yang sulit: modelnya.
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)
Namun, saya menerima kesalahan berikut ini:
ValueError: Input 0 of layer sequential_11 is incompatible with the layer: expected ndim=3, found
ndim=2. Full shape received: [None, 5]
Saya tidak mengerti bagaimana kita memilih parameter atau bentuk input. Saya telah melihat beberapa video dan membaca beberapa halaman Github dan semua orang tampaknya menjalankan LSTM dengan cara yang berbeda, yang membuatnya semakin sulit untuk diterapkan. Kesalahan sebelumnya mungkin berasal dari bentuk tetapi selain itu apakah semuanya benar? Dan bagaimana cara memperbaikinya agar berfungsi? Terima kasih
EDIT: Ini pertanyaan serupa tidak memecahkan masalah saya .. Saya sudah mencoba solusi dari sana
x_train = X_train_scaled.reshape(-1, 1, 5)
x_test = X_test_scaled.reshape(-1, 1, 5)
(X_test dan y_test saya hanya memiliki satu kolom). Dan solusinya juga sepertinya tidak berhasil. Saya mendapatkan kesalahan ini sekarang:
ValueError: Input 0 is incompatible with layer sequential_22: expected shape=
(None, None, 1), found shape=[None, 1, 5]
Jawaban
MEMASUKKAN:
Masalahnya adalah bahwa Anda memodelkan mengharapkan input bentuk 3D (batch, sequence, features)
tetapi Anda X_train
sebenarnya adalah potongan bingkai data, jadi array 2D:
X1=df_train[['day_of_month','day_of_week','month','quarter','holidays']]
X_train, y_train =X1, y1
Saya berasumsi kolom Anda seharusnya menjadi fitur Anda, jadi yang biasanya Anda lakukan adalah "tumpukan irisan" dari df Anda sehingga Anda X_train
terlihat seperti itu:
Berikut adalah kumpulan bentuk dummy 2D (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.]])
Anda dapat membentuknya kembali untuk menambahkan dimensi batch, misalnya (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.]]])
Data yang sama, tetapi disajikan dengan cara yang berbeda. Sekarang dalam contoh ini, batch = 15
dan sequence = 1
, saya tidak tahu berapa panjang urutan dalam kasus Anda, tetapi bisa apa saja.
MODEL :
Sekarang dalam model Anda, keras
input_shape
perkirakan (batch, sequence, features)
, ketika Anda meneruskan ini:
input_shape=(X_train.shape[1], 1)
Inilah yang Anda model lihat: (None, Sequence = X_train.shape[1] , num_features = 1)
None
adalah untuk dimensi batch. Saya tidak berpikir itulah yang Anda coba lakukan begitu Anda telah membentuk kembali Anda juga harus mengoreksi input_shape
agar sesuai dengan array baru.
Ini adalah masalah regresi multivariat yang Anda selesaikan menggunakan LSTM. Sebelum melompat ke dalam kode, mari kita lihat apa artinya
Pernyataan masalah:
- Anda memiliki
5
fiturholidays, day_of_month, day_of_week,month,quarter
per hari selamak
berhari - hari - Untuk setiap hari n, diberi fitur katakanlah 'm' hari terakhir Anda ingin memprediksi hari ke
y
-n
th
Membuat kumpulan data jendela:
- Kita harus memutuskan berapa hari kita ingin memberi makan model kita. Ini disebut panjang urutan (mari kita perbaiki menjadi 3 untuk contoh ini).
- Kita harus membagi hari dengan panjang urutan untuk membuat kumpulan data kereta dan pengujian. Hal ini dilakukan dengan menggunakan sliding window dimana ukuran jendela merupakan panjang urutan.
- Seperti yang Anda lihat, tidak ada prediksi yang tersedia oleh
p
rekaman terakhir di manap
panjang urutannya. - Kami akan melakukan pembuatan set data jendela menggunakan
timeseries_dataset_from_array
metode. - Untuk informasi lebih lanjut, ikuti dokumen tf resmi .
Model LSTM
Jadi bergambar apa yang ingin kami capai adalah tunjukkan di bawah ini:
Untuk setiap sel LSTM yang membuka gulungan, kami meneruskan 5 fitur hari ini, dan kami membuka gulungan dalam m
waktu di mana m
panjang urutannya. Kami memprediksi y
hari terakhir.
Kode:
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)
Keluaran:
(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>