A reproducible, multi-architecture image-classification pipeline that turns a GoPro pointed at industrial equipment into a soft sensor. Originally built to read the surface texture of dewatered sludge cake at the partner advanced wastewater treatment plant — and to predict whether the cake is too dry, looks good, or too wet.
By Irfan Karim · M.Sc. Cornell University · part of the Environment, Data, and AI portfolio.
Representative result — validation macro-F1 across random seeds, six model families. Figure produced from a private case-study dataset that is not distributed with this repository.
| If you are a... | Start here |
|---|---|
| Student learning computer vision | Tutorial |
| Someone interested in the methods | Methods deep dive |
Problem. At a large municipal wastewater plant, operators manually adjust polymer dosing on belt-filter press dewatering system by looking at the dry sludge cake leaving the belts. The judgment is correct but slow, expensive, and unevenly distributed across shifts. A camera and a deep-learning model can assist the operating staff and streamline this procedure, adding 24/7, real-time monitoring to each belt filter press.
Solution. A reproducible pipeline that benchmarks six modern computer-vision architectures on the same task, picks a winner with multi-seed statistics, and ships it as a deployable inference package.
Result. FastViT-S12 consistently led the leaderboard on a held-out
test split, with strong recall on the safety-critical Too Wet class. The
deployed model fits in tens of megabytes and runs in well under a second per
image on a CPU laptop. Specific per-model metrics are reported as
representative results in docs/results/ and are derived
from a private case-study dataset that is not distributed with this
repository.
Why this repo is interesting on a CV.
- Real industrial deployment context — not Kaggle. The problem affects the daily operations of a major municipal wastewater utility serving millions of residents.
- Multi-architecture benchmark — six families spanning CNNs, hybrid CNN-transformers, and texture-encoding heads (DeepTEN), with a pre-registered analysis protocol (Friedman + Nemenyi + Holm-Bonferroni).
- Cloud-GPU cost engineering — Modal orchestration brings full 60-run sweep to ~$3 of T4 time. Documented and reproducible.
- Soft-label training — KL-divergence on expert-vote proportions instead of hard labels, preserving inter-rater uncertainty as a learning signal.
- Engineering hygiene — typed Python, unit tests, CI, lint, leak-guard workflow, ONNX/TorchScript exports, model cards.
In typical mechanical dewatering systems such as the ones using belt filter presses for dewatering the wet sludge produced as a wwtp by-product, polyacrylamides (PAM) a.k.a. polymers are used as pre-conditioner to coagulate and flocculate the sludge solid particles together for effective mechanical dewatering. Typically, operating staff look at the semi-dry sludge cakes on the belts and decide if the polymer dose upstream needs adjustments. Their decision falls into one of three buckets:
- Too dry — too much polymer is being used; dose reduction needed.
- Looks good — the dose is acceptable.
- Too wet — too little polymer is being used; an increase in polymer dosing is needed.
Millions of dollars of polymer, fuel, and biosolids transport ride on those calls. This repository teaches a computer to assist in making that call from a single picture, which saves, annually, around $200,000 on polymer costs alone.
The same pipeline applies to any 3-class image classification problem — medical triage screens, manufacturing defect inspection, agricultural crop sorting,and dataset that depends on surface texture or dryness.
The pipeline ships with a public toy dataset so you can try it without needing your own data.
# 1. Clone and install
git clone https://github.com/IrfanKarim352/wastewater-sludge-image-classification-cloud-gpus.git
cd wastewater-sludge-image-classification-cloud-gpus
python -m venv .venv && source .venv/bin/activate
pip install -e .
# 2. Generate a 90-image synthetic toy dataset (3 classes, runs in ~5 seconds)
sludgevision make-demo-dataset --output examples/synthetic_run/data
# 3. Train MobileNet-V3-Large for 3 epochs on the toy dataset
sludgevision train \
--config configs/quickstart.yaml \
--model mobilenet_v3_large \
--epochs 3 \
--output examples/synthetic_run/results
# 4. Evaluate on the held-out split
sludgevision evaluate \
--checkpoint examples/synthetic_run/results/best.pth \
--split examples/synthetic_run/data/testThat's the entire loop. To swap in real images, edit one line in
configs/quickstart.yaml:
data:
source: folder # one of: folder | flowers102 | synthetic
root: /path/to/your/images # subfolders = class namesTo run the same training on a real GPU in the cloud — no GPU on your
laptop required — see docs/runtime_modal.md.
.
├── src/sludgevision/ # the importable Python package
│ ├── data/ # dataset adapters + augmentations
│ ├── models/ # model registry (6 architectures)
│ ├── training/ # training loop + KL-div soft-label loss
│ ├── eval/ # metrics, confusion matrices, calibration
│ ├── runtime/ # Modal + Colab + local runtime backends
│ └── cli.py # `sludgevision` command-line entry point
├── configs/ # YAML configs (datasets, models, recipes)
├── scripts/ # standalone scripts for sweeps and analysis
├── notebooks/ # Colab-ready notebooks (free GPU)
├── docs/ # tutorial, methods, results, case study
├── examples/ # synthetic-data end-to-end demo
└── tests/ # pytest suite (runs on synthetic data)
All six were fine-tuned from ImageNet weights with the same recipe (12 epochs, 4 frozen + 8 unfrozen, AdamW, cosine annealing, KL-div soft-label loss).
| Family | Params | Why it's here |
|---|---|---|
| MobileNet-V3-Large | 5.5 M | Mobile-first CNN; deployment baseline |
| EfficientNet-V2-S | 21 M | Strong CNN with progressive learning recipe |
| EfficientFormerV2-S1 | 6 M | Mobile-friendly transformer hybrid |
| FastViT-S12 | 11 M | Apple's latency-tuned hybrid (winner here) |
| DeepTEN-ResNet18 | 11 M + Deep Texture Encoding | Material-texture head — sludge is a texture problem |
| Sparse-AE CNN (Small) | 0.4 M | From-scratch reference; no pretraining |
Full architecture details in docs/methods/MODEL_CARDS.md.
| Mode | When to use | Cost | Setup time |
|---|---|---|---|
| Local (CPU or single GPU) | Development, debugging, small sweeps | free | < 5 min |
| Google Colab (free T4 GPU) | One-off training runs, students, tutorials | free | < 2 min |
| Modal (production cloud GPU) | Multi-seed sweeps, full benchmarks, batch inference | ~$0.05/run on T4 | ~10 min |
Each runtime is documented:
The plots below come from training on the original a private case-study dataset
(2,983 expert-voted images, 6 model families x 10 random seeds = 60 runs).
The images themselves remain private, but every aggregate metric and
figure below is shipped in docs/results/ and reproducible from your own
data.
![]() |
![]() |
| Validation macro-F1 across 10 seeds, per family. | Final holdout macro-F1 — FastViT wins. |
![]() |
![]() |
| Per-class F1 by family (mean across seeds). | FastViT-S12 confusion matrix on holdout (n=636). |
The full case study, including dataset construction, expert-voting protocol,
and statistical analysis, lives in docs/case_study/.
docs/TUTORIAL.md— step-by-step, no prior CV experience assumeddocs/runtime_local.md,runtime_colab.md,runtime_modal.md— three ways to rundocs/case_study/— the the case study storydocs/methods/— methods writeup, model cards, statistical protocoldocs/results/— figures, tables, leaderboards (aggregated only)docs/FAQ.md— common gotchas
If you use this work academically, please cite:
@software{karim2026sludgevision,
author = {Karim, Irfan},
title = {Wastewater Sludge Image Classification on Cloud GPUs:
a reproducible deep-learning pipeline for industrial soft-sensing},
year = {2026},
publisher = {GitHub},
url = {https://github.com/IrfanKarim352/wastewater-sludge-image-classification-cloud-gpus},
version = {1.0.0},
}A peer-reviewed paper based on this codebase is in preparation; this README will be updated with the citation when it is available.
I am Irfan Karim — a graduate student in Environmental Engineering at Cornell University (M.Sc. May 2026, minor in Data Analytics & AI), working in Dr. April Gu's lab on machine vision and data analytics for wastewater process optimisation. My field study at the partner facility — with Dr. Haydée De Clippeleir (industry collaborator) — produced the dataset and motivation for this codebase.
- GitHub profile: github.com/IrfanKarim352 — Environment, Data, and AI
- Personal site: irfankarim56.github.io
- LinkedIn: linkedin.com/in/irfankarim5656
- Email: ik352@cornell.edu
I am open to applied-ML and research-engineering roles in environmental, water, climate, and infrastructure domains, starting Summer / Fall 2026. Reach out by email.
Code is released under the MIT License. The original a major wastewater treatment utility sludge-cake images and per-image expert labels remain the property of the partner utility and are not distributed with this repository. Aggregated metrics and figures are derivative summary works that do not allow reconstruction of any individual image.
The CI pipeline includes a leak-guard.yml workflow that fails any commit
that introduces image files or label patterns matching the original dataset.




