π Live Demo: pneumodetect-493921.web.app
PneumoDetect is a full-stack web application designed to classify chest X-ray images for the detection of pneumonia. It leverages a powerful deep learning model served via a high-performance FastAPI backend, with a clean, responsive front end for user interaction. The entire application is containerized with Docker for easy setup and is automatically tested using a GitHub Actions CI pipeline.
- FastAPI Backend: A robust API built with FastAPI to handle image processing and prediction requests.
- Efficient ML Inference: Utilizes a pre-trained
EfficientNetV2-Smodel converted to the ONNX format for fast, CPU-based inference. - Guard Model: A CNN-based validation layer that rejects non-chest-X-ray images before running inference, preventing invalid predictions.
- PneumoCam (EigenCAM Heatmap): After a successful prediction, a saliency heatmap is overlaid on the processed X-ray highlighting the regions the model focused on. Implemented using EigenCAM. The composite image can be downloaded directly.
- Zero Data Retention: Medical images are processed entirely in-memory via the stateless REST API - no patient data is stored, logged, or persisted at any point. Privacy-preserving by design.
- Clean & Responsive Frontend: A simple user interface built with HTML, CSS, and vanilla JavaScript that works on both desktop and mobile.
- Fully Containerized: The entire application stack (Frontend Web Server & Backend API) is managed by Docker and Docker Compose for one-command setup.
- Automated Testing: A comprehensive test suite using
pytestvalidates the backend logic and API endpoints. - Continuous Integration & Deployment: A GitHub Actions workflow automatically runs all tests and deploys to Google Cloud Run and Firebase Hosting on every push to main.
The model deployed is an optimized EfficientNetV2-S which was systematically trained and tracked using MLflow to ensure the best performance and complete reproducibility of the final artifact.
This systematic approach allowed for hyperparameter optimization and architecture comparison, leading to a final test Accuracy of 96.15%.
The following screenshot from the MLflow UI shows the full performance metrics, including the final result and the learning curve for the best performing run.
Model trained and evaluated on the Kermany et al. Chest X-Ray Dataset (Cell, 2018)
- 5,856 clinically validated pediatric chest X-ray images across NORMAL and PNEUMONIA classes.
Base architecture: EfficientNetV2-S (Tan & Le, ICML 2021), fine-tuned for binary chest X-ray classification.
PneumoDetect provides visual explanations for every prediction through PneumoCam - an EigenCAM-based saliency map showing which regions of the X-ray influenced the model's diagnosis.
The heatmap is generated by extracting intermediate feature maps directly from the ONNX model, computing principal components via PCA, and projecting back to image space - requiring no external CAM library and keeping the production Docker image lean. The composite image (original X-ray + heatmap overlay) is returned alongside the prediction and can be downloaded directly from the UI.
EigenCAM: Muhammad & Yeasin, 2020
- Eigen-CAM: Class Activation Map using Principal Analysis.
The project is organized into a clean, scalable structure:
.
βββ .github/
β βββ workflows/
β βββ tests.yml-------------------# GitHub Actions workflow for CI
β βββ deploy.yml------------------# GitHub Actions deployment to GCP
βββ api/
β βββ tests/--------------------------# Backend tests
β β βββ conftest.py-----------------# Pytest fixtures and test setup
β β βββ create_dummy_model.py-------# Generates a lightweight model for testing
β β βββ test_main.py----------------# Tests for the FastAPI API layer (main.py)
β β βββ test_pipeline.py------------# Unit tests for the inference logic (pipeline.py)
β βββ Dockerfile----------------------# Blueprint for the backend container
β βββ main.py-------------------------# Main FastAPI application logic
β βββ pipeline.py---------------------# Handles the ONNX model inference
β βββ eigencam.py---------------------# Handles the EigenCAM Heatmap Utilities
βββ frontend/
β βββ assets/
β βββ css/
β βββ js/
β βββ Dockerfile----------------------# Blueprint for the frontend Nginx container
β βββ index.html
β βββ nginx.conf
βββ saved_models/
β βββ efficientnet_v2_s_best.onnx-----# The trained .onnx model file
β βββ cnn_guard_best.onnx-----# The trained guard .onnx model file
βββ .dockerignore
βββ docker-compose.yml
βββ .gitignore
βββ .gitattributes----------------------# Configures Git LFS for .onnx files
βββ requirements.txt--------------------# Python dependencies
Follow these instructions to get the project up and running on your local machine.
You must have the following software installed:
- Docker: Get Docker
- Docker Compose: (Usually included with Docker Desktop)
- Git: Get Git
- Git LFS: Install Git LFS. This is required to download the trained model file.
- Clone the repository:
git clone https://github.com/chillguycode/PneumoDetect.git cd PneumoDetect
With Docker and Docker Compose, running the entire application is a single command.
-
Build and run the containers: From the root directory of the project, run the following command:
docker-compose up --build
This command will build and start the
frontendandbackendcontainers. -
Access the application: Once the containers are running, open your web browser and navigate to: http://localhost:8080
-
Stopping the application: Press
Ctrl + Cin the terminal, then rundocker-compose downto stop and remove the containers.
- Click the "Choose an Image" button.
- Select a chest X-ray image (
.jpegor.png) from your computer. - A preview of the selected image will be displayed.
- Click the "Predict" button.
- The application will show a loading spinner while the backend processes the image.
- If the uploaded image is not detected as a chest X-ray, a rejection message will appear instead.
- If the image passes the guard check, a PneumoCam heatmap overlay will appear showing the regions that influenced the prediction.
- Click the download icon to save the composite image.
The backend includes a comprehensive test suite using pytest.
-
Install development dependencies: Ensure your
requirements.txtincludespytest,pytest-mock,httpxandonnx. Then install them into your virtual environment:pip install -r requirements.txt
-
Run the test suite: From the root directory of the project, execute
pytest:python -m pytest
This will automatically discover and run all tests in the
api/tests/directory.
This project uses GitHub Actions to automatically run the test suite for every push and pull request to the main and develop branches. This ensures that new changes do not break existing functionality.
The workflow is defined in the .github/workflows/tests.yml file and performs the following steps:
- Checks out the latest code.
- Sets up a specific version of Python.
- Installs all required dependencies from
requirements.txt. - Generates a dummy ONNX model to make tests fast and self-contained.
- Runs the entire
pytestsuite.
You can view the status and logs of the CI runs under the "Actions" tab of this repository.
For local development, all requests go through the Nginx proxy at port 8080. In production, the API is directly available at the Cloud Run URL.
- Method:
POST - Description: Uploads an image file for pneumonia classification.
- Local URL:
http://localhost:8080/predict - Production URL:
https://pneumodetect-backend-720802368286.asia-south1.run.app/predict - Body:
multipart/form-datawith a key namedfile.
Example using curl:
curl -X POST -F "file=@/path/to/your/xray.jpeg" http://localhost:8080/predict{
"guard_status": "PASSED",
"guard_confidence": 0.9823,
"prediction": "PNEUMONIA",
"confidence": 0.9876,
"heatmap": "<base64 PNG string>",
"xray": "<base64 PNG string>"
} If the file is not an image:
{
"detail": "File is not an image. Uploaded file type is: application/pdf"
}

