33 — Generative & Prob.

VAE — Variational Autoencoder#

GenerativeMathematical
◆ The PatternLearning a structured latent space for generation and interpolation

A VAE encodes inputs to a distribution over latent vectors, then decodes samples. The KL term forces a smooth, continuous latent space.

ELBO = E[log p(x|z)] − KL(q(z|x) || p(z))
ELBO = reconstruction + KL regularization
z = μ + σ·ε    ε ~ N(0,1)
Reparameterization trick: makes sampling differentiable
// VAE architecture diagram
Pattern bridge: Encoding data into a structured latent space, then decoding it. The KL term is a normal distribution regularizer — pulling the latent space toward Gaussian structure.
Worked example

For one input the encoder outputs μ = 1 and σ = 0.5. Sampling z = μ + σ·ε moves the randomness into ε, so gradients can flow through μ and σ; five samples land at 0.60, 1.12, 0.17, 1.33 and 1.57. The KL penalty that pulls this towards a standard normal is 0.818 nats: the price of a smooth latent space.

Where it misleads
  • With a powerful decoder the KL term can drive the encoder to ignore the input (“posterior collapse”, Bowman et al. 2016).
  • VAE samples tend to be blurrier than GAN or diffusion samples, partly because of the Gaussian likelihood.
  • The ELBO is a lower bound; a better bound does not always mean better samples.
In code
rng = np.random.default_rng(9)
mu, sigma = 1.0, 0.5                             # what the encoder outputs for one input
z = mu + sigma * rng.normal(size=5)              # reparameterization: randomness moved into eps
kl = 0.5 * (sigma ** 2 + mu ** 2 - 1 - np.log(sigma ** 2))   # KL(N(mu, sigma^2) || N(0, 1))
Python, in your browser — edit the code and run it again

Assumes import numpy as np. Each snippet carries its own example numbers; the comments say which are made up or simulated.

The same idea with a library
class VAE(nn.Module):
    def forward(self, x):
        mu, log_var = self.encode(x)
        z = mu + torch.exp(0.5*log_var) * torch.randn_like(mu)
        return self.decode(z), mu, log_var

def vae_loss(recon_x, x, mu, log_var):
    recon = F.mse_loss(recon_x, x)
    kl    = -0.5 * torch.mean(1 + log_var - mu**2 - log_var.exp())
    return recon + kl
Sources
  • D. P. Kingma & M. Welling, “Auto-Encoding Variational Bayes”, ICLR, 2014
  • D. J. Rezende, S. Mohamed & D. Wierstra, “Stochastic Backpropagation and Approximate Inference in Deep Generative Models”, ICML, 2014
  • S. R. Bowman et al., “Generating Sentences from a Continuous Space”, CoNLL, 2016

Last reviewed October 2026 · How this site checks its content · Report a mistake

Linked from 1
← Previous
SVD
Open in the full reader, with the topic sidebar