Repository navigation
feat(benchmarks): dish-ambiguity-v1 — taxonomy, manifests, and evaluated classifier pins - #57
Draft
obvious-autobuild[bot] wants to merge 6 commits into
Draft
obvious-autobuild[bot] wants to merge 6 commits into
obvious-autobuild[bot] wants to merge 6 commits into
Conversation
…pping Freeze the Food-101 -> bundled-recipe mapping for the dish-ambiguity benchmark: 101 classes -> 11 exact, 3 coarse, 2 ambiguous, 85 unsupported against the 166-recipe bundled catalog, each entry with catalog-evidenced reason and near-miss notes. - check_manifest.py validates class coverage, recipe existence, status-shape rules, exact/coarse uniqueness, ambiguous/no-exact overlap, stratification and >=2000 manifest requirements, and dHash near-duplicate discipline between dev and test manifests - build_manifest.py does seeded stratified sampling (25 official test images/class; dev from train with near-duplicate exclusion) - tests/ plants duplicate-group, unsupported-exact-recipe, and ambiguous double-booking conflicts and asserts the validator exits 1 on each; the real committed mapping must pass end-to-end (12 passed) - taxonomy-summary.json: 25/166 recipes claimed; 14 eligible classes -> 350/2525 sampled test images suggestion-eligible Note: this Food-101 distribution's meta/classes.txt has no 'cheeseburger' class (verified against the official tarball), so the burger family is represented by 'hamburger' alone. Checks: python3 check_manifest.py -> OK (exit 0); pytest 12 passed; planted duplicate and unsupported-exact demos both exit 1 with the expected ERROR lines.
Build the sampling manifests from the official Food-101 splits:
- manifest.json: 25 images per class from the official test split
(2,525 total), seeded (default_rng(20261010)), sorted-order
deterministic, with per-image sha256 and 64-bit dHash
- dev_manifest.json: 6 per class from the official train split
(606 total); near-duplicates of any test image (dHash Hamming <= 10,
development-only threshold) are excluded AND refilled from the same
seeded shuffle so stratification stays exact at 6/class
- dev-near-duplicates-dropped.json records the 5 exclusions with
their minimum Hamming distances
Also fixes build_manifest.py image paths to include the class
directory (images/<class>/<id>.jpg) and reads this distribution's
split files at meta/{split}.txt (not *_list.txt).
Rebuild determinism verified byte-for-byte (md5sum -c OK for both
manifests). check_manifest.py passes; pytest 12 passed.
Run both pinned Food-101 classifiers over the committed test + dev manifests on CPU and score the dish-ambiguity question end to end: - run.py: verifies pinned weight hashes, runs each model over both manifests, records per-image top-5 predictions with latency, retains per-image failures, emits run metadata (weight sha256, manifest hashes, peak RSS); 0 failures recorded across all runs - score.py: per-class stratified top1/top5 accuracy; abstention policy (suggest only exact-status predicted classes above a dev selected tau targeting 0.90 suggestion precision); deterministic report whose committed bytes are re-verified with --verify-report - results/: predictions, run metadata, scored.json, report.md Findings: nateraw/vit-base-food101 @ 55859a2 reaches top1 0.8075 / top5 0.9620 and, at tau 0.1, emits specific recipe suggestions at 1.000 precision with 0.500 coverage over the 350 eligible test images. rajkr/mobilenet-v2-food101 @ 0dea82e7 is broken: top1 0.0614 with a confident collapse onto five labels (no probability threshold separates right from wrong); its output was verified identical to the canonical HF pipeline, so the checkpoint is at fault. Dev cannot reach the precision target for it, so its tau is reported as unvalidated. Checks: pytest 18 passed; score.py --verify-report passes twice consecutively; canonical-pipeline cross-check on 30 images.
|
Important Review skippedBot user detected. To trigger a single review, invoke the ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…icted precision Review fixes for the dish-ambiguity-v1 evaluation (PR #57): - run.py/score.py: emitted paths are repo-relative when inside the checkout and bare names otherwise (previously absolute /home/user paths leaked into prediction metadata, run-metadata.json, and the report header); committed artifacts re-pointed without touching any pinned weight/output hash or prediction payload - score.py --verify-report confirmed from a different working directory (cwd-independent: both scripts anchor on __file__) - report now leads with unrestricted suggestion precision (175/183 = 0.9563, coverage 0.0725) and keeps the eligible-only statistic (175/175 = 1.0 precision at 0.500 coverage) clearly separate; suggestion_stats records the correct count - README: findings reordered to match, plus a Handoff section for wiring the policy into the app (pin, threshold, re-verification, open items) Checks: pytest 18 passed; score.py --verify-report OK from /tmp; no /home/user paths remain under benchmarks/dish-ambiguity-v1/results. Co-authored-by: obvious-autobuild[bot] <262744130+obvious-autobuild[bot]@users.noreply.github.com>
…hashes The Handoff section reported earlier did not survive into commit 9d84084 (only the findings reorder landed). Adding it for real: - pin: nateraw/vit-base-food101 @ 55859a2 (weights sha256 recorded in results/run-metadata.json); MobileNet explicitly not pinnable - policy: exact-status classes only, top1 >= tau 0.1, quoting unrestricted precision (175/183 = 0.9563) and eligible-only precision (175/175 = 1.000 at 0.500 coverage) with separate denominators; unsupported/ambiguous classes render dish identity, never a native bundled recipe - exact frozen manifest hashes (verified against the committed files and results/run-metadata.json): test manifest.json 85ae3fb0...2ec2, dev_manifest.json 90dd25db...15c6; a rebuild that hashes differently must not be rescored against - resume/verification commands (check_manifest, run, verify-report, pytest) and open items (per-class thresholds, tau transfer, macOS CI pending) No code changes; pinned weights/outputs and the 21-file diff are untouched. Co-authored-by: obvious-autobuild[bot] <262744130+obvious-autobuild[bot]@users.noreply.github.com>
feat/routing-eval-harness is stale against the current integration branch (alpha is 64 commits ahead), so PR #57 is ported onto alpha: merging origin/alpha (0309dd1) into obv/fl-l2-dish-ambiguity. No conflicts - alpha does not touch benchmarks/dish-ambiguity-v1 - and the study diff, pinned weights/outputs, frozen manifest hashes, and committed evidence are preserved byte-identically (git diff a6c921a..HEAD -- benchmarks/dish-ambiguity-v1 is empty). Re-verification runs on the merged head: check_manifest.py, pytest (18), score.py --verify-report. Co-authored-by: obvious-autobuild[bot] <262744130+obvious-autobuild[bot]@users.noreply.github.com>
obvious-autobuild
Bot
changed the base branch from
feat/routing-eval-harness
to
alpha
October 15, 2026 12:53
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Port onto alpha (2026-10-15, head
e6fa5b3)The original base
feat/routing-eval-harnessis stale:alpha(the current integration branch) is 64 commits ahead of it. The change is ported ontoalphaby mergingorigin/alpha@0309dd1intoobv/fl-l2-dish-ambiguity(merge commite6fa5b3, no conflicts; the PR base is retargeted toalpha). The merge brings in alpha's iOS/CI/skills changes only - it does not touchbenchmarks/dish-ambiguity-v1.Evidence preservation, verified on the merged head:
git diff a6c921a..e6fa5b3 -- benchmarks/dish-ambiguity-v1is empty: the 21-file study diff, all committed predictions/scored/report artifacts, and the pinned weight/output hashes are byte-identical to the reviewed heada6c921a.check_manifest.py→ exit 0 on the merged tree.python3 -m pytest benchmarks/dish-ambiguity-v1/tests -q→ 18 passed.python3 benchmarks/dish-ambiguity-v1/score.py --verify-report→ verify OK (scored.json and report.md byte-identical to committed).manifest.json85ae3fb06242bf542df026ba03e9e2e53faae690fe50b53eba7e12a984a12ec2, developmentdev_manifest.json90dd25dbc785a22a90b5efd6b98608ef25b38b62d36311f9a96b6701d71615c6(both matchresults/run-metadata.json).build-and-testpass (6m40s) anddead-code-advisorypass (3m10s).Everything below (the original dish-ambiguity experiment) is unchanged.
What changed and why
benchmarks/dish-ambiguity-v1answers the routing question: when a fridge photo is classified into one of Food-101's 101 dish labels, when can the app safely show a specific bundled recipe? Food-101 classes and the 166-recipe bundled catalog overlap only partially, and some labels are genuinely ambiguous (e.g.apple_pievscheesecake-family renders), so a blind "show recipe for the predicted dish" policy can render the wrong recipe with high confidence.Three commits, one per milestone, then review-fix commits:
f3fe481): every Food-101 class is mapped to the bundled catalog with statusexact(one recipe answer),coarse(an equivalence class of recipes),ambiguous(multiple non-equivalent renders; no answer claimable), orunsupported(nothing close in the catalog). 11 exact / 3 coarse / 2 ambiguous / 85 unsupported.check_manifest.pyvalidates coverage, recipe existence, uniqueness, and no-overlap rules.05c6ef0): seeded stratified samples from the official Food-101 splits - 25 test images/class (2,525) and 6 dev images/class (606), with per-image sha256 + dHash; 5 dev near-duplicates of test images excluded and refilled. Rebuild is byte-identical.12c1f23): both pinned classifiers run over both manifests on CPU; scorer computes accuracy + a dev-selected abstention threshold (suggest onlyexact-status predictions above tau, targeting 0.90 suggestion precision on dev, coverage-maximizing), and the committed report/scored JSON are re-verifiable byte-for-byte viascore.py --verify-report.9d84084): emitted paths canonicalized (repo-relative inside the checkout, bare names otherwise; no/home/userunder the committed results),--verify-reportconfirmed from a different working directory, and the report/README lead with unrestricted suggestion precision.a6c921a): the README Handoff section (the one reported for9d84084had not landed in that commit) with the frozen manifest hashes.Headline results
nateraw/vit-base-food101@55859a2is the only viable pin: top1 0.8075, top5 0.9620 (2,525 test images). At the dev-selected tau (0.1), unrestricted suggestion precision is 175/183 = 0.9563 (coverage 0.0725) across all test images. Restricted to the 350 eligible test images (true class exact/coarse), precision is 175/175 = 1.000 at 0.500 coverage. Recommendation: adopt it for recipe suggestion with this abstention policy; abstain otherwise.rajkr/mobilenet-v2-food101@0dea82eis broken: top1 0.0614 via a confident collapse - five labels absorb 2,196/2,525 predictions, often with top1 probability ~1.0, so no threshold can separate right from wrong. Cross-checked against the canonical HFimage-classificationpipeline at the same revision (identical outputs), so the checkpoint is at fault, not our runner.How I checked it
Re-verified in this review round at head
a6c921a, from a fresh independent worktree oforigin/obv/fl-l2-dish-ambiguity:cd /tmp && python3 /home/user/work/fridgeluck-57-review/benchmarks/dish-ambiguity-v1/score.py --verify-report→score: verify OK - scored.json and report.md byte-identical to committed(exit 0). The same command from the checkout root gives the identical output and exit 0.grep -rn "/home/user" benchmarks/dish-ambiguity-v1/results benchmarks/dish-ambiguity-v1/*.py benchmarks/dish-ambiguity-v1/README.md→ no matches. The report emitsResults: benchmarks/dish-ambiguity-v1/results(repo-relative).git diff 12c1f23..a6c921ashows the only changes to prediction payloads andrun-metadata.jsonare path strings (/home/user/...→ repo-relative/bare); model repo/revision/weights-sha256 pins, dataset tarball sha256, and manifest sha256s are byte-identical.precision 175/183 = 0.9563, coverage 0.0725over 2,525), and the eligible-only statistic on a separate line with a separate denominator (175/175 = 1.0, coverage 0.5over the 350 eligible images); the README Results section leads with unrestricted 175/183 for the recommended pin. The two claims are never blended.python3 -m pytest benchmarks/dish-ambiguity-v1/tests -q→ 18 passed (validator planted failures + scoring hand controls); re-run at head.python3 check_manifest.py→ exit 0 (check_manifest: OK); re-run at head.md5sum -cOK, byte-identical (at evaluation time).results/run-metadata.json).d97d15e4…4053a4, 101 classes, nocheeseburgerclass in this distribution.Handoff
For whoever wires recipe suggestion into the app:
nateraw/vit-base-food101@55859a2a1349(weights sha25661f707d9d423461b..., recorded inresults/run-metadata.json). Do not pinrajkr/mobilenet-v2-food101@0dea82e- the checkpoint is broken (see Headline results); if a small mobile model is wanted, re-run this benchmark over a replacement candidate before trusting it.exactinmapping.food101-v1.json, and (b) its top1 probability >= 0.1. Expected test behavior: unrestricted suggestion precision 175/183 = 0.9563 (coverage 0.0725), eligible-only precision 175/175 = 1.000 at 0.500 coverage on the 350 eligible images - keep the two denominators separate when quoting. Show nothing otherwise; unsupported/ambiguous classes should render dish identity only.python3 benchmarks/dish-ambiguity-v1/score.py --verify-report(works from any directory; byte-compares the committed report - confirmed from/tmpat heada6c921a). Full reproduction:run.py --dataset-root <food-101> --out benchmarks/dish-ambiguity-v1/results, thenscore.py; validate first withcheck_manifest.py, tests withpython3 -m pytest benchmarks/dish-ambiguity-v1/tests -q.a6c921a, must matchresults/run-metadata.json): testmanifest.json(2,525 images)85ae3fb06242bf542df026ba03e9e2e53faae690fe50b53eba7e12a984a12ec2; developmentdev_manifest.json(606 images)90dd25dbc785a22a90b5efd6b98608ef25b38b62d36311f9a96b6701d71615c6. Both are committed; changing either is a reproducibility break, not a tweak - rebuild withbuild_manifest.pyand re-pin deliberately. A rebuild that hashes differently is a different sample - do not rescore the committed results against it.python3 benchmarks/dish-ambiguity-v1/check_manifest.py(exit 0 = taxonomy/manifest consistency; re-verified at head),python3 -m pytest benchmarks/dish-ambiguity-v1/tests -q(18 passed at head), thenscore.py --verify-reportabove.What I could not check
Assumptions
meta/classes.txtlackscheeseburger; the burger family is represented byhamburgeralone, so the frozen class list is authoritative.exact-status predictions only) is the minimal deployable policy; per-class thresholds are future work.Human author: Sam Gu (sgu07966@gmail.com)
🔗 Obvious Project · 🧵 Obvious Thread · 🔀 Obvious PR Artifact