Inspiration
Every consumer mushroom-ID app is optimized to always return a species — and the best one is 44% accurate on toxic mushrooms; iNaturalist is 40%. The problem isn't accuracy, it's calibration: these models hand back a confident label even when they're wrong, and people have been hospitalized acting on it. In safety-critical field ID — where a false positive can be fatal and there's often no signal — "always answer" is the wrong objective function. We're foragers; the gap was obvious. So we built a classifier that abstains: "I can't confirm this" as a first-class output, not a failure.
What it does
Morel Compass is an offline-first PWA. You snap or upload a photo of a mushroom, and an on-device model either identifies it or refuses:
- Confident on a known-safe species → "consistent with chanterelle — verify the features, never eat on an app ID alone."
- Uncertain, or it resembles a toxic lookalike → "⚠ I can't confirm this — NOT CERTIFIED."
It runs fully offline — the forager who needs it is standing in a forest with no signal. Under the classifier sits a deterministic safety gate so a confident-but-wrong prediction can still be caught by hard rules. It never says "edible." The refusal is the product.
How we built it
- Frontend: React + Vite, installable PWA, dark scanner UI.
- On-device inference: ONNX Runtime Web (WebAssembly) — the model runs in the browser, no cloud, no app store, offline via a service worker + IndexedDB cache.
- Model: MobileNetV3-Small fine-tuned in PyTorch → exported to ONNX (~6 MB), 9 classes (8 forageable species + a reject class trained on toxic lookalikes). Trained on GBIF CC0/CC-BY images on an Apple-Silicon Mac (M2 / MPS).
- Safety logic: calibrated abstention (confidence threshold + reject option) plus a deterministic danger-marker gate — a real ML technique, not a warning label.
- Online enrichment: Tavily for live regional hazard data when a signal is available.
Challenges we ran into
- TensorFlow → ONNX was a dead end —
tf2onnxand TF 2.20 have an irreconcilable protobuf version conflict. We diagnosed it and pivoted the whole pipeline to PyTorch, wheretorch.onnx.exportjust works. - On-device ML in a browser — getting a 6 MB ONNX model to load, cache, and infer offline in mobile Safari (WASM fallback, service-worker precache, cache-warming).
- The core insight, learned the hard way: raising accuracy alone can never reach zero toxic-false-positives. A threshold sweep proved the model stays confidently wrong on a few hard toxics no matter how high you set it — so a deterministic safety gate is non-negotiable (layered defense).
- Fine-grained classification — telling safe species from deadly lookalikes (morel vs. false morel) is exactly where the danger lives.
Accomplishments that we're proud of
- A working, fully-offline, on-device AI PWA shipped in a day.
- We inverted the objective: optimizing for a safe failure mode (refuse) instead of raw top-1 accuracy — the metric that actually matters for a life-or-death decision is "how often confidently wrong," and we drove that down.
- The refusal moment: the app declines to confirm a death cap instead of guessing.
- Honest engineering — purpose-built models behind a safety gate, not a general LLM prompted to sound sure.
What we learned
- For safety-critical ID, calibration beats accuracy — an AI that abstains is more useful than one that's confidently wrong.
- On-device browser ML is production-viable in 2026 (ONNX Runtime Web).
- The model can't guarantee safety by itself — you need abstention + a deterministic gate.
- PyTorch → ONNX is the clean edge-deployment path; TF → ONNX is a trap.
What's next for Morel Compass
- The correction flywheel — every field confirm/correct becomes on-device, safety-labeled training data on the scarce distribution (toxic-lookalike edge cases). The loop, not the corpus, is the moat.
- Named toxic classes — so it can warn "this is a death cap", not just "not certified."
- Broad coverage via an iNaturalist-pretrained backbone (thousands of species).
- Habitat-suitability map tiles (species-distribution modeling) — "where are morels likely this week."
- The generalization — the same calibrated-abstention engine applies to any high-stakes, offline field decision: toxic plants, envenomation triage, agricultural disease.
Built With
- cloudflare
- computer-vision
- edge-ai
- gbif-api
- indexeddb
- machine-learning
- mobilenetv3
- onnx
- pwa
- python
- pytorch
- react
- tavily
- typescript
- vite
- webassembly
Log in or sign up for Devpost to join the conversation.