RNN Architecture
A network unrolled over time with shared weights
An RNN feeds each input together with the previous hidden state through a weight-shared cell, carrying information across steps. Unrolled over time it's a deep shared-weight network — with all the gradient implications.
What you will learn
- Describe the RNN cell update h_t = σ(Wx·x_t + Wh·h_(t-1) + b)
- Explain weight sharing across time steps
- Unroll a 3-step RNN and identify its depth
What is this?
A recurrent network uses one cell applied identically at every time step. At time t the cell combines the current input x_t with the previous hidden state h_(t-1): h_t = tanh(Wx·x_t + Wh·h_(t-1) + b). The same Wx, Wh and b are reused for every step — that's the 'recurrent' weight sharing. Unrolled, an RNN over T steps behaves like a T-layer network whose layers all share weights.
Why do you need it?
- Weight sharing lets an RNN handle variable-length sequences with a fixed number of parameters.
- The state h_t compresses the whole past into a fixed vector the model can read.
- Unrolling the recurrence is how backprop through time (BPTT) computes gradients.
- Because the same cell repeats, the number of steps T is your effective depth — and that's where gradients struggle.
Mental model
A runner handing off a baton at each lap marker
RNN state flowing through steps
The same runner (the shared cell) takes the baton (state) at each marker, reads where they are (input), and passes the baton forward — the baton is the accumulated knowledge, and the whole run depends on the same consistent stride (weights).
How it works
- Initial state h_0 (often zeros) starts the chain.
- At each t: h_t = tanh(Wx·x_t + Wh·h_(t-1) + b); h_t is the new state.
- Outputs are read from h_t by an output layer (per-step) or from the final h_T (sequence label).
- Unrolling: the computation graph is T identical cells deep — total depth T.
- Training: backprop through time (BPTT) computes gradients by unrolling and chaining through all T steps.
An RNN unrolled for 3 steps with shared weights.
In production
- Classic building blocks (before transformers) for speech-to-text stateful decoders.
- Character/music generators with vanilla RNNs still appear in lightweight demos.
- RL wrappers that compress observation history into a state vector.
Best practices
- Truncate BPTT to a manageable window while keeping states carried across batches.
- Use tanh activation (saturating, but with well-understood gradients) inside the cell.
- Initialize Wh to stay contractive (small-scale) to tame early recurrence blow-ups.
- Package sequences by length (bucket padding) to avoid wasting the shortest batch on the longest pad.
Common mistakes
- Sharing weights but training step-dependent copies (bug: not untying correctly in custom loops).
- Feeding un-padded variable-length sequences into a fixed shaped matrix.
- Not masking padded positions, so the loss 'learns' padding as context.
- Ignoring T-depth: a 500-token sentence = a 500-layer net's gradient path.
Common issues
State norm explodes over long sequencesRecurrence matrix spectral radius > 1 amplifies signal each step
Smaller Wh init, gradient clipping, or batch/group-norm on h; prefer LSTM/GRU cells.
Early steps contribute nothing (loss fixed by last steps only)Vanishing gradients through T unrolls
Truncated BPTT + carry, better init, or a cell with gates (LSTM/GRU).
Padding rows dominate the batch statsNo length bucketing or masking
Sort/bucket by length and mask pads in both loss and normalization.
Debugging tips
- Print h_t norms per step: explosion over steps signals a Wh-scale/LR problem.
- Run a 2-step toy and check the gradient via finite differences before scaling length.
- Masked loss? Confirm padding tokens contribute zero to loss, or pad-error dominates.
- Compare T=5 and T=50 behavior — the pain switching tells you gradient difficulty.
Interview checkpoint
Hands-on lab
- Implement the RNN cell update in numpy
- Unroll 3 steps and confirm state norms behave
- Compare with a framework RNN output on matching weights
A From-Scratch RNN Stepwise
25 min · intermediate
Quick quiz
Which parameters are shared across all time steps of an RNN?
An RNN's computational depth grows with sequence length.