Transfer Learning And Practical Training
Feature Extraction vs Fine-Tuning
Chapter 1, Section 5 introduced the transfer learning spectrum. This chapter covers its two most common practical points: feature extraction and fine-tuning.
Jr Codex Deep Learning Notes
Level: Intermediate–Advanced Prerequisites: Chapter 1: Why Train From Scratch Rarely Makes Sense Time to complete: ~25 minutes
Table of Contents
- Two Concrete Strategies
- Feature Extraction
- Fine-Tuning
- Layer-Wise (Gradual) Unfreezing
- Choosing a Learning Rate for Fine-Tuning
- Deciding Which Strategy to Use
- Summary & Next Steps
1. Two Concrete Strategies
Chapter 1, Section 5 introduced the transfer learning spectrum. This chapter covers its two most common practical points: feature extraction and fine-tuning.
2. Feature Extraction
Feature extraction freezes every pretrained layer entirely — their weights never update during training — and adds a new, small, randomly-initialized final layer (or few layers) trained specifically for the new task.
import torch
import torch.nn as nn
from torchvision import models
# Load a model PRETRAINED on ImageNet
model = models.resnet50(weights="IMAGENET1K_V2")
# FREEZE every existing parameter — none of these will be updated during training
for param in model.parameters():
param.requires_grad = False # Module 2, Ch.4 — no gradients computed OR applied
# REPLACE the final classification layer with a NEW one, sized for OUR task
num_classes = 10 # e.g. our own 10-category classification task
model.fc = nn.Linear(model.fc.in_features, num_classes) # ONLY this new layer has requires_grad=True by default
# Only the NEW layer's parameters get passed to the optimizer
optimizer = torch.optim.Adam(model.fc.parameters(), lr=0.001)Why Freeze Everything
─────────────────────────────────────────
The pretrained layers already encode GENERAL, useful visual
features (Chapter 1, Section 3) — freezing them means:
- MUCH faster training (backpropagation, Module 2 Ch.4,
doesn't need to compute gradients for the frozen
layers at all)
- Works well even with a SMALL new dataset — there are
very few new parameters (just the new final layer) to
overfit
- Cannot adapt the pretrained features AT ALL to the new
task's specific quirks — a real limitation if the new
task differs substantially from the original training
data
─────────────────────────────────────────
3. Fine-Tuning
Fine-tuning goes further: after replacing the final layer (as in Section 2), it unfreezes some or all of the pretrained layers, and continues training them — typically at a much lower learning rate than would be used for training from scratch.
import torch
import torch.nn as nn
from torchvision import models
model = models.resnet50(weights="IMAGENET1K_V2")
model.fc = nn.Linear(model.fc.in_features, num_classes=10)
# UNFREEZE everything this time — allow the ENTIRE network to adapt
for param in model.parameters():
param.requires_grad = True
# A MUCH lower learning rate than training from scratch would use (Module 3, Ch.5)
optimizer = torch.optim.Adam(model.parameters(), lr=0.00001) # note: 100x smaller than Section 2's new-layer-only rateWhy Fine-Tuning Needs a MUCH Lower Learning Rate
─────────────────────────────────────────
The pretrained weights already encode USEFUL, well-trained
representations (Chapter 1) — a LARGE learning rate (Module
3, Ch.5) risks DESTROYING this useful starting point with
large, disruptive updates, effectively "forgetting" what was
learned during pretraining before the new task's smaller
dataset can teach it anything better. A small learning rate
allows GENTLE adjustment, adapting pretrained features
slightly toward the new task, without erasing their
original value.
─────────────────────────────────────────
4. Layer-Wise (Gradual) Unfreezing
A refined middle-ground strategy: start with feature extraction (Section 2), then progressively unfreeze layers from the END of the network backward, retraining a bit more of the network at each stage.
def gradual_unfreezing_schedule(model, epoch):
"""A simplified illustration of progressively unfreezing layers, LATEST first"""
if epoch == 0:
# Only the new final layer is trainable
for name, param in model.named_parameters():
param.requires_grad = "fc" in name
elif epoch == 5:
# ALSO unfreeze the last residual block (Module 4, Ch.2)
for name, param in model.named_parameters():
if "fc" in name or "layer4" in name:
param.requires_grad = True
elif epoch == 10:
# Unfreeze EVERYTHING
for param in model.parameters():
param.requires_grad = TrueWhy Unfreeze LATE Layers First
─────────────────────────────────────────
Chapter 1, Section 3 established that LATE layers are the
most TASK-SPECIFIC — they're the layers MOST likely to
benefit from adapting to the new task, and least likely to
contain broadly useful general features worth preserving
UNCHANGED. Unfreezing them FIRST, before touching the
general early layers, minimizes the risk of disrupting the
valuable, general representations while still allowing
meaningful task-specific adaptation.
─────────────────────────────────────────
5. Choosing a Learning Rate for Fine-Tuning
A Practical Layer-Wise Learning Rate Strategy
─────────────────────────────────────────
EARLY layers (general features): VERY low learning rate,
or KEEP frozen entirely
— minimal risk of
disruption preferred
MIDDLE layers: LOW-to-MODERATE
learning rate
LATE layers + the NEW final layer: HIGHER learning
rate — these
need the MOST
adaptation to
the new task
─────────────────────────────────────────
import torch
# Different learning rates for different parts of the network — "discriminative fine-tuning"
optimizer = torch.optim.Adam([
{"params": model.layer1.parameters(), "lr": 1e-6}, # EARLIEST layers — barely adjust
{"params": model.layer2.parameters(), "lr": 1e-5},
{"params": model.layer3.parameters(), "lr": 1e-5},
{"params": model.layer4.parameters(), "lr": 1e-4}, # LATEST pretrained layers — adjust more
{"params": model.fc.parameters(), "lr": 1e-3}, # NEW layer — largest learning rate
])6. Deciding Which Strategy to Use
A Practical Decision Guide
─────────────────────────────────────────
SMALL new dataset, Feature extraction (Section 2) —
task SIMILAR to minimal risk of overfitting the
original training: few new parameters being trained
SMALL new dataset, Feature extraction still preferred
task DIFFERENT from — fine-tuning risks overfitting
original training: a small dataset with too
many trainable parameters
LARGE new dataset, Fine-tuning (Section 3) — enough
task SIMILAR to data to safely adapt more of
original training: the network without
overfitting
LARGE new dataset, Fine-tuning, likely
task DIFFERENT from unfreezing MORE layers,
original training: or even considering
training from
scratch (Chapter 1,
Section 4) if the
domain gap is severe
─────────────────────────────────────────
This decision matrix directly parallels the ML Notes' bias-variance framing: fewer trainable parameters (feature extraction) reduces variance/overfitting risk on small datasets; more trainable parameters (fine-tuning) reduces bias, but requires enough data to safely support it.
7. Summary & Next Steps
Key Takeaways
- Feature extraction freezes all pretrained layers and trains only a new final layer — fast, safe for small datasets, but cannot adapt pretrained features to the new task at all.
- Fine-tuning unfreezes some or all pretrained layers, requiring a much lower learning rate to avoid destroying the useful pretrained representations with large, disruptive updates.
- Gradual unfreezing progressively unfreezes layers from the end of the network backward, since late layers are most task-specific and safest to adapt first.
- The choice between feature extraction and fine-tuning depends on dataset size and how similar the new task is to the original pretraining task, directly echoing the ML Notes' bias-variance tradeoff.
Concept Check
- Why does fine-tuning require a much lower learning rate than training a randomly-initialized network from scratch?
- Why does gradual unfreezing proceed from the last layers to the first, rather than the reverse?
- If you have a very small, task-different dataset, which strategy from this chapter would you choose, and why?
Next Chapter
→ Chapter 3: Pretrained Models & Model Hubs
Jr Codex — 1-on-1 Personalized Coaching | Back to Module Index | Back to DL Index