diff options
Diffstat (limited to 'artifacts/spectral_frontier_probe/diag10.py')
| -rw-r--r-- | artifacts/spectral_frontier_probe/diag10.py | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/artifacts/spectral_frontier_probe/diag10.py b/artifacts/spectral_frontier_probe/diag10.py new file mode 100644 index 0000000..752612c --- /dev/null +++ b/artifacts/spectral_frontier_probe/diag10.py @@ -0,0 +1,41 @@ +import numpy as np, torch +from collections import defaultdict +def standardise(M): + M=np.asarray(M,dtype=np.float64); mask=~np.eye(len(M),dtype=bool); v=M[mask] + out=(M-v.mean())/v.std(); np.fill_diagonal(out,0.0); return out +d=torch.load('/home/yurenh2/emm/artifacts/synth_v1/omit_size.pt',map_location='cpu') +V0=d['visual_field'].double().numpy(); T0=d['text_field'].double().numpy() +T=standardise(T0); V=standardise(V0); N=len(T) +# exact automorphism-by-identical-rows of T (blind: uses T only) +key={}; cls=defaultdict(list) +Toff=T.copy(); np.fill_diagonal(Toff,0.0) +# group scenes whose T rows agree after removing the two swapped coords +groups=[]; used=np.zeros(N,bool) +for i in range(N): + if used[i]: continue + g=[i]; used[i]=True + for j in range(i+1,N): + if used[j]: continue + a=np.delete(Toff[i],[i,j]); b=np.delete(Toff[j],[i,j]) + if np.abs(a-b).max()<1e-9 and abs(Toff[i,j]-max(Toff[i,i],0))<1e6: + g.append(j); used[j]=True + groups.append(g) +sizes=np.array([len(g) for g in groups]) +print("T exact-twin classes: total",len(groups),"; size histogram",np.bincount(sizes)[1:]) +excess=int((sizes-1).sum()) +print("scenes in non-trivial classes:",int(sizes[sizes>1].sum()),"; log|Aut| classes:",int((sizes>1).sum())) +ceil=(N-int(sizes[sizes>1].sum())+int((sizes>1).sum()))/N +print(f"blind accuracy ceiling if class is identified but member picked at random: {ceil:.3f}") +# check the objective really is invariant: swap two members of a class +import itertools +p=np.arange(N) +E0=(( (T*T).sum()+(V*V).sum() )-2*(T[np.ix_(p,p)]*V).sum())/(N*(N-1)) +bad=0; tested=0 +for g in groups: + if len(g)>1: + i,j=g[0],g[1]; q=p.copy(); q[[i,j]]=q[[j,i]] + E1=(((T*T).sum()+(V*V).sum())-2*(T[np.ix_(q,q)]*V).sum())/(N*(N-1)) + tested+=1 + if abs(E1-E0)>1e-9: bad+=1 +print(f"swapping twins changes E in {bad}/{tested} classes (0 means exact symmetry of the objective)") +print(f"E(truth) = {E0:.10f}") |
