Variational Autoencoders: ELBO, Reparameterization, and KL Divergence
1009 words
5 min read
Visual companion
Python
Type and operator map
Python Week 1: the first filter for runtime behavior
View
Revision summary
What this note is really saying
Short form
# Variational Autoencoders: ELBO, Reparameterization, and KL Divergence ## 🎯 Learning Objectives - Understand the motivation for variational inference in latent variable models - Derive the ELBO (Evidence Lower Bound) from KL divergence - Implement the reparameterization trick for differentiable sampling - Compare...

Variational Autoencoders: ELBO, Reparameterization, and KL Divergence
🎯 Learning Objectives
- Understand the motivation for variational inference in latent variable models
- Derive the ELBO (Evidence Lower Bound) from KL divergence
- Implement the reparameterization trick for differentiable sampling
- Compare VAE with AE and understand the regularization effect of KL
📋 Prerequisites
- Bayesian inference basics
- KL divergence and entropy
- Autoencoder architecture
1. 📖 Core Content
1.1 The Generative Modeling Problem
We want to learn p(x) — the probability distribution of data. Latent variable models introduce a hidden variable z:
The problem: this integral is intractable for complex models (we'd need to integrate over all possible latent codes).
1.2 The ELBO Derivation
Starting from the log-likelihood:
Introduce an approximate posterior qϕ(z∣x):
Since DKL≥0:
Where:
- Eqϕ(z∣x)[logpθ(x∣z)]: Reconstruction loss (log-likelihood of data given latent)
- DKL(qϕ(z∣x)∣∣p(z)): KL regularization (encourages latent distribution to match prior)
1.3 The Reparameterization Trick
The sampling operation z∼qϕ(z∣x)=N(μ,σ2) is not differentiable. The reparameterization trick makes it differentiable:
Now gradients can flow through μ and σ:
python# runnable import torch import torch.nn as nn import torch.nn.functional as F class VAE(nn.Module): def __init__(self, input_dim=784, latent_dim=20, hidden_dim=400): super().__init__() # Encoder self.encoder = nn.Sequential( nn.Linear(input_dim, hidden_dim), nn.ReLU() ) self.mu_layer = nn.Linear(hidden_dim, latent_dim) self.logvar_layer = nn.Linear(hidden_dim, latent_dim) # Decoder self.decoder = nn.Sequential( nn.Linear(latent_dim, hidden_dim), nn.ReLU(), nn.Linear(hidden_dim, input_dim), nn.Sigmoid() ) def encode(self, x): h = self.encoder(x) return self.mu_layer(h), self.logvar_layer(h) def reparameterize(self, mu, logvar): """Reparameterization trick: z = μ + σ * ε""" if self.training: std = torch.exp(0.5 * logvar) eps = torch.randn_like(std) return mu + eps * std return mu # Deterministic at inference def decode(self, z): return self.decoder(z) def forward(self, x): mu, logvar = self.encode(x) z = self.reparameterize(mu, logvar) recon = self.decode(z) return recon, mu, logvar def vae_loss(recon, x, mu, logvar): """VAE loss = reconstruction + KL divergence""" # Reconstruction loss (binary cross-entropy) recon_loss = F.binary_cross_entropy(recon, x, reduction='sum') # KL divergence: KL(q(z|x) || p(z)) where p(z) = N(0, I) # Formula: -0.5 * sum(1 + log(σ²) - μ² - σ²) kl_loss = -0.5 * torch.sum(1 + logvar - mu.pow(2) - logvar.exp()) return recon_loss + kl_loss
1.4 Interpreting the KL Term
The KL divergence KL(qϕ(z∣x)∣∣N(0,I)) has two effects:
- Posterior collapse prevention: Prevents the encoder from mapping different inputs to distant latent codes
- Latent space regularization: Encourages the latent space to be smooth and continuous
| μ | σ² | KL | Effect |
|---|---|---|---|
| 0 | 1 | 0 | Perfect match to prior |
| 0.5 | 1 | 0.125 | Slight deviation |
| 2 | 1 | 2.0 | Large deviation (penalized) |
| 0 | 0.1 | 1.2 | Underconfident (too certain) |
| 0 | 3 | 0.39 | Overconfident (too uncertain) |
1.5 Beta-VAE
Beta-VAE introduces a weight β on the KL term:
β>1: Encourages disentangled representations (each latent dimension captures a separate factor of variation) β=0: Standard autoencoder (no regularization)
📝 Practice Questions
Q1<strong>Q1</strong>: Show that the ELBO is a lower bound on the log-likelihood.Start with log-likelihood: logp(x)=log∫p(x,z)dz =log∫q(z∣x)q(z∣x)p(x,z)dz ≥∫q(z∣x)logq(z∣x)p(x,z)dz (by Jensen's inequality: log(E[X]) ≥ E[log(X)]) =∫q(z∣x)logq(z∣x)p(x∣z)p(z)dz =∫q(z∣x)logp(x∣z)dz+∫q(z∣x)logq(z∣x)p(z)dz =Eq(z∣x)[logp(x∣z)]−KL(q(z∣x)∣∣p(z))This lower bound is the ELBO. Maximizing it improves the model's log-likelihood. Q2<strong>Q2<strong>Q2</strong>: In the reparameterization trick, why can't we directly sample z ~ N(μ, σ²) and backpropagate?Direct sampling: z = sample(N(μ, σ²))The gradient ∂z/∂μ and ∂z/∂σ doesn't exist — sampling is a stochastic operation with no defined gradient. The "sampling node" breaks the computation graph.Reparameterization: z = μ + σ·ε, ε ~ N(0,1)Now z is a deterministic function of μ, σ, and ε. Gradients ∂z/∂μ = 1 and ∂z/∂σ = ε exist and can be computed. The randomness comes from ε (external), which doesn't need gradients.This seemingly simple trick is what makes VAEs trainable with SGD. Q3<strong>Q3<strong>Q3<strong>Q3<strong>Q3</strong>: What is posterior collapse in VAEs, and how can it be detected?Posterior collapse: The KL term dominates the loss, and the encoder learns to map all inputs to the prior distribution: q(z∣x)≈p(z)=N(0,I).Symptoms:
- Ignored latent code: The decoder ignores z (produces same output regardless of input)
- KL divergence approaches 0: μ → 0, σ² → 1 for all inputs
- Reconstruction is blurry/mean: Decoder averages over all possibilities
- No latent structure: Interpolating in latent space doesn't change output
Causes: Powerful decoder (e.g., expressive autoregressive), weak latent, high β value.Fixes: Reduce β, use KL annealing, use a weaker decoder, increase latent dimensionality. Q4<strong>Q4<strong>Q4<strong>Q4<strong>Q4<strong>Q4</strong>: Compare VAEs and GANs on sample quality, latent space structure, and training stability.
| Aspect | VAE | GAN |
|---|---|---|
| Sample quality | Blurry, less sharp | Sharp, high quality |
| Latent space | Smooth, continuous (KL regularized) | Often less structured |
| Training stability | Stable (ELBO optimization) | Unstable (min-max game) |
| Likelihood | Tractable lower bound | No likelihood available |
| Mode coverage | Good (covers all modes) | Poor (mode collapse) |
| Mathematical framework | Variational inference | Game theory |
| Diversity | High | Low to moderate |
</details> * * * ## 🔗 Cross-References - **Next**: [Diffusion Models](/notes/04-degree-electives-bsda5002-genai-foundations-week04-04-diffusion-models) - **Previous**: [GANs](/notes/04-degree-electives-bsda5002-genai-foundations-week02-02-gans) - **Video**: BSDA5002 Week 4-5 transcripts [Join Discord](https://discord.gg/gE2m4Qrdqv) [Previous**GANs**](/notes/04-degree-electives-bsda5002-genai-foundations-week02-02-gans)[Next**Diffusion Models (DDPM)**](/notes/04-degree-electives-bsda5002-genai-foundations-week04-04-diffusion-models)VAEs excel at structured latent spaces (useful for interpolation, semi-supervised learning) while GANs excel at sample quality. Diffusion models (covered in Week 4-5) combine benefits of both.