Generar es aprender una distribución
¿Qué significa que una red "genere" algo nuevo?
Lección completa
Si quieres:
En la parte uno, las redes aprendieron a decidir: miran un dibujo como este y responden: es un siete.
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 la diferencia entre clasificar (trazar una frontera) y generar (conocer la distribución de los datos y sacar muestras nuevas de ella).
- Describir, pieza por pieza, cómo un autocodificador resume una imagen en dos números y la reconstruye, y qué es el espacio latente.
- Reconocer por qué el plano de un autocodificador simple tiene huecos y cómo las nubes de un VAE los rellenan para poder muestrear.
Ideas clave
- Clasificar es trazar una frontera entre grupos. Generar pide más: conocer la distribución de los datos, dónde se apiñan y hasta dónde llegan, para sacar muestras nuevas.
- Muestrear es sacar un dato nuevo siguiendo la distribución: sale más seguido lo común y pocas veces lo raro.
- Los píxeles de una imagen dependen unos de otros: sacarlos por separado da manchas. Por eso se comprime cada imagen en pocos números que sí basten para rehacerla.
- Un autocodificador tiene dos piezas: el codificador resume la imagen en un código (aquí, dos números) y el decodificador la reconstruye. El plano de los códigos es el espacio latente.
- El plano de un autocodificador simple queda desordenado y con huecos. Un VAE resume cada imagen en una nube y las junta en una zona conocida: así se puede muestrear. El precio, imágenes algo borrosas.
Lo que mucha gente cree
Creencia común La IA generativa recorta y pega trozos de imágenes que tiene guardadas: es un collage.
Lo correcto Aprende una distribución: guarda pesos, no imágenes, y genera sacando un punto al azar y decodificándolo. Lo generado se parece a los datos sin copiar ninguno. La excepción es la memorización (sobre todo de imágenes muy repetidas en los datos): un fallo real que se mide y se intenta evitar.
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.
Clasificar frente a generar
Un modelo que clasifica aprende : dado el dato, la etiqueta; le basta la frontera. Un modelo generativo aprende la distribución de los propios datos, , y permite muestrear . Se entrena, en general, por máxima verosimilitud:
La nube de los sietes
Cada dígito se mide con : la tinta de su mitad de arriba y la de su mitad de abajo (cada píxel vale de 0 a 1; cada mitad tiene 32 píxeles). Los óvalos de la lección son una gaussiana en dos dimensiones ajustada por máxima verosimilitud a los 179 sietes:
El óvalo pequeño es y el grande, . En una gaussiana de dos dimensiones caen dentro y de las muestras. Para muestrear se toma y , con (Cholesky). La frontera entre seises y sietes de la escena es la del análisis discriminante lineal: la recta donde las dos gaussianas, con su covarianza promedio, dan la misma densidad.
Por qué no basta con cada píxel por separado
Sacar cada píxel de su propia distribución equivale a suponer : píxeles independientes. En los dígitos es falso (un trazo enciende a sus vecinos), y por eso salen manchas. Hace falta un modelo de cómo varían juntos.
Autocodificador
Un codificador y un decodificador , entrenados juntos para minimizar el error de reconstrucción:
Los modelos de la lección son diminutos: con en la capa oculta y un sigmoide a la salida (4354 parámetros), entrenados con descenso del gradiente (Adam) sobre 1500 imágenes; otras 297 se reservaron para reconstruir imágenes que la red nunca vio. Error medio por imagen reservada según el tamaño del código: 3.14 con 1 número, 2.34 con 2, 1.46 con 4, 0.95 con 8 y 0.54 con 16 (adivinar siempre la imagen media daría 4.71). Con decodificador lineal y error cuadrático, un autocodificador aprende el mismo subespacio que el PCA (Goodfellow et al., 2016, §14.1); las capas no lineales lo generalizan, y Hinton y Salakhutdinov (2006) mostraron que los autocodificadores profundos aprenden códigos mucho mejores que el PCA.
Autocodificador variacional (VAE)
Se postula un código con distribución previa conocida, (la «zona redonda»), y un decodificador . El codificador devuelve una nube, : su centro y su tamaño. En el entrenamiento se saca un punto con el truco de reparametrización, que deja pasar el gradiente:
Lo que se maximiza es una cota inferior de (la ELBO):
El primer término es el error de reconstrucción; el segundo, la penalización que acerca cada nube a la zona estándar. Para gaussianas diagonales tiene forma cerrada:
La pérdida usada en la lección es con (4420 parámetros). Los dos términos compiten: la reconstrucción separa y encoge las nubes; la penalización las junta y las ensancha. Para generar: y . Con un decodificador gaussiano de varianza fija, la mejor reconstrucción de un código es el promedio de las imágenes que caben en él: de ahí la borrosidad. Kingma y Welling (2019, §2.8.2) la atribuyen a que el ajuste nunca es perfecto y señalan que se atenúa con modelos de inferencia y generativos más flexibles.
Muestrear con cada modelo
Para el autocodificador no hay una zona definida de la cual muestrear; el recurso ingenuo es sacar puntos uniformes en el recuadro de sus códigos. Un clasificador sencillo (regresión logística entrenada con las mismas 1500 imágenes) etiquetó 3000 muestras de cada modelo: el autocodificador dio 22 % de cuatros, 21 % de seises y 0.7 % de ochos; el VAE, entre 6 % y 14 % de cada dígito (los datos reales tienen cerca de 10 % de cada uno). Con ocho semillas distintas el resultado se repite: el VAE siempre queda más parejo (véase train_toy.py).
En código
import numpy as np
# cinco sietes medidos con (tinta arriba, tinta abajo): ejemplo
m = np.array([[12.0, 7.8], [10.4, 8.9], [11.3, 7.4], [9.6, 8.5], [10.9, 8.1]])
mu = m.mean(axis=0) # centro de la nube
cov = np.cov(m.T, bias=True) # forma del óvalo (máxima verosimilitud: divide entre N)
L = np.linalg.cholesky(cov) # L @ L.T == cov
rng = np.random.default_rng(0)
nuevos = mu + rng.standard_normal((3, 2)) @ L.T # muestrear: tres puntos nuevos de la nube
print(mu.round(2).tolist(), nuevos.round(1).tolist())
# [10.84, 8.14] [[10.9, 8.0], [11.4, 7.9], [10.4, 8.5]]
# Una nube de VAE: centro y tamaño (uno por cada número del código)
c, s = np.array([0.8, -0.3]), np.array([0.5, 0.8])
kl = 0.5 * np.sum(c**2 + s**2 - np.log(s**2) - 1) # penalización frente a la zona estándar N(0, I)
z = c + s * np.array([0.2, -1.0]) # un punto sacado de la nube (truco de reparametrización)
print(round(float(kl), 4), z.round(2).tolist())
# 0.7263 [0.9, -1.1]
Lo que viene
Los VAE fueron propuestos de forma independiente por Kingma y Welling (2013) y por Rezende, Mohamed y Wierstra (2014). Las redes generativas adversarias (lección 16) aprenden a generar sin escribir una densidad: compitiendo. La difusión (lección 17) aprende a quitar ruido, y su versión latente trabaja dentro del espacio comprimido de un autocodificador.
Lente de decisión
Qué significa esta idea si tu trabajo es decidir, no programar.
- Lo generado refleja la mezcla de los datos de entrenamiento, y a veces la distorsiona: en la demostración, el autocodificador casi nunca producía ochos. Pide que midan la mezcla de lo generado, no solo que muestren ejemplos.
- Cinco imágenes impecables no son evidencia. Pide muestras al azar, sin selección, y una medida de calidad y de variedad (por ejemplo, cuántos de cien intentos son utilizables y cuántos se parecen entre sí).
- «No es un collage» es la regla, no una garantía: con modelos grandes y datos repetidos hay memorización documentada. Pregunta por la deduplicación de datos, las pruebas de memorización y el origen y la licencia de lo que se usó para entrenar.
- Generar es muestrear: la misma instrucción da resultados distintos. Si necesitas reproducir un resultado, fija la semilla y registra la configuración; y recuerda que los datos sintéticos no traen información que no estuviera ya en los datos originales.
Términos de la lección
- 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.)
- Autocodificador Red de dos piezas: un codificador, que resume cada dato en pocos números (el código), y un decodificador, que intenta reconstruirlo desde el código. Se entrena para que baje el error de reconstrucción.
- Espacio latente El espacio de los códigos de un modelo («latente» significa oculto): cada dato es un punto, y los puntos cercanos suelen ser datos parecidos. Cualquier punto se puede decodificar.
- Autocodificador variacional (VAE) Autocodificador que resume cada dato en una nube (centro y tamaño) en lugar de un punto, y penaliza que las nubes se alejen de una zona estándar. Así el espacio latente queda sin huecos y se puede muestrear de él.
- Píxel El punto más pequeño de una imagen digital. En escala de grises es un número de 0 (negro) a 255 (blanco); en color son tres números (rojo, verde y azul).
- Vector Lista ordenada de números. En aprendizaje automático, cada ejemplo llega al modelo como un vector.
- Característica (feature) Una medida de un ejemplo expresada como número: el número de enlaces de un correo, el brillo de un píxel. Las características de un ejemplo forman su vector.
- 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.
- Datos de entrenamiento Ejemplos, cada uno con su respuesta correcta, con los que un modelo ajusta sus parámetros.
- 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.
- 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.
- Embedding Vector de números, aprendido de los datos, que representa algo (una palabra, una frase, una imagen) de modo que lo parecido quede cerca. Cada palabra tiene una fila en una tabla de embeddings.
- Espacio vectorial Espacio cuyos puntos son vectores. En un espacio de embeddings, la distancia o el ángulo entre dos puntos mide cuánto se parecen sus significados.
Transcripción completa
Fuentes
- Alpaydin, E., Kaynak, C. (1998). Optical Recognition of Handwritten Digits (UCI Machine Learning Repository, CC BY 4.0; datos de los dígitos de 8 × 8)
- Kingma, D. P., Welling, M. (2013). Auto-Encoding Variational Bayes
- Rezende, D. J., Mohamed, S., Wierstra, D. (2014). Stochastic Backpropagation and Approximate Inference in Deep Generative Models
- Kingma, D. P., Welling, M. (2019). An Introduction to Variational Autoencoders
- Hinton, G. E., Salakhutdinov, R. R. (2006). Reducing the Dimensionality of Data with Neural Networks
- Goodfellow, I., Bengio, Y., Courville, A. (2016). Deep Learning, capítulo 14 (Autoencoders) y capítulo 20 (Deep Generative Models)
- Alpaydin, E., Kaynak, C. (1998). Optical Recognition of Handwritten Digits (UCI Machine Learning Repository, CC BY 4.0)
- Carlini, N., Hayes, J., Nasr, M., Jagielski, M., Sehwag, V., Tramèr, F., Balle, B., Ippolito, D., Wallace, E. (2023). Extracting Training Data from Diffusion Models
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