Transfer Learning — Fine-Tuning Pretrained Vision Models
Feature extraction vs fine-tuning, layer freezing, and choosing the right backbone. Get ImageNet-level features without ImageNet-level compute.
Training ResNet50 from scratch on ImageNet took 29 hours on 8 V100 GPUs. Transfer learning uses those weights as a starting point and fine-tunes to your task in 20 minutes on one GPU. This is how every production vision system at startups is built.
Module 46 introduced the concept — take a pretrained backbone, replace the classifier head, fine-tune. This module goes deep on everything that matters in practice: which layers to freeze, which learning rates to use per layer group, how to choose the right backbone for your constraints, and when feature extraction beats fine-tuning.
The intuition: the first layers of any image model learn universal low-level features — edges, textures, gradients. These are the same whether the task is classifying fashion products or detecting defects in circuit boards. Later layers learn task-specific high-level features. Transfer learning reuses the universal layers and only retrains the task-specific ones.
A civil engineer who has spent 10 years building roads knows structural principles, material properties, load calculations — universal engineering knowledge. To now build bridges, they do not retrain their entire education. They learn bridge-specific design on top of existing expertise. That is transfer learning.
Early layers of a pretrained CNN have learned to detect edges, curves, and textures from 1.2 million ImageNet images. That knowledge transfers perfectly to detecting fabric defects, product damage, or medical anomalies. Only the final task-specific layers need to learn from your small dataset.
Feature extraction vs fine-tuning — when each one wins
Differential learning rates — tiny lr for backbone, normal lr for head
The biggest mistake in fine-tuning: using the same learning rate for all layers. Early backbone layers contain universal features learned from 1.2 million images — they need tiny updates (lr ≈ 1e-5) to preserve that knowledge. The new classification head is randomly initialised and needs large updates (lr ≈ 1e-3) to learn quickly. Using 1e-3 on backbone layers causes catastrophic forgetting. Using 1e-5 on the head causes slow convergence. Differential learning rates solve both.
ResNet vs EfficientNet vs ViT — which backbone for which constraint
The backbone is the pretrained feature extractor. Choosing the right one depends on your accuracy requirement, inference latency budget, available GPU memory, and dataset size. There is no universal best — EfficientNet-B0 is better than ResNet50 for mobile deployment, ViT-B/16 is better for large datasets and highest accuracy, ResNet18 is better when training data is very scarce.
Complete transfer learning pipeline — Shopify product classification
Every common transfer learning mistake — explained and fixed
The real decision: how much data do you have, and how far is your domain from ImageNet?
Every transfer learning project on a real team starts with the same two questions, answered before a single line of training code gets written: how many labelled images do we actually have, and how close is our domain to natural photographs? The answer to those two questions — not a blanket preference for "fine-tune everything" or "freeze everything" — is what decides how many layers get unfrozen and how aggressive the learning rates are.
A health-tech team building an abnormality classifier for chest X-rays reused the exact recipe that had worked well for a product-photo classifier: ResNet50 pretrained on ImageNet, backbone entirely frozen, fine-tune only a new head, 4,000 labelled X-rays. It shipped at 61 percent accuracy on the held-out test set — barely above the 58 percent majority-class baseline.
The cause was domain shift, not a bug. X-rays are single-channel grayscale images forced into 3 identical channels to match ResNet's input shape, their intensity statistics look nothing like natural photographs, and ImageNet's later layers are tuned to recognise things like fur, fabric weave, and wheel spokes — visual cues that simply do not exist in a lung radiograph. The frozen backbone's later layers were producing near-meaningless features for this input distribution, and no amount of head training could recover information that was never extracted in the first place.
The fix: unfreeze layer2 through layer4 with a small learning rate instead of just the head, so the network could re-learn its higher-level features on real X-ray statistics. Accuracy rose to 84 percent. The team later swapped the backbone entirely for one pretrained on radiology images instead of ImageNet, and gained a few more points — evidence that for domains this far from natural photographs, the pretraining dataset matters as much as the fine-tuning strategy.
Five things people get wrong about transfer learning
Transfer learning wins when your dataset is small-to-moderate relative to the task's complexity, or when your domain is reasonably close to the pretraining domain — that's most production vision problems, which is why it's the default recipe. But given a truly large, well-labelled dataset (hundreds of thousands of images) in a domain far from natural photographs, training from scratch — or fine-tuning so aggressively it's close to starting over — can match or beat a lightly fine-tuned pretrained model, because the model can learn representations specifically shaped by your data instead of inheriting ImageNet's biases. The right call depends on both dataset size and domain distance, not a blanket rule.
Freezing everything except the head (pure feature extraction) protects you from catastrophic forgetting, but it also caps how well the model can adapt — if your task needs task-specific high-level features the frozen backbone never learned (because ImageNet never needed them), no amount of head training will produce them. "Safer" here just means "less likely to break," not "more likely to perform best." For a dataset of meaningful size with any domain gap from ImageNet, selectively unfreezing later layers with a small learning rate consistently outperforms full freezing — the risk of forgetting is real but manageable, and the risk of under-adapting is often larger.
"Reasonably small" is relative to what the layer already knows, and early backbone layers know a lot — a learning rate that seems conservative for a randomly initialised head (1e-4, say) can still meaningfully disturb pretrained low-level filters over enough epochs, especially without gradient clipping or warmup. Catastrophic forgetting isn't a single threshold you cross; it's a matter of degree that compounds across training steps and depends on how many layers are unfrozen, for how long, and at what relative rate to the head. That's why the standard fix is differential learning rates *and* often gradual unfreezing, not just picking one small number and hoping it's small enough.
Early layers learn genuinely universal low-level patterns — edges, corners, colour gradients — that transfer well almost everywhere. But "transfers well" degrades the further the target domain sits from natural RGB photographs of everyday objects. Medical imaging (X-rays, MRI slices), satellite imagery, and microscopy all have fundamentally different structure, colour statistics, and scale than ImageNet's dog photos and street scenes — a backbone's later layers, tuned specifically to recognise ImageNet-style objects, offer far less of a head start there. In practice this means larger domain shift calls for unfreezing more layers (or fine-tuning more aggressively) than a task that closely resembles natural photography, and in extreme domain shift cases, transfer learning's advantage can shrink to not much more than a decent weight initialisation.
ImageNet top-1 accuracy measures how well a backbone performs at ImageNet's own task and scale — it does not directly predict how well its features transfer to your smaller, different dataset. A large model like ViT-B/16 (86M parameters) generally needs more fine-tuning data to avoid overfitting than a compact ResNet18 (11M parameters), so on a genuinely small dataset the "worse" ImageNet model can win after fine-tuning simply because it doesn't overfit as fast. Backbone choice has to weigh accuracy against your actual dataset size, latency budget, and deployment constraints — "highest ImageNet accuracy" is one input to that decision, not the answer to it.
Transfer learning — 5 questions interviewers actually ask
I'd default to transfer learning whenever labelled data is limited relative to the task (roughly under tens of thousands of images) and the domain isn't wildly different from natural photographs — which covers most production vision problems, since it gets you most of ImageNet's learned representations essentially for free and trains in a fraction of the time. I'd lean toward training from scratch, or very aggressive fine-tuning that's effectively close to it, when I have a large, high-quality dataset in a domain far from ImageNet — satellite imagery or microscopy, for example — where a from-scratch model can learn representations actually shaped by the data instead of inheriting biases that don't apply.
Early convolutional layers learn low-level, local patterns — edges, corners, colour gradients, simple textures — which are useful for recognising essentially any visual input, whether it's a shoe, an X-ray, or a satellite photo. Later layers combine those low-level patterns into progressively more abstract, task-specific representations — by the final layers, filters are effectively tuned to detect things like "dog snout" or "car wheel," which are specific to what the network was trained to classify. That's why the standard fine-tuning recipe freezes or barely touches early layers (their features are already close to optimal for any vision task) while unfreezing later layers with a higher learning rate so they can specialise toward the new task.
It's when fine-tuning updates backbone weights aggressively enough, early enough, that the useful pretrained representations get overwritten before the new head has learned anything useful to build on — you end up with a model that's worse than either the original pretrained backbone or a properly fine-tuned one. It typically comes from using too high a learning rate on backbone layers, especially in the first few epochs while the randomly initialised head is still producing large, noisy gradients that flow back into the backbone. I prevent it with differential learning rates (much smaller lr on backbone layers than the head), often combined with freezing the backbone entirely for the first few epochs so the head stabilises first, and gradient clipping as a safety net.
My first suspicion is domain shift: ImageNet is natural RGB photographs of everyday objects and scenes, and medical images (X-rays, MRI, histopathology slides) differ in colour statistics, texture, and scale in ways that make the backbone's later, more task-specific layers much less useful as a starting point than they'd be for, say, product photos. I'd check whether normalisation statistics match what the backbone expects, then try unfreezing more layers (or a larger portion of the network) than I would for an in-domain task, since less of the pretrained representation transfers cleanly here. I'd also sanity-check the data pipeline itself — grayscale medical images forced into 3-channel RGB, or intensity ranges very different from natural images, are common silent bugs that look exactly like a domain-shift problem.
I'd start with feature extraction as a fast baseline any time the dataset is small (under a few hundred images) or very similar to ImageNet — freeze the entire backbone, train only the new head, and see where accuracy lands. If I have a moderate-to-large dataset or the domain differs meaningfully from ImageNet, I'd move to fine-tuning: unfreeze the later backbone layers (and the head, obviously), keep the earliest layers frozen since their features are already near-universal, and assign a much smaller learning rate to unfrozen backbone layers than to the head — a common pattern is roughly 0.01× the head's learning rate for early unfrozen layers, scaling up toward the head. I'd validate the setup by watching per-layer-group loss behaviour early in training, and consider gradual unfreezing instead if the dataset is on the smaller side.
The Computer Vision section is complete. Section 10 — Generative AI — begins next.
You have completed the full Computer Vision section: image fundamentals, data augmentation, object detection, semantic segmentation, and transfer learning. You can build, train, evaluate, and deploy any standard vision system. Section 10 shifts from recognising images to generating them — GANs, VAEs, diffusion models, and the architecture behind Stable Diffusion.
GANs, VAEs, diffusion, and LLMs — what makes each one generative, and when each one is the right architecture.
🎯 Key Takeaways
- ✓Transfer learning reuses weights from a model pretrained on a large dataset (ImageNet) as the starting point for a new task. Early layers capture universal features (edges, textures) that transfer across all vision tasks. Only later layers and the classification head need retraining on your specific data.
- ✓Feature extraction freezes all backbone layers and only trains the new head — best for very small datasets (<500 images) or when domain is very similar to ImageNet. Fine-tuning unfreezes later backbone layers — best for moderate datasets (500–50k) and when highest accuracy is needed.
- ✓Differential learning rates are essential for fine-tuning: early layers get lr × 0.01, mid layers lr × 0.1, late layers lr × 1.0, head lr × 10. Using the same lr for all layers causes catastrophic forgetting in early layers and slow convergence in the head simultaneously.
- ✓Backbone selection depends on constraints: ResNet18 for very small datasets or extreme latency, ResNet50 for the default production choice, EfficientNet-B3 for best accuracy at similar parameter count, EfficientNet-B0 for mobile/edge deployment, ViT-B/16 for large datasets needing highest accuracy.
- ✓Always apply ImageNet normalisation (mean=[0.485,0.456,0.406], std=[0.229,0.224,0.225]) for any ImageNet-pretrained backbone. Missing normalisation is the single most common reason a fine-tuned model fails to learn — activations are in the wrong range and the pretrained features are meaningless.
- ✓Export trained models to ONNX (opset_version=17) for production deployment. ONNX runs on CPU, GPU, and edge devices without PyTorch dependency. Always validate with onnx.checker.check_model() after export. Use dynamic_axes to support variable batch sizes in deployment.
Discussion
0Have a better approach? Found something outdated? Share it — your knowledge helps everyone learning here.