DefectRAG phase 5: incremental real-model application migration
Browse files- README.md +3 -1
- backend/calibration.py +48 -0
- backend/highres.py +3 -2
- backend/main.py +3 -0
- deployment/space/app.py +2 -1
- deployment/space/publish.py +5 -1
- frontend/dist/assets/TeamWorkspace-C-ePZ-kX.js +41 -0
- frontend/dist/assets/index-BdEpy7cy.js +0 -0
- frontend/dist/index.html +1 -1
- results/sensitive_deployment_evaluation.json +710 -0
README.md
CHANGED
|
@@ -15,7 +15,9 @@ short_description: Live React dashboard and DINOv2 inspection on ZeroGPU
|
|
| 15 |
# DefectRAG — migration phase 5
|
| 16 |
|
| 17 |
Existing React UI, real frozen DINOv2 inspection across all 12 VisA categories,
|
| 18 |
-
original normal-reference banks
|
|
|
|
|
|
|
| 19 |
Anonymous browser history is isolated and temporary. Sign in to the configured
|
| 20 |
staff workspace for durable shared records when available. Do not treat anomaly
|
| 21 |
scores as probabilities or diagnoses. The operator selects the product category.
|
|
|
|
| 15 |
# DefectRAG — migration phase 5
|
| 16 |
|
| 17 |
Existing React UI, real frozen DINOv2 inspection across all 12 VisA categories,
|
| 18 |
+
original normal-reference banks and heatmaps, with versioned normal-only decision
|
| 19 |
+
calibration. No training rerun. The q95 sensitivity policy trades more false
|
| 20 |
+
alarms for higher recall; historical inspection decisions are preserved.
|
| 21 |
Anonymous browser history is isolated and temporary. Sign in to the configured
|
| 22 |
staff workspace for durable shared records when available. Do not treat anomaly
|
| 23 |
scores as probabilities or diagnoses. The operator selects the product category.
|
backend/calibration.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Versioned decision calibration; encoder, memory and old records stay unchanged."""
|
| 2 |
+
import json
|
| 3 |
+
import math
|
| 4 |
+
import os
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
POLICY = 'normal-q95-v1'
|
| 8 |
+
FILENAME = 'sensitive_deployment_evaluation.json'
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
def active_evaluation(root, baseline):
|
| 12 |
+
policy = os.getenv('DEFECTRAG_CALIBRATION', POLICY)
|
| 13 |
+
if policy == 'normal-max-v1':
|
| 14 |
+
return baseline
|
| 15 |
+
if policy != POLICY:
|
| 16 |
+
raise ValueError('Unknown decision calibration policy')
|
| 17 |
+
path = root / 'results' / FILENAME
|
| 18 |
+
if not path.exists():
|
| 19 |
+
return baseline
|
| 20 |
+
candidate = json.loads(path.read_text())
|
| 21 |
+
if candidate.get('decision_policy') != POLICY or set(candidate['categories']) != set(baseline['categories']):
|
| 22 |
+
raise ValueError('Invalid decision calibration manifest')
|
| 23 |
+
for category, original in baseline['categories'].items():
|
| 24 |
+
card = candidate['categories'][category]
|
| 25 |
+
for key in ('category', 'profile', 'encoder_sha256', 'bank_sha256', 'heatmap_scale', 'train_normal_count'):
|
| 26 |
+
if card[key] != original[key]:
|
| 27 |
+
raise ValueError('Calibration manifest does not match the original model: ' + category)
|
| 28 |
+
if (card['baseline_threshold'] != original['threshold'] or
|
| 29 |
+
card['model_id'] != original['model_id'] + '-q95-v1' or
|
| 30 |
+
card['calibration'].get('policy') != POLICY or
|
| 31 |
+
card['calibration']['normal'] != original['calibration']['normal'] or
|
| 32 |
+
card['calibration']['anomalous'] != 0 or
|
| 33 |
+
not math.isfinite(card['threshold']) or not 0 < card['threshold'] <= original['threshold'] or
|
| 34 |
+
not math.isclose(card['uncertainty_margin'], card['threshold'] * .05, abs_tol=1e-12)):
|
| 35 |
+
raise ValueError('Invalid calibrated threshold: ' + category)
|
| 36 |
+
return candidate
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
def calibrated_card(root, original):
|
| 40 |
+
# Both local and ZeroGPU inference use this exact manifest and guard logic.
|
| 41 |
+
baseline_path = root / 'results/highres_deployment_evaluation.json'
|
| 42 |
+
if not baseline_path.exists():
|
| 43 |
+
return original
|
| 44 |
+
baseline = json.loads(baseline_path.read_text())
|
| 45 |
+
for key in ('threshold', 'model_id', 'encoder_sha256', 'bank_sha256'):
|
| 46 |
+
if baseline['categories'][original['category']][key] != original[key]:
|
| 47 |
+
raise ValueError('Original model card and evaluation disagree')
|
| 48 |
+
return active_evaluation(root, baseline)['categories'][original['category']]
|
backend/highres.py
CHANGED
|
@@ -17,6 +17,7 @@ import torch.nn.functional as F
|
|
| 17 |
from transformers import AutoModel
|
| 18 |
from .vision import distances,ModelUnavailable,sha256,display_map
|
| 19 |
from .config import CATEGORIES
|
|
|
|
| 20 |
|
| 21 |
|
| 22 |
class HighResolutionEncoder:
|
|
@@ -84,11 +85,11 @@ class HighResolutionDetector:
|
|
| 84 |
self.banks={};self.lock=threading.Lock()
|
| 85 |
|
| 86 |
def cards(self):
|
| 87 |
-
return [json.loads((self.directory/f'{category}.json').read_text()) for category in CATEGORIES]
|
| 88 |
|
| 89 |
def load(self,category):
|
| 90 |
if category not in CATEGORIES:raise ValueError('Unsupported product category')
|
| 91 |
-
card=json.loads((self.directory/f'{category}.json').read_text())
|
| 92 |
encoder = self.encoder
|
| 93 |
if encoder is None:
|
| 94 |
source=self.settings.root/'models/encoder_dinov2'
|
|
|
|
| 17 |
from transformers import AutoModel
|
| 18 |
from .vision import distances,ModelUnavailable,sha256,display_map
|
| 19 |
from .config import CATEGORIES
|
| 20 |
+
from .calibration import calibrated_card
|
| 21 |
|
| 22 |
|
| 23 |
class HighResolutionEncoder:
|
|
|
|
| 85 |
self.banks={};self.lock=threading.Lock()
|
| 86 |
|
| 87 |
def cards(self):
|
| 88 |
+
return [calibrated_card(self.settings.root,json.loads((self.directory/f'{category}.json').read_text())) for category in CATEGORIES]
|
| 89 |
|
| 90 |
def load(self,category):
|
| 91 |
if category not in CATEGORIES:raise ValueError('Unsupported product category')
|
| 92 |
+
card=calibrated_card(self.settings.root,json.loads((self.directory/f'{category}.json').read_text()))
|
| 93 |
encoder = self.encoder
|
| 94 |
if encoder is None:
|
| 95 |
source=self.settings.root/'models/encoder_dinov2'
|
backend/main.py
CHANGED
|
@@ -115,6 +115,9 @@ def create_app(settings=None, detector=None, workflow=None, repository=None):
|
|
| 115 |
active=getattr(detector,'profile_name','legacy')=='dinov2_highres_v1'
|
| 116 |
path=settings.root/'results'/('highres_deployment_evaluation.json' if active else 'evaluation.json')
|
| 117 |
result=json.loads(path.read_text()) if path.exists() else {'status':'unverified'}
|
|
|
|
|
|
|
|
|
|
| 118 |
profile=settings.root/'results'/'serving_profile.json'
|
| 119 |
if profile.exists() and not active:result['serving_profile']=json.loads(profile.read_text())
|
| 120 |
return {'data':result}
|
|
|
|
| 115 |
active=getattr(detector,'profile_name','legacy')=='dinov2_highres_v1'
|
| 116 |
path=settings.root/'results'/('highres_deployment_evaluation.json' if active else 'evaluation.json')
|
| 117 |
result=json.loads(path.read_text()) if path.exists() else {'status':'unverified'}
|
| 118 |
+
if active and 'categories' in result:
|
| 119 |
+
from .calibration import active_evaluation
|
| 120 |
+
result=active_evaluation(settings.root,result)
|
| 121 |
profile=settings.root/'results'/'serving_profile.json'
|
| 122 |
if profile.exists() and not active:result['serving_profile']=json.loads(profile.read_text())
|
| 123 |
return {'data':result}
|
deployment/space/app.py
CHANGED
|
@@ -25,6 +25,7 @@ from fastapi import HTTPException
|
|
| 25 |
from fastapi.responses import FileResponse, JSONResponse, RedirectResponse
|
| 26 |
from fastapi.staticfiles import StaticFiles
|
| 27 |
from backend.config import CATEGORIES, Settings
|
|
|
|
| 28 |
from backend.highres import HighResolutionEncoder, foreground_mask, score_tokens, restore_map
|
| 29 |
from backend.vision import sha256, display_map
|
| 30 |
from backend.storage import now
|
|
@@ -32,7 +33,7 @@ from deployment.space.sessions import SessionRepository, identity, namespace, NA
|
|
| 32 |
|
| 33 |
ZERO = os.getenv('SPACES_ZERO_GPU') == '1'
|
| 34 |
DEVICE = 'cuda' if torch.cuda.is_available() else 'cpu'
|
| 35 |
-
CARDS = {category: json.loads((ROOT/f'models/highres/{category}.json').read_text()) for category in CATEGORIES}
|
| 36 |
ENCODER = HighResolutionEncoder(ROOT/'models/encoder_dinov2', device='cpu')
|
| 37 |
encoder_digest = sha256(ROOT/'models/encoder_dinov2/model.safetensors')
|
| 38 |
assert all(card['encoder_sha256'] == encoder_digest for card in CARDS.values())
|
|
|
|
| 25 |
from fastapi.responses import FileResponse, JSONResponse, RedirectResponse
|
| 26 |
from fastapi.staticfiles import StaticFiles
|
| 27 |
from backend.config import CATEGORIES, Settings
|
| 28 |
+
from backend.calibration import calibrated_card
|
| 29 |
from backend.highres import HighResolutionEncoder, foreground_mask, score_tokens, restore_map
|
| 30 |
from backend.vision import sha256, display_map
|
| 31 |
from backend.storage import now
|
|
|
|
| 33 |
|
| 34 |
ZERO = os.getenv('SPACES_ZERO_GPU') == '1'
|
| 35 |
DEVICE = 'cuda' if torch.cuda.is_available() else 'cpu'
|
| 36 |
+
CARDS = {category: calibrated_card(ROOT,json.loads((ROOT/f'models/highres/{category}.json').read_text())) for category in CATEGORIES}
|
| 37 |
ENCODER = HighResolutionEncoder(ROOT/'models/encoder_dinov2', device='cpu')
|
| 38 |
encoder_digest = sha256(ROOT/'models/encoder_dinov2/model.safetensors')
|
| 39 |
assert all(card['encoder_sha256'] == encoder_digest for card in CARDS.values())
|
deployment/space/publish.py
CHANGED
|
@@ -23,6 +23,8 @@ def main():
|
|
| 23 |
path=ROOT/relative
|
| 24 |
if path.exists():
|
| 25 |
files[relative]=path
|
|
|
|
|
|
|
| 26 |
for directory in ('backend','deployment/space'):
|
| 27 |
for path in (ROOT/directory).glob('*.py'):
|
| 28 |
files[path.relative_to(ROOT).as_posix()] = path
|
|
@@ -52,7 +54,9 @@ def main():
|
|
| 52 |
header = readme.split('---',2)[1].replace('DefectRAG - Phase 1 compatibility test','DefectRAG').replace('Existing React UI plus one genuine DINOv2 ZeroGPU inspection','Live React dashboard and DINOv2 inspection on ZeroGPU')
|
| 53 |
body = f'''\n# DefectRAG — migration phase {args.phase}\n
|
| 54 |
Existing React UI, real frozen DINOv2 inspection across all 12 VisA categories,
|
| 55 |
-
original normal-reference banks
|
|
|
|
|
|
|
| 56 |
Anonymous browser history is isolated and temporary. Sign in to the configured
|
| 57 |
staff workspace for durable shared records when available. Do not treat anomaly
|
| 58 |
scores as probabilities or diagnoses. The operator selects the product category.
|
|
|
|
| 23 |
path=ROOT/relative
|
| 24 |
if path.exists():
|
| 25 |
files[relative]=path
|
| 26 |
+
for relative in ('results/sensitive_deployment_evaluation.json',):
|
| 27 |
+
files[relative]=ROOT/relative
|
| 28 |
for directory in ('backend','deployment/space'):
|
| 29 |
for path in (ROOT/directory).glob('*.py'):
|
| 30 |
files[path.relative_to(ROOT).as_posix()] = path
|
|
|
|
| 54 |
header = readme.split('---',2)[1].replace('DefectRAG - Phase 1 compatibility test','DefectRAG').replace('Existing React UI plus one genuine DINOv2 ZeroGPU inspection','Live React dashboard and DINOv2 inspection on ZeroGPU')
|
| 55 |
body = f'''\n# DefectRAG — migration phase {args.phase}\n
|
| 56 |
Existing React UI, real frozen DINOv2 inspection across all 12 VisA categories,
|
| 57 |
+
original normal-reference banks and heatmaps, with versioned normal-only decision
|
| 58 |
+
calibration. No training rerun. The q95 sensitivity policy trades more false
|
| 59 |
+
alarms for higher recall; historical inspection decisions are preserved.
|
| 60 |
Anonymous browser history is isolated and temporary. Sign in to the configured
|
| 61 |
staff workspace for durable shared records when available. Do not treat anomaly
|
| 62 |
scores as probabilities or diagnoses. The operator selects the product category.
|
frontend/dist/assets/TeamWorkspace-C-ePZ-kX.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import{c as h,r as n,a as Q,b as d,R as e,L as X,S as $,A as ee,d as te}from"./index-BdEpy7cy.js";/**
|
| 2 |
+
* @license lucide-react v0.468.0 - ISC
|
| 3 |
+
*
|
| 4 |
+
* This source code is licensed under the ISC license.
|
| 5 |
+
* See the LICENSE file in the root directory of this source tree.
|
| 6 |
+
*/const ae=h("ArchiveRestore",[["rect",{width:"20",height:"5",x:"2",y:"3",rx:"1",key:"1wp1u1"}],["path",{d:"M4 8v11a2 2 0 0 0 2 2h2",key:"tvwodi"}],["path",{d:"M20 8v11a2 2 0 0 1-2 2h-2",key:"1gkqxj"}],["path",{d:"m9 15 3-3 3 3",key:"1pd0qc"}],["path",{d:"M12 12v9",key:"192myk"}]]);/**
|
| 7 |
+
* @license lucide-react v0.468.0 - ISC
|
| 8 |
+
*
|
| 9 |
+
* This source code is licensed under the ISC license.
|
| 10 |
+
* See the LICENSE file in the root directory of this source tree.
|
| 11 |
+
*/const _=h("Cloud",[["path",{d:"M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z",key:"p7xjir"}]]);/**
|
| 12 |
+
* @license lucide-react v0.468.0 - ISC
|
| 13 |
+
*
|
| 14 |
+
* This source code is licensed under the ISC license.
|
| 15 |
+
* See the LICENSE file in the root directory of this source tree.
|
| 16 |
+
*/const re=h("ExternalLink",[["path",{d:"M15 3h6v6",key:"1q9fwt"}],["path",{d:"M10 14 21 3",key:"gplh6r"}],["path",{d:"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6",key:"a6xqqp"}]]);/**
|
| 17 |
+
* @license lucide-react v0.468.0 - ISC
|
| 18 |
+
*
|
| 19 |
+
* This source code is licensed under the ISC license.
|
| 20 |
+
* See the LICENSE file in the root directory of this source tree.
|
| 21 |
+
*/const ne=h("LogIn",[["path",{d:"M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4",key:"u53s6r"}],["polyline",{points:"10 17 15 12 10 7",key:"1ail0h"}],["line",{x1:"15",x2:"3",y1:"12",y2:"12",key:"v6grx8"}]]);/**
|
| 22 |
+
* @license lucide-react v0.468.0 - ISC
|
| 23 |
+
*
|
| 24 |
+
* This source code is licensed under the ISC license.
|
| 25 |
+
* See the LICENSE file in the root directory of this source tree.
|
| 26 |
+
*/const le=h("LogOut",[["path",{d:"M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4",key:"1uf3rs"}],["polyline",{points:"16 17 21 12 16 7",key:"1gabdz"}],["line",{x1:"21",x2:"9",y1:"12",y2:"12",key:"1uyos4"}]]);/**
|
| 27 |
+
* @license lucide-react v0.468.0 - ISC
|
| 28 |
+
*
|
| 29 |
+
* This source code is licensed under the ISC license.
|
| 30 |
+
* See the LICENSE file in the root directory of this source tree.
|
| 31 |
+
*/const se=h("RefreshCw",[["path",{d:"M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8",key:"v9h5vc"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}],["path",{d:"M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16",key:"3uifl3"}],["path",{d:"M8 16H3v5",key:"1cv678"}]]);/**
|
| 32 |
+
* @license lucide-react v0.468.0 - ISC
|
| 33 |
+
*
|
| 34 |
+
* This source code is licensed under the ISC license.
|
| 35 |
+
* See the LICENSE file in the root directory of this source tree.
|
| 36 |
+
*/const ce=h("Send",[["path",{d:"M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z",key:"1ffxy3"}],["path",{d:"m21.854 2.147-10.94 10.939",key:"12cjpa"}]]);/**
|
| 37 |
+
* @license lucide-react v0.468.0 - ISC
|
| 38 |
+
*
|
| 39 |
+
* This source code is licensed under the ISC license.
|
| 40 |
+
* See the LICENSE file in the root directory of this source tree.
|
| 41 |
+
*/const oe=h("Users",[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}],["path",{d:"M22 21v-2a4 4 0 0 0-3-3.87",key:"kshegd"}],["path",{d:"M16 3.13a4 4 0 0 1 0 7.75",key:"1da9ce"}]]);function me(){var D;const[c,A]=n.useState(null),[l,x]=n.useState(null),[v,M]=n.useState([]),[S,H]=n.useState({}),[g,F]=n.useState(""),[R,L]=n.useState(""),[o,q]=n.useState(!1),[P,y]=n.useState(""),[E,W]=n.useState(!1),[s,w]=n.useState(null),[B,V]=n.useState([]),[K,G]=n.useState([]),[k,z]=n.useState(""),[Y,I]=n.useState(!1),[U,O]=n.useState(""),[Z,N]=n.useState(!1),C=Q();async function i(t){q(!0),y("");try{await t()}catch(r){y(r.message||"Team request failed.")}finally{q(!1)}}async function b(){const{client:t,staff:r}=await te();x(r);let a=t.from("shared_inspections").select("*").order("created_at",{ascending:!1}).limit(200);a=E?a.not("archived_at","is",null):a.is("archived_at",null);const[{data:m,error:f},{data:u,error:p}]=await Promise.all([a,t.from("staff_members").select("*")]);if(f)throw f;if(p)throw p;M(m||[]),H(Object.fromEntries((u||[]).map(T=>[T.user_id,T.display_name])))}n.useEffect(()=>{if(!C)return;let t=!1,r;return d().then(async a=>{r=a.auth.onAuthStateChange((f,u)=>{t||(A((u==null?void 0:u.user)||null),f==="PASSWORD_RECOVERY"&&I(!0))}).data.subscription;const{data:m}=await a.auth.getUser();t||A(m.user)}).catch(a=>{t||y(a.message)}),()=>{t=!0,r==null||r.unsubscribe()}},[C]),n.useEffect(()=>{if(!c)return;let t=!1;b().catch(a=>{t||y(a.message)});const r=setInterval(()=>b().catch(a=>{t||y(a.message)}),15e3);return()=>{t=!0,clearInterval(r)}},[c==null?void 0:c.id,E]);async function j(t){await i(async()=>{const r=await d(),a=r.storage.from("team-inspections"),m=await Promise.all([t.image_path,t.heatmap_path].map(p=>a.createSignedUrl(p,900)));if(m.some(p=>p.error))throw new Error("Private images could not be loaded. Check staff/storage policies.");const{data:f,error:u}=await r.from("staff_notes").select("*").eq("inspection_id",t.id).order("created_at");if(u)throw u;w(t),V(m.map(p=>p.data.signedUrl)),G(f||[])})}async function J(){await i(async()=>{const t=await d(),r=v.filter(a=>a.owner_id===c.id).map(a=>a.id);if(r.length){const{error:a}=await t.rpc("archive_team_inspections",{p_ids:r});if(a)throw a}w(null),N(!1),await b()})}return C?e.createElement(e.Fragment,null,e.createElement("section",{className:"card"},e.createElement("div",{className:"section-title"},e.createElement("div",null,e.createElement("h2",null,e.createElement(oe,{size:21})," Staff workspace"),e.createElement("p",null,"Signed-in staff share saved inspections and review notes. Live AI runs on the connected inspection backend.")),e.createElement("span",{className:"subtle-tag"},e.createElement(_,{size:13})," SUPABASE")),P&&e.createElement("div",{className:"error",role:"alert"},P),c?e.createElement(e.Fragment,null,e.createElement("div",{className:"team-toolbar"},e.createElement("div",null,e.createElement($,{size:18}),e.createElement("strong",null,(l==null?void 0:l.display_name)||c.email),e.createElement("span",{className:"subtle-tag"},(l==null?void 0:l.role)||"CHECKING MEMBERSHIP")),e.createElement("button",{className:"secondary",disabled:o,onClick:()=>i(b)},e.createElement(se,{size:16})," Refresh"),e.createElement("button",{className:"secondary",onClick:()=>i(async()=>{await(await d()).auth.signOut(),M([]),w(null),x(null)})},e.createElement(le,{size:16})," Sign out")),Y&&e.createElement("form",{className:"login-form",onSubmit:t=>{t.preventDefault(),i(async()=>{const r=await d(),{error:a}=await r.auth.updateUser({password:U});if(a)throw a;O(""),I(!1)})}},e.createElement("label",{className:"field"},"Set a new password",e.createElement("input",{type:"password",minLength:12,autoComplete:"new-password",value:U,onChange:t=>O(t.target.value),required:!0})),e.createElement("button",{className:"primary",disabled:o},"Save password")),e.createElement("div",{className:"team-toolbar"},e.createElement("span",null,"Latest ",v.length," shared records · refreshes every 15 seconds"),(l==null?void 0:l.role)==="developer"&&e.createElement("button",{className:"secondary",onClick:()=>{W(!E),w(null)}},e.createElement(ae,{size:16}),E?"Active history":"Developer recovery"),!E&&e.createElement("button",{className:"secondary danger",disabled:o||!v.some(t=>t.owner_id===c.id),onClick:()=>N(!0)},e.createElement(ee,{size:16})," Archive my visible history")),Z&&e.createElement("div",{className:"note"},e.createElement("div",null,e.createElement("strong",null,"Archive your visible records?"),e.createElement("p",null,"They will leave the shared active history. Original files and conversations remain recoverable by a developer. Other staff members’ records will stay active."),e.createElement("div",{className:"button-row"},e.createElement("button",{className:"primary",disabled:o,onClick:J},"Archive my records"),e.createElement("button",{className:"secondary",onClick:()=>N(!1)},"Cancel")))),e.createElement("div",{className:"table-wrap"},e.createElement("table",null,e.createElement("thead",null,e.createElement("tr",null,e.createElement("th",null,"Inspection"),e.createElement("th",null,"Product"),e.createElement("th",null,"Result"),e.createElement("th",null,"Shared by"),e.createElement("th",null,"Saved"),e.createElement("th",null))),e.createElement("tbody",null,v.map(t=>{var r;return e.createElement("tr",{key:t.id},e.createElement("td",null,e.createElement("strong",null,t.id.slice(0,8))),e.createElement("td",null,t.payload.category),e.createElement("td",null,e.createElement("span",{className:"badge "+((r=t.payload.verdict)==null?void 0:r.toLowerCase())},t.payload.verdict)),e.createElement("td",null,S[t.owner_id]||"Staff member"),e.createElement("td",null,new Date(t.created_at).toLocaleString()),e.createElement("td",null,e.createElement("button",{className:"text-button",onClick:()=>j(t)},"Review"),E&&(l==null?void 0:l.role)==="developer"&&e.createElement("button",{className:"text-button",disabled:o,onClick:()=>i(async()=>{const a=await d(),{error:m}=await a.rpc("restore_team_inspections",{p_ids:[t.id]});if(m)throw m;await b()})},"Restore")))}))),!v.length&&e.createElement("div",{className:"empty"},e.createElement(_,{size:30}),e.createElement("p",null,E?"No archived records to recover.":"No shared inspections yet. In the local app, open a result and select Share with staff.")))):e.createElement("form",{className:"login-form",onSubmit:t=>{t.preventDefault(),i(async()=>{const r=await d(),{error:a}=await r.auth.signInWithPassword({email:g,password:R});if(a)throw a;L("")})}},e.createElement("label",{className:"field"},"Work email",e.createElement("input",{type:"email",autoComplete:"username",value:g,onChange:t=>F(t.target.value),required:!0})),e.createElement("label",{className:"field"},"Password",e.createElement("input",{type:"password",autoComplete:"current-password",value:R,onChange:t=>L(t.target.value),required:!0})),e.createElement("button",{className:"primary",disabled:o},o?e.createElement(X,{className:"spin",size:17}):e.createElement(ne,{size:17})," Sign in"),e.createElement("button",{type:"button",className:"text-button",disabled:!g||o,onClick:()=>i(async()=>{const t=await d(),{error:r}=await t.auth.resetPasswordForEmail(g,{redirectTo:location.origin+location.pathname});if(r)throw r;y("Password reset requested. Check your email.")})},"Reset password"),e.createElement("p",{className:"caption"},"Accounts must be invited and approved by your workspace developer. Signing up alone does not grant staff access."))),c&&s&&e.createElement("section",{className:"card"},e.createElement("div",{className:"section-title"},e.createElement("div",null,e.createElement("h2",null,"Shared inspection · ",s.id.slice(0,8)),e.createElement("p",null,"Saved snapshot from ",S[s.owner_id]||"a colleague",". This page does not run a new prediction.")),e.createElement("button",{className:"text-button",onClick:()=>w(null)},"Close")),e.createElement("div",{className:"shared-images"},B.map((t,r)=>e.createElement("img",{key:t,src:t,alt:r?"Saved anomaly heatmap":"Saved inspected product"}))),e.createElement("div",{className:"observation"},e.createElement("strong",null,"SAVED MEASUREMENTS"),e.createElement("span",null,s.payload.verdict," · score ",Number(s.payload.score).toFixed(5)," · threshold ",Number(s.payload.threshold).toFixed(5))),e.createElement("h3",{className:"section-gap"},"Recorded evidence"),(D=s.conversation)!=null&&D.length?s.conversation.map((t,r)=>e.createElement("p",{className:"cloud-message",key:r},e.createElement("strong",null,t.role==="user"?"Inspector":"Evidence Assistant",": "),t.question||t.answer)):e.createElement("p",{className:"caption"},"No conversation was included when this inspection was shared."),e.createElement("h3",{className:"section-gap"},"Staff review notes"),K.map(t=>e.createElement("div",{className:"cloud-message",key:t.id},e.createElement("strong",null,S[t.author_id]||"Staff member"),e.createElement("p",null,t.body),e.createElement("small",null,new Date(t.created_at).toLocaleString()))),!s.archived_at&&e.createElement("form",{className:"question-form",onSubmit:t=>{t.preventDefault(),i(async()=>{const r=await d(),{error:a}=await r.from("staff_notes").insert({inspection_id:s.id,author_id:c.id,body:k.trim()});if(a)throw a;z(""),await j(s)})}},e.createElement("input",{"aria-label":"Staff review note",maxLength:2e3,placeholder:"Add a review note for your colleagues…",value:k,onChange:t=>z(t.target.value)}),e.createElement("button",{className:"primary",disabled:o||!k.trim()},e.createElement(ce,{size:16})," Add note")))):e.createElement("section",{className:"card cloud-setup"},e.createElement("div",{className:"setup-icon"},e.createElement(_,{size:32})),e.createElement("span",{className:"eyebrow"},"TEAM WORKSPACE"),e.createElement("h2",null,"One shared view of inspection."),e.createElement("p",null,"The staff workspace is ready to connect to your own Supabase project. No cloud project or account has been created for you."),e.createElement("div",{className:"setup-grid"},[["01","Create a free project","Use your Supabase account and select an eligible Free plan."],["02","Set up staff access","Run the supplied schema, add your developer account and invite colleagues."],["03","Connect this dashboard","Add the project URL and publishable key to config.js, then reload."]].map(([t,r,a])=>e.createElement("div",{key:t},e.createElement("b",null,t),e.createElement("h3",null,r),e.createElement("p",null,a)))),e.createElement("a",{className:"primary",href:"https://supabase.com/dashboard",target:"_blank",rel:"noreferrer"},"Open Supabase ",e.createElement(re,{size:16})),e.createElement("p",{className:"caption"},"Setup files: deployment/SUPABASE_SETUP.md and deployment/supabase.sql. Never place a service-role key in the browser. Local inspection works without cloud setup."))}export{me as default};
|
frontend/dist/assets/index-BdEpy7cy.js
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
frontend/dist/index.html
CHANGED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
-
<!doctype html><html lang="en"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><meta name="theme-color" content="#132e32"/><meta name="description" content="Local visual anomaly inspection with traceable evidence."/><title>DefectRAG · Inspection intelligence</title><link rel="icon" type="image/svg+xml" href="./logo.svg"><script src="./config.js"></script> <script type="module" crossorigin src="./assets/index-
|
| 2 |
<link rel="stylesheet" crossorigin href="./assets/index-Bn4HF2vD.css">
|
| 3 |
</head><body><div id="root"></div></body></html>
|
|
|
|
| 1 |
+
<!doctype html><html lang="en"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><meta name="theme-color" content="#132e32"/><meta name="description" content="Local visual anomaly inspection with traceable evidence."/><title>DefectRAG · Inspection intelligence</title><link rel="icon" type="image/svg+xml" href="./logo.svg"><script src="./config.js"></script> <script type="module" crossorigin src="./assets/index-BdEpy7cy.js"></script>
|
| 2 |
<link rel="stylesheet" crossorigin href="./assets/index-Bn4HF2vD.css">
|
| 3 |
</head><body><div id="root"></div></body></html>
|
results/sensitive_deployment_evaluation.json
ADDED
|
@@ -0,0 +1,710 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"method": "AnomalyDINO-inspired DINOv2 ViT-S/14; custom full-data adaptation",
|
| 3 |
+
"profile": "dinov2_highres_v1",
|
| 4 |
+
"protocol": "Official VisA test assignments; same frozen DINOv2 operational banks. Threshold is the fixed linear 95th percentile of the existing content-grouped held-out training-normal scores. All categories use the same quantile; no test-label optimization. Retrospective development evaluation, not independent validation.",
|
| 5 |
+
"encoder_sha256": "ae1e99fcefd534ed978cdeb8326f08030c96e28b7a81ffcbc98a857c84d14be1",
|
| 6 |
+
"device": "cuda",
|
| 7 |
+
"categories": {
|
| 8 |
+
"pcb1": {
|
| 9 |
+
"category": "pcb1",
|
| 10 |
+
"available": true,
|
| 11 |
+
"model_id": "dinov2-highres-pcb1-v1-q95-v1",
|
| 12 |
+
"method": "AnomalyDINO-inspired DINOv2 ViT-S/14; custom full-data adaptation",
|
| 13 |
+
"profile": "dinov2_highres_v1",
|
| 14 |
+
"encoder_sha256": "ae1e99fcefd534ed978cdeb8326f08030c96e28b7a81ffcbc98a857c84d14be1",
|
| 15 |
+
"bank_sha256": "14e71cb6285f22e3d12d2b0d6357c552a26685a8f03a9b626a3e8999e8a89c65",
|
| 16 |
+
"threshold": 0.1414354294538498,
|
| 17 |
+
"uncertainty_margin": 0.00707177147269249,
|
| 18 |
+
"heatmap_scale": 0.10316987216472613,
|
| 19 |
+
"uncertainty_policy": "Fixed \u00b15% of threshold; operational heuristic, not calibrated confidence",
|
| 20 |
+
"bank_size_bytes": 23237446,
|
| 21 |
+
"encoder_size_bytes": 88249960,
|
| 22 |
+
"calibration": {
|
| 23 |
+
"method": "Fixed linear 95th percentile of heldout normal scores; no anomalous calibration",
|
| 24 |
+
"normal": 91,
|
| 25 |
+
"anomalous": 0,
|
| 26 |
+
"seed": 42,
|
| 27 |
+
"policy": "normal-q95-v1",
|
| 28 |
+
"quantile": 0.95,
|
| 29 |
+
"calibration_above_threshold": 5,
|
| 30 |
+
"future_false_positive_rate_guaranteed": false
|
| 31 |
+
},
|
| 32 |
+
"train_normal_count": 813,
|
| 33 |
+
"metrics": {
|
| 34 |
+
"image_auroc": 0.9597,
|
| 35 |
+
"average_precision": 0.9564653221826244,
|
| 36 |
+
"precision": 0.9148936170212766,
|
| 37 |
+
"recall": 0.86,
|
| 38 |
+
"f1": 0.8865979381443299,
|
| 39 |
+
"confusion_matrix": [
|
| 40 |
+
[
|
| 41 |
+
92,
|
| 42 |
+
8
|
| 43 |
+
],
|
| 44 |
+
[
|
| 45 |
+
14,
|
| 46 |
+
86
|
| 47 |
+
]
|
| 48 |
+
],
|
| 49 |
+
"n_images": 200,
|
| 50 |
+
"pixel_auroc_224": 0.9946015614062951,
|
| 51 |
+
"pixel_average_precision_224": 0.8562862818777615,
|
| 52 |
+
"uncertain_fraction": 0.07,
|
| 53 |
+
"latency_median_ms": null,
|
| 54 |
+
"peak_gpu_mb": null,
|
| 55 |
+
"false_positive_rate": 0.08
|
| 56 |
+
},
|
| 57 |
+
"resolution_short_edge": 448,
|
| 58 |
+
"patch_size": 14,
|
| 59 |
+
"foreground": "Unsupervised PCA threshold/sign heuristic; can fail",
|
| 60 |
+
"baseline_threshold": 0.16181933879852295,
|
| 61 |
+
"decision_policy": "normal-q95-v1"
|
| 62 |
+
},
|
| 63 |
+
"capsules": {
|
| 64 |
+
"category": "capsules",
|
| 65 |
+
"available": true,
|
| 66 |
+
"model_id": "dinov2-highres-capsules-v1-q95-v1",
|
| 67 |
+
"method": "AnomalyDINO-inspired DINOv2 ViT-S/14; custom full-data adaptation",
|
| 68 |
+
"profile": "dinov2_highres_v1",
|
| 69 |
+
"encoder_sha256": "ae1e99fcefd534ed978cdeb8326f08030c96e28b7a81ffcbc98a857c84d14be1",
|
| 70 |
+
"bank_sha256": "fa34f8c1a203e609450e57156d5f75ca157140d88d07d0bf46947c3029675c55",
|
| 71 |
+
"threshold": 0.1439922600984573,
|
| 72 |
+
"uncertainty_margin": 0.007199613004922866,
|
| 73 |
+
"heatmap_scale": 0.1274158811569204,
|
| 74 |
+
"uncertainty_policy": "Fixed \u00b15% of threshold; operational heuristic, not calibrated confidence",
|
| 75 |
+
"bank_size_bytes": 22108790,
|
| 76 |
+
"encoder_size_bytes": 88249960,
|
| 77 |
+
"calibration": {
|
| 78 |
+
"method": "Fixed linear 95th percentile of heldout normal scores; no anomalous calibration",
|
| 79 |
+
"normal": 55,
|
| 80 |
+
"anomalous": 0,
|
| 81 |
+
"seed": 42,
|
| 82 |
+
"policy": "normal-q95-v1",
|
| 83 |
+
"quantile": 0.95,
|
| 84 |
+
"calibration_above_threshold": 3,
|
| 85 |
+
"future_false_positive_rate_guaranteed": false
|
| 86 |
+
},
|
| 87 |
+
"train_normal_count": 487,
|
| 88 |
+
"metrics": {
|
| 89 |
+
"image_auroc": 0.9683333333333333,
|
| 90 |
+
"average_precision": 0.9798232872953215,
|
| 91 |
+
"precision": 0.9425287356321839,
|
| 92 |
+
"recall": 0.82,
|
| 93 |
+
"f1": 0.877005347593583,
|
| 94 |
+
"confusion_matrix": [
|
| 95 |
+
[
|
| 96 |
+
55,
|
| 97 |
+
5
|
| 98 |
+
],
|
| 99 |
+
[
|
| 100 |
+
18,
|
| 101 |
+
82
|
| 102 |
+
]
|
| 103 |
+
],
|
| 104 |
+
"n_images": 160,
|
| 105 |
+
"pixel_auroc_224": 0.9704973188279925,
|
| 106 |
+
"pixel_average_precision_224": 0.403655563796705,
|
| 107 |
+
"uncertain_fraction": 0.0875,
|
| 108 |
+
"latency_median_ms": null,
|
| 109 |
+
"peak_gpu_mb": null,
|
| 110 |
+
"false_positive_rate": 0.08333333333333333
|
| 111 |
+
},
|
| 112 |
+
"resolution_short_edge": 448,
|
| 113 |
+
"patch_size": 14,
|
| 114 |
+
"foreground": "Unsupervised PCA threshold/sign heuristic; can fail",
|
| 115 |
+
"baseline_threshold": 0.19718621671199799,
|
| 116 |
+
"decision_policy": "normal-q95-v1"
|
| 117 |
+
},
|
| 118 |
+
"cashew": {
|
| 119 |
+
"category": "cashew",
|
| 120 |
+
"available": true,
|
| 121 |
+
"model_id": "dinov2-highres-cashew-v1-q95-v1",
|
| 122 |
+
"method": "AnomalyDINO-inspired DINOv2 ViT-S/14; custom full-data adaptation",
|
| 123 |
+
"profile": "dinov2_highres_v1",
|
| 124 |
+
"encoder_sha256": "ae1e99fcefd534ed978cdeb8326f08030c96e28b7a81ffcbc98a857c84d14be1",
|
| 125 |
+
"bank_sha256": "4b908b22f79158fb46c0e591610d5c9470d588d4f0d017dd0bb493a58e64c693",
|
| 126 |
+
"threshold": 0.1289861112833023,
|
| 127 |
+
"uncertainty_margin": 0.006449305564165116,
|
| 128 |
+
"heatmap_scale": 0.10505769878625872,
|
| 129 |
+
"uncertainty_policy": "Fixed \u00b15% of threshold; operational heuristic, not calibrated confidence",
|
| 130 |
+
"bank_size_bytes": 18366576,
|
| 131 |
+
"encoder_size_bytes": 88249960,
|
| 132 |
+
"calibration": {
|
| 133 |
+
"method": "Fixed linear 95th percentile of heldout normal scores; no anomalous calibration",
|
| 134 |
+
"normal": 45,
|
| 135 |
+
"anomalous": 0,
|
| 136 |
+
"seed": 42,
|
| 137 |
+
"policy": "normal-q95-v1",
|
| 138 |
+
"quantile": 0.95,
|
| 139 |
+
"calibration_above_threshold": 3,
|
| 140 |
+
"future_false_positive_rate_guaranteed": false
|
| 141 |
+
},
|
| 142 |
+
"train_normal_count": 405,
|
| 143 |
+
"metrics": {
|
| 144 |
+
"image_auroc": 0.9608000000000001,
|
| 145 |
+
"average_precision": 0.9817707260519815,
|
| 146 |
+
"precision": 0.9090909090909091,
|
| 147 |
+
"recall": 0.9,
|
| 148 |
+
"f1": 0.9045226130653266,
|
| 149 |
+
"confusion_matrix": [
|
| 150 |
+
[
|
| 151 |
+
41,
|
| 152 |
+
9
|
| 153 |
+
],
|
| 154 |
+
[
|
| 155 |
+
10,
|
| 156 |
+
90
|
| 157 |
+
]
|
| 158 |
+
],
|
| 159 |
+
"n_images": 150,
|
| 160 |
+
"pixel_auroc_224": 0.9960830910862268,
|
| 161 |
+
"pixel_average_precision_224": 0.7034966403298871,
|
| 162 |
+
"uncertain_fraction": 0.06,
|
| 163 |
+
"latency_median_ms": null,
|
| 164 |
+
"peak_gpu_mb": null,
|
| 165 |
+
"false_positive_rate": 0.18
|
| 166 |
+
},
|
| 167 |
+
"resolution_short_edge": 448,
|
| 168 |
+
"patch_size": 14,
|
| 169 |
+
"foreground": "Unsupervised PCA threshold/sign heuristic; can fail",
|
| 170 |
+
"baseline_threshold": 0.13224798440933228,
|
| 171 |
+
"decision_policy": "normal-q95-v1"
|
| 172 |
+
},
|
| 173 |
+
"candle": {
|
| 174 |
+
"category": "candle",
|
| 175 |
+
"available": true,
|
| 176 |
+
"model_id": "dinov2-highres-candle-v1-q95-v1",
|
| 177 |
+
"method": "AnomalyDINO-inspired DINOv2 ViT-S/14; custom full-data adaptation",
|
| 178 |
+
"profile": "dinov2_highres_v1",
|
| 179 |
+
"encoder_sha256": "ae1e99fcefd534ed978cdeb8326f08030c96e28b7a81ffcbc98a857c84d14be1",
|
| 180 |
+
"bank_sha256": "bb6767014719520899e8d2336ea2811ae8dadabb210a8855f7497f2ac48ab7ad",
|
| 181 |
+
"threshold": 0.15027016177773475,
|
| 182 |
+
"uncertainty_margin": 0.007513508088886738,
|
| 183 |
+
"heatmap_scale": 0.1193666505813595,
|
| 184 |
+
"uncertainty_policy": "Fixed \u00b15% of threshold; operational heuristic, not calibrated confidence",
|
| 185 |
+
"bank_size_bytes": 23244689,
|
| 186 |
+
"encoder_size_bytes": 88249960,
|
| 187 |
+
"calibration": {
|
| 188 |
+
"method": "Fixed linear 95th percentile of heldout normal scores; no anomalous calibration",
|
| 189 |
+
"normal": 90,
|
| 190 |
+
"anomalous": 0,
|
| 191 |
+
"seed": 42,
|
| 192 |
+
"policy": "normal-q95-v1",
|
| 193 |
+
"quantile": 0.95,
|
| 194 |
+
"calibration_above_threshold": 5,
|
| 195 |
+
"future_false_positive_rate_guaranteed": false
|
| 196 |
+
},
|
| 197 |
+
"train_normal_count": 810,
|
| 198 |
+
"metrics": {
|
| 199 |
+
"image_auroc": 0.9410000000000001,
|
| 200 |
+
"average_precision": 0.9459465742669609,
|
| 201 |
+
"precision": 0.8787878787878788,
|
| 202 |
+
"recall": 0.87,
|
| 203 |
+
"f1": 0.8743718592964824,
|
| 204 |
+
"confusion_matrix": [
|
| 205 |
+
[
|
| 206 |
+
88,
|
| 207 |
+
12
|
| 208 |
+
],
|
| 209 |
+
[
|
| 210 |
+
13,
|
| 211 |
+
87
|
| 212 |
+
]
|
| 213 |
+
],
|
| 214 |
+
"n_images": 200,
|
| 215 |
+
"pixel_auroc_224": 0.9911336061961822,
|
| 216 |
+
"pixel_average_precision_224": 0.33767271945011856,
|
| 217 |
+
"uncertain_fraction": 0.055,
|
| 218 |
+
"latency_median_ms": null,
|
| 219 |
+
"peak_gpu_mb": null,
|
| 220 |
+
"false_positive_rate": 0.12
|
| 221 |
+
},
|
| 222 |
+
"resolution_short_edge": 448,
|
| 223 |
+
"patch_size": 14,
|
| 224 |
+
"foreground": "Unsupervised PCA threshold/sign heuristic; can fail",
|
| 225 |
+
"baseline_threshold": 0.22504067420959473,
|
| 226 |
+
"decision_policy": "normal-q95-v1"
|
| 227 |
+
},
|
| 228 |
+
"chewinggum": {
|
| 229 |
+
"category": "chewinggum",
|
| 230 |
+
"available": true,
|
| 231 |
+
"model_id": "dinov2-highres-chewinggum-v1-q95-v1",
|
| 232 |
+
"method": "AnomalyDINO-inspired DINOv2 ViT-S/14; custom full-data adaptation",
|
| 233 |
+
"profile": "dinov2_highres_v1",
|
| 234 |
+
"encoder_sha256": "ae1e99fcefd534ed978cdeb8326f08030c96e28b7a81ffcbc98a857c84d14be1",
|
| 235 |
+
"bank_sha256": "37165883dcc6304f60346c2052c7fa4151d4048b44fdb80a4f60ffc48477ed7d",
|
| 236 |
+
"threshold": 0.15658171474933624,
|
| 237 |
+
"uncertainty_margin": 0.007829085737466813,
|
| 238 |
+
"heatmap_scale": 0.11275605440139722,
|
| 239 |
+
"uncertainty_policy": "Fixed \u00b15% of threshold; operational heuristic, not calibrated confidence",
|
| 240 |
+
"bank_size_bytes": 18458527,
|
| 241 |
+
"encoder_size_bytes": 88249960,
|
| 242 |
+
"calibration": {
|
| 243 |
+
"method": "Fixed linear 95th percentile of heldout normal scores; no anomalous calibration",
|
| 244 |
+
"normal": 46,
|
| 245 |
+
"anomalous": 0,
|
| 246 |
+
"seed": 42,
|
| 247 |
+
"policy": "normal-q95-v1",
|
| 248 |
+
"quantile": 0.95,
|
| 249 |
+
"calibration_above_threshold": 3,
|
| 250 |
+
"future_false_positive_rate_guaranteed": false
|
| 251 |
+
},
|
| 252 |
+
"train_normal_count": 407,
|
| 253 |
+
"metrics": {
|
| 254 |
+
"image_auroc": 0.9885999999999999,
|
| 255 |
+
"average_precision": 0.9944721280040146,
|
| 256 |
+
"precision": 0.9795918367346939,
|
| 257 |
+
"recall": 0.96,
|
| 258 |
+
"f1": 0.9696969696969697,
|
| 259 |
+
"confusion_matrix": [
|
| 260 |
+
[
|
| 261 |
+
48,
|
| 262 |
+
2
|
| 263 |
+
],
|
| 264 |
+
[
|
| 265 |
+
4,
|
| 266 |
+
96
|
| 267 |
+
]
|
| 268 |
+
],
|
| 269 |
+
"n_images": 150,
|
| 270 |
+
"pixel_auroc_224": 0.9952665200400623,
|
| 271 |
+
"pixel_average_precision_224": 0.6597053568827396,
|
| 272 |
+
"uncertain_fraction": 0.0,
|
| 273 |
+
"latency_median_ms": null,
|
| 274 |
+
"peak_gpu_mb": null,
|
| 275 |
+
"false_positive_rate": 0.04
|
| 276 |
+
},
|
| 277 |
+
"resolution_short_edge": 448,
|
| 278 |
+
"patch_size": 14,
|
| 279 |
+
"foreground": "Unsupervised PCA threshold/sign heuristic; can fail",
|
| 280 |
+
"baseline_threshold": 0.1614319533109665,
|
| 281 |
+
"decision_policy": "normal-q95-v1"
|
| 282 |
+
},
|
| 283 |
+
"fryum": {
|
| 284 |
+
"category": "fryum",
|
| 285 |
+
"available": true,
|
| 286 |
+
"model_id": "dinov2-highres-fryum-v1-q95-v1",
|
| 287 |
+
"method": "AnomalyDINO-inspired DINOv2 ViT-S/14; custom full-data adaptation",
|
| 288 |
+
"profile": "dinov2_highres_v1",
|
| 289 |
+
"encoder_sha256": "ae1e99fcefd534ed978cdeb8326f08030c96e28b7a81ffcbc98a857c84d14be1",
|
| 290 |
+
"bank_sha256": "ca73c0cd2b2e75d80874f7dd6270f09b13c55292fa93b1da1eeef361d8375ba4",
|
| 291 |
+
"threshold": 0.13227128088474271,
|
| 292 |
+
"uncertainty_margin": 0.006613564044237136,
|
| 293 |
+
"heatmap_scale": 0.10057919770479187,
|
| 294 |
+
"uncertainty_policy": "Fixed \u00b15% of threshold; operational heuristic, not calibrated confidence",
|
| 295 |
+
"bank_size_bytes": 18381371,
|
| 296 |
+
"encoder_size_bytes": 88249960,
|
| 297 |
+
"calibration": {
|
| 298 |
+
"method": "Fixed linear 95th percentile of heldout normal scores; no anomalous calibration",
|
| 299 |
+
"normal": 45,
|
| 300 |
+
"anomalous": 0,
|
| 301 |
+
"seed": 42,
|
| 302 |
+
"policy": "normal-q95-v1",
|
| 303 |
+
"quantile": 0.95,
|
| 304 |
+
"calibration_above_threshold": 3,
|
| 305 |
+
"future_false_positive_rate_guaranteed": false
|
| 306 |
+
},
|
| 307 |
+
"train_normal_count": 405,
|
| 308 |
+
"metrics": {
|
| 309 |
+
"image_auroc": 0.9924,
|
| 310 |
+
"average_precision": 0.9963591766254614,
|
| 311 |
+
"precision": 0.9894736842105263,
|
| 312 |
+
"recall": 0.94,
|
| 313 |
+
"f1": 0.964102564102564,
|
| 314 |
+
"confusion_matrix": [
|
| 315 |
+
[
|
| 316 |
+
49,
|
| 317 |
+
1
|
| 318 |
+
],
|
| 319 |
+
[
|
| 320 |
+
6,
|
| 321 |
+
94
|
| 322 |
+
]
|
| 323 |
+
],
|
| 324 |
+
"n_images": 150,
|
| 325 |
+
"pixel_auroc_224": 0.9735429349543053,
|
| 326 |
+
"pixel_average_precision_224": 0.4360142987071739,
|
| 327 |
+
"uncertain_fraction": 0.03333333333333333,
|
| 328 |
+
"latency_median_ms": null,
|
| 329 |
+
"peak_gpu_mb": null,
|
| 330 |
+
"false_positive_rate": 0.02
|
| 331 |
+
},
|
| 332 |
+
"resolution_short_edge": 448,
|
| 333 |
+
"patch_size": 14,
|
| 334 |
+
"foreground": "Unsupervised PCA threshold/sign heuristic; can fail",
|
| 335 |
+
"baseline_threshold": 0.15253151953220367,
|
| 336 |
+
"decision_policy": "normal-q95-v1"
|
| 337 |
+
},
|
| 338 |
+
"macaroni1": {
|
| 339 |
+
"category": "macaroni1",
|
| 340 |
+
"available": true,
|
| 341 |
+
"model_id": "dinov2-highres-macaroni1-v1-q95-v1",
|
| 342 |
+
"method": "AnomalyDINO-inspired DINOv2 ViT-S/14; custom full-data adaptation",
|
| 343 |
+
"profile": "dinov2_highres_v1",
|
| 344 |
+
"encoder_sha256": "ae1e99fcefd534ed978cdeb8326f08030c96e28b7a81ffcbc98a857c84d14be1",
|
| 345 |
+
"bank_sha256": "28ebf491e124df62266c5c3b72ea5bfebb50ef93c189d5615d3ae866e8675432",
|
| 346 |
+
"threshold": 0.14440965577960013,
|
| 347 |
+
"uncertainty_margin": 0.007220482788980007,
|
| 348 |
+
"heatmap_scale": 0.09929629743099211,
|
| 349 |
+
"uncertainty_policy": "Fixed \u00b15% of threshold; operational heuristic, not calibrated confidence",
|
| 350 |
+
"bank_size_bytes": 23251984,
|
| 351 |
+
"encoder_size_bytes": 88249960,
|
| 352 |
+
"calibration": {
|
| 353 |
+
"method": "Fixed linear 95th percentile of heldout normal scores; no anomalous calibration",
|
| 354 |
+
"normal": 90,
|
| 355 |
+
"anomalous": 0,
|
| 356 |
+
"seed": 42,
|
| 357 |
+
"policy": "normal-q95-v1",
|
| 358 |
+
"quantile": 0.95,
|
| 359 |
+
"calibration_above_threshold": 5,
|
| 360 |
+
"future_false_positive_rate_guaranteed": false
|
| 361 |
+
},
|
| 362 |
+
"train_normal_count": 810,
|
| 363 |
+
"metrics": {
|
| 364 |
+
"image_auroc": 0.909,
|
| 365 |
+
"average_precision": 0.9254645749095916,
|
| 366 |
+
"precision": 0.9827586206896551,
|
| 367 |
+
"recall": 0.57,
|
| 368 |
+
"f1": 0.721518987341772,
|
| 369 |
+
"confusion_matrix": [
|
| 370 |
+
[
|
| 371 |
+
99,
|
| 372 |
+
1
|
| 373 |
+
],
|
| 374 |
+
[
|
| 375 |
+
43,
|
| 376 |
+
57
|
| 377 |
+
]
|
| 378 |
+
],
|
| 379 |
+
"n_images": 200,
|
| 380 |
+
"pixel_auroc_224": 0.9932559185087934,
|
| 381 |
+
"pixel_average_precision_224": 0.22125282869927704,
|
| 382 |
+
"uncertain_fraction": 0.1,
|
| 383 |
+
"latency_median_ms": null,
|
| 384 |
+
"peak_gpu_mb": null,
|
| 385 |
+
"false_positive_rate": 0.01
|
| 386 |
+
},
|
| 387 |
+
"resolution_short_edge": 448,
|
| 388 |
+
"patch_size": 14,
|
| 389 |
+
"foreground": "Unsupervised PCA threshold/sign heuristic; can fail",
|
| 390 |
+
"baseline_threshold": 0.21722275018692017,
|
| 391 |
+
"decision_policy": "normal-q95-v1"
|
| 392 |
+
},
|
| 393 |
+
"macaroni2": {
|
| 394 |
+
"category": "macaroni2",
|
| 395 |
+
"available": true,
|
| 396 |
+
"model_id": "dinov2-highres-macaroni2-v1-q95-v1",
|
| 397 |
+
"method": "AnomalyDINO-inspired DINOv2 ViT-S/14; custom full-data adaptation",
|
| 398 |
+
"profile": "dinov2_highres_v1",
|
| 399 |
+
"encoder_sha256": "ae1e99fcefd534ed978cdeb8326f08030c96e28b7a81ffcbc98a857c84d14be1",
|
| 400 |
+
"bank_sha256": "8dfe4f82ece83668ea4a97c18ef134ab16bea8ab6d2913959eb810942537737a",
|
| 401 |
+
"threshold": 0.144144269824028,
|
| 402 |
+
"uncertainty_margin": 0.0072072134912014,
|
| 403 |
+
"heatmap_scale": 0.11770220518112187,
|
| 404 |
+
"uncertainty_policy": "Fixed \u00b15% of threshold; operational heuristic, not calibrated confidence",
|
| 405 |
+
"bank_size_bytes": 23243554,
|
| 406 |
+
"encoder_size_bytes": 88249960,
|
| 407 |
+
"calibration": {
|
| 408 |
+
"method": "Fixed linear 95th percentile of heldout normal scores; no anomalous calibration",
|
| 409 |
+
"normal": 90,
|
| 410 |
+
"anomalous": 0,
|
| 411 |
+
"seed": 42,
|
| 412 |
+
"policy": "normal-q95-v1",
|
| 413 |
+
"quantile": 0.95,
|
| 414 |
+
"calibration_above_threshold": 5,
|
| 415 |
+
"future_false_positive_rate_guaranteed": false
|
| 416 |
+
},
|
| 417 |
+
"train_normal_count": 810,
|
| 418 |
+
"metrics": {
|
| 419 |
+
"image_auroc": 0.845,
|
| 420 |
+
"average_precision": 0.8446602099722114,
|
| 421 |
+
"precision": 0.8727272727272727,
|
| 422 |
+
"recall": 0.48,
|
| 423 |
+
"f1": 0.6193548387096774,
|
| 424 |
+
"confusion_matrix": [
|
| 425 |
+
[
|
| 426 |
+
93,
|
| 427 |
+
7
|
| 428 |
+
],
|
| 429 |
+
[
|
| 430 |
+
52,
|
| 431 |
+
48
|
| 432 |
+
]
|
| 433 |
+
],
|
| 434 |
+
"n_images": 200,
|
| 435 |
+
"pixel_auroc_224": 0.9942242061289198,
|
| 436 |
+
"pixel_average_precision_224": 0.15769057747120718,
|
| 437 |
+
"uncertain_fraction": 0.19,
|
| 438 |
+
"latency_median_ms": null,
|
| 439 |
+
"peak_gpu_mb": null,
|
| 440 |
+
"false_positive_rate": 0.07
|
| 441 |
+
},
|
| 442 |
+
"resolution_short_edge": 448,
|
| 443 |
+
"patch_size": 14,
|
| 444 |
+
"foreground": "Unsupervised PCA threshold/sign heuristic; can fail",
|
| 445 |
+
"baseline_threshold": 0.15817631781101227,
|
| 446 |
+
"decision_policy": "normal-q95-v1"
|
| 447 |
+
},
|
| 448 |
+
"pcb2": {
|
| 449 |
+
"category": "pcb2",
|
| 450 |
+
"available": true,
|
| 451 |
+
"model_id": "dinov2-highres-pcb2-v1-q95-v1",
|
| 452 |
+
"method": "AnomalyDINO-inspired DINOv2 ViT-S/14; custom full-data adaptation",
|
| 453 |
+
"profile": "dinov2_highres_v1",
|
| 454 |
+
"encoder_sha256": "ae1e99fcefd534ed978cdeb8326f08030c96e28b7a81ffcbc98a857c84d14be1",
|
| 455 |
+
"bank_sha256": "694689b6703e399ea4076343a40ddff6a920f67c0c344048f0b2ef6402f3abb8",
|
| 456 |
+
"threshold": 0.1252228133380413,
|
| 457 |
+
"uncertainty_margin": 0.006261140666902066,
|
| 458 |
+
"heatmap_scale": 0.09851976394653338,
|
| 459 |
+
"uncertainty_policy": "Fixed \u00b15% of threshold; operational heuristic, not calibrated confidence",
|
| 460 |
+
"bank_size_bytes": 23253151,
|
| 461 |
+
"encoder_size_bytes": 88249960,
|
| 462 |
+
"calibration": {
|
| 463 |
+
"method": "Fixed linear 95th percentile of heldout normal scores; no anomalous calibration",
|
| 464 |
+
"normal": 91,
|
| 465 |
+
"anomalous": 0,
|
| 466 |
+
"seed": 42,
|
| 467 |
+
"policy": "normal-q95-v1",
|
| 468 |
+
"quantile": 0.95,
|
| 469 |
+
"calibration_above_threshold": 5,
|
| 470 |
+
"future_false_positive_rate_guaranteed": false
|
| 471 |
+
},
|
| 472 |
+
"train_normal_count": 810,
|
| 473 |
+
"metrics": {
|
| 474 |
+
"image_auroc": 0.9062,
|
| 475 |
+
"average_precision": 0.9098166487308751,
|
| 476 |
+
"precision": 0.875,
|
| 477 |
+
"recall": 0.84,
|
| 478 |
+
"f1": 0.8571428571428572,
|
| 479 |
+
"confusion_matrix": [
|
| 480 |
+
[
|
| 481 |
+
88,
|
| 482 |
+
12
|
| 483 |
+
],
|
| 484 |
+
[
|
| 485 |
+
16,
|
| 486 |
+
84
|
| 487 |
+
]
|
| 488 |
+
],
|
| 489 |
+
"n_images": 200,
|
| 490 |
+
"pixel_auroc_224": 0.9714470671684394,
|
| 491 |
+
"pixel_average_precision_224": 0.26303790724220233,
|
| 492 |
+
"uncertain_fraction": 0.09,
|
| 493 |
+
"latency_median_ms": null,
|
| 494 |
+
"peak_gpu_mb": null,
|
| 495 |
+
"false_positive_rate": 0.12
|
| 496 |
+
},
|
| 497 |
+
"resolution_short_edge": 448,
|
| 498 |
+
"patch_size": 14,
|
| 499 |
+
"foreground": "Unsupervised PCA threshold/sign heuristic; can fail",
|
| 500 |
+
"baseline_threshold": 0.341839998960495,
|
| 501 |
+
"decision_policy": "normal-q95-v1"
|
| 502 |
+
},
|
| 503 |
+
"pcb3": {
|
| 504 |
+
"category": "pcb3",
|
| 505 |
+
"available": true,
|
| 506 |
+
"model_id": "dinov2-highres-pcb3-v1-q95-v1",
|
| 507 |
+
"method": "AnomalyDINO-inspired DINOv2 ViT-S/14; custom full-data adaptation",
|
| 508 |
+
"profile": "dinov2_highres_v1",
|
| 509 |
+
"encoder_sha256": "ae1e99fcefd534ed978cdeb8326f08030c96e28b7a81ffcbc98a857c84d14be1",
|
| 510 |
+
"bank_sha256": "704ee7d0827ede2b0a795a0efae8eb524751d2d1cb054cf7278c22888550a44c",
|
| 511 |
+
"threshold": 0.1346755474805832,
|
| 512 |
+
"uncertainty_margin": 0.00673377737402916,
|
| 513 |
+
"heatmap_scale": 0.1029075479507446,
|
| 514 |
+
"uncertainty_policy": "Fixed \u00b15% of threshold; operational heuristic, not calibrated confidence",
|
| 515 |
+
"bank_size_bytes": 23242572,
|
| 516 |
+
"encoder_size_bytes": 88249960,
|
| 517 |
+
"calibration": {
|
| 518 |
+
"method": "Fixed linear 95th percentile of heldout normal scores; no anomalous calibration",
|
| 519 |
+
"normal": 91,
|
| 520 |
+
"anomalous": 0,
|
| 521 |
+
"seed": 42,
|
| 522 |
+
"policy": "normal-q95-v1",
|
| 523 |
+
"quantile": 0.95,
|
| 524 |
+
"calibration_above_threshold": 5,
|
| 525 |
+
"future_false_positive_rate_guaranteed": false
|
| 526 |
+
},
|
| 527 |
+
"train_normal_count": 814,
|
| 528 |
+
"metrics": {
|
| 529 |
+
"image_auroc": 0.9547524752475247,
|
| 530 |
+
"average_precision": 0.9645187368797429,
|
| 531 |
+
"precision": 0.90625,
|
| 532 |
+
"recall": 0.87,
|
| 533 |
+
"f1": 0.8877551020408163,
|
| 534 |
+
"confusion_matrix": [
|
| 535 |
+
[
|
| 536 |
+
92,
|
| 537 |
+
9
|
| 538 |
+
],
|
| 539 |
+
[
|
| 540 |
+
13,
|
| 541 |
+
87
|
| 542 |
+
]
|
| 543 |
+
],
|
| 544 |
+
"n_images": 201,
|
| 545 |
+
"pixel_auroc_224": 0.9805302802001331,
|
| 546 |
+
"pixel_average_precision_224": 0.33774957148695994,
|
| 547 |
+
"uncertain_fraction": 0.08955223880597014,
|
| 548 |
+
"latency_median_ms": null,
|
| 549 |
+
"peak_gpu_mb": null,
|
| 550 |
+
"false_positive_rate": 0.0891089108910891
|
| 551 |
+
},
|
| 552 |
+
"resolution_short_edge": 448,
|
| 553 |
+
"patch_size": 14,
|
| 554 |
+
"foreground": "Unsupervised PCA threshold/sign heuristic; can fail",
|
| 555 |
+
"baseline_threshold": 0.16282716393470764,
|
| 556 |
+
"decision_policy": "normal-q95-v1"
|
| 557 |
+
},
|
| 558 |
+
"pcb4": {
|
| 559 |
+
"category": "pcb4",
|
| 560 |
+
"available": true,
|
| 561 |
+
"model_id": "dinov2-highres-pcb4-v1-q95-v1",
|
| 562 |
+
"method": "AnomalyDINO-inspired DINOv2 ViT-S/14; custom full-data adaptation",
|
| 563 |
+
"profile": "dinov2_highres_v1",
|
| 564 |
+
"encoder_sha256": "ae1e99fcefd534ed978cdeb8326f08030c96e28b7a81ffcbc98a857c84d14be1",
|
| 565 |
+
"bank_sha256": "8847deec2a0b8daab9139e7680d502352161e994bb5d2fe4bc313df6af4cc5d5",
|
| 566 |
+
"threshold": 0.1401524841785431,
|
| 567 |
+
"uncertainty_margin": 0.007007624208927155,
|
| 568 |
+
"heatmap_scale": 0.10422959923744202,
|
| 569 |
+
"uncertainty_policy": "Fixed \u00b15% of threshold; operational heuristic, not calibrated confidence",
|
| 570 |
+
"bank_size_bytes": 23248613,
|
| 571 |
+
"encoder_size_bytes": 88249960,
|
| 572 |
+
"calibration": {
|
| 573 |
+
"method": "Fixed linear 95th percentile of heldout normal scores; no anomalous calibration",
|
| 574 |
+
"normal": 91,
|
| 575 |
+
"anomalous": 0,
|
| 576 |
+
"seed": 42,
|
| 577 |
+
"policy": "normal-q95-v1",
|
| 578 |
+
"quantile": 0.95,
|
| 579 |
+
"calibration_above_threshold": 5,
|
| 580 |
+
"future_false_positive_rate_guaranteed": false
|
| 581 |
+
},
|
| 582 |
+
"train_normal_count": 813,
|
| 583 |
+
"metrics": {
|
| 584 |
+
"image_auroc": 0.9865346534653465,
|
| 585 |
+
"average_precision": 0.9822685098306626,
|
| 586 |
+
"precision": 0.96,
|
| 587 |
+
"recall": 0.96,
|
| 588 |
+
"f1": 0.96,
|
| 589 |
+
"confusion_matrix": [
|
| 590 |
+
[
|
| 591 |
+
97,
|
| 592 |
+
4
|
| 593 |
+
],
|
| 594 |
+
[
|
| 595 |
+
4,
|
| 596 |
+
96
|
| 597 |
+
]
|
| 598 |
+
],
|
| 599 |
+
"n_images": 201,
|
| 600 |
+
"pixel_auroc_224": 0.9806894408642699,
|
| 601 |
+
"pixel_average_precision_224": 0.3216614985757051,
|
| 602 |
+
"uncertain_fraction": 0.04477611940298507,
|
| 603 |
+
"latency_median_ms": null,
|
| 604 |
+
"peak_gpu_mb": null,
|
| 605 |
+
"false_positive_rate": 0.039603960396039604
|
| 606 |
+
},
|
| 607 |
+
"resolution_short_edge": 448,
|
| 608 |
+
"patch_size": 14,
|
| 609 |
+
"foreground": "Unsupervised PCA threshold/sign heuristic; can fail",
|
| 610 |
+
"baseline_threshold": 0.17516569793224335,
|
| 611 |
+
"decision_policy": "normal-q95-v1"
|
| 612 |
+
},
|
| 613 |
+
"pipe_fryum": {
|
| 614 |
+
"category": "pipe_fryum",
|
| 615 |
+
"available": true,
|
| 616 |
+
"model_id": "dinov2-highres-pipe_fryum-v1-q95-v1",
|
| 617 |
+
"method": "AnomalyDINO-inspired DINOv2 ViT-S/14; custom full-data adaptation",
|
| 618 |
+
"profile": "dinov2_highres_v1",
|
| 619 |
+
"encoder_sha256": "ae1e99fcefd534ed978cdeb8326f08030c96e28b7a81ffcbc98a857c84d14be1",
|
| 620 |
+
"bank_sha256": "e28bf35ca2e553dd21821230f34682b94b11a5d203459f61049a774663c0d819",
|
| 621 |
+
"threshold": 0.17671903371810913,
|
| 622 |
+
"uncertainty_margin": 0.008835951685905457,
|
| 623 |
+
"heatmap_scale": 0.1333938717842105,
|
| 624 |
+
"uncertainty_policy": "Fixed \u00b15% of threshold; operational heuristic, not calibrated confidence",
|
| 625 |
+
"bank_size_bytes": 18401041,
|
| 626 |
+
"encoder_size_bytes": 88249960,
|
| 627 |
+
"calibration": {
|
| 628 |
+
"method": "Fixed linear 95th percentile of heldout normal scores; no anomalous calibration",
|
| 629 |
+
"normal": 45,
|
| 630 |
+
"anomalous": 0,
|
| 631 |
+
"seed": 42,
|
| 632 |
+
"policy": "normal-q95-v1",
|
| 633 |
+
"quantile": 0.95,
|
| 634 |
+
"calibration_above_threshold": 3,
|
| 635 |
+
"future_false_positive_rate_guaranteed": false
|
| 636 |
+
},
|
| 637 |
+
"train_normal_count": 405,
|
| 638 |
+
"metrics": {
|
| 639 |
+
"image_auroc": 0.9891999999999999,
|
| 640 |
+
"average_precision": 0.9951337553868363,
|
| 641 |
+
"precision": 0.9801980198019802,
|
| 642 |
+
"recall": 0.99,
|
| 643 |
+
"f1": 0.9850746268656716,
|
| 644 |
+
"confusion_matrix": [
|
| 645 |
+
[
|
| 646 |
+
48,
|
| 647 |
+
2
|
| 648 |
+
],
|
| 649 |
+
[
|
| 650 |
+
1,
|
| 651 |
+
99
|
| 652 |
+
]
|
| 653 |
+
],
|
| 654 |
+
"n_images": 150,
|
| 655 |
+
"pixel_auroc_224": 0.9927315263511816,
|
| 656 |
+
"pixel_average_precision_224": 0.47984772131593945,
|
| 657 |
+
"uncertain_fraction": 0.013333333333333334,
|
| 658 |
+
"latency_median_ms": null,
|
| 659 |
+
"peak_gpu_mb": null,
|
| 660 |
+
"false_positive_rate": 0.04
|
| 661 |
+
},
|
| 662 |
+
"resolution_short_edge": 448,
|
| 663 |
+
"patch_size": 14,
|
| 664 |
+
"foreground": "Unsupervised PCA threshold/sign heuristic; can fail",
|
| 665 |
+
"baseline_threshold": 0.18373285233974457,
|
| 666 |
+
"decision_policy": "normal-q95-v1"
|
| 667 |
+
}
|
| 668 |
+
},
|
| 669 |
+
"macro_mean": {
|
| 670 |
+
"image_auroc": 0.950126705170517,
|
| 671 |
+
"average_precision": 0.956391637511357,
|
| 672 |
+
"precision": 0.932608381224698,
|
| 673 |
+
"recall": 0.8383333333333334,
|
| 674 |
+
"f1": 0.8755953086666709,
|
| 675 |
+
"pixel_auroc_224": 0.9861669559777334,
|
| 676 |
+
"pixel_average_precision_224": 0.4315059138196397,
|
| 677 |
+
"false_positive_rate": 0.07433718371837184
|
| 678 |
+
},
|
| 679 |
+
"decision_policy": "normal-q95-v1",
|
| 680 |
+
"baseline_evaluation_sha256": "4265f2fe45c49d3e71dacba9883e935b190829511fa42ecbc45c26e495984ec0",
|
| 681 |
+
"validation_scope": "Normal-only calibration and cached-score/software consistency checks; future recall and false-alarm rates are not guaranteed.",
|
| 682 |
+
"decision_policy_reason": "User requested prioritizing anomaly recall and accepts more false alarms.",
|
| 683 |
+
"policy_selection_context": "Policy adopted after viewing retrospective threshold-sensitivity results; not an independent or test-blind validation.",
|
| 684 |
+
"source_sha256": {
|
| 685 |
+
"experiments\\dinov2_highres_v1\\pcb1\\normal_calibration.json": "8224a5c38e21ae2b65497c109f45ce586e231525d43946779e0309225faf7010",
|
| 686 |
+
"experiments\\dinov2_highres_v1\\pcb1\\test_progress.json": "ba9bdde38b06df345c8f5a72ff1358a40d04287f609cac4bbac629cd652e6640",
|
| 687 |
+
"experiments\\dinov2_highres_v1\\capsules\\normal_calibration.json": "05a2f76ac29bb3d3e794155587f90e2ad3099b2df1bc14b0c8b6447aaab6f4f6",
|
| 688 |
+
"experiments\\dinov2_highres_v1\\capsules\\test_progress.json": "a214382658449bec9468a1d1103775cfa989b9f4d96c728ea756b1539c7a05e6",
|
| 689 |
+
"experiments\\dinov2_highres_v1\\cashew\\normal_calibration.json": "20b872ab18468386c96cee420ecddff58d4d9bb40ceb16edbb77a7965413dac2",
|
| 690 |
+
"experiments\\dinov2_highres_v1\\cashew\\test_progress.json": "dc236ba067baeac20b431da6b323abdcccadbfdd4fb58148f26dd0b2fd4733c1",
|
| 691 |
+
"experiments\\dinov2_highres_v1\\candle\\normal_calibration.json": "097689c7796940d5bcb30117fa22f454b906c519d7a4472bdd87e6434a3eb500",
|
| 692 |
+
"experiments\\dinov2_highres_v1\\candle\\test_progress.json": "2ec3a02bcc0c95d94242d4d31469b53126ddeae9ce5d777f0706dec984c362b2",
|
| 693 |
+
"experiments\\dinov2_highres_v1\\chewinggum\\normal_calibration.json": "012178e1e91e311e511a7f8b2ebabbff4fe1146a7d6a2227e374c264c763b995",
|
| 694 |
+
"experiments\\dinov2_highres_v1\\chewinggum\\test_progress.json": "ea5102f1d9e668ad8ff256dfcba10813b3f3723e0b09606b87745f71347b1a0f",
|
| 695 |
+
"experiments\\dinov2_highres_v1\\fryum\\normal_calibration.json": "6cd8984692afd2c20825b45a2c18d07550367510e376ce6c70d5bb2e44990432",
|
| 696 |
+
"experiments\\dinov2_highres_v1\\fryum\\test_progress.json": "52e7dababf991acdeda16907ae38cc9a2599a0164becbfcd7b3bbd96658c944f",
|
| 697 |
+
"experiments\\dinov2_highres_v1\\macaroni1\\normal_calibration.json": "6c83ed692639479b8b18914c7bea0c884eea7a1c0583106ea9bcd3d30c01dfde",
|
| 698 |
+
"experiments\\dinov2_highres_v1\\macaroni1\\test_progress.json": "d67ebfb2159c5dbe1cee314c300deb04123751caefd99288e99961dcfac1bb04",
|
| 699 |
+
"experiments\\dinov2_highres_v1\\macaroni2\\normal_calibration.json": "8c80102797cc6d81fd1862ec5c27465b3293e206ccb0b2af40973526a93a96a6",
|
| 700 |
+
"experiments\\dinov2_highres_v1\\macaroni2\\test_progress.json": "12bfe59625f5039623c341451c9e4ce0721271d98d7a8a815b2dc443465a88d8",
|
| 701 |
+
"experiments\\dinov2_highres_v1\\pcb2\\normal_calibration.json": "3b0713db8eebc9f7ea81ac1e758c42799e325aa0050a3c0c2ac1454e7457cd3a",
|
| 702 |
+
"experiments\\dinov2_highres_v1\\pcb2\\test_progress.json": "3b08920766efc75a65d1f7f4518adb086241b0ba71e2659a20edcf57a783afdb",
|
| 703 |
+
"experiments\\dinov2_highres_v1\\pcb3\\normal_calibration.json": "2c0e355bca9f8554fad3715d3a31acf733b30788c7b7e97a931cd24fb4d6ebd3",
|
| 704 |
+
"experiments\\dinov2_highres_v1\\pcb3\\test_progress.json": "e5e8d8d7adb1198b6cdca2f5bda7da0e71b4e30a672ae93714eb6efe7aefff0b",
|
| 705 |
+
"experiments\\dinov2_highres_v1\\pcb4\\normal_calibration.json": "2b364ef709f3ead9196871d7f0351ae38f477fbf98d6f94ca8607128a853b28a",
|
| 706 |
+
"experiments\\dinov2_highres_v1\\pcb4\\test_progress.json": "dd844a6415590d7effee5ba32eb7f2fbd737d7967efafebd845af506fd7685ae",
|
| 707 |
+
"experiments\\dinov2_highres_v1\\pipe_fryum\\normal_calibration.json": "21b3357ff4836e8b4d7fb7fee7e48fc7579a62d9c11dbf888f2de05397a88d56",
|
| 708 |
+
"experiments\\dinov2_highres_v1\\pipe_fryum\\test_progress.json": "0af8805dd69be9f39b2bedb13f8bd15e853f326e1ed9940b540d26ff01cf6dbf"
|
| 709 |
+
}
|
| 710 |
+
}
|