Lensa ML

How GANs Work

Step 1 of 6: The Goal: Fool the Best Referee

Two distributions, and the best possible discriminator between them

-4-2024600.51real datageneratorbest possible D
Generator centre-1.00
Generator spread0.80
Gap between the two (JS divergence, 0 to 1)
0.957
Best possible referee accuracy
99%
Real data: centre · spread
2 · 0.5

A GAN has two networks. The generator makes fake samples (red); the discriminator, a referee, sees one sample at a time and outputs D(x), its probability that the sample is real. Here the data is just numbers, drawn from the green curve. For any generator, the best possible referee is D(x) = p_real / (p_real + p_fake), the dashed line: near 1 where only real data lives, near 0 where only fakes land. Right now the best referee could be right 99% of the time. Move the generator onto the green curve and watch that fall to 50%: then the referee can do no better than a coin flip, which is exactly the generator's goal.

Drag the generator onto the green curve and watch the best referee's accuracy fall to 50%. Goodfellow et al. (2014) showed that for a fixed generator the best discriminator is D*(x) = p_data(x) / (p_data(x) + p_g(x)), and that against D* the generator's objective is a constant plus twice the Jensen–Shannon divergence between the two distributions. So training the generator against a good discriminator pushes the JS gap (top-left card) towards 0, where D* is 0.5 everywhere. Real GANs do this in millions of dimensions, one per pixel, but the picture is the same.

Step 2 of 6: The Generator Is a Function

Noise in, samples out

noise z ~ N(0, 1)x = G(z) = b + a·z-4-20246

Green band = where most real data lies (2 ± 1).

weight a0.80
bias b0.00
Output centre (= b)
0.00
Output spread (= |a|)
0.80
Gap to real data (JS)
0.771

The generator never sees real data. It's a function that turns random noise into a sample: draw z from a bell curve, output G(z). This one is the smallest possible network, one weight and one bias, so x = b + a·z. Each grey dot on top is a noise value and its line shows where G sends it. The noise is what makes every sample different; a and b decide what shape those samples form. Matching the data here means b = 2 and |a| = 0.5. The next steps show how the discriminator teaches the generator to find those values.

Set a to 0 and every noise value lands on the same output. Real generators work the same way with far more parameters: a vector z of 100 to 512 Gaussian numbers goes through a deep network that outputs an image. DCGAN (Radford et al., 2015) set the standard design of transposed convolutions that double the image size at each layer. Whatever the size, the generator is a function: the same z always gives the same output, and the randomness comes only from drawing z.

Step 3 of 6: Training the Discriminator

Its slope is the generator's only teacher

-4-2024600.51real datageneratorD(x)best possible D

Amber arrows under the fakes = the slope of D there, the direction that looks more real to it.

Discriminator steps
0
Its loss (2 ln 2 = 1.386 means guessing)
1.386
Mean D on real · on fake
0.50 · 0.50
Slope of D at the fakes' centre
0.000

Now the generator is frozen and only the discriminator trains. Each step it sees 64 real and 64 fake samples and nudges its weights to push D up on real ones and down on fakes, minimising −log D(real) − log(1 − D(fake)). It starts at 0.5 everywhere: it can't tell them apart. Press play. Where there's no data at all, far to the left, D's value means nothing: nothing constrains it there. The arrows matter most: the slope of D at each fake sample is the only thing the generator will ever learn from.

Press play and watch the amber curve approach the dashed best possible curve where there is data. The discriminator is an ordinary binary classifier trained with cross-entropy on its probability, −log D(real) − log(1 − D(fake)); a loss of 2 ln 2 ≈ 1.386 means it is guessing. This one is logistic regression on 23 fixed bumps plus x and x², which makes its slope exact. In a real GAN it is a convolutional network, and its gradient with respect to the input image, computed by backpropagation, is the signal the generator trains on.

Step 4 of 6: The Adversarial Game

Take turns until D can only guess

discriminator steps per generator step:
-4-2024600.51real datageneratorD(x)0 stepsgap (JS)D loss ÷ 2 ln 2
Generator steps
0
Generator centre · spread
-2.50 · 0.50
Gap to real data (JS)
1.000
Discriminator loss
1.386

Now both train in turn: 1 discriminator update, then one generator update that moves a and b so its samples climb the slope of D. Neither network ever sees the other's weights; the generator learns only through D's slope. The generator starts far to the left. Press play.

Press play and watch the red curve slide onto the green one, then compare 1, 3 and 5 discriminator steps per generator step. Each generator update moves a and b along the average slope of D at its own samples, using the non-saturating loss. As fakes arrive in a region, D stops calling it real, so the generator keeps being pushed until the two distributions overlap. At that point D is about 0.5 everywhere and its loss is near 2 ln 2. This 1-D GAN converges cleanly; large GANs often oscillate around the equilibrium instead of settling.

Step 5 of 6: When the Referee Wins Too Early

Why GANs use the non-saturating loss

-4-2024600.51real datageneratorD(x)0 stepsgap (JS)generator gradient
Mean D on fakes
0.002
Generator gradient now
0.008
First-step gradient: minimax · non-sat.
0.008 · 1.59
Gap to real data (JS)
1.000

Here the discriminator got a 400-step head start, so it rejects the fakes with confidence: D on them is 0.002. The original minimax loss asks the generator to minimise log(1 − D(fake)). When D(fake) is near 0 that curve is almost flat, so the gradient is tiny: 0.008 on the first step, against 1.59 for the other loss. Press play and the generator barely moves for a long time. Both losses aim at the same equilibrium; only how hard they pull from far away differs. That's why practically every GAN uses the non-saturating version.

Compare the first-step gradients of the two losses against the same confident discriminator. The original minimax objective has the generator minimise log(1 − D(G(z))), which is flat when D(G(z)) is near 0, exactly the situation early in training. Goodfellow et al. proposed maximising log D(G(z)) instead. It has the same fixed point but a steep slope when the generator is losing. Later variants such as WGAN (Arjovsky et al., 2017) replace the loss altogether to keep gradients useful even when the two distributions don't overlap.

Step 6 of 6: Mode Collapse

Two clusters of real data, one generator

-4-2024600.51real datageneratorD(x)
Generator steps
0
Fakes near the left mode
0%
Fakes near the right mode
0%
Gap to real data (JS)
0.967

Now the real data has two clusters, say two kinds of image. Press play and let it run for a few hundred steps. Try the other buttons: what the generator can represent and where it starts both decide what it ends up making.

Try all four combinations of generator and starting point. A straight generator can only make one bell curve, so it either covers one cluster or smears across the gap. The bent generator can make two bumps, but only finds both clusters if it starts between them. Started on one cluster, both get stuck, because the generator only learns from D's slope where its own samples are. Real GANs suffer the same way, producing only a few kinds of output. Remedies include minibatch features that let D see diversity, unrolled updates, and different losses.

What is a generative adversarial network (GAN)?

A generative adversarial network (GAN) is a pair of neural networks trained against each other: a generator that turns random noise into fake data, and a discriminator that tries to tell fake data from real data. The generator improves by learning to fool the discriminator, and the discriminator improves by catching it. When training works, the generator's outputs become hard to distinguish from the training set.

GANs produced the first convincing high-resolution synthetic faces, and they are used for image super-resolution, image-to-image translation (sketches to photos, day to night), data augmentation, and style editing. A trained generator makes an image in a single forward pass, which keeps GANs fast enough for real-time use. Their adversarial loss also appears inside other systems, for example to sharpen the decoders of image autoencoders.

Key ideas

  • A GAN trains a generator and a discriminator against each other.
  • The generator maps random noise z to a sample and never sees real data directly.
  • The discriminator is a binary classifier that outputs the probability an input is real.
  • At the ideal equilibrium the generated distribution matches the data and D outputs 0.5 everywhere.
  • Training is unstable: one network can overpower the other, and the generator can collapse to a few outputs.
  • A trained generator makes a sample in one forward pass.

Common questions

What is the difference between a GAN and a VAE?

A VAE is trained to reconstruct its inputs through a probabilistic latent code and gives an estimate of likelihood, but its samples tend to be blurry. A GAN never reconstructs anything; it learns only from the discriminator's feedback, which gives sharper samples but less stable training and no likelihood. Some models combine both, using a VAE with an adversarial loss on its decoder.

Are GANs still used now that diffusion models exist?

Diffusion models now lead in general text-to-image generation because they train more reliably and cover more of the data. GANs remain common where speed matters, such as real-time super-resolution, video filters, and face editing. Adversarial losses are also used to distill diffusion models into fast few-step generators.

Can GANs generate text?

Not easily. Text is made of discrete tokens, and picking a token is not differentiable, so the discriminator's gradient cannot flow back into the generator. Workarounds use reinforcement learning or continuous relaxations such as Gumbel-softmax, but autoregressive language models work far better for text.

What is a CycleGAN?

CycleGAN learns to translate images between two domains, such as horses and zebras, without paired examples. It trains two generators, one for each direction, plus a cycle-consistency loss: translating an image to the other domain and back should return the original. This lets it learn from two unmatched collections of images.

Related explainers

References

  1. Goodfellow et al. (2014), "Generative Adversarial Nets", NeurIPS
  2. Radford, Metz & Chintala (2015), "Unsupervised Representation Learning with Deep Convolutional Generative Adversarial Networks"
  3. Gulrajani et al. (2017), "Improved Training of Wasserstein GANs"
  4. Karras, Laine & Aila (2019), "A Style-Based Generator Architecture for Generative Adversarial Networks", CVPR

Last updated