3.5.7Sequence Models

Sequence-to-sequence models

2,572 words12 min readdifficulty · medium6 backlinks

What Problem Does Seq2Seq Solve?

The challenge: Standard neural networks expect fixed input/output sizes. But in machine translation, summarization, chatbots, the input "Bonjour" → output "Hello" has 1 token → 1 token, while "Comment ça va?" → "How are you doing?" has 3 → 4 tokens.

The breakthrough: Decouple input processing from output generation.

  • Encoder: Reads the entire input sequence x1,x2,,xTxx_1, x_2, \dots, x_{T_x} and produces a context vector c\mathbf{c} (the "thought").
  • Decoder: Generates output sequence y1,y2,,yTyy_1, y_2, \dots, y_{T_y} conditioned on c\mathbf{c}, one token at a time.

Why this works: The context vector is a learned, compressed representation. The decoder learns to "unfold" this representation into the target language/format.


Architecture Derivation from First Principles

Step 1: The Encoder

We need to process a variable-length input. What structure handles sequences? RNNs, LSTMs, or GRUs.

Let the encoder be an LSTM. At each time step tt: ht(enc)=LSTM(xt,ht1(enc))h_t^{(enc)} = \text{LSTM}(x_t, h_{t-1}^{(enc)})

After processing all TxT_x tokens, the final hidden state hTx(enc)h_{T_x}^{(enc)} contains information about the entire input. We set: c=hTx(enc)\mathbf{c} = h_{T_x}^{(enc)}

Why the final state? In an LSTM, information flows forward. The last hidden state has "seen" all previous tokens (though it might forget early ones—this motivates attention later).


Step 2: The Decoder

The decoder generates the output sequence. At each decoding step tt: ht(dec)=LSTM(c,yt1,ht1(dec))h_t^{(dec)} = \text{LSTM}(\mathbf{c}, y_{t-1}, h_{t-1}^{(dec)})

Wait, what's yt1y_{t-1}? The previous output token. During training, we use teacher forcing: feed the ground-truth previous token. During inference, we feed the model's own prediction.

The decoder's hidden state ht(dec)h_t^{(dec)} is passed through a softmax layer to predict the next token: P(yty<t,c)=softmax(Woht(dec)+bo)P(y_t \mid y_{<t}, \mathbf{c}) = \text{softmax}(W_o h_t^{(dec)} + b_o)

Why softmax? We're choosing one token from a vocabulary VV, so we need a probability distribution over V|V| classes.

The full sequence probability (assuming conditional independence given c\mathbf{c}): P(y1,,yTyx1,,xTx)=t=1TyP(yty<t,c)P(y_1, \dots, y_{T_y} \mid x_1, \dots, x_{T_x}) = \prod_{t=1}^{T_y} P(y_t \mid y_{<t}, \mathbf{c})


Step 3: Training with Cross-Entropy

We have ground-truth pairs (x,y)(x, y). The loss for one example: L=t=1TylogP(yty<t,c)\mathcal{L} = -\sum_{t=1}^{T_y} \log P(y_t^* \mid y_{<t}^*, \mathbf{c})

where yty_t^* is the true target token at position tt.

Why negative log-likelihood? We want to maximize the probability of the correct sequence. Maximizing logP(yx)\log P(y \mid x) is equivalent to minimizing logP(yx)-\log P(y \mid x).

Backpropagation: Gradients flow backward through the decoder, into c\mathbf{c}, then through the encoder. This is backpropagation through time (BPTT) across two RNNs.


Training vs. Inference: The Critical Difference

Training (Teacher Forcing)

Input:  "I love AI" 
Target: "<SOS> Me encanta IA <EOS>"

Decoder sees at t=1: <SOS> (from target)
Decoder predicts: "Me" (loss if wrong)

Decoder sees at t=2: "Me" (ground truth, not prediction!)
Decoder predicts: "encanta"
... and so on

Why teacher forcing? Speeds up training. The model gets the correct context at each step, rather than compounding errors.

Inference (Autoregressive Generation)

Input: "I love AI"
Decoder starts with <SOS>

t=1: Decoder predicts "Me" (from <SOS>)
t=2: Decoder uses "Me" to predict "encanta"
t=3: Decoder uses "encanta" to predict "IA"
t=4: Decoder predicts <EOS>, stop.

The exposure bias problem: At training, the decoder never sees its own mistakes. At inference, one wrong prediction can cascade. This is a known weakness of teacher forcing.


Worked Example: English → Spanish Translation

Input: "I am happy"
Target: "Estoy feliz"

Encoding Phase

Vocabulary: {I, am, happy} → {0, 1, 2}
Embed: x1=E[0],x2=E[1],x3=E[2]x_1 = E[0], x_2 = E[1], x_3 = E[2]

Encoder LSTM (simplified, dh=4d_h = 4):

h_0 = [0,0,0]
h_1 = LSTM(x_1, h_0) → [0.2, -0.1, 0.5, 0.3]
h_2 = LSTM(x_2, h_1) → [0.4, 0.2, 0.1, -0.2]
h_3 = LSTM(x_3, h_2) → [0.1, 0.6, -0.3, 0.4]

Context vector c = h_3 = [0.1, 0.6, -0.3, 0.4]

Decoding Phase

Target vocab: {, Estoy, feliz, } → {0, 1, 2, 3}

Initialize decoder with c\mathbf{c}:

Input: y_0 = <SOS> (token 0)
h_1^(dec) = LSTM(c, E[0], h_0^(dec))
Output: P(y_1|c) = softmax(W_o h_1^(dec))
       = [0.01, 0.92, 0.05, 0.02]  # Predicts "Estoy" (token 1)

Input: y_1 = "Estoy" (token 1, teacher forcing)
h_2^(dec) = LSTM(c, E[1], h_1^(dec))
Output: P(y_2|y_1,c) = [0.02, 0.03, 0.93, 0.02]  # Predicts "feliz" (token 2)

Input: y_2 = "feliz" (token 2)
h_3^(dec) = LSTM(c, E[2], h_2^(dec))
Output: P(y_3|y_1,y_2,c) = [0.01, 0.02, 0.03, 0.94]  # Predicts <EOS> (token 3)

Loss calculation (assuming these are the correct predictions): L=log(0.92)log(0.93)log(0.94)0.24\mathcal{L} = -\log(0.92) - \log(0.93) - \log(0.94) \approx 0.24

Why this step? We sum negative log-probs of the correct tokens. Lower loss means higher confidence in correct sequence.


Common Decoding Strategies

1. Greedy Decoding

Pick the highest-probability token at each step: yt=argmaxvP(vy<t,c)y_t = \arg\max_{v} P(v \mid y_{<t}, \mathbf{c})

Fast but suboptimal: Doesn't consider future consequences. Picking the best word now might lead to a dead-end later.

Maintain top-kk candidate sequences at each step. Expand, keep top-kk again.

Example with beam width k=2k=2:

Step 1: <SOS> → {"Estoy" (0.9), "Yo" (0.7)}

Step 2 (expand both):
  "Estoy" → {"Estoy feliz" (0.9×0.8=0.72), "Estoy contento" (0.9×0.6=0.54)}
  "Yo" → {"Yo soy" (0.7×0.5=0.35), "Yo estoy" (0.7×0.4=0.28)}
  
Keep top 2: {"Estoy feliz" (0.72), "Estoy contento" (0.54)}

Why beam search? Balances exploration and efficiency. Considers multiple paths without exhaustive search.


Special Tokens and the Mechanism

Problem: How does the decoder know when to stop?

Solution: Add a special end-of-sequence (EOS) token to the vocabulary. Train the model to predict <EOS> when the output is complete.

Training data:
Input:  "Hello"
Target: "<SOS> Hola <EOS>"

At inference, we stop generating when the model outputs <EOS> or we hit a max length (safety).

Why <SOS>? The decoder needs an initial input. <SOS> (start-of-sequence) signals the beginning.


The Information Bottleneck Problem

Why it feels right: The LSTM's hidden state is designed to carry forward information.

The reality: A fixed-size vector c\mathbf{c} (e.g., 512 dimensions) must encode everything about a potentially long input (e.g., 50 tokens, each with rich meaning). For long sequences, early information gets forgotten—the LSTM's memory is limited.

The fix: Attention mechanisms (next topic). Instead of one fixed c\mathbf{c}, the decoder computes a different context vector at each decoding step by "looking back" at all encoder hidden states.

Steel-man the mistake: For short sequences (5-10 tokens), the bottleneck isn't severe. The original seq2seq paper (Sutskever et al., 2014) got good results on moderate-length sentences. The problem becomes critical for documents, paragraphs, or nuanced context.


Bidirectional Encoder Improvement

Limitation: A unidirectional encoder at token tt has only seen x1,,xtx_1, \dots, x_t, not future tokens.

Enhancement: Use a bidirectional RNN/LSTM as encoder: ht=LSTMforward(xt,ht1)\overrightarrow{h}_t = \text{LSTM}_{\text{forward}}(x_t, \overrightarrow{h}_{t-1}) ht=LSTMbackward(xt,ht+1)\overleftarrow{h}_t = \text{LSTM}_{\text{backward}}(x_t, \overleftarrow{h}_{t+1})

Concatenate: ht(enc)=[ht;ht]h_t^{(enc)} = [\overrightarrow{h}_t; \overleftarrow{h}_t]

The context vector becomes: c=[hTxforward;h1backward]\mathbf{c} = [h_{T_x}^{\text{forward}}; h_1^{\text{backward}}]

Why this helps: The encoder now has information about the entire sequence at every position. The word "bank" can be understood differently if followed by "river" vs. "money".


Input: "The cat sat on the mat. It was very comfortable."
Target: "Cat on mat."

Encoder

Tokenize input: ["The", "cat", "sat", "on", "the", "mat", ".", "It", "was", "very", "comfortable", "."]
Process through bidirectional LSTM → cR512\mathbf{c} \in \mathbb{R}^{512}

Decoder

t=1: Input <SOS>, output "Cat" (prob 0.85)
t=2: Input "Cat", output "on" (prob 0.78)
t=3: Input "on", output "mat" (prob 0.82)
t=4: Input "mat", output "." (prob 0.91)
t=5: Input ".", output <EOS> (prob 0.95)

Loss: log(0.85)log(0.78)log(0.82)log(0.91)log(0.95)0.77-\log(0.85) - \log(0.78) - \log(0.82) - \log(0.91) - \log(0.95) \approx 0.77

Why each step?

  • t=1: Decoder learns to pick the most salient subject.
  • t=2-3: Learns to compress "sat on the" → "on".
  • t=4: Punctuation is part of well-formed output.
  • t=5: Termination signal.

When to Use Seq2Seq

Use Case Why Seq2Seq Fits
Machine Translation Variable-length input/output, meaning transfer
Text Summarization Long input → short output, content selection
Chatbots Input query → response, dialogue context
Speech Recognition Audio frames → text tokens
Video Captioning Frame sequence → sentence

Not ideal for: Tasks where input/output alignment is known (e.g., POS tagging—here, each input word gets one tag; simpler models suffice).



Recall Explain to a 12-Year-Old

Imagine you're playing a game of "telephone" but in two languages. You hear a sentence in English, and you need to whisper it in Spanish to the next person. But here's the trick: you can't just translate word-by-word because the sentence structure is different!

So you do it in two steps:

  1. Listen carefully to the whole English sentence and remember the idea in your head (that's the encoder making the context vector).
  2. Say it in Spanish, one word at a time, using what you remembered (that's the decoder).

The "context vector" is like a mental note you made: "They're talking about a happy cat on a mat." Then you speak Spanish words that match that mental note, not the exact English words. That's why the lengths can be different—you're translating ideas, not just words!


Or simply: "Understand, Remember, Speak" (Encoder understands, Context remembers, Decoder speaks).


Connections


#flashcards/ai-ml

What are the two main components of a seq2seq model? :: Encoder (processes input into context vector) and Decoder (generates output from context)

Why is teacher forcing used during training?
To speed up training and provide correct context at each step, though it creates exposure bias at inference time
What is the context vector in seq2seq?
The final hidden state of the encoder (h_Tx), a fixed-size representation encoding the entire input sequence
How does the decoder generate output tokens?
Autoregressively: at each step t, it takes the context vector and previous token y_{t-1}, outputs a distribution over vocabulary via softmax
What is the information bottleneck problem?
The fixed-size context vector cannot adequately encode long input sequences, leading to information loss (solved by attention)
What is beam search and why use it?
A decoding strategy that keeps top-k candidate sequences at each step; balances exploration vs. gredy decoding's myopia
Why use bidirectional encoder?
To give each token access to both past and future context in the input, improving representation quality
What is the loss function for seq2seq training?
Negative log-likelihood (cross-entropy) sumed over all output tokens: -Σ log P(y_t* | y_{<t}, c)
What signals the decoder to stop generating?
Predicting the (end-of-sequence) special token or hitting max length limit
What's the difference between training and inference in seq2seq?
Training uses teacher forcing (ground-truth previous tokens), inference uses model's own predictions (autoregressive)

Concept Map

solved by

splits into

splits into

read by

final hidden state

conditions

hidden state

softmax over vocab

feeds prev token to

product of probs

negative log

Variable length seq problem

Seq2Seq model

Encoder LSTM

Decoder LSTM

Input tokens x1..xTx

Context vector c

Decoder state

Output tokens y1..yTy

Teacher forcing

Sequence probability

Cross-entropy loss

Hinglish (regional understanding)

Intuition Hinglish mein samjho

Dekho, seq2seq models ka concept bahut simple hai lekin powerful. Jab tumhe ek language se dosri language mein translate karna ho, ya phir ek lambi text ko summarize karna ho, toh input aur output ki lengths different ho sakti hain. Ek normal neural network fixed size expect karta hai, lekin translation mein "Namaste" ek word hai aur "Hello" bhi ek word, par "Aap kaise hain?" teen words hain aur "How are you?" bhi teen hain, lekin structure alag hai.

Seq2seq ne is problem ko solve kiya do parts mein – encoder aur decoder. Encoder pora input sentence padhta hai aur ek chota sa "meaning vector" (context vector) bana leta hai, jisme pori input ki information compressed form mein hoti hai. Sochlo jaise tumne ek paragraph padha aur ek sentence mein summary yad rakh li. Phir decoder us summary ko use karke output generate karta hai,ek token (word) at a time. Training mein hum "teacher forcing" use karte hain – matlab decoder ko actual correct previous word dikhate hain, lekin inference (real use) mein decoder apne hi predictions use karta hai.

Ismek badi problem hai jo "information bottleneck" kehte hain – agar input bahut lamba ho (50-100 words), toh ek fixed-size context vector mein sab kuch fit nahi ho pata, aur starting ki information bhool jati hai. Isliye bad mein "attention mechanism" aya, jo is problem ko solve karta hai. Lekin basic seq2seq ne machine translation aur chatbots ka foundation rakha, aur aj bhi simple tasks ke liye use hota hai. Ye architecture samajhna zaroori hai kyunki modern models (Transformers) bhi isi idea ko extend karte hain – encode karo, compress karo, decode karo. Ye technique sirf translation ke liye nahi, speech recognition, summarization, aur dialogue systems mein bhi kaam ati hai, jahan variable-length input/output natural hai.

Go deeper — visual, from zero

Test yourself — Sequence Models

Connections