Přeskočit na obsah
coden

Generativní adversariální sítě (GAN): padělatel proti detektivovi

Hra generátoru a diskriminátoru, GAN napsaný od nuly, nesaturující ztráta, osm shluků na kružnici a zhroucení módů, číslice ostřejší než u VAE, ale ne všechny, a cesta od GAN k difúzním modelům.

12 minut Matěj Žalmánek 2026-10-16

Série Základy AI Díl 76 z 83
  1. Mapa umělé inteligence: co je co a jak to do sebe zapadá
  2. Stručná historie umělé inteligence: od Turinga po jazykové modely
  3. Data, model, trénink, inference: základní pojmy na jednom příkladu
  4. Jak číst matematický zápis: symboly, indexy, sumy a kvantifikátory
  5. Množiny a relace: stavebnice, ze které se skládají definice v AI
  6. Funkce a zobrazení: proč je každý model v AI funkce
  7. Logika a důkazy: pravidla, podle kterých se v AI uvažuje
  8. Grafy a stromy: struktura, na které stojí hledání i neuronové sítě
  9. Lineární algebra pro strojové učení: vektory, matice a proč AI hlavně násobí
  10. Derivace, gradient a řetízkové pravidlo: jak model zjistí, kterým směrem se učit
  11. Gradientní sestup: jak se model učí
  12. Co je pravděpodobnost: od hodu kostkou ke Kolmogorovovým axiomům
  13. Podmíněná pravděpodobnost a Bayesova věta: jak změnit odhad, když se dozvíte něco nového
  14. Náhodná veličina a distribuční funkce: jedna funkce, která o rozdělení řekne všechno
  15. Funkce hustoty a pravděpodobnostní funkce: proč má spojitá veličina v bodě pravděpodobnost nula
  16. Střední hodnota, rozptyl a kovariance: kde rozdělení leží, jak je široké a co s čím souvisí
  17. Přehled pravděpodobnostních rozdělení: Bernoulli, binomické, Poisson, rovnoměrné, normální a exponenciální
  18. Zákon velkých čísel a centrální limitní věta: proč se průměry chovají tak předvídatelně
  19. Statistika a odhady parametrů: maximální věrohodnost, MAP a intervaly spolehlivosti
  20. Teorie informace: entropie, křížová entropie a KL divergence — odkud se berou ztrátové funkce
  21. Prohledávání stavového prostoru: BFS, DFS, UCS a A* s animacemi
  22. Hry a protivník: minimax, alfa-beta ořezávání a Monte Carlo tree search
  23. Splňování omezujících podmínek: backtracking, propagace omezení a AC-3 na sudoku a mapě krajů
  24. Logika a znalostní systémy: dopředné a zpětné řetězení, rezoluce a expertní systémy
  25. Plánování: STRIPS, svět kostek, heuristiky z relaxace a plánování v AI agentech
  26. Lokální hledání a simulované žíhání: obchodní cestující přes krajská města
  27. Genetické algoritmy: populace, křížení, mutace a výběr na batohu na výlet
  28. Evoluční strategie a genetické programování: od pravidla jedné pětiny po Keplerův zákon
  29. Optimalizace mravenčí kolonií: jak feromonová stopa najde krátkou cestu
  30. Optimalizace hejnem částic: setrvačnost, vlastní zkušenost a zkušenost hejna
  31. Neuroevoluce: evoluce vah i tvaru neuronových sítí a algoritmus NEAT
  32. Fuzzy množiny a funkce příslušnosti: jak zapsat „trochu teplo“
  33. Fuzzy logika a pravděpodobnost: proč „trochu teplo“ neznamená „pravděpodobně teplo“
  34. Fuzzy logika: t-normy, implikace a pravidla KDYŽ–PAK
  35. Fuzzy řízení: Mamdani a Sugeno od ventilátoru po kyvadlo na vozíku
  36. Fuzzy shlukování: algoritmus fuzzy c-means a body mezi shluky
  37. Neuro-fuzzy systémy (ANFIS): fuzzy pravidla, která se učí z dat
  38. Markovovy řetězce: přechodová matice, stacionární rozdělení a PageRank
  39. Skryté Markovovy modely: Viterbiho algoritmus a nepoctivé kasino
  40. Bayesovské sítě: proč je tráva mokrá a co z toho plyne pro postřikovač
  41. Kalmanův filtr: jak z nepřesných měření odhadnout, kde auto je a jak rychle jede
  42. Druhy strojového učení: s učitelem, bez učitele, s částečným učitelem a další
  43. Přeučení a regularizace: proč model, který zná data nazpaměť, selže
  44. Vyhodnocení modelu: křížová validace, F1 a křivka ROC
  45. Shlukování a snížení dimenze: k-means, PCA a t-SNE
  46. Klasifikace a regrese: dvě úlohy učení s učitelem
  47. Lineární regrese: nejmenší čtverce geometricky i maticově
  48. Polynomiální a nelineární regrese: jak přímku ohnout
  49. Logistická regrese: sigmoida, šance a křížová entropie
  50. Vícetřídní klasifikace a softmax: od dvou tříd k mnoha
  51. Naivní Bayesův klasifikátor: spamový filtr, který funguje lépe, než by měl
  52. Ztrátové funkce: co přesně model minimalizuje
  53. Rozhodovací stromy a k nejbližších sousedů: modely bez vzorců
  54. Ansámbly: náhodný les a gradient boosting
  55. SVM a jádrový trik: nejširší hranice a jak ji ohnout
  56. Signál a vzorkování: proč platí Nyquistův teorém
  57. Fourierova transformace: rozklad signálu na frekvence
  58. Filtry a konvoluce: vyhlazení, hrany a odstranění šumu
  59. Zvuk a řeč: spektrogram, melová škála a MFCC
  60. Obraz jako signál: pixely, barvy, konvoluce a hrany
  61. Perceptron a umělý neuron: nejjednodušší neuronová síť a co neumí
  62. Neuronová síť od nuly: zpětné šíření chyby krok za krokem
  63. Aktivace, inicializace a normalizace: drobnosti, na kterých hluboká síť stojí
  64. Konvoluční sítě: jak síť poznává obrázky
  65. Rekurentní sítě: paměť pro posloupnosti a mizející gradient
  66. LSTM a GRU: brány, které rozhodují, co si síť zapamatuje
  67. Autoenkodéry: síť, která se učí data stlačit a zase rozbalit
  68. Embeddingy a word2vec: jak se slovo stane vektorem
  69. Mechanismus pozornosti: jak se model naučí, kam se dívat
  70. Transformery a velké jazykové modely: architektura krok za krokem
  71. Tokenizace: jak se text rozseká na kousky pro model
  72. Předtrénování a škálování: proč větší model a víc dat funguje
  73. Doladění a RLHF: jak se z doplňovače textu stane asistent
  74. Prompty, kontext a RAG: jak modelu dát správné informace
  75. Variační autoenkodéry (VAE): nové obrázky ze spojitého latentního prostoru
  76. Generativní adversariální sítě (GAN): padělatel proti detektivovi
  77. Difúzní modely: jak se z čistého šumu stane obrázek
  78. Markovovy rozhodovací procesy: stavy, akce, odměny a Bellmanovy rovnice
  79. Q-learning a DQN: učení hodnoty akcí od tabulky po neuronovou síť
  80. Policy gradient a PPO: učení přímo strategie
  81. Jak funguje AI agent: jazykový model ve smyčce s nástroji
  82. Programování s AI agenty: zadání, testy a kontrola
  83. Vyhodnocení a bezpečnost AI systémů: jak měřit a jak hlídat

Celá osnova série 83 z 83 témat hotovo

Co si odnesete
  • Jak se generátor učí jen z gradientu diskriminátoru.
  • Proč je učení GAN nestabilní a co je zhroucení módů.
  • V čem GAN vyhrává nad VAE, v čem prohrává a proč je dnes nahradila difúze.

Co se hodí znát předem: Variační autoenkodéry (VAE): nové obrázky ze spojitého latentního prostoru, Logistická regrese: sigmoida, šance a křížová entropie, Hry a protivník: minimax, alfa-beta ořezávání a Monte Carlo tree search

Variační autoenkodér z minulého dílu generuje poctivě, ale rozmazaně. V roce 2014 přišel Ian Goodfellow s nápadem, který vypadá skoro jako trik: nebudeme měřit, jak moc se vzorek liší od dat, ale necháme to posoudit jinou sítí. Dvě sítě hrají hru — jedna padělá, druhá pozná padělek — a obě se při tom zlepšují. Tak vznikly první strojově generované tváře, které od fotek nerozeznáte. V tomhle dílu obě sítě napíšeme od nuly a uvidíme, proč je jejich učení tak vrtkavé.

Navazuje na díly Variační autoenkodéry, Logistická regrese (sigmoida a křížová entropie) a Hry a minimax.

1. Padělatel a detektiv

Definice — generativní adversariální síť (GAN)

Nechť 𝒳 ⊆ ℝd je prostor dat, pdata rozdělení dat na 𝒳 (s hustotou pdata), k ≥ 1 a pz = N(0, I) rozdělení šumu na ℝk. Logaritmy v tomto díle jsou přirozené (log = ln). Generativní adversariální síť (GAN; Ian Goodfellow a kol., 2014) tvoří dvě neuronové sítě:

  1. generátor G : ℝk → 𝒳, který šum z ~ pz převede na vzorek G(z); rozdělení vzorků G(z) značíme pG;
  2. diskriminátor D : 𝒳 → (0, 1), kde D(x) je odhad pravděpodobnosti, že x pochází ze skutečných dat, a ne z generátoru.

Hodnota hry je

V(D, G) = Ex ~ pdata[log D(x)] + Ez ~ pz[log(1 − D(G(z)))]

a učení hledá rovnováhu hry dvou hráčů s nulovým součtem

minG maxD V(D, G):

diskriminátor V zvyšuje, generátor snižuje, a co jeden získá, druhý ztratí. Pro pevné G je nejlepší diskriminátor D*(x) = pdata(x)/pdata(x) + pG(x) (věta níže). V rovnováze generuje G přesně rozdělení dat, pG = pdata, a D* všude vrací 1/2.

Laicky řečeno

Padělatel tiskne bankovky, detektiv je třídí na pravé a falešné. Detektiv se učí z toho, kde se spletl. Padělatel nikdy neviděl pravou bankovku — učí se jen z toho, co detektiva prozradilo. Když se oba zlepšují, padělky jsou čím dál lepší. Konec hry: detektiv může jen hádat, a hádá napůl.

minG maxD   Ex ~ pdata[ log D(x) ] + Ez ~ pz[ log(1 − D(G(z))) ]

Ex ~ pdata[log D(x)]
diskriminátor na skutečných datech — je největší (0), když D dává pravým vzorkům 1; logaritmus sebejistý omyl (D → 0) trestá neomezeně
Ez[log(1 − D(G(z)))]
diskriminátor na padělcích — je největší, když jim dává 0; je to jediný člen, ve kterém se vyskytuje G, takže generátor se učí jen z něj
maxD
diskriminátor hodnotu zvyšuje — oba členy dohromady jsou záporná binární křížová entropie, takže je to obyčejné učení klasifikátoru „pravé / padělek“
minG
generátor hodnotu snižuje — chce, aby diskriminátor na padělcích chyboval; co jeden hráč získá, druhý ztratí (nulový součet)
Hodnota hry V(D, G); obě střední hodnoty se při učení odhadují průměrem přes dávku.
Věta — nejlepší diskriminátor a co generátor minimalizuje

Nechť pdata a pG jsou hustoty na 𝒳 a generátor G je pevný. Pak pro každý diskriminátor D : 𝒳 → (0, 1) je

V(D, G) = ∫𝒳 [pdata(x) log D(x) + pG(x) log(1 − D(x))] dx

a v každém bodě x, kde pdata(x) > 0 a pG(x) > 0, je integrand maximální pro

D*(x) = pdata(x)/pdata(x) + pG(x).

S tímto diskriminátorem platí

V(D*, G) = −log 4 + 2 · JSD(pdata ‖ pG),

kde pro hustoty p, q na 𝒳 je m = 1/2(p + q) a Jensenova–Shannonova divergence JSD(p ‖ q) = 1/2 DKL(p ‖ m) + 1/2 DKL(q ‖ m) (DKL je KL divergence, pro hustoty s integrálem místo součtu, viz díl o VAE). Generátor tedy proti nejlepšímu diskriminátoru minimalizuje JSD.

Důkaz. Vzorek G(z) má hustotu pG, takže Ez[log(1 − D(G(z)))] = ∫ pG(x) log(1 − D(x)) dx; odtud první vzorec. Integrál je největší, když je v každém bodě x největší integrand, tedy funkce f(y) = a log y + b log(1 − y) pro y ∈ (0, 1), kde a = pdata(x) > 0, b = pG(x) > 0. Její derivace

f′(y) = a/y − b/1 − y

je nulová právě pro y = a/a + b, a protože f″(y) = −a/y² − b/(1 − y)² < 0, je f konkávní a jde o maximum. Odtud D*. Protože pdata + pG = 2m, je D* = pdata/2m a 1 − D* = pG/2m, takže

V(D*, G) = Epdata[log pdata/m] − log 2 + EpG[log pG/m] − log 2 = DKL(pdata ‖ m) + DKL(pG ‖ m) − log 4,

což je −log 4 + 2 · JSD(pdata ‖ pG). ∎

Jensenova–Shannonova divergence je nezáporná a nulová právě pro pG = pdata (obě KL divergence jsou nezáporné a nulové právě pro p = m = q). Minimum −log 4 ≈ −1,386 tedy nastane právě tehdy, když generátor generuje přesně data.

Příklad: tam, kde je hustota dat 0,3 a padělků 0,1, je D* = 0,3/0,3 + 0,1 = 0,75 (bod je spíš pravý); kde generátor přestřelí (data 0,1, padělky 0,3), je D* = 0,1/0,1 + 0,3 = 0,25. Tam, kde se hustoty rovnají, je D* = 1/2 a ztráta diskriminátoru (binární křížová entropie na jeden vzorek) je −log 1/2 = ln 2 ≈ 0,693.

Diskriminátor je obyčejný klasifikátor se sigmoidou a křížovou entropií, jako logistická regrese, jen s vrstvami navíc. Kouzlo je v generátoru: gradient jeho ztráty proteče zpětným šířením přes diskriminátor až do obrázku a odtud do vah generátoru. Diskriminátor mu tak říká, kterým směrem má každý pixel posunout, aby vypadal věrohodněji.

2. Učení: střídavé kroky

Učí se na střídačku: krok diskriminátoru (dávka skutečných dat a dávka padělků, zvýšit D na pravých, snížit na falešných), pak krok generátoru (posunout padělky tam, kde je D považuje za pravé). Obě sítě u nás mají dvě skryté vrstvy s leaky ReLU a učí se Adamem.

Definice — nesaturující ztráta generátoru

Nechť σ(s) = 1/1 + e−s je sigmoida a diskriminátor má tvar D(x) = σ(s(x)), kde s(x) ∈ ℝ je jeho výstup před sigmoidou (logit). Pro padělek G(z) s logitem s = s(G(z)) je

  1. původní (minimaxová) ztráta generátoru ℓmm(s) = log(1 − σ(s)) = log(1 − D(G(z))), člen hodnoty hry V;
  2. nesaturující ztráta generátoru ℓns(s) = −log σ(s) = −log D(G(z)).

Generátor minimalizuje střední hodnotu zvolené ztráty přes z ~ pz. Obě ztráty jsou klesající funkce D, mají tedy stejný cíl (zvýšit D na padělcích), ale jiný gradient: s D = σ(s) je

∂ℓmm/∂s = −D,   ∂ℓns/∂s = −(1 − D).

Nesaturující ztráta tak dává silný gradient právě u padělků, které diskriminátor odhalil (D ≈ 0). Navrhli ji už Goodfellow a kol. ve stejném článku.

Laicky řečeno

Na začátku jsou padělky špatné a detektiv je snadno prozradí, D je u nich blízko nuly. Původní ztráta v tu chvíli skoro neposílá žádný signál — padělatel se nedozví, co zlepšit, právě když to potřebuje nejvíc. Obrácená otázka („jak detektiva přesvědčit“) dává silný signál hned od začátku.

∂/∂s log(1 − σ(s)) = −D,    ∂/∂s (−log σ(s)) = −(1 − D)

s
logit — výstup diskriminátoru před sigmoidou; derivujeme podle něj, protože odtud gradient teče zpět do diskriminátoru a přes něj do padělku
D = σ(s)
pravděpodobnost, že padělek je pravý; používá se σ′(s) = σ(s)(1 − σ(s)), proto vyjdou tak jednoduché výrazy
log(1 − σ(s))
původní ztráta generátoru (minimalizuje se) — její gradient má velikost D, takže když diskriminátor padělek bezpečně odhalí (D ≈ 0), je skoro nulový: saturace
−log σ(s)
nesaturující ztráta — gradient má velikost 1 − D, tedy největší právě u padělků, které diskriminátor odhalil
Při D = 0,01 dá původní ztráta gradient −0,01, nesaturující −(1 − 0,01) = −0,99 — devadesátdevětkrát víc. Obě ztráty klesají, když D roste, takže mají stejný cíl. Barvy odpovídají křivkám v grafu níže.
00,51 00,250,50,751 začátek učení D(G(z)) — pravděpodobnost, že padělek je pravý (0–1) gradient |∂ztráta/∂s| (0–1)
Síla signálu pro generátor podle toho, jak moc diskriminátor věří padělku původní log(1 − D) nesaturující −log D

Upřímně: v našich malých pokusech se učila i původní ztráta, protože diskriminátor nebyl na začátku tak sebejistý. U velkých sítí na obrázcích, kde diskriminátor vyhraje rychle, je rozdíl zásadní. Dál používáme nesaturující ztrátu.

Jak se gradient dostane až ke generátoru, ukazuje řetízkové pravidlo. Padělek x = G(z) je pro diskriminátor jen vstup, takže zpětné šíření v něm nemusí skončit:

∂LG/∂θG = ∂LG/∂s · ∂s/∂x · ∂x/∂θG

∂LG/∂s
jedno číslo ze ztráty, u nesaturující −(1 − D) — „jak moc“ se má padělek zlepšit
∂s/∂x
gradient diskriminátoru podle jeho vstupu (u kružnice 2 čísla, u číslice 64) — „kterým směrem“ posunout každou souřadnici, aby padělek vypadal pravěji; váhy diskriminátoru se v tomto kroku nemění
∂x/∂θG
obyčejné zpětné šíření generátorem — převede požadovaný posun padělku na změnu vah θG generátoru
Generátor nikdy nevidí data; jediná informace o nich přichází prostředním členem.
Definice — ztráta diskriminátoru a softplus

Nechť σ(s) = 1/1 + e−s je sigmoida, diskriminátor vrací logit s(x) ∈ ℝ a D(x) = σ(s(x)). Funkce softplus je softplus : ℝ → (0, ∞),

softplus(u) = ln(1 + eu).

Nechť xr je pravý vzorek s logitem sr = s(xr) a xf = G(z) padělek s logitem sf = s(xf). Ztráta diskriminátoru na této dvojici je binární křížová entropie s cíli 1 (pravý) a 0 (padělek):

LD = −log σ(sr) − log(1 − σ(sf)) = softplus(−sr) + softplus(sf).

Druhá rovnost plyne z −log σ(s) = ln(1 + e−s) = softplus(−s) a z 1 − σ(s) = σ(−s). Minimalizovat LD je totéž jako maximalizovat V. Program počítá softplus přes logit, ne přes D: pro s = 40 je σ(s) v plovoucí čárce přesně 1 a log(1 − D) by vyšel −∞, kdežto softplus(40) ≈ 40. Gradienty: ∂LD/∂sr = σ(sr) − 1,   ∂LD/∂sf = σ(sf).

for t in range(kroku):
    # 1. krok diskriminátoru: pravé → 1, padělky → 0
    gD = 0
    for _ in range(davka):
        x = nahodny_vzorek(data)
        gD += D.zpet(D(x), dL_ds=sigmoid(D(x)) - 1)
        f = G(sum())                           # padělek, G se teď neučí
        gD += D.zpet(D(f), dL_ds=sigmoid(D(f)))
    adam_D(gD / davka)
    # 2. krok generátoru: gradient projde D až do padělku
    gG = 0
    for _ in range(davka):
        x = G(sum())
        dL_ds = sigmoid(D(x)) - 1              # nesaturující −log σ(s)
        dL_dx = D.zpet_do_vstupu(dL_ds)        # váhy D beze změny
        gG += G.zpet(dL_dx)
    adam_G(gG / davka)                         # Adam s β₁ = 0,5 jako u DCGAN

3. Osm shluků na kružnici

Klasický pokus: data jsou body z osmi malých normálních shluků (σ = 0,05) rozmístěných na kružnici o poloměru 2. Generátor dostává dvourozměrný šum a vrací bod v rovině. Měříme kvalitu (podíl vzorků do 3σ od některého středu) a pokrytí (do kolika shluků padne aspoň 2 % vzorků).

Definice — data, kvalita a pokrytí

Nechť r = 2 je poloměr kružnice a σ = 0,05 šířka shluků. Středy shluků jsou body c0, …, c7 ∈ ℝ2,

cj = (r cos 2πj/8, r sin 2πj/8),   j = 0, …, 7.

Datový bod je x = cJ + ε, kde J je rovnoměrně náhodné z {0, …, 7} a ε ~ N(0, σ²I) je na J nezávislý šum (I je jednotková matice 2 × 2).

Nechť x1, …, xn ∈ ℝ2 jsou vzorky generátoru, pro konečnou množinu M značí #M počet jejích prvků a pro j = 0, …, 7 je nj = #{i ∈ {1, …, n} : ‖xi − cj‖ < 3σ} počet vzorků do 3σ od středu cj. Pak

  1. kvalita je podíl vzorků blízko některého středu, kvalita = 1/n · #{i ∈ {1, …, n} : minj ‖xi − cj‖ < 3σ};
  2. pokrytí je počet shluků, do kterých padne aspoň 2 % vzorků, pokrytí = #{j ∈ {0, …, 7} : nj ≥ 0,02 · n}.

Čísla: 3σ = 0,15, sousední středy jsou od sebe 2r sin π/8 ≈ 1,53, tedy přes desetkrát dál, takže žádný vzorek se nezapočítá ke dvěma středům. Snímky mají n = 400 vzorků, takže shluk se počítá jako pokrytý od 8 vzorků.

Ani dokonalý generátor nemá kvalitu 100 %: vzdálenost bodu od středu dvourozměrného normálního rozdělení N(0, σ²I) má Rayleighovo rozdělení, P(‖ε‖ < t) = 1 − exp(−t²/2σ²), a do 3σ tedy padne podíl 1 − exp(−9/2) ≈ 0,989, asi 98,9 %.

skutečná data krok 500 krok 2 000 krok 8 000 souřadnice x₁ (bez jednotky) x₂ (bez jednotky)
Skutečná data a vzorky generátoru v průběhu učení (běh se semínkem 2)

Po 500 krocích generátor vyrábí rozmazaný oblak (kvalita 6 %), po 2 000 krocích se body stahují do 6 shluků a na konci (krok 8 000) pokrývá všech 8 s kvalitou 73 %. Generátor nikdy neviděl jediný skutečný bod — všechno se dozvěděl z gradientu diskriminátoru.

4. Zhroucení módů

Definice — zhroucení módů (mode collapse)

Nechť pdata je rozdělení dat a M1, …, MK ⊆ 𝒳 jsou navzájem disjunktní oblasti, mezi které se data rozpadají na oddělené skupiny, tzv. módy (shluky, druhy obrázků), každá s pravděpodobností Pdata(Mm) > 0. Nechť PG(Mm) = P(G(z) ∈ Mm), z ~ pz, je pravděpodobnost, že generátor vyrobí vzorek z módu m. Generátor trpí zhroucením módů, právě když pro některý mód m je PG(Mm) mnohem menší než Pdata(Mm), v krajním případě nulová — vyrábí jen část rozdělení dat a ostatní módy vynechá. (Hranice „mnohem menší“ není pevně daná; v pokusu s kružnicí níže bereme mód za vynechaný, když do něj padne méně než 2 % vzorků.) Při úplném zhroucení vyrábí generátor pro každé z skoro totéž, tj. pG je soustředěno v malém okolí jediného bodu.

Ztráta to přímo netrestá: diskriminátor posuzuje každý vzorek zvlášť, a dobrý padělek jednoho druhu je pro něj stejně přesvědčivý jako pestrá sbírka.

Laicky řečeno

Padělatel zjistí, že detektiv nejhůř poznává falešné stovky. Tiskne tedy jen stovky. Detektiv si časem všimne a začne stovky podezírat — padělatel přeskočí na dvoustovky. Hra se točí v kruhu a padělatel nikdy nevyrábí všechny bankovky naráz.

Věta — proti pevnému diskriminátoru je nejlepší jediný bod

Nechť D : 𝒳 → (0, 1) je pevný diskriminátor, který nabývá maxima v bodě x* ∈ 𝒳, tj. D(x) ≤ D(x*) pro všechna x ∈ 𝒳. Pak pro každý generátor G : ℝk → 𝒳 platí pro nesaturující ztrátu

LG(G) = Ez ~ pz[−log D(G(z))] ≥ −log D(x*),

a rovnost nastane pro konstantní generátor G(z) = x* pro všechna z ∈ ℝk.

Důkaz. Pro každé z je D(G(z)) ≤ D(x*), a protože −log je klesající, je −log D(G(z)) ≥ −log D(x*); střední hodnota nerovnost zachová. Pro konstantní generátor je −log D(G(z)) = −log D(x*) pro každé z. ∎

Ztráta je průměr přes jednotlivé vzorky a nic v ní neodměňuje rozmanitost. Proti pevnému soupeři je tedy úplné zhroucení optimální; brání mu jen to, že diskriminátor reaguje a místo x* začne podezírat. Pokud generátor přeskočí rychleji, než diskriminátor zapomene, točí se hra v kruhu. Proto pomáhají úpravy, které dávají diskriminátoru pohled na celou dávku (minibatch discrimination, Tim Salimans a kol., 2016), nebo jiná vzdálenost rozdělení (Wasserstein, níže).

Stejná síť, stejná data, stejné nastavení — jen jiné náhodné semínko:

semínkopokrytých shluků po krocích 1 000 … 8 000na koncikvalita na konci
10 · 2 · 7 · 6 · 6 · 7 · 7 · 77 z 866 %
24 · 5 · 8 · 8 · 8 · 8 · 8 · 88 z 873 %
31 · 4 · 4 · 4 · 5 · 5 · 5 · 55 z 854 %
40 · 5 · 6 · 6 · 6 · 6 · 6 · 66 z 849 %
semínko 1: 7 z 8 semínko 3: 5 z 8 semínko 4: 6 z 8 souřadnice x₁ (bez jednotky) x₂ (bez jednotky)
Konec učení u ostatních běhů (plný kroužek = pokrytý shluk)

Jen jeden ze čtyř běhů pokryl všech osm shluků. Běh se semínkem 3 skončil u 5 a od kroku 5 000 se už nepohnul. Tohle je u GAN typické: učení nemá jednu ztrátu, která by klesala, ale hru dvou hráčů, a výsledek závisí na náhodě víc, než bychom chtěli.

5. Číslice: ostřejší, ale ne všechny

Teď stejné číslice 8 × 8 jako u VAE. Generátor: osmirozměrný šum → 64 → 64 → 64 pixelů se sigmoidou; diskriminátor zrcadlově. 6 000 kroků, dva běhy s různým semínkem. Kvalitu měříme stejně jako v minulém dílu — vzdáleností vzorku k nejbližší trénovací číslici.

GAN, semínko 1 GAN, semínko 2 VAE (minulý díl)
Prvních deset vzorků (kód / šum s 8 rozměry)

Vzorky GAN jsou ostřejší: vzdálenost 0,049 a 0,042 proti 0,054 u VAE (skutečné číslice 0,017). GAN netrestá rozmazanost průměrováním jako rekonstrukční ztráta VAE — rozmazaný obrázek diskriminátor snadno pozná. Jenže kterých číslic generátor vyrábí kolik?

020406080 0 1 2 3 4 5 6 7 8 9 cifra (0–9) počet vzorků (z 200)
Kolikrát která cifra mezi 200 vzorky (podle nejbližší trénovací číslice) semínko 1semínko 2 rovnoměrně (20)

V datech je každé cifry stejně. Běh se semínkem 2 přitom vyrábí hlavně šestky (69 z 200), osmičky a trojky, a cifry 0, 1, 2, 4, 7 skoro vůbec (nejvýš 3 vzorky). Běh se semínkem 1 je pestřejší, ale i tam mají cifry 0, 4, 9 méně než polovinu svého podílu (nejvýš 6 vzorků místo 20). Je to totéž zhroucení módů jako u kružnice, jen na obrázcích: GAN vyhrává ostrostí, VAE pokrytím.

6. Od GAN k difúzi

  • DCGAN (Alec Radford a kol., 2015) ukázal, jak stavět konvoluční GAN, které se dají spolehlivě učit na fotkách.
  • Wasserstein GAN (Martin Arjovsky a kol., 2017) nahradil klasifikátor „kritikem“, který měří vzdálenost rozdělení; učení je stabilnější a méně náchylné ke zhroucení módů.
  • StyleGAN (Tero Karras a kol., Nvidia, 2018–2020) generuje fotorealistické tváře v rozlišení 1024 × 1024 — známý web „this person does not exist“.
  • Kolem roku 2021 GAN předstihly difúzní modely (Prafulla Dhariwal a Alex Nichol: „Diffusion Models Beat GANs on Image Synthesis“). Jsou pomalejší, ale učí se stabilně a pokrývají celé rozdělení. Myšlenka diskriminátoru ale žije dál — jako pomocná ztráta, která obrázkům dodá ostrost, třeba v kodérech obrazu nebo zvuku.

Proč Wasserstein pomáhá, je vidět na nejjednodušším příkladu (zjednodušená verze příkladu z článku Arjovsky a kol., 2017): data jsou jediný bod 0, generátor vyrábí jediný bod θ. Dokud θ ≠ 0, rozdělení se nepřekrývají a JSD = ln 2 ≈ 0,693 bez ohledu na to, jak daleko θ je — gradient podle θ je nulový a generátor neví, kam jít. Wassersteinova vzdálenost je |θ|, takže ukazuje směr i z velké dálky.

W(pdata, pG) = sup‖f‖L ≤ 1 ( Ex ~ pdata[f(x)] − Ez ~ pz[f(G(z))] )

sup‖f‖L ≤ 1
supremum přes kritiky f : 𝒳 → ℝ — síť, která místo pravděpodobnosti vrací libovolné číslo; podmínka „1-lipschitzovská“ (|f(a) − f(b)| ≤ ‖a − b‖) mu nedovolí rozlišit dva blízké body libovolně ostře, jinak by rozdíl mohl růst do nekonečna
Ex ~ pdata[f(x)]
průměrné hodnocení skutečných dat — kritik ho chce co největší
Ez[f(G(z))]
průměrné hodnocení padělků — kritik ho chce co nejmenší, generátor co největší; rozdíl je spojitý v parametrech generátoru, takže gradient nezmizí, ani když se rozdělení nepřekrývají
Kantorovičova–Rubinsteinova dualita: nejmenší „práce“ potřebná k přesunutí hmoty jednoho rozdělení na druhé je rovna největšímu rozdílu průměrů přes 1-lipschitzovské funkce. V příkladu výše stačí f(x) = −x · sgn θ: f(0) = 0 − f(θ) = −|θ|, rozdíl je 0 − (−|θ|) = |θ|.

7. Shrnutí

  • GAN = generátor a diskriminátor ve hře; generátor se učí jen z gradientu, který mu pošle diskriminátor.
  • Nesaturující ztráta −log D(G(z)) dává generátoru silný signál i na začátku, kdy diskriminátor vyhrává.
  • Na osmi shlucích pokryl všechny jen jeden ze čtyř běhů (7, 8, 5, 6); výsledek hodně závisí na náhodě.
  • Na číslicích jsou vzorky ostřejší než u VAE (0,042 proti 0,054), ale některé cifry chybějí — zhroucení módů.
  • Dnes obrázky generují hlavně difúzní modely; diskriminátor zůstal jako pomocník pro ostrost.

Chcete si to osahat? Nechte AI agenta naučit malý GAN na osmi shlucích na kružnici a pustit ho pětkrát s různým semínkem. Pak ať zkusí Wasserstein GAN se stejnou sítí a porovná, kolik shluků pokaždé pokryje.

Máte na to jiný názor? Napište na support@coden-app.com.

Agent na vašem počítači, ovládaný z telefonu