YAML Metadata Warning:empty or missing yaml metadata in repo card
Check out the documentation for more information.
Chest X-Ray Pneumonia Detection with Grad-CAM
Fine-tuned EfficientNet-B0 to detect pneumonia from chest X-rays, with Grad-CAM explainability implemented from scratch to visualise model attention regions.
Results
| Metric | Value |
|---|---|
| Test Accuracy | 93% |
| ROC-AUC | 0.9798 |
| Pneumonia F1 | 0.94 |
| Pneumonia Recall | 0.97 |
Evaluated on 624 test images (234 NORMAL, 390 PNEUMONIA).
Grad-CAM Visualisations
Grad-CAM (Gradient-weighted Class Activation Mapping) highlights which regions of the X-ray the model focused on when making its prediction. Implemented from scratch without external libraries.
Finding: The model primarily attends to lung tissue for pneumonia classification. Some attention to peripheral regions (arms) suggests potential shortcut learning β a deployment robustness concern relevant to clinical settings.
Training Curves
ROC Curve
Confusion Matrix
Dataset
Chest X-Ray Images (Pneumonia) by Paul Mooney on Kaggle.
- 5,216 training images
- 624 test images
- Classes: NORMAL, PNEUMONIA
- Class imbalance: ~3:1 (PNEUMONIA:NORMAL)
Key Design Decisions
Transfer Learning EfficientNet-B0 pretrained on ImageNet. All layers fine-tuned at a low learning rate (1e-4) to preserve pretrained features while adapting to chest X-ray domain.
Handling Class Imbalance Two complementary approaches:
- WeightedRandomSampler β oversamples minority class during training
- Weighted CrossEntropyLoss β penalises misclassification of minority class more heavily
Learning Rate Scheduling ReduceLROnPlateau reduces LR by 10x if validation loss plateaus for 3 epochs β automatically adapts without manual tuning.
Grad-CAM Implementation Forward hook captures feature maps at EfficientNet's last conv block. Backward hook captures gradients. Weights each feature map by its mean gradient, takes weighted sum, applies ReLU, upsamples to image size. No external explainability libraries used.
Project Structure
chest_xray_project/
βββ model.py β EfficientNet-B0 with custom classification head
βββ train.py β training loop, weighted sampler, LR scheduler
βββ evaluate.py β metrics, confusion matrix, ROC curve
βββ gradcam.py β Grad-CAM implementation from scratch
βββ visualise.py β heatmap generation and overlay
βββ outputs/ β training curves, confusion matrix, ROC curve
βββ gradcam_outputs/ β heatmap visualisations
Setup
git clone https://github.com/HarmeetKalha/chest-xray-pneumonia
cd chest-xray-pneumonia
pip install torch torchvision matplotlib seaborn scikit-learn opencv-python
Download the dataset from Kaggle and place it at:
data/chest_xray/train/
data/chest_xray/val/
data/chest_xray/test/
Download model weights from
Hugging Face
and place in checkpoints/best_model.pth.
Training
python train.py
Evaluation
python evaluate.py
Grad-CAM Visualisation
python visualise.py
Author
Harmeet Singh Kalha
- GitHub: @HarmeetKalha
- LinkedIn: harmeetsinghkalha



