Skip to content

Commit 4aebb95

Browse files
committed
add some mimics stuff
1 parent dcf8d22 commit 4aebb95

18 files changed

Lines changed: 3651 additions & 0 deletions

File tree

contrib/mimics/README.md

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# Cambridge Mimicry: SAE Feature Validation for Heliconius Butterflies
2+
3+
Tools for validating and exploring SAE features that discriminate Heliconius mimic pairs (erato subspecies vs melpomene subspecies), using the Cambridge Butterfly dataset.
4+
5+
## Problem
6+
7+
Current workflow: train sparse linear classifiers on SAE activations, extract selected feature indices, run `visuals.py` to render top-activating images, then manually interpret.
8+
9+
The interpretation step is where things break down. `visuals.py` shows a feature's top-activating images globally with no connection to the classification task. There are no class labels on images, no per-class breakdown, no discrimination stats. You end up switching between the feature visuals, notebook tables, and raw data, trying to hold context across windows.
10+
11+
The unit of analysis is wrong. It's currently "feature N activates on these images." It should be "feature N captures this morphological difference between these two taxa."
12+
13+
## Ideas
14+
15+
### Tier 1: Close the validation loop
16+
17+
#### 1. Per-class activation grids
18+
19+
For a (feature, task) pair, show images split by class:
20+
21+
```
22+
FEATURE 2391 (weight +0.034, favors melpomene)
23+
single-feature AUC: 0.91 | fires on 89% melpomene, 12% erato
24+
25+
erato (lativitta dorsal) melpomene (malleti dorsal)
26+
Top [img+overlay] [img] [img] [img+overlay] [img] [img]
27+
Bottom [img+overlay] [img] [img] [img+overlay] [img] [img]
28+
```
29+
30+
Each image gets the SAE activation heatmap overlay and the subspecies/view label. "Top" = highest activation within that class, "Bottom" = lowest. Answers:
31+
32+
- Does the feature fire consistently on one class?
33+
- Does it fire on the wrong class?
34+
- When it doesn't fire, what does the specimen look like?
35+
- Is it always the same wing region?
36+
37+
Highest priority item.
38+
39+
#### 2. Feature discrimination stats
40+
41+
For each (feature, task) pair, compute from existing SAE activations (`token_acts.npz` + class labels, no new inference):
42+
43+
- Activation rate per class: % of images where max patch activation > 0.
44+
- Mean activation per class: the gap between classes measures effect size.
45+
- Single-feature AUC: ROC AUC using just this feature. Individual discriminative power.
46+
- Activation distribution: per-class histograms.
47+
48+
Computable for all features at once. Useful as a triage filter before rendering images.
49+
50+
#### 3. Labels on every image
51+
52+
Stamp `lativitta dorsal` or `malleti ventral` on every rendered image. PIL text overlay.
53+
54+
### Tier 2: Deeper understanding
55+
56+
#### 4. Spatial activation heatmaps
57+
58+
Average SAE activation maps across all specimens of a class for a given feature. Averages out per-specimen noise, reveals consistent spatial signal. Butterflies in the Cambridge dataset are pose-normalized (pinned specimens), so spatial averaging should work. The difference map (melpomene avg minus erato avg) shows where on the wing the feature discriminates.
59+
60+
#### 5. Counter-example explorer
61+
62+
For a feature that should distinguish erato from melpomene, find the hard cases:
63+
64+
- Erato specimens where the feature fires strongly (false positives)
65+
- Melpomene specimens where the feature is silent (false negatives)
66+
67+
These reveal whether the feature is picking up on something subtler than expected, whether hybrids are confusing it, or whether a subspecies population is unusual.
68+
69+
#### 6. Feature interaction plots
70+
71+
For a classifier with N features, make 2D scatter plots of pairwise feature activations colored by class. Shows whether features contribute independent signal or are redundant.
72+
73+
#### 7. Morphological series
74+
75+
Sort all specimens by a feature's activation value and display as a filmstrip. The morphological trait should vary smoothly. Computational equivalent of a morphological series in taxonomy. Could be a GIF, a marimo slider, or a static strip of 20 images.
76+
77+
### Tier 3: Cross-run and meta-analysis
78+
79+
#### 8. Cross-run feature alignment
80+
81+
Different SAE runs have different latent indices. Feature 2391 in run A and feature 7739 in run B are unrelated by index, but if they activate on the same images, they capture the same trait.
82+
83+
Compute Jaccard similarity of top-K activated image sets across runs. Build a bipartite matching. If a trait appears in 8/10 runs, it's robust. If only 1 run, likely noise. Addresses the question of biological signal vs. SAE training artifacts.
84+
85+
#### 9. Mimicry precision quantification
86+
87+
For each feature, measure how closely the mimic matches the model:
88+
89+
```
90+
Feature 2391:
91+
erato (lativitta): mean activation 0.82 +/- 0.15
92+
melpomene (malleti): mean activation 0.31 +/- 0.12
93+
mimicry gap: 0.51
94+
95+
Feature 48:
96+
erato: mean 0.44 +/- 0.08
97+
melpomene: mean 0.41 +/- 0.09
98+
mimicry gap: 0.03
99+
```
100+
101+
Large gaps = mimicry breaks down (what the classifier picks up on). Small gaps = precise mimicry (strong selection pressure). Reframes classifier feature weights as a quantitative map of mimicry imprecision.
102+
103+
#### 10. Feature annotation dictionary
104+
105+
Record annotations as you validate: `{run: "r27w7pmf", feature: 2391, trait: "red forewing band extent", confidence: "high", notes: "consistent across dorsal views"}`. Simple JSON/CSV. Builds a reusable lookup from SAE latents to morphological traits.
106+
107+
#### 11. Batch HTML report
108+
109+
Standalone HTML per checkpoint. Each feature gets a card with the per-class grid (1), stats (2), and annotations (10). Inline images as base64, no server needed. For sharing with collaborators.
110+
111+
### Wild cards
112+
113+
#### 12. Hybrid specimen analysis
114+
115+
Run the classifier's selected features on hybrid specimens. See which parent species they resemble per trait. A hybrid might have erato-like forewing band (feature 2391 low) but melpomene-like hindwing spots (feature 48 high). Per-trait decomposition of hybrid phenotypes.
116+
117+
#### 13. Wing region vocabulary
118+
119+
Map features to named wing regions (forewing costa, hindwing discal cell, etc., standard lepidopteran venation nomenclature). Even a rough partition into 4-6 regions anchors ML features in morphological language.
120+
121+
## Priority
122+
123+
Build idea 1 first (per-class activation grids with labels). Compute idea 2 (discrimination stats) alongside it. Idea 3 (labels) is trivial.
124+
125+
Then idea 4 (spatial heatmaps) and idea 5 (counter-examples).
126+
127+
Ideas 8-9 (cross-run alignment, mimicry precision) are what turn this into a quantitative biology contribution rather than an interpretability exercise.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# 001-heliconius
2+
3+
Local render sweep for Heliconius mimic-pair tasks.
4+
5+
## Run
6+
7+
```bash
8+
uv run launch.py render --sweep exps/001-heliconius/render.py
9+
```
10+
11+
## Dry Run
12+
13+
```bash
14+
uv run python contrib/mimics/launch.py render --sweep contrib/mimics/exps/001-heliconius/render.py --dry-run
15+
```
16+
17+
## Consistency
18+
19+
```bash
20+
uv run python contrib/mimics/launch.py consistency --task-filter dorsal
21+
```
22+
23+
Or score only one run:
24+
25+
```bash
26+
uv run python contrib/mimics/launch.py consistency --run-ids 3rqci2h1
27+
```
28+
29+
## Viewer
30+
31+
```bash
32+
uv run marimo edit contrib/mimics/notebooks/viewer.py
33+
```
34+
35+
## Notes
36+
37+
- The sweep defines one config per task name (`pair x view`).
38+
- Use CLI args to override the sweep defaults (`--top-k-ckpts`, `--max-pooled-features`, etc.).

0 commit comments

Comments
 (0)