Masukan urutan lapisan tidak sesuai dengan kesalahan lapisan: bentuk di LSTM

Dec 22 2020

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

2 YoanB.M.Sc Dec 22 2020 at 21:18

MEMASUKKAN:

Masalahnya adalah bahwa Anda memodelkan mengharapkan input bentuk 3D (batch, sequence, features)tetapi Anda X_trainsebenarnya 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_trainterlihat 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 = 15dan sequence = 1, saya tidak tahu berapa panjang urutan dalam kasus Anda, tetapi bisa apa saja.

MODEL :

Sekarang dalam model Anda, keras input_shapeperkirakan (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) Noneadalah untuk dimensi batch. Saya tidak berpikir itulah yang Anda coba lakukan begitu Anda telah membentuk kembali Anda juga harus mengoreksi input_shapeagar sesuai dengan array baru.

1 mujjiga Dec 24 2020 at 21:27

Ini adalah masalah regresi multivariat yang Anda selesaikan menggunakan LSTM. Sebelum melompat ke dalam kode, mari kita lihat apa artinya

Pernyataan masalah:

  • Anda memiliki 5fitur holidays, day_of_month, day_of_week,month,quarterper hari selama kberhari - hari
  • Untuk setiap hari n, diberi fitur katakanlah 'm' hari terakhir Anda ingin memprediksi hari ke y- nth

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 prekaman terakhir di mana ppanjang urutannya.
  • Kami akan melakukan pembuatan set data jendela menggunakan timeseries_dataset_from_arraymetode.
  • 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 mwaktu di mana mpanjang urutannya. Kami memprediksi yhari 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>