En este módulo, aprenderemos a construir una Red Neuronal Convolucional (CNN) desde cero utilizando PyTorch. Las CNNs son especialmente efectivas para tareas de visión por computadora, como la clasificación de imágenes. Vamos a desglosar el proceso en pasos claros y detallados.
Objetivos del Módulo
- Comprender la arquitectura básica de una CNN.
- Implementar una CNN simple en PyTorch.
- Entrenar la CNN con un conjunto de datos de imágenes.
- Evaluar el rendimiento de la CNN.
- Arquitectura Básica de una CNN
Una CNN típica consta de las siguientes capas:
- Capas Convolucionales: Aplican filtros para extraer características de la imagen.
- Capas de Pooling: Reducen la dimensionalidad de las características extraídas.
- Capas Completamente Conectadas: Realizan la clasificación final basándose en las características extraídas.
Ejemplo de Arquitectura
- Entrada: Imagen de 32x32x3 (ancho x alto x canales de color).
- Capa Convolucional 1: 32 filtros de 3x3, stride=1, padding=1.
- Capa de Pooling 1: MaxPooling de 2x2.
- Capa Convolucional 2: 64 filtros de 3x3, stride=1, padding=1.
- Capa de Pooling 2: MaxPooling de 2x2.
- Capa Completamente Conectada: 512 neuronas.
- Salida: 10 neuronas (para clasificación en 10 clases).
- Implementación de una CNN en PyTorch
Paso 1: Importar Librerías Necesarias
import torch import torch.nn as nn import torch.optim as optim import torchvision import torchvision.transforms as transforms
Paso 2: Definir la Arquitectura de la CNN
class SimpleCNN(nn.Module): def __init__(self): super(SimpleCNN, self).__init__() self.conv1 = nn.Conv2d(in_channels=3, out_channels=32, kernel_size=3, stride=1, padding=1) self.pool = nn.MaxPool2d(kernel_size=2, stride=2, padding=0) self.conv2 = nn.Conv2d(in_channels=32, out_channels=64, kernel_size=3, stride=1, padding=1) self.fc1 = nn.Linear(in_features=64 * 8 * 8, out_features=512) self.fc2 = nn.Linear(in_features=512, out_features=10) def forward(self, x): x = self.pool(F.relu(self.conv1(x))) x = self.pool(F.relu(self.conv2(x))) x = x.view(-1, 64 * 8 * 8) # Aplanar el tensor x = F.relu(self.fc1(x)) x = self.fc2(x) return x
Paso 3: Preparar el Conjunto de Datos
Usaremos el conjunto de datos CIFAR-10 para este ejemplo.
transform = transforms.Compose( [transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))]) trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform) trainloader = torch.utils.data.DataLoader(trainset, batch_size=4, shuffle=True, num_workers=2) testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform) testloader = torch.utils.data.DataLoader(testset, batch_size=4, shuffle=False, num_workers=2) classes = ('plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')
Paso 4: Definir la Función de Pérdida y el Optimizador
net = SimpleCNN() criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)
Paso 5: Entrenar la CNN
for epoch in range(2): # número de épocas running_loss = 0.0 for i, data in enumerate(trainloader, 0): inputs, labels = data optimizer.zero_grad() outputs = net(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step() running_loss += loss.item() if i % 2000 == 1999: # imprimir cada 2000 mini-batches print(f'[Epoch {epoch + 1}, Batch {i + 1}] loss: {running_loss / 2000:.3f}') running_loss = 0.0 print('Finished Training')
Paso 6: Evaluar la CNN
correct = 0 total = 0 with torch.no_grad(): for data in testloader: images, labels = data outputs = net(images) _, predicted = torch.max(outputs.data, 1) total += labels.size(0) correct += (predicted == labels).sum().item() print(f'Accuracy of the network on the 10000 test images: {100 * correct / total} %')
Ejercicio Práctico
Ejercicio 1: Modificar la Arquitectura
Modifica la arquitectura de la CNN para agregar una tercera capa convolucional con 128 filtros y una tercera capa de pooling. Entrena y evalúa la nueva red.
Solución
class ModifiedCNN(nn.Module): def __init__(self): super(ModifiedCNN, self).__init__() self.conv1 = nn.Conv2d(in_channels=3, out_channels=32, kernel_size=3, stride=1, padding=1) self.pool = nn.MaxPool2d(kernel_size=2, stride=2, padding=0) self.conv2 = nn.Conv2d(in_channels=32, out_channels=64, kernel_size=3, stride=1, padding=1) self.conv3 = nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3, stride=1, padding=1) self.fc1 = nn.Linear(in_features=128 * 4 * 4, out_features=512) self.fc2 = nn.Linear(in_features=512, out_features=10) def forward(self, x): x = self.pool(F.relu(self.conv1(x))) x = self.pool(F.relu(self.conv2(x))) x = self.pool(F.relu(self.conv3(x))) x = x.view(-1, 128 * 4 * 4) # Aplanar el tensor x = F.relu(self.fc1(x)) x = self.fc2(x) return x # Entrenamiento y evaluación se realizan de la misma manera que antes.
Conclusión
En este módulo, hemos aprendido a construir una CNN desde cero utilizando PyTorch. Hemos cubierto la arquitectura básica de una CNN, cómo implementarla, entrenarla y evaluarla. Además, hemos realizado un ejercicio práctico para modificar y mejorar la arquitectura de la red. En el próximo módulo, exploraremos el aprendizaje por transferencia y cómo utilizar modelos preentrenados para mejorar el rendimiento de nuestras redes neuronales.
PyTorch: De Principiante a Avanzado
Módulo 1: Introducción a PyTorch
- ¿Qué es PyTorch?
- Configuración del Entorno
- Operaciones Básicas con Tensores
- Autograd: Diferenciación Automática
Módulo 2: Construcción de Redes Neuronales
- Introducción a las Redes Neuronales
- Creación de una Red Neuronal Simple
- Funciones de Activación
- Funciones de Pérdida y Optimización
Módulo 3: Entrenamiento de Redes Neuronales
- Carga y Preprocesamiento de Datos
- Bucle de Entrenamiento
- Validación y Pruebas
- Guardar y Cargar Modelos
Módulo 4: Redes Neuronales Convolucionales (CNNs)
- Introducción a las CNNs
- Construcción de una CNN desde Cero
- Aprendizaje por Transferencia con Modelos Preentrenados
- Ajuste Fino de CNNs
Módulo 5: Redes Neuronales Recurrentes (RNNs)
- Introducción a las RNNs
- Construcción de una RNN desde Cero
- Redes de Memoria a Largo Plazo (LSTM)
- Unidades Recurrentes con Puerta (GRUs)
Módulo 6: Temas Avanzados
- Redes Generativas Antagónicas (GANs)
- Aprendizaje por Refuerzo con PyTorch
- Despliegue de Modelos PyTorch
- Optimización del Rendimiento