ThoraxGuard is an end-to-end deep learning project for chest CT scan classification. It includes a TensorFlow/Keras training pipeline, model evaluation artifacts, a Flask prediction API, Docker packaging, and GitHub Actions based deployment to AWS EC2 through Amazon ECR.
The current prediction service classifies CT images into:
adenocarcinomanormal
- TensorFlow/Keras based image classification model
- Flask web interface and REST prediction API
- Dockerized production server with Gunicorn
- Health endpoint for deployment verification
- DVC-style ML pipeline stages for ingestion, base model preparation, training, and evaluation
- GitHub Actions workflow for ECR image build/push and EC2 deployment
- Git LFS support for the trained Keras model artifact
ThoraxGuard/
├── app.py # Flask/Gunicorn entry point
├── Dockerfile # Production Docker image
├── requirements.txt # Python dependencies
├── setup.py # Editable package setup
├── config/
│ └── config.yaml # Pipeline and model paths
├── params.yaml # Training hyperparameters
├── src/
│ ├── cnnClassifier/ # Prediction and shared utilities
│ └── cancer/ # Training pipeline components
├── artifacts/
│ ├── training/model.keras # Trained model artifact
│ └── evaluation/scores.json # Evaluation metrics
├── templates/
│ └── index.html # Web UI
├── static/
│ └── css/style.css # UI styling
├── dvc.yaml # ML pipeline definition
└── .github/workflows/main.yaml # AWS deployment workflow
Create and activate a virtual environment:
python3 -m venv .venv
source .venv/bin/activateInstall dependencies:
python -m pip install --upgrade pip
python -m pip install -r requirements.txtRun the Flask app locally:
python app.pyThe app will start at:
http://127.0.0.1:8080
Health check:
curl http://127.0.0.1:8080/healthImage prediction using multipart upload:
curl -X POST http://127.0.0.1:8080/predict \
-F "file=@/path/to/ct-image.jpg"The prediction response returns the predicted class, confidence, and class probabilities.
Build the image:
docker build -t thoraxguard:latest .Run the container:
docker run --rm -p 8080:8080 -e PORT=8080 thoraxguard:latestVerify:
curl http://127.0.0.1:8080/healthThe Docker image expects the trained model at:
artifacts/training/model.keras
This file is tracked with Git LFS because it is a large binary model artifact. Before cloning or deploying, make sure Git LFS is installed:
git lfs install
git lfs pullIf the model file is missing, Docker build will fail before deployment.
The pipeline stages are defined in dvc.yaml:
dvc reproMain stages:
data_ingestionprepare_base_modeltrainingevaluation
The dataset paths in config/config.yaml currently point to a local dataset directory. Update those paths before running the training pipeline on a different machine.
Deployment is handled by GitHub Actions in:
.github/workflows/main.yaml
The workflow:
- Builds the Docker image on GitHub-hosted Ubuntu runner.
- Pushes the image to Amazon ECR.
- Uses a self-hosted EC2 runner to pull and run the latest image.
- Verifies deployment with
/health.
Required GitHub Actions repository secrets:
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AWS_DEFAULT_REGION
ECR_REPO
ECR_REPO should be only the ECR repository name, not the full ECR URL.
Example:
ECR_REPO=thoraxguard
The deploy job requires an EC2 self-hosted runner with these labels:
self-hosted, Linux, X64
To start the runner manually on EC2:
cd ~/actions-runner
./run.shKeep the terminal open until it shows:
Listening for Jobs
For a permanent runner service:
cd ~/actions-runner
sudo ./svc.sh install ubuntu
sudo ./svc.sh start
sudo ./svc.sh status- Do not commit
.env,.venv/, AWS credentials, or local secret files. - Store AWS credentials only in GitHub Actions repository secrets.
- Rotate any AWS access key that was shared publicly or exposed in screenshots.
- Python 3.12
- TensorFlow 2.16
- Flask
- Gunicorn
- Docker
- GitHub Actions
- Amazon ECR
- AWS EC2
- Git LFS
- DVC