| name | deep-learning-forecasting |
| description | Forecasts time series using recurrent neural networks (RNN, LSTM, GRU) with ForecasterRnn and the create_and_compile_model helper. Covers model architecture, training, and multi-series deep learning. Use when the user wants to use deep learning / neural networks for time series forecasting.
|
Deep Learning Forecasting (RNN/LSTM)
References
See references/architecture-options.md for
the complete create_and_compile_model signature, recurrent layer types,
output shape rules, exog architecture, custom Keras model requirements,
and fit_kwargs options.
When to Use
Use ForecasterRnn when:
- You have large datasets (thousands of observations)
- Complex nonlinear patterns that tree-based models struggle with
- Multi-series problems where series share deep temporal patterns
Requirements: pip install skforecast[deeplearning] (installs keras)
Related skills
- Before:
choosing-a-forecaster (confirm ForecasterRnn is the right choice for the data size and pattern)
- Before:
feature-engineering (RNN models still benefit from cyclical / calendar exogenous features)
- After:
hyperparameter-optimization (tune RNN architecture and training hyperparameters)
- After:
prediction-intervals (only conformal intervals are supported for ForecasterRnn)
Stop Conditions
Scan before writing code. Each row lists a rule, the symptom when it is broken, and the recovery. Full pitfall catalog: the troubleshooting-common-errors skill.
| Rule | Symptom | Recovery |
|---|
lags in ForecasterRnn must match create_and_compile_model(..., lags=...) | Input shape mismatch error during fit | Use the same lags value in both calls |
ForecasterRnn supports only method='conformal' for intervals | Error when calling predict_interval(method='bootstrapping') | Use method='conformal' |
Pass exog to create_and_compile_model if exog is used in fit() / predict() | Architecture mismatch or failure when predicting with exog | Build the model with the same exog you train on |
Scale inputs with transformer_series=MinMaxScaler() | Poor convergence; RNNs are scale-sensitive | Always set a scaler on transformer_series |
Quick Start
import pandas as pd
from skforecast.deep_learning import ForecasterRnn, create_and_compile_model
from sklearn.preprocessing import MinMaxScaler
series = pd.read_csv('data.csv', index_col='date', parse_dates=True)
series = series.asfreq('h')
model = create_and_compile_model(
series=series,
lags=48,
steps=24,
levels=series.columns.tolist(),
recurrent_layer='LSTM',
recurrent_units=[64, 32],
dense_units=[32],
compile_kwargs={'optimizer': 'adam', 'loss': 'mse'},
)
forecaster = ForecasterRnn(
levels=series.columns.tolist(),
lags=48,
estimator=model,
transformer_series=MinMaxScaler(feature_range=(0, 1)),
fit_kwargs={'epochs': 50, 'batch_size': 32, 'verbose': 0},
)
forecaster.fit(series=series)
predictions = forecaster.predict(steps=24)
Model Architecture with create_and_compile_model
from skforecast.deep_learning import create_and_compile_model
model = create_and_compile_model(
series=series,
lags=48,
steps=24,
levels='target',
recurrent_layer='LSTM',
recurrent_units=[64],
dense_units=[32],
compile_kwargs={'optimizer': 'adam', 'loss': 'mse'},
)
model = create_and_compile_model(
series=series,
lags=48,
steps=24,
levels=series.columns.tolist(),
recurrent_layer='LSTM',
recurrent_units=[128, 64, 32],
dense_units=[64, 32],
compile_kwargs={'optimizer': 'adam', 'loss': 'mse'},
)
model = create_and_compile_model(
series=series,
lags=48,
steps=24,
levels='target',
recurrent_layer='GRU',
recurrent_units=[64],
dense_units=[32],
compile_kwargs={'optimizer': 'adam', 'loss': 'mse'},
)
model = create_and_compile_model(
series=series,
lags=48,
steps=24,
levels=series.columns.tolist(),
recurrent_layer='LSTM',
recurrent_units=[128, 64],
recurrent_layers_kwargs={'activation': 'tanh'},
dense_units=[64],
dense_layers_kwargs={'activation': 'relu'},
output_dense_layer_kwargs={'activation': 'linear'},
compile_kwargs={'optimizer': 'adam', 'loss': 'mse'},
model_name='my_lstm_model',
)
With Exogenous Variables
When using exogenous variables, pass exog to create_and_compile_model so it
builds the correct architecture (uses TimeDistributed layers internally).
exog = pd.DataFrame({'temperature': [...], 'holiday': [...]}, index=series.index)
model = create_and_compile_model(
series=series,
lags=48,
steps=24,
levels=series.columns.tolist(),
exog=exog,
recurrent_layer='LSTM',
recurrent_units=[64, 32],
dense_units=[32],
compile_kwargs={'optimizer': 'adam', 'loss': 'mse'},
)
forecaster = ForecasterRnn(
levels=series.columns.tolist(),
lags=48,
estimator=model,
fit_kwargs={'epochs': 50, 'batch_size': 32, 'verbose': 0},
)
forecaster.fit(series=series, exog=exog)
predictions = forecaster.predict(steps=24, exog=exog_test)
Custom Keras Model
import keras
inputs = keras.layers.Input(shape=(48, 1))
x = keras.layers.LSTM(64, return_sequences=True)(inputs)
x = keras.layers.LSTM(32)(x)
x = keras.layers.Dense(32, activation='relu')(x)
outputs = keras.layers.Dense(24)(x)
model = keras.Model(inputs=inputs, outputs=outputs)
model.compile(optimizer='adam', loss='mse')
forecaster = ForecasterRnn(
levels='target',
lags=48,
estimator=model,
transformer_series=MinMaxScaler(feature_range=(0, 1)),
fit_kwargs={'epochs': 100, 'batch_size': 32},
)
Multi-series custom model: For N levels, the output layer should be
Dense(steps * n_levels) followed by Reshape((steps, n_levels)).
Prediction Intervals
forecaster.fit(series=series, store_in_sample_residuals=True)
predictions = forecaster.predict_interval(
steps=24,
method='conformal',
interval=[0.1, 0.9],
use_in_sample_residuals=True,
use_binned_residuals=True,
)
Backtesting
from skforecast.model_selection import backtesting_forecaster_multiseries, TimeSeriesFold
cv = TimeSeriesFold(
steps=24,
initial_train_size=len(series) - 200,
refit=False,
)
metric, predictions = backtesting_forecaster_multiseries(
forecaster=forecaster,
series=series,
cv=cv,
metric='mean_absolute_error',
)
Common Mistakes
- Not scaling data: RNNs are sensitive to scale. Always use
transformer_series=MinMaxScaler().
- Too few epochs: Deep learning needs more training iterations. Start with 50-100 epochs.
- Wrong input shape: The
lags parameter in ForecasterRnn and create_and_compile_model must match.
- Refit=True in backtesting: Retraining RNNs at every fold is very slow — use
refit=False or refit=5.
- No GPU: Training is slow on CPU. Use GPU if available.
- Using
predict_interval(method='bootstrapping'): ForecasterRnn only supports method='conformal'.
- Forgetting
exog in create_and_compile_model: If you use exog in fit()/predict(), you must also pass exog when building the model so the architecture accounts for the extra input features.