계층 순차 입력이 계층과 호환되지 않음 : LSTM의 모양 오류

Dec 22 2020

저는 신경망을 처음 접했고 다른 기계 학습 방법과 비교하기 위해 신경망을 사용하고 싶습니다. 약 2 년 범위의 다변량 시계열 데이터가 있습니다. LSTM을 사용하는 다른 변수를 기반으로 향후 며칠 동안 'y'를 예측하고 싶습니다. 내 데이터의 마지막 날은 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

입력:

문제는 모델이 모양의 3D 입력을 기대 (batch, sequence, features)하지만 X_train실제로는 데이터 프레임의 조각이므로 2D 배열입니다.

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

나는 당신의 칼럼이 당신의 특징이라고 가정하고, 그래서 당신이 일반적으로 할 일은 당신 X_train이 다음과 같이 보이 도록 당신의 df의 "스택 슬라이스" 입니다.

다음은 더미 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.]])

예를 들어 배치 차원을 추가하기 위해 모양을 변경할 수 있습니다 (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 = 15sequence = 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,quarterk
  • 어느 날 N, 당신은 예측하고자하는 말의 기능에 주어진 마지막 'm'일 yn일 일

창 데이터 세트 만들기 :

  • 먼저 모델에 공급할 일수를 결정해야합니다. 이를 시퀀스 길이라고합니다 (이 예에서는 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>