Computer Vision
Compared a custom CNN, frozen EfficientNet-B0 transfer learning, and partial fine-tuning on the FER2013 emotion dataset.
Overview
This project teaches a computer to recognise seven facial expressions (angry, disgust, fear, happy, neutral, sad, surprise) from small grayscale photos, and compares three ways of building that model.
What I did
I built and trained all three approaches in PyTorch, evaluated them on 7,178 held-out test images, and compared the results.
Why it matters
Knowing when a big pretrained model helps, and when it doesn't, saves real compute and time. This experiment showed that the off-the-shelf approach alone wasn't enough.
Problem
FER2013 is hard: 48×48 grayscale faces, noisy labels, and heavy class imbalance (436 'disgust' vs 7,215 'happy' training images).
Architecture
PyTorch on a Colab T4 GPU. A custom convolutional network is trained from scratch at native resolution, then compared with EfficientNet-B0 pretrained on ImageNet (images resized to 224×224, grayscale to 3 channels), first as a frozen feature extractor and then with its last blocks unfrozen.
System flow
- FER2013
- Custom CNN
- EfficientNet-B0
- Partial fine-tune
- Compare on test set
Technical decisions
- Baseline before transfer learningTraining a small CNN first set an honest baseline to judge whether a pretrained backbone actually helps.
- Partial unfreezingImageNet features transfer poorly to tiny grayscale faces, so the last blocks plus the classifier were unfrozen with a 90/10 train/validation split.
Challenges
- A frozen ImageNet backbone barely beat the scratch CNN (44.57% vs 44.25%), which pointed to domain mismatch rather than model capacity.
Verified results
- 44.25%
- 44.57%
Technologies
Python · PyTorch · torchvision · EfficientNet-B0 · Google Colab · NumPy · Matplotlib