Kiru Lab / Deep Learning / Architectures as Priors
Sequences, Memory, and the Bottleneck That Broke Recurrence
RNNs assume order matters and that a fixed-size state can carry the past. The second assumption is where they broke.
Concept · about 30 minutes
A recurrent network processes a sequence one element at a time, carrying a hidden state forward. The state is the model's entire memory of everything before now, compressed into a fixed-size vector.
Two problems follow directly from that recurrence. First, information from step 1 must survive being multiplied by `W_h` at every subsequent step — the vanishing-gradient product from track two, now operating over sequence length instead of depth. LSTMs and GRUs mitigate it with gates that create a path where the multiplier is near one. Second, the hidden state is a fixed-size bottleneck: no matter how long the sequence, the past must compress into the same number of dimensions.
The move that resolved it
Attention removes the bottleneck by keeping every previous element available and letting the model retrieve whichever ones are relevant, rather than forcing everything through a single running summary. The cost is that comparing every position to every other is quadratic in sequence length — which is why context windows have a price and why long-context research is an active field.
This is the exact motivation for the next track. Attention is not a clever trick added to sequence models; it is the structural answer to a specific bottleneck you can now name precisely.
Hold on to
- A recurrent hidden state is a fixed-size compression of the entire past
- Long-range failure in RNNs is the vanishing-gradient product over time
- Attention trades a bottleneck for quadratic cost
Work through
Try each one before opening the solution. Getting it wrong first is most of where the learning happens.
-
Train a small RNN on a copy task at sequence lengths 10, 50, and 200. Plot accuracy against length.
Hint
The copy task: show a random sequence, then ask the model to reproduce it.
Solution
A vanilla RNN handles length 10 well, degrades noticeably by 50, and is near chance at 200. The cause is the vanishing-gradient product operating along the sequence: the signal from position 1 must survive multiplication by the recurrent weight matrix 200 times to influence the loss at position 200.
import numpy as np, torch, torch.nn as nn def copy_batch(length, batch=64, vocab=8): x = torch.randint(1, vocab, (batch, length)) return x, x.clone() for length in (10, 50, 200): model = nn.RNN(input_size=16, hidden_size=64, batch_first=True) # train briefly, then evaluate exact-match accuracy on held-out sequences print(length, evaluate(model, length)) -
Repeat with an LSTM and explain the difference in terms of the gating path.
Hint
Compare where the gradient goes in an LSTM's cell state against a vanilla RNN's hidden state.
Solution
The LSTM holds up far better at length 200. Its cell state is updated additively and gated, so when the forget gate stays near 1 there is a path along which the gradient is multiplied by approximately 1 at each step rather than by a weight matrix. That is the same trick as a residual connection, applied along time instead of along depth — and noticing that these are one idea is the point of the exercise.
In the Bio Mirror
Working Memory and Its Hard LimitSign in to track your progress through the lab.