0% encontró este documento útil (0 votos)
20 vistas7 páginas

Codigo VAE

El documento describe la implementación de un Autoencoder Variacional (VAE) utilizando TensorFlow y Keras, que aprende a representar datos en un espacio latente y puede generar nuevas imágenes. Se detallan las etapas de construcción del modelo, incluyendo el codificador y el decodificador, así como el proceso de entrenamiento y generación de imágenes. Finalmente, se incluye un ejemplo de cómo cargar y preparar datos, entrenar el modelo y visualizar las imágenes generadas.

Cargado por

Jorfel Adonay
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como TXT, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
20 vistas7 páginas

Codigo VAE

El documento describe la implementación de un Autoencoder Variacional (VAE) utilizando TensorFlow y Keras, que aprende a representar datos en un espacio latente y puede generar nuevas imágenes. Se detallan las etapas de construcción del modelo, incluyendo el codificador y el decodificador, así como el proceso de entrenamiento y generación de imágenes. Finalmente, se incluye un ejemplo de cómo cargar y preparar datos, entrenar el modelo y visualizar las imágenes generadas.

Cargado por

Jorfel Adonay
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como TXT, PDF, TXT o lee en línea desde Scribd

¡Claro!

Este código implementa un Autoencoder Variacional (VAE), un tipo de red


neuronal que aprende una representación comprimida de los datos (espacio latente) y
luego puede generar nuevos datos similares.

Aquí te explico cada línea:

1. Importaciones de Librerías
Python

import numpy as np
import tensorflow as tf
import [Link] as plt
from tensorflow import keras
from [Link] import layers
import numpy as np: Importa la librería NumPy, que es fundamental para operaciones
numéricas, especialmente con arrays y matrices. Se usa para manejar los datos de
las imágenes.

import tensorflow as tf: Importa la librería TensorFlow, un framework de código


abierto para aprendizaje automático. Es el motor principal detrás de la
construcción y el entrenamiento de la red neuronal.

import [Link] as plt: Importa la librería Matplotlib, que se usa para


crear gráficos y visualizaciones. En este caso, para mostrar las imágenes
generadas.

from tensorflow import keras: Importa el módulo Keras de TensorFlow. Keras es una
API de alto nivel para construir y entrenar modelos de aprendizaje profundo de
forma más sencilla.

from [Link] import layers: Importa el submódulo layers de Keras, que


contiene las diferentes capas predefinidas que se usan para construir las redes
neuronales (como capas convolucionales, densas, etc.).

2. Parámetros del VAE


Python

latent_dim = 2
latent_dim = 2: Define la dimensión del espacio latente. Esto significa que cada
imagen original (de 28x28 píxeles) se comprimirá en un vector de 2 números. Un
espacio latente de baja dimensión es bueno para visualizar y manipular las
representaciones aprendidas.

3. El Codificador (Encoder)
El codificador toma una imagen y la convierte en dos vectores que describen su
distribución en el espacio latente: la media y la varianza logarítmica.

Python

encoder_inputs = [Link](shape=(28, 28, 1))


x = layers.Conv2D(32, 3, activation="relu", strides=2, padding="same")
(encoder_inputs)
x = layers.Conv2D(64, 3, activation="relu", strides=2, padding="same")(x)
x = [Link]()(x)
x = [Link](16, activation="relu")(x)
z_mean = [Link](latent_dim, name="z_mean")(x)
z_log_var = [Link](latent_dim, name="z_log_var")(x)
encoder = [Link](encoder_inputs, [z_mean, z_log_var], name="encoder")
encoder_inputs = [Link](shape=(28, 28, 1)): Define la capa de entrada del
codificador. Espera imágenes de 28x28 píxeles con 1 canal (escala de grises).

x = layers.Conv2D(32, 3, activation="relu", strides=2, padding="same")


(encoder_inputs): Primera capa convolucional (Conv2D). Aplica 32 filtros de 3x3,
usa la función de activación ReLU, reduce la resolución a la mitad (strides=2) y
añade relleno para mantener el tamaño (padding="same").

x = layers.Conv2D(64, 3, activation="relu", strides=2, padding="same")(x): Segunda


capa convolucional similar, pero con 64 filtros, reduciendo la resolución de nuevo.

x = [Link]()(x): Convierte la salida 3D de las capas convolucionales en un


vector 1D plano. Esto es necesario para conectarlo a las capas densas.

x = [Link](16, activation="relu")(x): Una capa densa (totalmente conectada)


con 16 neuronas y activación ReLU. Actúa como una capa intermedia para procesar las
características extraídas.

z_mean = [Link](latent_dim, name="z_mean")(x): Capa densa que genera el


vector de medias (z_mean) para la distribución latente. Su tamaño es igual a
latent_dim.

z_log_var = [Link](latent_dim, name="z_log_var")(x): Capa densa que genera el


vector de logaritmo de las varianzas (z_log_var) para la distribución latente.
También de tamaño latent_dim. Se usa el logaritmo de la varianza para asegurar que
la varianza sea siempre positiva y por estabilidad numérica.

encoder = [Link](encoder_inputs, [z_mean, z_log_var], name="encoder"): Crea el


modelo del codificador. Toma encoder_inputs como entrada y devuelve los dos
vectores: z_mean y z_log_var.

4. El Decodificador (Decoder)
El decodificador toma un vector del espacio latente y lo convierte de nuevo en una
imagen.

Python

latent_inputs = [Link](shape=(latent_dim,))
x = [Link](7 * 7 * 64, activation="relu")(latent_inputs)
x = [Link]((7, 7, 64))(x)
x = layers.Conv2DTranspose(64, 3, activation="relu", strides=2, padding="same")(x)
x = layers.Conv2DTranspose(32, 3, activation="relu", strides=2, padding="same")(x)
decoder_outputs = layers.Conv2DTranspose(1, 3, activation="sigmoid",
padding="same")(x)
decoder = [Link](latent_inputs, decoder_outputs, name="decoder")
latent_inputs = [Link](shape=(latent_dim,)): Define la capa de entrada del
decodificador. Espera un vector del tamaño latent_dim.

x = [Link](7 * 7 * 64, activation="relu")(latent_inputs): Una capa densa que


expande el vector latente a un tamaño que luego se puede reformar en una cuadrícula
(7x7x64).

x = [Link]((7, 7, 64))(x): Reforma el vector 1D en una cuadrícula 3D de 7x7


con 64 canales. Este es el tamaño al que las capas convolucionales inversas pueden
empezar a reconstruir la imagen.

x = layers.Conv2DTranspose(64, 3, activation="relu", strides=2, padding="same")(x):


Primera capa convolucional transpuesta (Conv2DTranspose). Es el inverso de una
convolución, aumentando la resolución (desconvolución). Usa 64 filtros, tamaño de
filtro 3x3, strides=2 para duplicar la resolución y padding="same".
x = layers.Conv2DTranspose(32, 3, activation="relu", strides=2, padding="same")(x):
Segunda capa convolucional transpuesta similar, pero con 32 filtros, aumentando la
resolución de nuevo.

decoder_outputs = layers.Conv2DTranspose(1, 3, activation="sigmoid",


padding="same")(x): Última capa convolucional transpuesta. Genera la imagen final
de 28x28x1 (1 canal para escala de grises). La activación sigmoid se usa porque las
imágenes están normalizadas entre 0 y 1.

decoder = [Link](latent_inputs, decoder_outputs, name="decoder"): Crea el


modelo del decodificador. Toma latent_inputs como entrada y devuelve la
decoder_outputs (la imagen reconstruida).

5. El Modelo VAE Completo


Esta clase combina el codificador y el decodificador, y define cómo se entrena el
modelo.

Python

class VAE([Link]):
def __init__(self, encoder, decoder, **kwargs):
super(VAE, self).__init__(**kwargs)
[Link] = encoder
[Link] = decoder

def train_step(self, data):


if isinstance(data, tuple):
data = data[0]
with [Link]() as tape:
z_mean, z_log_var = [Link](data)
z = [Link]((z_mean, z_log_var))
reconstruction = [Link](z)
reconstruction_loss = tf.reduce_mean(
[Link].binary_crossentropy(data, reconstruction)
)
reconstruction_loss *= 28 * 28
kl_loss = 1 + z_log_var - [Link](z_mean) - [Link](z_log_var)
kl_loss = tf.reduce_mean(kl_loss)
kl_loss *= -0.5
total_loss = reconstruction_loss + kl_loss
grads = [Link](total_loss, self.trainable_weights)
[Link].apply_gradients(zip(grads, self.trainable_weights))
return {
"loss": total_loss,
"reconstruction_loss": reconstruction_loss,
"kl_loss": kl_loss,
}

def call(self, data):


z_mean, z_log_var = [Link](data)
z = [Link]((z_mean, z_log_var))
return [Link](z)

def sampling(self, args):


z_mean, z_log_var = args
batch = [Link](z_mean)[0]
dim = [Link](z_mean)[1]
epsilon = [Link].random_normal(shape=(batch, dim))
return z_mean + [Link](0.5 * z_log_var) * epsilon
class VAE([Link]):: Define una nueva clase VAE que hereda de [Link], lo
que permite que se comporte como un modelo de Keras estándar.

def __init__(self, encoder, decoder, **kwargs):: El constructor de la clase. Recibe


los modelos encoder y decoder que definimos antes y los guarda como atributos.

def train_step(self, data):: Este método sobrescribe el train_step predeterminado


de Keras para definir el proceso de entrenamiento personalizado del VAE.

if isinstance(data, tuple): data = data[0]: Maneja el caso en que data podría ser
una tupla (común en datasets de Keras donde data y labels se pasan juntas).

with [Link]() as tape:: Inicia una cinta de gradientes. TensorFlow


registra todas las operaciones dentro de este bloque para calcular los gradientes
más tarde.

z_mean, z_log_var = [Link](data): Pasa los datos (imágenes) a través del


codificador para obtener la media y la varianza logarítmica.

z = [Link]((z_mean, z_log_var)): Llama al método sampling (explicado a


continuación) para obtener una muestra aleatoria del espacio latente. Esto es
crucial para la parte "variacional" del VAE.

reconstruction = [Link](z): Pasa la muestra latente a través del


decodificador para reconstruir la imagen.

reconstruction_loss = tf.reduce_mean(...): Calcula la pérdida de reconstrucción.


Compara la imagen original (data) con la imagen reconstruida (reconstruction)
usando la entropía cruzada binaria (adecuada para imágenes de 0 a 1).

reconstruction_loss *= 28 * 28: Escala la pérdida de reconstrucción por el número


de píxeles para que la pérdida sea por imagen, no por píxel.

kl_loss = 1 + z_log_var - [Link](z_mean) - [Link](z_log_var): Calcula la pérdida


KL (Kullback-Leibler). Esta es la parte "variacional". Mide qué tan cerca está la
distribución latente aprendida de una distribución normal estándar. Anima al
codificador a producir distribuciones latentes que sean fáciles de muestrear.

kl_loss = tf.reduce_mean(kl_loss): Calcula la media de la pérdida KL.

kl_loss *= -0.5: Ajusta la pérdida KL con un factor de -0.5 (parte de la


formulación de la pérdida ELBO en VAEs).

total_loss = reconstruction_loss + kl_loss: La pérdida total es la suma de la


pérdida de reconstrucción y la pérdida KL.

grads = [Link](total_loss, self.trainable_weights): Calcula los gradientes


de la pérdida total con respecto a todos los pesos entrenables del modelo.

[Link].apply_gradients(zip(grads, self.trainable_weights)): Aplica los


gradientes para actualizar los pesos del modelo, lo que lo entrena.

return {...}: Devuelve un diccionario con las diferentes pérdidas, útil para
monitorear el progreso del entrenamiento.

def call(self, data):: Este método define el comportamiento de "inferencia" del VAE
cuando se usa model(input_data). No se usa directamente durante el entrenamiento si
se sobrescribe train_step, pero es útil para la generación de imágenes.
Es similar a los primeros pasos de train_step: codifica la imagen, muestrea del
espacio latente y decodifica.

def sampling(self, args):: Este método implementa el "truco de reparametrización".

z_mean, z_log_var = args: Recibe la media y la varianza logarítmica del


codificador.

batch = [Link](z_mean)[0]: Obtiene el tamaño del lote (número de imágenes).

dim = [Link](z_mean)[1]: Obtiene la dimensión del espacio latente.

epsilon = [Link].random_normal(shape=(batch, dim)): Genera ruido


aleatorio (epsilon) de una distribución normal estándar. Esto permite que el modelo
aprenda a muestrear del espacio latente mientras los gradientes pueden fluir a
través de esta operación aleatoria.

return z_mean + [Link](0.5 * z_log_var) * epsilon: Aplica la fórmula del truco de


reparametrización para obtener una muestra z de la distribución gaussiana definida
por z_mean y z_log_var.

6. Carga y Preparación de Datos


Python

(x_train, _), (x_test, _) = [Link].load_data()


x_train = np.expand_dims(x_train, -1).astype("float32") / 255.0
x_test = np.expand_dims(x_test, -1).astype("float32") / 255.0
(x_train, _), (x_test, _) = [Link].load_data(): Carga el dataset
MNIST (imágenes de dígitos escritos a mano). Solo se necesitan las imágenes de
entrenamiento y prueba (x_train, x_test), por eso se usa _ para ignorar las
etiquetas.

x_train = np.expand_dims(x_train, -1).astype("float32") / 255.0:

np.expand_dims(x_train, -1): Añade una dimensión al final de los datos de la imagen


(de 28x28 a 28x28x1), que es el formato que esperan las capas convolucionales
(altura, ancho, canales).

.astype("float32"): Convierte el tipo de datos a coma flotante de 32 bits, lo que


es común para redes neuronales.

/ 255.0: Normaliza los valores de los píxeles de 0-255 a 0-1. Esto ayuda a la red a
aprender de manera más efectiva.

x_test = np.expand_dims(x_test, -1).astype("float32") / 255.0: Realiza las mismas


operaciones de preprocesamiento para el conjunto de datos de prueba.

7. Entrenamiento del VAE


Python

vae = VAE(encoder, decoder)


[Link](optimizer=[Link]())
[Link](x_train, epochs=30, batch_size=128)
vae = VAE(encoder, decoder): Crea una instancia de la clase VAE que definimos,
pasándole los modelos de codificador y decodificador.

[Link](optimizer=[Link]()): Compila el modelo. Se especifica el


optimizador, en este caso Adam, que ajusta los pesos del modelo durante el
entrenamiento. No se especifica una función de pérdida aquí porque ya la definimos
dentro del train_step personalizado.

[Link](x_train, epochs=30, batch_size=128): Entrena el modelo.

x_train: Los datos de entrenamiento.

epochs=30: El número de veces que el modelo verá todo el conjunto de datos de


entrenamiento.

batch_size=128: El número de muestras que se procesan antes de que se actualicen


los pesos del modelo.

8. Generación de Nuevas Imágenes


Después de entrenar el VAE, podemos usar el decodificador para generar nuevas
imágenes a partir de muestras aleatorias del espacio latente.

Python

n = 10
digit_size = 28
figure = [Link]((digit_size * n, digit_size * n))
# Sample random vectors from a normal distribution
z_sample = [Link](size=(n * n, latent_dim))
# Decode the vectors into images
x_decoded = [Link](z_sample)
# Reshape the images and combine them into a grid
for i in range(n):
for j in range(n):
digit = x_decoded[i * n + j].reshape(digit_size, digit_size)
figure[i * digit_size : (i + 1) * digit_size,
j * digit_size : (j + 1) * digit_size] = digit
# Plot the grid of images
[Link](figsize=(10, 10))
[Link](figure, cmap="Greys_r")
[Link]("off")
[Link]()
n = 10: Define el número de filas y columnas para la cuadrícula de imágenes
generadas (10x10).

digit_size = 28: El tamaño de cada dígito (28x28 píxeles).

figure = [Link]((digit_size * n, digit_size * n)): Crea un array NumPy vacío que


será la cuadrícula donde se colocarán las imágenes generadas. Su tamaño será
(28*10)x(28*10) = 280x280.

z_sample = [Link](size=(n * n, latent_dim)): Genera vectores aleatorios


(z_sample) del espacio latente. Estos vectores provienen de una distribución normal
estándar, ya que el VAE está entrenado para mapear el espacio latente a una normal
estándar. Se generan n*n (100) vectores.

x_decoded = [Link](z_sample): Pasa los vectores latentes generados


aleatoriamente a través del decodificador para convertirlos en imágenes.

for i in range(n): for j in range(n):: Bucle anidado para recorrer la cuadrícula de


10x10.

digit = x_decoded[i * n + j].reshape(digit_size, digit_size): Toma una imagen


decodificada, la reforma a su tamaño original de 28x28.
figure[i * digit_size : (i + 1) * digit_size, j * digit_size : (j + 1) *
digit_size] = digit: Coloca el dígito reconstruido en la posición correcta dentro
de la cuadrícula figure.

[Link](figsize=(10, 10)): Crea una figura para la gráfica con un tamaño de


10x10 pulgadas.

[Link](figure, cmap="Greys_r"): Muestra la cuadrícula de imágenes generadas.


cmap="Greys_r" invierte la escala de grises para que el fondo sea negro y los
dígitos blancos.

[Link]("off"): Desactiva los ejes de la gráfica para mostrar solo la imagen.

[Link](): Muestra la gráfica.

En resumen, este código construye un VAE que aprende a comprimir imágenes de


dígitos en un espacio latente bidimensional y luego a generar nuevos dígitos
"creativos" a partir de ese espacio.

También podría gustarte