Interactive lecture notes for CSC413 / CSC2516 Deep Learning at the University of Toronto. Built with Quarto and Observable JS.
Install Quarto (v1.4 or later):
# macOS (Homebrew)
brew install quarto
# Verify
quarto --versionNo Python or R installation is required — all interactive visualisations run directly in the browser via Observable JS.
cd website
quarto previewThis starts a local dev server (default http://localhost:4848) and
live-reloads whenever you save a .qmd or .css file.
cd website
quarto renderOutput is written to website/_site/. Those files are plain HTML/CSS/JS and
can be served from any static host — no server needed.
cd website
quarto publish gh-pagesQuarto pushes the rendered _site/ to the gh-pages branch automatically.
Enable GitHub Pages in the repo settings (source: gh-pages branch, root /).
- Create
website/lectures/NN-topic.qmd(copy the header from an existing file). - Add one line to
website/_quarto.ymlunderchapters::chapters: - index.qmd - lectures/02-mlp-backprop.qmd - lectures/03-regularization.qmd # ← new line
- Save — the preview server picks up the change immediately.
Each lecture is written from its transcript and slides in
lecture_notes/Lecture <N>/, following three reference guides:
website/persona.md (voice and structure), website/notation.qmd (symbols),
and website/style.md (figures). Three helper scripts at the repo root turn
this into a repeatable, three-stage pipeline: draft → refine text → fix
figures. Each script generates a prompt — you run that prompt in Claude Code,
which reads the sources plus the guides and does the writing or editing. The
scripts themselves only detect files and fill the prompt; they do not call a
model.
Prerequisites for this pipeline (not needed to build or view the site): Python 3 (standard library only — no packages to install) for the scripts, and Google Chrome for the figure-render check in the visual pass.
Expected source layout (filenames are auto-detected, case- and space-insensitive):
lecture_notes/Lecture 11/
lecture11_transcript.txt # the spoken transcript
Lecture11.pdf # the slides / notes PDF
[anything *bonus* / *supplement* .pdf is picked up too]
python gen_lecture_prompt.py 11 --title "Architecture Grab Bag, Part 2 — Transposed Convolution, the U-Net, Autoencoders, and VAEs" --writeWrites lecture_notes/Lecture 11/generation-prompt.filled.md. Hand that prompt
to Claude Code; it reads the transcript, slides, and the three guides, then
drafts website/lectures/11-<slug>.qmd — prose in the lecture's measured voice,
with inline SVG figures. Afterward, wire the file into _quarto.yml (see
Adding a New Lecture) and run quarto render to confirm
it compiles.
python gen_fidelity_prompt.py 11 --writeWrites lecture_notes/Lecture 11/fidelity-prompt.filled.md. Running that prompt
compares the drafted .qmd against the transcript and slides, records every
discrepancy — MISSING, MISALIGNED / INCORRECT, UNSOURCED ADDITIONS,
ORDERING, NOTATION / VOICE — in lecture_notes/Lecture 11/fidelity-report.txt,
and then edits the .qmd to add the missing substance and correct the
misaligned statements (targeted edits only, preserving voice and structure).
python gen_visual_prompt.py 11 --writeWrites lecture_notes/Lecture 11/visual-prompt.filled.md. Running that prompt
renders each inline SVG (headless Chrome screenshot), looks at it next to the
hand-drawn slide, and flags wrong numbers/labels and layout problems (overlaps,
clipping, off-canvas text, misalignment, palette misuse). Findings go to
lecture_notes/Lecture 11/visual-report.txt, and the SVG coordinates, labels,
and values in the .qmd are corrected and re-rendered until each figure matches
its source.
Options (all three scripts):
- Omit
--writeto print the prompt to stdout instead of saving it. --report <name>overrides the report filename (passes 2 and 3).gen_lecture_prompt.pyneeds--title "..."unless the lecture is in its built-in registry;--slugis derived from the title if omitted.- After each stage,
cd website && quarto render lectures/11-<slug>.qmdto confirm the page still compiles (SVGs intact, no broken math or citations).
Observable JS chunks are fenced with ```{ojs}. They have access to:
| Global | Description |
|---|---|
Plot |
Observable Plot for charts |
d3 |
D3.js v7 for custom SVG |
Inputs |
Sliders, checkboxes, toggles |
html, svg, md |
Tagged template literals |
Example — a live slider controlling a plot:
```{ojs}
viewof n = Inputs.range([1, 20], {step: 1, label: "n", value: 5})
Plot.plot({ marks: [Plot.line(Array.from({length: n}, (_, i) => ({x: i, y: i**2}))), {x:"x", y:"y"}] })
```The site follows the aesthetic of visionbook.mit.edu with UofT branding:
- Body font: Source Serif 4 (serif, academic)
- Code font: Source Code Pro
- Theme: Quarto
cosmo(light) /darkly(dark) - Accent colour: UofT navy
#002A5C— headings, links, table headers, callout borders - No gradients, no colour fills — borders and whitespace carry the hierarchy
- Callout boxes: left border only, near-white background
- Boxed equations: thin navy border, no fill
Custom CSS lives in website/styles/custom.css.