GAN: el falsificador y el detective
¿Cómo aprende un generador compitiendo contra un crítico?
Lección completa
Si quieres:
Un falsificador pinta billetes falsos y un detective intenta descubrirlos. Cada vez que el detective lo atrapa, el falsificador aprende a pintar mejor.
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.
Modo revisiónComentar este pasoTerminé la lección
Qué lograrás
- Explicar qué hace el generador (convierte un número sorteado en un dato falso) y qué hace el discriminador (estima qué tan probable es que un dato sea real).
- Describir el entrenamiento adversario como un juego por turnos y reconocer su final ideal: el discriminador responde 0.5 porque ya no distingue.
- Reconocer el colapso de modo y la inestabilidad en un entrenamiento real, y explicar por qué la difusión tomó la delantera en imágenes.
Ideas clave
- Una GAN son dos redes que compiten: el generador convierte un número sorteado en un dato falso; el discriminador estima qué tan probable es que un dato sea real.
- El generador nunca ve los datos reales: aprende solo a través de la respuesta del discriminador, moviendo sus falsos hacia donde este dice «más real».
- El final ideal es un empate: el discriminador responde 0.5 a todo porque ya no distingue. En la GAN de la lección se llega cerca, aunque no del todo.
- El colapso de modo (producir solo una parte de la variedad) y la inestabilidad son sus problemas típicos: con un solo ajuste distinto, cuatro de veinte partidas colapsaron.
- La difusión tomó la delantera en imágenes (Dhariwal y Nichol, 2021) porque se entrena de forma estable y cubre mejor la variedad; las GAN siguen siendo más rápidas al generar.
Lo que mucha gente cree
Creencia común El generador de una GAN aprende copiando los datos reales que le muestran.
Lo correcto El generador nunca ve un dato real. Solo recibe números al azar y la respuesta del discriminador, y ajusta sus pesos para que esa respuesta sea «real». Los datos reales solo los ve el discriminador.
Compruébalo
Cuatro preguntas. Sin nota ni cuenta: sirven para ver si la idea quedó.
Por dentroPara quien quiere las fórmulas y el código. No hace falta para seguir el curso.
El juego en una fórmula
El generador recibe ruido (en la lección, la campana estándar) y produce . El discriminador devuelve , la probabilidad que asigna a que venga de los datos. Goodfellow et al. (2014) plantean un juego de dos jugadores de tipo minimax:
sube diciendo «1» a los reales y «0» a los falsos (es la entropía cruzada de un clasificador binario, con signo cambiado); la baja haciendo que se acerque a 1. Lo que gana uno lo pierde el otro: es un juego de suma cero.
El mejor detective posible y el empate
Con fijo, el discriminador óptimo es
donde es la distribución de los falsos. Si en una zona hay dos falsos por cada real, lo mejor que puede responder ahí es . Es lo que se mide en la partida que colapsa: en la montaña izquierda (todos los falsos y la mitad de los reales) el detective responde entre 0.32 y 0.35; en la derecha, donde no hay falsos, 1.00. El artículo demuestra que el juego tiene su óptimo global en , con en todas partes. Ahí la pérdida del detective vale y la del generador (versión no saturante, abajo) ; en los últimos doscientos pasos de la partida sana de la lección promedian 1.384 y 0.702.
El truco no saturante y los pasos
Al principio, rechaza los falsos con mucha seguridad y se satura: casi no da gradiente. Por eso el mismo artículo propone que maximice , que tiene el mismo punto fijo y gradientes más fuertes al inicio. Es lo que usa la lección. El gradiente que corrige a pasa por (retropropagación a través de las dos redes, lección 8): para cada falso, dice hacia dónde moverlo. Las flechas de la escena son esa derivada, calculada con la curva real del detective.
El Algoritmo 1 alterna pasos de con uno de ; los autores usaron . En la lección, es el único hiperparámetro que cambia: con , las 20 semillas cubren las dos montañas; con , 15 las cubren, 4 colapsan (una montaña recibe menos de 5 % de los falsos) y una queda a medias (48 % y 6 %). El artículo advierte del desequilibrio contrario, entrenar demasiado a sin actualizar a , que llama «el escenario Helvetica»: manda demasiados valores de al mismo . En los dos sentidos, el equilibrio entre los jugadores importa.
La GAN de la lección
- Datos: mezcla 50/50 de y . Los 800 reales de la escena son cuantiles de cada campana, y los 800 sorteos del generador, cuantiles de : así cada histograma es reproducible.
- Redes: y son iguales, (141 parámetros cada una). Adam con tasa y , lotes de 256, 2000 pasos del generador. Los pesos se exportaron cuantizados a 16 bits y el navegador ejecuta las redes (solo la pasada hacia delante); los scripts
train_gan.pyytrain_detective.pyestán en la carpeta de la lección. - El detective solo: para presentarlo aparte, se entrenó el detective inicial de la partida sana durante 1000 pasos contra el falsificador inicial congelado (todo cerca de 0). Responde 0.95 a 1.6 y 0.05 a 0.07.
- «Cerca de una montaña»: a menos de 0.8 de su centro. Los reales: 47.75 % en cada una. Los falsos al final de la partida sana: 46.4 % y 48.1 %.
- Lo que no salió perfecto: las montañas falsas son más angostas (la más alta junta 337 de 800 falsos en un tramo de 0.25; la real, 98), y queda un puente de falsos en el valle. El puente es inevitable con este diseño: es una función continua de un solo número, así que los cercanos a 0 caen entre las dos montañas. Ahí . El detective, pequeño y entrenado al mismo ritmo, no detecta lo angosto.
En código
import torch, torch.nn as nn
torch.manual_seed(0)
def red(): # 1 → 10 → 10 → 1, con tanh: 141 parámetros
return nn.Sequential(nn.Linear(1, 10), nn.Tanh(), nn.Linear(10, 10), nn.Tanh(), nn.Linear(10, 1))
def reales(n): # mezcla 50/50 de N(−1.5, 0.4²) y N(+1.5, 0.4²)
signo = torch.randint(0, 2, (n, 1)) * 2 - 1
return 1.5 * signo + 0.4 * torch.randn(n, 1)
G, D = red(), red() # falsificador y detective
opt_G = torch.optim.Adam(G.parameters(), lr=5e-4, betas=(0.5, 0.999))
opt_D = torch.optim.Adam(D.parameters(), lr=5e-4, betas=(0.5, 0.999))
bce = nn.BCEWithLogitsLoss() # aplica la sigmoide y calcula −log
uno, cero = torch.ones(256, 1), torch.zeros(256, 1)
for paso in range(2000):
# turno del detective: a los reales debe decir 1; a los falsos, 0
falsos = G(torch.randn(256, 1)).detach()
perdida_D = bce(D(reales(256)), uno) + bce(D(falsos), cero)
opt_D.zero_grad(); perdida_D.backward(); opt_D.step()
# turno del falsificador: que el detective diga «real» a sus falsos
perdida_G = bce(D(G(torch.randn(256, 1))), uno)
opt_G.zero_grad(); perdida_G.backward(); opt_G.step()
with torch.no_grad():
x = G(torch.randn(10000, 1))
izq = ((x + 1.5).abs() < 0.8).float().mean().item()
der = ((x - 1.5).abs() < 0.8).float().mean().item()
print(f'falsos cerca de cada montaña: {izq:.2f} y {der:.2f}')
dr, df = torch.sigmoid(D(reales(10000))).mean().item(), torch.sigmoid(D(x)).mean().item()
print(f'detective, en promedio: reales {dr:.2f}, falsos {df:.2f}')
# falsos cerca de cada montaña: 0.47 y 0.48
# detective, en promedio: reales 0.50, falsos 0.50
(PyTorch 2.11 en CPU; otra versión puede dar cifras algo distintas.)
Lo que viene
Las GAN dominaron la generación de imágenes de alta calidad hasta que Dhariwal y Nichol (2021) mostraron que los modelos de difusión las superaban. Ellos mismos señalan que las GAN capturan menos variedad y son difíciles de entrenar, «colapsando sin hiperparámetros y regularizadores cuidadosamente elegidos», mientras que la difusión ofrece cobertura de la distribución, un objetivo de entrenamiento estacionario (no depende de un rival que cambia) y facilidad para escalar; su desventaja es que genera más lento, en muchos pasos de quitar ruido. Eso es la lección 17.
Lente de decisión
Qué significa esta idea si tu trabajo es decidir, no programar.
- El ojo humano ya no es un detector confiable: en el estudio de Nightingale y Farid (2022), 315 personas acertaron 48.2 % al separar rostros reales de rostros hechos con StyleGAN2, y con entrenamiento y retroalimentación llegaron solo a 59.0 %. Verificar autenticidad exige procedencia y herramientas, no intuición.
- Si un proveedor genera datos sintéticos (para entrenar o para probar), pregunta cómo midió la variedad: el colapso de modo puede borrar justo los casos raros que más importan, sin que las muestras «se vean mal».
- Entrenar una GAN es frágil: pide resultados de varias corridas y semillas, no una sola demostración. En la lección, cambiar un ajuste hizo colapsar cuatro de veinte partidas.
- Elige por el uso: la difusión da más calidad y variedad pero genera en muchos pasos; una GAN genera en una sola pasada, útil cuando la velocidad manda (tiempo real, dispositivos pequeños).
Términos de la lección
- GAN (red generativa adversaria) Modelo generativo formado por dos redes que se entrenan compitiendo: un generador que produce datos falsos y un discriminador que intenta distinguirlos de los reales (Goodfellow et al., 2014).
- Generador En una GAN, la red que convierte un número (o un vector) sorteado al azar en un dato falso. Nunca ve los datos reales: aprende con la respuesta del discriminador.
- Discriminador En una GAN, la red que recibe un dato y estima, entre 0 y 1, qué tan probable es que sea real y no del generador. En el empate ideal responde 0.5.
- Colapso de modo Falla típica de las GAN: el generador produce solo una parte de la variedad de los datos (por ejemplo, una sola de varias «montañas» o un solo tipo de imagen).
- Modelo generativo Modelo que aprende la distribución de sus datos (qué es común, qué es raro) y por eso puede producir datos nuevos parecidos. Un modelo que clasifica, en cambio, solo aprende la frontera entre grupos.
- Distribución La forma en que se reparten los datos: qué valores (o combinaciones de valores) son comunes, cuáles raros y cuáles no aparecen nunca. En dos medidas se ve como una nube de puntos.
- Muestrear Sacar un dato nuevo siguiendo una distribución: lo común sale a menudo y lo raro pocas veces. Es como genera un modelo generativo. (No confundir con las muestras de audio de la lección 2.)
- Sigmoide Función σ(z) = 1/(1 + e⁻ᶻ): convierte cualquier número en un valor entre 0 y 1, y vale 0.5 cuando z = 0.
- Descenso del gradiente Método que ajusta los pesos paso a paso, siempre en contra de la pendiente del error (el gradiente), hasta llegar a un fondo.
- Retropropagación Algoritmo que calcula el gradiente de la pérdida respecto de todos los pesos de una red en un solo recorrido hacia atrás, aplicando la regla de la cadena capa por capa. Calcula las culpas; no mueve los pesos (en el artículo de 1986, el nombre abarcaba todo el procedimiento de aprendizaje).
- Lote Conjunto pequeño de ejemplos, tomado al azar, con el que se estima el gradiente en un paso de entrenamiento.
- Hiperparámetro Ajuste que fija una persona para el entrenamiento (tasa, tamaño del lote, épocas, optimizador, calendario). No se aprende con gradientes.
- Función de pérdida Un único número que resume qué tan equivocado está un modelo con sus datos. Entrenar es buscar los parámetros que lo hacen lo más pequeño posible.
- Peso (w) En un modelo lineal, el número que multiplica a la entrada: la pendiente de la recta. Indica cuánto sube la predicción por cada unidad que aumenta la entrada.
- Modelo de difusión Modelo generativo que aprende a deshacer un proceso fijo que mezcla los datos con ruido paso a paso (el proceso hacia delante). Genera partiendo de estática pura y quitando un poco de ruido estimado, muchas veces.
Transcripción completa
Fuentes
- Goodfellow, I. J., Pouget-Abadie, J., Mirza, M., Xu, B., Warde-Farley, D., Ozair, S., Courville, A., Bengio, Y. (2014). Generative Adversarial Networks (arXiv 1406.2661; NeurIPS 2014)
- Goodfellow, I. (2016). NIPS 2016 Tutorial: Generative Adversarial Networks (arXiv 1701.00160)
- Dhariwal, P., Nichol, A. (2021). Diffusion Models Beat GANs on Image Synthesis (arXiv 2105.05233; NeurIPS 2021)
- Nightingale, S. J., Farid, H. (2022). AI-synthesized faces are indistinguishable from real faces and more trustworthy (PNAS 119(8), e2120481119)
- Karras, T., Laine, S., Aittala, M., Hellsten, J., Lehtinen, J., Aila, T. (2020). Analyzing and Improving the Image Quality of StyleGAN (arXiv 1912.04958; CVPR 2020)
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