Phase 6: Computer Vision
Module 16: Transfer Learning
What You Will Learn
In this module, you will learn:
- What is Transfer Learning?
- Why Transfer Learning?
- Pretrained Models
- Freeze Layers
- Fine-Tuning
- Feature Extraction
- Building a Cats vs Dogs Classifier
- Best Practices
What is Transfer Learning?
Transfer Learning is a technique where a model trained on one large dataset is reused for another related task.
Instead of training a model from scratch, we start with a model that has already learned useful visual features.
For example:
1ImageNet Dataset 2 (1.2 Million Images) 3 │ 4 ▼ 5Pretrained ResNet50 6 │ 7 ▼ 8Replace Final Layer 9 │ 10 ▼ 11Cats vs Dogs Classifier
The pretrained model already knows how to detect:
- Edges
- Corners
- Shapes
- Textures
- Objects
We only teach it the new classes.
Why Use Transfer Learning?
Training from scratch requires:
- Huge datasets
- Powerful GPUs
- Long training time
Transfer Learning offers:
- Faster training
- Better accuracy
- Less data required
- Reduced overfitting
Training From Scratch vs Transfer Learning
| Training From Scratch | Transfer Learning |
|---|---|
| Millions of images | Thousands of images |
| Long training time | Fast training |
| High computational cost | Low computational cost |
| Random initialization | Pretrained weights |
| More prone to overfitting | Better generalization |
What are Pretrained Models?
A pretrained model is a model already trained on a large dataset such as ImageNet.
ImageNet contains:
11.2 Million Images 2 31000 Classes
Popular pretrained models include:
- ResNet
- VGG
- DenseNet
- MobileNet
- EfficientNet
- Vision Transformer (ViT)
Loading a Pretrained Model
Example using ResNet18:
1from torchvision.models import ( 2 resnet18, 3 ResNet18_Weights 4) 5 6model = resnet18( 7 weights=ResNet18_Weights.DEFAULT 8)
Understanding the Model
1print(model)
The last layer looks like:
1(fc): Linear( 2 in_features=512, 3 out_features=1000 4)
Since ImageNet has 1000 classes, we must replace this layer.
Replacing the Final Layer
Suppose our dataset has:
1Cat 2 3Dog
Only 2 classes.
Replace the classifier:
1import torch.nn as nn 2 3model.fc = nn.Linear( 4 model.fc.in_features, 5 2 6)
Now the model predicts:
1Cat 2 3Dog
Freeze Layers
Why Freeze Layers?
Early CNN layers already learn:
- Edges
- Curves
- Textures
These features work well for most image tasks.
Instead of retraining everything, we freeze them.
Freeze All Layers
1for param in model.parameters(): 2 3 param.requires_grad = False
Train Only Final Layer
1import torch.nn as nn 2 3model.fc = nn.Linear( 4 model.fc.in_features, 5 2 6) 7 8for param in model.fc.parameters(): 9 10 param.requires_grad = True
Only the classifier learns.
Verify Frozen Layers
1for name, param in model.named_parameters(): 2 3 print( 4 name, 5 param.requires_grad 6 )
Output
1conv1.weight False 2 3bn1.weight False 4 5layer1... False 6 7layer2... False 8 9layer3... False 10 11layer4... False 12 13fc.weight True 14 15fc.bias True
Feature Extraction
Feature Extraction means:
- Freeze the backbone
- Train only the classifier
Pipeline
1Image 2 │ 3 ▼ 4Pretrained CNN 5(Frozen) 6 │ 7Extract Features 8 │ 9 ▼ 10Classifier 11 │ 12Prediction
Feature Extraction Example
1from torchvision.models import ( 2 resnet18, 3 ResNet18_Weights 4) 5 6import torch.nn as nn 7 8model = resnet18( 9 weights=ResNet18_Weights.DEFAULT 10) 11 12for param in model.parameters(): 13 14 param.requires_grad = False 15 16model.fc = nn.Linear( 17 model.fc.in_features, 18 2 19)
Fine-Tuning
Feature Extraction trains only the classifier.
Fine-Tuning trains:
- Classifier
- Some deeper CNN layers
This usually gives better accuracy.
Fine-Tuning Strategy
1Input Image 2 │ 3 ▼ 4Frozen Layers 5 │ 6 ▼ 7Trainable Layers 8 │ 9 ▼ 10Classifier
Unfreeze Last Block
1for param in model.layer4.parameters(): 2 3 param.requires_grad = True
Now:
1Layer1 ❄ Frozen 2 3Layer2 ❄ Frozen 4 5Layer3 ❄ Frozen 6 7Layer4 ✅ Trainable 8 9FC Layer ✅ Trainable
Optimizer for Fine-Tuning
Only optimize trainable parameters.
1import torch.optim as optim 2 3optimizer = optim.Adam( 4 5 filter( 6 lambda p: p.requires_grad, 7 model.parameters() 8 ), 9 10 lr=1e-4 11)
Data Preparation
1from torchvision import transforms 2 3train_transform = transforms.Compose([ 4 5 transforms.Resize((224,224)), 6 7 transforms.RandomHorizontalFlip(), 8 9 transforms.RandomRotation(10), 10 11 transforms.ToTensor(), 12 13 transforms.Normalize( 14 15 mean=[0.485,0.456,0.406], 16 17 std=[0.229,0.224,0.225] 18 ) 19])
Validation Transform
1val_transform = transforms.Compose([ 2 3 transforms.Resize((224,224)), 4 5 transforms.ToTensor(), 6 7 transforms.Normalize( 8 9 mean=[0.485,0.456,0.406], 10 11 std=[0.229,0.224,0.225] 12 ) 13])
Loading Dataset
Folder Structure
1cats_dogs/ 2 3├── train/ 4 5│ ├── cats/ 6 7│ └── dogs/ 8 9└── validation/ 10 11 ├── cats/ 12 13 └── dogs/
Dataset
1from torchvision.datasets import ImageFolder 2from torch.utils.data import DataLoader 3 4train_dataset = ImageFolder( 5 "cats_dogs/train", 6 transform=train_transform 7) 8 9val_dataset = ImageFolder( 10 "cats_dogs/validation", 11 transform=val_transform 12) 13 14train_loader = DataLoader( 15 train_dataset, 16 batch_size=32, 17 shuffle=True 18) 19 20val_loader = DataLoader( 21 val_dataset, 22 batch_size=32 23)
Loss Function
1import torch.nn as nn 2 3criterion = nn.CrossEntropyLoss()
Training Loop
1device = torch.device( 2 "cuda" 3 if torch.cuda.is_available() 4 else "cpu" 5) 6 7model.to(device) 8 9epochs = 5 10 11for epoch in range(epochs): 12 13 model.train() 14 15 running_loss = 0 16 17 correct = 0 18 19 total = 0 20 21 for images, labels in train_loader: 22 23 images = images.to(device) 24 25 labels = labels.to(device) 26 27 optimizer.zero_grad() 28 29 outputs = model(images) 30 31 loss = criterion( 32 outputs, 33 labels 34 ) 35 36 loss.backward() 37 38 optimizer.step() 39 40 running_loss += loss.item() 41 42 _, predicted = outputs.max(1) 43 44 total += labels.size(0) 45 46 correct += ( 47 predicted == labels 48 ).sum().item() 49 50 print( 51 52 f"Epoch {epoch+1}" 53 54 f" Loss:{running_loss/len(train_loader):.4f}" 55 56 f" Accuracy:{100*correct/total:.2f}%" 57 )
Validation Loop
1model.eval() 2 3correct = 0 4 5total = 0 6 7with torch.no_grad(): 8 9 for images, labels in val_loader: 10 11 images = images.to(device) 12 13 labels = labels.to(device) 14 15 outputs = model(images) 16 17 _, predicted = outputs.max(1) 18 19 total += labels.size(0) 20 21 correct += ( 22 predicted == labels 23 ).sum().item() 24 25print( 26 "Validation Accuracy:", 27 100 * correct / total 28)
Save the Model
1import torch 2 3torch.save( 4 5 model.state_dict(), 6 7 "cats_vs_dogs_resnet18.pth" 8)
Load the Model
1model.load_state_dict( 2 3 torch.load( 4 "cats_vs_dogs_resnet18.pth" 5 ) 6) 7 8model.eval()
Complete Project Structure
1cats_vs_dogs_project/ 2 3│ 4 5├── train/ 6 7│ ├── cats/ 8 9│ └── dogs/ 10 11│ 12 13├── validation/ 14 15│ ├── cats/ 16 17│ └── dogs/ 18 19│ 20 21├── train.py 22 23├── model.py 24 25├── predict.py 26 27└── best_model.pth
Transfer Learning Workflow
1Load Pretrained Model 2 │ 3 ▼ 4Replace Final Layer 5 │ 6 ▼ 7Freeze Backbone 8 │ 9 ▼ 10Train Classifier 11 │ 12 ▼ 13Fine Tune Last Layers 14 │ 15 ▼ 16Save Best Model
Popular Pretrained Models
| Model | Parameters | Best Use |
|---|---|---|
| ResNet18 | 11.7M | General image classification |
| ResNet50 | 25.6M | High accuracy |
| DenseNet121 | 8M | Medical imaging |
| MobileNetV2 | 3.5M | Mobile devices |
| EfficientNet-B0 | 5.3M | Production applications |
| ViT-B/16 | 86M | Large-scale vision tasks |
Feature Extraction vs Fine-Tuning
| Feature Extraction | Fine-Tuning |
|---|---|
| Freeze backbone | Unfreeze some layers |
| Train only classifier | Train classifier + selected backbone layers |
| Faster | Slower |
| Less GPU memory | More GPU memory |
| Less data required | More data preferred |
| Good baseline | Usually higher accuracy |
Best Practices
- Use pretrained weights whenever possible instead of training from scratch.
- Replace the final classification layer to match the number of target classes.
- Start with feature extraction, then move to fine-tuning if needed.
- Use a smaller learning rate (e.g.,
1e-4or1e-5) during fine-tuning. - Apply data augmentation to improve generalization.
- Normalize images using the statistics expected by the pretrained model.
- Save the best-performing model based on validation accuracy or validation loss.
- Fine-tune deeper layers only after the classifier has learned reasonable weights.
Practice Project: Cats vs Dogs Classification
Objective
Build an image classifier using a pretrained ResNet18 model.
Tasks
- Download the Cats vs Dogs dataset.
- Apply image augmentation for training.
- Load a pretrained
ResNet18. - Replace the final fully connected layer with a 2-class classifier.
- Freeze the backbone and train only the classifier.
- Fine-tune the last residual block (
layer4). - Evaluate performance on the validation dataset.
- Save the best model as
cats_vs_dogs_resnet18.pth.
Module Summary
In this module, you learned:
- ✅ What Transfer Learning is and why it dramatically reduces training time and data requirements.
- ✅ How to load and use pretrained models from
torchvision.models. - ✅ How to replace the final classification layer for a custom dataset.
- ✅ How to freeze layers and train only the classifier.
- ✅ The difference between Feature Extraction and Fine-Tuning.
- ✅ How to unfreeze selected layers for higher accuracy.
- ✅ How to build a complete Cats vs Dogs image classifier using a pretrained ResNet18.
- ✅ Best practices for training, validation, model saving, and deployment.
After mastering Transfer Learning, you'll be able to adapt powerful pretrained CNNs to a wide range of custom computer vision tasks using only a relatively small amount of labeled data.