Repository navigation
Eval: score.py with tests on synthetic boxes - #9
Merged
Merged
Conversation
score.py scores a detections file against the manifest as part B of the protocol defines it. Masks are rounded outward to whole pixels, as the app paints them, and each face's covered share is computed exactly from those pixels, so faces under the rotation transform need no special case. It reports the miss rate, the share covered completely, recall at IoU 0.5 and false masks per image, each with a 95% bootstrap interval over images, broken down by face size, occlusion, truncation and yaw, and finds the operating point on the tune split. transforms.py holds the rotation geometry, matched to Pillow. Contract 0.2 rounds masks outward to whole pixels. The protocol now states how the recall match works, the bootstrap's generator and how padding and threshold are set together. 35 tests on synthetic boxes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
--operating-point now refuses --split other than tune instead of ignoring it; the bootstrap builds its resample counts once per group; the dropped zero-face resamples of a breakdown are stated in the protocol; the file hashes come from download.sha256_file; the summary names the settings. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
shashwat-deep
marked this pull request as ready for review
October 27, 2026 18:55
shashwat-deep
added a commit
that referenced
this pull request
Oct 27, 2026
This was referenced Oct 27, 2026
06pratyush
approved these changes
Oct 28, 2026
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.
Second step of the evidence half (
docs/plan.md, "Your half", item 3). Stacked on #2: merge #2 first; GitHub then moves this PR ontomain.What is in it
eval/score.pyscores a detections file (docs/contracts.md§4) against the manifest, as part B of the protocol defines it. Padding and threshold are applied here, so sweeping them needs no new detection run.pad, rounded outward to whole pixels and clipped: the pixels the app paints.numpy.random.default_rng(0), percentile interval.--faceswrites one row per face for later breakdowns (luma, for example).--operating-pointapplies the protocol's padding and threshold rules on the tune split.eval/transforms.py: for now only the geometry ofrot<degrees>, written to match Pillow'srotate(expand=True)exactly, including its transposes at 90°, 180° and 270°. The image transforms and the darkening noise parameters come with the runner, before the first run.35 new tests on synthetic boxes, 44 in total. They cover:
A mutation check confirmed that the tests fail when the order by score, the rounding direction or the depiction rule for false masks is broken.
Speed: on the real manifest with made-up detections, scoring the 800 report images takes about 1 s, and the operating-point search on the 200 tune images also about 1 s.
For both of us to agree before any run
docs/contracts.md§2): masks are rounded outward to whole pixels, left and top edges withMath.floor, right and bottom withMath.ceil. This is whatmaskForinapp/src/pipeline/mask.ts(Skeleton 3/4: cover each face with a padded opaque block #6) already does, so the contract now records it, andscore.pycounts the same pixels. (fillRectwith fractional edges would blend the edge pixels with the face beneath them.)How to check
🤖 Generated with Claude Code