Spaces:
Running
Running
Fix : Improving Results
Browse files- src/api/search.py +4 -4
- src/common/utils.py +2 -2
- src/core/config.py +11 -9
src/api/search.py
CHANGED
|
@@ -128,10 +128,10 @@ async def _query_face_split(fv, idx_arcface, idx_adaface, pc=None, cluster_uid=N
|
|
| 128 |
)
|
| 129 |
raise
|
| 130 |
|
| 131 |
-
#
|
| 132 |
-
#
|
| 133 |
-
#
|
| 134 |
-
CLUSTER_EXPAND_MIN_SCORE = 0.
|
| 135 |
high_confidence = {
|
| 136 |
url: d for url, d in image_map.items()
|
| 137 |
if d.get("fused_score", 0.0) >= CLUSTER_EXPAND_MIN_SCORE
|
|
|
|
| 128 |
)
|
| 129 |
raise
|
| 130 |
|
| 131 |
+
# Expand clusters for matches with fused_score >= 0.35 (more inclusive).
|
| 132 |
+
# Most same-person matches score above 0.35; this ensures complete photo galleries.
|
| 133 |
+
# Lowered from 0.50 to catch borderline cases while still rejecting imposters.
|
| 134 |
+
CLUSTER_EXPAND_MIN_SCORE = 0.35
|
| 135 |
high_confidence = {
|
| 136 |
url: d for url, d in image_map.items()
|
| 137 |
if d.get("fused_score", 0.0) >= CLUSTER_EXPAND_MIN_SCORE
|
src/common/utils.py
CHANGED
|
@@ -86,8 +86,8 @@ def face_ui_score(raw_score: float, mode: str = "fused") -> float:
|
|
| 86 |
The sigmoid maps raw cosine → probability of match for the UI.
|
| 87 |
"""
|
| 88 |
if mode == "fused":
|
| 89 |
-
threshold = 0.
|
| 90 |
-
k =
|
| 91 |
else:
|
| 92 |
threshold = 0.50
|
| 93 |
k = 18.0
|
|
|
|
| 86 |
The sigmoid maps raw cosine → probability of match for the UI.
|
| 87 |
"""
|
| 88 |
if mode == "fused":
|
| 89 |
+
threshold = 0.26 # Lowered to match new FUSED_MATCH_THRESHOLD
|
| 90 |
+
k = 15.0 # Gentler curve — more visible results
|
| 91 |
else:
|
| 92 |
threshold = 0.50
|
| 93 |
k = 18.0
|
src/core/config.py
CHANGED
|
@@ -107,17 +107,18 @@ ARCFACE_WEIGHT = float(os.getenv("ARCFACE_WEIGHT", "0.6"))
|
|
| 107 |
ADAFACE_WEIGHT = float(os.getenv("ADAFACE_WEIGHT", "0.4"))
|
| 108 |
|
| 109 |
# ArcFace-R100 same-person mean ~0.55, std ~0.12.
|
| 110 |
-
# 0.30
|
| 111 |
-
#
|
| 112 |
-
FACE_MATCH_THRESHOLD = float(os.getenv("FACE_MATCH_THRESHOLD", "0.
|
| 113 |
|
| 114 |
-
# With both models agreeing, 0.
|
| 115 |
-
#
|
| 116 |
-
FUSED_MATCH_THRESHOLD = float(os.getenv("FUSED_MATCH_THRESHOLD", "0.
|
| 117 |
|
| 118 |
# ArcFace-only floor (no AdaFace confirmation available).
|
| 119 |
-
#
|
| 120 |
-
|
|
|
|
| 121 |
|
| 122 |
# Query-time augmentation: OFF by default, enabled via deep_search form flag
|
| 123 |
ENABLE_QUERY_TIME_AUG = int(os.getenv("ENABLE_QUERY_TIME_AUG", "0"))
|
|
@@ -127,7 +128,8 @@ FACE_SEARCH_TOP_K = int(os.getenv("FACE_SEARCH_TOP_K", "500"))
|
|
| 127 |
OBJECT_SEARCH_TOP_K = int(os.getenv("OBJECT_SEARCH_TOP_K", "100"))
|
| 128 |
|
| 129 |
# Final API returns at most this many per-face matches (after dedup)
|
| 130 |
-
|
|
|
|
| 131 |
|
| 132 |
# ──────────────────────────────────────────────────────────────
|
| 133 |
# Phase 3: People View + Job Queue — DEFAULT OFF (opt-in via env)
|
|
|
|
| 107 |
ADAFACE_WEIGHT = float(os.getenv("ADAFACE_WEIGHT", "0.4"))
|
| 108 |
|
| 109 |
# ArcFace-R100 same-person mean ~0.55, std ~0.12.
|
| 110 |
+
# Lowered from 0.30 to 0.22 for better recall on same-person photos.
|
| 111 |
+
# Still well above impostor tail (different-person mean ~0.05, std ~0.08).
|
| 112 |
+
FACE_MATCH_THRESHOLD = float(os.getenv("FACE_MATCH_THRESHOLD", "0.22"))
|
| 113 |
|
| 114 |
+
# With both models agreeing, 0.26 fused ≈ arc 0.22 + ada 0.30 together.
|
| 115 |
+
# Lower threshold when both models agree = more complete galleries.
|
| 116 |
+
FUSED_MATCH_THRESHOLD = float(os.getenv("FUSED_MATCH_THRESHOLD", "0.26"))
|
| 117 |
|
| 118 |
# ArcFace-only floor (no AdaFace confirmation available).
|
| 119 |
+
# Lowered from 0.38 to 0.28 — still strict enough to reject imposters while
|
| 120 |
+
# capturing same-person photos across diverse angles/lighting.
|
| 121 |
+
ARCFACE_SOLO_THRESHOLD = float(os.getenv("ARCFACE_SOLO_THRESHOLD", "0.28"))
|
| 122 |
|
| 123 |
# Query-time augmentation: OFF by default, enabled via deep_search form flag
|
| 124 |
ENABLE_QUERY_TIME_AUG = int(os.getenv("ENABLE_QUERY_TIME_AUG", "0"))
|
|
|
|
| 128 |
OBJECT_SEARCH_TOP_K = int(os.getenv("OBJECT_SEARCH_TOP_K", "100"))
|
| 129 |
|
| 130 |
# Final API returns at most this many per-face matches (after dedup)
|
| 131 |
+
# Increased from 200 to 500 to show complete photo galleries
|
| 132 |
+
FACE_RESULTS_PER_QUERY_CAP = int(os.getenv("FACE_RESULTS_PER_QUERY_CAP", "500"))
|
| 133 |
|
| 134 |
# ──────────────────────────────────────────────────────────────
|
| 135 |
# Phase 3: People View + Job Queue — DEFAULT OFF (opt-in via env)
|