MziziGuard: Crop Disease Detection with AdaptShot¶
MziziGuard is a complete, working application built on AdaptShot that helps smallholder farmers identify maize diseases from just a few photos — no internet, no GPU, no expensive hardware.
It comes in two modes:
| Mode | Command | Best for |
|---|---|---|
| Terminal demo | python examples/crop_disease_demo.py |
Presentations, quick test |
| Full web app | python -m examples.mziziguard.app |
Real usage, training, field deployment |
You will learn: - How to run the full Gradio web application with 5-tab interface - How few-shot learning works in practice (5 photos per class) - How to use human-in-the-loop corrections (the core power of AdaptShot) - How OOD detection prevents wrong answers in the field - How to read calibration reports for system monitoring - How to adapt MziziGuard for your own crops and use cases
The Problem¶
In Tanzania and across East Africa, maize is the staple food. But diseases like Northern Leaf Blight and Gray Leaf Spot destroy 20–60% of harvests every season. Agricultural extension officers can't reach every village. By the time a farmer gets a diagnosis, the crop is already lost.
Almost every farmer has a basic smartphone. What if they could just take a photo and get an instant, accurate diagnosis — without needing internet?
That's what MziziGuard solves.
Running the Full Web Application¶
Install dependencies and start the Gradio web server:
# Install AdaptShot with Gradio UI support
pip install -e ".[ui]"
# Launch the web application
python -m examples.mziziguard.app
# Or with a custom port and public link
python -m examples.mziziguard.app --port 8080 --share
Then open http://localhost:7860 in your browser. You'll see 5 tabs:
| Tab | What it does |
|---|---|
| ⚙️ Setup | Generate synthetic samples or load real images from folders |
| 🔍 Diagnose | Upload a crop photo → instant Swahili diagnosis with confidence |
| 👩🏫 Teach | Correct wrong predictions — the model learns immediately |
| 🏥 Health | System calibration dashboard & session metrics |
| 📦 Batch | Process multiple photos at once, export results |
Quick Start: The Terminal Demo¶
For a 6-stage narrated presentation (great for demos):
python examples/crop_disease_demo.py
# Press Enter between stages for a live presentation
# Use --no-pause for non-interactive mode
| Stage | What happens | Key concept |
|---|---|---|
| 0 | Why this matters | The problem |
| 1 | Load 5 photos per disease | Few-shot learning |
| 2 | Predict on a new photo | Inference |
| 3 | A human corrects the model | Human-in-the-loop |
| 4 | Show something unfamiliar | OOD detection |
| 5 | System health report | Calibration |
| 6 | Why AdaptShot, why Tanzania | Vision |
How It Works (Step by Step)¶
1. Generating the Dataset¶
The demo uses PIL to create synthetic leaf images — green ovals with veins for healthy leaves, plus brown lesions (Northern Leaf Blight) or gray rectangular spots (Gray Leaf Spot). This means you can run the demo anywhere, even without downloading real datasets.
from examples.crop_disease_demo import generate_dataset, DISEASE_GENERATORS
# Generate 5 support + 3 query images per class
paths, labels = generate_dataset("/tmp/demo", n_support=5, n_query=3)
# 3 classes × 5 support = 15 training images total
2. Creating the Learner¶
from adaptshot import AdaptShotConfig, FewShotLearner
config = AdaptShotConfig(
backbone="resnet18", # Frozen feature extractor
device="cpu", # No GPU needed
seed=42, # Reproducible
eco_mode=True, # Carbon-aware inference
)
learner = FewShotLearner(config=config)
learner.load_support_images(paths, labels)
Behind the scenes, AdaptShot extracts embeddings from each support image using a frozen ResNet-18. These embeddings become the model's "knowledge" — it compares new images to these stored examples.
3. Making a Prediction¶
result = learner.predict("path/to/query_leaf.png")
print(result.prediction) # "northern_leaf_blight"
print(result.calibrated_confidence) # 0.87
print(result.uncertainty_flag) # False (model is confident)
The PredictionResult tells you more than just a label. It gives you a calibrated confidence score — the model tells you HOW sure it is, not just WHAT it thinks.
4. Human Correction (The Magic)¶
This is what makes AdaptShot different from every other ML library:
# The agricultural officer says: "This is actually northern_leaf_blight"
result = learner.correct(
image_path="path/to/query_leaf.png",
true_label="northern_leaf_blight",
confidence_weight=0.8, # How confident is the human?
)
The correction is routed through AdaptShot's feedback pipeline: 1. Updates the calibration engine (temperature scaling) 2. Adds the example to the replay buffer 3. Updates per-class ACT thresholds 4. Triggers CA-EWC fine-tuning if enough corrections accumulate
Every correction makes the model smarter for the next farmer.
5. OOD Detection — Saying "I Don't Know"¶
# Show it something completely unfamiliar (soil, a hand, a rock)
result = learner.predict("path/to/soil_photo.png")
if result.ood_flag:
print("I don't know what this is.") # Honest, not guessing
Most AI systems would confidently give a wrong answer. AdaptShot's OOD (out-of-distribution) detection checks whether the new image is close enough to any known support example. If not, it raises a flag instead of guessing.
6. System Health Monitoring¶
report = learner.calibration_report()
print(report["ece"]) # Expected Calibration Error
print(report["temperature"]) # Current temperature scaling
print(report["window_size"]) # Number of corrections recorded
print(report["support_size"]) # Total support embeddings
You don't need to be an ML expert to know if the system is healthy. The calibration report gives you plain numbers that tell you whether the model is well-calibrated and has enough data.
Using the Python API¶
MziziGuard has a clean Python API for programmatic use. Here's the full workflow:
Configuration (config.yaml)¶
Edit examples/mziziguard/config.yaml to add your own crops:
crops:
maize:
swahili: "mahindi"
diseases:
healthy_maize:
swahili: "mahindi yenye afya"
action: "Hakuna matibabu yanayohitajika."
severity: "low"
northern_leaf_blight:
swahili: "ugonjwa wa mabaka ya kahawia"
action: "Ondoa majani yaliyoathirika. Tumia dawa ya kuvu."
severity: "moderate"
Initialize and Predict¶
from examples.mziziguard import MziziGuard
# Load from config
guard = MziziGuard("examples/mziziguard/config.yaml")
# Option A: Generate synthetic samples for quick start
guard.initialize_with_samples(n_support=5)
# Option B: Load real images from a folder structure
# (folder/{class_name}/*.png)
guard.load_images_from_dir("path/to/crop_photos/", max_per_class=10)
# Diagnose
result = guard.diagnose("photo_of_leaf.jpg")
print(f"Diagnosis: {result.swahili}")
print(f"Confidence: {result.confidence:.1%}")
print(f"Action: {result.action}")
Teach the Model (Human-in-the-Loop)¶
# When the prediction is wrong, correct it:
result = guard.teach(
image_path="photo_of_leaf.jpg",
true_label="northern_leaf_blight",
confidence_weight=0.9, # How sure are you?
)
# The model updates IMMEDIATELY — next prediction will be better
Batch Processing¶
# Process a whole folder of farmer photos
results = guard.batch_diagnose([
"farmer_1.jpg", "farmer_2.jpg", "farmer_3.jpg",
])
for r in results:
print(f"{r.swahili}: {r.confidence:.1%} — {r.action}")
# Export to CSV for record-keeping
csv_data = guard.batch_to_csv(results)
with open("diagnoses.csv", "w") as f:
f.write(csv_data)
Save and Resume¶
# Save the trained model for next session
guard.save_model("models/session_2024.json")
# Later, resume from that save
restored_count = guard.load_model("models/session_2024.json")
print(f"Restored {restored_count} support images")
System Health¶
health = guard.system_health()
print(f"Calibration ECE: {health['calibration']['ece']}")
print(f"Session accuracy: {health['session']['accuracy']}")
print(f"Eco mode: {health['config']['eco_mode']}")
Adapting MziziGuard for Your Own Use Case¶
Add your own crops and diseases¶
Edit config.yaml to define new crops:
crops:
coffee:
swahili: "kahawa"
diseases:
coffee_leaf_rust:
swahili: "kutu ya majani ya kahawa"
action: "Tumia dawa ya kuvu yenye shaba. Punguza kivuli."
description: "Orange-yellow powdery spots on leaf undersides."
severity: "high"
healthy_coffee:
swahili: "kahawa yenye afya"
action: "Endelea na utunzaji wa kawaida."
severity: "low"
Load real images¶
Organize your photos like this and use load_images_from_dir():
my_photos/
├── healthy_coffee/
│ ├── img_001.jpg
│ └── img_002.jpg
├── coffee_leaf_rust/
│ ├── img_003.jpg
│ └── img_004.jpg
└── coffee_berry_disease/
└── img_005.jpg
Other use cases that work with the same template¶
- Coffee leaf rust detection — major issue for Tanzania's cash crop
- Cassava mosaic disease — affects food security across East Africa
- Poultry disease screening — respiratory conditions from droppings photos
- Skin condition triage — community health workers in rural clinics
- Manufacturing defect detection — quality control for small industries
Any problem where a non-expert needs to classify images with just a few examples is a candidate for MziziGuard + AdaptShot.
Presentation Tips¶
If you're presenting this demo to a non-technical audience:
-
Start with the problem, not the technology. "How many of you know a farmer who lost crops to disease?" Everyone will raise their hand.
-
Use Swahili names. The demo includes Swahili translations for each disease. Say "ugonjwa wa mabaka ya kahawia" alongside "Northern Leaf Blight."
-
Emphasize the "just 5 photos" part. Most people think AI needs millions of examples. "You don't need a thousand pictures of sick maize. You need five."
-
The human correction moment is your climax. Pause. Explain: "In most AI, if the computer is wrong, you're stuck. In AdaptShot, you correct it — and it learns. Like teaching a student."
-
The OOD demo is your trust-builder. "What if someone shows it a photo of their hand by accident? Most AI would say 'diseased crop.' AdaptShot says 'I don't know.' That's the difference between a tool you can trust and a tool you can't."
-
End with the big picture. "One laptop. One extension officer. Every farmer in the district gets a crop doctor. That's what we're building."
Project Structure¶
examples/mziziguard/
├── __init__.py # Public API (MziziGuard, DiagnosisResult)
├── config.yaml # Crop/disease definitions & engine settings
├── engine.py # Core engine wrapping FewShotLearner
├── data.py # Sample generation + real image folder loader
└── app.py # Gradio web UI (5-tab interface)
What This Project Demonstrates About AdaptShot¶
| Feature | How MziziGuard uses it |
|---|---|
| Few-shot learning | Only 5–10 images per disease class |
| CPU-only | Runs on any laptop, no GPU required |
| Offline capable | Full functionality with no internet |
| Human-in-the-loop | Teach tab corrects wrong predictions instantly |
| Calibrated confidence | Shows confidence % with every diagnosis |
| OOD detection | Flags non-crop images instead of guessing |
| Eco mode | eco_mode: true in config.yaml |
| Calibration report | Health tab shows ECE, temperature, metrics |
| Model persistence | save_model() / load_model() — resumes between sessions |
| Batch processing | Process entire folders of farmer photos at once |
| YAML configuration | Easy to add new crops/diseases without code changes |
| Swahili localization | Every diagnosis includes Swahili name + treatment advice |
Next Steps¶
- Launch the full app:
python -m examples.mziziguard.app - Edit
config.yamlto add your own crops and diseases - Try loading real images with
load_images_from_dir()instead of synthetic - Present the terminal demo to non-technical audiences using
--no-pause - Check the Full API Reference for all
FewShotLearnermethods
Created by Johnson Christopher Hassan
Connect on LinkedIn
Project: github.com/johnson2006christopher/adaptshot