A full-stack repository (API + App) that implements ResNet-101 in PyTorch to classify images of cats and dogs, and includes an interpretability module to understand what the network “sees” for each prediction.
The goal is to provide an advanced, reliable classification and explanation tool with high reproducibility: modular code, YAML-based configuration, and evaluation/visualization utilities.
- Binary classification (cat vs. dog) on user-supplied images (local file or URL).
- Advanced interpretability to inspect the model’s decision per image:
- Occlusion Sensitivity — patch-wise relevance mapping.
- Integrated Gradients — path-integrated attributions from a baseline.
- Grad-CAM — class-specific heatmaps.
- Feature Maps (by depth) — intermediate activations per layer.
- Kernels (by depth) — learned filters (e.g., first conv layer).
-
resnet101/— model implementation (from scratch) and experiment artifactssrc/— architecture, residual blocks, checkpoint utilitiesmodel_trained/— trained weightsexperiments/— results and generated dashboards
-
src/— inference API (FastAPI) and utilitiesapi/— routers (/health,/predict,/predict/advanced), errors, middleware, depsinference/— preprocessing → forward pass → postprocessing → validation pipelineschemas/— Pydantic v2 contracts for requests/responses (incl. metadata & base64 images)utils/— configuration, env var loading, path helpers, etc.tests/— contract tests and input validation (pytest)
-
app/— user interface (Streamlit) to upload images/URLs and explore explanations -
config/— centralized YAML configuration for API, model training, DataOps and monitoringapi.yaml— API paths, IO limits, timeouts and model loading configmodel/oxford_pets_binary_resnet101.yaml— experiment configurationdata_governance.yaml— explicit DataOps governance and data contractmlops.yamlandparams.yaml— monitoring thresholds and DVC pipeline parameters
-
data/— DataOps documentation, preprocessing and statisticsprocessed/— working directory (do not version raw data)pet_stats.json— means/standard deviations for reproducible normalizationDATAOPS.md— operational DataOps notescreate_dataset/preprocess_training_data.py— reproducible training preprocessing report
-
notebooks/— data-flow verification and model sanity checks -
config/model/oxford_pets_binary_resnet101.yaml— experiment configuration (data, model, optimizer, scheduler, device) -
airflow/— DAGs and logs for MLOps orchestration -
scripts/andresnet101/scripts/— project CLIs (API/app launch, ingest, train, infer) -
monitoring/— operational reports (software metrics, drift, model health, quality gates, deployment history, rollback history)
- Model weights must be downloaded from MODEL and placed in the path:
resnet101/model_trained. - Datasets must comply with their original licenses. This project uses Oxford-IIIT Pet strictly for educational purposes.
App overview (Home / Image upload):
Advanced Prediction (Method-specific Interpretability):
Occlusion Sensitivity![]() Local relevance by hiding patches. |
Integrated Gradients (overlay)![]() Accumulated attributions overlaid on the input. |
Minimum requirements: Python 3.11+ (if using Poetry), Git.
Recommended alternative: Docker + Docker Compose (no need to install Python or Poetry locally).
git clone <URL>
cd <PROYECT CARPET>Place the weights file (e.g., ResNet101.pth) in: resnet101/model_trained/
Useful for quick development without containers.
- Install dependencies and activate the virtual environment:
poetry install- (Optional) Environment variable to make Streamlit point to a different API:
# PowerShell
$env:API_BASE_URL="http://127.0.0.1:8000"
# Bash
export API_BASE_URL="http://127.0.0.1:8000"- Open two terminals at the project root:
Terminal 1 — API (FastAPI/Uvicorn)
poetry run uvicorn src.api.main:app --host 0.0.0.0 --port 8000 --reloadTerminal 2 — UI (Streamlit)
poetry run streamlit run app/app.py- API docs: http://localhost:8000/docs
- UI: http://localhost:8501
Run the MLOps services in independent containers (ingestion, training, deploy) and optionally run Airflow orchestration.
docker compose buildIngestion stage
docker compose run --rm ingestionTraining stage (MLflow tracking enabled)
docker compose run --rm trainingDeploy stage (API)
docker compose up -d deployIf you want the Streamlit UI, run it locally with CLI:
python3 scripts/run_app.py --host 0.0.0.0 --port 8501# Start in detached mode
docker compose up -d deploy
# View logs (MLOps services)
docker compose logs -f ingestion
docker compose logs -f training
docker compose logs -f deploy
# Rebuild & restart after code changes
docker compose up -d --build
# Stop and remove containers
docker compose downdocker compose -f docker-compose.airflow.yml up -d --build- Airflow UI: http://localhost:8080
- Main DAG:
resnet101_mlops_orchestrator
- Weights not found: check the path
resnet101/model_trained/ResNet101.pth. - CORS / App–API connection: verify
API_BASE_URLand ensure Uvicorn is running at127.0.0.1:8000. - Dependencies: reinstall with
poetry install/pip install -r requirements-mlops.txt. - Airflow cannot run Docker commands: verify Docker socket mount (
/var/run/docker.sock) indocker-compose.airflow.yml.
# Run API
python3 scripts/run_api.py --host 0.0.0.0 --port 8000
# Run Streamlit app
python3 scripts/run_app.py --host 0.0.0.0 --port 8501# Data ingestion
python3 resnet101/scripts/cli_ingest.py --data-dir data --stats-path data/pet_stats.json
# Training (MLflow)
python3 resnet101/scripts/cli_train.py \
--config config/model/oxford_pets_binary_resnet101.yaml \
--output-dir resnet101/model_trained/mlops \
--tracking-uri file:./resnet101/mlruns
# Quick inference by image path
python3 resnet101/scripts/cli_infer.py \
--image-path data/processed/examples_oxford/cat_example.jpg --pretty# DataOps contract/preprocessing report
python3 data/create_dataset/preprocess_training_data.py \
--config-path config/model/oxford_pets_binary_resnet101.yaml \
--report-path monitoring/dataops_preprocess_report.json
# Software monitoring: latency, inference time and endpoint counts
python3 -m src.mlops.software_monitor \
--inference-log-path monitoring/inference_events.jsonl \
--report-path monitoring/software_metrics_report.json
# Drift monitoring: data, model, problem and concept drift
python3 -m src.mlops.detect_drift \
--reference-stats-path data/pet_stats.json \
--inference-log-path monitoring/inference_events.jsonl \
--feedback-log-path monitoring/feedback_events.jsonl \
--report-path monitoring/drift_report.json
# Model health: confidence plus supervised metrics when feedback exists
python3 -m src.mlops.evaluate_model_health \
--inference-log-path monitoring/inference_events.jsonl \
--feedback-log-path monitoring/feedback_events.jsonl \
--report-path monitoring/model_health_report.jsonThis repository now includes a complete operational MLOps loop:
- Ingestion (
ingestionservice /cli_ingest.py) - DataOps preprocessing contract (
data/create_dataset/preprocess_training_data.py) - Training + Tracking (
trainingservice / MLflow) - Quality Gate (
src/mlops/quality_gate.py) - Promotion to deployment model (
src/mlops/deployment_manager.py --action promote) - API deployment (
deployservice) - Monitoring:
- Software metrics: latency, preprocessing time, inference time and endpoint counts (
src/mlops/software_monitor.py) - Drift detection: data drift, model drift, problem drift and concept drift (
src/mlops/detect_drift.py) - Model health: confidence, uncertainty, accuracy, precision, recall, F1 and ROC-AUC (
src/mlops/evaluate_model_health.py)
- Software metrics: latency, preprocessing time, inference time and endpoint counts (
- Automatic retraining decision (Airflow DAG branching)
- Automatic rollback if quality gate fails or post-deploy health degrades
Operational reports are stored in monitoring/ (JSON/JSONL), including:
drift_report.jsonsoftware_metrics_report.jsonmodel_health_report.jsondataops_preprocess_report.jsonquality_gate_report_*.jsondeployment_history.jsonlrollback_history.jsonlorchestration_report.json
The DAG resnet101_mlops_orchestrator orchestrates bootstrap + continuous monitoring + retraining + rollback.
docker compose -f docker-compose.airflow.yml up -d --build- UI: http://localhost:8080
- Schedule: every 2 hours
- Decision logic:
- Retrain if drift is detected or model behavior degrades.
- Promote only if quality gates pass.
- Rollback automatically if post-deploy checks fail.
For orchestration details, see: AIRFLOW_ORCHESTRATION.md
GET /health→ Service statusPOST /predict→ Basic prediction:label,scores,metaPOST /predict/advanced→ Prediction + interpretabilityartifacts
- Input: file or URL → validation (MIME/shape)
- Preprocessing: resize/center-crop → normalized tensor (cached statistics)
- Model (ResNet-101): forward pass → logits → softmax
- Basic output:
label+scores+meta - Advanced output: adds
artifactswith panels (base64 PNGs) for:gradcam_panelintegrated_gradients_overlayocclusion_overlayfeature_maps_panelkernels_panel
(includes error indicators per panel when applicable)
Summary
| Metric | Value |
|---|---|
| Val Loss | 0.4084 |
| ROC-AUC | 0.9108 |
Classification Report
| Class | Precision | Recall | F1-Score | Support |
|---|---|---|---|---|
| 0 (cat) | 0.6840 | 0.8750 | 0.7678 | 240 |
| 1 (dog) | 0.9301 | 0.8044 | 0.8627 | 496 |
| Accuracy | 0.8274 | 736 | ||
| Macro Avg | 0.8071 | 0.8397 | 0.8153 | 736 |
| Weighted Avg | 0.8498 | 0.8274 | 0.8318 | 736 |
- Centralized YAML config (dataset, normalization, architecture, optimizer, scheduler).
- Normalization statistics cached in
data/pet_stats.json. - Controlled seeds and devices (CPU/CUDA).
- Reproducible MLOps stages through MLFlow + Docker services + Airflow DAG orchestration.
- Quality gates and deployment/rollback history persisted under
monitoring/.
- Intended for research and MLOps use.
- Please cite He et al., 2016 (ResNet) and the original interpretability works used in this project.
- Thanks to the PyTorch community and the Oxford-IIIT Pet dataset.
- For issues and enhancements, use the repository’s Issue Tracker.
- For technical questions, open a Discussion with the
help-wantedtag.





