Phase 08: Generative AI

GANs Générateur contre Discriminateur

Le truc de Goodfellow en 2014 était de sauter la densité entièrement. Deux réseaux. L'un fait des faux. L'autre les attrape. Ils se battent jusqu'à ce que les faux soient indistinguibles du vrai. Cela ne devrait pas fonctionner. Cela ne fonctionne souvent pas. Quand cela se produit, les échantillons sont toujours les plus acérés dans la littérature pour les domaines étroits.

Type: Build

Languages: Python

Prerequisites: Phase 3 · 02 (Backprop), Phase 3 · 08 (Optimizers), Phase 8 · 02 (VAE)

Time: ~75 minutes

Le problème

Les VAE produisent des échantillons flou parce que leur perte de décodeur MSE est Bayes-optimale pour l'image moyenne et la moyenne de nombreux chiffres plausibles est un chiffre flou. Vous voulez une perte qui récompense plausibilité, pas la proximité pixel-wise à une cible. Il n'y a pas de forme fermée pour la plausibilité. Vous devez l'apprendre.

L'idée de Goodfellow: former un classifiateur D(x)Pour distinguer les images réelles des fausses.G(z)Pour faire la folieD- Le signal de perte pourGC' est quoi ?DCe signal est mis à jour commeGSi les deux réseaux convergent,Ga appris la distribution des données sans jamais écrire.log p(x)- Je suis désolé .

C'est une formation à l'adversité.

min_G max_D  E_real[log D(x)] + E_fake[log(1 - D(G(z)))]

En 2026, les GAN ne sont plus le générateur de SOTA (diffusion et flux de correspondance ont mangé cette couronne). Mais StyleGAN 2/3 reste les modèles de visage les plus acérés jamais expédiés, les discriminateurs GAN sont utilisés comme persections perceptuelles dans l'entraînement à la diffusion, et l'entraînement à l'adversité alimente les distillations rapides en 1 étape (SDXL-Turbo, SD3-Turbo, LCM) qui vous permettent d'expédition diffusion en temps réel.

Le concept

!GAN training: generator and discriminator in minimax

Generator G(z).Mape un vecteur de bruit z ~ N(0, I)à un échantillon x̂Un réseau en forme de décodeur (convecteur dense ou transposé).

Discriminator D(x).Mape un échantillon à une probabilité (ou score) scalaire.

Loss.Deux mises à jour alternatives:

  • Train D: loss_D = -[ log D(x) + log(1 - D(G(z))) ]- Entropie binaire croisée sur réel = 1, faux = 0.
  • Train G: loss_G = -log D(G(z))C'est la forme non saturante utilisée par Goodfellow (original)log(1 - D(G(z)))saturé et tue les gradients lorsque Dest confiant).

Training loop.Une étape de D, une étape de GJe répète.

Why it works.Si vousGIl est parfait .p_dataAlors ...Dne peut pas faire mieux que le hasard et les résultats sont 0,5 partout; GIl n'y a plus de gradient.

Why it breaks.L'effondrement du mode (Gtrouve un mode DJe ne peux pas le classer et le mettre à mort pour toujours, le gradient disparaissant (DIl apprend trop vite et log DLes taux d'apprentissage, les tailles de lot, tout ce qui est nécessaire.

Variantes qui ont permis de faire fonctionner les GAN

YearInnovationFix
2015DCGANConv/deconv, batch norm, LeakyReLU — the first stable architecture.
2017WGAN, WGAN-GPReplace BCE with Wasserstein distance + gradient penalty. Fixes vanishing gradient.
2017Spectral normalizationLipschitz-bound the discriminator. Still used in 2026 discriminators.
2018Progressive GANTrain low-res first, add layers. First megapixel results.
2019StyleGAN / StyleGAN2Mapping network + adaptive instance norm. State of the art for fixed-domain photorealism.
2021StyleGAN3Alias-free, translation-equivariant — still the face gold standard in 2026.
2022StyleGAN-XLConditional, class-aware, larger scale.
2024R3GANRebrands with stronger regularization; works on 1024² without tricks.

Faites-le

code/main.pyLe générateur et le discriminateur sont des MLP à couche cachée unique. Nous mettons en œuvre la boucle avant, arrière et minimax à la main. L'objectif est de voir les deux modes de défaillance clés (effondrement de mode + gradient de disparition) au fur et à mesure qu'ils se produisent.

Étape 1: Perte non saturante

La perte de la vanille de Goodfellow .log(1 - D(G(z)))Le gradient de G est essentiellement zéro G ne peut pas s'améliorer.-log D(G(z))Il est opposé à l'asymptote: il explose quand D est confiant, donnant à G un signal fort.

pythondef g_loss(d_fake):
    # maximize log D(G(z))  <=>  minimize -log D(G(z))
    return -sum(math.log(max(p, 1e-8)) for p in d_fake) / len(d_fake)

Étape 2: une étape discriminatrice par étape génératrice

pythonfor step in range(steps):
    # train D
    real_batch = sample_real(batch_size)
    fake_batch = [G(z) for z in sample_noise(batch_size)]
    update_D(real_batch, fake_batch)

    # train G
    fake_batch = [G(z) for z in sample_noise(batch_size)]  # fresh fakes
    update_G(fake_batch)

Des faux pour G, sinon les gradients sont obsolètes.

Étape 3: surveillez l'effondrement du mode

pythonif step % 200 == 0:
    samples = [G(z) for z in sample_noise(500)]
    mode_a = sum(1 for s in samples if s < 0)
    mode_b = 500 - mode_a
    if min(mode_a, mode_b) < 50:
        print("  [!] mode collapse: one mode is starved")

Le symptôme canonique: l'un des deux modes réels cesse d'être généré. Le discriminateur cesse de le corriger parce qu'il n'est jamais vu comme faux.

Les pièges

  • Discriminator too strong.Réduire le taux d'apprentissage de D de 2 à 5 fois, ou ajouter du bruit d'instance/couche. Si D atteint une précision de > 95%, G est mort.
  • Generator memorizes a mode.Ajouter du bruit aux entrées D, utiliser une couche de discrimination mini-batch ou passer à WGAN-GP.
  • Batch norm leaking statistics.Les statistiques sont mélangées par un vrai lot + un faux lot qui traverse la même couche BN.
  • Inception-score gaming.Les échantillons FID et IS sont bruyants à faible nombre d'échantillons.
  • One-shot sampling is a lie for conditional tasks.Vous avez encore besoin de balances CFG, de trucs de troncage et de re-échantillonnage pour obtenir des résultats utilisables.

Utilisez-le

La pile de GAN 2026:

SituationPick
Photoreal human faces, fixed poseStyleGAN3 (sharpest, smallest)
Anime / stylized facesStyleGAN-XL or Stable Diffusion LoRA
Image-to-image translationPix2Pix / CycleGAN (Phase 8 · 04) or ControlNet (Phase 8 · 08)
Fast 1-step text-to-imageAdversarial distillation of diffusion (SDXL-Turbo, SD3-Turbo)
Perceptual loss inside a diffusion trainerSmall GAN discriminator on image crops
Anything multi-modal, open-endedDon't — use diffusion or flow matching

Les GAN sont nettes mais étroites. Une fois que votre domaine s'ouvre photos, des textes arbitraires, des vidéos passer à la diffusion.

La faire partir

  • Ça va .outputs/skill-gan-debugger.md. Skill prend une opération GAN défaillante (curves de perte, grille d'échantillon, taille de jeu de données) et produit une liste classée des causes probables, des corrections à une ligne et un protocole de répétition.

Exercices

  1. Easy.On court .code/main.pyavec les paramètres de stock.D_LR = 5 * G_LRLa perte de G s'effondre rapidement à une constante.
  2. Medium.Remplacez la perte de Goodfellow BCE par la perte de WGAN: loss_D = E[D(fake)] - E[D(real)]- Je suis là .loss_G = -E[D(fake)], et de cliper les poids de D à [-0.01, 0.01]- L'entraînement est plus stable ?
  3. Hard.Extension de l'exemple 1D à des données 2D (mixture de 8 Gaussians sur un anneau). Suivre combien des 8 modes le générateur capture aux étapes 1k, 5k, 10k. Implémenter la discrimination minibatch et re-mesure.

Les termes clés

TermWhat people sayWhat it actually means
Generator"G"Noise-to-sample network, G: z → x̂.
Discriminator"D"Classifier D: x → [0, 1], real vs fake.
Minimax"The game"min_G max_D of a joint objective.
Non-saturating loss"The fix"Use -log D(G(z)) for G instead of log(1 - D(G(z))).
Mode collapse"G memorized one thing"Generator produces few distinct outputs despite diverse data.
WGAN"Wasserstein"Replace BCE with Earth-Mover distance + gradient penalty; smoother gradient.
Spectral norm"Lipschitz trick"Constrain D's weight norms to bound its slope; stabilizes training.
StyleGAN"The one that works"Mapping network + AdaIN; best-in-class for faces, still in 2026.

Note de production: l'inférence à un seul coup est l'avantage durable de GAN

Les GAN ne gagnent plus sur la qualité des échantillons pour la génération de domaine ouvert, mais ils gagnent toujours sur le coût de l'inférence.

  • No prefill, no decode stages.Une seule .G(z)TTFT ≈ latence totale.
  • No KV-cache pressure.La taille du lot est limitée par la mémoire d'activation, pas par le cache.
  • Trivial continuous batching.Comme chaque demande reçoit les mêmes FLOPs fixes, un lot statique à l'occupation cible du serveur est généralement optimal.

C'est pourquoi la distillation GAN (SDXL-Turbo, SD3-Turbo, ADD, LCM) est la technique dominante pour la transmission rapide de texte à image en 2026: elle effondre un pipeline de diffusion de 20 à 50 étapes en passages avant de 1 à 4 GAN tout en conservant la distribution d'une base de diffusion.

Pour en savoir plus

This free lesson is part of the AI Engineering from Scratch curriculum. Read the full explanation, run the lesson code, and verify the result in the interactive reader or from the repository source.

Browse the complete course catalog or open this lesson on GitHub.