Inspiration
Pneumonia is one of the leading causes of death in young children worldwide, and it is highly treatable when caught early. The bottleneck is often not treatment but diagnosis: in many clinics there are too few radiologists, and a chest X-ray can wait a long time to be read.
AI can help, but most medical AI tools are black boxes. They output "pneumonia: 94%" with no explanation, and a doctor has little reason to trust a number they can't question. I wanted to build something that doesn't just predict, but shows its reasoning and admits when it isn't sure. That became LungLens: see what the AI sees.
What it does
Upload a chest X-ray and LungLens returns:
- A prediction (Normal vs. Pneumonia) with a confidence score
- A Grad-CAM heatmap highlighting the lung regions that drove the decision
- An "Uncertain, please consult a doctor" result when confidence is too low, instead of forcing a guess
It is designed as a triage aid to help prioritize scans, not to replace clinicians.
How I built it
- Model: transfer learning with a pretrained [ResNet18 / MobileNetV2] in PyTorch, fine-tuned on the public Chest X-Ray Images (Pneumonia) dataset
- Data handling: the provided validation set was too small to be reliable, so I created my own stratified train/validation/test split, with augmentation (rotation, brightness, flips) to improve generalization
- Class imbalance: pneumonia images outnumber normal ones, so I used a weighted loss:
$$\mathcal{L} = -\frac{1}{N}\sum_{i=1}^{N} w_{y_i}\,\log p_{\theta}(y_i \mid x_i)$$
- Explainability: Grad-CAM weights each feature map $A^k$ by the average gradient of the class score $y^c$:
$$\alpha_k^c = \frac{1}{Z}\sum_{i}\sum_{j}\frac{\partial y^c}{\partial A^k_{ij}}, \qquad L^c_{\text{Grad-CAM}} = \text{ReLU}!\left(\sum_k \alpha_k^c A^k\right)$$
- Uncertainty: if the top softmax probability is below a threshold $\tau$, the app returns "uncertain" instead of a label
- App: a Streamlit web interface so anyone can upload an image and get results instantly
Tech stack: Python, PyTorch, torchvision, Streamlit, NumPy, OpenCV, Matplotlib, GitHub
Results
Evaluated on a held-out test set, I focused on sensitivity (not missing sick patients) rather than accuracy alone:
$$\text{Sensitivity} = \frac{TP}{TP + FN}, \qquad \text{Specificity} = \frac{TN}{TN + FP}$$
- Sensitivity: [X%]
- Specificity: [X%]
- Accuracy: [X%]
Challenges I ran into
- Misleading accuracy: because the data is imbalanced, a model could look accurate while missing sick patients. I switched to sensitivity, specificity and a confusion matrix.
- Unreliable validation set: the provided validation split had only a handful of images, so I rebuilt the splits myself to get trustworthy evaluation.
- Overconfident predictions: neural networks can be confidently wrong, which is dangerous in healthcare. This motivated the uncertainty threshold.
- Checking the heatmaps: a good score isn't enough if the model is looking at the wrong thing (like text markers or borders). Grad-CAM let me catch this. [Describe anything you actually found.]
- [Add any real bug or setback you hit while building.]
What I learned
- Accuracy alone can be dangerous in medical AI. Choosing the right metric matters as much as choosing the right model.
- Explainability builds trust: seeing why a model decided helps spot errors and shortcuts.
- A responsible health tool should know its limits and say "I'm not sure."
- How to take a model from a notebook to a usable app that non-technical people can try.
Limitations and ethics
LungLens is a research prototype, not a medical device. It was trained on a single public dataset of pediatric X-rays and has not been clinically validated. It should never be used for real diagnosis without review by a qualified clinician.
What's next
- Test on more diverse datasets (different hospitals, ages, scanners)
- Add more conditions (e.g., tuberculosis, COVID-19)
- Calibrate confidence scores more rigorously
- Work with clinicians to evaluate real-world usefulness
Built With
- computer-vision
- convolutional-neural-networks
- deep-learning
- explainable-ai
- grad-cam
- machine-learning
- matplotlib
- medical-imaging
- numpy
- opencv
- pandas
- pillow
- python
- pytorch
- scikit-learn
- streamlit
- torchvision
- transfer-learning
Log in or sign up for Devpost to join the conversation.