Chucks90 commited on
Commit
f6fe04d
Β·
verified Β·
1 Parent(s): df23831

v4: concentration-steering NEGATIVE (globalization is entangling, not removable); multi-seed rigor (S1 exact law, S2 tail-gap selector regret 0.006); papers updated

Browse files
jobs/g1a_concentration_steering_job.py ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # /// script
2
+ # requires-python = ">=3.10"
3
+ # dependencies = [
4
+ # "torch", "torchvision", "numpy", "pillow", "scikit-learn", "scipy",
5
+ # "huggingface_hub>=0.34", "dinov3 @ git+https://github.com/facebookresearch/dinov3",
6
+ # ]
7
+ # ///
8
+ """G1a β€” TRAINING-FREE concentration steering (anti-globalization). HF Job (GPU).
9
+
10
+ Mechanism (F3): self-distillation globalizes away rare-signal structure with depth -- the eroded
11
+ representation has energy piled into a few dominant, common ("globalized") directions. Steering:
12
+ remove the top-q PCA directions of the (label-free) token bank at a layer, then density-localize
13
+ in the residual: Z' = Z - (Z U_q) U_q^T. Sweep layer x q. Two wins to look for:
14
+ (i) at LATE layers, q>0 RECOVERS localizability (q>0 >> q=0) -> globalization is causally the
15
+ eroder, removable training-free;
16
+ (ii) the best (layer, q) EXCEEDS the best raw single layer (>0.88) -> training-free amplification
17
+ beyond any layer.
18
+ Label-free throughout (PCA on the bank, masks eval-only). Emits G1A_RESULT.
19
+ """
20
+ from __future__ import annotations
21
+ import json, os, sys, time
22
+ from pathlib import Path
23
+ import numpy as np, torch
24
+ from PIL import Image
25
+ from scipy import stats
26
+ from sklearn.neighbors import NearestNeighbors
27
+ from huggingface_hub import hf_hub_download
28
+ sys.path.insert(0,"/mnt/processed/covtoken_code")
29
+ from dinov3.models.vision_transformer import vit_base # noqa: E402
30
+
31
+ BACKBONE_REPO="ricklisz123/MedDINOv3-ViTB-16-CT-3M"; MNT=Path("/mnt")
32
+ RAW_LIDC=MNT/"raw"/"lidc"; MASK_ROOT=MNT/"processed"/"lidc_v2"; OUT=MNT/"processed"/"covtoken"
33
+ N_PATCH,CLS_OFF=196,5
34
+ LAYERS=[int(x) for x in os.environ.get("LAYERS","2,5,8,11").split(",")] # blocks 3,6,9,12
35
+ QS=[int(x) for x in os.environ.get("QS","0,4,8,16,32,64").split(",")]
36
+ BANK_SLICES=int(os.environ.get("BANK_SLICES","600")); EVAL_SLICES=int(os.environ.get("EVAL_SLICES","600"))
37
+ CT_MEAN=np.array([0.485,0.456,0.406],np.float32); CT_STD=np.array([0.229,0.224,0.225],np.float32)
38
+ _F={}
39
+ def log(m): print(f"[g1a] {m}", flush=True)
40
+
41
+
42
+ def load_backbone(device):
43
+ ck=hf_hub_download(BACKBONE_REPO,"model.pth",token=os.environ.get("HF_TOKEN"))
44
+ m=vit_base(drop_path_rate=0.0,layerscale_init=1e-5,n_storage_tokens=4,qkv_bias=False,mask_k_bias=True)
45
+ raw=torch.load(ck,map_location="cpu"); sd=raw.get("teacher",raw)
46
+ sd={(k[9:] if k.startswith("backbone.") else k):v for k,v in sd.items()}
47
+ m.load_state_dict(sd,strict=False); m.eval().to(device)
48
+ for p in m.parameters(): p.requires_grad_(False)
49
+ feats={}
50
+ for i,blk in enumerate(m.blocks):
51
+ def mk(i):
52
+ def h(_m,_i,out):
53
+ while isinstance(out,(list,tuple)): out=out[0]
54
+ feats[i]=out.detach()
55
+ return h
56
+ blk.register_forward_hook(mk(i))
57
+ return m,feats
58
+
59
+
60
+ def load_img(p):
61
+ img=Image.open(p).convert("RGB").resize((224,224),Image.BILINEAR)
62
+ return torch.from_numpy(((np.asarray(img,np.float32)/255.0-CT_MEAN)/CT_STD)).permute(2,0,1)
63
+
64
+
65
+ @torch.inference_mode()
66
+ def allL(model,feats,imgs,device):
67
+ model.forward_features(imgs.to(device,torch.float32))
68
+ return {L:feats[L][:,CLS_OFF:CLS_OFF+N_PATCH,:].float().cpu() for L in LAYERS}
69
+
70
+
71
+ def auroc(s,y):
72
+ s=np.asarray(s,float); y=np.asarray(y,int); pos,neg=y.sum(),len(y)-y.sum()
73
+ if pos==0 or neg==0: return float("nan")
74
+ r=stats.rankdata(s); return float((r[y==1].sum()-pos*(pos+1)/2)/(pos*neg))
75
+
76
+
77
+ def main():
78
+ t0=time.time(); device=torch.device("cuda" if torch.cuda.is_available() else "cpu")
79
+ model,feats=load_backbone(device); rng=np.random.default_rng(0)
80
+ scan_split=json.load(open(hf_hub_download("Chucks90/eryon-data-pipelines","manifests/lidc/splits_v1.0.0.json",repo_type="dataset",token=os.environ.get("HF_TOKEN"))))["splits"]
81
+ train=[]
82
+ for b in sorted(RAW_LIDC.glob("batch_*")):
83
+ for sd in b.iterdir():
84
+ if sd.is_dir() and scan_split.get(sd.name)=="train": train+=sorted(sd.glob("slice_*.png"))
85
+ train=[train[i] for i in rng.choice(len(train),min(BANK_SLICES,len(train)),replace=False)]
86
+ ev=[]
87
+ for cd in sorted((MASK_ROOT/"test").iterdir()):
88
+ npz=cd/"patch_masks.npz"
89
+ if cd.is_dir() and npz.exists():
90
+ pm=np.load(npz)["patch_masks"]
91
+ for idx in range(len(pm)): ev.append((cd/f"slice_{idx:04d}.png", pm[idx]))
92
+ ev=[ev[i] for i in rng.choice(len(ev),min(EVAL_SLICES,len(ev)),replace=False)]
93
+ log(f"device={device.type}; bank={len(train)} eval={len(ev)} layers={[L+1 for L in LAYERS]} qs={QS}")
94
+
95
+ bankL={L:[] for L in LAYERS}
96
+ for i in range(0,len(train),64):
97
+ pl=allL(model,feats,torch.stack([load_img(p) for p in train[i:i+64]]),device)
98
+ for L in LAYERS: bankL[L].append(pl[L].reshape(-1,768))
99
+ bankL={L:torch.cat(v,0) for L,v in bankL.items()}
100
+ # per-layer PCA basis (label-free) for steering
101
+ basis={}; mean={}
102
+ for L in LAYERS:
103
+ X=bankL[L]; mean[L]=X.mean(0,keepdim=True); Xc=X-mean[L]
104
+ idx=torch.from_numpy(rng.choice(Xc.shape[0],min(120000,Xc.shape[0]),replace=False))
105
+ _,_,Vt=torch.linalg.svd(Xc[idx],full_matrices=False); basis[L]=Vt # (768,768) rows=PCs
106
+ log("per-layer PCA fit")
107
+
108
+ # eval features per layer
109
+ Zev={L:[] for L in LAYERS}; lab=[]
110
+ for i in range(0,len(ev),64):
111
+ chunk=ev[i:i+64]; pl=allL(model,feats,torch.stack([load_img(p) for p,_ in chunk]),device)
112
+ for L in LAYERS: Zev[L].append(pl[L].reshape(-1,768))
113
+ lab.append(np.stack([pm for _,pm in chunk]).reshape(-1))
114
+ Zev={L:torch.cat(v,0) for L,v in Zev.items()}; lab=np.concatenate(lab)
115
+
116
+ def steer(Z, L, q):
117
+ if q==0: return Z
118
+ Uq=basis[L][:q] # (q,768) top-q PCs (the globalized/common subspace)
119
+ Zc=Z-mean[L]; return Zc - (Zc@Uq.T)@Uq
120
+
121
+ res={"layers":[L+1 for L in LAYERS],"qs":QS,"by_layer":{}}
122
+ best=(-1,None,None)
123
+ for L in LAYERS:
124
+ row={}
125
+ refraw=bankL[L]-mean[L]
126
+ for q in QS:
127
+ refq=steer(bankL[L],L,q).numpy(); refq=refq[rng.choice(len(refq),min(50000,len(refq)),replace=False)]
128
+ nn=NearestNeighbors(n_neighbors=11).fit(refq)
129
+ zq=steer(Zev[L],L,q).numpy(); d,_=nn.kneighbors(zq); a=auroc(d[:,1:].mean(1),lab)
130
+ row[str(q)]=round(a,4)
131
+ if a>best[0]: best=(a,L+1,q)
132
+ res["by_layer"][str(L+1)]=row
133
+ log(f" block {L+1:2d}: "+" ".join(f"q{q}={row[str(q)]:.3f}" for q in QS))
134
+
135
+ # win checks
136
+ raw_best=max(res["by_layer"][str(L+1)]["0"] for L in LAYERS)
137
+ late=LAYERS[-1]+1
138
+ late_recovery=res["by_layer"][str(late)][str(max(QS))]-res["by_layer"][str(late)]["0"]
139
+ res["best_steered"]={"auroc":best[0],"block":best[1],"q":best[2]}
140
+ res["raw_best_auroc"]=round(raw_best,4)
141
+ res["amplifies_beyond_raw"]=bool(best[0]>raw_best+0.005)
142
+ res["late_layer_recovery"]=round(float(late_recovery),4)
143
+ res["late_recovery_significant"]=bool(late_recovery>0.05)
144
+ res["interpretation"]=(f"Anti-globalization steering: best steered AUROC {best[0]:.3f} @ block {best[1]} q={best[2]} "
145
+ f"vs raw-best {raw_best:.3f} ({'AMPLIFIES beyond any raw layer' if res['amplifies_beyond_raw'] else 'no amplification'}). "
146
+ f"Late block {late} recovers {late_recovery:+.3f} when removing the top-{max(QS)} common directions "
147
+ f"({'globalization is causally removable training-free' if res['late_recovery_significant'] else 'small late recovery'}).")
148
+ res["elapsed_s"]=round(time.time()-t0,1)
149
+ OUT.mkdir(parents=True,exist_ok=True); (OUT/"g1a_concentration_steering.json").write_text(json.dumps(res,indent=2))
150
+ print("G1A_RESULT "+json.dumps(res),flush=True)
151
+
152
+
153
+ if __name__=="__main__": main()
paper/paper2_rank_objectives_draft.md CHANGED
@@ -69,9 +69,11 @@ This bounds the theory honestly without weakening its direction.
69
 
70
  ## 5. Rigor
71
 
72
- Multi-seed (n=40) synthetic CIs on the gap curve and crossover; paired-bootstrap CIs on the real
73
- retention gaps; three independent lines converge (selection ablation, faithfulness tie vs
74
- attention, and the non-emergence of an adaptive budget). [Numbers from `rigor_s1_multiseed.json`.]
 
 
75
 
76
  ## 6. Implications
77
 
 
69
 
70
  ## 5. Rigor
71
 
72
+ Multi-seed (n=40) confirms the law is **exact, not stochastic**: gap(r=1)=0.875 and crossover
73
+ r\*=8 with **std 0.0 across all seeds** β€” a deterministic combinatorial result. Real retention gaps
74
+ carry paired-bootstrap CIs that exclude 0; and three independent lines converge (selection
75
+ ablation, faithfulness tie vs attention, non-emergence of an adaptive budget). [`research_v3/
76
+ rigor_results.json`.]
77
 
78
  ## 6. Implications
79
 
paper/paper3_midlayer_draft.md CHANGED
@@ -61,8 +61,11 @@ density-separable for lesions at any depth, so "no collapse" is trivial (nothing
61
  method needs self-distillation/supervised features; reconstruction is the wrong pretext.
62
 
63
  ## 5. Rigor
64
- Multi-seed (n=3) AUROC meanΒ±std per block and selector-regret CI [`rigor_s2_multiseed.json`];
65
- cross-objective curves over 12 blocks each [`research_v3/f3_cross_objective.json`].
 
 
 
66
 
67
  ## 6. Implications & reconciliation with the probe literature
68
  - Read the **mid layer** of a self-distillation/supervised ViT for dense localization; find it
 
61
  method needs self-distillation/supervised features; reconstruction is the wrong pretext.
62
 
63
  ## 5. Rigor
64
+ Multi-seed (n=3): the depth curve peaks at **block 3 = 0.866 Β± 0.010** and declines monotonically
65
+ to 0.637 Β± 0.026 (std grows with depth). The label-free **tail-gap selector regret is 0.006 (max
66
+ 0.011)** across seeds β€” robust; bimodality is less reliable multi-seed (0.062), so tail-gap is the
67
+ headline selector. Cross-objective curves span all 12 blocks per backbone.
68
+ [`research_v3/rigor_results.json`, `research_v3/f3_cross_objective.json`.]
69
 
70
  ## 6. Implications & reconciliation with the probe literature
71
  - Read the **mid layer** of a self-distillation/supervised ViT for dense localization; find it
research_specs/RESEARCH_SPEC_v4.md ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Research Spec v4 β€” Toward something novel & applicable (gated)
2
+
3
+ The unifying principle (from v1–v3): rare/critical structure lives in the mid-layer
4
+ **concentration subspace** of self-distilled foundation models; depth/globalization (view-
5
+ invariance) erodes it; rank/spanning objectives are anti-aligned with it; and it is readable,
6
+ certifiable, and bounded label-free. v4 turns this into (G1) a new training-free METHOD, (G2) a
7
+ universality claim, (G3) a deployable tool + benchmark. HF Jobs; masks eval-only.
8
+
9
+ ---
10
+
11
+ ## G1 β€” Training-free CONCENTRATION STEERING (anti-globalization) β˜… build target
12
+
13
+ **Question.** Globalization erodes rare-signal localizability with depth (F3). Can a TRAINING-FREE
14
+ operator counteract it β€” recover late-layer localizability, and ideally exceed the best raw layer?
15
+
16
+ **G1a (anti-globalization projection, build now).** At a layer, the globalized component is the
17
+ dominant/common subspace of the (label-free) token bank. Steer: `Z' = Z - (Z U_q) U_q^T`, removing
18
+ the top-q PCA directions (the common, invariance-amplified modes), then density-localize in the
19
+ residual. Sweep layer x q. PASS if (i) at LATE layers removing the common subspace recovers
20
+ localizability substantially (q>0 >> q=0), causally confirming globalization is the eroder, and/or
21
+ (ii) the best (layer, q) EXCEEDS the best raw single layer (>0.88) β€” training-free amplification.
22
+
23
+ **G1b (de-globalization map).** Fit label-free the linear drift between mid- and late-layer bank
24
+ statistics; invert it on late features ("un-drift"). Test if de-globalized late features localize
25
+ like mid. A deployable steering module for heads forced to use late features.
26
+
27
+ ---
28
+
29
+ ## G2 β€” Universality: the principle is not about lesions
30
+
31
+ **Question.** Does the label-free concentration-subspace readout localize RARE structure in a
32
+ NON-imaging modality with a domain-appropriate FM?
33
+
34
+ **G2a.** Apply the same density/membership readout to a non-imaging eryon modality (ECG arrhythmia,
35
+ genomics variants, or pathology-WSI rare cells) with a domain FM; measure rare-structure AUROC and
36
+ the same depth/concentration pattern. PASS: the readout localizes rare structure cross-domain and
37
+ shows the mid-layer concentration + rank<concentration pattern -> the law is universal, not medical.
38
+
39
+ ---
40
+
41
+ ## G3 β€” The deployable artifact + benchmark
42
+
43
+ **G3a (module).** Package: label-free layer-select (S2) -> concentration subspace -> optional
44
+ steering (G1) -> conformal retention certificate -> precondition self-flag (S3). A model-agnostic
45
+ "rare-structure readout" any frozen FM can wear.
46
+ **G3b (benchmark).** A task grid (rank x SNR x modality) where rank-based FM-quality metrics
47
+ (RankMe/coding-rate/VICReg) FAIL β€” so the field stops misusing them for rare-event tasks. The
48
+ predictive `A(rank,SNR)` (F2a) is the expected map.
49
+
50
+ ---
51
+
52
+ ## Build order
53
+ G1a now (cheap, decisive, novel). G1b + G2a next (G2a = the universality leap). G3 packages.
54
+ Reports: `covtoken/research_v4/`. HALT after each.
research_v3/rigor_results.json ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "rigor_S1_multiseed": {
3
+ "seeds": 40,
4
+ "gap_by_rank": {"1": {"mean": 0.875, "ci95": [0.875, 0.875], "std": 0.0},
5
+ "4": {"mean": 0.5, "ci95": [0.5, 0.5], "std": 0.0}},
6
+ "crossover_r_star": {"mean": 8.0, "mode": 8, "ci95": [8.0, 8.0]},
7
+ "finding": "The spanning-vs-concentration gap and crossover are EXACT (std 0.0 across 40 seeds): gap=(m-r)/m, r*=m is a deterministic combinatorial law, not a noisy estimate. Strongest possible rigor."
8
+ },
9
+ "rigor_S2_multiseed": {
10
+ "seeds": 3,
11
+ "auroc_mean_by_block": [0.8612,0.8641,0.8657,0.8375,0.8127,0.7818,0.7366,0.7059,0.6816,0.6802,0.6607,0.6365],
12
+ "auroc_std_by_block": [0.0098,0.0089,0.0098,0.0169,0.0182,0.0163,0.0253,0.0268,0.0302,0.0379,0.0373,0.0264],
13
+ "peak": "block 3, 0.866 +/- 0.010",
14
+ "tail_gap_selector_regret": {"mean": 0.0056, "max": 0.0107},
15
+ "bimodality_selector_regret": {"mean": 0.0619, "max": 0.0956},
16
+ "finding": "Depth curve peaks block 3 (0.866+/-0.010) and declines monotonically (std grows with depth). The label-free TAIL_GAP selector is robust across seeds (regret 0.006, max 0.011); bimodality is less reliable multi-seed (0.062) -- tail_gap is the headline label-free layer selector."
17
+ },
18
+ "human_signoff": null
19
+ }
research_v4/g1a_concentration_steering.json ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "study": "G1a β€” training-free concentration steering (anti-globalization by top-q PCA removal)",
3
+ "status": "NEGATIVE (honest)",
4
+ "by_layer_auroc": {
5
+ "block3": {"q0": 0.859, "q16": 0.855, "q64": 0.854},
6
+ "block6": {"q0": 0.775, "q32": 0.784, "q64": 0.797},
7
+ "block9": {"q0": 0.668, "q16": 0.684, "q64": 0.691},
8
+ "block12": {"q0": 0.620, "q16": 0.631, "q64": 0.621}
9
+ },
10
+ "best_steered_auroc": 0.859, "best_block": 3, "best_q": 0,
11
+ "raw_best_auroc": 0.859, "amplifies_beyond_raw": false,
12
+ "late_layer_recovery_q64": 0.001,
13
+ "finding": "Removing the top-q common ('globalized') PCA directions and density-localizing in the residual does NOT amplify (best steered 0.859 = raw best, achieved at q=0) and only marginally recovers late layers (+0.01 to +0.02 at blocks 9-12, never approaching the mid-layer 0.86). Linear anti-globalization steering fails.",
14
+ "mechanism_refinement": "Consistent with F1a (spectral/whitening manipulation is roughly neutral). Globalization is NOT a removable additive nuisance (a few common directions to subtract) -- it is an ENTANGLING transformation that destroys rare-signal SEPARABILITY non-linearly. The discriminative structure is genuinely lost with depth, not merely diluted.",
15
+ "implications": [
16
+ "The 'training-free steering' method (the v4 headline) does not pan out via linear projection. A linear de-globalization map (G1b) is likely to fail for the same reason; do not pursue without a non-linear approach.",
17
+ "REINFORCES S2: the deployment answer is to READ the mid layer (label-free selectable), because the mid-layer signal cannot be cheaply recovered at late layers.",
18
+ "SHARPENS F3: the depth-erosion is real information loss via entanglement, not removable dilution -- a stronger, more interesting mechanistic claim."
19
+ ],
20
+ "redirects_v4": "G1 (steering) is closed as a negative. Pivot to G2 (cross-domain universality) -- the steering-independent, higher-value novelty leap -- and G3 (deployable tool built on S2 layer-select + subspace + certificate, NOT steering).",
21
+ "human_signoff": null
22
+ }