อินพุตของลำดับชั้นไม่เข้ากันกับเลเยอร์: รูปร่างผิดพลาดใน LSTM

Dec 22 2020

ฉันเพิ่งเคยใช้เครือข่ายประสาทเทียมและต้องการใช้เพื่อเปรียบเทียบกับวิธีการเรียนรู้ของเครื่องอื่น ๆ ฉันมีข้อมูลอนุกรมเวลาหลายตัวแปรที่มีช่วงเวลาประมาณสองปี ฉันต้องการทำนาย 'y' ในอีกสองสามวันข้างหน้าโดยอาศัยตัวแปรอื่น ๆ โดยใช้ LSTM วันสุดท้ายของข้อมูลของฉันคือ 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

ในการฝึกโมเดล LSTM ฉันยังแยกข้อมูลออกเป็นข้อมูลรถไฟและข้อมูลการทดสอบ

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

เนื่องจากฉันทำงานกับ LSTM จึงจำเป็นต้องมีการปรับขนาด:

scaler = MinMaxScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

ตอนนี้เข้าสู่ส่วนที่ยาก: แบบจำลอง

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)

อย่างไรก็ตามฉันได้รับข้อผิดพลาดต่อไปนี้:

ValueError: Input 0 of layer sequential_11 is incompatible with the layer: expected ndim=3, found 
ndim=2. Full shape received: [None, 5]

ฉันไม่เข้าใจว่าเราเลือกพารามิเตอร์หรือรูปร่างของอินพุตอย่างไร ฉันเคยเห็นวิดีโอและอ่านหน้า Github และทุกคนดูเหมือนจะใช้ LSTM ด้วยวิธีที่แตกต่างกันซึ่งทำให้ยากต่อการใช้งานมากขึ้น ข้อผิดพลาดก่อนหน้านี้น่าจะมาจากรูปร่าง แต่นอกเหนือจากนั้นคืออย่างอื่นใช่หรือไม่? และจะแก้ไขให้ใช้งานได้อย่างไร? ขอบคุณ

แก้ไข: คำถามที่คล้ายกันนี้ไม่สามารถแก้ปัญหาของฉันได้ฉันได้ลองวิธีแก้ปัญหาจากที่นั่นแล้ว

x_train = X_train_scaled.reshape(-1, 1, 5)
x_test  = X_test_scaled.reshape(-1, 1, 5)

(X_test และ y_test ของฉันมีเพียงคอลัมน์เดียว) และวิธีแก้ปัญหาก็ดูเหมือนจะไม่ได้ผล ฉันได้รับข้อผิดพลาดนี้ทันที:

ValueError: Input 0 is incompatible with layer sequential_22: expected shape= 
(None, None, 1), found shape=[None, 1, 5]

คำตอบ

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

อินพุต:

ปัญหาคือโมเดลของคุณคาดว่าจะมีอินพุต 3 มิติของรูปร่าง(batch, sequence, features)แต่X_trainจริงๆแล้วของคุณเป็นชิ้นส่วนของเฟรมข้อมูลดังนั้นอาร์เรย์ 2D:

X1=df_train[['day_of_month','day_of_week','month','quarter','holidays']]
X_train, y_train =X1, y1

ฉันคิดว่าคอลัมน์ของคุณควรเป็นคุณลักษณะของคุณดังนั้นสิ่งที่คุณมักจะทำคือ "สแต็กสไลซ์" ของ df ของคุณเพื่อให้คุณX_trainมีลักษณะดังนี้:

นี่คือชุดข้อมูล 2 มิติจำลองของรูปร่าง(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.]])

คุณสามารถปรับรูปร่างใหม่เพื่อเพิ่มมิติชุดงานตัวอย่างเช่น(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.]]])

ข้อมูลเดียวกัน แต่นำเสนอในรูปแบบที่แตกต่างกัน ตอนนี้ในตัวอย่างนี้batch = 15และsequence = 1ฉันไม่รู้ว่าความยาวของลำดับในกรณีของคุณคืออะไร แต่อาจเป็นอะไรก็ได้

รุ่น:

ตอนนี้ในโมเดลของคุณkeras input_shapeคาดว่า(batch, sequence, features)เมื่อคุณผ่านสิ่งนี้:

input_shape=(X_train.shape[1], 1)

นี่คือสิ่งที่โมเดลที่คุณเห็น: (None, Sequence = X_train.shape[1] , num_features = 1) Noneสำหรับมิติแบทช์ ฉันไม่คิดว่านั่นคือสิ่งที่คุณพยายามทำเช่นนั้นเมื่อคุณปรับรูปร่างใหม่แล้วคุณควรแก้ไขinput_shapeให้ตรงกับอาร์เรย์ใหม่ด้วย

1 mujjiga Dec 24 2020 at 21:27

เป็นปัญหาการถดถอยหลายตัวแปรที่คุณกำลังแก้โดยใช้ LSTM ก่อนที่จะกระโดดลงไปในโค้ดให้ดูว่ามันหมายถึงอะไร

คำชี้แจงปัญหา:

  • คุณมี5คุณสมบัติholidays, day_of_month, day_of_week,month,quarterต่อวันเป็นkเวลาหลายวัน
  • สำหรับวัน n ใด ๆ ที่กำหนดคุณสมบัติของการพูดสุดท้าย 'm' วันที่คุณต้องการในการทำนายyของnวันที่

การสร้างชุดข้อมูลหน้าต่าง:

  • เราจำเป็นต้องตัดสินใจเกี่ยวกับจำนวนวันที่เราต้องการให้อาหารแก่นางแบบของเรา สิ่งนี้เรียกว่าความยาวของลำดับ (ให้แก้ไขเป็น 3 สำหรับตัวอย่างนี้)
  • เราต้องแบ่งวันของความยาวของลำดับเพื่อสร้างรถไฟและชุดข้อมูลทดสอบ ทำได้โดยใช้หน้าต่างบานเลื่อนที่ขนาดของหน้าต่างเป็นความยาวของลำดับ
  • อย่างที่คุณเห็นไม่มีการคาดคะเนใด ๆ ในpระเบียนสุดท้ายที่pความยาวของลำดับอยู่ที่ใด
  • เราจะทำการสร้างชุดข้อมูลหน้าต่างโดยใช้timeseries_dataset_from_arrayวิธีการ
  • สำหรับสิ่งล่วงหน้ามากกว่าทำตาม TF อย่างเป็นทางการเอกสาร

LSTM รุ่น

ดังนั้นภาพที่เราต้องการบรรลุจึงแสดงไว้ด้านล่าง:

สำหรับการคลายเซลล์ LSTM แต่ละเซลล์เราจะส่งผ่านคุณสมบัติ 5 ประการของวันและเราจะคลายmเวลาโดยที่mความยาวของลำดับคือ เรากำลังคาดการณ์yวันสุดท้าย

รหัส:

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)

เอาท์พุต:

(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>