Skip to content

Model Tester GUI

The test_model.py script provides a standalone web GUI for testing exported models on individual images. It auto-discovers all available checkpoints and lets you visually predict the species and breed of any cattle or buffalo image.


Quick Start

# After training (or using an exported model):
python test_model.py

This opens a browser at http://localhost:8501 with the GUI.


Features

  • Drag & Drop / File Upload: Supports PNG, JPG, JPEG, BMP, and WebP formats
  • Model Selector: Auto-discovers all available checkpoints:
  • Phase 1/2/3 training checkpoints (outputs/checkpoints/)
  • INT8 quantized models (lite2_quantized.pt)
  • Portable export bundles (outputs/export/portable/)
  • Prediction Results:
  • Species classification: Cattle or Buffalo with confidence %
  • Top-5 breed predictions with animated confidence bars
  • Model metadata footer (which model was used, device info)
  • Dual Modes (--dev vs --present):
  • Developer Mode (--dev): The default mode providing full technical insights (EXIF metadata, detailed stats, data json viewer, and presenter configuration).
  • Presenter Mode (--present): A clean, distraction-free UI ideal for demonstrations, which hides technical clutter and removes export functionalities.
  • Presenter Configuration: Interactive toggles in dev mode let you control branding, visible sections, and confidence metrics. Settings are persisted seamlessly across server restarts via outputs/logs/presenter_config.json.
  • Comprehensive Logging: Every action (server start, model load, prediction trace) is logged out to outputs/logs/ automatically.
  • Zero Config: Works out of the box with any trained checkpoint

Usage

# Auto-open browser at http://localhost:8501
python test_model.py

# Custom port
python test_model.py --port 9000

# Don't auto-open browser
python test_model.py --no-browser

CLI Flags

Flag Description
--port N Port to serve on (default: 8501)
--no-browser Don't auto-open the browser window
--dev Start in developer mode (default). Shows full technical UI and presenter settings.
--present Start in presenter mode. Hides detailed stats and limits confidence metrics.

How It Works

┌─────────────┐     POST /api/predict     ┌──────────────────┐
│  Browser UI  │ ─────────────────────────▶│  test_model.py   │
│  (HTML/JS)   │                           │  HTTP Server     │
│              │◀───────────────────────── │                  │
│  Shows Top-5 │     JSON response         │  ModelManager    │
│  breed bars  │                           │  ├─ load model   │
└─────────────┘                            │  ├─ preprocess   │
                                           │  └─ predict      │
                                           └──────────────────┘
  1. ModelManager scans outputs/checkpoints/ and outputs/export/portable/ on startup
  2. User uploads an image and selects a model in the browser
  3. Image is sent as multipart/form-data to POST /api/predict
  4. The model runs inference and returns species + top-5 breeds as JSON
  5. The browser renders animated confidence bars

API Endpoints

Method Path Description
GET / Serves the HTML GUI
GET /api/models Returns available models + device info
POST /api/predict Accepts image (file) + model (name), returns prediction
GET /api/cattle-data Returns cattle class mappings
GET /api/buffalo-data Returns buffalo class mappings
GET /api/presenter-config Returns saved presenter UI configuration
POST /api/presenter-config Saves updated presenter UI configuration

Example /api/predict Response

{
  "species": "Cattle",
  "species_confidence": 98.4,
  "top_breed": "Gir",
  "top_breed_confidence": 91.2,
  "top5_breeds": [
    {"breed": "Gir", "confidence": 91.2},
    {"breed": "Sahiwal", "confidence": 3.1},
    {"breed": "Red Sindhi", "confidence": 1.8},
    {"breed": "Tharparkar", "confidence": 1.1},
    {"breed": "Kankrej", "confidence": 0.6}
  ],
  "gender": {
    "label": "Female (Cow)",
    "short_label": "Female",
    "confidence": 86.5,
    "method": "clip_zeroshot",
    "note": "Visual estimation from body/udder profile"
  },
  "age_group": {
    "label": "Adult (> 3 yrs)",
    "short_label": "Adult",
    "confidence": 89.1,
    "method": "clip_zeroshot",
    "note": "Visual stage estimate; verify via dentition (teeth) for exact age"
  },
  "traits": {
    "hump": "Large / Prominent",
    "horn": "Curved (Half-moon)",
    "ear": "Long & Pendulous",
    "dewlap": "Large & Pendulous",
    "size": "Medium-Large"
  },
  "knowledge": {
    "headline": "Gir adult female — protect lactation: 8 - 12 L/day ...",
    "priority_actions": ["Milk 2-3 times a day ..."],
    "nutrition": {"green_fodder": "22 - 30 kg/day", "...": "..."},
    "production": {"milk": {"daily_yield": "8 - 12 L/day", "...": "..."}},
    "economics": {"market_price": "₹45,000 - ₹100,000", "schemes": ["..."]},
    "disclaimer": "General guidance only — confirm with your veterinarian ..."
  },
  "ood": false,
  "model_used": "lite2_phase2_best_v26_1012-2332_f9ce"
}

The same enriched payload (gender, age_group, traits, knowledge, plus traits_detail / attributes_meta for developer views) is returned by the Flask server's POST /api/predict in server/routes/predict.py. See docs/attributes.md for how each attribute is produced and docs/breed-knowledge.md for the advisory engine and the /api/breed-knowledge/... + /api/advisory-recalculate endpoints.


Workflow

After training with local_train.py:

# 1. Train (any mode)
python local_train.py --quarter-data

# 2. Test exported models visually
python test_model.py

# 3. Upload any cattle/buffalo image in the browser
# 4. See species + breed prediction with confidence

OOD Calibration from a Breed-Named Folder

The OOD tools card (🧪 OOD Calibration & Dataset) now calibrates thresholds from any folder of breed-named images for the model selected in Inspect Model:

Control Meaning
Breed-named image folder Free text with a picker of repository folders. Flat (Deoni_01.jpg) and nested (cattle/deoni/…) layouts are both supported
Percentile Energy percentile used as the threshold (default 95)
Max images Upper bound on images used (default 500)

Press 🔄 Recalibrate OOD to run it. The result shows the new thresholds, the sample count, matched/unmatched images, the per-breed coverage and the path of the saved profile (outputs/ood/<model>.json). Unmatched names are listed so a mis-named folder is visible instead of silently skewing the thresholds.

Leave the folder empty to recalibrate on the generated validation split, as before.


Requirements

  • Trained model checkpoint(s) in outputs/checkpoints/ or outputs/export/portable/
  • No class-map JSON required — maps, resolution, normalization mode and OOD thresholds are read from the model itself (src/model_introspect.py). Legacy data/splits/*.json / outputs/ood/*.json are still honoured as a fallback. Run python scripts/embed_metadata.py --all to bake the contract into older artifacts. See Self-Describing Models.
  • Python packages: torch, torchvision, Pillow (installed by local_train.py)