LSTM. How to forecast multivariative time series?

Viewed 122

I'm trying to forecast multivariative time series:

the table

So, there are 4 series here.

I tried to write an LSTM implementaion. At start, I split my dataframe into TensorFlow windowed dataset. So, each matrix with shape [12, 4] could forecast next [4] values:

def get_windowed_dataset(df):
    ds = tf.data.Dataset.from_tensor_slices(df.values)
    ds = ds.window(13, shift=1, drop_remainder=True)
    ds = ds.flat_map(lambda w: w.batch(13))
    ds = ds.shuffle(1024)
    ds = ds.map(lambda w: (w[:-1], w[-1]))
    return ds

And then I created an LSTM model:

model = tf.keras.models.Sequential([
  tf.keras.layers.LSTM(16, return_sequences=True, input_shape=[None, 4]),
  tf.keras.layers.LSTM(16),
  tf.keras.layers.Flatten(),
  tf.keras.layers.Dense(8, activation="relu"),
  tf.keras.layers.Dense(4)
])

model.compile(loss=tf.keras.losses.Huber(),
              optimizer=tf.keras.optimizers.Adam(),
              metrics=["mae"])

But when I call

train_set = get_windowed_dataset(df)
model.fit(train_set, epochs=100)

An error raising: ValueError: Error when checking input: expected lstm_12_input to have 3 dimensions, but got array with shape (None, 4).

What's the problem?

EDIT

Thanks to @Molessia, I've found out that datasets need to be batched. So, my solution is:

def get_windowed_dataset(df):
    ds = data.Dataset.from_tensor_slices(df)
    ds = ds.window(13, shift=1, drop_remainder=True)
    ds = ds.flat_map(lambda w: w.batch(13))
    ds = ds.shuffle(1024)
    ds = ds.map(lambda w: (w[:-1], w[-1]))
    return ds.batch(32).prefetch(1)
1 Answers

I think the issue here is that Keras always expect you to provide your input data in batches, even if you choose the batch size to be 1. This means that you need to add an extra dimension to your input in order to make it three-dimensional with the first dimension being the batch_size.

To solve this, you can reshape the input dataset like this:

data = data.reshape((1, 12, 4))
Related