Part III: Discovery Through Data and Models
Chapter 34: Generative Models for Discovery

34.1 Generative Models as Hypothesis Generators

"My discriminator says this molecule is fake. My chemist says it binds the target. One of them is wrong, and I know which one I trust more."

A GAN That Discovered Drug Candidates

Prerequisites

This section opens Chapter 34 on generative models for scientific discovery. You should be comfortable with neural network training (loss functions, backpropagation, gradient descent) and latent space concepts from Chapter 26: Representation Learning. The probability background from Appendix A: Mathematical Foundations (distributions, KL divergence, expectations) is essential for understanding the ELBO derivation. Familiarity with Bayesian inference from Chapter 32: Bayesian Discovery will deepen your understanding but is not strictly required.

The Big Picture

Discriminative models answer "what is this?" Generative models answer "what could exist?" In scientific discovery, the second question is far more powerful. A classifier trained on known molecules tells you whether a compound is drug-like. A generative model trained on the same data proposes entirely new compounds that satisfy drug-likeness constraints. This shift from recognition to creation transforms machine learning from an analysis tool into a hypothesis generator. The challenge is building generative models that produce not just plausible outputs but physically valid, synthesizable, and functionally useful ones. This section surveys four generative architectures (variational autoencoders (VAEs), generative adversarial networks (GANs), autoregressive models, normalizing flows), explains why diffusion models displaced them for most scientific applications, and establishes the mathematical foundations that the rest of the chapter builds on.

1. The Generative Modeling Problem

Traditional screening libraries contain millions of compounds, yet cover less than 0.001% of estimated drug-like chemical space; when a promising target has no known binders, exhaustive search is simply futile. Generative models bypass that bottleneck by learning to propose candidates directly from the highest-probability regions of chemical space. What if you could hand a machine the entire known pharmacopeia and ask it to invent the next antibiotic? Given a dataset \(\mathcal{D} = \{x_1, x_2, \ldots, x_N\}\) drawn from an unknown data distribution \(p_{\text{data}}(x)\), a generative model learns an approximation \(p_\theta(x)\) from which we can sample new data points. In scientific contexts, \(x\) might represent a molecular graph, a protein backbone, a crystal structure, or a material composition. The quality of the generative model depends on two properties: coverage (can it generate all valid structures in the target distribution?) and precision (does every generated sample satisfy the validity constraints of the domain?).

A generative model defines a parametric probability distribution \(p_\theta(x)\) fitted to observed data. New samples drawn from \(p_\theta\) should be statistically indistinguishable from samples drawn from the true data distribution \(p_{\text{data}}\). The model proposes candidates that have never been observed, rather than analyzing existing data. That proposal loop is the core of scientific hypothesis generation. The mechanism is density estimation: the model learns where probability mass concentrates in data space. For example, it identifies which regions of chemical space contain drug-like molecules. Sampling from that learned density produces new points in high-probability regions. Use a generative model instead of a discriminative one whenever the goal is to propose new candidates rather than classify existing ones. Use retrieval or combinatorial enumeration when the search space is small enough to enumerate explicitly (fewer than roughly \(10^6\) candidates).

Coverage and precision define the core discovery trade-off. High coverage with low precision produces many invalid molecules alongside a few interesting ones. High precision with low coverage yields valid but unoriginal molecules from a narrow region of chemical space. Each generative architecture balances this trade-off differently. In short: A generative model is a machine for proposing what has never been observed, and the art lies in ensuring those proposals are not just novel but physically real.

In practice, generative models serve as hypothesis generators through a propose-evaluate-refine cycle. The model proposes candidate structures (molecules, proteins, materials) by sampling from its learned distribution. A domain-specific evaluator (a docking simulation, a property predictor, a physics-based energy function) scores each candidate. The scores then feed back into the model, either by retraining on the highest-scoring candidates, by adjusting the sampling distribution through conditioning, or by optimizing directly in the latent space. Each iteration narrows the search toward structures that are both statistically plausible and scientifically useful. The architectures surveyed below differ in how they represent the learned distribution and how readily they support this feedback loop.

Common Misconception

A common misconception is that a generative model with high validity (say, 95% of outputs parse as valid molecules) has "learned chemistry." In reality, high validity means the model has learned the syntactic rules of the representation (for example, matching parentheses in Simplified Molecular-Input Line-Entry System (SMILES) strings or correct valence counts in molecular graphs), not the physical or biological properties of the generated compounds. A model can produce thousands of valid molecules that are all unstable, unsynthesizable, or biologically inert. Validity is a necessary floor, not evidence of scientific understanding.

Key Insight: Generative Models Invert the Data Pipeline

In standard machine learning, the pipeline runs data \(\to\) features \(\to\) prediction. Generative models invert this: specification \(\to\) latent code \(\to\) data. This inversion is what makes them useful for discovery. Instead of asking "what properties does this molecule have?", you ask "generate a molecule with these properties." The mathematical machinery (latent spaces, score functions (gradients of the log-density, covered in Section 34.2), denoising) all serves this inversion. When the inversion is accurate and the latent space is well-structured, the generative model becomes a design tool. When it is not, you get plausible-looking nonsense. The evaluation section in Section 34.4 explains how to tell the difference.

2. Variational Autoencoders (VAEs)

A variational autoencoder (Kingma and Welling, 2014) introduces a latent variable \(z\) and factorizes generation into two steps: sample \(z \sim p(z)\) from a simple prior (usually a standard normal), then map \(z\) to data space with a decoder \(p_\theta(x|z)\). The marginal likelihood of the data is:

$$p_\theta(x) = \int p_\theta(x|z) \, p(z) \, dz$$

This integral is intractable for nonlinear decoders. The VAE sidesteps this by introducing an encoder \(q_\phi(z|x)\) that approximates the true posterior \(p_\theta(z|x)\), then optimizing the Evidence Lower BOund (ELBO):

$$\log p_\theta(x) \geq \mathbb{E}_{q_\phi(z|x)}[\log p_\theta(x|z)] - D_{\text{KL}}(q_\phi(z|x) \| p(z)) = \text{ELBO}(\theta, \phi; x)$$

The first term is the reconstruction loss: the decoder must reconstruct the input from the latent code. The second term is the Kullback-Leibler (KL) regularization: the encoder's posterior should stay close to the prior. This creates a tension. Strong regularization (\(D_{\text{KL}} \to 0\)) makes the latent space smooth and interpolable but degrades reconstruction. Weak regularization gives sharp reconstructions but a disorganized latent space where sampling from the prior produces garbage.

Mental Model

Think of the ELBO trade-off like organizing a library. The reconstruction term is the requirement that every book can be found from its catalog entry (the latent code). The KL term is the requirement that the catalog uses the Dewey Decimal System (the prior) rather than an idiosyncratic personal scheme. A perfectly personal catalog lets you retrieve every book flawlessly but is useless to anyone browsing the shelves by topic. A strictly Dewey-organized catalog lets browsers find related books nearby (smooth interpolation in latent space) but sometimes files a quantum physics textbook under "cookbooks" (reconstruction error). The \(\beta\) parameter in \(\beta\)-VAE is how strictly you enforce the Dewey system: low \(\beta\) lets the librarian bend the rules for accuracy, high \(\beta\) insists on a clean, browsable organization at the cost of some mis-shelved books.

The reparameterization trick makes the ELBO differentiable with respect to \(\phi\). Instead of sampling \(z \sim q_\phi(z|x) = \mathcal{N}(\mu_\phi(x), \sigma_\phi^2(x))\) directly (which blocks gradient flow), we write \(z = \mu_\phi(x) + \sigma_\phi(x) \cdot \epsilon\) where \(\epsilon \sim \mathcal{N}(0, I)\). The randomness is now in \(\epsilon\), independent of \(\phi\), so gradients pass through \(\mu_\phi\) and \(\sigma_\phi\) normally.

import torch
import torch.nn as nn
import torch.nn.functional as F

class MolecularVAE(nn.Module):
    """VAE for SMILES-encoded molecules."""

    def __init__(self, vocab_size: int, max_len: int, latent_dim: int = 128):
        super().__init__()
        self.max_len = max_len
        self.latent_dim = latent_dim

        # Encoder: 1D convolutions over SMILES characters
        self.conv1 = nn.Conv1d(vocab_size, 64, kernel_size=9, padding=4)
        self.conv2 = nn.Conv1d(64, 64, kernel_size=9, padding=4)
        self.conv3 = nn.Conv1d(64, 32, kernel_size=11, padding=5)
        self.fc_enc = nn.Linear(32 * max_len, 256)
        self.fc_mu = nn.Linear(256, latent_dim)
        self.fc_logvar = nn.Linear(256, latent_dim)

        # Decoder: GRU over latent code
        self.fc_dec = nn.Linear(latent_dim, 256)
        self.gru = nn.GRU(256, 512, num_layers=3, batch_first=True)
        self.fc_out = nn.Linear(512, vocab_size)

    def encode(self, x):
        """x: (batch, vocab_size, max_len) one-hot encoded SMILES."""
        h = F.relu(self.conv1(x))
        h = F.relu(self.conv2(h))
        h = F.relu(self.conv3(h))
        h = h.view(h.size(0), -1)
        h = F.relu(self.fc_enc(h))
        return self.fc_mu(h), self.fc_logvar(h)

    def reparameterize(self, mu, logvar):
        """Sample z = mu + sigma * epsilon (reparameterization trick)."""
        std = torch.exp(0.5 * logvar)
        eps = torch.randn_like(std)
        return mu + std * eps

    def decode(self, z):
        """z: (batch, latent_dim) -> (batch, max_len, vocab_size) logits."""
        h = F.relu(self.fc_dec(z))
        h = h.unsqueeze(1).repeat(1, self.max_len, 1)  # repeat for each position
        h, _ = self.gru(h)
        return self.fc_out(h)

    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_logits, target, mu, logvar):
    """ELBO loss: reconstruction (cross-entropy) + KL divergence."""
    # Reconstruction: cross-entropy per character position
    recon_loss = F.cross_entropy(
        recon_logits.view(-1, recon_logits.size(-1)),
        target.view(-1),
        reduction='mean'
    )
    # KL divergence: closed form for diagonal Gaussian vs N(0,I)
    kl_loss = -0.5 * torch.mean(1 + logvar - mu.pow(2) - logvar.exp())
    return recon_loss + kl_loss
Molecular VAE with convolutional encoder and GRU decoder for SMILES strings, including the reparameterization trick in reparameterize() and the closed-form ELBO loss combining per-character cross-entropy reconstruction with KL regularization against a standard normal prior.

Molecular VAEs typically achieve roughly 70 to 85% validity (fraction of generated SMILES that parse into valid molecules) on drug-like compound datasets, depending on architecture and hyperparameter choices. The primary failure mode is the KL-reconstruction trade-off: the model either memorizes training molecules (low KL) or generates diverse but often invalid structures (high KL). The \(\beta\)-VAE variant (Higgins et al., 2017) adds a weight \(\beta\) to the KL term, letting you tune this trade-off explicitly.

Step-Through: VAE Reparameterization and Sampling

Trace through a single forward pass of a VAE with latent dimension 2. Suppose the encoder receives molecule "CCO" (ethanol) and outputs \(\mu = [1.5, -0.8]\) and \(\log\sigma^2 = [-1.0, -2.0]\). First compute \(\sigma\): $\sigma = [\exp(-0.5) , \exp(-1.0)] = [0.607, 0.368]$. Draw \(\epsilon = [0.3, -1.2]\) from \(\mathcal{N}(0, I)\). The latent code is $z = \mu + \sigma \odot \epsilon = [1.5 + 0.607 \times 0.3,\; -0.8 + 0.368 \times (-1.2)] = [1.682, -1.242]$. Now compute the KL term for each dimension: \(\text{KL}_1 = 0.5(1.5^2 + e^{-1.0} - (-1.0) - 1) = 0.5(2.25 + 0.368 + 1.0 - 1) = 1.309\); \(\text{KL}_2 = 0.5(0.64 + e^{-2.0} - (-2.0) - 1) = 0.5(0.64 + 0.135 + 2.0 - 1) = 0.888\). Total KL = 2.197. This penalizes the encoder for placing ethanol's code far from the origin (the \(\mu^2\) terms) and for using narrow variance (the \(\log\sigma^2\) and \(e^{\log\sigma^2}\) terms). The decoder then maps \(z = [1.682, -1.242]\) to a probability distribution over SMILES characters at each position, and cross-entropy against the target "CCO" gives the reconstruction loss.

3. Generative Adversarial Networks (GANs)

The VAE's explicit density model and smooth latent space come at the cost of blurry outputs; GANs sacrifice those properties in favor of sharp, high-fidelity samples by eliminating the likelihood function entirely.

GANs (Goodfellow et al., 2014) take a completely different approach: train a generator \(G_\theta\) to map noise \(z \sim p(z)\) to data space, while simultaneously training a discriminator \(D_\phi\) to distinguish real data from generated samples. The two networks play a minimax game:

$$\min_\theta \max_\phi \, \mathbb{E}_{x \sim p_{\text{data}}}[\log D_\phi(x)] + \mathbb{E}_{z \sim p(z)}[\log(1 - D_\phi(G_\theta(z)))]$$

At equilibrium (if it exists), the generator produces samples indistinguishable from real data. The theoretical appeal is that GANs do not require an explicit likelihood function, making them applicable to complex data types where defining \(p_\theta(x)\) is difficult. Unlike VAEs, which optimize a bound on the log-likelihood, GANs learn through a game between two networks, so their quality signal comes from the discriminator rather than from an explicit probability computation.

In practice, GANs for scientific applications, particularly drug discovery, face two serious problems. Mode collapse, where the generator learns to produce a small set of high-quality samples that fool the discriminator, ignoring most of the data distribution: for drug discovery, this means the model might generate 50 variants of aspirin and nothing else. Training instability: the generator and discriminator can oscillate rather than converge, requiring careful hyperparameter tuning and architectural choices. The Wasserstein GAN (Arjovsky et al., 2017) partially addresses both problems. It replaces the Jensen-Shannon divergence (a symmetric measure of how different two probability distributions are, derived from KL divergence) with the Wasserstein distance (also called earth mover's distance, a measure of the minimum "work" needed to transform one probability distribution into another) , providing smoother gradients. The Wasserstein distance also yields a meaningful training signal even when the generator distribution does not overlap with the data distribution.

Practical Example: ORGAN for Molecular Optimization

Guimaraes et al. (2017) introduced ORGAN (Objective-Reinforced Generative Adversarial Network), which augments a GAN with a reward signal for molecular properties. The generator produces SMILES strings; the discriminator judges chemical plausibility; and a separate reward function scores properties like Quantitative Estimate of Drug-likeness (QED) and synthetic accessibility (SA). The combined objective balances realism and utility. In benchmarks on the ZINC dataset, ORGAN produces molecules with higher QED scores than the training distribution while maintaining 85% validity. The key insight is that the GAN provides a learned quality signal (the discriminator) while REINFORCE, where REINFORCE is a policy gradient algorithm that uses the reward signal to update the generator's parameters without differentiating through the reward function (covered in Section 34.4), steers toward task-specific properties.

4. Autoregressive Models and Normalizing Flows

Autoregressive models factorize the joint distribution as a product of conditionals:

$$p_\theta(x) = \prod_{i=1}^{n} p_\theta(x_i | x_1, \ldots, x_{i-1})$$

Each token (atom, bond, or SMILES character) is generated conditioned on all previous tokens. This is the architecture behind language models, and it transfers naturally to molecular strings. The advantage is exact likelihood computation and stable training. The disadvantage for 3D scientific structures is that the sequential generation order is arbitrary: there is no natural "first atom" in a molecule. Graph-based autoregressive models (You et al., 2018) generate molecules node by node, choosing which atom to add next and where to connect it. These achieve higher validity (often 95%+) than SMILES-based models because each step can check chemical valency constraints before committing. (That gap matters: a SMILES-based VAE producing 70% valid molecules wastes nearly a third of every generation batch, while a graph-based autoregressive model at 95%+ validity makes almost every sample usable.)

Checkpoint

So far: VAEs learn a smooth latent space but trade off reconstruction against regularity; GANs produce sharp samples but suffer mode collapse and training instability; autoregressive models achieve high validity through sequential dependency enforcement but impose an arbitrary generation order on inherently unordered structures.

Normalizing flows (Rezende and Mohamed, 2015) construct an invertible mapping \(f_\theta: \mathbb{R}^d \to \mathbb{R}^d\) that transforms a simple base distribution (Gaussian) into the data distribution. The change-of-variables formula gives the exact log-likelihood:

$$\log p_\theta(x) = \log p_z(f_\theta^{-1}(x)) + \log \left| \det \frac{\partial f_\theta^{-1}}{\partial x} \right|$$

where the determinant of the Jacobian \(\frac{\partial f_\theta^{-1}}{\partial x}\) accounts for how the transformation stretches or compresses volume in data space (intuitively, regions where the mapping compresses many data points into a small latent region receive higher density). Flows provide exact likelihood and exact sampling (both forward and inverse passes are available), making them attractive for density estimation. However, the invertibility constraint limits architectural expressiveness. Continuous normalizing flows (CNFs), which parameterize the transformation as an ODE, relax this constraint at the cost of requiring an ODE solver during training. Flow matching (Section 34.2) builds on this idea while avoiding the ODE solver bottleneck.

import torch
import torch.nn as nn
from torch.distributions import Normal

class AffineCouplingLayer(nn.Module):
    """Single affine coupling layer for a normalizing flow."""

    def __init__(self, dim: int, hidden_dim: int = 256):
        super().__init__()
        half = dim // 2
        # Scale and translation networks
        self.scale_net = nn.Sequential(
            nn.Linear(half, hidden_dim), nn.ReLU(),
            nn.Linear(hidden_dim, hidden_dim), nn.ReLU(),
            nn.Linear(hidden_dim, dim - half), nn.Tanh()
        )
        self.translate_net = nn.Sequential(
            nn.Linear(half, hidden_dim), nn.ReLU(),
            nn.Linear(hidden_dim, hidden_dim), nn.ReLU(),
            nn.Linear(hidden_dim, dim - half)
        )

    def forward(self, x):
        """Forward pass: data -> latent (used for training)."""
        x1, x2 = x.chunk(2, dim=-1)
        s = self.scale_net(x1)       # log-scale
        t = self.translate_net(x1)   # translation
        y2 = x2 * torch.exp(s) + t   # affine transform
        log_det = s.sum(dim=-1)       # log determinant of Jacobian
        return torch.cat([x1, y2], dim=-1), log_det

    def inverse(self, y):
        """Inverse pass: latent -> data (used for sampling)."""
        y1, y2 = y.chunk(2, dim=-1)
        s = self.scale_net(y1)
        t = self.translate_net(y1)
        x2 = (y2 - t) * torch.exp(-s)
        return torch.cat([y1, x2], dim=-1)

class NormalizingFlow(nn.Module):
    """Stack of affine coupling layers with permutations."""

    def __init__(self, dim: int, n_layers: int = 6, hidden_dim: int = 256):
        super().__init__()
        self.layers = nn.ModuleList([
            AffineCouplingLayer(dim, hidden_dim) for _ in range(n_layers)
        ])
        self.base_dist = Normal(torch.zeros(dim), torch.ones(dim))
        # Alternating permutation indices
        self.perms = [torch.randperm(dim) for _ in range(n_layers)]

    def log_prob(self, x):
        """Compute exact log-likelihood via change of variables."""
        log_det_total = 0
        z = x
        for layer, perm in zip(self.layers, self.perms):
            z = z[:, perm]  # permute dimensions
            z, log_det = layer(z)
            log_det_total += log_det
        log_pz = self.base_dist.log_prob(z).sum(dim=-1)
        return log_pz + log_det_total

    def sample(self, n: int):
        """Generate samples by inverting the flow."""
        z = self.base_dist.sample((n,))
        x = z
        for layer, perm in zip(reversed(self.layers), reversed(self.perms)):
            x = layer.inverse(x)
            inv_perm = torch.argsort(perm)
            x = x[:, inv_perm]
        return x
Normalizing flow built from stacked affine coupling layers, where forward() computes exact log-likelihoods via the change-of-variables Jacobian determinant and inverse() generates samples by reversing each coupling layer through the learned scale-and-translate networks.

5. Why Diffusion Models Won

Each of the architectures above offers a distinct mathematical trade-off, yet all share a common vulnerability: at least one failure mode (mode collapse, KL-reconstruction tension, invertibility constraints) that limits reliability in scientific applications.

By 2022, diffusion models had largely displaced VAEs, GANs, and flows as the dominant architecture for both image generation and scientific applications. Four properties account for this shift.

Training stability. Diffusion models optimize a simple denoising objective: predict the noise added to a data point. There is no adversarial game (GANs), no KL-reconstruction trade-off (VAEs), and no architectural constraint (flows). The loss landscape is smooth, and training reliably converges without extensive hyperparameter tuning.

Mode coverage. Because diffusion models are trained to denoise from every noise level, they see the full data distribution at every training step. This largely eliminates the mode collapse problem that plagues GANs. In molecular generation, coverage translates directly to chemical diversity: the model explores the full space of valid structures rather than memorizing a subset.

Beyond Sample Quality

Conditioning flexibility. Adding conditional information (target protein structure, desired molecular properties, binding pocket geometry) is straightforward: classifier-free guidance, where the model learns both conditional and unconditional generation and interpolates between them at inference time , provides a general mechanism that works with any conditioning signal without architectural changes. Section 34.4 covers this in depth.

Compositionality. Diffusion models naturally compose: you can combine multiple guidance signals (bind this target AND be synthesizable AND have low toxicity) at inference time without retraining. For discovery, where the objective is always multi-dimensional, this is crucial.

Research Frontier: Discrete Diffusion for Sequences

Classical diffusion operates on continuous data (images, 3D coordinates). Scientific sequences (SMILES strings, protein sequences, DNA) are discrete. Austin et al. (2021) introduced D3PM (Discrete Denoising Diffusion Probabilistic Models), which replaces Gaussian noise with discrete corruption (random token substitution, masking, or absorbing states). Campbell et al. (2024) extended this with continuous-time discrete diffusion using a rate matrix formulation, achieving competitive performance with autoregressive models on protein sequence generation while gaining the conditioning flexibility of diffusion. Most recently, Stark et al. (2025) introduced DIAMODN (Diffusion bridges for 3D molecular design), which uses a diffusion bridge process to generate molecules conditioned on protein binding pockets, outperforming prior pocket-conditioned generative models on the CrossDocked2020 benchmark by achieving state-of-the-art binding affinity (Vina score) while maintaining drug-likeness and synthetic accessibility. This line of work demonstrates that diffusion is converging with flow matching as a unified framework for both continuous 3D structures and discrete sequences in scientific generation.

6. The Generative Landscape for Discovery

Diffusion models may dominate, but they did not eliminate the earlier architectures; each retains a niche where its particular strengths still matter.

Each architecture occupies a niche in the current discovery landscape, as summarized in Figure 34.1. VAEs remain useful when you need a smooth, interpretable latent space for optimization (navigating chemical space by interpolating latent codes). GANs persist in applications where sample quality matters more than diversity (generating high-resolution microscopy images for data augmentation). Autoregressive models dominate protein sequence generation (as in Evolutionary Scale Modeling (ESM) based design; as of 2024, ESM3, a multimodal generative model over sequence, structure, and function, has extended this family beyond pure autoregression) because the sequential nature of amino acid chains maps naturally to left-to-right generation. Normalizing flows appear in Boltzmann generators, where Boltzmann generators are normalizing flows trained to sample from a physical system's Boltzmann distribution so that exact likelihood enables computation of thermodynamic quantities like free energy differences (see Chapter 43: Scientific Simulation). Figure 34.1.1 illustrates Generative architecture comparison: VAE, GAN, Autoregressive, Normalizing Flow, and Diffusion.

Generative architecture comparison: VAE, GAN, Autoregressive, Normalizing Flow, and Diffusion
Figure 34.1.1: Side-by-side comparison of five generative architectures showing data flow, training objectives, and key mathematical quantities for VAEs, GANs, autoregressive models, normalizing flows, and diffusion models.
VAE GAN Autoregressive Flow Diffusion Training stability Mode coverage Sample quality Exact likelihood Conditioning flex. High Low High High High Medium Low Medium High High Medium High High Medium High Lower bound No Yes Yes No Medium Medium Medium Low High
Figure 34.1: Comparison of five generative architectures across key properties for scientific discovery. Green indicates a strength, yellow a moderate capability, and red a limitation. Diffusion models achieve high marks on four of five axes, lacking only exact likelihood, which explains their dominance since 2022.

Diffusion models and their close relative, flow matching, dominate 3D structure generation: molecules, proteins, crystals, and materials. Their combination of training stability, mode coverage, and conditioning flexibility makes them the default choice for de novo design. The next three sections focus on this dominant paradigm: Section 34.2 covers the mathematical foundations of score-based diffusion and flow matching; Section 34.3 extends these ideas to equivariant generation on 3D structures; and Section 34.4 addresses conditioning, optimization, and evaluation.

Try It: Compare VAE and Autoregressive Molecular Generation

This mini-project lets you generate molecules with two architectures and compare their trade-offs using only RDKit and PyTorch. (1) Install dependencies: pip install torch rdkit-pypi. (2) Download the ZINC 250K SMILES file from the TDC (Therapeutics Data Commons) package or directly from https://raw.githubusercontent.com/aspuru-guzik-group/chemical_vae/master/models/zinc/250k_rndm_zinc_drugs_clean_3.csv, and tokenize the SMILES into character-level sequences with a vocabulary of about 35 tokens. (3) Train a minimal character-level VAE (encoder: two linear layers to \(\mu\) and \(\log\sigma^2\) with latent dim 64; decoder: single-layer GRU) for 20 epochs, then sample 1,000 SMILES by decoding random \(z \sim \mathcal{N}(0, I)\). (4) Train a minimal character-level autoregressive model (single-layer Long Short-Term Memory (LSTM) network, using teacher forcing, where the model receives the ground-truth previous token as input at each step during training rather than its own predictions ,) for 20 epochs on the same data, then sample 1,000 SMILES by greedy or temperature-scaled decoding. (5) Use RDKit to compute three metrics for each model's output: validity (Chem.MolFromSmiles(s) is not None), uniqueness (number of distinct valid SMILES divided by total valid), and novelty (fraction of valid SMILES not in the training set). You should find that the autoregressive model achieves higher validity (typically 85%+ vs. 60-75% for the VAE) because it enforces sequential token dependencies, while the VAE offers a latent space you can interpolate for smooth property optimization.

Library Shortcut: Hugging Face Diffusers and TorchDrug

Building a VAE or normalizing flow from scratch (as in the code above) requires 100-200 lines of boilerplate for training loops, noise scheduling, and sampling. The Hugging Face Diffusers library provides pretrained diffusion models, noise schedulers, and training utilities in a unified API. For molecular generation specifically, TorchDrug wraps graph-based generative models (GraphAF (Graph Autoregressive Flow, which generates molecular graphs by sequentially adding atoms and bonds via a flow-based policy) and GCPN (Graph Convolutional Policy Network, which uses reinforcement learning over graph convolutions to grow molecules step by step)) with dataset loading, property prediction, and evaluation metrics. As of 2024, the Therapeutics Data Commons (TDC) benchmarking suite and the newer PyTDC library have largely supplanted TorchDrug for standardized molecular generation benchmarks, though TorchDrug remains useful for its built-in graph generative model implementations. Starting with these libraries and customizing only what your research question demands saves weeks of implementation time while ensuring your baselines are correct.

Real-World Application: Drug Design with Insilico Medicine's Chemistry42

Insilico Medicine's Chemistry42 platform uses a VAE coupled with reinforcement learning to generate novel drug candidates for fibrotic diseases. In 2019, the system designed a first-in-class inhibitor of the DDR1 kinase target that progressed from computational generation to animal testing in 46 days (Zhavoronkov et al., Nature Biotechnology, 2019), compared to the typical 2 to 3 years for traditional medicinal chemistry. The VAE's latent space enables smooth interpolation between known active scaffolds, while the RL component steers generation toward molecules satisfying simultaneous constraints on potency, selectivity, and synthetic accessibility. As of 2024, Insilico Medicine has advanced multiple AI-designed candidates into Phase II clinical trials, including ISM001-055 for idiopathic pulmonary fibrosis, making it one of the first fully AI-generated drugs to reach mid-stage clinical testing.

Fun Note

The original VAE paper (Kingma and Welling, 2014) appeared at ICLR 2014, and the original GAN paper (Goodfellow et al., 2014) appeared at NeurIPS 2014, both published within the same year. Neither paper mentioned molecules or proteins. A decade later, both architectures are used daily in pharmaceutical companies. The lesson: fundamental mathematical ideas find applications their creators never imagined, which is itself a form of discovery.

Exercise 34.1.1

A molecular VAE trained on the ZINC 250K dataset produces the following metrics after 20 epochs: reconstruction accuracy = 92%, KL divergence per latent dimension = 0.03, and validity of random samples from \(z \sim \mathcal{N}(0, I)\) = 45%. Diagnose the problem. Which term of the ELBO is dominating, and what specific change to the training configuration would you make to improve sample validity without completely sacrificing reconstruction quality?

Hint

A KL divergence of 0.03 per dimension (summed over, say, 128 dimensions: total KL = 3.84) is very low, meaning the encoder is barely constrained toward the prior. This is the "posterior collapse in reverse" regime (the encoder is too free, using an idiosyncratic latent code) that reconstructs well but does not match the standard normal prior you sample from at generation time. Consider increasing \(\beta\) in a \(\beta\)-VAE formulation (start with \(\beta = 2\) or \(\beta = 5\)) or applying KL annealing (linearly increase \(\beta\) from 0 to 1 over the first 10 epochs) so the latent space is forced to align with the prior while the decoder still learns useful structure.

Exercises

  1. (Conceptual) Explain why mode collapse in a GAN is particularly harmful for drug discovery compared to image generation. What scientific consequence would it have if your molecular generator only produced variations of a few scaffolds?
  2. (Coding) Implement a \(\beta\)-VAE for molecular fingerprints (2048-dimensional binary vectors from RDKit Morgan fingerprints, where Morgan fingerprints are circular substructure hashes that encode the presence of molecular neighborhoods within a fixed radius around each atom ). Train on 10,000 molecules from the ZINC dataset. Vary \(\beta \in \{0.1, 0.5, 1.0, 5.0\}\) and measure reconstruction accuracy (Tanimoto similarity, where Tanimoto similarity is the ratio of shared bits to total set bits between two binary fingerprints , between input and reconstructed fingerprints) and latent space smoothness (average distance between interpolated decodings of neighboring molecules). Plot the trade-off curve.
  3. (Analysis) Compare the sample quality (validity, uniqueness, novelty as defined in Section 34.4) of a SMILES-based autoregressive model versus a graph-based autoregressive model (GraphAF from TorchDrug) on the ZINC 250K subset. Which achieves higher validity? Explain the result in terms of the structural constraints each representation enforces during generation.

Lab: Latent Space Geography of Molecular VAEs

Goal: Explore how a VAE's latent space organizes molecules by property and discover whether smooth interpolation in latent space produces chemically meaningful transitions. Tools: Python, PyTorch, RDKit (pip install torch rdkit-pypi), and the pretrained molecular VAE weights from the chemical_vae repository (Gomez-Bombarelli et al., 2018). Procedure (25 min): (1) Load the pretrained encoder and encode 5,000 ZINC molecules into latent vectors. (2) Color-code the latent vectors by a molecular property (logP, QED, or molecular weight) and project them to 2D with Principal Component Analysis (PCA) or Uniform Manifold Approximation and Projection (UMAP). Observe whether the property varies smoothly across the latent space or forms disconnected clusters. (3) Pick two molecules with very different logP values. Linearly interpolate their latent codes in 10 steps (\(z_t = (1-t) z_A + t z_B\), \(t \in \{0, 0.1, \ldots, 1\}\)), decode each \(z_t\) to a SMILES string, and compute its logP with RDKit. Plot logP vs. \(t\). What to vary: Try interpolation between molecules that are structurally similar vs. structurally different (measured by Tanimoto similarity of Morgan fingerprints). Try spherical interpolation (slerp), where slerp traverses the surface of the hypersphere in latent space rather than cutting through its interior , instead of linear interpolation. What to observe: Does logP change monotonically along the interpolation path? Do all intermediate decoded molecules parse as valid SMILES? Where does the latent space "break" (produce invalid molecules), and does slerp reduce the breakage rate?

What's Next

Diffusion models dominate scientific generation because of their training stability, mode coverage, and conditioning flexibility. Section 34.2: Score-Based Diffusion and Flow Matching develops the mathematical core: the score function, denoising score matching, the Denoising Diffusion Probabilistic Model (DDPM) forward and reverse processes, noise schedules, and the flow matching alternative. By the end of Section 34.2, you will have a working diffusion model in PyTorch and understand the continuous-time formulations (stochastic differential equations (SDEs) and ordinary differential equations (ODEs)) that unify these approaches.

Bibliography

Kingma, D. P. & Welling, M. (2014). Auto-encoding variational Bayes. ICLR 2014.

The foundational VAE paper introducing the ELBO and reparameterization trick.

Rezende, D. J. & Mohamed, S. (2015). Variational inference with normalizing flows. ICML 2015.

Normalizing flows for flexible posterior approximation and generative modeling.

Arjovsky, M., Chintala, S., & Bottou, L. (2017). Wasserstein generative adversarial networks. ICML 2017.

Wasserstein distance as a training objective, addressing mode collapse and training instability in GANs.

Austin, J., Johnson, D. D., Ho, J., Tarlow, D., & van den Berg, R. (2021). Structured denoising diffusion models in discrete state-spaces. NeurIPS 2021.

D3PM: extending diffusion to discrete data, enabling sequence generation for molecular and protein applications.