Skip to content
ml-recall

Topic notes

Recurrent Neural Networks

Recurrent networks for sequences; the hidden-state recurrence, weight sharing and parameter counts, backpropagation through time, vanishing and exploding gradients, LSTM and GRU gates, and seq2seq.

4-min read AI-checked

Practise 47 questions Take a test

Key ideas

Formulas

It,Ft,Ot=σ(XtWx⋅+Ht−1Wh⋅+b⋅),C~t=tanh⁡(⋯ ),Ct=Ft⊙Ct−1+It⊙C~t,Ht=Ot⊙tanh⁡(Ct)\mathbf{I}_t, \mathbf{F}_t, \mathbf{O}_t = \sigma(\mathbf{X}_t W_{x\cdot} + \mathbf{H}_{t-1} W_{h\cdot} + \mathbf{b}_\cdot),\quad \tilde{\mathbf{C}}_t = \tanh(\cdots),\quad \mathbf{C}_t = \mathbf{F}_t \odot \mathbf{C}_{t-1} + \mathbf{I}_t \odot \tilde{\mathbf{C}}_t,\quad \mathbf{H}_t = \mathbf{O}_t \odot \tanh(\mathbf{C}_t) Ht=Zt⊙Ht−1+(1−Zt)⊙H~t,H~t=tanh⁡(XtWxh+(Rt⊙Ht−1)Whh+bh)\mathbf{H}_t = \mathbf{Z}_t \odot \mathbf{H}_{t-1} + (1 - \mathbf{Z}_t) \odot \tilde{\mathbf{H}}_t,\qquad \tilde{\mathbf{H}}_t = \tanh\big(\mathbf{X}_t W_{xh} + (\mathbf{R}_t \odot \mathbf{H}_{t-1}) W_{hh} + \mathbf{b}_h\big) g←min⁡(1,θ∥g∥)g\mathbf{g} \leftarrow \min\left(1, \frac{\theta}{\lVert\mathbf{g}\rVert}\right)\mathbf{g}

Parameters per block of the form XWx+HWh+b\mathbf{X}W_x + \mathbf{H}W_h + \mathbf{b}: h(d+h+1)h(d + h + 1). A vanilla RNN layer has 1 block, a GRU 3, an LSTM 4 (cost per step scales the same way). PyTorch stores two bias vectors per block, so it reports h(d+h+2)h(d + h + 2) per block.

Worked example

Scalar RNN ht=tanh⁡(0.5 ht−1+xt)h_t = \tanh(0.5\,h_{t-1} + x_t), h0=0h_0 = 0, inputs x=(1,0,0)x = (1, 0, 0):

Every step multiplies by whh⋅tanh⁡′≤0.5w_{hh} \cdot \tanh' \le 0.5, so the influence of x1x_1 shrinks geometrically. Even a per-step factor of 0.9 (a linear RNN with whh=0.9w_{hh} = 0.9) leaves the first of 50 inputs a weight of only 0.949≈0.00570.9^{49} \approx 0.0057. Counting parameters for d=10d = 10, h=20h = 20 (one bias per block): a block has 20⋅31=62020 \cdot 31 = 620, so RNN 620, GRU 1860, LSTM 2480.

In code

import torch
from torch import nn
for cls in (nn.RNN, nn.GRU, nn.LSTM):
    m = cls(input_size=10, hidden_size=20, batch_first=True)
    print(cls.__name__, sum(p.numel() for p in m.parameters()))  # RNN 640, GRU 1920, LSTM 2560
out, (h, c) = nn.LSTM(10, 20, batch_first=True)(torch.zeros(4, 7, 10))
print(out.shape, h.shape)          # torch.Size([4, 7, 20]) torch.Size([1, 4, 20])
bi = nn.GRU(10, 20, batch_first=True, bidirectional=True)
print(bi(torch.zeros(4, 7, 10))[0].shape)  # torch.Size([4, 7, 40])

Common pitfalls

References

  1. Natural Language Processing with Deep Learning (Ruhr University Bochum, 2025/26) — Lecture 6 slides, frames 'Define RNN recursively — Computing current state', 'Graphical visualization of abstract RNN (unrolled)', 'RNN as acceptor or encoder', 'RNN as transducer', 'Bi-directional RNNs', 'How to provide more controlled memory access?'
  2. Dive into Deep Learning — Sec. 9.5 Recurrent Neural Network Implementation from Scratch (9.5.1 RNN Model, 9.5.2 RNN-Based Language Model, 9.5.3 Gradient Clipping)
  3. Dive into Deep Learning — Sec. 9.7 Backpropagation Through Time (9.7.1.2 Truncating Time Steps, 9.7.2 Backpropagation Through Time in Detail)
  4. Dive into Deep Learning — Sec. 10.1 Long Short-Term Memory (LSTM) (introduction, 10.1.1 Gated Memory Cell)
  5. Dive into Deep Learning — Sec. 10.2 Gated Recurrent Units (GRU) (10.2.1 Reset Gate and Update Gate, 10.2.2 Candidate Hidden State, 10.2.3 Hidden State)
  6. Dive into Deep Learning — Sec. 10.4 Bidirectional Recurrent Neural Networks (introduction, 10.4.3 Summary)
  7. Dive into Deep Learning — Sec. 10.7 Sequence-to-Sequence Learning for Machine Translation (10.7.1 Teacher Forcing, 10.7.3 Decoder, 10.7.5 Loss Function with Masking, 10.7.7 Prediction)
  8. AI for Beginners — Lesson: Generative networks (introduction: RNN architecture patterns; Soft text generation and temperature)