परत अनुक्रमिक का इनपुट परत के साथ असंगत है: LSTM में त्रुटि आकार

Dec 22 2020

मैं तंत्रिका नेटवर्क के लिए नया हूं और मैं अन्य मशीन सीखने के तरीकों से तुलना करने के लिए उनका उपयोग करना चाहता हूं। मेरे पास लगभग दो वर्षों की श्रृंखला के साथ एक बहुभिन्नरूपी श्रृंखला डेटा है। मैं अगले कुछ दिनों के लिए 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]

मुझे समझ नहीं आ रहा है कि हम किस तरह से पैरामीटर या इनपुट के आकार को चुनते हैं। मैंने कुछ वीडियो देखे हैं और कुछ गिथब पृष्ठ पढ़े हैं और सभी को एलएसटीएम को एक अलग तरीके से चलाना प्रतीत होता है, जिसे लागू करना और भी कठिन हो जाता है। पिछली त्रुटि शायद आकार से आ रही है, लेकिन इसके अलावा क्या बाकी सब सही है? और मैं इसे काम करने के लिए कैसे ठीक कर सकता हूं? धन्यवाद

संपादित करें: यह इसी तरह का सवाल मेरी समस्या का समाधान नहीं करता है .. मैंने वहां से समाधान की कोशिश की है

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

INPUT:

समस्या यह है कि आप मॉडल आकार के एक 3 डी इनपुट की उम्मीद (batch, sequence, features)करते हैं लेकिन आपका X_trainवास्तव में डेटा फ्रेम का एक टुकड़ा है, इसलिए 2 डी सरणी:

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,quarterk
  • किसी भी दिन n के लिए, पिछले 'मी' दिनों की विशेषताओं को देखते हुए आप वें दिन yकी भविष्यवाणी करना चाहते nहैं

विंडो डेटासेट बनाना:

  • हमें मुट्ठी की जरूरत है कि हम अपने मॉडल को कितने दिनों तक खिलाना चाहते हैं। इसे अनुक्रम लंबाई कहा जाता है (इस उदाहरण के लिए इसे 3 पर ठीक करने देता है)।
  • ट्रेन और परीक्षण डेटासेट बनाने के लिए हमें अनुक्रम लंबाई के दिनों को विभाजित करना होगा। यह एक स्लाइडिंग विंडो का उपयोग करके किया जाता है, जहां खिड़की का आकार अनुक्रम में है।
  • जैसा कि आप देख सकते हैं कि पिछले pरिकॉर्ड्स द्वारा कोई भविष्यवाणी उपलब्ध नहीं है जहां pअनुक्रम लंबाई है।
  • हम timeseries_dataset_from_arrayविधि का उपयोग करते हुए विंडो डेटासेट क्रिएशन करेंगे ।
  • अधिक अग्रिम सामग्री के लिए आधिकारिक tf डॉक्स का पालन करें ।

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>