17

Difusión: de ruido a imagen

¿Cómo se crea una imagen quitando ruido paso a paso?

12 min

Difusión: de ruido a imagen

Con voz. Puedes pausar y saltar a cualquier paso.

Lección completa

Subtítulos

Esto es estática: sesenta y cuatro píxeles al azar. Mira con calma: en unos segundos, una red diminuta la convierte en un siete que nunca existió.

Voz

Sin voz: la lección avanza sola con subtítulos.

La voz de esta lección está en preparación: por ahora avanza sola con subtítulos.

0:00 / 0:00

Qué lograrás

  • Explicar el proceso hacia delante (mezclar una imagen con ruido, paso a paso, hasta que solo queda estática) y por qué deshacerlo de un salto es imposible y en muchos pasos pequeños, no.
  • Describir, pieza por pieza, qué recibe y qué entrega la red de un modelo de difusión (imagen con ruido y paso → ruido estimado) y cómo se genera partiendo de estática pura.
  • Reconocer qué hacen el guiado sin clasificador (exagerar la pista, a cambio de variedad) y la difusión latente (difundir en un espacio de códigos, mucho más barato).

Ideas clave

  1. El proceso hacia delante mezcla una imagen con ruido, paso a paso, según un calendario fijo, hasta que solo queda estática. No aprende nada, y al final toda imagen termina en la misma clase de estática, fácil de fabricar.
  2. Deshacer el ruido de un salto es imposible: la misma estática pudo venir de cualquier imagen y lo mejor que se puede adivinar es un promedio borroso. Un paso pequeño, en cambio, sí se puede estimar.
  3. La red recibe la imagen con ruido y el número del paso, y estima el ruido. Se entrena con ejemplos que nunca se acaban: el ruido lo fabricamos nosotros, así que conocemos la respuesta.
  4. Generar es partir de estática pura y quitar un poco del ruido estimado, muchas veces. Con otra estática sale otro resultado: nada estaba guardado.
  5. El guiado sin clasificador exagera la diferencia entre la estimación con pista y sin pista: más fidelidad, menos variedad. La difusión latente hace todo esto en un espacio de códigos mucho más pequeño y decodifica al final; así funciona Stable Diffusion.

Lo que mucha gente cree

Creencia común La red «limpia» una imagen que ya estaba escondida en la estática: solo la descubre.

Lo correcto En la estática no hay ninguna imagen. Paso a paso, la red va decidiendo qué dibujo es plausible según lo que aprendió de los datos; con otra estática, o con otra pista, sale otro dibujo distinto.

Compruébalo

Cuatro preguntas. Sin nota ni cuenta: sirven para ver si la idea quedó.

Concepto¿Qué aprende la red de un modelo de difusión?
Concepto¿Por qué no se quita todo el ruido de un solo salto?
CálculoUn sistema genera cada imagen con 50 pasos y guiado sin clasificador. Cada evaluación de la red tarda 0.02 s. ¿Cuánto tarda una imagen, sin contar la decodificación?
AplicaciónUn equipo de marketing sube mucho la escala de guiado para que las imágenes se parezcan más a lo que pide. ¿Qué debe esperar?

Por dentroPara quien quiere las fórmulas y el código. No hace falta para seguir el curso.

El proceso hacia delante

Con un calendario de ruido β1,…,βT\beta_1,\dots,\beta_T, sea αt=1−βt\alpha_t = 1-\beta_t y αˉt=∏s≤tαs\bar\alpha_t = \prod_{s\le t}\alpha_s. Cada paso es q(xt∣xt−1)=N(αt xt−1, βtI)q(x_t\mid x_{t-1}) = \mathcal N\big(\sqrt{\alpha_t}\,x_{t-1},\ \beta_t I\big), y al encadenarlos sale una fórmula cerrada para cualquier paso:

xt=αˉt x0+1−αˉt ε,ε∼N(0,I).x_t = \sqrt{\bar\alpha_t}\,x_0 + \sqrt{1-\bar\alpha_t}\,\varepsilon,\qquad \varepsilon\sim\mathcal N(0,I).

La barra de la lección muestra αˉt\bar\alpha_t (la parte de la «energía» de la mezcla que todavía es imagen) y 1−αˉt1-\bar\alpha_t (la que es ruido). La lección usa T=50T = 50 y el calendario coseno de Nichol y Dhariwal (2021), αˉ(t)∝cos⁡2 ⁣(t/T+s1+s⋅π2)\bar\alpha(t) \propto \cos^2\!\big(\tfrac{t/T + s}{1+s}\cdot\tfrac{\pi}{2}\big) con s=0.008s = 0.008, recortando cada βt\beta_t a 0.35 como máximo (con tan pocos pasos, los últimos β\beta del coseno se acercan a 1). Así αˉ\bar\alpha vale 0.899 en el paso 10, 0.494 en el 25, 0.094 en el 40 y 0.003 en el 50. Los píxeles se pasan antes a la escala −1…1-1\ldots 1; en pantalla se recorta a 0…10\ldots 1.

Por qué no de un salto

La red se entrena con error cuadrático, y lo que minimiza el error cuadrático es el promedio condicionado E[x0∣xt]\mathbb E[x_0\mid x_t]. Cuando t=Tt = T la estática casi no conserva información, así que E[x0∣xT]≈E[x0]\mathbb E[x_0\mid x_T]\approx \mathbb E[x_0]: el promedio de todos los dígitos, la mancha de la lección. En cambio, si cada βt\beta_t es pequeño, el paso inverso q(xt−1∣xt)q(x_{t-1}\mid x_t) es casi gaussiano, con la misma forma que el paso hacia delante (Sohl-Dickstein et al., 2015, que citan a Feller, 1949): basta estimar su media.

Qué aprende la red y cómo se entrena

La red εθ(xt,t,c)\varepsilon_\theta(x_t, t, c) estima el ruido. La pérdida simplificada de Ho et al. (2020) es

L(θ)=Ex0, t, ε[ ∥ε−εθ(αˉt x0+1−αˉt ε, t)∥2 ].L(\theta) = \mathbb E_{x_0,\,t,\,\varepsilon}\big[\,\lVert \varepsilon - \varepsilon_\theta(\sqrt{\bar\alpha_t}\,x_0 + \sqrt{1-\bar\alpha_t}\,\varepsilon,\ t)\rVert^2\,\big].

Gracias a la fórmula cerrada no hace falta recorrer los pasos al entrenar: se salta directo a un tt al azar. La red de píxeles de la lección tiene 53 056 parámetros (tres capas de 128 neuronas con conexiones residuales y SiLU; entradas: los 64 píxeles, 16 números que codifican el paso y la etiqueta en 11 casillas, la última para «sin pista») y se entrenó 30 000 rondas con lotes de 256 imágenes: 7 680 000 versiones con ruido de los 1500 dígitos de entrenamiento de la lección 15. Con la imagen del siete en el paso 20, su estimación del ruido tiene un error cuadrático medio de 0.135 por píxel; si dijera «no hay ruido», el error sería 0.864.

El muestreo

El muestreo original de DDPM parte de xT∼N(0,I)x_T\sim\mathcal N(0,I) y, para t=T,…,1t=T,\dots,1, calcula

xt−1=1αt(xt−βt1−αˉt ε^)+βt z,z∼N(0,I),x_{t-1} = \frac{1}{\sqrt{\alpha_t}}\Big(x_t - \frac{\beta_t}{\sqrt{1-\bar\alpha_t}}\,\hat\varepsilon\Big) + \sqrt{\beta_t}\, z,\qquad z\sim\mathcal N(0,I),

con un poco de ruido nuevo zz en cada paso (salvo el último). La escena usa la variante determinista de Song et al. (2021), DDIM con η=0\eta = 0, con la misma red entrenada como en DDPM:

x^0=xt−1−αˉt ε^αˉt,xt−1=αˉt−1 x^0+1−αˉt−1 ε^.\hat x_0 = \frac{x_t - \sqrt{1-\bar\alpha_t}\,\hat\varepsilon}{\sqrt{\bar\alpha_t}},\qquad x_{t-1} = \sqrt{\bar\alpha_{t-1}}\,\hat x_0 + \sqrt{1-\bar\alpha_{t-1}}\,\hat\varepsilon .

Es decir: con la estimación del ruido se calcula la imagen limpia que implica y se vuelve a mezclar con la parte de ruido que le toca al paso anterior. Sin ruido nuevo, cada punto del plano sigue exactamente su flecha y la misma estática da siempre el mismo resultado; con otra estática sale otro.

Guiado sin clasificador

Se entrena una sola red con la etiqueta cc y, con probabilidad 0.15, sin ella (∅\varnothing). Al muestrear se combina

ε^=εθ(xt,∅)+s (εθ(xt,c)−εθ(xt,∅)).\hat\varepsilon = \varepsilon_\theta(x_t,\varnothing) + s\,\big(\varepsilon_\theta(x_t,c)-\varepsilon_\theta(x_t,\varnothing)\big).

Con s=0s=0 es la estimación sin pista (la pista se ignora); con s=1s=1, la condicional, que sigue la pista tal cual; con s>1s>1 se exagera la dirección de la pista. Es la misma convención de la lección 18. Ho y Salimans (2022) escriben lo mismo con w=s−1w = s-1: ε~=(1+w) εθ(xt,c)−w εθ(xt)\tilde\varepsilon = (1+w)\,\varepsilon_\theta(x_t,c) - w\,\varepsilon_\theta(x_t). Cada paso guiado cuesta dos evaluaciones de la red. En el plano de la lección, con la pista «siete» y doscientos puntos (lector: la regresión logística de la lección 15), se leen como siete 26 con s=0s = 0, 199 con s=1s = 1 y 200 con s=5s = 5. A la vez, los sietes reales que se quedan sin ningún punto nuevo a menos de 0.3 son 4 de 154 con s=1s = 1, 48 con s=2s = 2, 95 con s=3s = 3 y 144 con s=5s = 5: los puntos se amontonan en la orilla del grupo más alejada de los demás dígitos. La red de píxeles genera sus sietes con s=3s = 3.

Difusión latente

Un autocodificador comprime la imagen a un código z=E(x)z=E(x); la difusión ocurre en zz y al final se decodifica x=D(z)x=D(z) (Rombach et al., 2022). En la lección, zz son los dos números del VAE de la lección 15, multiplicados por 1.6 antes de difundir (Stable Diffusion también reescala sus códigos con un factor fijo), y la red del plano tiene 10 370 parámetros. En Stable Diffusion v1, el autocodificador reduce cada lado 8 veces y entrega 4 canales: una imagen de 512×512×3=786 432512\times512\times3 = 786\,432 números se vuelve un código de 64×64×4=16 38464\times64\times4 = 16\,384, 48 veces menos.

En código

import numpy as np

T, s = 50, 0.008
f = lambda t: np.cos((t / T + s) / (1 + s) * np.pi / 2) ** 2
a_full = f(np.arange(T + 1)) / f(0)
betas = np.clip(1 - a_full[1:] / a_full[:-1], 1e-4, 0.35)   # calendario de ruido
alphas = 1 - betas
abar = np.cumprod(alphas)
print('imagen en la mezcla (%):', [round(float(100 * abar[t - 1]), 1) for t in (10, 25, 40, 50)])

# Datos de juguete: un solo número que vale -1 o +1. Para ellos, el mejor
# estimador del ruido se puede escribir a mano (en la lección lo aprende una red).
def ruido_estimado(x, i):
    a, b = np.sqrt(abar[i]), np.sqrt(1 - abar[i])
    x0 = np.tanh(a * x / b**2)          # promedio de x0 dado x_t
    return (x - a * x0) / b

rng = np.random.default_rng(0)
x = rng.standard_normal(10_000)        # estática pura
for i in reversed(range(T)):           # cincuenta pasos de regreso (DDPM)
    e = ruido_estimado(x, i)
    x = (x - betas[i] / np.sqrt(1 - abar[i]) * e) / np.sqrt(alphas[i])
    if i > 0:
        x += np.sqrt(betas[i]) * rng.standard_normal(x.size)

print('a menos de 0.1 de -1 o de +1:', round(float(np.mean(np.abs(np.abs(x) - 1) < 0.1)), 3))
print('fracción en +1:', round(float(np.mean(x > 0)), 3))
# imagen en la mezcla (%): [89.9, 49.4, 9.4, 0.3]
# a menos de 0.1 de -1 o de +1: 1.0
# fracción en +1: 0.499

Lo que viene

La lección 18 muestra cómo una frase se convierte en la pista que guía la difusión (CLIP y el condicionamiento por texto). Más adelante, el transformer (lecciones 21 y 22) reemplaza a la red convolucional en muchos modelos de difusión modernos.

Lente de decisión

Qué significa esta idea si tu trabajo es decidir, no programar.

  • El costo de generar es pasos × evaluaciones de la red × imágenes. El guiado sin clasificador duplica las evaluaciones por paso: para campañas masivas, estima el volumen y compara configuraciones con menos pasos o menor resolución.
  • La escala de guiado es una perilla de negocio: más alta da resultados más fieles a lo pedido, pero más parecidos entre sí. Prueba varias escalas con tus propios casos antes de fijarla.
  • La calidad aparente engaña: revisa detalles (texto dentro de la imagen, manos, logotipos) y mantén revisión humana antes de publicar.
  • Estos modelos aprenden de grandes colecciones de imágenes reales: pregunta al proveedor de dónde vienen los datos, qué licencias cubren y qué política de uso y de etiquetado de imágenes sintéticas ofrece.

Términos de la lección

Transcripción completa
ComentariosConversación pública de esta lección: dudas, datos por revisar, ideas.

Los comentarios viven en GitHub Discussions, en el repositorio público del curso; para escribir se necesita una cuenta de GitHub. Se cargan desde giscus.app al abrir esta sección. Las personas que revisan el curso los leen, y si un cambio se acepta, se aplica en los dos idiomas. Abrir el hilo en GitHub

Fuentes