Level 12 · AdvancedLesson 12.1 40 min read 10 question quiz 12 marks of written practice

Autoencoders and GANs: Machines That Create

Telling apart, or making new

Most of this course so far has been about discriminative models: given an input, predict a label. A generative model learns what the data itself looks like, well enough to produce new examples that could have come from it.

DiscriminativeGenerative
LearnsWhich label goes with an inputWhat the data looks like
Answers"Is this a cat or a dog?""Draw me a new cat."
ExamplesSpam filters, image classifiersLanguage models, image generators, music generators

A language model (Level 11) is a generative model of text: it learns the probability of every sequence of tokens and samples new ones. This level is about generating images, sound and more, where the data is a grid of numbers rather than a sequence of tokens.

Autoencoders: squeeze, then rebuild

An autoencoder is two networks back to back. The encoder squeezes the input into a much smaller vector, the latent code; the decoder tries to rebuild the original from that code alone. Training minimises the reconstruction error between input and output.

An autoencoderA pixel image of the digit 2, 784 numbers, passes through an encoder drawn as three shrinking 3D blocks, 784 to 128 to 32 numbers, into a latent code of 32 numbers shown as a short coloured column. A decoder of three growing blocks, 32 to 128 to 784, rebuilds a slightly blurred copy of the digit. A red bracket joins the input and the rebuilt image: the loss is the reconstruction error between them.An autoencoder: squeeze through a bottleneck, then rebuildinput784 numbersencoder784 → 128 → 32codelatent code32 numbersdecoder32 → 128 → 784rebuilt784 numbersloss: the reconstruction error, how different the rebuilt image is from the input
With only 32 numbers in the middle, the network must keep what matters and drop the rest.

A 28 × 28 image has 784 numbers; squeezed through a bottleneck of 32, the network cannot copy the image, so it must learn which features matter most: the slant of a stroke, the width of a loop. Uses include:

  • Compression: store or send the small code instead of the image.
  • Denoising: train with noisy inputs and clean targets, and the network learns to remove noise.
  • Anomaly detection: an autoencoder trained only on normal data rebuilds unusual data badly, so a large reconstruction error flags something odd, such as a faulty machine part.

Latent space

The latent codes form a latent space. Because the decoder must rebuild similar inputs from codes, similar inputs end up with nearby codes, just as similar words had nearby embeddings in Level 9.

A latent spaceAn illustration of a decoder's two-number latent space as a 7 by 7 grid. Each cell shows the shape decoded from that point: from left to right the shapes change from diamonds through circles to rounded squares, and from top to bottom from tall and narrow to wide, with colours shifting gradually. A dashed amber line from one code to another crosses the grid: decoding the points along it morphs a narrow diamond into a wide square through every shape in between.A latent space: every point decodes to something, and neighbours look alikelatent number 1 →latent number 2 →Each cell shows what the decoder makesfrom that point of a two-number latent space.Moving right makes shapes squarer;moving down makes them wider.The amber walk between two codes morphsa narrow diamond into a wide square,through every shape in between.In a model of faces, directions like thesemight add a smile, or turn the head.
An illustration: real latent spaces have dozens or hundreds of dimensions, but the idea is the same.

Walking in a straight line between two codes and decoding each step morphs one output into another. Moving in a particular direction can change one property at a time: in a model of faces, one direction might add a smile and another add glasses.

Variational autoencoders

A plain autoencoder's latent space has gaps: decode a random point between the codes it learned and you may get nonsense. A variational autoencoder (VAE), introduced in 2013, fixes this so that you can sample new data:

A variational autoencoderTop: a digit enters an encoder, which outputs a mean and a spread instead of one code. A code z is sampled from the bell curve they describe, z equals the mean plus the spread times a random number, and the decoder rebuilds the digit from it. Bottom left: a plain autoencoder's codes form separate clumps with gaps, and a point in a gap decodes to nonsense. Bottom right: a VAE's clouds overlap inside one smooth bell, so any random point decodes to something sensible.A variational autoencoder encodes a cloud, not a pointencodermeanspreadsample z = mean + spread × randomdecoderplain autoencoder: codes scattered, with gapsa gap: decodes to nonsenseVAE: clouds pulled into one smooth bellany random point decodes to something sensible
The extra loss term packs the clouds together, which is what makes sampling work.
  1. The encoder outputs a mean and a spread for each latent number, describing a small cloud rather than a single point.
  2. A code is sampled from that cloud: z = mean + spread × a random number.
  3. The decoder rebuilds the input from z.
  4. The loss adds a second term that pulls every cloud towards a standard bell curve centred on zero.

That second term packs the clouds together into one smooth region with no gaps. To create something new, pick a random point from the standard bell curve and decode it.

Generative adversarial networks

A generative adversarial network (GAN), from 2014, trains two networks against each other:

  • The generator turns random noise into fake data. It never sees a real example.
  • The discriminator is shown real examples and fakes, and learns to tell them apart.
A generative adversarial networkRandom noise enters a violet generator, the forger, which outputs a fake picture of a cat. An orange discriminator, the detective, is shown real photos and fakes and outputs how likely each is to be real: for this fake, 0.30. A pink arrow carries the gradient of that verdict back to the generator, which changes so its next fakes look more real, while the discriminator also learns from its mistakes.A GAN: a forger and a detective, trained against each othernoisegeneratorthe forgera fakea real photodiscriminatorthe detective“real” or “fake”?P(real) = 0.30the generator follows the gradient of the verdict to make its next fakes look more realthe detective learns fromits mistakes too
The generator never sees a real photo: everything it learns comes through the discriminator's verdicts.

It is a contest between a forger and a detective. Each time the detective gets better at spotting fakes, the gradient of its verdict tells the forger exactly how to change its fakes to be more convincing. They take turns: a few steps training the discriminator, then a few training the generator to make the discriminator answer "real".

Training a GANA stepped graph over values from minus 1 to 9. The real data, in teal, has two bumps, at 3 and 6. The fakes, in pink, start as one bump at 0.5; the optimal discriminator D*(x) = p_data / (p_data + p_fake), drawn dashed in amber against a 0 to 1 scale, is near 1 over the data and near 0 over the fakes. The fakes then move to a wide bump around 2.6, then split into two bumps near 3.3 and 5.5 while D* flattens, and finally match the data exactly, where D* is 0.5 everywhere.Training a GAN: the fakes' distribution moves onto the real one00.20.40.60123456789valuereal datafakesdiscriminatorD*(x), right axis00.51
The amber curve is the best possible discriminator for each stage: p_data ÷ (p_data + p_fake).

In theory the contest ends when the generator's fakes are distributed exactly like the real data. Then the best the discriminator can do is guess, and it outputs 0.5 for everything.

Why GANs are hard to train

Two networks chasing each other do not always settle down:

  • Mode collapse: the generator finds a few outputs that fool the discriminator and produces only those, ignoring the variety of the real data.
  • Oscillation: the two networks circle around each other instead of converging.
  • Vanishing gradients: if the discriminator becomes too good too fast, its verdicts saturate and give the generator almost no signal to learn from.
Mode collapseThree panels, each with eight faint rings arranged in a circle. Real data, in teal, has points in all eight clusters. A healthy generator, in pink, also fills all eight. A collapsed generator, in red, piles all its points into just two of the clusters: each fake looks real, but the variety of the data is lost.Mode collapse: fooling the detective with only a few kinds of outputreal data: 8 clustershealthy generator: all 8mode collapse: only 2Each fake on its own looks real, but the variety of the data is lost.
A classic test: real data in a ring of clusters makes collapse easy to see.

Because there is no single loss that falls steadily, judging progress is hard too. The usual measure, the Fréchet Inception Distance (FID) from 2017, compares statistics of real and generated images inside a trained image classifier: lower is better.

GANs in the world

YearModelMilestone
2014GANBlurry but recognisable digits and faces
2015DCGANConvolutional GANs that train reliably
2016pix2pixImage-to-image translation: sketches to photos, day to night
2017CycleGANTranslation without paired examples: horses into zebras
2017Progressive GANPhotorealistic faces at 1024 × 1024 pixels
2018StyleGANControl over pose, hair and age; the faces behind thispersondoesnotexist.com

The same power enables harm. Deepfakes, a word coined in 2017, put real people's faces and voices into fake videos, and have been used for fraud, harassment and misinformation. Level 15 covers detection, watermarking and the law; Lesson 12.2 shows the newer method that has largely replaced GANs for image generation.

Hands-on: an autoencoder and a GAN

A two-into-one autoencoder

Forty points lie close to the line y = 2x. The encoder squeezes each point's two numbers into one, and the decoder rebuilds two numbers from that one. To rebuild well, the network has to discover the line.

Python
import random

random.seed(1)
data = []
for _ in range(40):
    t = random.uniform(-1, 1)
    data.append((t + random.gauss(0, 0.05), 2 * t + random.gauss(0, 0.05)))

enc = [0.3, -0.2]          # encoder: z = enc . x       (2 numbers squeezed into 1)
dec = [0.1, 0.4]           # decoder: x' = dec * z      (1 number expanded back into 2)
lr = 0.05
for epoch in range(301):
    total = 0.0
    for x in data:
        z = enc[0] * x[0] + enc[1] * x[1]
        rec = [dec[0] * z, dec[1] * z]
        err = [rec[0] - x[0], rec[1] - x[1]]
        total += err[0] ** 2 + err[1] ** 2
        g_dec = [2 * err[0] * z, 2 * err[1] * z]
        g_z = 2 * (err[0] * dec[0] + err[1] * dec[1])
        g_enc = [g_z * x[0], g_z * x[1]]
        dec = [d - lr * g for d, g in zip(dec, g_dec)]
        enc = [e - lr * g for e, g in zip(enc, g_enc)]
    if epoch % 60 == 0:
        print(f"epoch {epoch:3}: reconstruction error {total / len(data):.4f}")

print("decoder direction:", [round(d / dec[0], 2) for d in dec], "(the line y = 2x is [1, 2])")
for x in sorted(data)[:3] + sorted(data)[-3:]:
    z = enc[0] * x[0] + enc[1] * x[1]
    print(f"point ({x[0]:5.2f}, {x[1]:5.2f}) -> latent {z:5.2f} -> rebuilt ({dec[0] * z:5.2f}, {dec[1] * z:5.2f})")

A GAN in one dimension

The real data are numbers with mean 4 and spread 1.25. The generator starts by producing numbers with mean 0 and spread 1, and only ever learns from the discriminator's verdicts.

Python
import math, random

random.seed(2)
def sigmoid(v):
    return 1 / (1 + math.exp(-max(-30.0, min(30.0, v))))

real_mean, real_sd = 4.0, 1.25          # the "real data" the generator never sees directly
a, b = 1.0, 0.0                         # generator: x = a * noise + b
w1, w2, c = 0.0, 0.0, 0.0               # discriminator: D(x) = sigmoid(w1 u + w2 u^2 + c), u = x / 4

def D(x):
    u = x / 4
    return sigmoid(w1 * u + w2 * u * u + c), u

for step in range(1501):
    # 1. the discriminator learns to say 1 for real examples and 0 for fakes
    gw1 = gw2 = gc = 0.0
    for _ in range(8):
        for x, label in ((random.gauss(real_mean, real_sd), 1), (a * random.gauss(0, 1) + b, 0)):
            d, u = D(x)
            gw1 += (d - label) * u
            gw2 += (d - label) * u * u
            gc += d - label
    w1 -= 1.0 * gw1 / 8
    w2 -= 1.0 * gw2 / 8
    c -= 1.0 * gc / 8
    # 2. the generator learns to make the discriminator say 1
    ga = gb = 0.0
    for _ in range(8):
        z = random.gauss(0, 1)
        d, u = D(a * z + b)
        g_x = -(1 - d) * (w1 + 2 * w2 * u) / 4      # how -log D changes as the fake moves
        ga += g_x * z
        gb += g_x
    a -= 0.05 * ga / 8
    b -= 0.05 * gb / 8
    if step % 250 == 0:
        print(f"step {step:4}: fakes have mean {b:5.2f} and spread {abs(a):4.2f};  D(4) = {D(4)[0]:.2f}")
print(f"real data:  mean {real_mean:5.2f} and spread {real_sd:4.2f}")

Watch the spread overshoot and swing back: the two players chase each other around the answer, and D(4) hovers near 0.5 once the fakes are convincing.

Try this

  1. In the autoencoder, change the data to lie along y = −x. Which direction does the decoder find?
  2. In the GAN, change the generator's learning rate from 0.05 to 0.5. What happens to the spread?

Level check

  • Distinguish discriminative and generative models, with examples
  • Describe an autoencoder, its bottleneck and its reconstruction loss
  • Give three uses of autoencoders
  • Explain what a latent space is and what interpolating in it does
  • Explain how a VAE makes its latent space suitable for sampling
  • Describe how a GAN's generator and discriminator are trained against each other
  • Explain mode collapse and why GAN training is unstable
  • Discuss the benefits and harms of generated images

Key terms you must be able to define

Generative model
A model that learns what data looks like, so it can produce new examples.
Discriminative model
A model that learns to predict a label from an input.
Autoencoder
An encoder and a decoder trained to rebuild their input through a small bottleneck.
Latent code
The small vector an encoder produces; the compressed description of one input.
Latent space
The space of all latent codes, in which similar inputs lie close together.
Reconstruction error
How different an autoencoder's output is from its input.
Variational autoencoder (VAE)
An autoencoder whose codes are sampled from learned clouds pulled towards a standard bell curve, so new data can be sampled.
Generative adversarial network (GAN)
A generator and a discriminator trained against each other.
Generator
The network in a GAN that turns random noise into fake data.
Discriminator
The network in a GAN that learns to tell real data from fakes.
Mode collapse
When a generator produces only a few kinds of output instead of the data's full variety.
Deepfake
Realistic generated media that puts a real person's face or voice into something they never did.

Flashcards

DefineGenerative model
AnswerA model that learns what data looks like, so it can produce new examples.
DefineDiscriminative model
AnswerA model that learns to predict a label from an input.
DefineAutoencoder
AnswerAn encoder and a decoder trained to rebuild their input through a small bottleneck.
DefineLatent code
AnswerThe small vector an encoder produces; the compressed description of one input.
DefineLatent space
AnswerThe space of all latent codes, in which similar inputs lie close together.
DefineReconstruction error
AnswerHow different an autoencoder's output is from its input.
DefineVariational autoencoder (VAE)
AnswerAn autoencoder whose codes are sampled from learned clouds pulled towards a standard bell curve, so new data can be sampled.
DefineGenerative adversarial network (GAN)
AnswerA generator and a discriminator trained against each other.

Go further: notes for future AI engineers

The optimal discriminator

For a fixed generator, the best possible discriminator can be written down exactly. If pdata(x) is how likely x is under the real data and pg(x) under the generator, then

D*(x) = pdata(x) ÷ (pdata(x) + pg(x))

Where the generator makes too many of something, D* is below 0.5; where it makes too few, above 0.5. Training the generator against this D* turns out to minimise the Jensen–Shannon divergence, a measure of the difference between the two distributions, which is zero exactly when they are equal, and then D*(x) = 0.5 everywhere.

Wasserstein GANs

When the real and fake distributions barely overlap, the Jensen–Shannon divergence stops changing and the generator's gradients vanish. Wasserstein GANs (2017) instead measure the "earth mover's distance": how much probability has to be moved, and how far, to turn one distribution into the other. It keeps shrinking smoothly as the fakes improve, which made GAN training far more stable.

Misconceptions to avoid

Avoid these
  • Thinking an autoencoder is useful because its output matches its input. The point is the small code it is forced to learn.
  • Believing the generator copies training images. It never sees them; it learns only from the discriminator's verdicts.
  • Assuming a GAN's losses fall steadily like a classifier's. They rise and fall as the two networks compete.
  • Thinking a discriminator at 0.5 is broken. When the fakes match the real data perfectly, 0.5 is the best possible answer.
  • Sampling from a plain autoencoder's latent space and expecting good results. Only a VAE's latent space is shaped for sampling.
Fun fact

By Ian Goodfellow's own account, he came up with generative adversarial networks in 2014 while arguing with friends in a bar in Montreal, went home, and wrote a version that worked that same night.

Knowledge check

0 of 10 answered
1What does a generative model learn?
2Why does an autoencoder have a small bottleneck in the middle?
3An autoencoder trained on normal engine sounds rebuilds a new sound badly. What might that mean?
4What happens when you decode points along a straight line between two latent codes?
5What extra term does a variational autoencoder add to its loss?
6In a GAN, what does the generator receive as input?
7How does the generator learn to improve its fakes?
8A GAN's generator produces only two kinds of face, though the data has many. What is this called?
9When a GAN's generator perfectly matches the real data, what does the best discriminator output?
10Which of these is a misuse of generative models?
Score 0 / 10

Check you could explain this

12 marks
1Describe how an autoencoder is trained, and explain one use of it.4 marks
Describe

Mark scheme0 / 4
  • LAn encoder compresses the input into a small latent code / bottleneck
  • LA decoder rebuilds the input from the code
  • LTrained to minimise the reconstruction error between input and output
  • LA use, explained: compression, denoising or anomaly detection
Model answer

An autoencoder has an encoder that compresses the input, such as an image, into a much smaller latent code, and a decoder that tries to rebuild the original from that code. Both are trained together by gradient descent to minimise the reconstruction error, the difference between the input and the rebuilt output, so the code is forced to capture the most important features. One use is anomaly detection: an autoencoder trained only on normal data rebuilds unusual data badly, so a large reconstruction error flags, for example, a faulty machine part.

The marker looks for key phrases. If you said it another way and it is still right, give yourself the mark.

Think this answer or mark scheme is wrong? Report it

2Explain how a generative adversarial network is trained.5 marks
Explain

Mark scheme0 / 5
  • LA generator turns random noise into fake data
  • LA discriminator is trained to tell real data from fakes
  • LThe generator is trained to make the discriminator classify its fakes as real
  • LThey are trained alternately / take turns
  • LUsing the gradient of the discriminator's output with respect to the fakes
  • LIdeally until fakes match the data and the discriminator outputs 0.5
Model answer

A GAN has two networks. The generator takes random noise and turns it into fake data; the discriminator is shown both real examples and fakes and is trained to output 1 for real and 0 for fake. Training alternates between them: the discriminator takes a step to get better at spotting fakes, then the generator takes a step to make the discriminator call its fakes real, using the gradient of the discriminator's verdict, backpropagated through the discriminator into the generator. Ideally the contest continues until the fakes are distributed like the real data and the discriminator can only guess, outputting 0.5.

The marker looks for key phrases. If you said it another way and it is still right, give yourself the mark.

Think this answer or mark scheme is wrong? Report it

3Explain why a variational autoencoder can generate new data when a plain autoencoder usually cannot.3 marks
Explain

Mark scheme0 / 3
  • LA plain autoencoder's latent space has gaps; random points decode to nonsense
  • LA VAE's encoder outputs a mean and spread, and codes are sampled from that cloud
  • LAn extra loss term pulls the clouds towards a standard bell curve, filling the space smoothly
  • LSo a random sample from the standard bell curve decodes to a sensible new example
Model answer

A plain autoencoder maps each input to a single point, and the points it learns are scattered with gaps between them, so a random latent point often decodes to nonsense. A VAE's encoder instead outputs a mean and a spread, and the code is sampled from that small cloud, while an extra loss term pulls every cloud towards a standard bell curve centred on zero. This packs the codes into one smooth region without gaps, so a random sample from the standard bell curve decodes to a sensible new example.

The marker looks for key phrases. If you said it another way and it is still right, give yourself the mark.

Think this answer or mark scheme is wrong? Report it

Machine mark 0 / 12