Skip to content

Real-World Use Cases

AdaptShot was built for resource-constrained environments. This guide shows concrete, runnable examples of how the library solves real problems in agriculture, healthcare, conservation, and manufacturing.

Every example in this guide uses the same core API (FewShotLearner) and runs CPU-only with <250MB RAM. No GPU. No cloud. No large datasets.


1. Agriculture: Crop Disease Detection

Problem: A small-scale farmer needs to identify cassava mosaic virus from leaf photos. They have 10 reference images, a $50 Android phone, and no internet in the field.

Solution: Classify a field photo against a small support set of healthy and diseased leaves. Route uncertain predictions to a human expert for verification.

Runnable Example

"""Crop disease detection -- 10 support images, 2 classes."""
import tempfile
from pathlib import Path

import numpy as np
from PIL import Image

from adaptshot import FewShotLearner
from adaptshot.config.settings import AdaptShotConfig


def make_leaf_image(path: Path, green: int, brown: int, seed: int) -> None:
    """Create a synthetic leaf-like image (green=healthy, brown=blighted)."""
    rng = np.random.default_rng(seed)
    arr = np.zeros((224, 224, 3), dtype=np.uint8)
    arr[:, :, 0] = brown       # Red channel (brown tint)
    arr[:, :, 1] = green       # Green channel
    arr[:, :, 2] = rng.integers(0, 40, size=(224, 224), dtype=np.uint8)
    noise = rng.integers(0, 25, size=(224, 224, 3), dtype=np.uint8)
    arr = np.clip(arr + noise, 0, 255).astype(np.uint8)
    Image.fromarray(arr).save(path)


with tempfile.TemporaryDirectory(prefix="crop_disease_") as tmp:
    root = Path(tmp)
    (root / "healthy").mkdir()
    (root / "blight").mkdir()

    image_paths: list[str] = []
    labels: list[str] = []

    # 5 healthy leaves
    for i in range(5):
        p = root / "healthy" / f"leaf_{i}.png"
        make_leaf_image(p, green=180, brown=20, seed=i)
        image_paths.append(str(p))
        labels.append("healthy")

    # 5 blighted leaves
    for i in range(5):
        p = root / "blight" / f"leaf_{i}.png"
        make_leaf_image(p, green=60, brown=160, seed=100 + i)
        image_paths.append(str(p))
        labels.append("blighted")

    # Field photo (blighted)
    field = root / "field_photo.png"
    make_leaf_image(field, green=55, brown=170, seed=999)

    # Configure for field deployment
    config = AdaptShotConfig(
        backbone="mobilenet_v3_small",  # Lightweight for phone CPU
        device="cpu",
        seed=42,
        max_buffer_size=50,
        eco_mode=True,                   # Save battery
        early_exit_threshold=0.90,
    )
    learner = FewShotLearner(config=config)
    learner.load_support_images(image_paths, labels)

    # Diagnose
    result = learner.predict(str(field))
    print(f"Crop diagnosis: {result.prediction}")
    print(f"Confidence: {result.calibrated_confidence:.1%}")

    if result.uncertainty_flag:
        # Route to agricultural extension officer for review
        print("Uncertain diagnosis -- routing to human expert.")
        learner.correct(
            image_path=str(field),
            true_label="blighted",
            confidence_weight=0.95,  # Expert is very sure
        )
        print("Correction recorded. Model will improve for next diagnosis.")

Key Takeaways: - mobilenet_v3_small keeps the model small enough for phone deployment - eco_mode=True extends battery life in the field - Human corrections accumulate over time, improving accuracy for the entire community


2. Healthcare: Pneumonia Triage from Chest X-Rays

Problem: A rural clinic has a basic X-ray machine but no radiologist. The nurse needs to flag urgent pneumonia cases for transfer to a city hospital versus routine cases that can wait.

Solution: Train AdaptShot on 15 labeled X-rays (10 pneumonia, 5 normal) and use it to triage new cases. High-confidence pneumonia predictions get flagged for immediate transfer.

Usage Pattern

# Support set: 10 pneumonia X-rays, 5 normal X-rays
xray_paths = [
    "xrays/pneumonia_01.png", "xrays/pneumonia_02.png",  # ... 10 total
    "xrays/normal_01.png", "xrays/normal_02.png",        # ... 5 total
]
xray_labels = (["pneumonia"] * 10) + (["normal"] * 5)

config = AdaptShotConfig(
    backbone="resnet18",           # Higher accuracy for medical use
    calibration_method="scaling_binning",  # Finer calibration
    enable_ood_detection=True,     # Flag unusual images
    ood_threshold_quantile=0.95,   # Conservative threshold
    recalibrate_after_feedback=True,
)
learner = FewShotLearner(config=config)
learner.load_support_images(xray_paths, xray_labels)

# Triage a new patient
result = learner.predict("xrays/new_patient.png")

if result.prediction == "pneumonia" and result.calibrated_confidence > 0.85:
    print("URGENT: Transfer to city hospital immediately.")
elif result.uncertainty_flag or result.ood_flag:
    print("Uncertain: Send image to remote radiologist for review.")
else:
    print("Normal: Patient can wait for routine follow-up.")

Key Takeaways: - Medical use cases demand high calibration quality -- scaling_binning provides finer control than temperature - OOD detection catches images that don't look like any training example (different equipment, patient positioning) - The human-in-the-loop loop builds a growing corpus of labeled examples


3. Conservation: Wildlife Camera Trap Classification

Problem: A conservation NGO has camera traps in a remote national park. They collect thousands of images but can only label a few dozen manually. They need to classify remaining images as containing endangered species or common animals.

Solution: Use a small labeled support set to seed AdaptShot, then run batch prediction on the remaining images. Flag uncertain classifications for human review by a conservation biologist.

Batch Processing Pattern

from pathlib import Path

# 20 labeled support images (10 endangered, 10 common)
support_paths = list(Path("labeled/endangered").glob("*.jpg"))[:10]
support_paths += list(Path("labeled/common").glob("*.jpg"))[:10]
support_labels = (["endangered"] * 10) + (["common"] * 10)

config = AdaptShotConfig(
    backbone="resnet18",
    device="cpu",
    max_buffer_size=200,        # Larger buffer for batch processing
    use_faiss=True,             # FAISS for faster search with many images
    enable_ood_detection=True,
)
learner = FewShotLearner(config=config)
learner.load_support_images(
    image_paths=[str(p) for p in support_paths],
    labels=support_labels,
)

# Batch predict on unlabeled camera trap images
unlabeled = list(Path("unlabeled").glob("*.jpg"))
results = {
    "endangered_high_conf": [],
    "endangered_needs_review": [],
    "common": [],
    "ood_rejected": [],
}

for img_path in unlabeled:
    result = learner.predict(str(img_path))

    if result.ood_flag:
        results["ood_rejected"].append(str(img_path))
    elif result.prediction == "endangered":
        if result.uncertainty_flag:
            results["endangered_needs_review"].append(str(img_path))
        else:
            results["endangered_high_conf"].append(str(img_path))
    else:
        results["common"].append(str(img_path))

print(f"Endangered (high confidence): {len(results['endangered_high_conf'])}")
print(f"Endangered (needs review):   {len(results['endangered_needs_review'])}")
print(f"Common animals:              {len(results['common'])}")
print(f"OOD / rejected:              {len(results['ood_rejected'])}")

Key Takeaways: - FAISS acceleration (use_faiss=True) improves batch throughput for large image sets - Larger max_buffer_size accommodates growing support sets as corrections accumulate - OOD detection prevents false positives on animals never seen before


4. Manufacturing: Defect Detection from Few Reference Images

Problem: A small factory needs to detect manufacturing defects on circuit boards. They have 8 photos of "good" boards and 6 photos of "defective" boards. Defects are rare and varied.

Solution: Train AdaptShot on the small support set and use it to screen new boards. Route defect predictions to a quality control engineer for confirmation.

Usage Pattern

config = AdaptShotConfig(
    backbone="resnet18",
    inference_mode="prototypical",    # Better with imbalanced classes
    similarity_metric="cosine",       # Direction matters more than magnitude
    calibration_method="temperature",
    recalibrate_after_feedback=True,
)
learner = FewShotLearner(config=config)
learner.load_support_images(
    image_paths=["good_01.jpg", "good_02.jpg", ..., "defect_06.jpg"],
    labels=["good", "good", ..., "defective"],
)

# Screen a new board
result = learner.predict("board_new.jpg")

if result.prediction == "defective":
    print("Potential defect detected -- route to QC engineer.")
    if result.calibrated_confidence < 0.80:
        print("Low confidence -- request immediate human verification.")
elif result.uncertainty_flag:
    print("Uncertain -- flag for manual inspection.")
else:
    print("Pass: board appears defect-free.")

Key Takeaways: - prototypical inference mode handles imbalanced classes better than nearest-neighbor - cosine similarity focuses on direction (shape features) rather than magnitude (brightness) - Corrections from QC engineers continuously refine the model


5. Education: Learning Disability Screening from Handwriting

Problem: A rural teacher needs to screen for early signs of dysgraphia (writing difficulty) using samples of student handwriting. They have 12 reference samples and no specialist available on-site.

Solution: AdaptShot can classify handwriting samples against known patterns, flagging students who may need specialist evaluation.

Usage Pattern

config = AdaptShotConfig(
    backbone="mobilenet_v3_small",
    device="cpu",
    max_buffer_size=30,
    early_exit_threshold=0.92,
)
learner = FewShotLearner(config=config)
learner.load_support_images(
    image_paths=[...],  # Handwriting samples as images
    labels=[...],       # "typical", "needs_evaluation"
)

result = learner.predict("student_sample.jpg")
if result.prediction == "needs_evaluation":
    print("Recommend specialist evaluation.")
else:
    print("Writing appears within typical range.")

6. MziziGuard: Deployed Crop Disease Detection

MziziGuard is a complete, production-ready application built entirely on AdaptShot. It's deployed as a Gradio web application with 5 interactive tabs and runs on a standard laptop with no internet.

Architecture

Farmer takes photo → MziziGuard Web UI → MziziGuard Engine → AdaptShot FewShotLearner
                                                                    → ResNet-18 Backbone
                                                                    → Similarity Search
                                                                    → Calibration + ACT + OOD
                                                                    → DiagnosisResult (Swahili + Action)

Key Numbers

Metric Value
Training images needed 5 per disease class
Supported crops Configurable via YAML
Languages English + Swahili
Memory usage <250MB
Inference latency ~150ms on CPU
Internet required No (after install)

How to Deploy

pip install "adaptshot[ui]"
python -m examples.mziziguard.app
# → http://localhost:7860

Full guide: MziziGuard Complete Guide


General Patterns Across All Use Cases

Concern Config Choice Why
Battery life eco_mode=True, mobilenet_v3_small Reduces compute and energy
Medical accuracy resnet18, scaling_binning Higher accuracy, finer calibration
Many images use_faiss=True FAISS accelerates batch search
Rare classes inference_mode="prototypical" Better with imbalanced support sets
Unknown inputs enable_ood_detection=True Flags images outside known distribution
Growing knowledge recalibrate_after_feedback=True Model improves with every correction

Profiling and Monitoring Across Use Cases — v0.2.0

Every deployment should incorporate production monitoring. Here is how to add profiling to any use case:

Add Memory Tracking

from adaptshot.profiling import MemoryTracker

tracker = MemoryTracker()
tracker.start()

# In your inference loop:
with tracker.section("batch_inference"):
    for img_path in unlabeled_images:
        result = learner.predict(img_path)

report = tracker.get_report()
if report['peak_memory_mb'] > 250:
    print(f"⚠️ Memory budget exceeded: {report['peak_memory_mb']:.0f} MB")

Add Penalty Trend Monitoring

# After each correction, check penalty trends
if hasattr(learner, 'explainability_engine'):
    penalties = learner.explainability_engine.get_penalty_summary()
    if penalties.get('global_trend') == 'degrading':
        print("⚠️ Model penalties are increasing — consider refreshing support set")

Periodic Cache Clearing

# For long-running services (conservation camera traps, manufacturing QC):
# Clear backbone cache every 1000 predictions
if prediction_count % 1000 == 0:
    learner.clear_backbone_cache()

Use Case Monitoring Matrix

Use Case Key Metric Alert Threshold Action
Crop Disease Memory peak > 200 MB Reduce max_buffer_size
Medical Triage ECE > 0.10 Recalibrate with scaling_binning
Camera Traps Penalty trend "degrading" Refresh support set
Manufacturing OOD rate > 20% Add more "defective" examples
Education Latency > 500 ms Switch to mobilenet_v3_small

Verification Checklist

  • [ ] You can run the crop disease example on your machine.
  • [ ] You understand how to adapt the batch processing pattern to your own dataset.
  • [ ] You know which config changes to make for each domain (medical vs. field vs. factory).
  • [ ] You understand that AdaptShot's role is to augment human expertise, not replace it.

Created by Johnson Christopher Hassan
Connect on LinkedIn
Project: github.com/johnson2006christopher/adaptshot