Transfer learning and training CNNs in practice
Start from pretrained weights, then fine-tune with a modern recipe
Almost nobody trains vision models from scratch anymore. A backbone pretrained on ImageNet (or on billions of web images, as with CLIP and DINOv2) already knows edges, textures, parts and objects; fine-tuning adapts that knowledge to your 2,000 X-rays or 500 product photos in minutes. The same logic — pretrain broadly, adapt cheaply — is exactly what LoRA does for LLMs (8.2 Fine-tuning and PEFT). This lesson gives you the recipe, the augmentations and the debugging habits that make fine-tuning reliable, and prepares the project in 5.10 Project: train and deploy an image classifier.
You'll be able to
- Explain why early features transfer and choose between feature extraction and fine-tuning based on data size and domain similarity
- Write a complete timm/PyTorch fine-tuning loop with discriminative learning rates, a schedule and mixed precision
- Select and justify data augmentations, including mixup/CutMix, and avoid label-destroying ones
- Handle class imbalance and tiny datasets using weighting, embeddings and foundation backbones
- Diagnose a fine-tuning run with confusion matrices, top losses and calibration
Key ideas
- Early layers learn general edge/texture detectors; later layers are task-specific — so pretrained initialization helps everywhere and most when data is scarce.
- Small data + similar domain → freeze and train a head (or logistic regression on embeddings); large data → fine-tune everything with a small LR; in between, discriminative LRs and gradual unfreezing.
- A reliable recipe: timm backbone, fresh head, pretraining mean/std, AdamW with 10× lower LR for the backbone, warmup + cosine, label smoothing, bf16 autocast, EMA.
Show 4 more key ideas
- Augmentation is the strongest regularizer: random resized crops, flips, RandAugment, mixup/CutMix — but only transformations that preserve the label.
- For imbalance: class weights or weighted sampling plus threshold tuning; for tiny datasets: frozen foundation-model embeddings + kNN/logistic regression.
- Normalize with the pretraining statistics, mind train/test resolution, and scale LR with batch size.
- Debug with confusion matrices, top-loss images and calibration before touching the architecture.
Suggested path through this lesson
Why pretrained features transfer
Yosinski et al. (2014) split an ImageNet network and measured how well layers transfer to a different task. First-layer filters are Gabor-like edge and color detectors — general for any natural image. Middle layers detect textures and parts; the last layers are specific to the training classes. Transferability decreases with depth, but even specific layers help as initialization: fine-tuning from pretrained weights beats random initialization on almost every dataset, and the gap grows as your dataset shrinks. In 2026 the starting points are better than ever: ImageNet-21K and JFT-pretrained ConvNeXts and ViTs, and self-supervised or language-supervised foundation encoders (DINOv2, CLIP, SigLIP — 5.8 Self-supervised and contrastive learning, 8.10 Multimodal models) whose features work well frozen.
Two regimes
| your data | similar to pretraining domain | different domain (medical, satellite, microscopy) |
|---|---|---|
| small (hundreds–few thousand) | feature extraction: freeze backbone, train a linear/MLP head (or logistic regression on embeddings) | extract from earlier layers or use a self-supervised backbone; fine-tune carefully with strong regularization |
| large (tens of thousands+) | fine-tune the whole network with a small learning rate | fine-tune everything; consider longer schedules or domain-specific pretraining |
Feature extraction is fast (one forward pass per image, then a tiny classifier) and nearly impossible to overfit. Full fine-tuning gives the best accuracy when data allows. A middle path: unfreeze progressively from the top (gradual unfreezing) and use discriminative learning rates — small LRs for early layers (keep the general features), larger for the head.
The fine-tuning recipe (2026 defaults)
- Backbone:
timmoffers 1,000+ pretrained weights; good first picks areconvnext_tinyorresnet50for speed,vit_base_patch16_224or a DINOv2 ViT for quality. - Head: replace the classifier with a fresh linear layer of
num_classesoutputs. - Preprocessing: resize/crop to the model's training resolution and normalize with the pretraining mean/std (timm stores them in the model config). Mismatched normalization is the classic silent bug.
- Optimizer: AdamW, weight decay 0.05, head LR , backbone LR (10× lower); or SGD + momentum 0.9 for ResNets.
- Schedule: 1–3 warmup epochs then cosine decay (4.5 Optimizers and learning-rate schedules); 10–30 epochs is typical for fine-tuning.
- Regularization: label smoothing 0.1, stochastic depth 0.1 for deep nets, dropout only in the head, EMA of weights for a free boost.
- Precision: bf16/fp16 autocast halves memory and doubles throughput (4.9 PyTorch II: real training pipelines).
import timm, torch, torch.nn as nn
model = timm.create_model("convnext_tiny", pretrained=True, num_classes=NUM_CLASSES)
cfg = timm.data.resolve_data_config({}, model=model) # mean/std/input size
train_tf = timm.data.create_transform(**cfg, is_training=True, auto_augment="rand-m9-mstd0.5")
val_tf = timm.data.create_transform(**cfg, is_training=False)
head_params = [p for n, p in model.named_parameters() if n.startswith("head")]
body_params = [p for n, p in model.named_parameters() if not n.startswith("head")]
opt = torch.optim.AdamW([{"params": body_params, "lr": 1e-4},
{"params": head_params, "lr": 1e-3}], weight_decay=0.05)
sched = torch.optim.lr_scheduler.OneCycleLR(opt, max_lr=[1e-4, 1e-3],
total_steps=EPOCHS * len(train_loader), pct_start=0.1)
loss_fn = nn.CrossEntropyLoss(label_smoothing=0.1)
scaler = torch.amp.GradScaler()
for epoch in range(EPOCHS):
model.train()
for x, y in train_loader:
x, y = x.cuda(), y.cuda()
with torch.autocast("cuda", dtype=torch.bfloat16):
loss = loss_fn(model(x), y)
opt.zero_grad(set_to_none=True)
scaler.scale(loss).backward()
scaler.step(opt); scaler.update(); sched.step()
Data augmentation: the strongest regularizer in vision
Augmentation multiplies your dataset with label-preserving transformations and teaches invariances (4.7 Regularization in deep nets). Standard: random resized crop (scale 0.08–1 for ImageNet; gentler, 0.5–1, for small datasets), horizontal flip, color jitter. Automated policies: RandAugment / TrivialAugment apply random operations at random magnitudes and are strong defaults. Mixing methods regularize the decision boundary:
CutMix pastes a patch from into with equal to the area fraction. Random erasing hides rectangles. Think before you augment: vertical flips break digits and text, hue shifts break species identification by color, and crops that remove the lesion destroy the label in medical images. At test time, averaging predictions over a few flips/crops (test-time augmentation) adds a reliable half-point.
Imbalance and tiny datasets
For imbalanced classes use class-weighted cross-entropy or a weighted sampler, and tune the decision threshold on validation rather than trusting 0.5 (3.5 Evaluating models: metrics, validation and the bias–variance trade-off). Focal loss (5.5 Object detection) helps when the easy majority dominates. With very few labels per class (5–50), skip training a CNN head: extract frozen embeddings from a strong backbone and fit logistic regression or kNN (3.4 k-Nearest Neighbors) on them — this often beats fine-tuning and is trivially reproducible. If you have lots of unlabeled domain images, self-supervised pretraining on them (5.8 Self-supervised and contrastive learning) is the next lever.
Resolution, batch size and learning rate
Train and test resolution interact: networks trained with random-resized-crop see objects larger than at test time, so testing at a slightly higher resolution (or fine-tuning the head at test resolution, "FixRes") improves accuracy. Progressive resizing — train small, finish at full size — saves compute. When you change batch size, scale the learning rate linearly (4.5 Optimizers and learning-rate schedules) and check memory with the arithmetic from 4.12 Compute, hardware and scale basics.
Evaluate, then debug
Report accuracy and per-class precision/recall; plot the confusion matrix and look at the most confused pairs; inspect the highest-loss training images (fast.ai's plot_top_losses) — you will find label errors and near-duplicates. Check calibration (reliability diagram, 5.9 Interpretability, robustness and adversarial examples). When validation lags, the usual fixes in order: get more or cleaner data, stronger augmentation, a better backbone, more epochs — architecture tweaks come last.
When to train from scratch
He et al. ("Rethinking ImageNet Pre-training", 2018) showed that with enough iterations a from-scratch detector matches a pretrained one on COCO — pretraining mainly speeds convergence. In practice this needs 100K+ images and days of GPU; for a learner or a product team, always start pretrained, and consider domain pretraining when the domain is far from natural images.
Where this shows up later
- The same recipe trains detectors and segmenters on pretrained backbones — 5.5 Object detection, 5.6 Segmentation; you run it end-to-end in 5.10 Project: train and deploy an image classifier.
- Frozen embeddings + a small classifier is the pattern behind retrieval and RAG — 9.2 Embeddings deep dive; LoRA is fine-tuning with a low-rank budget — 8.2 Fine-tuning and PEFT.
- Self-supervised and contrastive pretraining supply the backbones — 5.8 Self-supervised and contrastive learning, 8.10 Multimodal models.
Common pitfalls (4)
- Normalizing with the wrong mean/std (or not at all) — the model still trains, just worse, so the bug hides.
- Fine-tuning the whole network with the head's large learning rate: pretrained features get destroyed in the first epochs ('catastrophic forgetting').
- Augmentations that change the label (vertical flips of text, hue shifts for color-defined classes) or that leak between train and validation (augmenting before splitting).
- Evaluating with model.train() active (dropout and BatchNorm batch statistics) — always call model.eval() and torch.no_grad() for validation.
Recap: all 7 key points
- Early layers learn general edge/texture detectors; later layers are task-specific — so pretrained initialization helps everywhere and most when data is scarce.
- Small data + similar domain → freeze and train a head (or logistic regression on embeddings); large data → fine-tune everything with a small LR; in between, discriminative LRs and gradual unfreezing.
- A reliable recipe: timm backbone, fresh head, pretraining mean/std, AdamW with 10× lower LR for the backbone, warmup + cosine, label smoothing, bf16 autocast, EMA.
- Augmentation is the strongest regularizer: random resized crops, flips, RandAugment, mixup/CutMix — but only transformations that preserve the label.
- For imbalance: class weights or weighted sampling plus threshold tuning; for tiny datasets: frozen foundation-model embeddings + kNN/logistic regression.
- Normalize with the pretraining statistics, mind train/test resolution, and scale LR with batch size.
- Debug with confusion matrices, top-loss images and calibration before touching the architecture.
Watch
Fine-tune a pretrained classifier on your own images in minutes — the mindset of this lesson in action.
Read
Exercises
- Feature extraction vs fine-tuning
On a small dataset (e.g., Oxford-IIIT Pets or 10 classes of Food-101), compare (a) logistic regression on frozen
convnext_tinyembeddings, (b) a trained linear head, (c) full fine-tuning with discriminative LRs. Record accuracy, training time and GPU memory for each. Expected: (a) is within a few points of (c) at a fraction of the cost on this kind of data. - Augmentation ablation
Train the same model for 10 epochs with: no augmentation; flips + crops; + RandAugment; + mixup. Plot train vs validation accuracy for each. Expected: train accuracy drops as augmentation strengthens while validation rises, until it plateaus or dips.
- Find the label errors
Compute per-image loss on the training set after fine-tuning, sort descending and display the top 32 with their labels. Expected: a handful of mislabeled or ambiguous images; fix them and retrain to measure the gain.
Quiz
Flashcards
These cards are now in your spaced-repetition queue. Review all due cards →