Skip to content

Foundations Isle: fastbook ch.13–20 (CNNs, ResNets, optimizers, from-scratch Learner)#6

Open
CodeWithOz wants to merge 3 commits into
mainfrom
claude/pensive-albattani-5f4330
Open

Foundations Isle: fastbook ch.13–20 (CNNs, ResNets, optimizers, from-scratch Learner)#6
CodeWithOz wants to merge 3 commits into
mainfrom
claude/pensive-albattani-5f4330

Conversation

@CodeWithOz

@CodeWithOz CodeWithOz commented Jul 6, 2026

Copy link
Copy Markdown
Owner

What this adds

A new landmass — the Foundations Isle, reached by ferry across a new sea south of the Frontier — extending DL World from fastbook ch.4–12 through ch.13–20. Same MNIST digits, seen deeper: everything trains live, in the same spirit as the existing city.

Chapter → in-world mapping (concept-first names; the chapter map lives only in the README):

  • ch.13 Convolutions — Kernel Workshop (hand-made kernels, stride/padding arithmetic, conv-as-matmul) + Convolution Works (the book's simple_cnn learning its own kernels, feature-map floor, receptive-field tracing, the "colorful dimension" stability plot with a batchnorm switch)
  • ch.14 ResNets + ch.18 CAM — Residual Works (identity-init blocks computing x + f(x) racing a skipless twin) + Saliency Lighthouse (CAM / Grad-CAM shining a light back through the live model)
  • ch.15 Architecture + ch.16 Optimizers — Architecture Atelier (cut a trained body, sew on a head → siamese "same digit?" matcher with freeze / per-group lr; upsampling desk) + Optimizer Institute (SGD vs momentum vs RMSProp vs Adam on identical nets, momentum desk, Adam microscope)
  • ch.17 Foundations + ch.19 Learner — Foundations Quarry (matmul three ways, broadcasting, init, backprop by hand vs autograd) + Learner Hall (the training loop rebuilt as named events + callbacks, with a breakable NaN guard)
  • ch.20 Conclusion — the Horizon Beacon, the tour's final stop, looking back over the city and out at open water

Engine

  • src/engine/conv.tsconv2d, adaptive average pooling, batchnorm with real backward passes (feature maps stored as [batch, C·H·W]), plus im2col / upsample / transposed-conv demo helpers
  • src/engine/optim.ts — Momentum / RMSProp / Adam / grouped-SGD to the book's formulas
  • All new ops finite-difference gradient-checked in tests/engine.test.ts

World

  • A ferry + sea (no bridge — the only crossing is the boat), a full island landmass (MAP_H → 106), sand/dock tiles, a sweeping lighthouse beacon, tour stops ㉒–㉚, and ~25 new inspection panels
  • Five new live trainers wired into World (convnet, resnet, optrace, siamese, learnerlab)

Reviewer notes

  • Adam is deliberately the book's simplified form (first-moment debias only, eps inside the sqrt), not the canonical paper — matching the vendored chapter is the project's governing rule (AGENTS.md). A code comment flags this so it isn't "corrected" later.
  • A numerical-stability quirk is turned into a teaching point: the stable softmax bounds cross-entropy at ~25 even at absurd learning rates, so the loss only goes NaN once the weights overflow float32 (lr ≈ 1e20). The Learner Hall's NaN-guard demo and its test rely on this — please don't "fix" it to a small lr.
  • Second commit addresses a full CodeRabbit review (BN double-update on the display pass, momentum read-from-live, learner reset counters, chapter-number leaks in blurbs, siamese label order, robust optimizer lookup, actStats guard).

Verification

  • npm test54 passing (engine gradient checks + island smoke/property tests, including regression assertions for the review fixes)
  • npm run build — clean (tsc + vite)
  • Verified in the browser preview: ferry crossing both ways, all island panels render, beacon interaction, BN stats advance once per step

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added convolution, residual, saliency, optimizer-race, transfer/learner training, and enhanced upsampling visualization panels.
    • Expanded the guided city tour with a new Foundations Isle route, ferry crossing, and Horizon Beacon endpoint.
    • Added new CNN-style training scenarios plus additional optimizers (Momentum, RMSProp, Adam, and grouped learning rates).
  • Bug Fixes
    • Improved convolution/pooling/batch normalization and gradient correctness with stronger input validation and better training/eval behavior.
    • Enhanced training-loop responsiveness with callback controls and reliable early-stop on non-finite losses.
  • Documentation
    • Updated project docs to reflect the expanded training/tour scope.

CodeWithOz and others added 2 commits July 6, 2026 10:20
…, from-scratch Learner)

Adds a new landmass south of the Frontier, reached by ferry, covering the
final eight chapters. Same digits, seen deeper: everything trains live.

Engine: conv2d / adaptive avg pool / batchnorm with real backward passes
(feature maps as [batch, C*H*W]); Momentum / RMSProp / Adam / grouped-SGD
to the book's formulas. All finite-difference gradient-checked.

Scenarios: the book's simple_cnn; a residual net racing a skipless twin
(identity-init blocks); a four-optimizer derby on one lr dial; a siamese
pair-matcher whose encoder is cut from the trained CNN; a from-scratch
MiniLearner with an event/callback loop and a NaN guard.

World: ferry + sea (no bridge), island landmass (MAP_H→106), sand/dock
tiles, a sweeping lighthouse beacon, tour stops 22–30, ~25 inspection
panels. README/AGENTS updated; 54 tests pass.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- BatchNorm running stats now advance once per step: the base trainStep's
  recorded display pass no longer folds into them (stats=null on record).
- Momentum Desk reads the moving average straight from the live optimizer
  after step() instead of re-deriving the update rule (every-number-real).
- MiniLearner.reset() also restarts loop counters (stepsDone, epochsDone,
  eventCounts, lastTrace) so the Callback Rack's reset button truly resets.
- Removed 4 chapter-number leaks from in-world panel copy (residual,
  saliency, atelier, learnerhall).
- Fixed the siamese logits label order (index 0 = different, 1 = same).
- Momentum Desk looks the racer up by type, not a fixed index.
- Guarded the Stability Observatory against an empty actStats.
- Documented that Adam deliberately follows the book's simplified form
  (first-moment debias only, eps inside the sqrt), not the canonical paper.

Added regression assertions for the reset and momentum-read fixes.
All 54 tests pass; build clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 6, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
dl-world bbd1f45 Commit Preview URL

Branch Preview URL
Jul 06 2026, 01:21 PM

@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8454e8b9-d2a6-41f9-abd4-3d7f5a4acf41

📥 Commits

Reviewing files that changed from the base of the PR and between 8a320bd and bbd1f45.

📒 Files selected for processing (6)
  • src/sim/learner.ts
  • src/ui/panels/atelier.ts
  • src/ui/panels/common.ts
  • src/ui/panels/saliency.ts
  • tests/engine.test.ts
  • tests/island.test.ts
✅ Files skipped from review due to trivial changes (1)
  • src/ui/panels/common.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • tests/engine.test.ts
  • src/ui/panels/saliency.ts
  • tests/island.test.ts
  • src/sim/learner.ts

Walkthrough

This PR adds convolution and optimizer primitives to the tensor engine, introduces new training scenarios and learner callbacks, expands the world with a ferry-connected island and new buildings, adds educational UI panels, and updates documentation and tests.

Changes

Foundations Isle Feature

Layer / File(s) Summary
Documentation updates
AGENTS.md, README.md, src/main.ts
Rewrites the project’s chapter, tour, ferry, and curriculum descriptions to match the expanded island route and engine/scenario scope.
Convolution and optimizer primitives
src/engine/conv.ts, src/engine/optim.ts, src/engine/tensor.ts, tests/engine.test.ts
Adds conv/pool/batchnorm ops, demo convolution helpers, new optimizer classes, concatCols, and tests covering forward behavior, gradients, and optimizer updates.
Training scenarios and learner callbacks
src/sim/scenarios3.ts, src/sim/learner.ts, src/sim/scenarios.ts, src/sim/trainer.ts, src/sim/world.ts, tests/island.test.ts
Introduces ConvNet, ResRace, OptRace, SiamesePairs, MiniLearner, LearnerLab, expands scenario typing, wires new trainers into World, and adds scenario integration tests.
Island map, buildings, and ferry travel
src/world/city.ts, src/world/buildings.ts, src/world/game.ts
Expands the map with sea/island terrain, Horizon Beacon rendering, ferry interaction and boat travel, and new buildings/trainer identifiers.
Educational UI panels
src/ui/panels/*.ts, src/ui/panels/index.ts, src/ui/widgets.ts
Adds the new visualization panels, registers them, and extends line charts to render extra series.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Player
  participant Game
  participant City
  Player->>Game: interact near ferry pier
  Game->>City: ferryAt(tx, ty)
  City-->>Game: island / mainland / null
  Game->>Game: startFerry(dest), mode="boat"
  Game->>Game: render() draws ferry hull during crossing
Loading
sequenceDiagram
  participant LearnerLab
  participant MiniLearner
  participant LabCallback
  participant SGD
  LearnerLab->>MiniLearner: oneBatch()
  MiniLearner->>LabCallback: fire before_batch
  MiniLearner->>MiniLearner: buildLoss() / forward
  MiniLearner->>SGD: backward + step()
  LabCallback-->>MiniLearner: CancelFitException on NaN loss
  MiniLearner->>LabCallback: fire after_batch / after_cancel_fit
Loading

Possibly related PRs

  • CodeWithOz/dl-world#1: Establishes the initial tensor engine and scenario foundation that this PR extends with new ops, optimizers, and scenarios.
  • CodeWithOz/dl-world#2: Touches the same tour/world path that this PR extends with the ferry and Horizon Beacon route.
  • CodeWithOz/dl-world#5: Modifies the same Trainer class that this PR updates with an optional constructor speed parameter.

Poem

A rabbit hopped to the island shore,
With kernels, ferries, and much more.
The beacon glows, the charts all dance,
Optimizers zip in training trance.
One hop, two hops — the world grew bright,
And code-moss sparkled in the night. 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly reflects the main change: adding Foundations Isle content for CNNs, ResNets, optimizers, and the from-scratch learner.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/pensive-albattani-5f4330

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (4)
tests/engine.test.ts (1)

243-254: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a gradient check for batchNorm eval-mode backward.

batchNorm has two distinct backward branches (training stats vs. the eval-mode affine map at conv.ts Lines 274-283). Only the training branch is gradient-checked (Line 236); the eval branch is exercised for forward output only here, leaving its backward unverified.

💚 Suggested eval-mode gradCheck
   it("batchNorm eval mode uses running stats", () => {
     const stats = makeBnStats(1, 1); // momentum 1: running stats = last batch stats
     const gamma = Tensor.fromArray([2]);
     const beta = Tensor.fromArray([1]);
     const xTrain = Tensor.fromArray([0, 2, 4, 6], [4, 1]);
     batchNorm(xTrain, gamma, beta, 1, stats, true);
     expect(stats.runMean[0]).toBeCloseTo(3, 5);
     const xEval = Tensor.fromArray([3], [1, 1]);
     const yEval = batchNorm(xEval, gamma, beta, 1, stats, false);
     // (3-3)/std*2 + 1 = 1
     expect(yEval.data[0]).toBeCloseTo(1, 4);
+    // eval-mode backward is an affine map through frozen stats — verify it
+    const xg = Tensor.randn([3, 2 * 2], 1, rand);
+    const gg = Tensor.randn([2], 0.5, rand);
+    const bg = Tensor.randn([2], 0.5, rand);
+    const evalStats = makeBnStats(2, 1);
+    evalStats.runMean.set([0.2, -0.1]);
+    evalStats.runVar.set([1.3, 0.8]);
+    gradCheck((inp) => mean(mul(batchNorm(inp[0], inp[1], inp[2], 2, evalStats, false), inp[0])), [xg, gg, bg]);
   });

As per path instructions: "Any new engine operation must have a finite-difference gradient check using the existing gradCheck helper, and backward functions must match the clamped/actual forward behavior."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/engine.test.ts` around lines 243 - 254, Add a finite-difference
gradient check for the eval-mode backward path of batchNorm in the engine tests.
Extend the existing batchNorm coverage in tests/engine.test.ts to call the same
`gradCheck` helper on the eval branch (the `batchNorm` path that uses running
stats and the affine map), and verify its gradients against the forward
behavior. Keep the current training-mode check, but add a separate eval-mode
case so both branches of `batchNorm` are validated.

Source: Path instructions

src/ui/panels/atelier.ts (1)

225-235: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

digit14 is a byte-for-byte duplicate of the same helper in src/ui/panels/saliency.ts (lines 16-26).

Both compute a 2×2-average-pooled 14×14 downsample of a 28×28 test image with identical logic. Worth extracting to a shared helper (e.g. common.ts) so the two copies can't drift.

♻️ Proposed extraction
+// src/ui/panels/common.ts
+export function digit14(world: World, i: number): Float32Array {
+  const out = new Float32Array(196);
+  const imgs = world.data.testImages;
+  const off = i * 784;
+  for (let r = 0; r < 14; r++)
+    for (let c = 0; c < 14; c++) {
+      const o = off + r * 2 * 28 + c * 2;
+      out[r * 14 + c] = (imgs[o] + imgs[o + 1] + imgs[o + 28] + imgs[o + 29]) / 4 / 255;
+    }
+  return out;
+}

Then import it in both atelier.ts and saliency.ts instead of the local copies.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/ui/panels/atelier.ts` around lines 225 - 235, The digit14 helper is
duplicated in both atelier.ts and saliency.ts, so extract the shared 14x14
downsampling logic into a common helper (for example in common.ts) and update
both digit14 call sites to import and use that shared function. Keep the
existing behavior and signature consistent by preserving the
World/testImages-based pooling logic in the shared helper and removing the local
copies.
src/sim/learner.ts (1)

221-228: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

CancelFit attribution is hard-coded to TerminateOnNaN.

If a future callback throws CancelFitException, the catch block always searches for an enabled TerminateOnNaN and reports that as the canceller (by), which would be wrong. Today only TerminateOnNaN throws so this is latent, but attributing by the actual raising callback would be more robust.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/sim/learner.ts` around lines 221 - 228, The CancelFitException handling
in learner.ts is attributing cancellation to a hard-coded TerminateOnNaN
callback, which is too narrow. Update the catch block in the fit flow to
identify the actual callback that raised the exception instead of always
searching for TerminateOnNaN, and use that callback’s name when setting
this.cancelled.by. If needed, thread the throwing callback identity through
CancelFitException or the callback invocation path so the attribution in the
cancel handling remains correct for any future callback.
tests/island.test.ts (1)

71-81: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Loss-reduction assertion may be flaky.

late/8 < early/8 after only 8+24+8 heavy conv steps on a tiny batch (12) can occasionally fail on adverse batch draws even when training is healthy. Averaging windows help but don't eliminate it. Consider a small tolerance (e.g. late/8 < early/8 * 1.0< early/8 - eps is stricter; instead assert late/8 <= early/8), or seed-fix the loader for determinism. Low priority given the fixed data seed already in the scenario.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/island.test.ts` around lines 71 - 81, The training-loss test in ConvNet
is too brittle because the `expect(late / 8).toBeLessThan(early / 8)` assertion
can fail on normal batch variance even when `trainStep()` is working. Update the
`reduces its training loss over a short run` test in `tests/island.test.ts` to
use a non-flaky check, either by adding a small tolerance around the comparison
or by relaxing it to an inclusive/seeded deterministic assertion tied to
`ConvNet` and its `trainStep()` loop.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/sim/learner.ts`:
- Around line 221-228: The CancelFitException handling in learner.ts is
attributing cancellation to a hard-coded TerminateOnNaN callback, which is too
narrow. Update the catch block in the fit flow to identify the actual callback
that raised the exception instead of always searching for TerminateOnNaN, and
use that callback’s name when setting this.cancelled.by. If needed, thread the
throwing callback identity through CancelFitException or the callback invocation
path so the attribution in the cancel handling remains correct for any future
callback.

In `@src/ui/panels/atelier.ts`:
- Around line 225-235: The digit14 helper is duplicated in both atelier.ts and
saliency.ts, so extract the shared 14x14 downsampling logic into a common helper
(for example in common.ts) and update both digit14 call sites to import and use
that shared function. Keep the existing behavior and signature consistent by
preserving the World/testImages-based pooling logic in the shared helper and
removing the local copies.

In `@tests/engine.test.ts`:
- Around line 243-254: Add a finite-difference gradient check for the eval-mode
backward path of batchNorm in the engine tests. Extend the existing batchNorm
coverage in tests/engine.test.ts to call the same `gradCheck` helper on the eval
branch (the `batchNorm` path that uses running stats and the affine map), and
verify its gradients against the forward behavior. Keep the current
training-mode check, but add a separate eval-mode case so both branches of
`batchNorm` are validated.

In `@tests/island.test.ts`:
- Around line 71-81: The training-loss test in ConvNet is too brittle because
the `expect(late / 8).toBeLessThan(early / 8)` assertion can fail on normal
batch variance even when `trainStep()` is working. Update the `reduces its
training loss over a short run` test in `tests/island.test.ts` to use a
non-flaky check, either by adding a small tolerance around the comparison or by
relaxing it to an inclusive/seeded deterministic assertion tied to `ConvNet` and
its `trainStep()` loop.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5ec6a192-07c2-48c1-82cf-cf4b21aead10

📥 Commits

Reviewing files that changed from the base of the PR and between 9f06447 and 8a320bd.

📒 Files selected for processing (27)
  • AGENTS.md
  • README.md
  • src/engine/conv.ts
  • src/engine/optim.ts
  • src/engine/tensor.ts
  • src/main.ts
  • src/sim/learner.ts
  • src/sim/scenarios.ts
  • src/sim/scenarios3.ts
  • src/sim/trainer.ts
  • src/sim/world.ts
  • src/ui/panels/atelier.ts
  • src/ui/panels/beacon.ts
  • src/ui/panels/convworks.ts
  • src/ui/panels/index.ts
  • src/ui/panels/institute.ts
  • src/ui/panels/kernels.ts
  • src/ui/panels/learnerhall.ts
  • src/ui/panels/quarry.ts
  • src/ui/panels/residual.ts
  • src/ui/panels/saliency.ts
  • src/ui/widgets.ts
  • src/world/buildings.ts
  • src/world/city.ts
  • src/world/game.ts
  • tests/engine.test.ts
  • tests/island.test.ts

…, test coverage)

- CancelFitException now carries the name of the callback that raised it,
  stamped in MiniLearner.call(), so the "halted by" attribution is correct
  for any callback instead of a hardcoded TerminateOnNaN lookup.
- Extracted the duplicated 14×14 downsample helper (digit14) into
  panels/common.ts; the Saliency Lighthouse and Architecture Atelier now
  share it.
- Added a finite-difference gradient check for batchNorm's eval-mode
  backward path (running stats + affine map), which the training-mode
  check didn't cover.

55 tests pass; build clean; panels + NaN-guard attribution verified in preview.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant