A real-time facial emotion classification app built with a custom CNN trained from scratch in PyTorch. The Streamlit web app supports both image upload and live webcam inference via WebRTC.
App predicting sad with 68.1% confidence, showing full probability breakdown across all 7 emotion classes
A custom 3-block CNN built in PyTorch — no pretrained backbone, trained from scratch.
Input (1×128×128 grayscale)
│
├── Block 1: Conv2d(1→32) → BN → ReLU → Conv2d → BN → ReLU → MaxPool → Dropout(0.1)
├── Block 2: Conv2d(32→64) → BN → ReLU → Conv2d → BN → ReLU → MaxPool → Dropout(0.1)
├── Block 3: Conv2d(64→128) → BN → ReLU → Conv2d → BN → ReLU → MaxPool → Dropout(0.1)
│
├── AdaptiveAvgPool2d(1×1)
└── Classifier: Linear(128) → ReLU → Dropout(0.5) → Linear(7)
Key design choices:
- Grayscale input (1 channel) — removes color bias, focuses on facial structure
- BatchNorm after every conv layer — faster convergence and stable training
- AdaptiveAvgPool — makes the model input-size flexible
- Dropout at 0.1 (conv blocks) and 0.5 (FC layer) — reduces overfitting
Trained and evaluated on the Facial Emotion Recognition dataset (Kaggle) — 7,470 test samples.
| Emotion | Precision | Recall | F1-Score | Support |
|---|---|---|---|---|
| Angry | 0.53 | 0.40 | 0.46 | 888 |
| Disgust | 0.77 | 0.77 | 0.77 | 888 |
| Fear | 0.47 | 0.33 | 0.39 | 888 |
| Happy | 0.86 | 0.80 | 0.83 | 1711 |
| Neutral | 0.57 | 0.64 | 0.60 | 1226 |
| Sad | 0.43 | 0.65 | 0.52 | 981 |
| Surprise | 0.76 | 0.70 | 0.73 | 888 |
| Overall Accuracy | 63% | 7470 |
Happy and Disgust are the strongest classes. Fear and Angry are the hardest to classify — consistent with findings in the literature on this dataset due to visual similarity between emotions.
angry · disgust · fear · happy · neutral · sad · surprise
emotion-classifier-cnn/
├── app.py # Main Streamlit app (image upload + webcam tabs)
├── script.py # Image upload inference module
├── video.py # Webcam real-time inference module
├── best_emotion_cnn.pt # Trained model weights
├── class_names.json # Emotion label list
├── requirements.txt # Python dependencies
└── README.md
git clone https://github.com/Alnurabda/emotion-classifier-cnn.git
cd emotion-classifier-cnnpython -m venv venv
source venv/bin/activate # macOS/Linux
venv\Scripts\activate # Windowspip install -r requirements.txtstreamlit run app.pyOpen your browser at http://localhost:8501
- Upload Image tab — drag & drop any face image and get:
- Top predicted emotion with confidence score
- Full probability bar chart across all 7 classes
- Raw probability table
- RealTime tab — live webcam feed with:
- Per-frame emotion prediction overlaid on video
- Optional moving-average smoothing to stabilize predictions
- Runs entirely on CPU — no GPU required
IMG_SIZE = 128 # Input resolution (must match training)
IN_CH = 1 # 1 = grayscale, 3 = RGB
TOPK = 3 # Top-K predictions shown
SMOOTH_N = 8 # Webcam smoothing window (frames)| Package | Purpose |
|---|---|
torch / torchvision |
Model definition & inference |
streamlit |
Web UI |
streamlit-webrtc |
Real-time webcam streaming |
opencv-python |
Frame processing |
Pillow |
Image loading |
numpy / pandas |
Data handling & display |
av |
Video frame decoding |
Built by Alnura · GitHub