Cómo dibujar un múltiple de un autoencoder variacional en Keras

Gracias por el A2A.

Hay una manera fácil que las personas suelen usar con las visualizaciones, y una forma un poco más compleja que es más “correcta”. Me atendré al camino fácil 🙂

Asumiré que tenemos un VAE entrenado. El muestreo del modelo generativo es sencillo en este caso:

[matemáticas] z ^ l \ sim p (z) [/ matemáticas]

[matemáticas] x ^ l \ sim p (x | z) [/ matemáticas]

Para un VAE estándar, [math] p (z) = \ mathcal {N} (z; 0, I) [/ math]. Suponiendo que tiene un backend TensorFlow y que su modelo tiene un método llamado decodificación, que debería devolver los parámetros de la distribución de [math] x | z [/ math].

z_samp = np.random.normal (size = (n_samps, dim_z))
params_x = model.decode (z_samp)

Luego, simplemente puede generar muestras de [matemáticas] x [/ matemáticas] a partir de la distribución apropiada utilizando los parámetros, o trazar la media / modo si lo prefiere. Entrené un VAE (TensorFlow) en MNIST, y estas son algunas muestras del modelo entrenado (realmente no optimizó ningún hiperparámetro, por lo que probablemente podría hacerlo mejor que eso):

Eso es generalmente cierto para el muestreo de un VAE. Si quieres dibujar una variedad, eso es un poco más complicado. La manera fácil es hacer que su espacio latente sea bidimensional (lo que, por supuesto, reduce la calidad de las muestras. Las anteriores se toman de un espacio latente de 10 días, y eso también es un poco pequeño). En ese caso, en lugar de muestrear [math] z [/ math] de la distribución anterior, simplemente cuadrícula un espacio de 2-d. Una cosa para recordar es que un hipercubo espaciado linealmente no corresponde a la misma cuadrícula en el espacio latente con una distribución gaussiana. Para remediar esto, podemos pasar nuestras muestras [matemáticas] z [/ matemáticas] a través del CDF inverso de la distribución gaussiana (las personas generalmente se saltan esto, pero es más “correcto”). Al poner todo junto y agregar un poco de pelusa para el trazado de la cuadrícula, obtenemos:

nx = ny = 15
x_values ​​= np.linspace (.05, .95, nx)
y_values ​​= np.linspace (.05, .95, ny)

lienzo = np.empty ((28 * ny, 28 * nx))
para i, yi en enumerate (x_values):
para j, xi en enumerate (y_values):
z_mu = np.array ([[norm.ppf (xi), norm.ppf (yi)]]). astype (‘float32’)
x_mean = model.decode_new (z_mu)
lienzo [(nx-i-1) * 28: (nx-i) * 28, j * 28: (j + 1) * 28] = x_mean [0] .reshape (28, 28)

plt.figure (figsize = (8, 10))
plt.imshow (lienzo, origen = “superior”, cmap = “gris”)
plt.tight_layout ()

Tomé las cosas de la trama de la excelente publicación de blog de Jan Hendrik Metzen. El VAE es mío, y mapeo a través del cdf inverso (que omitió) resultados tan diferentes. Cuando ejecuto esto con mi VAE obtengo la siguiente cuadrícula:

Bastante genial eh? De hecho, esperaba dígitos de menor calidad usando solo un espacio latente 2d. Si su dominio es más complejo que MNIST y requiere más de 2d latentes, se vuelve un poco complicado. Una cosa que puede hacer es identificar las dos dimensiones latentes con la desviación estándar empírica más alta (es decir, codificar todos sus datos de entrenamiento y luego medir la desviación estándar de cada dimensión latente). Luego, podría congelar todos los dims latentes a 0, y solo cuadricular los dos con la varianza más alta. Esto no es lo mismo que dibujar la variedad completa, pero es una forma de hacerlo.