Las Redes Generativas Adversariales (GAN, por sus siglas en inglés) son una clase de algoritmos de aprendizaje profundo que se utilizan para generar datos nuevos y realistas a partir de un conjunto de datos de entrenamiento. Fueron introducidas por Ian Goodfellow y sus colegas en 2014 y han revolucionado el campo de la inteligencia artificial generativa.

Conceptos Clave

  1. ¿Qué es una GAN?

Una GAN consiste en dos redes neuronales que compiten entre sí:

  • Generador (G): Intenta crear datos falsos que se asemejen a los datos reales.
  • Discriminador (D): Intenta distinguir entre los datos reales y los datos generados por el generador.

  1. Funcionamiento de una GAN

El proceso de entrenamiento de una GAN se puede resumir en los siguientes pasos:

  1. Generador crea datos falsos: El generador toma un vector de ruido aleatorio y lo transforma en un dato falso.
  2. Discriminador evalúa: El discriminador recibe tanto datos reales como falsos y trata de clasificarlos correctamente.
  3. Retropropagación: Se calculan las pérdidas del generador y del discriminador, y se actualizan sus pesos mediante retropropagación.
  4. Iteración: Este proceso se repite hasta que el generador produce datos que el discriminador no puede distinguir de los datos reales.

  1. Función de Pérdida

La función de pérdida en una GAN se compone de dos partes:

  • Pérdida del Discriminador (D): Maximiza la probabilidad de clasificar correctamente los datos reales y falsos.
  • Pérdida del Generador (G): Minimiza la probabilidad de que el discriminador clasifique correctamente los datos falsos.

La función de pérdida combinada se puede expresar como: \[ \min_G \max_D V(D, G) = \mathbb{E}{x \sim p{data}(x)} [\log D(x)] + \mathbb{E}_{z \sim p_z(z)} [\log (1 - D(G(z)))] \]

Ejemplo Práctico: Implementación de una GAN en TensorFlow

A continuación, se presenta un ejemplo de implementación básica de una GAN utilizando TensorFlow.

Paso 1: Importar las Librerías Necesarias

import tensorflow as tf
from tensorflow.keras.layers import Dense, LeakyReLU, BatchNormalization, Reshape, Flatten
from tensorflow.keras.models import Sequential
import numpy as np
import matplotlib.pyplot as plt

Paso 2: Definir el Generador

def build_generator():
    model = Sequential()
    model.add(Dense(256, input_dim=100))
    model.add(LeakyReLU(alpha=0.2))
    model.add(BatchNormalization(momentum=0.8))
    model.add(Dense(512))
    model.add(LeakyReLU(alpha=0.2))
    model.add(BatchNormalization(momentum=0.8))
    model.add(Dense(1024))
    model.add(LeakyReLU(alpha=0.2))
    model.add(BatchNormalization(momentum=0.8))
    model.add(Dense(28 * 28 * 1, activation='tanh'))
    model.add(Reshape((28, 28, 1)))
    return model

Paso 3: Definir el Discriminador

def build_discriminator():
    model = Sequential()
    model.add(Flatten(input_shape=(28, 28, 1)))
    model.add(Dense(512))
    model.add(LeakyReLU(alpha=0.2))
    model.add(Dense(256))
    model.add(LeakyReLU(alpha=0.2))
    model.add(Dense(1, activation='sigmoid'))
    return model

Paso 4: Compilar el Modelo

def compile_gan(generator, discriminator):
    discriminator.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
    discriminator.trainable = False
    gan_input = tf.keras.Input(shape=(100,))
    generated_image = generator(gan_input)
    gan_output = discriminator(generated_image)
    gan = tf.keras.Model(gan_input, gan_output)
    gan.compile(loss='binary_crossentropy', optimizer='adam')
    return gan

Paso 5: Entrenar la GAN

def train_gan(generator, discriminator, gan, epochs=10000, batch_size=128):
    (X_train, _), (_, _) = tf.keras.datasets.mnist.load_data()
    X_train = X_train / 127.5 - 1.0
    X_train = np.expand_dims(X_train, axis=3)
    valid = np.ones((batch_size, 1))
    fake = np.zeros((batch_size, 1))

    for epoch in range(epochs):
        idx = np.random.randint(0, X_train.shape[0], batch_size)
        real_imgs = X_train[idx]
        noise = np.random.normal(0, 1, (batch_size, 100))
        gen_imgs = generator.predict(noise)
        d_loss_real = discriminator.train_on_batch(real_imgs, valid)
        d_loss_fake = discriminator.train_on_batch(gen_imgs, fake)
        d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)
        noise = np.random.normal(0, 1, (batch_size, 100))
        g_loss = gan.train_on_batch(noise, valid)

        if epoch % 1000 == 0:
            print(f"{epoch} [D loss: {d_loss[0]} | D accuracy: {100*d_loss[1]}] [G loss: {g_loss}]")
            save_imgs(generator, epoch)

def save_imgs(generator, epoch, examples=10, dim=(1, 10), figsize=(10, 1)):
    noise = np.random.normal(0, 1, (examples, 100))
    gen_imgs = generator.predict(noise)
    gen_imgs = 0.5 * gen_imgs + 0.5
    fig, axs = plt.subplots(dim[0], dim[1], figsize=figsize)
    cnt = 0
    for i in range(dim[0]):
        for j in range(dim[1]):
            axs[i, j].imshow(gen_imgs[cnt, :, :, 0], cmap='gray')
            axs[i, j].axis('off')
            cnt += 1
    plt.show()

Ejecución del Entrenamiento

generator = build_generator()
discriminator = build_discriminator()
gan = compile_gan(generator, discriminator)
train_gan(generator, discriminator, gan)

Ejercicio Práctico

Ejercicio 1: Modificar la Arquitectura del Generador

Modifica la arquitectura del generador para que tenga más capas y neuronas. Observa cómo afecta esto a la calidad de las imágenes generadas.

Ejercicio 2: Cambiar la Función de Activación

Prueba diferentes funciones de activación en el generador y el discriminador. ¿Cómo afecta esto al rendimiento de la GAN?

Ejercicio 3: Implementar una GAN para un Conjunto de Datos Diferente

Implementa una GAN para un conjunto de datos diferente, como CIFAR-10. Ajusta la arquitectura y los hiperparámetros según sea necesario.

Conclusión

En esta sección, hemos aprendido sobre las Redes Generativas Adversariales (GAN), su funcionamiento y cómo implementarlas utilizando TensorFlow. Las GAN son una herramienta poderosa para la generación de datos sintéticos y tienen aplicaciones en una amplia variedad de campos, desde la generación de imágenes hasta la creación de música y texto. Con la práctica y experimentación, se pueden lograr resultados sorprendentes y creativos.

En el siguiente módulo, exploraremos los Autoencoders, otra técnica avanzada en Deep Learning que se utiliza para la reducción de dimensionalidad y la detección de anomalías.

© Copyright 2024. Todos los derechos reservados