Skip to content
ML Academy

Core day 46 of 60 · Week 10 · Part II · orientation depth

Generative Modeling

The data team wants to hand an external vendor a synthetic copy of booking records, and a colleague says "just use a GAN, or diffusion, it is the newest". Before choosing a family: what is each one trained to do, what can its samples quietly lack, and what would you check before the vendor receives a single row?

By the end: For autoregressive, VAE, GAN and diffusion models you state the training objective in one line, name the constraint each one fits, read a quality-versus-coverage table from a sampling sweep, and list the provenance and licensing checks that precede sharing generated data.

At a glance

Four generative families trade likelihood, speed and stability differently; judge samples on quality and coverage separately and check memorisation before release.

  • Four objectives

    Next element, reconstruction + prior, fool a critic, undo noise.

  • One knob

    Temperature, truncation and guidance trade coverage for typicality.

  • Rare patterns first

    Cleaner settings delete the rare mode while every sample still looks real.

  • Precision and recall

    Score realism and coverage separately; a single score folds them together.

  • Before release

    Search for memorised rows, confirm licence, label provenance.

Recall · 5 min

If no cards are due, answer from memory: what does temperature change in a next-token sampler, and why is "fluent" not evidence that a statement is supported? Then name one number you would need before trusting a generated answer.

Open due reviews

Sign in to record this block.

Concept · 10 min

A Generative model learns the distribution of the data, p(x)p(x), so you can draw new samples. Four families answer "how do we train it so samples look like data?" differently, each with a price. One knob exists in all of them, the Quality-diversity trade-off: cleaner, more typical samples cost coverage, and rare patterns vanish first.

Lowering the temperature makes samples look more typical and quietly removes the rare mode

Predict first

Temperature drops from 1.0 to 0.3. What happens to the share of samples from a pattern that makes up about 5% of the real data?

Text description of the figure

A scatter of generated points over five dashed real-data regions (toy two-dimensional Gaussian clusters, one of them rare at 6% of the data) and a fixed set of real reference points. Sliders set sampling temperature, truncation (keep the densest share of probability), the number of samples and the seed. Readouts give quality (generated points inside a real region) and coverage (reference points with a generated neighbour), a per-cluster table and a curve of both against temperature. As temperature falls, quality rises, coverage falls and the rare cluster empties; as it rises, points land outside every region.

Likelihood families: predict the next element, or rebuild x through a code Diagram
AR: sequence sofarp(next element)trained on exactlikelihoodSampled elementVAE: data xLatent code zpulled toward a simplepriorReconstruction of xscored against the inputxz drawn from thepriorgeneration: no input xNew samplepredictsampleappend, repeatencodedecodedecode
  1. AR: sequence so far
    • predict: to p(next element)
  2. VAE: data x
    • encode: to Latent code z
  3. p(next element)trained on exact likelihood
    • sample: to Sampled element
  4. Latent code zpulled toward a simple prior
    • decode: to Reconstruction of x
  5. z drawn from the priorgeneration: no input x
    • decode: to New sample
  6. Sampled element
    • append, repeat: back to AR: sequence so far
  7. Reconstruction of xscored against the input x
  8. New sample

Generation reuses the trained part: AR samples one element at a time; a VAE decodes a z drawn from the prior in one pass, which works only because training kept codes near that prior.

No likelihood: fool a critic, or learn to remove noise Diagram
GAN: generatorturns random noiseinto a sampleFake sampleDiscriminator:real?Real dataDiffusion: dataxNoisy x_tnoise level t drawn atrandomNoise predictorregression on the knownnoisegeneratejudgedjudgedfool Dadd noisepredict noise
  1. GAN: generatorturns random noise into a sample
    • generate: to Fake sample
  2. Diffusion: data x
    • add noise: to Noisy x_t
  3. Fake sample
    • judged: to Discriminator: real?
  4. Noisy x_tnoise level t drawn at random
    • predict noise: to Noise predictor
  5. Discriminator: real?
    • fool D: back to GAN: generator
  6. Noise predictorregression on the known noise
  7. Real data
    • judged: back to Discriminator: real?

The dashed arrow is the gradient that teaches G to fool D. Generation: a GAN runs the generator once; diffusion starts from pure noise and applies the noise predictor many times.

The four families compared Comparison
CriterionAutoregressiveVAEGANDiffusion
Trained toPredict each next element from the ones beforeReconstruct x through a latent code kept near a priorFool a discriminator that tells real from fakePredict the noise added to data; generate by denoising
Exact likelihoodYesLower bound onlyNoBound, not used directly
SamplingSequential, one element at a timeOne pass through the decoderOne passMany denoising steps
TrainingStable maximum likelihoodStableDelicate two-player gameStable regression on noise
Typical weaknessSlow long outputs; errors compoundSofter, blurrier samplesMode collapse: covers part of the dataSlow sampling; latent diffusion cuts cost

Kingma 2014 (VAE), Goodfellow 2014 (GAN), Ho 2020 (DDPM), Rombach 2022 (latent diffusion).

Precision and recall against temperature (application output) Chart
00.250.50.751123T 0.3: P 0.97, R 0.80T 1.0: 0.98, 0.98Precision (realism) — Sampling temperature: 0.3, Score: 0.97Precision (realism) — Sampling temperature: 1, Score: 0.98Precision (realism) — Sampling temperature: 2, Score: 0.94Precision (realism) — Sampling temperature: 3, Score: 0.88Precision (realism)Recall (coverage) — Sampling temperature: 0.3, Score: 0.8Recall (coverage) — Sampling temperature: 1, Score: 0.98Recall (coverage) — Sampling temperature: 2, Score: 0.98Recall (coverage) — Sampling temperature: 3, Score: 0.96Recall (coverage)Sampling temperatureScore
  • Precision (realism)
  • Recall (coverage)

Cooling keeps precision and loses coverage; heating keeps coverage and loses precision. T 1.0 matches the data process (T 2.0: 0.94 and 0.98; T 3.0: 0.88 and 0.96).

Distance to the closest training row exposes copies that fidelity metrics miss Illustration
near-copy zone04080Rows per bin0.0010.010.1132 planted copiesheld-out and fresh overlapDistance to the closest training row (log scale)
  • Held-out real rows
  • Fresh generator
  • Memorising generator

Rows closer to a training row than 99% of held-out real rows (left of the line): held-out 4, fresh 5, memorising 36 of 400. The spike is the 32 planted copies.

GeneratorQualityCoverageNear-copies
Fresh0.960.915
Memorising0.960.9036

The same two generators on the fidelity metrics: a copy of a real row is as realistic as a row can be, so quality and coverage cannot see memorisation.

Synthetic 2-D rows from the Day 46 toy mixture: 400 training, 400 held-out and 400 generated rows (seeded). The memorising generator replaces 8% of its rows with training rows plus jitter of at most 0.005. Threshold = 1st percentile of held-out distances.

Generated rows are compared with real rows held out from training; a generated row closer to a training row than almost any held-out row is a near-copy.

  • Autoregressive: predict the next element; exact likelihood, sequential sampling (Day 42).
  • VAE: encode to a latent code and decode; smooth latent space, softer samples.
  • GAN: generator against discriminator; one-pass sampling, may cover only part of the data.
  • Diffusion: learn to undo small noising steps; high quality, slow sampling.
  • Measure precision (samples inside real data) and recall (real variety reached) separately, then check memorisation, licence and provenance before release (not legal advice).

Assumptions

  • The training data represent the distribution you want; a generator reproduces only patterns the data and model capacity cover.

  • Quality and coverage are measured with enough samples and a defined "close" (here a two-dimensional nearest-neighbour ball; image work uses learned feature spaces).

  • A generated sample is a draw from a learned distribution, not an observation of the world; it supports testing and augmentation, not claims about real customers.

Sign in to record this block.

Application and workplace decision · 10 min

  • A vendor needs a synthetic copy of bookings (lead time and fare index, synthetic) for load testing now and, later, to train a group-booking detector. Group bookings are about 5% of rows.
  • The code's generator is a three-pattern mixture with a temperature control, plus a "collapsed" generator that emits only the largest pattern; each is scored against 1,000 real rows with nearest-neighbour precision and recall.
  • T = 1.0 matches the data process (the reference ceiling). Predict which settings keep the rare pattern.

Python

import numpy as np
from scipy.spatial.distance import cdist

rng = np.random.default_rng(46)
centers = np.array([[0.0, 0.0], [6.0, 0.0], [3.0, 5.0]])  # three booking patterns (synthetic)
weights = np.array([0.50, 0.45, 0.05])                     # the third pattern is rare

def sample(n, temp=1.0, only_mode=None):
    w = weights ** (1 / temp)
    w = w / w.sum()
    comp = np.full(n, only_mode) if only_mode is not None else rng.choice(3, n, p=w)
    return centers[comp] + rng.normal(0, np.sqrt(temp), (n, 2)), comp

def knn_radius(x, k=3):
    return np.sort(cdist(x, x), axis=1)[:, k]  # distance to k-th neighbour (column 0 is self)

def precision_recall(real, gen):
    r_real, r_gen = knn_radius(real), knn_radius(gen)
    precision = (cdist(gen, real) <= r_real).any(axis=1).mean()  # gen inside real manifold
    recall = (cdist(real, gen) <= r_gen).any(axis=1).mean()      # real covered by gen manifold
    return precision, recall

real, _ = sample(1000, temp=1.0)
print("setting        precision recall  rare-mode share")
for name, temp, mode in [("T=0.3", 0.3, None), ("T=1.0", 1.0, None), ("T=2.0", 2.0, None), ("T=3.0", 3.0, None), ("collapsed", 1.0, 0)]:
    gen, comp = sample(1000, temp, mode)
    p, r = precision_recall(real, gen)
    print(f"{name:<13} {p:9.2f} {r:6.2f} {np.mean(comp == 2):10.3f}")

This code is executed in the repository's checks (pnpm lesson:py / lesson:sql). It is not run on this site; copy it into your notebook.

Sign in to record this block.

Mini-assessment · 8 min

Your first answer is your evidence. You can re-answer later in practice mode; that is labelled practice.

Question 1 · easy

Which description matches how a diffusion model is trained?
Options

How confident are you? (optional, used for calibration)

Question 2 · medium

A teammate lowers the sampling temperature of a tabular generator so the synthetic rows "look cleaner", and the realism score improves slightly. What should you expect from a separate coverage check, and what do you do?
Options

How confident are you? (optional, used for calibration)

Question 3 · hard

You must pick a generator to create extra rare-fraud-pattern records for a detector. Two hypothetical candidates are evaluated on the same 5,000 real rows. Model A: realism score 8 (lower is better), precision 0.97, recall 0.45. Model B: realism score 11, precision 0.90, recall 0.85. Which do you take forward, and what is the deciding evidence?
Options

How confident are you? (optional, used for calibration)

Question 4 · medium

In the booking-generator toy the real mixture has three patterns with weights 0.50, 0.45 and 0.05. Sampling at temperature T reweights the patterns in proportion to weight^(1/T) and renormalises. At T = 2.0, what share of the generated rows comes from the rare pattern, in percent?
percent

How confident are you? (optional, used for calibration)

Question 5 · hard

A team's tabular generator scores precision 0.98 and recall 0.97 against 1,000 real booking rows (synthetic figures), and the vendor wants the synthetic copy shared outside the company. A nearest-neighbour search shows that 6% of the generated rows lie within a tiny distance of a single training row, including a rare group booking. What do you do before release?
Options

How confident are you? (optional, used for calibration)

Sign in to complete lessons and keep your progress.

Technical depth · optional · 30 min in total

Open only what you need. Nothing here is required to complete the day; the assessment covers the core above.

The four objectives, term by term6 minOne line of maths per family, every symbol explained, the derivation behind each line, and the GAN game as a loop.
Autoregressive factorisation Formula
p(x)=∏tp(xt∣x<t)p(x) = \prod_{t} p(x_t \mid x_{<t})
p(x)p(x)
the joint probability of the whole sequence, the thing being learned
∏t\prod_t
the chain rule, p(x1, x2, ...) = p(x1) p(x2 | x1) ...: exact for any ordering, an identity, not an approximation
xtx_t
element t (token, product id, pixel)
x<tx_{<t}
everything generated before it
p(xt∣x<t)p(x_t \mid x_{<t})
one conditional per position; the model's only job

Derivation in one line: the chain rule makes maximum likelihood split into one next-element prediction per position. Logs turn the product into a sum, so exact log-likelihood is computable; the optional lab compares model and true process (-1.168 versus -1.163 per move).

VAE lower bound (ELBO) Formula
log⁡p(x)≥Eq(z∣x)[log⁡p(x∣z)]−KL(q(z∣x) ∥ p(z))\log p(x) \ge \mathbb{E}_{q(z|x)}[\log p(x|z)] - \mathrm{KL}(q(z|x)\,\|\,p(z))
log⁡p(x)\log p(x)
the quantity we would like to maximise but cannot compute directly
≥\ge
Jensen's inequality: the right side (the ELBO) never exceeds the left
q(z∣x)q(z|x)
encoder distribution over latent codes
Eq(z∣x)\mathbb{E}_{q(z|x)}
average over the codes the encoder proposes for this x
log⁡p(x∣z)\log p(x|z)
reconstruction term: how well the decoder rebuilds x from z
KL\mathrm{KL}
keeps codes close to the prior p(z), usually a standard normal
log⁡p(x)−ELBO\log p(x) - \text{ELBO}
the gap, exactly KL(q(z|x) ‖ p(z|x)) ≥ 0: the bound is tight when the encoder matches the true posterior

Derivation: write log p(x) = log ∫ p(x|z) p(z) dz, multiply and divide by q(z|x) inside the integral, and apply Jensen's inequality to the concave log. What is lost is the KL gap in the last row (Kingma 2014).

The GAN game Formula
min⁡Gmax⁡D  Ex[log⁡D(x)]+Ez[log⁡(1−D(G(z)))]\min_G \max_D\; \mathbb{E}_{x}[\log D(x)] + \mathbb{E}_{z}[\log(1 - D(G(z)))]
min⁡Gmax⁡D\min_G \max_D
two players with opposite objectives: D is trained up, G is trained against it
DD
discriminator; probability that its input is real
Ex[log⁡D(x)]\mathbb{E}_x[\log D(x)]
D's reward for recognising real data as real
G(z)G(z)
generator output from noise z
log⁡(1−D(G(z)))\log(1 - D(G(z)))
falls as fakes fool D, which is exactly what G minimises
D∗(x)=pdata(x)pdata(x)+pg(x)D^*(x) = \tfrac{p_{data}(x)}{p_{data}(x) + p_g(x)}
the best discriminator for a fixed G; substituting it back shows G minimises the Jensen-Shannon divergence to the data, zero only when they match

Goodfellow et al. 2014 (the divergence result holds up to a constant). No likelihood is computed, so there is no shared yardstick with the other families.

Diffusion training loss (DDPM, simplified) Formula
L=Ex,ϵ,t[ ∥ϵ−ϵθ(xt,t)∥2]\mathcal{L} = \mathbb{E}_{x, \epsilon, t}\big[\,\|\epsilon - \epsilon_\theta(x_t, t)\|^{2}\big]
ϵ\epsilon
the Gaussian noise the training loop itself added, so the label is known exactly
xt=αˉtx0+1−αˉtϵx_t = \sqrt{\bar\alpha_t}x_0 + \sqrt{1-\bar\alpha_t}\epsilon
data after t noising steps, built in closed form in one jump; this is why the noise label is known exactly
tt
a noise level drawn at random each training step, so one network covers all levels
ϵθ\epsilon_\theta
network that predicts the added noise
∥⋅∥2\|\cdot\|^2
a plain squared error: training is stable supervised regression

Ho et al. 2020 derive this loss as a simplified weighting of the ELBO. Generation runs the learned denoising step many times, starting from pure noise.

GAN training alternates two players with opposite goals Loop
no likelihoodanywhere in theloop1Draw noise za fresh batch every step2Fakes G(z) + realrowsone mixed batch3D(x) for every rowprobability that the rowis real4Sharper Dreal scored up, fakesdown5Better Gfakes move toward what Dcalls realgenerateD scores each rowupdate D (max)update G (min)repeat
  1. Draw noise za fresh batch every stepgenerate ↓
  2. Fakes G(z) + real rowsone mixed batchD scores each row ↓
  3. D(x) for every rowprobability that the row is realupdate D (max) ↓
  4. Sharper Dreal scored up, fakes downupdate G (min) ↓
  5. Better Gfakes move toward what D calls realrepeat ↓
  6. ↺ back to 1 · Draw noise z

The game in the equation above, run as a loop. If G finds one pattern D accepts, nothing in the loop pushes it to cover the others: that is mode collapse, the low-recall failure.

Temperature, measured6 minWhat the knob does to a distribution, worked by hand on three weights, shown at four settings and swept end to end.
Temperature on a discrete distribution Formula
pi(T)=pi1/T∑jpj1/Tp_i(T) = \frac{p_i^{1/T}}{\sum_j p_j^{1/T}}
pip_i
probability of outcome i at T = 1 (a token, a mixture component, a grid cell)
TT
temperature: below 1 sharpens, above 1 flattens
pi1/Tp_i^{1/T}
every ratio between two outcomes is raised to 1/T, so the smallest outcomes shrink fastest when T < 1

The same as dividing logits by T before the softmax. A 1-in-10 ratio between two outcomes becomes 1-in-100 at T = 0.5.

Temperature by hand: a retail order generator with pattern weights 0.6, 0.3, 0.1 Table
StepT = 0.5 (each weight squared)T = 2.0 (square root of each)
Raise each weight to 1/T0.36, 0.09, 0.010.775, 0.548, 0.316
Sum the raised weights0.461.639
Divide each by the sum0.783, 0.196, 0.0220.473, 0.334, 0.193
Rare pattern (bulk orders)10% falls to 2.2%10% rises to 19.3%

Hypothetical e-commerce mixture (weekday, weekend, bulk), verified in Python. The 6:1 ratio between largest and rare becomes 36:1 at T = 0.5 and 2.4:1 at T = 2.0: ratios move, which is why the smallest weight moves most.

One generator, four temperatures Illustration
T = 0.35 (cooler)rare mode

Quality 99% · coverage 79% · rare mode 1% of in-region points (real 6%), 1/9 rare reference points covered.

T = 0.6 (cooler)rare mode

Quality 93% · coverage 89% · rare mode 5% of in-region points (real 6%), 6/9 rare reference points covered.

T = 1 (as trained)rare mode

Quality 85% · coverage 92% · rare mode 5% of in-region points (real 6%), 7/9 rare reference points covered.

T = 1.6 (hotter)rare mode

Quality 67% · coverage 94% · rare mode 10% of in-region points (real 6%), 7/9 rare reference points covered.

  • generated, inside a real region
  • generated, outside every region
  • rare mode (6% of real data)

Toy 2-D mixture (five modes) and a generator that is 1.3x too wide, both from the Day 46 widget code; 350 seeded samples per panel against 240 reference points. Not a trained network.

Cooling pulls samples into the dense cores and the rare mode (outlined) empties first, while every remaining point still looks real.

Quality, coverage and the rare mode across temperature Illustration
0.000.250.500.751.001.250.250.500.751.001.251.50T = 1: as trainedbest balance T ≈ 0.50T 0.25: quality 1.00, coverage 0.70, rare 0.00 of real shareT 0.30: quality 1.00, coverage 0.76, rare 0.05 of real shareT 0.35: quality 0.99, coverage 0.78, rare 0.19 of real shareT 0.40: quality 0.99, coverage 0.83, rare 0.14 of real shareT 0.45: quality 0.99, coverage 0.80, rare 0.39 of real shareT 0.50: quality 0.97, coverage 0.91, rare 0.39 of real shareT 0.55: quality 0.96, coverage 0.89, rare 0.55 of real shareT 0.60: quality 0.94, coverage 0.88, rare 0.61 of real shareT 0.65: quality 0.93, coverage 0.90, rare 0.61 of real shareT 0.70: quality 0.96, coverage 0.89, rare 0.80 of real shareT 0.75: quality 0.91, coverage 0.91, rare 1.00 of real shareT 0.80: quality 0.86, coverage 0.90, rare 0.50 of real shareT 0.85: quality 0.89, coverage 0.91, rare 1.18 of real shareT 0.90: quality 0.84, coverage 0.90, rare 0.68 of real shareT 0.95: quality 0.86, coverage 0.95, rare 1.55 of real shareT 1.00: quality 0.84, coverage 0.94, rare 1.02 of real shareT 1.05: quality 0.85, coverage 0.93, rare 1.24 of real shareT 1.10: quality 0.78, coverage 0.90, rare 1.16 of real shareT 1.15: quality 0.79, coverage 0.93, rare 1.08 of real shareT 1.20: quality 0.81, coverage 0.96, rare 1.36 of real shareT 1.25: quality 0.75, coverage 0.95, rare 0.89 of real shareT 1.30: quality 0.75, coverage 0.97, rare 1.01 of real shareT 1.35: quality 0.74, coverage 0.93, rare 0.97 of real shareT 1.40: quality 0.71, coverage 0.93, rare 1.07 of real shareT 1.45: quality 0.71, coverage 0.93, rare 1.60 of real shareT 1.50: quality 0.68, coverage 0.90, rare 0.98 of real shareT 1.55: quality 0.72, coverage 0.91, rare 1.79 of real shareT 1.60: quality 0.70, coverage 0.95, rare 1.49 of real sharequalitycoveragerare ÷ realrare mode almost absentSampling temperature TShare (rare: ÷ real share)
  • quality (generated points inside a real region)
  • coverage (reference points with a generated neighbour)
  • rare-mode share ÷ real share (1 = right amount)

Toy 2-D mixture from the Day 46 widget; 350 seeded samples per temperature against 240 reference points. Shapes carry over to real generators; the numbers do not.

Cooling raises quality and loses coverage; the rare mode reaches half its real share only from T ≈ 0.55. The best balance of quality and coverage here is T ≈ 0.50 (quality 0.97, coverage 0.91), below 1 because this generator is too wide.

For an imperfect generator the balance point need not be T = 1. Tune on quality, coverage and pattern shares together, at a fixed sample size, and record the setting with the generator version.

The same knob under different names Table
KnobFamilyTurn it toward typical and you get
TemperatureAutoregressive, mixturesSharper weights; rare patterns lose mass fastest
TruncationGAN latents, top-pCuts the tail outright: a pattern below the cut gets exactly zero mass
Guidance scaleDiffusionFidelity up, diversity down (Ho and Salimans 2022)

Nucleus (top-p) sampling is from Holtzman et al. 2020. Temperature shrinks a rare pattern; truncation deletes it.

Cooling repeats the likeliest trips; heating adds variety and unseen moves Chart
  • T = 0.40.48 distinct
  • T = 1.00.87 distinct
  • T = 2.05% of trips use a move never observed0.95 distinct

Optional-lab output (seeded bigram model over six airport codes): the share of distinct trips among 300 generated. At T = 0.4 and 1.0 every trip uses only observed moves.

Measuring quality and coverage4 minHow nearest-neighbour precision and recall work, how to read them together, and what every metric misses.
How the toy precision and recall are computed Sequence
  1. Radii

    For every real point, the distance to its 3rd nearest real neighbour; same for generated points.

  2. Precision

    Share of generated points inside at least one real point's ball.

  3. Recall

    Share of real points inside at least one generated point's ball.

  4. Task test

    Train on generated data, score on real data: the use the data is for.

Reading precision and recall together Map

Varied but sloppy

Covers the data, many off-pattern rows (T = 3.0).

The goal

Real-looking samples across all patterns (T = 1.0 here).

Broken

Neither realistic nor covering.

Typical but narrow

Mode collapse or low temperature: rare patterns missing.

The idea of separating the two is from Kynkaanniemi et al. 2019; the toy metric imitates it.

Generative metrics and what each is blind to Table
CheckMeasuresBlind to
FID (images)Distance between real and generated feature statisticsWhether a loss is quality or coverage; copies of training images
PrecisionShare of samples inside the real data's neighbourhoodMissing modes; a memorised row scores perfectly
RecallShare of real data reached by some sampleOff-pattern rows, as long as each sits near something real
Pattern sharesEach known segment's share against its real shareSegments nobody labelled
Distance to closest recordNear-copies of training rowsWhether the data are useful
Train on synthetic, test on realUsefulness for the intended modelPrivacy; patterns that task does not use

FID from Heusel et al. 2017; precision and recall from Kynkaanniemi et al. 2019. Report several checks; none is sufficient alone.

How each family fails3 minThe typical failure of each family, the symptom that exposes it, and three common misreadings.
How each family fails, and the symptom to look for Overview
  • GAN: mode collapse

    Precision fine, recall low, whole patterns missing. Check per-pattern shares.

  • Autoregressive: compounding

    Each element conditions on earlier ones, so an early slip shapes the rest. Check quality by position.

  • VAE: averaging

    Samples blend nearby data; sharp edges and rare extremes soften.

  • Diffusion: cost and copies

    Many network calls per sample; training images have been extracted from such models (Carlini 2023).

  • Any family: feedback loops

    Training on unlabelled generated data thins the tails (Shumailov 2024).

Three common misreadings, and the evidence against each Overview
  • "T = 1 is the correct setting"

    Only for a perfect model. An imperfect one balances quality and coverage elsewhere (see the temperature sweep).

  • "Low FID means good synthetic data"

    One number mixes quality and coverage, and it rewards copies of the reference set.

  • "Labelled synthetic means anonymous"

    Generators can reproduce training rows; only a nearest-record check looks for them.

Choosing a family2 minA decision path from the binding constraint to a shortlist, with the evaluation every branch shares.
Choosing a family by the constraint that binds (practitioner heuristic) Diagram
Purpose anddata type knownSmall table,few columns?Simple baselinefirstmixture model; comparebefore anything deepSequences or a…Autoregressivetext, codes, eventsequencesOne-pass…GAN or VAEwatch recall: modes gomissingDiffusion, oftenlatentquality first; manystepsyesnoyesnoyesno
  1. Purpose and data type known
  2. Small table, few columns?
    • no: to Sequences or a likelihood needed?
  3. Simple baseline firstmixture model; compare before anything deep
  4. Sequences or a likelihood needed?
    • no: to One-pass sampling required?
  5. Autoregressivetext, codes, event sequences
  6. One-pass sampling required?
    • no: to Diffusion, often latent
  7. GAN or VAEwatch recall: modes go missing
  8. Diffusion, often latentquality first; many steps

Every branch ends in the same evaluation, quality and coverage separately plus a task test on real held-out rows, and the same release checks.

Memorisation, licence and provenance4 minThe nearest-record check step by step, and the other checks before any generated row is shared.
Before generated data leaves the building Diagram
Generated setNear-copy of atraining row?Remove, re-checkor retrain withsafeguardsLicence permitsthis use?Stop and ask thedata ownerLabel provenancesynthetic, source,generator versionReleaseyesnono or unknownyes
  1. Generated set
  2. Near-copy of a training row?
    • no: to Licence permits this use?
  3. Remove, re-checkor retrain with safeguards
  4. Licence permits this use?
    • yes: to Label provenance
  5. Stop and ask the data owner
  6. Label provenancesynthetic, source, generator version
  7. Release

Diffusion models have emitted individual training images (Carlini 2023); generated data is not automatically private. NIST AI 600-1 lists information integrity and intellectual property among generative-AI risks. Not legal advice.

Distance to closest record: the memorisation check, step by step Sequence
  1. Scale the columns

    Scale numeric columns and treat categorical ones separately, or one wide column decides every distance.

  2. Generated to training

    For each generated row, the distance to its nearest training row.

  3. Held-out to training

    The same distance for real rows held out from training: what a fresh draw looks like.

  4. Flag near-copies

    Generated rows closer than almost every held-out row (the demo uses its 1st percentile) are near-copies.

  5. Read it honestly

    A clean result is evidence against verbatim copying, not a privacy guarantee; rare combinations need their own re-identification test.

The memorisation demo in the Concept block runs exactly this check against planted copies.

A tabular baseline and its defaultsadvanced3 minThe scikit-learn defaults that matter when a mixture model is the first synthetic-data generator.
A simple tabular baseline in scikit-learn (defaults checked in 1.9.1) Table
SettingDefaultWhy it matters for synthetic data
GaussianMixture n_components1One Gaussian cannot hold a separate rare pattern; choose the count on held-out likelihood or BIC
covariance_typefullKeeps correlation between columns within each component; diag drops it
n_init1A single start can merge a small cluster into a large one; try several starts
NearestNeighbors metricminkowski, p = 2Euclidean: scale columns first, or one wide column decides every nearest-record distance

GaussianMixture.sample has no temperature argument; sampling with narrower spread means editing the fitted covariances, a choice to document.

Latent diffusionadvanced2 minWhy modern image generators run diffusion in an autoencoder's latent space.
Latent diffusion, bottom to top Stack
  1. AutoencoderCompresses images into a smaller latent grid and decodes back.
  2. Diffusion in latent spaceNoising and denoising run on the compact latents, far cheaper.
  3. ConditioningText or other inputs steer denoising; guidance trades diversity for fidelity.
  4. DecodeThe final latent is decoded to pixels.

Rombach et al. 2022.

Memory anchor

Objective explains behaviour; realism is not coverage; and generated data has a source.

Useful for

  • Choosing a model family for synthetic data, image or audio generation across domains: synthetic transactions for fraud-detector testing (banking), patient-like records for research access (healthcare), defect images for augmentation (manufacturing).

  • Reviewing a generative proposal for the right evaluation (quality and coverage separately, plus a task test) and the right release checks.

  • Explaining to stakeholders why "looks realistic" does not mean "covers our customers" and why generated data is not automatically private.

Not suitable for

  • Judging whether a particular generator is good enough for your data; that needs your data, your metric and a downstream task test.

  • Training or tuning a generative model; this day is orientation and the toy code scores samples, it does not train a network.

  • Legal conclusions about copyright or licensing; the lesson names the checks, and a lawyer decides what they imply.

Traps

Ranking generators by one realism score

A single number such as FID mixes sample quality and coverage, so a generator that emits a narrow set of excellent samples can win while missing the rare patterns the project needs.

How to avoid it

Report precision and recall (or quality and coverage) separately at the same sample size, compare pattern shares with the real data, and finish with a downstream task test on real held-out data.

Treating generated data as private and licence-free

Generators can reproduce training records, and synthetic copies of licensed or personal data inherit the terms and the risk of their source. A "synthetic" patient table or transaction log can still expose the original record, and in regulated sectors (health, banking) that is a reportable incident, not a modelling bug.

How to avoid it

Search outputs for near-duplicates of training rows, keep a provenance record of sources and licences, get governance sign-off before release, and never feed unlabelled generated data back into training.

Senior reasoning

A senior does not ask which family is best. They ask which constraint binds (coverage of rare patterns, sampling speed, a usable latent space, a likelihood, training stability, data volume), shortlist two families, and test them on the target task with quality and coverage reported separately. They treat sampling settings as a decision about the product, not a cosmetic choice, and they ask where the training data came from before anyone asks how good the samples look.

Interview question

"A team proposes a diffusion model to generate synthetic customer data for a vendor. What questions do you ask before approving it?"

Recall cards scheduled after completion

  • State the training objective of an autoregressive model, a VAE, a GAN and a diffusion model in one line each.
  • What does lowering temperature (or raising guidance) do to precision, recall and rare patterns?

Reviewed on a 1 · 3 · 7 · 14 · 30-day schedule; a miss returns the card to 1 day.

References

  • Auto-Encoding Variational Bayes — Diederik P. Kingma, Max Welling, 2014optional

    Defines the variational autoencoder, its lower-bound objective and the reparameterisation trick behind the VAE line in the mechanism. (Section 2 (Method))

  • Generative Adversarial Nets — Ian J. Goodfellow, Jean Pouget-Abadie, Mehdi Mirza, Bing Xu, David Warde-Farley, Sherjil Ozair, Aaron Courville, Yoshua Bengio, 2014optional

    States the generator-discriminator game that defines the GAN objective. (Section 3 (Adversarial nets))

  • Denoising Diffusion Probabilistic Models — Jonathan Ho, Ajay Jain, Pieter Abbeel, 2020core

    Gives the forward noising process and the learned reverse denoising process used in the diffusion line. (Sections 2-3)

  • High-Resolution Image Synthesis with Latent Diffusion Models — Robin Rombach, Andreas Blattmann, Dominik Lorenz, Patrick Esser, Björn Ommer, 2022optional

    Moves the diffusion process into an autoencoder's latent space to cut compute; supports the latent diffusion sentence. (Section 3 (Method))

  • Improved Precision and Recall Metric for Assessing Generative Models — Tuomas Kynkäänniemi, Tero Karras, Samuli Laine, Jaakko Lehtinen, Timo Aila, 2019core

    Separates sample quality (precision) from coverage of the real distribution (recall), which a single FID-style value conflates; the toy metric imitates this idea.

  • Classifier-Free Diffusion Guidance — Jonathan Ho, Tim Salimans, 2022optional

    Shows that guidance trades diversity for fidelity, in the spirit of low-temperature sampling.

  • Extracting Training Data from Diffusion Models — Nicholas Carlini, Jamie Hayes, Milad Nasr, Matthew Jagielski, Vikash Sehwag, Florian Tramèr, Borja Balle, Daphne Ippolito, Eric Wallace, 2023optional

    Documents that diffusion models memorised and emitted individual training images, which is why generated data is not automatically private.

  • GANs Trained by a Two Time-Scale Update Rule Converge to a Local Nash Equilibrium — Martin Heusel, Hubert Ramsauer, Thomas Unterthiner, Bernhard Nessler, Sepp Hochreiter, 2017optional

    Introduces FID, the single feature-statistics distance that the metric table contrasts with separate precision and recall.

  • The Curious Case of Neural Text Degeneration — Ari Holtzman, Jan Buys, Li Du, Maxwell Forbes, Yejin Choi, 2020optional

    Proposes nucleus (top-p) sampling, the truncation knob that removes low-probability outcomes outright.

  • AI models collapse when trained on recursively generated data — Ilia Shumailov, Zakhar Shumaylov, Yiren Zhao, Nicolas Papernot, Ross Anderson, Yarin Gal, 2024optional

    Shows that training on recursively generated data removes the tails of the original distribution, the feedback-loop failure in the failure cards.

  • Artificial Intelligence Risk Management Framework: Generative Artificial Intelligence Profile — National Institute of Standards and Technology (NIST), 2024optional

    Lists information integrity and intellectual property among generative-AI risks and describes provenance-related actions; supports the release-check list. (Section 2 (risks), Information Integrity and Intellectual Property)

Optional sections

Deep dive · 10 min

Objectives in symbols.

  • VAE: log⁡pθ(x)≥Eqϕ(z∣x)[log⁡pθ(x∣z)]−KL(qϕ(z∣x) ∥ p(z))\log p_\theta(x) \ge \mathbb{E}_{q_\phi(z \mid x)}[\log p_\theta(x \mid z)] - \mathrm{KL}(q_\phi(z \mid x)\,\|\,p(z)), the evidence lower bound (ELBO). The first term rewards reconstruction; the second keeps the encoder's codes close to the prior so that sampling z∼p(z)z \sim p(z) is meaningful.
  • GAN: min⁡Gmax⁡D  Ex∼pdata[log⁡D(x)]+Ez∼pz[log⁡(1−D(G(z)))]\min_G \max_D \; \mathbb{E}_{x \sim p_{\text{data}}}[\log D(x)] + \mathbb{E}_{z \sim p_z}[\log(1 - D(G(z)))]. There is no likelihood term, which is why held-out likelihood cannot score a GAN.
  • Diffusion (DDPM-style): train ϵθ\epsilon_\theta to predict the noise added to x0x_0 at a random step tt, minimising E ∥ϵ−ϵθ(αˉt x0+1−αˉt ϵ,  t)∥2\mathbb{E}\,\lVert \epsilon - \epsilon_\theta(\sqrt{\bar\alpha_t}\,x_0 + \sqrt{1-\bar\alpha_t}\,\epsilon,\; t)\rVert^2.
  • Classifier-free guidance mixes a conditional and an unconditional noise estimate, ϵ~=(1+w) ϵθ(xt,c)−w ϵθ(xt)\tilde\epsilon = (1+w)\,\epsilon_\theta(x_t, c) - w\,\epsilon_\theta(x_t); larger ww gives samples that follow the condition more closely and vary less.

| Family | Training signal | Sampling | Likelihood | Typical price | |---|---|---|---|---| | Autoregressive | Next-element likelihood | Sequential, one element per step | Exact | Slow for long outputs; error compounds | | VAE | Lower bound: reconstruction and prior match | One decoder pass | Bound only | Smooth latent space, softer samples | | GAN | Adversarial game | One generator pass | None | Unstable training; may miss modes | | Diffusion | Denoising of noised data | Many denoising steps | Bound, indirect | Slow sampling; latent variants cut cost |

Feedback loops. Training a generator on its own earlier output removes the tails of the distribution (Shumailov et al., 2024, shown for several model types). Keep a real-data anchor and a provenance label on every record (insight 0545).

What the toy metric hides. The nearest-neighbour balls assume that "inside the real data's neighbourhood" means realistic. In high dimensions distances behave differently, which is why practitioners use features from a trained network; the principle of reporting two numbers survives, the exact values do not transfer.

Hands-on lab: Exact likelihood and sampling temperature for an autoregressive model · 15 min

Fit a first-order autoregressive model (a bigram table over airport codes) to synthetic trips, compute its exact held-out log-likelihood, and sample at three temperatures. Before running, write down which temperature should give the most distinct trips and which the highest share of trips that use only moves observed in training. Then run it and note two things: how close the fitted model's likelihood is to the true process (an exact likelihood is available here, which a GAN cannot offer), and what the share of "observed moves only" does at the highest temperature. Finally, explain in two sentences why this is a coverage-versus-validity trade-off.

import numpy as np

rng = np.random.default_rng(7)
codes = ["IST", "ADB", "AYT", "ESB", "LHR", "FRA"]
K = len(codes)
true_p = rng.dirichlet(np.full(K, 0.4), size=K)  # synthetic "true" next-airport process

def make_trips(n, length=6):
    trips = np.zeros((n, length), dtype=int)
    for i in range(n):
        s = rng.integers(K)
        for t in range(length):
            trips[i, t] = s
            s = rng.choice(K, p=true_p[s])
    return trips

train, test = make_trips(600), make_trips(200)
counts = np.full((K, K), 0.5)  # additive smoothing so unseen moves keep a little probability
for trip in train:
    for a, b in zip(trip[:-1], trip[1:]):
        counts[a, b] += 1
model = counts / counts.sum(axis=1, keepdims=True)

def avg_loglik(trips, p):
    return np.mean([np.log(p[a, b]) for tr in trips for a, b in zip(tr[:-1], tr[1:])])

print(f"avg log-lik per move: model {avg_loglik(test, model):.3f}, true process {avg_loglik(test, true_p):.3f}")
seen = counts > 0.5  # transitions observed in the training trips

def generate(temp, n=300, length=6):
    p = model ** (1 / temp)
    p = p / p.sum(axis=1, keepdims=True)
    out = []
    for _ in range(n):
        s, trip = rng.integers(K), []
        for _ in range(length):
            trip.append(s)
            s = rng.choice(K, p=p[s])
        out.append(tuple(trip))
    return out

for temp in (0.4, 1.0, 2.0):
    trips = generate(temp)
    distinct = len(set(trips)) / len(trips)
    valid = np.mean([all(seen[a, b] for a, b in zip(t[:-1], t[1:])) for t in trips])
    print(f"T={temp}: distinct trips {distinct:.2f}, share using only observed moves {valid:.2f}")
Interview practice · 10 min

An insurer wants to release a "synthetic version" of its claims table to external researchers. How do you decide whether it is safe and useful?

Content version 6 · last verified 2026-10-12 · depends on numpy, scipy, scikit-learn