v9.1.1
Menu

Chapter 5: Sequence Models

Week 5

Master recurrent neural networks and their variants for processing sequential text data — from vanilla RNNs to LSTMs, GRUs, and the encoder-decoder paradigm.

Topics
6
Demos
3
Videos
3
Min read
45

Chapter Overview

Sequence models are the backbone of modern NLP systems that process text as ordered sequences of tokens. Unlike feedforward networks that treat each input independently, recurrent architectures maintain a hidden state that accumulates information as it reads through a sequence one token at a time. This memory mechanism allows the model to capture dependencies between words regardless of their distance in the sentence.

The vanilla RNN introduced the fundamental idea of recurrence but suffers from the vanishing gradient problem, which makes it difficult to learn long-range dependencies. The Long Short-Term Memory (LSTM) network and the Gated Recurrent Unit (GRU) solve this with gating mechanisms that control information flow through the network. These gated architectures became the dominant approach for tasks like language modeling, machine translation, and text classification throughout the 2010s.

This chapter traces the evolution from simple RNNs through gated variants, bidirectional processing, and the encoder-decoder framework that enabled sequence-to-sequence tasks like translation. Understanding these architectures is essential background for the attention mechanism (Chapter 6) and the Transformer (Chapter 7), which ultimately replaced recurrence with parallelizable self-attention.

Chapter Roadmap

Click any topic to jump in

Explainer videoInteractive demo
1
Recurrent Neural Networks

The fundamental recurrence equation, BPTT, and why vanilla RNNs struggle with long-range dependencies.

Hidden State RecurrenceBackpropagation Through Time (BPTT)Vanishing and Exploding GradientsRNN Output Modes
Solving the gradient problem

Two gated architectures that preserve long-range gradients

2
LSTM

Gating mechanisms that solve the vanishing gradient problem via an additive cell state highway.

Forget GateInput Gate and Candidate Cell StateCell State UpdateOutput Gate
3
GRU

A streamlined alternative to LSTM that merges the cell and hidden state with fewer gates.

Update GateReset GateCandidate Hidden State
Reading in both directions
4
Bidirectional RNNs

Running two RNNs in opposite directions to capture both past and future context at every position.

Forward and Backward PassesConcatenation of Hidden StatesUse Cases and Limitations
Mapping sequences to sequences

Encoder compresses, decoder generates with search strategies

5
Sequence-to-Sequence

The encoder-decoder paradigm for mapping variable-length input sequences to variable-length outputs.

EncoderDecoder and Autoregressive GenerationTeacher ForcingFixed-Length Bottleneck
6
Encoder-Decoder Architecture

Context vector design, beam search decoding, and nucleus sampling for generation quality.

Context Vector DesignBeam Search DecodingNucleus (Top-p) Sampling

Topics

6 topics in this chapter

A Recurrent Neural Network (RNN) processes a sequence by applying the same function at each time step, taking the current input xtx_t and the previous hidden state ht−1h_{t-1} to produce a new hidden state hth_t. This recurrence is what gives the network its "memory" --- the hidden state is a compressed summary of everything the network has seen so far.

The hidden state update uses a simple formula: ht=tanh⁡(Whhht−1+Wxhxt+bh)h_t = \tanh(W_{hh} h_{t-1} + W_{xh} x_t + b_h). The tanh⁡\tanh nonlinearity squashes the output to [−1,1][-1, 1], and the two weight matrices WhhW_{hh} (hidden-to-hidden) and WxhW_{xh} (input-to-hidden) are shared across all time steps. This weight sharing means an RNN can process sequences of arbitrary length with a fixed number of parameters.

Training an RNN requires Backpropagation Through Time (BPTT), which unrolls the recurrence and applies the chain rule across time steps. Unfortunately, gradients that are multiplied through many time steps tend to either vanish (shrink to zero) or explode (grow unboundedly). The vanishing gradient problem means vanilla RNNs struggle to learn dependencies spanning more than about 10--20 time steps, motivating the gated architectures covered in the next topics.

Definition

A recurrent neural network is a sequence model that keeps a hidden state hth_t and updates it at every step with the same parameters, ht=tanh⁡(Whhht−1+Wxhxt+bh)h_t = \tanh(W_{hh} h_{t-1} + W_{xh} x_t + b_h). Because the weights are shared across time, one network handles sequences of any length; it is trained by backpropagation through time.

In this topic

  1. 1Hidden State Recurrence
  2. 2Backpropagation Through Time (BPTT)
  3. 3Vanishing and Exploding Gradients
  4. 4RNN Output Modes
1 of 4
Hidden State Recurrence

ht=tanh⁡(Whhht−1+Wxhxt+bh)h_t = \tanh(W_{hh} h_{t-1} + W_{xh} x_t + b_h)

The hidden state hth_t is a vector that encodes information about the entire sequence up to time tt. At each step, it combines the previous hidden state (what the network remembers) with the current input (what it sees now) through learned weight matrices. The tanh activation bounds the hidden state values, preventing unbounded growth. The same weights WhhW_{hh} and WxhW_{xh} are reused at every time step, which is what makes the architecture recurrent.

Mathematical Intuition

The recurrence ht=tanh⁡(Whhht−1+Wxhxt+bh)h_t = \tanh(W_{hh} h_{t-1} + W_{xh} x_t + b_h) is a nonlinear dynamical system where WhhW_{hh} controls memory retention and WxhW_{xh} controls input sensitivity. The tanh squashing to [−1,1][-1,1] acts as a soft saturation — when the pre-activation magnitude exceeds ~2, the output barely changes, causing gradient attenuation. The eigenvalues of WhhW_{hh} determine the system's stability: eigenvalues with magnitude < 1 cause exponential decay (forgetting), while magnitude > 1 causes exponential growth (exploding activations).

Example:

If h0=[0,0]h_0 = [0, 0], x1=[1]x_1 = [1], Whh=[[0.5,0.1],[0.2,0.3]]W_{hh} = [[0.5, 0.1], [0.2, 0.3]], Wxh=[[0.4],[0.6]]W_{xh} = [[0.4], [0.6]], and bh=[0,0]b_h = [0, 0], compute h1h_1.

2 of 4
Backpropagation Through Time (BPTT)

∂L∂Whh=∑t=1T∂Lt∂ht∏k=tT∂hk∂hk−1\frac{\partial L}{\partial W_{hh}} = \sum_{t=1}^{T} \frac{\partial L_t}{\partial h_t} \prod_{k=t}^{T} \frac{\partial h_k}{\partial h_{k-1}}

BPTT unrolls the RNN into a deep feedforward network with TT layers (one per time step) and applies standard backpropagation. The gradient of the loss with respect to the shared weights involves a product of Jacobian matrices ∂hk∂hk−1\frac{\partial h_k}{\partial h_{k-1}} across time steps. When the spectral norm of these Jacobians is consistently less than 1, the gradient product shrinks exponentially --- this is the vanishing gradient problem. When it exceeds 1, gradients explode.

Mathematical Intuition

The gradient ∂L∂Whh=∑t∂Lt∂ht∏k∂hk∂hk−1\frac{\partial L}{\partial W_{hh}} = \sum_t \frac{\partial L_t}{\partial h_t} \prod_k \frac{\partial h_k}{\partial h_{k-1}} involves a product of Jacobians across TT time steps. Each Jacobian ∂hk∂hk−1=diag(1−hk2)Whh\frac{\partial h_k}{\partial h_{k-1}} = \text{diag}(1 - h_k^2) W_{hh} has spectral norm bounded by ∥Whh∥⋅max⁡(1−hk2)\|W_{hh}\| \cdot \max(1 - h_k^2). Over TT steps, this product scales as λmax⁡T\lambda_{\max}^T where λmax⁡\lambda_{\max} is the largest singular value of WhhW_{hh} modulated by tanh derivatives — explaining why gradients vanish (λmax⁡<1\lambda_{\max} < 1) or explode (λmax⁡>1\lambda_{\max} > 1) exponentially.

Example:

In a 50-step sequence, if the Jacobian norm at each step is 0.9, what fraction of the gradient from the last step reaches the first step?

3 of 4
Vanishing and Exploding Gradients

The vanishing gradient problem occurs when the product of Jacobian norms across time steps shrinks to near zero, making it impossible to learn long-range dependencies. The exploding gradient problem is the opposite: gradients grow exponentially, causing unstable weight updates. Gradient clipping (capping the gradient norm to a threshold) is a practical fix for exploding gradients. However, vanishing gradients require architectural changes --- specifically the gating mechanisms introduced by LSTMs and GRUs.

Mathematical Intuition

Gradient clipping rescales g←g⋅θ/∥g∥g \leftarrow g \cdot \theta / \|g\| when ∥g∥>θ\|g\| > \theta, which projects the gradient onto a ball of radius θ\theta. This preserves the direction of the gradient while bounding its magnitude, preventing catastrophic weight updates. Vanishing gradients cannot be fixed by scaling because the information about long-range dependencies is lost — the gradient signal is exponentially attenuated relative to short-range signals, so amplifying everything uniformly does not recover the lost structure.

Example:

Why does gradient clipping fix exploding gradients but not vanishing gradients?

4 of 4
RNN Output Modes

The same recurrent core can be wired to inputs and outputs in different ways, and the choice follows from the shape of the task's labels. Many-to-one reads the whole sequence and uses only the final hidden state hTh_T, as in sentiment classification. Many-to-many emits an output yt=softmax(Whyht+by)y_t = \text{softmax}(W_{hy} h_t + b_y) at every step, as in part-of-speech tagging or named entity recognition. One-to-many starts from a single input and generates a sequence, as in image captioning. The failure mode of many-to-one is that every gradient must travel back from the last step, so early tokens learn slowly. Encoder-decoder models, later in this chapter, combine many-to-one with one-to-many.

Mathematical Intuition

In many-to-one mode, only hTh_T contributes to the loss, so gradients must flow backward through all TT steps to update early representations. In many-to-many mode, each hth_t contributes to a local loss, providing gradient injection at every time step. This makes many-to-many training more stable because the effective backpropagation distance is shorter — each parameter receives gradient signal from the nearest output, not just the final one.

Example:

For a part-of-speech tagging task on a 10-word sentence, which output mode would you use, and how many predictions does the model make?

Theory Exercise

Problem:

Explain why weight sharing across time steps is essential for RNNs. What would happen if each time step had its own weight matrices?

Hints:
  • Think about the number of parameters relative to sequence length

Coding Exercise

Problem:

Implement a vanilla RNN cell in PyTorch from scratch (without using nn.RNN). Create a class that takes an input and previous hidden state, applies the recurrence formula, and returns the new hidden state.

Hints:
  • Define W_xh, W_hh, and b_h as nn.Parameter