Reti generative avversarie (GAN): il falsario contro il detective
La partita tra generatore e discriminatore, un GAN scritto da zero, la perdita non saturante, otto cluster su una circonferenza e il collasso dei modi, cifre più nitide che con il VAE, ma non tutte, e il percorso dai GAN ai modelli di diffusione.
Serie Basi di IA Parte 45 di 52
- Mappa dell’intelligenza artificiale: che cos’è ciascuna cosa e come si incastra tutto
- Breve storia dell’intelligenza artificiale: da Turing ai modelli linguistici
- Dati, modello, addestramento, inferenza: i concetti di base su un unico esempio
- Come leggere la notazione matematica: simboli, indici, sommatorie e quantificatori
- Insiemi e relazioni: i mattoncini con cui si costruiscono le definizioni nell’IA
- Funzioni e applicazioni: perché ogni modello di IA è una funzione
- Logica e dimostrazioni: le regole con cui si ragiona nell’IA
- Grafi e alberi: la struttura su cui poggiano la ricerca e le reti neurali
- Algebra lineare per l’apprendimento automatico: vettori, matrici e perché l’IA soprattutto moltiplica
- Derivate, gradiente e regola della catena: come un modello capisce in quale direzione imparare
- Discesa del gradiente: come impara un modello
- Che cos’è la probabilità: dal lancio di un dado agli assiomi di Kolmogorov
- Probabilità condizionata e teorema di Bayes: come cambiare una stima quando scopri qualcosa di nuovo
- Variabile aleatoria e funzione di ripartizione: una sola funzione che dice tutto sulla distribuzione
- Funzione di densità e funzione di massa: perché una variabile continua ha probabilità zero in un punto
- Valore atteso, varianza e covarianza: dove si trova una distribuzione, quanto è larga e che cosa è legato a che cosa
- Panoramica delle distribuzioni di probabilità: Bernoulli, binomiale, Poisson, uniforme, normale ed esponenziale
- Legge dei grandi numeri e teorema del limite centrale: perché le medie si comportano in modo così prevedibile
- Statistica e stima dei parametri: massima verosimiglianza, MAP e intervalli di confidenza
- Teoria dell’informazione: entropia, entropia incrociata e divergenza KL — da dove vengono le funzioni di perdita
- Ricerca nello spazio degli stati: BFS, DFS, UCS e A* con animazioni
- Giochi e avversari: minimax, potatura alfa-beta e Monte Carlo tree search
- Soddisfacimento di vincoli: backtracking, propagazione dei vincoli e AC-3 su un sudoku e una mappa delle regioni ceche
- Logica e sistemi basati sulla conoscenza: concatenazione in avanti e all’indietro, risoluzione e sistemi esperti
- Pianificazione: STRIPS, il mondo dei blocchi, euristiche dal rilassamento e pianificazione negli agenti IA
- Ricerca locale e ricottura simulata: un commesso viaggiatore tra i capoluoghi di regione cechi
- Algoritmi genetici: popolazione, incrocio, mutazione e selezione su uno zaino per l’escursione
- Strategie evolutive e programmazione genetica: dalla regola di un quinto alla legge di Keplero
- Ottimizzazione con colonie di formiche: come una traccia di feromone trova un percorso breve
- Ottimizzazione a sciame di particelle: inerzia, esperienza propria ed esperienza dello sciame
- Neuroevoluzione: evoluzione dei pesi e della forma delle reti neurali e l’algoritmo NEAT
- Insiemi fuzzy e funzioni di appartenenza: come scrivere «un po’ caldo»
- Logica fuzzy e probabilità: perché «un po’ caldo» non significa «probabilmente caldo»
- Logica fuzzy: t-norme, implicazioni e regole SE–ALLORA
- Controllo fuzzy: Mamdani e Sugeno, dal ventilatore al pendolo inverso su un carrello
- Clustering fuzzy: l’algoritmo fuzzy c-means e i punti tra i cluster
- Sistemi neuro-fuzzy (ANFIS): regole fuzzy che imparano dai dati
- Catene di Markov: matrice di transizione, distribuzione stazionaria e PageRank
- Modelli di Markov nascosti: l’algoritmo di Viterbi e il casinò disonesto
- Reti bayesiane: perché l’erba è bagnata e che cosa significa per l’irrigatore
- Filtro di Kalman: come stimare da misure imprecise dove si trova un’auto e a che velocità va
- Tipi di apprendimento automatico: supervisionato, non supervisionato, semi-supervisionato e altri
- Prompt, contesto e RAG: come dare a un modello le informazioni giuste
- Autoencoder variazionali (VAE): immagini nuove da uno spazio latente continuo
- Reti generative avversarie (GAN): il falsario contro il detective
- Modelli di diffusione: come il rumore puro diventa un’immagine
- Processi decisionali di Markov: stati, azioni, ricompense ed equazioni di Bellman
- Q-learning e DQN: imparare il valore delle azioni, dalla tabella alla rete neurale
- Policy gradient e PPO: imparare direttamente la politica
- Come funziona un agente IA: un modello linguistico in un ciclo con strumenti
- Programmare con agenti IA: incarico, test e controllo
- Valutazione e sicurezza dei sistemi di IA: come misurare e come sorvegliare
Programma completo della serie 52 di 83 argomenti pubblicati
- Come il generatore impara solo dal gradiente del discriminatore.
- Perché l’apprendimento di un GAN è instabile e che cos’è il collasso dei modi.
- In che cosa i GAN battono i VAE, in che cosa perdono e perché oggi li ha sostituiti la diffusione.
Utile sapere prima: Autoencoder variazionali (VAE): immagini nuove da uno spazio latente continuo, Giochi e avversari: minimax, potatura alfa-beta e Monte Carlo tree search
L’autoencoder variazionale della parte precedente genera onestamente, ma in modo sfocato. Nel 2014 Ian Goodfellow ebbe un’idea che sembra quasi un trucco: invece di misurare quanto un campione si discosta dai dati, lasciamo che a giudicarlo sia un’altra rete. Due reti giocano una partita — una falsifica, l’altra smaschera il falso — e intanto migliorano entrambe. Così sono nati i primi volti generati da una macchina che non distingui da una foto. In questa parte scriveremo le due reti da zero e vedremo perché il loro apprendimento è così capriccioso.
Segue le parti Autoencoder variazionali, Regressione logistica (sigmoide ed entropia incrociata) e Giochi e avversari.
1. Il falsario e il detective
Definizione — rete generativa avversaria (GAN)
Un GAN (Ian Goodfellow e coll., 2014) è formato da due reti. Il generatore G trasforma un rumore casuale z ~ N(0, I) in un campione G(z). Il discriminatore D restituisce la probabilità D(x) che x provenga dai dati reali. Giocano una partita a due giocatori a somma zero:
minG maxD Ex ~ data[log D(x)] + Ez[log(1 − D(G(z)))].
Per G fissato, il discriminatore migliore è D*(x) = pdata(x) / (pdata(x) + pG(x)). All’equilibrio G genera esattamente la distribuzione dei dati e D restituisce ovunque ½.
Il falsario stampa banconote, il detective le divide in vere e false. Il detective impara da dove ha sbagliato. Il falsario non ha mai visto una banconota vera — impara solo da ciò che ha tradito il falso agli occhi del detective. Se migliorano entrambi, i falsi sono sempre più riusciti. Fine della partita: il detective può solo tirare a indovinare, e indovina una volta su due.
minG maxD Ex ~ data[ log D(x) ] + Ez ~ N(0, I)[ log(1 − D(G(z))) ]
- Ex ~ data[log D(x)]
- il discriminatore sui dati reali — è massimo (0) quando D dà 1 ai campioni veri; il logaritmo punisce senza limiti un errore commesso con sicurezza (D → 0)
- Ez[log(1 − D(G(z)))]
- il discriminatore sui falsi — è massimo quando dà loro 0; è l’unico termine in cui compare G, quindi il generatore impara solo da esso
- maxD
- il discriminatore aumenta il valore — i due termini insieme sono l’entropia incrociata binaria cambiata di segno, quindi è il normale addestramento di un classificatore «vero / falso»
- minG
- il generatore diminuisce il valore — vuole che il discriminatore sbagli sui falsi; ciò che un giocatore guadagna, l’altro lo perde (somma zero)
Teorema — il discriminatore migliore e che cosa minimizza il generatore
Per G fissato il valore del gioco è ∫ [pdata(x) log D(x) + pG(x) log(1 − D(x))] dx. In ogni punto x massimizziamo la funzione a log y + b log(1 − y) per y ∈ (0, 1), dove a = pdata(x), b = pG(x).
Dimostrazione. La derivata a/y − b/(1 − y) si annulla per y = a/(a + b) e la funzione è concava (derivata seconda −a/y² − b/(1 − y)² < 0), quindi si tratta di un massimo. Da qui D*(x) = pdata(x) / (pdata(x) + pG(x)). Sostituendo e semplificando (Goodfellow e coll., 2014):
V(D*, G) = −log 4 + 2 · JSD(pdata ‖ pG), JSD(p ‖ q) = ½ KL(p ‖ m) + ½ KL(q ‖ m), m = ½(p + q).
La divergenza di Jensen–Shannon è non negativa e nulla esattamente per pG = pdata. Con il discriminatore migliore il generatore minimizza quindi la JSD, e il minimo −log 4 ≈ −1,386 si raggiunge quando genera esattamente i dati. ∎
Esempio: dove la densità dei dati è 0,3 e quella dei falsi 0,1, si ha D* = 0,3 / 0,4 = 0,75 (il punto è piuttosto vero); dove il generatore esagera (dati 0,1, falsi 0,3), D* = 0,25. Dove le densità sono uguali, D* = ½ e la perdita del discriminatore (entropia incrociata binaria per campione) vale ln 2 ≈ 0,693.
Il discriminatore è un normale classificatore con sigmoide ed entropia incrociata, come la regressione logistica, solo con qualche strato in più. La magia sta nel generatore: il gradiente della sua perdita scorre con la retropropagazione attraverso il discriminatore fino all’immagine e da lì nei pesi del generatore. Il discriminatore gli dice così in quale direzione spostare ogni pixel per sembrare più credibile.
2. Apprendimento: passi alternati
Si impara a turno: un passo del discriminatore (un batch di dati reali e un batch di falsi, aumentare D su quelli veri, diminuirlo su quelli falsi), poi un passo del generatore (spostare i falsi dove D li ritiene veri). Da noi entrambe le reti hanno due strati nascosti con leaky ReLU e imparano con Adam.
Definizione — perdita non saturante del generatore
Invece di minimizzare log(1 − D(G(z))) del gioco originale, il generatore impara a massimizzare log D(G(z)), cioè a minimizzare −log D(G(z)). Le due perdite hanno lo stesso obiettivo, ma un gradiente diverso: se D = σ(s), allora |∂ log(1 − D)/∂s| = D, mentre |∂(−log D)/∂s| = 1 − D. L’hanno proposta già Goodfellow e coll. nello stesso articolo.
All’inizio i falsi sono pessimi e il detective li smaschera facilmente, per loro D è vicino a zero. La perdita originale in quel momento non manda quasi nessun segnale — il falsario non scopre che cosa migliorare proprio quando ne ha più bisogno. La domanda rovesciata («come convincere il detective») dà un segnale forte fin dall’inizio.
∂/∂s log(1 − σ(s)) = −D, ∂/∂s (−log σ(s)) = −(1 − D)
- s
- logit — l’uscita del discriminatore prima della sigmoide; deriviamo rispetto a esso perché da lì il gradiente torna indietro nel discriminatore e, attraverso di esso, nel falso
- D = σ(s)
- probabilità che il falso sia vero; si usa σ′(s) = σ(s)(1 − σ(s)), per questo escono espressioni così semplici
- log(1 − σ(s))
- la perdita originale del generatore (si minimizza) — il suo gradiente ha modulo D, quindi quando il discriminatore smaschera il falso con sicurezza (D ≈ 0) è quasi nullo: saturazione
- −log σ(s)
- la perdita non saturante — il gradiente ha modulo 1 − D, quindi è massimo proprio per i falsi che il discriminatore ha smascherato
A essere sinceri: nei nostri piccoli esperimenti imparava anche la perdita originale, perché all’inizio il discriminatore non era così sicuro di sé. Nelle grandi reti sulle immagini, dove il discriminatore vince in fretta, la differenza è fondamentale. Da qui in poi usiamo la perdita non saturante.
Come il gradiente arrivi fino al generatore lo mostra la regola della catena. Il falso x = G(z) per il discriminatore è solo un input, quindi la retropropagazione non deve fermarsi lì:
∂LG / ∂θG = ∂LG / ∂s · ∂s / ∂x · ∂x / ∂θG
- ∂LG / ∂s
- un solo numero dalla perdita, per quella non saturante −(1 − D) — «di quanto» deve migliorare il falso
- ∂s / ∂x
- il gradiente del discriminatore rispetto al suo input (2 numeri per la circonferenza, 64 per una cifra) — «in quale direzione» spostare ogni coordinata perché il falso sembri più vero; i pesi del discriminatore in questo passo non cambiano
- ∂x / ∂θG
- la normale retropropagazione attraverso il generatore — traduce lo spostamento desiderato del falso in una modifica dei pesi del generatore
Definizione — perdita del discriminatore e softplus
Il discriminatore restituisce un logit s e D = σ(s). Per un campione vero con logit sr e un falso con logit sf la sua perdita è l’entropia incrociata binaria
LD = −log σ(sr) − log(1 − σ(sf)) = softplus(−sr) + softplus(sf), softplus(u) = ln(1 + eu),
perché −log σ(s) = ln(1 + e−s) e 1 − σ(s) = σ(−s). Il programma calcola softplus a partire dal logit, non da D: per s = 40, σ(s) in virgola mobile vale esattamente 1 e log(1 − D) darebbe −∞, mentre softplus(40) ≈ 40. Gradienti: ∂LD/∂sr = σ(sr) − 1, ∂LD/∂sf = σ(sf).
for t in range(kroku):
# 1. passo del discriminatore: veri → 1, falsi → 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()) # falso, G qui non impara
gD += D.zpet(D(f), dL_ds=sigmoid(D(f)))
adam_D(gD / davka)
# 2. passo del generatore: il gradiente attraversa D fino al falso
gG = 0
for _ in range(davka):
x = G(sum())
dL_ds = sigmoid(D(x)) - 1 # non saturante −log σ(s)
dL_dx = D.zpet_do_vstupu(dL_ds) # pesi di D invariati
gG += G.zpet(dL_dx)
adam_G(gG / davka) # Adam con β₁ = 0,5 come in DCGAN
3. Otto cluster su una circonferenza
Un esperimento classico: i dati sono punti di otto piccoli cluster normali (σ = 0,05) disposti su una circonferenza di raggio 2. Il generatore riceve un rumore bidimensionale e restituisce un punto del piano. Misuriamo la qualità (la quota di campioni entro 3σ da uno dei centri) e la copertura (in quanti cluster cade almeno il 2 % dei campioni).
Definizione — dati, qualità e copertura
I centri dei cluster sono cj = (r cos(2πj/8), r sin(2πj/8)) per j = 0, …, 7 con r = 2; un punto dei dati è cj con j casuale più un rumore N(0, σ²I), σ = 0,05. Per i campioni x1, …, xn del generatore:
qualità = (1/n) · #{i : minj ‖xi − cj‖ < 3σ}, copertura = #{j : nj ≥ 0,02 · n},
dove nj è il numero di campioni entro 3σ dal centro cj. In numeri: 3σ = 0,15, centri vicini distano 2r sin(π/8) ≈ 1,53, cioè più di dieci volte tanto. Le istantanee hanno n = 400 campioni, quindi un cluster conta come coperto da 8 campioni in su.
Nemmeno un generatore perfetto ha qualità 100 %: la distanza di un punto dal centro di una distribuzione normale bidimensionale segue la distribuzione di Rayleigh, ed entro 3σ cade la quota 1 − e−9/2 ≈ 0,989, cioè circa il 98,9 %.
Dopo 500 passi il generatore produce una nuvola sfocata (qualità 6 %), dopo 2 000 passi i punti si raccolgono in 6 cluster e alla fine (passo 8 000) li copre tutti e 8 con qualità 73 %. Il generatore non ha mai visto un solo punto reale — ha imparato tutto dal gradiente del discriminatore.
4. Collasso dei modi
Definizione — collasso dei modi (mode collapse)
Il generatore produce solo una parte della distribuzione dei dati — alcuni modi (cluster, tipi di immagini) — e tralascia gli altri. La perdita non lo punisce direttamente: il discriminatore giudica ogni campione separatamente, e un buon falso di un solo tipo per lui è convincente quanto una collezione varia. In caso di collasso completo il generatore produce quasi la stessa cosa per ogni z.
Il falsario scopre che il detective riconosce peggio di tutte le false banconote da cento. Allora stampa solo banconote da cento. Col tempo il detective se ne accorge e comincia a sospettare di quelle da cento — il falsario passa a quelle da duecento. Il gioco gira in tondo e il falsario non produce mai tutte le banconote insieme.
Teorema — contro un discriminatore fissato il migliore è un solo punto
Per D fissato la perdita del generatore è LG = Ez[−log D(G(z))] ≥ −log D(x*), dove x* è il punto in cui D è massimo. L’uguaglianza vale per un generatore che manda ogni z in x*.
Dimostrazione. Per ogni z vale D(G(z)) ≤ D(x*), e poiché −log è decrescente, −log D(G(z)) ≥ −log D(x*); il valore atteso conserva la disuguaglianza. ∎
La perdita è una media sui singoli campioni e niente in essa premia la varietà. Contro un avversario fissato il collasso completo è quindi ottimale; lo impedisce solo il fatto che il discriminatore reagisce e comincia a sospettare di x*. Se il generatore salta più in fretta di quanto il discriminatore dimentichi, il gioco gira in tondo. Per questo aiutano le modifiche che danno al discriminatore una visione dell’intero batch (minibatch discrimination, Tim Salimans e coll., 2016) o un’altra distanza tra distribuzioni (Wasserstein, più sotto).
Stessa rete, stessi dati, stesse impostazioni — cambia solo il seed casuale:
| seed | cluster coperti dopo i passi 1 000 … 8 000 | alla fine | qualità alla fine |
|---|---|---|---|
| 1 | 0 · 2 · 7 · 6 · 6 · 7 · 7 · 7 | 7 su 8 | 66 % |
| 2 | 4 · 5 · 8 · 8 · 8 · 8 · 8 · 8 | 8 su 8 | 73 % |
| 3 | 1 · 4 · 4 · 4 · 5 · 5 · 5 · 5 | 5 su 8 | 54 % |
| 4 | 0 · 5 · 6 · 6 · 6 · 6 · 6 · 6 | 6 su 8 | 49 % |
Solo una delle quattro esecuzioni ha coperto tutti e otto i cluster. L’esecuzione con seed 3 si è fermata a 5 e dal passo 5 000 non si è più mossa. È tipico dei GAN: l’apprendimento non ha un’unica perdita che scende, ma una partita a due giocatori, e il risultato dipende dal caso più di quanto vorremmo.
5. Cifre: più nitide, ma non tutte
Ora le stesse cifre 8 × 8 del VAE. Generatore: rumore a otto dimensioni → 64 → 64 → 64 pixel con sigmoide; discriminatore speculare. 6 000 passi, due esecuzioni con seed diversi. Misuriamo la qualità come nella parte precedente — con la distanza del campione dalla cifra di addestramento più vicina.
I campioni del GAN sono più nitidi: distanza 0,049 e 0,042 contro 0,054 del VAE (cifre reali 0,017). Il GAN non punisce la sfocatura con la media come la perdita di ricostruzione del VAE — un’immagine sfocata il discriminatore la riconosce facilmente. Ma quante di ciascuna cifra produce il generatore?
Nei dati ogni cifra compare lo stesso numero di volte. L’esecuzione con seed 2 produce invece soprattutto sei (69 su 200), otto e tre, e le cifre 0, 1, 2, 4, 7 quasi per niente (al massimo 3 campioni). L’esecuzione con seed 1 è più varia, ma anche lì le cifre 0, 4, 9 hanno meno della metà della loro quota (al massimo 6 campioni invece di 20). È lo stesso collasso dei modi della circonferenza, solo sulle immagini: il GAN vince in nitidezza, il VAE in copertura.
6. Dai GAN alla diffusione
- DCGAN (Alec Radford e coll., 2015) ha mostrato come costruire GAN convoluzionali che si possono addestrare in modo affidabile sulle foto.
- Wasserstein GAN (Martin Arjovsky e coll., 2017) ha sostituito il classificatore con un «critico» che misura la distanza tra distribuzioni; l’apprendimento è più stabile e meno soggetto al collasso dei modi.
- StyleGAN (Tero Karras e coll., Nvidia, 2018–2020) genera volti fotorealistici in risoluzione 1024 × 1024 — il noto sito «this person does not exist».
- Intorno al 2021 i GAN sono stati superati dai modelli di diffusione (Prafulla Dhariwal e Alex Nichol: «Diffusion Models Beat GANs on Image Synthesis»). Sono più lenti, ma imparano in modo stabile e coprono tutta la distribuzione. L’idea del discriminatore però sopravvive — come perdita ausiliaria che dà nitidezza alle immagini, per esempio nei codificatori di immagini o di audio.
Perché Wasserstein aiuti si vede sull’esempio più semplice (una versione semplificata dell’esempio dell’articolo di Arjovsky e coll., 2017): i dati sono un solo punto 0, il generatore produce un solo punto θ. Finché θ ≠ 0, le distribuzioni non si sovrappongono e JSD = ln 2 ≈ 0,693 indipendentemente da quanto sia lontano θ — il gradiente rispetto a θ è nullo e il generatore non sa dove andare. La distanza di Wasserstein è |θ|, quindi indica la direzione anche da molto lontano.
W(pdata, pG) = sup‖f‖L ≤ 1 ( Ex ~ data[f(x)] − Ez[f(G(z))] )
- sup‖f‖L ≤ 1
- il critico f — una rete che invece di una probabilità restituisce un numero qualsiasi; la condizione «1-lipschitziana» (|f(a) − f(b)| ≤ ‖a − b‖) gli impedisce di distinguere due punti vicini in modo arbitrariamente netto, altrimenti la differenza potrebbe crescere all’infinito
- Edata[f(x)]
- il punteggio medio dei dati reali — il critico lo vuole il più grande possibile
- Ez[f(G(z))]
- il punteggio medio dei falsi — il critico lo vuole il più piccolo possibile, il generatore il più grande; la differenza è continua nei parametri del generatore, quindi il gradiente non sparisce nemmeno quando le distribuzioni non si sovrappongono
7. Riepilogo
- GAN = generatore e discriminatore in una partita; il generatore impara solo dal gradiente che gli manda il discriminatore.
- La perdita non saturante −log D(G(z)) dà al generatore un segnale forte anche all’inizio, quando il discriminatore vince.
- Sugli otto cluster solo una delle quattro esecuzioni li ha coperti tutti (7, 8, 5, 6); il risultato dipende molto dal caso.
- Sulle cifre i campioni sono più nitidi che con il VAE (0,042 contro 0,054), ma alcune cifre mancano — collasso dei modi.
- Oggi le immagini le generano soprattutto i modelli di diffusione; il discriminatore è rimasto come aiuto per la nitidezza.
Vuoi toccarlo con mano? Fai addestrare a un agente IA un piccolo GAN sugli otto cluster su una circonferenza e fallo girare cinque volte con seed diversi. Poi fagli provare un Wasserstein GAN con la stessa rete e confrontare quanti cluster copre ogni volta.
La vedi diversamente? Scrivi a support@coden-app.com.