deep-learning · temario
3.4tema 4 de 4

Transfer Learning — Pretrained Models & Fine-tuning

Modelos preentrenados, congelamiento de capas y fine-tuning

Transfer learning es la práctica de reutilizar un modelo entrenado en una tarea grande (ImageNet, corpus de texto masivo) como punto de partida para una tarea específica. En lugar de aprender desde cero, heredas las representaciones ya construidas. Es el equivalente a contratar a alguien con 10 años de experiencia en lugar de enseñarle todo desde cero.

Hay dos estrategias principales. En feature extraction congelás todas las capas del modelo base (sus pesos no se actualizan) y solo entrenás una cabeza nueva conectada al final. En fine-tuning descongelás algunas o todas las capas y ajustás el modelo completo con un learning rate muy bajo. Feature extraction es más rápido; fine-tuning produce mejores resultados cuando tienes suficientes datos.

Congelar capas significa poner requires_grad=False en sus parámetros. Si no lo hacés, el optimizador actualizará los pesos preentrenados junto con los nuevos, arruinando las representaciones aprendidas durante el preentrenamiento en pocas iteraciones.

El learning rate es crítico en fine-tuning. Las capas preentrenadas necesitan un LR muy bajo (1e-5 a 1e-4) para ajustarse suavemente sin olvidar lo que saben. La cabeza nueva puede usar un LR más alto (1e-3). Los optimizadores modernos permiten definir grupos de parámetros con distintos LR, técnica conocida como discriminative fine-tuning.

Los modelos de Hugging Face (BERT, ResNet, ViT, GPT-2) están disponibles con una API unificada. Cargar un modelo preentrenado, reemplazar la capa de clasificación y fine-tunear es el flujo estándar en NLP y visión computacional modernas.

El riesgo principal del transfer learning es el catastrophic forgetting: si el LR es demasiado alto o se entrenan demasiadas capas con pocos datos, el modelo olvida sus representaciones originales y performa peor que si se hubiera entrenado desde cero. El learning rate scheduling y el early stopping son la defensa habitual.

structure.txt
FEATURE EXTRACTION (all layers frozen)
  model = models.resnet50(weights='IMAGENET1K_V2')
  for param in model.parameters():
      param.requires_grad = False          # freeze all
  model.fc = nn.Linear(model.fc.in_features, num_classes)  # new head
  optimizer = torch.optim.Adam(model.fc.parameters(), lr=1e-3)

FINE-TUNING (partial unfreeze)
  model = models.resnet50(weights='IMAGENET1K_V2')
  for param in model.parameters():
      param.requires_grad = False          # freeze all first
  for param in model.layer4.parameters():
      param.requires_grad = True           # unfreeze last block
  model.fc = nn.Linear(model.fc.in_features, num_classes)
  optimizer = torch.optim.Adam([
      {'params': model.layer4.parameters(), 'lr': 1e-4},
      {'params': model.fc.parameters(),     'lr': 1e-3},
  ])

HUGGING FACE (NLP)
  from transformers import AutoModel, AutoTokenizer
  model = AutoModel.from_pretrained('bert-base-uncased')
  tokenizer = AutoTokenizer.from_pretrained('bert-base-uncased')
  # freeze encoder, train classification head only:
  for param in model.parameters():
      param.requires_grad = False

Debugging lab

Detecta y corrige el error en el código.

0/5 tests passing0%
  1. 3.4.5.1

    model = models.resnet50(weights='IMAGENET1K_V2') model.fc = nn.Linear(model.fc.in_features, 10) optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)

  2. 3.4.5.2

    for param in model.parameters(): param.requires_grad = False model.fc = nn.Linear(512, 10) optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)

  3. 3.4.5.3

    # fine-tuning with same lr for all layers optimizer = torch.optim.Adam([ {'params': model.backbone.parameters(), 'lr': 1e-3}, {'params': model.head.parameters(), 'lr': 1e-3}, ])

  4. 3.4.5.4

    model = AutoModel.from_pretrained('bert-base-uncased') for param in model.encoder.layer[:6].parameters(): param.requires_grad = True # want to freeze first 6 layers

  5. 3.4.5.5

    # verifying trainable parameters trainable = sum(p.numel() for p in model.parameters()) print(f'Trainable params: {trainable}')