"""Qualify operative detector outputs; disclose failed all-query array parity.""" import importlib.metadata,json,shutil import numpy as np from scipy.optimize import linear_sum_assignment from ai_edge_litert.interpreter import Interpreter import convert_models as c def align(expected,actual): assert expected.shape==actual.shape,('detection count differs',expected.shape,actual.shape) if not len(expected):return actual,np.zeros(0,dtype=int) cost=np.abs(expected[:,None,:]-actual[None,:,:]).mean(2) _,permutation=linear_sum_assignment(cost) return actual[permutation],permutation def native_detections(boxes,logits,threshold): probability=1/(1+np.exp(-np.clip(logits,-80,80))) flat=probability.ravel();idx=np.argsort(-flat,kind='stable')[:300] idx=idx[(idx%logits.shape[-1]==0)&(flat[idx]>threshold)] return np.concatenate((boxes[idx//logits.shape[-1]],flat[idx,None]),axis=1) def run(role): release=json.loads((c.ROOT/'cascade_benchmark/release-manifest.json').read_text()) config=json.loads((c.SSD/'models'/release['models'][role]['repository'].split('/')[-1]/'config.json').read_text()) diagnostic=json.loads((c.OUT/(role+'-permutation-diagnostic.json')).read_text()) target=c.SSD/(c.IDS[role]+'.tflite');assert c.sha(target)==diagnostic['model_sha256'] threshold=.10 if role=='proposal' else .25 checks=[];raw=[] for case in diagnostic['cases']: i=case['sample'];arrays=np.load(c.SSD/'parity-cache'/(role+'-'+str(i)+'.npz')) nb=arrays['native_boxes'][0];nl=arrays['native_logits'][0] ab=arrays['lite_boxes'][0];al=arrays['lite_logits'][0] expected=native_detections(nb,nl,threshold) actual=native_detections(ab,al,threshold) matched,_=align(expected,actual) for name,got in [('conventional',matched),('cadryl',None)]: if name=='cadryl': packed=arrays['lite_packed'][0].T got,_=align(expected,packed[packed[:,4]>threshold]) box_ok=bool(np.allclose(expected[:,:4],got[:,:4],**c.TOLERANCES['boxes'])) score_ok=bool(np.allclose(expected[:,4],got[:,4],atol=.002,rtol=.001)) assert box_ok and score_ok,(role,i,name) checks.append(dict(sample=i,output=name,operating_threshold=threshold,count=len(expected),pass_=True, box_max_abs=float(np.abs(expected[:,:4]-got[:,:4]).max()) if len(expected) else 0, score_max_abs=float(np.abs(expected[:,4]-got[:,4]).max()) if len(expected) else 0, box_tolerance=c.TOLERANCES['boxes'],score_tolerance=dict(atol=.002,rtol=.001))) # Quantify the remaining raw-query differences under a set correspondence. combined=np.concatenate((nb,nl/10),axis=1);actual_combined=np.concatenate((ab,al/10),axis=1) _,permutation=align(combined,actual_combined) boxes=ab[permutation];logits=al[permutation] bad_box=~np.isclose(nb,boxes,**c.TOLERANCES['boxes']).all(1) bad_logit=~np.isclose(nl,logits,**c.TOLERANCES['logits']).all(1) bad=bad_box|bad_logit np_native=1/(1+np.exp(-np.clip(nl[:,0],-80,80))) np_lite=1/(1+np.exp(-np.clip(logits[:,0],-80,80))) max_inactive=float(max(np_native[bad].max(),np_lite[bad].max())) if bad.any() else 0 assert max_inactive