El ajuste fino (fine-tuning) de redes neuronales convolucionales (CNNs) es una técnica poderosa que permite reutilizar modelos preentrenados en nuevas tareas. En lugar de entrenar una red desde cero, lo cual puede ser costoso en términos de tiempo y recursos, el ajuste fino aprovecha el conocimiento adquirido por una red preentrenada en una tarea similar y lo adapta a una nueva tarea específica.

Conceptos Clave

  1. Modelos Preentrenados: Modelos que han sido entrenados en grandes conjuntos de datos, como ImageNet.
  2. Transferencia de Aprendizaje: Técnica que utiliza modelos preentrenados y los adapta a nuevas tareas.
  3. Congelación de Capas: Proceso de mantener ciertas capas del modelo preentrenado sin cambios durante el entrenamiento.
  4. Descongelación de Capas: Proceso de permitir que ciertas capas del modelo preentrenado se actualicen durante el entrenamiento.

Pasos para el Ajuste Fino de CNNs

  1. Selección del Modelo Preentrenado

PyTorch proporciona varios modelos preentrenados a través del módulo torchvision.models. Algunos de los modelos más comunes incluyen ResNet, VGG, y AlexNet.

import torch
import torchvision.models as models

# Cargar un modelo preentrenado
model = models.resnet50(pretrained=True)

  1. Congelación de Capas

Para evitar que las capas preentrenadas se actualicen durante el entrenamiento inicial, se pueden "congelar" estas capas.

for param in model.parameters():
    param.requires_grad = False

  1. Modificación de la Capa de Salida

La capa de salida del modelo debe ser modificada para que coincida con el número de clases de la nueva tarea.

import torch.nn as nn

# Modificar la capa de salida para una nueva tarea con 10 clases
num_ftrs = model.fc.in_features
model.fc = nn.Linear(num_ftrs, 10)

  1. Definición del Optimizador y la Función de Pérdida

Definir el optimizador y la función de pérdida para el entrenamiento.

import torch.optim as optim

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.fc.parameters(), lr=0.001, momentum=0.9)

  1. Entrenamiento del Modelo

Entrenar el modelo con los datos de la nueva tarea.

# Ejemplo de bucle de entrenamiento simplificado
for epoch in range(num_epochs):
    for inputs, labels in dataloader:
        optimizer.zero_grad()
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

  1. Descongelación de Capas y Ajuste Fino

Después de entrenar la capa de salida, se pueden descongelar algunas de las capas preentrenadas para ajustar finamente el modelo.

# Descongelar todas las capas
for param in model.parameters():
    param.requires_grad = True

# Redefinir el optimizador para incluir todos los parámetros
optimizer = optim.SGD(model.parameters(), lr=0.0001, momentum=0.9)

# Continuar el entrenamiento
for epoch in range(num_fine_tune_epochs):
    for inputs, labels in dataloader:
        optimizer.zero_grad()
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

Ejercicio Práctico

Ejercicio

  1. Selecciona un modelo preentrenado de torchvision.models.
  2. Congela todas las capas del modelo.
  3. Modifica la capa de salida para una tarea de clasificación con 5 clases.
  4. Entrena el modelo con un conjunto de datos de tu elección.
  5. Descongela las capas y realiza un ajuste fino del modelo.

Solución

import torch
import torchvision.models as models
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader

# 1. Selección del modelo preentrenado
model = models.resnet50(pretrained=True)

# 2. Congelación de todas las capas
for param in model.parameters():
    param.requires_grad = False

# 3. Modificación de la capa de salida
num_ftrs = model.fc.in_features
model.fc = nn.Linear(num_ftrs, 5)

# 4. Definición del optimizador y la función de pérdida
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.fc.parameters(), lr=0.001, momentum=0.9)

# 5. Preparación de los datos
transform = transforms.Compose([
    transforms.Resize(256),
    transforms.CenterCrop(224),
    transforms.ToTensor(),
])

train_dataset = datasets.FakeData(transform=transform)
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)

# Entrenamiento inicial
num_epochs = 5
for epoch in range(num_epochs):
    for inputs, labels in train_loader:
        optimizer.zero_grad()
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

# 6. Descongelación de capas y ajuste fino
for param in model.parameters():
    param.requires_grad = True

optimizer = optim.SGD(model.parameters(), lr=0.0001, momentum=0.9)

num_fine_tune_epochs = 5
for epoch in range(num_fine_tune_epochs):
    for inputs, labels in train_loader:
        optimizer.zero_grad()
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

Conclusión

El ajuste fino de CNNs es una técnica eficiente para adaptar modelos preentrenados a nuevas tareas, ahorrando tiempo y recursos. Al congelar y descongelar capas estratégicamente, se puede aprovechar el conocimiento previo del modelo y mejorar su rendimiento en la nueva tarea. Esta técnica es especialmente útil en escenarios donde los datos de entrenamiento son limitados.

© Copyright 2024. Todos los derechos reservados