An end-to-end, production-grade deep learning application that classifies chest X-ray images as either Normal or Pneumonia.
Built with PyTorch, served via FastAPI, and accessible through an interactive Streamlit UI — all fully Dockerized.
- Overview
- Features
- Model Performance
- Dataset
- Tech Stack
- Architecture
- Setup
- Usage
- Testing
- Deployment
- License
This project uses transfer learning with a pre-trained ResNet50 model for accurate pneumonia detection from chest X-rays.
The architecture cleanly separates core ML logic, the API backend, and the UI frontend, ensuring scalability, maintainability, and deployment flexibility.
✅ High-Performance Model – PyTorch CNN + Transfer Learning
✅ RESTful API – Built with FastAPI for scalable inference
✅ Interactive UI – Drag & drop image upload with Gradio
✅ Dockerized – One command deploy anywhere
✅ MLOps-Ready – Versioned models, automated tests, clean workflow
The model was trained for 10 epochs, achieving a final validation accuracy of 87.50%. On the unseen test set, the model's performance was evaluated as follows:
- Overall Accuracy: 82.85%
- Key Metrics for Pneumonia Class:
- Precision: 0.91 (Of all the images predicted as "Pneumonia", 91% were correct.)
- Recall: 0.96 (The model correctly identified 96% of all actual "Pneumonia" cases.)
- F1-Score: 0.88 (A balanced measure of precision and recall.)
| Class | Precision | Recall | F1-Score | Support |
|---|---|---|---|---|
| NORMAL | 0.91 | 0.60 | 0.72 | 234 |
| PNEUMONIA | 0.80 | 0.96 | 0.88 | 390 |
| Total | 0.84 | 0.83 | 0.82 | 624 |
Source: Kaggle – Chest X-Ray Images (Pneumonia)
Size: 5,863 images (JPEG) — split into Pneumonia and Normal.
Origin: Pediatric patients (1–5 years old) from Guangzhou Women and Children’s Medical Center, China.
- Backend: Python, FastAPI
- Deep Learning: PyTorch, Torchvision
- UI: Gradio
- Containerization: Docker
- Testing: Pytest
- Utilities: Scikit-learn, Pillow, Matplotlib, Seaborn
The project follows a modular structure to ensure a clean separation of concerns, with each file having a specific responsibility:
medical_image_classifier/
│
├── app/
│ ├── __init__.py
│ ├── main.py # FastAPI routes and server logic
│ └── predict.py # Core model inference service
│
├── assets/
│ ├── normal_example.jpeg
│ └── pneumonia_example.jpeg
│
├── data/ # (Local) Dataset storage (ignored by Git)
│
├── logs/ # Stores application log files (auto-generated)
│
├── models/ # Trained model files (auto-generated)
│ └── pneumonia_classifier_v1_....h5
│
├── src/
│ ├── __init__.py
│ ├── config.py # All project constants and paths
│ ├── data_loader.py # Data loading and preprocessing pipeline
│ ├── evaluate.py # Model evaluation script
│ ├── logger.py # Logging configuration
│ ├── model.py # CNN architecture definition
│ └── train.py # Model training script
│
├── tests/
│ └── test_predict.py # Unit tests for the prediction service
│
├── ui/
│ └── interface.py # Gradio user interface
│
├── .dockerignore # Specifies files to ignore in the Docker build
├── .gitignore # Specifies files to ignore for Git
├── Dockerfile # Recipe for building the application container
├── pytest.ini # Pytest configuration
├── requirements.txt # Project dependencies
└── README.md # Project documentation
Follow these steps to set up the project on your local machine.
-
Clone the repository:
git clone https://github.com/Murci20965/medical_image_classifier.git cd medical_image_classifier -
Create and activate a virtual environment:
# For Windows python -m venv venv .\venv\Scripts\activate
-
Install the required dependencies:
pip install -r requirements.txt
-
Download the Dataset: Download the dataset from the Kaggle link and place the contents into the
data/raw/directory. The final path should bedata/raw/chest_xray/.
Ensure your virtual environment is active before running any commands.
To train the model from scratch, run the following command from the project's root directory. This will save a new, timestamped model file in the models/ directory.
python -m src.trainTo evaluate the performance of the latest trained model on the unseen test set, run:
python -m src.evaluateThis will print a classification report to the console and save a confusion matrix plot to the plots/ folder.
To run the application locally, you will need two separate terminals. Make sure the virtual environmwnt is activated.
-
Terminal 1: Start the API Server
uvicorn app.main:app --host 127.0.0.1 --port 8000
The API documentation will be available at
http://12-7.0.0.1:8000/docs. -
Terminal 2: Start the Gradio UI
python ui/interface.py
Open the local URL provided in the terminal to access the web interface.
Ensure Docker Desktop is installed and running.
-
Build the Docker image:
docker build -t medical-image-classifier . -
Run the container:
docker run --rm -p 8000:8000 --name medical-app medical-image-classifier
The API will be running inside the container and accessible at
http://localhost:8000. You can then start the Gradio UI locally (Step 3B) to interact with it.
To run the automated unit tests and ensure the application's core logic is working correctly, use the following command:
python -m pytestThis application is fully containerized and ready for deployment. The Dockerfile can be used to deploy the application to any cloud service that supports containers, such as AWS, Azure, or Google Cloud Platform.
This project is licensed under the MIT License. See the LICENSE file for more details.