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 pltPaso 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 = 3072Conclusió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
