step 0loss 0.693fit 50.0%learning
A network is learning my initials in your browser. Tap the field to add a point the letters, or . How it works
Alan Zeng
CS student and developer. I study what neural networks learn, and build the tools to see it.
I train small models to understand big ones, and I ship the tools I wish I’d had.
Now
- Writing up a probing studyPreprint this winter.
- Reading everything on sparse autoencodersNotes go up as I go.
- Looking for a research internshipSummer 2027, interpretability or ML systems.
- Teaching assistant, Introduction to Machine LearningSpring 2026.
Things I’ve built
- StratumLayer-by-layer probing for PyTorch models.
pip install stratum from stratum import probe report = probe(model, layers="all", labels=y) report.plot() # accuracy per layer - TidewaterReplays an agent’s tool calls one step at a time.
npx tidewater ./runs/0412.jsonl # step 7/23 tool: search # step 8/23 tool: read_file # ←/→ to step, enter to inspect - FootnoteChecks whether a model’s citations say what it claims they say.
from footnote import check check(answer, sources) # 4 claims, 3 supported, 1 not found - LanternAttention maps you can scrub through in the browser.
import { lantern } from "lantern" lantern(el, { trace, layer: 6, head: 3 }) - SteamerA job queue that shares a few GPUs among many students.
steamer submit train.py --gpus 1 --hours 4 steamer queue # 3 running, 5 waiting, yours starts in ~40m - HalfstepAn autodiff engine in 480 lines, written to teach backprop.
from halfstep import Value x = Value(2.0); y = x * x + 3 y.backward() x.grad # 4.0 - KilnA small harness for running evals the same way twice.
kiln run evals/arith.yaml --seed 7 # 200 items, 183 correct, saved to runs/arith-7
How the AZ up top works
It isn’t a video. A small neural network is training in your browser right now. This is its code, step by step.
// points from the letters
const ctx = hidden.getContext("2d");
ctx.font = `700 ${size}px Geist`;
ctx.fillText("AZ", x, y);
const inside = (u, v) => alphaAt(ctx, u, v) > 128;
while (points.length < 1460) {
const [u, v] = [Math.random(), Math.random()];
points.push({ u, v, label: inside(u, v) ? 1 : 0 });
}
// random Fourier features
const B = gaussian(2 * 24, 1.45);
function lift(x, y, out) {
for (let k = 0; k < 24; k++) {
const a = 2 * Math.PI * (B[2 * k] * x + B[2 * k + 1] * y);
out[k] = Math.sin(a); out[24 + k] = Math.cos(a);
}
}
// one hidden layer
function forward(f, h) {
for (let j = 0; j < 48; j++) {
let s = b1[j];
for (let i = 0; i < 48; i++) s += f[i] * W1[i * 48 + j];
h[j] = Math.tanh(s);
}
return sigmoid(dot(h, W2) + b2);
}
// learn from mistakes
function step(batch) {
grads.fill(0);
for (const { f, label } of batch) {
const p = forward(f, h);
const dz = p - label; // cross-entropy + sigmoid
backprop(dz, f, h, grads);
}
adam(params, grads, { lr: 0.01 });
}
setInterval(() => { for (let i = 0; i < 8; i++) step(sample(128)); });
// draw its answer
for (const cell of grid) cell.p = forward(cell.f, h);
const edge = marchingSquares(grid, 0.5);
ctx.strokeStyle = accent;
ctx.stroke(edge); // the model's A and Z
Sample the letters
Draw A and Z on a hidden canvas, then sample about 460 points inside the shapes and a thousand outside.
Lift every point
Random Fourier features turn each (x, y) into 48 waves. That is what lets a tiny network draw sharp corners.
One hidden layer
48 tanh units and a sigmoid on top. About 2,400 weights, small enough to train while you watch.
Learn from mistakes
Adam on batches of 128, in a Web Worker, so the page never waits for the model.
Draw its answer
Every few steps the model is asked about every cell of a grid. The line where it is exactly unsure, p = 0.5, is the shape you see.
Research
When Features Settle: Tracking Representation Drift Across Training
2026Layer by Layer: Where Linear Probes Stop Working
2025Sparse Lenses for Small Transformers
2024
In progress
- Counting Heads: how many attention heads does a fact need?2026Experiments running, write-up this winter.
- Steamer: tiered scheduling for shared student GPUs2026Systems note, draft.
Talks
- Reading a model one layer at a time2026Lab reading group.
- Probing without fooling yourself2025Department machine learning seminar.
- Building research tools people install2025Campus developer meetup.
Teaching
- Teaching assistant, Introduction to Machine Learning2026
- Teaching assistant, Data Structures2025
- PyTorch from zero, a workshop for first-year students2024
Education
- B.S. in Computer Science, minor in Mathematics2027Deep learning, optimization, probability, compilers.
Awards
- Undergraduate research grant2025
- Campus hackathon, first place2024
Writing
Write to me about research, internships, or a tool you need.
alanzeng423@Or press ⌘K anywhere on this page.