El aprendizaje por transferencia es una técnica poderosa en el campo del aprendizaje profundo que permite utilizar modelos preentrenados en grandes conjuntos de datos para resolver problemas específicos con menos datos y tiempo de entrenamiento. En este módulo, aprenderemos cómo aplicar el aprendizaje por transferencia utilizando PyTorch.
¿Qué es el Aprendizaje por Transferencia?
El aprendizaje por transferencia implica tomar un modelo que ha sido preentrenado en una tarea grande y general (como la clasificación de imágenes en el conjunto de datos ImageNet) y adaptarlo a una tarea específica. Los beneficios incluyen:
- Reducción del tiempo de entrenamiento: Aprovechamos el conocimiento ya adquirido por el modelo.
- Mejora del rendimiento: Los modelos preentrenados suelen tener una mejor capacidad de generalización.
- Menor necesidad de datos: Podemos obtener buenos resultados con menos datos de entrenamiento.
Pasos para Implementar el Aprendizaje por Transferencia
- Seleccionar un modelo preentrenado: PyTorch proporciona varios modelos preentrenados a través de la biblioteca
torchvision.models
. - Modificar la última capa: Adaptar la última capa del modelo para que coincida con el número de clases de nuestro problema específico.
- Congelar capas: Opcionalmente, congelar algunas capas del modelo para evitar que se actualicen durante el entrenamiento.
- Entrenar el modelo: Entrenar el modelo en nuestro conjunto de datos específico.
Ejemplo Práctico: Clasificación de Imágenes con ResNet
Paso 1: Importar Librerías y Cargar el Modelo Preentrenado
import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, models, transforms # Configuración del dispositivo device = torch.device("cuda" if torch.cuda.is_available() else "cpu") # Cargar el modelo preentrenado ResNet18 model = models.resnet18(pretrained=True) model = model.to(device)
Paso 2: Modificar la Última Capa
La red ResNet18 tiene una capa totalmente conectada (fc
) al final que produce 1000 salidas (para las 1000 clases de ImageNet). Necesitamos modificar esta capa para que coincida con el número de clases de nuestro problema.
num_classes = 10 # Ejemplo: 10 clases model.fc = nn.Linear(model.fc.in_features, num_classes) model = model.to(device)
Paso 3: Congelar Capas (Opcional)
Podemos congelar las capas iniciales del modelo para evitar que se actualicen durante el entrenamiento. Esto es útil si queremos aprovechar al máximo el conocimiento preentrenado.
for param in model.parameters(): param.requires_grad = False # Solo entrenar la última capa for param in model.fc.parameters(): param.requires_grad = True
Paso 4: Preparar el Conjunto de Datos y el Bucle de Entrenamiento
# Transformaciones de datos data_transforms = { 'train': transforms.Compose([ transforms.RandomResizedCrop(224), transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]), 'val': transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]), } data_dir = 'data/hymenoptera_data' image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x), data_transforms[x]) for x in ['train', 'val']} dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=4, shuffle=True, num_workers=4) for x in ['train', 'val']} dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'val']} class_names = image_datasets['train'].classes # Definir la función de pérdida y el optimizador criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(model.fc.parameters(), lr=0.001, momentum=0.9)
Paso 5: Entrenar y Evaluar el Modelo
def train_model(model, criterion, optimizer, num_epochs=25): for epoch in range(num_epochs): print(f'Epoch {epoch}/{num_epochs - 1}') print('-' * 10) for phase in ['train', 'val']: if phase == 'train': model.train() else: model.eval() running_loss = 0.0 running_corrects = 0 for inputs, labels in dataloaders[phase]: inputs = inputs.to(device) labels = labels.to(device) optimizer.zero_grad() with torch.set_grad_enabled(phase == 'train'): outputs = model(inputs) _, preds = torch.max(outputs, 1) loss = criterion(outputs, labels) if phase == 'train': loss.backward() optimizer.step() running_loss += loss.item() * inputs.size(0) running_corrects += torch.sum(preds == labels.data) epoch_loss = running_loss / dataset_sizes[phase] epoch_acc = running_corrects.double() / dataset_sizes[phase] print(f'{phase} Loss: {epoch_loss:.4f} Acc: {epoch_acc:.4f}') return model model = train_model(model, criterion, optimizer, num_epochs=25)
Ejercicio Práctico
Ejercicio 1: Aplicar Aprendizaje por Transferencia con VGG16
- Cargar el modelo VGG16 preentrenado.
- Modificar la última capa para un problema de clasificación con 5 clases.
- Congelar todas las capas excepto la última.
- Entrenar el modelo en un conjunto de datos de su elección.
Solución
# Cargar el modelo preentrenado VGG16 model_vgg = models.vgg16(pretrained=True) model_vgg = model_vgg.to(device) # Modificar la última capa model_vgg.classifier[6] = nn.Linear(model_vgg.classifier[6].in_features, 5) model_vgg = model_vgg.to(device) # Congelar todas las capas excepto la última for param in model_vgg.features.parameters(): param.requires_grad = False # Definir la función de pérdida y el optimizador criterion = nn.CrossEntropyLoss() optimizer = optim.SGD(model_vgg.classifier[6].parameters(), lr=0.001, momentum=0.9) # Entrenar el modelo model_vgg = train_model(model_vgg, criterion, optimizer, num_epochs=25)
Conclusión
En este módulo, hemos aprendido cómo aplicar el aprendizaje por transferencia utilizando modelos preentrenados en PyTorch. Esta técnica nos permite aprovechar modelos robustos y bien entrenados para resolver problemas específicos de manera eficiente. Hemos cubierto los pasos clave, desde la selección y modificación del modelo hasta el entrenamiento y evaluación. Con esta base, puedes explorar y aplicar el aprendizaje por transferencia a una variedad de problemas en el campo del aprendizaje profundo.
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