I have timeseries data with 1 minute cadence with 4 features, and I want to try to predict the time-evolution of 2 of these features using a RNN using LSTMs in Keras. My aim is to predict the e.g. next 10 minutes of data for these two features, based on the last hour of data of the 4 features.
I have previously constructed a RNN which can predict a single timestep for each 60 minute data input, using keras (many-to-one). Since I only predict a single timestep (minute), I need to predict all 4 features, to be able to use this model to predict up to 10 timesteps (minutes) iteratively. The model looks like this:
from keras.models import Sequential
from keras.layers import Dense, LSTM, Dropout, Activation, BatchNormalization
model = Sequential()
model.add(LSTM(32, return_sequences=True, input_shape=(shape,4)))
# ... more hidden LSTM layers
model.add(LSTM(32))
model.add(Dense(4))
My input data are timeseries of the features, data
. I use MinMaxScaler
in scikit-learn
to normalize the features to (0,1)
. I then use TimeseriesGenerator
from keras
to generate the training data. I use a length of 60 to provide the RNN with 60 timesteps of data in the input.
from keras.preprocessing.sequence import TimeseriesGenerator
# data.shape is (n,4), n timesteps
tsgen = TimeseriesGenerator(data, data, length=60, batch_size=240)
I then fit the model, with checkpointing:
mcp = ModelCheckpoint("rnn_{epoch:03d}_{loss:.6f}.h5")
model.fit_generator(tsgen, epochs=30, callbacks=[mcp])
I would now like to a prediction "many-to-many", so that I do not need to predict all 4 features, but rather predict the next 10 timesteps of the 2 sought-after features.
I have looked at the TimeDistributed
layer for keras, but according to the documentation that will only allow me to predict 60 values (i.e. the length of my input timestep shape). How do I use that to predict only the next 10 minutes of data, based on the last 60 minutes? How would I write that in keras? Do I need to use my own TimeseriesGenerator to account for the target vector? For example, is it sufficient to fill the last 50 minutes of the target vector with zeros, and just use the TimeDistributed
layer?
Best Answer
If you're still interested in this, I would check out this thread: https://github.com/keras-team/keras/issues/6063. A sample model might look like this:
I am also pretty interested in doing something similar and might end up coming back to it because it looks promising. I hope this helps!