Modelli di diffusione: come il rumore puro diventa un’immagine
Il processo diretto che aggiunge rumore, una rete che stima il rumore, DDPM e DDIM scritti da zero, otto cluster senza collasso dei modi, quanti passi di campionamento servono, il confronto con VAE e GAN sulle cifre e la strada verso le immagini da un testo.
Serie Basi di IA Parte 46 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 funzionano il processo diretto e quello inverso della diffusione.
- Perché la diffusione si addestra in modo più stabile di un GAN e quanto costa il numero di passi.
- Come la diffusione diventa un generatore di immagini a partire da un testo.
Utile sapere prima: Reti generative avversarie (GAN): il falsario contro il detective, Autoencoder variazionali (VAE): immagini nuove da uno spazio latente continuo
Stable Diffusion, Midjourney, DALL·E 3 e i modelli che generano video si basano tutti sulla stessa idea, ed è sorprendentemente semplice. Distruggere un’immagine è facile — basta aggiungerle gradualmente rumore finché non resta solo rumore. Se imparassimo ad annullare ogni piccolo passo, potremmo partire dal rumore puro e farne emergere un’immagine passo dopo passo. In questa parte lo programmiamo da zero e lo confrontiamo con il VAE e il GAN sugli stessi dati.
Si collega alle parti Reti generative avversarie e Autoencoder variazionali.
1. Processo diretto: l’immagine si dissolve nel rumore
Definizione — processo diretto (di diffusione)
Si sceglie un numero di passi T e un piano di piccole varianze β1, …, βT. A ogni passo si aggiunge un po’ di rumore: xt = √(1 − βt) · xt−1 + √βt · ε, ε ~ N(0, I). Componendo i passi si ottiene la forma chiusa xt = √ᾱt · x0 + √(1 − ᾱt) · ε, dove ᾱt = ∏s ≤ t (1 − βs). Per t abbastanza grande ᾱt ≈ 0 e xt è rumore puro.
Una goccia d’inchiostro in un bicchiere d’acqua: per un attimo si vede la forma della goccia, poi si diffonde e alla fine l’acqua è colorata in modo uniforme e la forma originale non si riconosce più. La formula chiusa dice che si può saltare direttamente a qualsiasi istante — non serve simulare tutti i passi.
xt = √ᾱt · x0 + √(1 − ᾱt) · ε
- xt
- l’immagine rumorosa al passo t — esattamente ciò che la rete riceve in ingresso durante l’addestramento
- √ᾱt
- quanto resta dell’immagine originale; ᾱt è il prodotto di tutti gli (1 − βs) fino al passo t, quindi diminuisce a ogni passo
- x0
- l’immagine originale presa dai dati
- √(1 − ᾱt)
- quanto rumore c’è; le radici quadrate ci sono perché a sommarsi sono le varianze: (√ᾱ)² + (√(1 − ᾱ))² = 1, così dati con varianza 1 hanno varianza 1 a ogni passo e alla fine passano gradualmente a N(0, I)
- ε
- un campione di rumore da N(0, I) — proprio ciò che la rete dovrà indovinare; il fatto che lo conosciamo trasforma l’addestramento in una normale regressione
Teorema — perché basta un solo salto
Se vale xt−1 = √ᾱt−1 x0 + √(1 − ᾱt−1) ε′ con ε′ ~ N(0, I), vale anche xt = √ᾱt x0 + √(1 − ᾱt) ε con un nuovo ε ~ N(0, I).
Dimostrazione. Sostituiamo in un passo: xt = √(1 − βt) √ᾱt−1 x0 + √(1 − βt) √(1 − ᾱt−1) ε′ + √βt ε″. Il primo termine è √ᾱt x0, perché ᾱt = (1 − βt) ᾱt−1. Gli altri due sono rumori normali indipendenti con media 0; la loro somma è di nuovo normale e le varianze si sommano: (1 − βt)(1 − ᾱt−1) + βt = 1 − (1 − βt) ᾱt−1 = 1 − ᾱt. Per t = 1 l’affermazione vale direttamente (ᾱ0 = 1), il resto segue per induzione. ∎
Esempio — il nostro piano del rumore in numeri
β cresce linearmente: βt = β1 + (βT − β1) · (t − 1)/(T − 1), cioè di 0,00101 a ogni passo.
| t | βt | ᾱt | √ᾱt (segnale) | √(1 − ᾱt) (rumore) |
|---|---|---|---|---|
| 1 | 0,00010 | 0,9999 | 1,000 | 0,010 |
| 2 | 0,00111 | 0,9988 | 0,999 | 0,035 |
| 25 | 0,02432 | 0,7351 | 0,857 | 0,515 |
| 37 | 0,03643 | 0,5045 | 0,710 | 0,704 |
| 38 | 0,03744 | 0,4856 | 0,697 | 0,717 |
| 50 | 0,04955 | 0,2830 | 0,532 | 0,847 |
| 100 | 0,10000 | 0,0056 | 0,075 | 0,997 |
Verifichiamo a mano la seconda riga: ᾱ2 = (1 − β1)(1 − β2) = 0,9999 · 0,99889 = 0,99879. Segnale e rumore si equivalgono (ᾱ = 0,5) tra i passi 37 e 38; al passo 100 l’immagine originale ha un peso di appena 0,075 contro 0,997 del rumore.
Nel nostro caso T = 100 e β cresce linearmente da 0,0001 a 0,1. La quota del segnale originale √ᾱt è 0,86 al passo 25, 0,53 al passo 50 e appena 0,07 al passo 100.
2. Processo inverso: una rete che indovina il rumore
Definizione — DDPM (denoising diffusion probabilistic model)
DDPM (Jonathan Ho, Ajay Jain e Pieter Abbeel, 2020; idea di Jascha Sohl-Dickstein e colleghi, 2015) addestra una rete εθ(xt, t) a stimare, da un’immagine rumorosa e dal numero del passo, quale rumore ε è stato aggiunto. La perdita è il normale errore quadratico medio E ‖ε − εθ(√ᾱt x0 + √(1 − ᾱt) ε, t)‖² con t casuale. Si campiona all’indietro a partire da xT ~ N(0, I): xt−1 = (xt − βt/√(1 − ᾱt) · εθ) / √(1 − βt) + √βt · z.
La rete riceve una foto sfocata e rumorosa e la domanda «quanto rumore c’è dentro e che aspetto ha?». Se sa stimarlo, sa anche toglierne un po’. Ripetiamo cento volte, ogni volta con un pizzico di casualità fresca — e dal rumore emerge un’immagine. L’addestramento è una normale regressione: nessun avversario come nel GAN, nessun compromesso come nel VAE.
L(θ) = Ex0, t, ε ‖ε − εθ(√ᾱt x0 + √(1 − ᾱt) ε, t)‖²
- ε
- il rumore che abbiamo aggiunto noi stessi all’immagine — la risposta corretta, ed è per questo che la conosciamo senza alcuna etichettatura dei dati
- εθ(…, t)
- la stima del rumore fatta dalla rete; riceve anche il numero del passo t, perché con t = 2 deve trovare poco rumore e con t = 100 xt è quasi solo rumore
- √ᾱt x0 + √(1 − ᾱt) ε
- l’immagine rumorosa xt prodotta con un solo salto — grazie alla formula chiusa basta estrarre t ed ε per ogni esempio, non si simula nulla passo dopo passo
xt−1 = 1/√(1 − βt) · (xt − βt/√(1 − ᾱt) · εθ(xt, t)) + √βt · z
- xt
- lo stato rumoroso attuale — si parte dal rumore puro xT ~ N(0, I)
- εθ(xt, t)
- la stima del rumore presente in xt
- βt/√(1 − ᾱt)
- quanta parte del rumore stimato togliere — solo la quota che corrisponde a un passo (βt), riportata al livello complessivo di rumore √(1 − ᾱt); nel nostro caso 0,01 al passo 1 e 0,10 al passo 100
- 1/√(1 − βt)
- annulla la riduzione del passo diretto (lì si moltiplicava per √(1 − βt)); al passo 100 vale 1,054
- √βt · z
- rumore fresco z ~ N(0, I) (all’ultimo passo z = 0) — il processo inverso è casuale come quello diretto; senza di esso i campioni verrebbero attirati verso immagini medie. L’ampiezza √βt è una delle due scelte provate da Ho e colleghi
# addestramento (DDPM)
ripeti 16 000×:
per ciascuno dei 64 esempi del batch:
x₀ = esempio casuale dai dati
t = a caso tra 1 … 100
ε = vettore di numeri casuali da N(0, 1)
x_t = √ᾱ_t · x₀ + √(1 − ᾱ_t) · ε
errore = ‖ε − ε_θ(x_t, codice(t))‖² / dimensione
passo di Adam sull’errore medio
# campionamento (DDPM, 100 passi)
x = vettore da N(0, 1)
per t = 100, 99, …, 1:
ε̂ = ε_θ(x, codice(t))
z = vettore da N(0, 1), zero al passo t = 1
x = (x − β_t / √(1 − ᾱ_t) · ε̂) / √(1 − β_t) + √β_t · z
restituisci x
Definizione — codifica sinusoidale del tempo
La rete non riceve direttamente il numero t, ma otto numeri codice(t) = (sin(fπt/T), cos(fπt/T)) per f = 1, 2, 4, 8. Le frequenze lente dicono «più o meno a che punto del processo siamo», quelle rapide distinguono passi vicini; tutti i numeri sono tra −1 e 1, così nessun ingresso prevale sugli altri.
Per t = 25 (un quarto del processo, angoli π/4, π/2, π e 2π): codice(25) = (0,707; 0,707; 1,000; 0,000; 0,000; −1,000; 0,000; 1,000).
La nostra rete è la normale rete multistrato della parte sui GAN: in ingresso xt e otto numeri della codifica sinusoidale del tempo t (come la codifica posizionale in un transformer), in uscita la stima del rumore. Sul cerchio ha due strati nascosti da 64 neuroni, sulle cifre da 128. Si addestra con Adam per 16 000 passi.
3. Otto cluster senza collasso
Gli stessi dati della parte precedente: otto cluster su un cerchio. Ecco come appaiono 400 campioni durante il processo inverso:
Ancora al passo 25 i punti sono sparsi in modo quasi uniforme (qualità 3 %), al passo 10 si delinea il cerchio e negli ultimi dieci passi i punti si radunano nei cluster. Alla fine sono coperti tutti gli 8 cluster e ognuno ha ricevuto da 28 a 50 dei 500 campioni. La qualità (quota entro 3σ da un centro) è 63 %.
La differenza rispetto al GAN non sta nella qualità, ma nell’affidabilità. Il GAN ha coperto tutti e otto i cluster solo in un’esecuzione su quattro; la diffusione ci è riuscita nell’unica esecuzione che abbiamo lanciato (un’esecuzione non è una prova, ma è coerente con ciò che si sa della diffusione). La perdita della diffusione infatti non è un gioco, ma una regressione, e la rete viene penalizzata per ogni campione dei dati — non può «lasciar perdere» nessun cluster.
4. Quanti passi servono
Definizione — DDIM
DDIM (Jiaming Song, Chenlin Meng e Stefano Ermon, 2020) usa la stessa rete addestrata, ma campiona in modo deterministico e a salti più grandi: dalla stima del rumore calcola una stima dell’immagine pulita x̂0 = (xt − √(1 − ᾱt) εθ) / √ᾱt e da questa direttamente xs = √ᾱs x̂0 + √(1 − ᾱs) εθ per qualsiasi tempo precedente s < t.
Invece di cento passettini ne facciamo venti più lunghi. A ogni passo la rete si chiede «come sarebbe, più o meno, l’immagine finita?» e salta di conseguenza per un tratto di strada. Se i salti sono troppo grandi, la rete sbaglia mira.
xs = √ᾱs · x̂0 + √(1 − ᾱs) · εθ(xt, t), x̂0 = (xt − √(1 − ᾱt) εθ) / √ᾱt
- xt
- lo stato in cui ci troviamo adesso
- εθ
- la stima del rumore — la stessa rete del DDPM, non si riaddestra nulla
- x̂0
- la stima dell’immagine finita: la formula chiusa del processo diretto risolta rispetto a x0; si divide per √ᾱt, che all’inizio è piccolo, quindi è qui che la stima è meno precisa
- √ᾱs
- quanta immagine deve esserci al tempo di arrivo s — lo stesso fattore del processo diretto, solo per un altro tempo
- √(1 − ᾱs)
- quanto rumore deve restare; il DDIM usa lo stesso rumore stimato e non ne estrae di nuovo — per questo è deterministico
Esempio — perché due passi non bastano (in modo semplificato)
Il DDIM con n passi percorre tempi distribuiti in modo uniforme: con 5 passi 100 → 80 → 60 → 40 → 20 → 0, con 2 passi 100 → 50 → 0. Il primo salto parte sempre da t = 100, dove √ᾱ100 = 0,075.
Se la rete sbaglia la stima del rumore di δ, la stima x̂0 sbaglia di δ · √(1 − ᾱ100)/√ᾱ100 = 13,3 δ — l’errore viene amplificato più di dieci volte. Sostituendo nel salto verso il tempo s, il nuovo stato differisce da quello corretto di δ · (√(1 − ᾱs) − √ᾱs · 13,3):
- 5 passi, salto 100 → 80: fattore −1,59,
- 2 passi, salto 100 → 50: fattore −6,23,
Con un salto piccolo la stima sbagliata x̂0 viene mescolata con un peso piccolo √ᾱ80 = 0,19 e i passi successivi la correggono. Con un salto fino a metà del processo entra con il peso √ᾱ50 = 0,53 e resta un solo passo. Il ragionamento segue un solo errore in un solo passo e presuppone che per il resto la rete stimi con precisione; mostra però perché i primi passi, i più rumorosi, sono i più delicati.
Il DDIM con 50 passi raggiunge una qualità del 79 % — più del DDPM con 100 passi (63 %), molto probabilmente perché non aggiunge rumore casuale che la nostra rete imprecisa non fa in tempo a eliminare negli ultimi passi. Con 10 passi è ancora il 70 %, con 5 passi il 60 %. Con 2 passi il campionamento va in pezzi (0 %). Il numero di passi è il costo principale della diffusione: ogni passo è un passaggio attraverso la rete, mentre un GAN genera un’immagine con un solo passaggio.
5. Cifre: confronto tra tre generatori
Sulle cifre 8 × 8 (pixel riportati all’intervallo da −1 a 1) la rete si addestra per 16 000 passi.
| modello | distanza dalla cifra più vicina | cifra meno rappresentata (su 200) | cifre con meno di 10 campioni |
|---|---|---|---|
| VAE (k = 8) | 0,054 | 10 | 0 |
| GAN, seme 1 | 0,049 | 3 | 3 |
| GAN, seme 2 | 0,042 | 0 | 6 |
| diffusione (100 passi) | 0,063 | 12 | 0 |
Qui bisogna essere onesti: la nostra diffusione ha una distanza di 0,063, peggio del VAE (0,054) e del GAN (0,042). Nelle immagini si vede un rumore residuo. La rappresentazione delle cifre però è equilibrata — la cifra meno frequente ha 12 campioni, mentre al GAN con seme 2 mancano del tutto due cifre.
Perché la nitidezza è peggiore? Una piccola rete multistrato deve togliere il rumore dalle immagini a tutti i cento livelli di rumore insieme, ed è un compito più difficile dell’unica mappatura rumore → immagine di un GAN. In compenso migliora in modo costante con il calcolo: la distanza dei campioni è scesa durante l’addestramento 0,096 (passo 4 000), 0,082 (passo 8 000), 0,068 (passo 12 000), 0,063 (passo 16 000) (stima rapida su 100 campioni DDIM con 20 passi). Nessun collasso né oscillazioni. I veri modelli di diffusione usano reti convoluzionali U-Net o transformer con centinaia di milioni di parametri e si addestrano per settimane — e allora vincono anche in nitidezza.
6. Dalle cifre alle immagini da un testo
- Condizionamento. La rete εθ(xt, t, c) riceve in più una descrizione c — un embedding del testo prodotto da un modello linguistico, collegato tramite l’attenzione (la parte sull’attenzione). Si addestra su miliardi di coppie immagine–didascalia.
- Guida senza classificatore (classifier-free guidance, Jonathan Ho e Tim Salimans, 2021). La rete si addestra sia con la descrizione sia senza, e durante il campionamento la stima viene spostata nella direzione «con descrizione meno senza descrizione», amplificata da un coefficiente. L’immagine corrisponde così meglio alla richiesta, al prezzo di una minore varietà.
- Diffusione latente. La diffusione avviene nel piccolo spazio latente di un autoencoder, non nei pixel — vedi la parte sui VAE. Grazie a questo Stable Diffusion (2022) gira perfino su una scheda grafica da gioco.
- Meno passi. Campionatori migliori e la distillazione (una rete impara a imitare molti passi in uno solo o in pochi) hanno ridotto la generazione da centinaia di passi a poche unità.
ε̃ = εθ(xt, t, ∅) + w · (εθ(xt, t, c) − εθ(xt, t, ∅))
- εθ(…, ∅)
- la stima del rumore senza descrizione (condizione vuota ∅) — «che aspetto ha un’immagine qualsiasi»; la rete la impara perché durante l’addestramento la descrizione viene ogni tanto scartata a caso
- εθ(…, c) − εθ(…, ∅)
- di quanto cambia la stima quando la rete conosce la descrizione — la direzione in cui la descrizione tira l’immagine
- w
- forza della guida: w = 0 ignora la descrizione, w = 1 è un normale modello condizionato, w > 1 esagera l’influenza della descrizione — l’immagine corrisponde meglio alla richiesta, ma i campioni si somigliano di più
7. Riepilogo
- Il processo diretto aggiunge rumore poco a poco; a qualsiasi passo si può saltare con la formula √ᾱ x₀ + √(1 − ᾱ) ε.
- La rete impara a stimare il rumore aggiunto — una normale regressione. Si genera all’indietro a partire dal rumore puro.
- Sugli otto cluster la diffusione li ha coperti tutti in un’unica esecuzione (DDIM con 50 passi 79 %); il GAN solo in un’esecuzione su quattro.
- Meno passi (DDIM) accelerano il campionamento; con 10 passi la qualità è del 70 %, con 2 passi va in pezzi.
- Sulle cifre la diffusione copre tutte le cifre, mentre in nitidezza resta indietro con la nostra piccola rete; però migliora in modo costante con il calcolo.
Vuoi metterci le mani? Fai addestrare a un agente IA un piccolo DDPM su dati bidimensionali (per esempio punti a forma delle tue iniziali) e fagli disegnare come i punti si compongono in lettere durante il processo inverso.
La vedi diversamente? Scrivi a support@coden-app.com.