🔗 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"
}

