3.5.1Sequence Models

Recurrent Neural Networks (RNN) architecture

2,946 words13 min readdifficulty · medium1 backlinks

Overview

Recurrent Neural Networks (RNs) are neural network architectures designed to process sequential data by maintaining an internal hidden state that acts as memory. Unlike feedforward networks that treat each input independently, RNNs have connections that loop back on themselves, allowing information to persist across time steps.

Figure — Recurrent Neural Networks (RNN) architecture

Core Architecture Components

Derivation from First Principles

WHY this architecture?

Start with the problem: we want a function ff that maps a sequence to outputs, but the function should "remember" previous inputs.

Step 1: Encode memory as a vector

  • Let h(t)h^{(t)} be our memory at time tt
  • h(t)h^{(t)} should depend on current input x(t)x^{(t)} AND previous memory h(t1)h^{(t-1)}

Step 2: Combine inputs linearly

  • Most general linear combination: z=Whh(t1)+Wxhx(t)+bhz = W_{h} h^{(t-1)} + W_{xh} x^{(t)} + b_h
  • WHY linear? We can learn any non-linear transformation by composing linear maps with non-linearities

Step 3: Add non-linearity

  • Apply activation function: h(t)=σ(z)h^{(t)} = \sigma(z)
  • WHY tanh\tanh? Outputs in [1,1][-1, 1], keeps gradients healthier than sigmoid during backprop, zero-centered

Step 4: Produce output

  • Linear projection: y(t)=Whyh(t)+byy^{(t)} = W_{hy} h^{(t)} + b_y
  • WHY separate from hidden state? Allows hidden dimension to differ from output dimension; hidden state can be richer

Unfolding Through Time

The "recurrence" can be visualized by unfolding the network through time:

x^(1)    x^(2)    x^(3)
 |        |        |
 ↓        ↓        ↓
[RNN] → [RNN] → [RNN]
  ↓        ↓        ↓
 y^(1)   y^(2)   y^(3)

Each box shares the SAME weights. The arrows between boxes represent h(t1)h(t)h^{(t-1)} \to h^{(t)}.


Training: Backpropagation Through Time (BPTT)

Deriving Gradient for WhhW_{hh}:

By chain rule: LWhh=t=1TL(t)Whh\frac{\partial \mathcal{L}}{\partial W_{hh}} = \sum_{t=1}^{T} \frac{\partial L^{(t)}}{\partial W_{hh}}

For time step tt: L(t)Whh=L(t)y(t)y(t)h(t)h(t)Whh\frac{\partial L^{(t)}}{\partial W_{hh}} = \frac{\partial L^{(t)}}{\partial y^{(t)}} \frac{\partial y^{(t)}}{\partial h^{(t)}} \frac{\partial h^{(t)}}{\partial W_{hh}}

But h(t)h^{(t)} depends on h(t1)h^{(t-1)}, which depends on h(t2)h^{(t-2)}, ... back to h(1)h^{(1)}!

Full gradient: L(t)Whh=k=1tL(t)y(t)y(t)h(t)h(t)h(k)h(k)Whh\frac{\partial L^{(t)}}{\partial W_{hh}} = \sum_{k=1}^{t} \frac{\partial L^{(t)}}{\partial y^{(t)}} \frac{\partial y^{(t)}}{\partial h^{(t)}} \frac{\partial h^{(t)}}{\partial h^{(k)}} \frac{\partial h^{(k)}}{\partial W_{hh}}

Where: h(t)h(k)=i=k+1th(i)h(i1)=i=k+1tWhTdiag(tanh(z(i)))\frac{\partial h^{(t)}}{\partial h^{(k)}} = \prod_{i=k+1}^{t} \frac{\partial h^{(i)}}{\partial h^{(i-1)}} = \prod_{i=k+1}^{t} W_{h}^T \cdot \text{diag}(\tanh'(z^{(i)}))

WHY this matters? This product of Jacobians causes vanishing/exploding gradients.


RNN Variants and Types


Common Mistakes and Fixes


Key Properties

Property Description
Parameter Sharing Same weights across all time steps → handles variable-length sequences
Hidden State h(t)h^{(t)} acts as memory, summary of sequence up to time tt
Inductive Bias Assumes nearby elements are more relevant than distant ones
Limitation Vanishing gradients → poor long-term dependencies (fixed by LSTM/GRU)

Computational Complexity

For a sequence of length TT:

  • Forward pass: O(Tdh2)O(T \cdot d_h^2) (matrix multiplications at each step)
  • Backward pass (BPTT): O(Tdh2)O(T \cdot d_h^2) (same, but gradients flow backward)
  • Space: O(Tdh)O(T \cdot d_h) (store hidden states for backprop)

Comparison to feedforward:

  • Feedforward: O(1)O(1) for one input, no sequential dependency
  • RNN: O(T)O(T) sequential operations, cannot parallelize across time

This sequential nature is RNN's key limitation compared to Transformers.


Recall Explain to a 12-year-old

Imagine you're reading a detective story. Each page gives you a clue. A normal robot brain (feedforward network) would look at each page separately and forget what it read before—useless for solving the mystery!

An RNN is like a detective's notebook. When you read page1, you write down important stuff in your notebook. On page 2, you read the NEW clue AND check your notebook to remember what you learned before. You update your notebook with this combined information. Page 3? Same thing—read new clue, check notebook, update.

The notebook is the "hidden state" (hh). The detective's brain uses the same thinking rules (weights WW) for every page, but the notebook contents change as you learn more. By the last page, your notebook has clues from the ENTIRE book, helping you say "The butler did it!"

Problem: If the book is 1000 pages long, the notebook might forget stuff from page 1 by page 1000—that's the vanishing gradient problem. Better detectives (LSTM, GRU) have special notebooks that can remember longer!


Connections


#flashcards/ai-ml

What is the purpose of the hidden state in RNNs? :: The hidden state h(t)h^{(t)} acts as memory, encoding information about all previous time steps, allowing the network to maintain context across the sequence.

Why do RNNs share weights across time steps?
Weight sharing allows RNNs to handle variable-length sequences with a fixed number of parameters, and provides an inductive bias that the sequence rules don't change over time (analogous to spatial weight sharing in CNNs).
Write the RNN hidden state update equation
h(t)=tanh(Whhh(t1)+Wxhx(t)+bh)h^{(t)} = \tanh(W_{hh} h^{(t-1)} + W_{xh} x^{(t)} + b_h) where WhhW_{hh} are recurrent weights, WxhW_{xh} are input weights, and tanh\tanh is the activation function.
What causes vanishing gradients in RNNs?
During backpropagation through time, gradients involve products of Jacobians iWhhTdiag(tanh)\prod_{i} W_{hh}^T \cdot \text{diag}(\tanh'). If Whh<1||W_{hh}|| < 1, repeated multiplication shrinks gradients exponentially, making it impossible to learn long-term dependencies.
What is the difference between many-to-one and many-to-many RNN architectures?
Many-to-one processes an input sequence and produces a single output (e.g., sentiment classification using final hidden state). Many-to-many processes an input sequence and produces an output sequence (e.g., machine translation), with potentially different input/output lengths.
Why initialize h(0)=0h^{(0)} = \mathbf{0} at the start of each new sequence?
Training examples are independent. Carrying over hidden state from a previous sequence creates spurious correlations, causing the network to learn patterns that don't actually exist across different sequences.
What is truncated BPTT and why use it?
Truncated Backpropagation Through Time limits gradient computation to kk time steps instead of the full sequence. This reduces memory usage and computation for long sequences, while still allowing forward propagation through the entire sequence.
How do you produce output from an RNN hidden state?
Apply a linear projection: y(t)=Whyh(t)+byy^{(t)} = W_{hy} h^{(t)} + b_y, then apply task-specific activation (softmax for classification, none for regression). This allows hidden dimension to differ from output dimension.
What is the computational complexity of RNN forward pass for sequence length TT?
O(Tdh2)O(T \cdot d_h^2) where dhd_h is hidden dimension. This is due to matrix multiplications at each time step. Unlike feedforward networks, RNN operations are sequential and cannot be parallelized across time.
Why use tanh\tanh activation instead of sigmoid RNN hidden state?
tanh\tanh outputs in range [1,1][-1, 1] (zero-centered) instead of sigmoid's [0,1][0, 1], which helps maintain healthier gradients during backpropagation and prevents bias shift issues in the hidden state.

Concept Map

processed by

maintains

acts as

feeds back via

updates

via W_xh

tanh activation

via W_hy

reuses

gives

enables

solves

Sequential data

RNN cell

Hidden state h_t

Memory

Recurrent weights W_hh

Input x_t

Non-linearity

Output y_t

Weight sharing

Parameter efficiency

Generalization across time

No-memory problem of feedforward nets

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Dekho, RNN ka core idea bahut simple hai — jab hum ek sentence padhte hain word by word, to "mat" tak pahuchne se pehle humein "cat" aur "sat" yaad rehta hai. Normal feedforward networks mein yeh memory nahi hoti, woh har input ko alag-alag treat karte hain. Isliye RNN ek hidden state (basically ek memory vector) rakhta hai jo time ke saath aage travel karta hai. Har time step par network current input ke saath purani memory ko combine karta hai, ek formula se: naya hidden state = tanh(purani memory + current input). Yahi loop-back connection RNN ko "sequential" data ke liye perfect banata hai.

Ab sabse important baat jo yaad rakhni hai woh hai weight sharing. Matlab jo weight matrices hain (WxhW_{xh}, WhhW_{hh}, WhyW_{hy}), woh har time step par same rehte hain — badalte nahi. Yeh isliye zaroori hai kyunki isse humein sirf ek fixed set of parameters chahiye, chahe sequence kitna bhi lamba ho. Aur jo pattern network position 1 par seekhta hai, woh position 5 par bhi apply ho jaata hai. Yeh CNN ke spatial weight sharing jaisa hi hai, bas yahan hum time ke across share kar rahe hain. Iska matlab hai ek strong assumption — ki "sequence ke rules time ke saath change nahi hote".

Yeh concept kyun matter karta hai? Kyunki real-world mein bahut saara data sequential hota hai — text, speech, stock prices, weather, sab kuch. In sab mein order aur context important hota hai, aur RNN humein woh "memory" deta hai jisse machine bhi context samajh sake. Language models, translation, speech recognition — yeh sab RNN (aur uske advanced versions jaise LSTM, GRU) ki foundation par khade hain. Toh agar aap sequence models ko samajhna chahte ho, to yeh hidden state aur weight sharing ka intuition aapki base hai — ise achhe se pakad lo, aage sab kuch isi par build hoga.

Go deeper — visual, from zero

Test yourself — Sequence Models

Connections