Skip to content

chillguycode/PneumoDetect

Repository files navigation

PneumoDetect: Chest X-Ray Analysis

PneumoDetect Logo Backend CI Pipeline

πŸ”— 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.

Features

  • FastAPI Backend: A robust API built with FastAPI to handle image processing and prediction requests.
  • Efficient ML Inference: Utilizes a pre-trained EfficientNetV2-S model 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 pytest validates 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.

Tech Stack

Component Technology Description
Backend Python Core programming language.
FastAPI High-performance web framework for the API.
ONNX Runtime For efficient, cross-platform model inference.
Frontend HTML5 Structure of the web application.
CSS3 Styling the user interface.
JavaScript Handling user interaction and API calls.
Testing Pytest A robust framework for testing the Python backend.
Deployment & CI/CD Docker Containerization of the application.
Docker Compose Orchestrating the multi-container setup for local development.
Nginx Serving the frontend and reverse proxy for local development.
GitHub Actions CI testing and deployment pipeline
Google Cloud Run Serverless backend deployment.
Firebase Frontend hosting via Firebase Hosting.

🎯 Model Performance & Reproducibility (MLflow)

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%.

Comprehensive Metrics Tracking

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.

Metrics

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.


πŸ”¬ PneumoCam: EigenCAM Explainability

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.

PneumoCam Example

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.

Project Structure

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



Getting Started

Follow these instructions to get the project up and running on your local machine.

Prerequisites

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.

Installation & Setup

  1. Clone the repository:
    git clone https://github.com/chillguycode/PneumoDetect.git
    cd PneumoDetect

Running the Application

With Docker and Docker Compose, running the entire application is a single command.

  1. 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 frontend and backend containers.

  2. Access the application: Once the containers are running, open your web browser and navigate to: http://localhost:8080

  3. Stopping the application: Press Ctrl + C in the terminal, then run docker-compose down to stop and remove the containers.

How to Use

  1. Click the "Choose an Image" button.
  2. Select a chest X-ray image (.jpeg or .png) from your computer.
  3. A preview of the selected image will be displayed.
  4. Click the "Predict" button.
  5. The application will show a loading spinner while the backend processes the image.
  6. If the uploaded image is not detected as a chest X-ray, a rejection message will appear instead.
  7. If the image passes the guard check, a PneumoCam heatmap overlay will appear showing the regions that influenced the prediction.
  8. Click the download icon to save the composite image.

Testing and Continuous Integration

Running Tests Locally

The backend includes a comprehensive test suite using pytest.

  1. Install development dependencies: Ensure your requirements.txt includes pytest, pytest-mock, httpx and onnx. Then install them into your virtual environment:

    pip install -r requirements.txt
  2. 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.

Continuous Integration (CI)

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:

  1. Checks out the latest code.
  2. Sets up a specific version of Python.
  3. Installs all required dependencies from requirements.txt.
  4. Generates a dummy ONNX model to make tests fast and self-contained.
  5. Runs the entire pytest suite.

You can view the status and logs of the CI runs under the "Actions" tab of this repository.


API Endpoint Documentation

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.

/predict

  • 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-data with a key named file.

Example using curl:

curl -X POST -F "file=@/path/to/your/xray.jpeg" http://localhost:8080/predict

Success Response (200 OK)

{
    "guard_status": "PASSED",
    "guard_confidence": 0.9823,
    "prediction": "PNEUMONIA",
    "confidence": 0.9876,
    "heatmap": "<base64 PNG string>",
    "xray": "<base64 PNG string>"
} 

Error Response (400 Bad Request)

If the file is not an image:

{
  "detail": "File is not an image. Uploaded file type is: application/pdf"
}