title: Multivariate Encoder-Decoder Model approaches value
body: <p>I am creating my first multivariate multistep encoder-decoder LSTM to forecast revenues.</p>
  <p>As you can see, the values move towards a value and then stop at that value. The aim is to create a forecast for a longer period, but there is no deviation at all from this standard value after the first week.
  What is wrong and what can I do? To me it doesn't look like it is working at all.</p>
  <h2>code:</h2>
  <pre><code>    class ModelTrainer:
          def __init__(self, prediction_length=30, offset=1):
              self.prediction_length = prediction_length
              self.offset = offset
              self._setup_values()
              self.use_scaling = True
              self.__prepare_data()
      
          def _setup_values(self):
              # Model configuration
              self.additional_metrics = ['accuracy']
              self.embedding_output_dims = 15
              self.max_sequence_length = 300
              self.num_distinct_words = 5000
              self.verbosity_mode = 1
      
              # DATA
              self.WINDOW_LENGTH = 70  # ! SHOULD BE ADJUSTED TO THE AMOUNT OF FORECASTING DAYS
              self.SAMPLING_RATE = 1
              self.BATCH_SIZE = 128
      
              # MODEL
              self.DROPOUT = 0.3
              self.NODES_PER_LAYER = 256
              self.NUMBER_OF_LAYERS = 3
      
              # TRAINING
              self.LEARNING_RATE = 0.001
              self.OPTIMIZER = Adam(learning_rate=self.LEARNING_RATE)
              self.VALIDATION_SPLIT = 0.20
              self.NUMBER_OF_EPOCHS = 10
              self.TEST_SIZE = 0.1
              self.RANDOM_STATE = 123
              self.LOSS_FUNCTION = MeanSquaredError()
      
          def __import_data(self):
              self.series = DataOrganizer().df
      
          def __prepare_data(self):
              self.__import_data()
              self.scaler = preprocessing.MinMaxScaler()
              data_scaled = self.scaler.fit_transform(self.series)
              self.features, self.target = self._create_feature_target_values_window(
                  data_scaled)
      
          def _create_feature_target_values_window(self, data):
              self.number_of_output_columns = 4
              feature_data = data
              target_data = data[:, :self.number_of_output_columns]
              features, target = list(), list()
              in_start = 0
              for _ in range(len(data)):
                  in_end = in_start + self.WINDOW_LENGTH
                  out_end = in_end + self.prediction_length
                  if out_end &lt;= len(data):
                      features.append(feature_data[in_start:in_end, :])
                      target.append(
                          target_data[in_end:out_end, 0:self.number_of_output_columns])
                  in_start += 1
              return np.array(features), np.array(target)
      
          def __create_LSTM_model(self):
              num_feature_columns = self.features.shape[2]
              num_output_columns = self.target.shape[2]
              model = Sequential()
              model.add(LSTM(self.NODES_PER_LAYER, input_shape=(
                  self.WINDOW_LENGTH, num_feature_columns)))
              model.add(Dropout(self.DROPOUT))
              model.add(RepeatVector(self.prediction_length))
              model.add(LSTM(self.NODES_PER_LAYER, return_sequences=True))
              model.add(Dropout(self.DROPOUT))
              model.add(TimeDistributed(Dense(self.NODES_PER_LAYER)))
              model.add(Dropout(self.DROPOUT))
              model.add(TimeDistributed(Dense(num_output_columns)))
              model.summary()
              return model
      
          def train_model(self, callbacks=[]):
              model = self.__create_LSTM_model()
              model.compile(loss=self.LOSS_FUNCTION,
                            optimizer=self.OPTIMIZER,
                            metrics=['accuracy', MeanAbsoluteError()]
                            )
              model.fit(
                  x=self.features,
                  y=self.target,
                  epochs=self.NUMBER_OF_EPOCHS,
                  validation_split=self.TEST_SIZE,
                  shuffle=False,
                  callbacks=callbacks
              )
              self.model = model
      
          def create_forecast(self):
              prediction = self.model.predict(self.features[-1:])
              # prediction = self.model.predict(self.features[-30:-29]) # Show forecast from a month old
              test_X = self.features.copy()
              test_X = test_X[:self.prediction_length,
                              :1, self.number_of_output_columns:]
              test_X = test_X.reshape(
                  self.prediction_length, self.series.shape[1] - self.number_of_output_columns)
              prediction = prediction.reshape(self.prediction_length,
                                              self.number_of_output_columns)
              inv_yhat = np.concatenate((prediction, test_X), axis=1)
              inv_yhat = self.scaler.inverse_transform(inv_yhat)
              prediction_df = pd.DataFrame(
                  inv_yhat, columns=self.scaler.feature_names_in_)
              first_date = self.series.last_valid_index() + timedelta(days=1)
              last_date = first_date + timedelta(days=self.prediction_length-1)
              days = pd.date_range(first_date, last_date, freq='D')
              prediction_df.set_index(days, inplace=True)
              prediction_df = prediction_df[self.series.columns[0:4]]
  </code></pre>
  <h2>Actual</h2>
  <p><a href="https://i.stack.imgur.com/9kVpO.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/9kVpO.png" alt="actual" /></a></p>
  <h2>Forecast:</h2>
  <p>(I know the x-axis description is incorrect. Don't worry about it)
  <a href="https://i.stack.imgur.com/cHEFV.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/cHEFV.png" alt="forecast" /></a></p>