17 — Deep Learning

LSTM & GRU#

Deep LearningStatistical 1 min read
◆ The PatternGated architectures for long-range memory

LSTM adds a cell state and three gates (forget, input, output) to control information flow, solving the vanishing gradient problem. GRU simplifies this to two gates (reset, update) with comparable performance. Both are the default deep learning baseline for time series.

LSTM:   ft = σ(Wf[ht−1,xt])   |   it = σ(Wi[ht−1,xt])   |   ot = σ(Wo[ht−1,xt])
The forget gate decides what to discard, the input gate what to write, and the output gate what to expose.
// Interactive — LSTM gate activations
Pattern bridge: LSTM gates are an attention mechanism before attention existed — they learn what to remember, connecting to the formal self-attention in transformers. The GRU/LSTM choice mirrors the GRU topic in ML Math.
Worked example

On a random walk, “tomorrow equals today” has a mean absolute error of 0.79; forecasting the training average gives 8.87; adding the historical drift does no better than naive (0.79). No model — LSTM or otherwise — can beat naive on a pure random walk, which is why every forecasting result should be reported against it.

Where it misleads
  • Plotted one step ahead, a naive-like model looks impressively accurate; the plot hides that it is just copying yesterday.
  • In the M-competitions, machine-learning methods often trailed simple statistical ones (Makridakis et al. 2018), especially on single series.
  • LSTMs need careful tuning and many series; their gains are real on large, related datasets.
In code
rng = np.random.default_rng(11)
y = 100 + rng.normal(0, 1, 2_000).cumsum()       # a random walk, like many prices
test = y[1_000:]
naive = np.abs(test[1:] - test[:-1]).mean()       # tomorrow = today
mean_fc = np.abs(test[1:] - y[:1_000].mean()).mean()   # tomorrow = the training average
drift = np.abs(test[1:] - (test[:-1] + np.diff(y[:1_000]).mean())).mean()
Python, in your browser — edit the code and run it again

Assumes import numpy as np and import pandas as pd. Each snippet simulates or makes up its own series, as the comments say.

The same idea with a library
# PyTorch — LSTM for multi-step forecasting
class LSTMForecaster(nn.Module):
    def __init__(self, n_features, hidden, n_out):
        super().__init__()
        self.lstm = nn.LSTM(n_features, hidden,
                            num_layers=2, batch_first=True, dropout=0.2)
        self.fc = nn.Linear(hidden, n_out)
    def forward(self, x):
        out, _ = self.lstm(x)
        return self.fc(out[:, -1, :])
Sources
  • S. Hochreiter & J. Schmidhuber, “Long Short-Term Memory”, Neural Computation 9(8), 1997
  • S. Makridakis, E. Spiliotis & V. Assimakopoulos, “Statistical and Machine Learning Forecasting Methods: Concerns and Ways Forward”, PLoS ONE 13(3), 2018
  • H. Hewamalage, C. Bergmeir & K. Bandara, “Recurrent Neural Networks for Time Series Forecasting: Current Status and Future Directions”, International Journal of Forecasting 37(1), 2021

Last reviewed October 2026 · How this site checks its content · Report a mistake

Linked from 2
← Previous
RNNs for Time Series
Open in the full reader, with the topic sidebar