Introducción
En esta sección, aprenderemos a crear una Red Generativa Adversarial (GAN) para la generación de imágenes. Las GANs son un tipo de red neuronal que consta de dos sub-redes: el generador y el discriminador. Estas redes compiten entre sí en un juego de suma cero, donde el generador intenta crear imágenes que parezcan reales y el discriminador intenta distinguir entre imágenes reales y generadas.
Objetivos
- Comprender la arquitectura de una GAN.
- Implementar una GAN básica para la generación de imágenes.
- Entrenar la GAN y evaluar su rendimiento.
Arquitectura de una GAN
Una GAN consta de dos componentes principales:
- Generador (G): Toma un vector de ruido como entrada y genera una imagen.
- Discriminador (D): Toma una imagen como entrada y predice si es real o generada.
Diagrama de una GAN
Vector de Ruido (z) --> Generador (G) --> Imagen Generada (G(z)) Imagen Real (x) --> Discriminador (D) --> Probabilidad de ser Real (D(x)) Imagen Generada (G(z)) --> Discriminador (D) --> Probabilidad de ser Real (D(G(z)))
Implementación de una GAN
Paso 1: Importar las Librerías Necesarias
import torch import torch.nn as nn import torch.optim as optim import torchvision.datasets as dsets import torchvision.transforms as transforms from torch.utils.data import DataLoader import matplotlib.pyplot as plt
Paso 2: Definir el Generador
class Generator(nn.Module): def __init__(self, input_size, hidden_size, output_size): super(Generator, self).__init__() self.main = nn.Sequential( nn.Linear(input_size, hidden_size), nn.ReLU(True), nn.Linear(hidden_size, hidden_size), nn.ReLU(True), nn.Linear(hidden_size, output_size), nn.Tanh() ) def forward(self, x): return self.main(x)
Paso 3: Definir el Discriminador
class Discriminator(nn.Module): def __init__(self, input_size, hidden_size, output_size): super(Discriminator, self).__init__() self.main = nn.Sequential( nn.Linear(input_size, hidden_size), nn.LeakyReLU(0.2, inplace=True), nn.Linear(hidden_size, hidden_size), nn.LeakyReLU(0.2, inplace=True), nn.Linear(hidden_size, output_size), nn.Sigmoid() ) def forward(self, x): return self.main(x)
Paso 4: Configurar el Entrenamiento
# Hiperparámetros batch_size = 100 learning_rate = 0.0002 num_epochs = 100 input_size = 784 # Para imágenes de 28x28 hidden_size = 256 latent_size = 64 # Cargar el dataset MNIST transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize(mean=(0.5,), std=(0.5,)) ]) mnist = dsets.MNIST(root='./data', train=True, transform=transform, download=True) data_loader = DataLoader(dataset=mnist, batch_size=batch_size, shuffle=True) # Crear las redes G = Generator(latent_size, hidden_size, input_size) D = Discriminator(input_size, hidden_size, 1) # Configurar los optimizadores criterion = nn.BCELoss() optimizerD = optim.Adam(D.parameters(), lr=learning_rate) optimizerG = optim.Adam(G.parameters(), lr=learning_rate)
Paso 5: Entrenar la GAN
for epoch in range(num_epochs): for i, (images, _) in enumerate(data_loader): # Preparar datos reales y etiquetas images = images.view(batch_size, -1) real_labels = torch.ones(batch_size, 1) fake_labels = torch.zeros(batch_size, 1) # Entrenar el discriminador outputs = D(images) d_loss_real = criterion(outputs, real_labels) real_score = outputs z = torch.randn(batch_size, latent_size) fake_images = G(z) outputs = D(fake_images) d_loss_fake = criterion(outputs, fake_labels) fake_score = outputs d_loss = d_loss_real + d_loss_fake optimizerD.zero_grad() d_loss.backward() optimizerD.step() # Entrenar el generador z = torch.randn(batch_size, latent_size) fake_images = G(z) outputs = D(fake_images) g_loss = criterion(outputs, real_labels) optimizerG.zero_grad() g_loss.backward() optimizerG.step() print(f'Epoch [{epoch+1}/{num_epochs}], d_loss: {d_loss.item():.4f}, g_loss: {g_loss.item():.4f}, D(x): {real_score.mean().item():.2f}, D(G(z)): {fake_score.mean().item():.2f}')
Paso 6: Generar y Visualizar Imágenes
# Generar imágenes después del entrenamiento z = torch.randn(batch_size, latent_size) fake_images = G(z) fake_images = fake_images.view(fake_images.size(0), 1, 28, 28) fake_images = fake_images.data # Visualizar algunas imágenes generadas for i in range(6): plt.subplot(2, 3, i+1) plt.imshow(fake_images[i][0], cmap='gray') plt.show()
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 esto afecta la calidad de las imágenes generadas.
Ejercicio 2: Entrenar la GAN con un Dataset Diferente
Entrena la GAN utilizando un dataset diferente, como CIFAR-10. Asegúrate de ajustar los tamaños de entrada y salida en consecuencia.
Soluciones
Solución al Ejercicio 1
class Generator(nn.Module): def __init__(self, input_size, hidden_size, output_size): super(Generator, self).__init__() self.main = nn.Sequential( nn.Linear(input_size, hidden_size), nn.ReLU(True), nn.Linear(hidden_size, hidden_size), nn.ReLU(True), nn.Linear(hidden_size, hidden_size), nn.ReLU(True), nn.Linear(hidden_size, output_size), nn.Tanh() ) def forward(self, x): return self.main(x)
Solución al Ejercicio 2
# Cargar el dataset CIFAR-10 transform = transforms.Compose([ transforms.ToTensor(), transforms.Normalize(mean=(0.5, 0.5, 0.5), std=(0.5, 0.5, 0.5)) ]) cifar10 = dsets.CIFAR10(root='./data', train=True, transform=transform, download=True) data_loader = DataLoader(dataset=cifar10, batch_size=batch_size, shuffle=True) # Ajustar los tamaños de entrada y salida input_size = 3072 # Para imágenes de 32x32x3 output_size = 3072
Conclusión
En esta sección, hemos aprendido a crear y entrenar una GAN para la generación de imágenes. Hemos explorado la arquitectura básica de una GAN y cómo implementar tanto el generador como el discriminador. Además, hemos realizado ejercicios prácticos para modificar y mejorar la GAN. Con estos conocimientos, estás preparado para explorar aplicaciones más avanzadas y personalizadas de las GANs en tus propios proyectos.
Curso de Deep Learning
Módulo 1: Introducción a Deep Learning
- ¿Qué es Deep Learning?
- Historia y evolución del Deep Learning
- Aplicaciones de Deep Learning
- Conceptos básicos de redes neuronales
Módulo 2: Fundamentos de Redes Neuronales
- Perceptrón y Perceptrón Multicapa
- Función de activación
- Propagación hacia adelante y hacia atrás
- Optimización y función de pérdida
Módulo 3: Redes Neuronales Convolucionales (CNN)
- Introducción a las CNN
- Capas convolucionales y de pooling
- Arquitecturas populares de CNN
- Aplicaciones de CNN en reconocimiento de imágenes
Módulo 4: Redes Neuronales Recurrentes (RNN)
- Introducción a las RNN
- LSTM y GRU
- Aplicaciones de RNN en procesamiento del lenguaje natural
- Secuencias y series temporales
Módulo 5: Técnicas Avanzadas en Deep Learning
- Redes Generativas Adversariales (GAN)
- Autoencoders
- Transfer Learning
- Regularización y técnicas de mejora
Módulo 6: Herramientas y Frameworks
- Introducción a TensorFlow
- Introducción a PyTorch
- Comparación de frameworks
- Entornos de desarrollo y recursos adicionales
Módulo 7: Proyectos Prácticos
- Clasificación de imágenes con CNN
- Generación de texto con RNN
- Detección de anomalías con Autoencoders
- Creación de una GAN para generación de imágenes