Spaces:
Sleeping
Sleeping
Commit Β·
a5f0dad
1
Parent(s): 82d1c05
feat: backend-specific ArcFace thresholds (onnx cosine=0.50, deepface cosine=0.68)
Browse filesInsightFace does not publish official thresholds; 0.50 is the widely-cited
community best-practice (stricter than deepface's 0.68 because InsightFace
embeddings cluster more tightly). Update info tab with a threshold table
and per-backend sourcing notes.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- app.py +17 -5
- static/style.css +21 -0
- templates/index.html +30 -9
app.py
CHANGED
|
@@ -29,17 +29,29 @@ UPLOAD_FOLDER = os.path.join(os.path.dirname(__file__), "uploads")
|
|
| 29 |
ALLOWED_EXT = {"png", "jpg", "jpeg", "bmp", "webp"}
|
| 30 |
MAX_CONTENT_LENGTH = 16 * 1024 * 1024 # 16 MB
|
| 31 |
|
| 32 |
-
#
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
ARCFACE_THRESHOLDS = {
|
| 37 |
"cosine": 0.68,
|
| 38 |
"euclidean": 4.15,
|
| 39 |
"euclidean_l2": 1.13,
|
| 40 |
"manhattan": None,
|
| 41 |
"chebyshev": None,
|
| 42 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
|
| 44 |
METRIC_LABELS = {
|
| 45 |
"cosine": "Cosine",
|
|
|
|
| 29 |
ALLOWED_EXT = {"png", "jpg", "jpeg", "bmp", "webp"}
|
| 30 |
MAX_CONTENT_LENGTH = 16 * 1024 * 1024 # 16 MB
|
| 31 |
|
| 32 |
+
# Per-metric thresholds β deepface values are officially published by serengil/deepface.
|
| 33 |
+
# InsightFace does not publish thresholds; 0.50 is the widely-cited community value
|
| 34 |
+
# (stricter than deepface's 0.68 because InsightFace embeddings sit in a tighter cluster).
|
| 35 |
+
_ARCFACE_THRESHOLDS_DEEPFACE = {
|
|
|
|
| 36 |
"cosine": 0.68,
|
| 37 |
"euclidean": 4.15,
|
| 38 |
"euclidean_l2": 1.13,
|
| 39 |
"manhattan": None,
|
| 40 |
"chebyshev": None,
|
| 41 |
}
|
| 42 |
+
_ARCFACE_THRESHOLDS_ONNX = {
|
| 43 |
+
"cosine": 0.50, # InsightFace community best-practice
|
| 44 |
+
"euclidean": None,
|
| 45 |
+
"euclidean_l2": None,
|
| 46 |
+
"manhattan": None,
|
| 47 |
+
"chebyshev": None,
|
| 48 |
+
}
|
| 49 |
+
|
| 50 |
+
ARCFACE_THRESHOLDS = (
|
| 51 |
+
_ARCFACE_THRESHOLDS_DEEPFACE if FACE_BACKEND == "deepface"
|
| 52 |
+
else _ARCFACE_THRESHOLDS_ONNX
|
| 53 |
+
)
|
| 54 |
+
ARCFACE_COSINE_THRESHOLD = ARCFACE_THRESHOLDS["cosine"]
|
| 55 |
|
| 56 |
METRIC_LABELS = {
|
| 57 |
"cosine": "Cosine",
|
static/style.css
CHANGED
|
@@ -835,6 +835,27 @@ body {
|
|
| 835 |
opacity: 0.7;
|
| 836 |
}
|
| 837 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 838 |
/* ---------- Hi-tech Loader ---------- */
|
| 839 |
.loader {
|
| 840 |
display: flex; flex-direction: column;
|
|
|
|
| 835 |
opacity: 0.7;
|
| 836 |
}
|
| 837 |
|
| 838 |
+
/* ---------- Threshold table ---------- */
|
| 839 |
+
.threshold-table {
|
| 840 |
+
width: 100%;
|
| 841 |
+
border-collapse: collapse;
|
| 842 |
+
font-size: 0.83rem;
|
| 843 |
+
margin: 10px 0 12px;
|
| 844 |
+
}
|
| 845 |
+
.threshold-table th, .threshold-table td {
|
| 846 |
+
padding: 6px 12px;
|
| 847 |
+
border: 1px solid var(--border);
|
| 848 |
+
text-align: left;
|
| 849 |
+
}
|
| 850 |
+
.threshold-table thead th {
|
| 851 |
+
background: rgba(56, 189, 248, 0.08);
|
| 852 |
+
color: var(--accent);
|
| 853 |
+
font-family: 'JetBrains Mono', monospace;
|
| 854 |
+
font-weight: 600;
|
| 855 |
+
}
|
| 856 |
+
.threshold-table tbody tr:hover { background: rgba(255,255,255,0.03); }
|
| 857 |
+
.threshold-table code { font-size: 0.78rem; }
|
| 858 |
+
|
| 859 |
/* ---------- Hi-tech Loader ---------- */
|
| 860 |
.loader {
|
| 861 |
display: flex; flex-direction: column;
|
templates/index.html
CHANGED
|
@@ -319,7 +319,7 @@
|
|
| 319 |
|
| 320 |
<p><b>Kenapa 512 angka?</b> Itu pilihan arsitektur ArcFace. Lebih sedikit dimensi β kurang ekspresif, susah membedakan jutaan orang. Lebih banyak β mahal komputasi tanpa banyak peningkatan akurasi. 512 dianggap sweet spot oleh para peneliti.</p>
|
| 321 |
|
| 322 |
-
<p><b>Bagaimana cara membandingkan?</b> Kita ambil dua embedding (vektor 512 angka), lalu hitung <i>jarak</i>-nya pakai rumus seperti Cosine atau Euclidean. Kalau jaraknya kecil β wajah mirip. Kalau jaraknya besar β wajah beda. Threshold-nya
|
| 323 |
|
| 324 |
<h4>Rumus tiap algoritma</h4>
|
| 325 |
<p>Untuk dua vektor embedding ArcFace 512-dimensi <code>a</code> dan <code>b</code>:</p>
|
|
@@ -382,16 +382,36 @@
|
|
| 382 |
<p>ArcFace dilatih dengan <i>angular margin loss</i> β identitas wajah tersimpan di <b>arah</b> vektor, bukan panjangnya. Jadi Euclidean L2 biasanya lebih stabil untuk verifikasi wajah dibanding Euclidean biasa.</p>
|
| 383 |
<p>Secara matematis, Euclidean L2 dan Cosine sebenarnya membawa informasi yang sama (sudut antar vektor), dengan hubungan:</p>
|
| 384 |
<div class="formula-eq">Euclidean_L2Β² = 2 Γ Cosine_distance</div>
|
| 385 |
-
<p>Itu sebabnya threshold
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 386 |
|
| 387 |
<h4>Kenapa threshold tiap algoritma berbeda?</h4>
|
| 388 |
-
<p>Karena tiap rumus menghasilkan skala angka yang berbeda β distance Manhattan untuk pasangan wajah yang sama bisa puluhan, sedangkan Chebyshev cuma di angka satuan. Threshold
|
| 389 |
|
| 390 |
<h4>Kenapa Manhattan & Chebyshev cuma "INFO"?</h4>
|
| 391 |
-
<p>
|
| 392 |
|
| 393 |
<h4>Metrik mana yang paling utama?</h4>
|
| 394 |
-
<p><b>Cosine</b>. Itu metrik
|
| 395 |
|
| 396 |
<h4>Sumber & Referensi</h4>
|
| 397 |
<p class="ref-group-label">Paper Model</p>
|
|
@@ -430,15 +450,16 @@
|
|
| 430 |
</li>
|
| 431 |
</ul>
|
| 432 |
|
| 433 |
-
<p class="ref-group-label">Threshold
|
| 434 |
<ul class="ref-list">
|
| 435 |
<li>
|
| 436 |
-
|
| 437 |
<a href="https://github.com/serengil/deepface/blob/master/deepface/config/threshold.py#L5" target="_blank" rel="noopener">deepface/config/threshold.py</a>
|
|
|
|
| 438 |
</li>
|
| 439 |
<li>
|
| 440 |
-
|
| 441 |
-
<a href="https://github.com/
|
| 442 |
</li>
|
| 443 |
</ul>
|
| 444 |
|
|
|
|
| 319 |
|
| 320 |
<p><b>Kenapa 512 angka?</b> Itu pilihan arsitektur ArcFace. Lebih sedikit dimensi β kurang ekspresif, susah membedakan jutaan orang. Lebih banyak β mahal komputasi tanpa banyak peningkatan akurasi. 512 dianggap sweet spot oleh para peneliti.</p>
|
| 321 |
|
| 322 |
+
<p><b>Bagaimana cara membandingkan?</b> Kita ambil dua embedding (vektor 512 angka), lalu hitung <i>jarak</i>-nya pakai rumus seperti Cosine atau Euclidean. Kalau jaraknya kecil β wajah mirip. Kalau jaraknya besar β wajah beda. Threshold-nya dikalibrasi per backend β lihat bagian <i>"Threshold per backend"</i> di bawah.</p>
|
| 323 |
|
| 324 |
<h4>Rumus tiap algoritma</h4>
|
| 325 |
<p>Untuk dua vektor embedding ArcFace 512-dimensi <code>a</code> dan <code>b</code>:</p>
|
|
|
|
| 382 |
<p>ArcFace dilatih dengan <i>angular margin loss</i> β identitas wajah tersimpan di <b>arah</b> vektor, bukan panjangnya. Jadi Euclidean L2 biasanya lebih stabil untuk verifikasi wajah dibanding Euclidean biasa.</p>
|
| 383 |
<p>Secara matematis, Euclidean L2 dan Cosine sebenarnya membawa informasi yang sama (sudut antar vektor), dengan hubungan:</p>
|
| 384 |
<div class="formula-eq">Euclidean_L2Β² = 2 Γ Cosine_distance</div>
|
| 385 |
+
<p>Itu sebabnya threshold DeepFace konsisten: Cosine <code>0.68</code> β Euclidean L2 <code>β(2 Γ 0.68) β 1.166</code>, dibulatkan jadi <code>1.13</code> β</p>
|
| 386 |
+
|
| 387 |
+
<h4>Threshold per backend</h4>
|
| 388 |
+
<p>Kedua backend menghasilkan ArcFace embedding 512-dim yang strukturnya sama, tapi threshold verifikasi-nya <b>berbeda</b> karena sumber kalibrasiya beda:</p>
|
| 389 |
+
<table class="threshold-table">
|
| 390 |
+
<thead>
|
| 391 |
+
<tr><th>Metrik</th><th>Backend <code>onnx</code> (InsightFace)</th><th>Backend <code>deepface</code></th></tr>
|
| 392 |
+
</thead>
|
| 393 |
+
<tbody>
|
| 394 |
+
<tr><td><b>Cosine</b></td><td>0.50</td><td>0.68</td></tr>
|
| 395 |
+
<tr><td>Euclidean</td><td>β</td><td>4.15</td></tr>
|
| 396 |
+
<tr><td>Euclidean L2</td><td>β</td><td>1.13</td></tr>
|
| 397 |
+
<tr><td>Manhattan</td><td>β</td><td>β</td></tr>
|
| 398 |
+
<tr><td>Chebyshev</td><td>β</td><td>β</td></tr>
|
| 399 |
+
</tbody>
|
| 400 |
+
</table>
|
| 401 |
+
<ul>
|
| 402 |
+
<li><b>Backend <code>deepface</code></b> β threshold dipublikasikan resmi oleh serengil/deepface (<code>deepface/config/threshold.py</code>), hasil kalibrasi di dataset LFW. <code>cosine 0.68</code> adalah nilai default untuk ArcFace.</li>
|
| 403 |
+
<li><b>Backend <code>onnx</code></b> β InsightFace tidak mempublikasikan threshold resmi. Nilai <code>cosine 0.50</code> adalah best-practice komunitas yang banyak dipakai (lebih strict dari deepface karena embedding InsightFace cenderung ter-cluster lebih ketat). Metrik lain tidak ada nilai kalibrasi yang teruji, sehingga ditampilkan sebagai info saja.</li>
|
| 404 |
+
</ul>
|
| 405 |
+
<p>Perbedaan threshold ini penting: dengan backend <code>deepface</code> cosine 0.65 dianggap MATCH, tapi dengan backend <code>onnx</code> (threshold 0.50) itu NO MATCH. Selalu perhatikan backend aktif saat menginterpretasi hasil.</p>
|
| 406 |
|
| 407 |
<h4>Kenapa threshold tiap algoritma berbeda?</h4>
|
| 408 |
+
<p>Karena tiap rumus menghasilkan skala angka yang berbeda β distance Manhattan untuk pasangan wajah yang sama bisa puluhan, sedangkan Chebyshev cuma di angka satuan. Threshold bukan dipilih sembarang β itu nilai kalibrasi hasil pengujian ArcFace pada dataset wajah berlabel (LFW dll) untuk cari batas optimal "orang sama" vs "orang beda" per metrik.</p>
|
| 409 |
|
| 410 |
<h4>Kenapa Manhattan & Chebyshev cuma "INFO"?</h4>
|
| 411 |
+
<p>Tidak ada threshold resmi (dari DeepFace maupun InsightFace) untuk dua metrik ini pada ArcFace, jadi tidak ada angka kalibrasi yang valid untuk memutuskan MATCH / NO MATCH. Keduanya tetap dihitung sebagai info tambahan, tapi tidak dipakai untuk verdict.</p>
|
| 412 |
|
| 413 |
<h4>Metrik mana yang paling utama?</h4>
|
| 414 |
+
<p><b>Cosine</b>. Itu metrik yang paling stabil untuk embedding ArcFace (tidak sensitif magnitudo vektor). Verdict utama (MATCH / NO MATCH) di aplikasi ini selalu memakai cosine dengan threshold sesuai backend aktif.</p>
|
| 415 |
|
| 416 |
<h4>Sumber & Referensi</h4>
|
| 417 |
<p class="ref-group-label">Paper Model</p>
|
|
|
|
| 450 |
</li>
|
| 451 |
</ul>
|
| 452 |
|
| 453 |
+
<p class="ref-group-label">Threshold β sumber per backend</p>
|
| 454 |
<ul class="ref-list">
|
| 455 |
<li>
|
| 456 |
+
<b>Backend <code>deepface</code></b> β threshold ArcFace di-hardcode di file config (<code>cosine: 0.68</code>, <code>euclidean: 4.15</code>, <code>euclidean_l2: 1.13</code>):
|
| 457 |
<a href="https://github.com/serengil/deepface/blob/master/deepface/config/threshold.py#L5" target="_blank" rel="noopener">deepface/config/threshold.py</a>
|
| 458 |
+
Β· lookup via <a href="https://github.com/serengil/deepface/blob/master/deepface/modules/verification.py#L477" target="_blank" rel="noopener">deepface/modules/verification.py</a>
|
| 459 |
</li>
|
| 460 |
<li>
|
| 461 |
+
<b>Backend <code>onnx</code></b> β InsightFace tidak mempublikasikan threshold. Nilai <code>cosine: 0.50</code> adalah best-practice komunitas yang banyak dipakai; lihat diskusi di:
|
| 462 |
+
<a href="https://github.com/deepinsight/insightface/issues/1071" target="_blank" rel="noopener">deepinsight/insightface #1071</a>
|
| 463 |
</li>
|
| 464 |
</ul>
|
| 465 |
|