fix: stop re-gating gallery scores in the live path
`score_crop` returns only scores the gallery already accepted: the raw 0.55 line, or the fine-tuned head's own 0.40. The live path then ranked that aggregate with `decide_identity(scale="cosine")`, whose defaults rewrite to COSINE_ACCEPT 0.60 / COSINE_AMBIGUOUS 0.50 - a second, higher line. Every head match between 0.40 and 0.60 was therefore refused or downgraded to ambiguous, which is the live regression: the head's own training views score 0.57-0.77. `engine.inspect` and `_classify_with_gallery` already avoid this by ranking through `decision_for_match`, which applies only the published margin. The live path now does the same: on the cosine scale it passes explicit zero accept lines, so the margin gate is the only extra gate. Regression tests: a 0.45 head-scale match is labelled (fails on the previous code), and a 0.45/0.44 pair inside the margin stays unnamed. Verified: `python -m unittest discover -s code -p 'test_*.py'` - 257 tests, OK, 2 skipped.
This commit is contained in:
parent
1bb1b7158b
commit
84ca113b90
2 changed files with 57 additions and 6 deletions
|
|
@ -1146,9 +1146,17 @@ class LiveSession:
|
|||
from identity import aggregate_votes, decide_identity
|
||||
|
||||
mean_scores = aggregate_votes(track.observations)
|
||||
decision = decide_identity(
|
||||
mean_scores, method=method, scale=getattr(self.engine, "identity_scale", "inlier")
|
||||
)
|
||||
if getattr(self.engine, "identity_scale", "inlier") == "cosine":
|
||||
# score_crop only returns a score the gallery already accepted, so
|
||||
# the aggregate must not be re-gated at COSINE_ACCEPT: that line is
|
||||
# above the head's own 0.40 and refused matches the gallery had
|
||||
# accepted. Only the margin gate is left to apply.
|
||||
decision = decide_identity(
|
||||
mean_scores, method=method, scale="cosine",
|
||||
min_score=0.0, min_confidence=0.0,
|
||||
)
|
||||
else:
|
||||
decision = decide_identity(mean_scores, method=method)
|
||||
track.candidates = [
|
||||
{"sku_id": row.get("sku_id"), "score": row.get("score")}
|
||||
for row in (decision.get("ranked_candidates") or [])[:3]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue