Variational AutoEncoder
Los Variational AutoEncoders (VAE) ([1],[2]) son modelos de aprendizaje que mezclan las redes neuronales con distribuciones de probabilidad. Su principal uso es el de construir modelos generativos que son capaces de producir datos sintéticos que siguen los mismos patrones que los grandes conjuntos de datos de los que se alimentan. Normalmente, se han usado para generar imágenes que asemejan, por ejemplo, características conocidas tales como caras, vehículos, habitáculos, etc. aunque en teoría podrían usarse para la generación de cualquier tipo de dato, siempre y cuando el conjunto de entrenamiento de datos reales sea adecuado (en tamaño y contenido).

Resultados generados por un VAE junto a las imágenes que se han usado para entrenamiento
Modelos Generativos y Autoencoders
En general, un modelo de Machine Learning generativo se puede interpretar simplemente como un algoritmo que, tras entrenarse con un conjunto de datos, genera una nueva salida que se parece a los datos de entrenamiento. La diferencia que introduce el modelo VAE respecto a los modelos de generación puramente al azar es que, además, permite influir en la dirección específica en la que explorar las variaciones posibles tomando como referencia datos concretos del conjunto de entrenamiento.

Estructura general de un autoencoder
Haciendo uso de redes neuronales, un VAE [3] se construye a partir de un autoencoder (autocodificador) [4] formado por dos redes: un encoder (codificador), y un decoder (decodificador), a los que se añade una función de pérdida que mide cuánto se parece un objeto decodificado (la salida de la red) al objeto que se codifica (la entrada de la red).
En un autoencoder neuronal, el encoder es una red neuronal que transforma sus entradas en una representación interna (intermedia), normalmente de dimensión muy inferior a la entrada, con el fin de obligarle a aprender una compresión eficiente que extraiga las propiedades principales de los datos de entrada. Posteriormente, esta representación intermedia (salida del encoder) se utiliza como entrada del decoder para recuperar, en la medida de lo posible, la entrada original.
Debido a esto, podríamos usar la salida del encoder como nueva representación del dato para cualquier tarea, no solo para reproducirlo, porque en esa representación se encuentra codificada toda la información relevante del dato de entrada para poder llevar a cabo su reconstrucción. De hecho, es lo que hacen todas las redes neuronales en cualquiera de sus capas intermedias, pero los autoencoder centran su tarea en la capacidad reproductiva de la entrada (o de ligeras variantes de ella).
Normalmente, las dos redes involucradas, encoder y decoder, se entrenan simultáneamente como una unidad con el fin de acoplar el comportamiento de una al de la otra, y se usa la función de pérdida como mecanismo para dirigir este entrenamiento y conseguir que el error existente entre el original y la reproducción se vaya reduciendo (desde un punto de vista técnico, la función de pérdida es la función objetivo a minimizar). Debido al objetivo que persiguen los autoencoders, a esta función de pérdida suele denominarse también pérdida de reproducción, y el proceso asegura que se penalicen las configuraciones de la red que crean salidas distintas de la entrada.
Espacios Latentes
Una vez obtenido un autoencoder, podríamos intentar usar el espacio de representaciones intermedias (también llamado espacio latente) como un mecanismo independiente para obtener con el decoder salidas similares a los datos de entrada. Para ello, tomaríamos al azar un punto del espacio latente, le aplicaríamos el decoder, y como resultado obtendríamos una salida que debe reflejar un objeto que se mueve en el mismo espacio que las entradas.

Espacio latente de representaciones en un autoencoder
El proceso definido hasta el momento es general de todos los autoencoders, no específico de los VAE. Sin embargo, si no se tienen en cuenta algunos detalles adicionales, los autoencoders generales presentan algunos problemas que no facilitan su uso como generadores de variantes.
El principal problema que se ha constatado es que, en la mayoría de los casos, las representaciones internas que se obtienen (la representación en el espacio latente, salida del encoder, que sirve de entrada al decoder) forman un espacio que no es continuo, sino formado por diversas bolsas aisladas que agrupan en su interior representaciones de datos de entrada similares (clases). Por ejemplo, si las entradas fuesen letras manuscritas de un alfabeto, podríamos encontrar representaciones internas similares para las "a's", que forman un conjunto de representaciones relativamente compacto, otra bolsa completamente distinta para las "b's", etc. Entre estas bolsas encontramos un espacio de posibles representaciones (que realmente no son imagen de ningún dato de entrenamiento) y que, esperamos, reflejasen objetos con propiedades intermedias a las de las entradas de las bolsas más cercanas. Pero la realidad experimental indica que no es así, y que una interpolación en el espacio de representaciones no se corresponde con una interpolación similar en el espacio original de datos (es decir, una representación intermedia entre una representación de un objeto de tipo "a" y otro de tipo "b", no se corresponde en general con un objeto que presenta propiedades entre esos dos objetos). Formalmente, el espacio de representación intermedio en general no proporciona buenas propiedades de interpolación y conectividad debido a que su topología es mucho más compleja y no es cóncava.
Cuando estamos buscando un algoritmo generador, el problema que plantea este hecho es que si el espacio de representación intermedia tiene discontinuidades y tomamos una muestra en una de estas zonas intermedias, entonces el decoder producirá una salida muy poco realista, que no reconocemos como un objeto similar a los que han servido para alimentar el entrenamiento de la red completa. La razón es que el decoder no tiene información acerca de cómo manejar una representación que proviene de esa región del espacio latente, ya que durante el entrenamiento nunca ha visto objetos codificados que provengan de esa zona.
Suavizando el Espacio Latente con Distribuciones
Los VAE precisamente tienen como objetivo eliminar ese problema construyendo explícitamente un espacio latente que ha de ser continuo, permitiendo generar objetos por medio de la interpolación de representaciones latentes de datos de entrada y, en consecuencia, la generación al azar por medio de un muestreo aleatorio del espacio latente.
Para conseguir este efecto, un VAE [1] considera que la representación intermedia no viene dada por medio de un vector de tamaño prefijado (la dimensión que se requiera en el espacio latente), sino por medio de dos vectores del mismo tamaño pero con significados bien distintos: un vector de medias, $\vec{\mu}=(\mu_1,\dots,\mu_n)$, y un vector de desviaciones estándar, $\vec{\sigma}=(\sigma_1,\dots,\sigma_n)$, que conjuntamente forman un vector de variables aleatorias descritas por medio de distribuciones normales $(N(\mu_1,\sigma_1),\dots,N(\mu_n,\sigma_n))$.

Arquitectura general de un VAE
A partir de este vector de distribuciones normales podemos obtener un vector (que realmente es una muestra al azar siguiendo esas funciones de distribución) que podemos pasar al decoder para que genere una salida. Al ser un muestreo de una variable aleatoria $n$-dimensional no podemos asegurar que vayamos a obtener siempre la misma salida, sino un vector que, con mayor o menor probabilidad, produce una salida con pequeñas variaciones.
Siguiendo la interpretación habitual de las distribuciones normales, la media controla el centro aproximado en el que una entrada debe ser codificada, mientras que la desviación controla cuánto se puede desviar de ese centro en cualquiera de sus muestreos. Como las representaciones intermedias que genera el encoder se toman al azar dentro de esta región (la distribución de probabilidad de la normal), el decoder debe aprender no solo que el punto central se corresponde con una representación de la entrada, sino que toda la región debe producir salidas que deben tener un error bajo de reproducción, facilitando la continuidad del espacio latente.
Cuando entrenamos este modelo de forma repetida sobre una buena cantidad de entradas, el decoder va asociando áreas completas, y no solo puntos aislados como ocurría en los autoencoders tradicionales, a ligeras variantes de la misma salida, generando un espacio latente mucho más suave e interpolado que es capaz de producir nuevas salidas que comparten propiedades de entradas diversas. Como no hay restricciones en los valores de $\mu$ y $\sigma$ que el encoder puede producir, podemos aprender a generar valores distintos para las distintas clases. Si se toman las medias suficientemente lejos, estaremos seguros de que el solapamiento entre clases es mínimo, y las regiones intermedias serán verdaderas interpolaciones de características de objetos esencialmente distintos. Si, adicionalmente, se toman desviaciones pequeñas, entonces la reconstrucción de entradas reales tendrá poco error, produciendo un reconstructor muy fiel ante entradas conocidas. En cada una de estas bolsas el objetivo sería disponer de codificaciones (representaciones latentes) que sean cercanas pero distintas entre sí. De esta forma, se favorece la interpolación del espacio y la construcción de nuevas muestras que compartirán muchas características con las muestras originales.

Comparación entre un autoencoder clásico y un VAE
La diferencia del modelo VAE con otros autoencoders es que podemos interpretar el espacio latente no como un espacio de codificación, sino como una distribución de probabilidad (porque no proporciona una codificación única, sino un conjunto de codificaciones que, con mayor o menor probabilidad, podrían ser el resultado del encoder), y esta interpretación también se traslada al espacio de salida por medio del decoder. En consecuencia, las funciones de pérdida habituales (las pérdidas de representación), que suelen venir dadas por (agrupaciones de) distancias entre las entradas y las salidas, no son adecuadas para medir el error que comete la red en su generación.
Con el fin de solucionar este problema, se introduce un factor nuevo en la función de pérdida, llamada KL-divergencia (Divergencia de Kullback-Leibler [5]), que, en vez de medir la distancia entre puntos, mide la diferencia existente entre dos distribuciones de probabilidad. Cuando una de estas distribuciones es una normal la KL-divergencia medirá cuánto se parece esta distribución normal a la distribución real que queremos aproximar.

KL-Divergencia aplicada a dos distribuciones de probabilidada
Una de las distribuciones está clara, es la suma de distribuciones normales cuyos parámetros forman el espacio latente de nuestra red, pero ¿cuál es la otra distribución? El objetivo sería medir la distancia con respecto a "la distribución ideal" que genera las salidas que nos gustaría obtener, pero esta distribución no la conocemos (es precisamente la que nos gustaría obtener con este modelo), así que parece un problema sin salida. Sin embargo, podemos intentar imponer condiciones para que nuestra red sea capaz de aprender una distribución que sea suficientemente buena.
Por ejemplo, podríamos suponer que la distribución ideal estaría, en general, centrada en el origen y de desviación 1, y entonces la KL-divergencia daría como resultado:
$$KL= \sum_{i=1}^n \sigma_i^2 + \mu_i^2 - log(\sigma_i)-1$$
Pero si solo consideramos este término y no imponemos condiciones adicionales, la red aprenderá a situar todas las representaciones alrededor del origen (aproximándose a la distribución objetivo) y será incapaz de diferenciar las diversas clases que podemos encontrar dentro de nuestro conjunto de entrenamiento (todas las representaciones latentes estarían demasiado cerca entre sí como para poder agruparlas en bolsas diferenciadas). Así pues, hemos de considerar también durante el entrenamiento una información adicional que el decodificador debería aprender: debe dar como salida el mismo dato que recibe como entrada, y para eso podemos usar la función de pérdida habitual. Por tanto, una opción es que nuestra nueva función de pérdida considere ambos hechos simultáneamente:
$$Loss'(x)= Loss(x,x')+ KL$$
donde $x$ es el dato de entrada, $x'$ es la salida producida por el decoder, $Loss$ es la función de pérdida habitual (por ejemplo, distancia euclídea entre $x$ y $x'$), y $KL$ es la KL-divergencia calculada anteriormente (y que depende de la representación latente aprendida por el encoder por medio de los parámetros de las normales).
De esta forma, conseguimos que la red mantenga cerca las bolsas de representación entre sí, facilitando la continuidad del espacio de representación, a la vez que intentará diferenciar el contenido de una bolsa de otra, asegurando el aprendizaje de patrones.

Espacio Latente obtenido por un VAE
Con todos los componentes anteriores hay que entrenar la red con los datos de que disponemos (realmente, los datos se usan para el entrenamiento de la red completa pero, posteriormente, para usar la red como generador, haremos uso únicamente de la parte decoder), y nos encontramos con un nuevo problema que puede ser resuelto pero excede los objetivos marcados en esta entrada, y es que los métodos tradicionales de entrenamiento de redes trabajan con variantes del back-propagation que necesitan derivar la función de pérdida [2]. En nuestro caso, disponemos de una función de pérdida en donde interviene una distancia entre distribuciones, por lo que su derivada no es tan evidente, pero se puede llevar a cabo gracias a un mecanismo que se conoce como reparametrization trick, y que será nuestro centro de atención en una entrada posterior. El objetivo de esta entrada ha sido intentar explicar de una forma intuitiva y poco técnica las características que hacen que VAE se comporte de forma sorprendentemente bien en las tareas generativas en las que otros modelos fallan.
Referencias
[1] Kingma, D.P.; Welling, M. Auto-encoding variational bayes. arXiv preprint arXiv:1312.6114, 2013.
[2] Rezende, D.J.; Mohamed, S.; Wierstra, D. Stochastic backpropagation and approximate inference in deep generative models. arXiv preprint arXiv:1401.4082, 2014.
[3] Doersch, C. Tutorial on variational autoencoders. arXiv preprint arXiv:1606.05908, 2016.
[4] Goodfellow, I.; Bengio, Y.; Courville, A. Deep Learning. MIT Press. 2016. ISBN 978-0262035613
[5] Kullback, S.; Leibler, R.A. On information and sufficiency. Annals of Mathematical Statistics. 22 (1): 79–86, 1951. doi:10.1214/aoms/1177729694.