Jaber Notes · 14 of 16
RNNs & Sequences
RNN, BPTT, LSTM/GRU gates, seq2seq, attention, beam search.
Sequence modeling before (and into) transformers: the vanilla RNN and BPTT, the formal vanishing-gradient analysis, LSTM/GRU gate equations and why gradients survive, seq2seq with teacher forcing, and Bahdanau/Luong attention.
Visual reference
Self-attention (simplified)
Processing ordered data: language, time series, speech. From vanilla RNNs and their failure mode, through LSTM's gating solution, to the attention mechanism that replaced them.
Table of contents
- Sequence modeling problem
- Vanilla RNN
- Backpropagation through time (BPTT)
- Vanishing gradient in RNNs (formal)
- LSTM (Long Short-Term Memory)
- GRU (Gated Recurrent Unit)
- Bidirectional RNNs
- Seq2Seq (Encoder-Decoder)
- Attention mechanism
- Practical notes and code
1. Sequence modeling problem
Given a sequence (e.g., words, time-series values), we want to:
- Sequence classification: (e.g., sentiment, speaker ID).
- Sequence labeling: (e.g., POS tagging, NER).
- Language modeling: (predict next token).
- Seq2Seq: with different lengths (translation, summarization).
Key challenge: inputs/outputs can be of variable length; dependencies can span long distances (long-range dependencies).
2. Vanilla RNN
2.1 Architecture
Processes sequence one step at a time, maintaining a hidden state (memory):
In matrix form (concat input and hidden):
Parameters: , , , where = hidden size, = input size, = output size. Shared across all time steps — same weights at every .
2.2 Unrolled RNN
The RNN is a deep feedforward network "unrolled" over time:
x₁ → [h₁] → ŷ₁
↓
x₂ → [h₂] → ŷ₂
↓
x₃ → [h₃] → ŷ₃Depth = sequence length . This creates the vanishing gradient problem for long sequences.
2.3 Initial hidden state
(most common), or learned as a parameter, or set from a context encoder.
2.4 Training objectives
Many-to-many (language model):
Many-to-one (classification): use as sequence representation, then linear classifier.
3. Backpropagation through time (BPTT)
3.1 Algorithm
Unroll the RNN for steps, then apply standard backpropagation through the unrolled graph.
Gradient of loss at time w.r.t. hidden state at time :
Each Jacobian factor:
where comes from .
Total gradient product over steps:
3.2 Truncated BPTT
Full BPTT for long sequences: memory and time. Truncated BPTT: backpropagate through only the last steps. Trades accuracy for efficiency.
4. Vanishing gradient in RNNs (formal)
4.1 Analysis
The magnitude of the gradient product after steps:
where \lambda_\max is the largest singular value of .
Since , if \lambda_\max(\mathbf{W}_h) < 1: gradients vanish exponentially as grows. If \lambda_\max(\mathbf{W}_h) > 1: gradients explode (fixed by gradient clipping).
Consequence: vanilla RNNs struggle to learn dependencies spanning > ~10 steps. The gradient carries essentially no information from time back to time when is large.
5. LSTM (Long Short-Term Memory)
5.1 Motivation (Hochreiter & Schmidhuber, 1997)
Replace the simple hidden state with a cell state that flows mostly unchanged through time (like a "conveyor belt"), with gates controlling what information to add or remove.
5.2 LSTM equations
At each time step, with input and previous states :
Forget gate (what to erase from cell state):
Input gate (what new information to write):
Candidate cell values (proposed update):
Cell state update:
Output gate (what to expose as hidden state):
Hidden state:
5.3 Gate intuitions
| Gate | Role | Values close to |
|---|---|---|
| Forget | Erase irrelevant past from | 0 = forget, 1 = keep |
| Input | Write new info to | 0 = block, 1 = write |
| Output | Reveal part of as | 0 = hide, 1 = expose |
5.4 Why LSTM solves vanishing gradients
The gradient flows through :
The Jacobian is diagonal with values . If the forget gate is near 1, the gradient flows through the cell state mostly unchanged — no repeated matrix multiplication that would cause exponential decay.
This is the constant error carousel: the cell state provides a nearly unimpeded gradient pathway for long-range dependencies.
5.5 Parameters
Four gates, each with weight matrices and bias . Total: parameters.
For : parameters per layer.
6. GRU (Gated Recurrent Unit)
6.1 Equations (Cho et al., 2014)
Simpler than LSTM: merges cell state and hidden state, uses only two gates.
Reset gate (how much past to forget):
Update gate (interpolation between old and new):
Candidate hidden state:
Hidden state update (linear interpolation):
When : copy old hidden state (remember long-term). When : replace with new candidate (update quickly).
6.2 GRU vs LSTM
| LSTM | GRU | |
|---|---|---|
| States | , | only |
| Gates | 3 (forget, input, output) | 2 (reset, update) |
| Parameters | ||
| Performance | Slightly better on long sequences | Slightly faster, competitive |
Rule of thumb: try both; GRU is often preferred for smaller datasets due to fewer parameters.
7. Bidirectional RNNs
7.1 Motivation
A standard RNN at time can only use past context . For tasks where the full sequence is available (e.g., NER, POS tagging, text classification), future context can also help.
7.2 Architecture
Run two RNNs: one forward (left to right), one backward (right to left):
Concatenate: .
Limitation: cannot be used for autoregressive generation (future tokens unknown at time ). BERT uses bidirectional transformers for encoding; GPT uses unidirectional for generation.
8. Seq2Seq (Encoder-Decoder)
8.1 Architecture (Sutskever et al., 2014)
Problem: input sequence length ≠ output sequence length .
Encoder: RNN reads input, compresses to fixed context vector:
Decoder: RNN generates output autoregressively, conditioned on :
Training: teacher forcing — feed ground-truth as decoder input (even if previous prediction was wrong). Faster convergence.
Inference: use predicted as decoder input (autoregressive decoding). Exposure bias: mismatch between training (ground-truth inputs) and inference (own predictions).
8.2 Bottleneck problem
The entire input sequence must be compressed into a single fixed-size vector . For long sequences, this is information-lossy. Solution: attention mechanism.
8.3 Beam search
Greedy decoding: at each step, pick most probable token. Suboptimal (misses high-probability sequences).
Beam search: maintain top- partial sequences at each step:
- Expand each beam by all vocabulary tokens.
- Score each extension by accumulated log-prob.
- Keep top-.
Beam size is common. Increases quality significantly over greedy, at cost.
9. Attention mechanism
9.1 Bahdanau attention (Bahdanau et al., 2015)
Allow the decoder to attend to different encoder positions at each decoding step, instead of using one fixed context vector.
Alignment scores: score how relevant encoder hidden state is for decoder step :
Attention weights:
Context vector (weighted sum of encoder states):
Decoder uses (dynamic, per-step) instead of a fixed .
9.2 Luong attention (Luong et al., 2015)
Computes alignment after computing current decoder hidden state:
Three variants: dot (), general (), concat (Bahdanau style). Dot product is simplest and scales to the transformer.
9.3 Interpretability
Attention weights can be visualized: which source words did the decoder focus on when producing target word ? In practice these are interpretable for NMT (e.g., diagonal pattern for monotone alignment).
Caveat: attention weights ≠ feature importance. They influence the context vector but are not directly a complete explanation of model behavior.
10. Practical notes and code
10.1 Sequence padding and packing
Batching variable-length sequences: pad shorter sequences to the batch maximum length.
import torch
import torch.nn as nn
from torch.nn.utils.rnn import pack_padded_sequence, pad_packed_sequence
# Packing: skip padded positions (efficient computation)
packed = pack_padded_sequence(padded_input, lengths, batch_first=True, enforce_sorted=False)
output_packed, (h_n, c_n) = lstm(packed)
output, _ = pad_packed_sequence(output_packed, batch_first=True)10.2 PyTorch LSTM / GRU
lstm = nn.LSTM(
input_size=128,
hidden_size=256,
num_layers=2,
batch_first=True,
dropout=0.3,
bidirectional=True
)
gru = nn.GRU(input_size=128, hidden_size=256, num_layers=2, batch_first=True)
# Input: (batch, seq_len, input_size)
output, (h_n, c_n) = lstm(x) # LSTM
output, h_n = gru(x) # GRU
# output: (batch, seq_len, 2*hidden) for bidirectional
# h_n: (num_layers*num_dir, batch, hidden)10.3 When RNNs vs Transformers
| Scenario | RNN/LSTM | Transformer |
|---|---|---|
| Long sequences (very long) | Struggles (vanishing gradient) | Better (direct attention) |
| Small data | LSTM can be better (inductive bias) | Needs more data |
| Sequential tasks (streaming) | Natural | Harder (needs full sequence) |
| Parallelism during training | Sequential → slow | Fully parallel → fast |
| Current NLP | Largely replaced | Dominant |
| Lightweight sequence models | Still used | Expensive |
*File: notes/14_rnns_and_sequences.md — next: notes/15_transformers.md*