Years ago I worked through an online deep learning specialisation and kept everything: the notes, the quizzes, the assignments. Rereading them recently, I wanted something different from them: a course I could hand to someone else, that runs anywhere, and that does not ask anyone to trust a diagram. So I rebuilt the subject from scratch, from the original papers rather than from that material, as nine Jupyter notebooks with one hard rule: every model must train on an ordinary laptop CPU in minutes, with no GPU, no API key and no dataset download.
Nine modules, three parts
The CPU rule shapes everything. Datasets are either bundled with scikit-learn (8×8 handwritten digits, two moons) or generated in the notebook: an hourly demand signal with daily and weekly cycles, an English to Spanish grammar with conjugation and gender agreement, a word corpus with gender, royalty and geography built in, and scenes of circles, squares and triangles with exact masks and boxes. Synthetic data sounds like a compromise, but it has a big advantage for teaching: the ground truth is exact, so every metric means exactly what it says.
Four results that came out differently
Every claim in the course is an experiment that runs in front of the reader. That turned out to matter, because several of them did not produce the textbook picture on the first try. I kept the real results and explained them, instead of tuning until the expected story appeared.
| Transfer learning, 5 labelled examples per class | 10.3% → 5.8% error |
| Default LSTM vs plain RNN, dependence 50 steps back | 8.2e-12 vs 7.6e-12 |
| LSTM with forget-gate bias 3, same measure | 2.0e-2 |
| Beam search on an undertrained translator: fixed vs broken | 25 vs 41 |
| Triplet embedding, one-shot: seen digits vs unseen digits | 99.2% vs 68.2% |
Transfer learning only helped once the source network was trained with augmentation. Reusing a network trained plainly on digits 0 to 4 to learn 5 to 9 barely helped: a little with one or two examples per class, and with 25 examples it did worse than training from scratch, because its features were specialised to perfectly centred digits. Trained with random shifts, the same network roughly halved the error, even though it scored lower on its own task. General features transfer; specialised ones do not.
An LSTM at default settings forgets as fast as a plain RNN. Measuring how much the final state depends on each earlier input showed identical decay for both, because a forget gate that starts at 0.5 halves the memory every step. Opening the gate with a positive bias, a trick from 2000, changes the curve completely. Gates make long memory possible, not automatic.
Beam search broke more translations than it fixed. On a translator checkpoint taken early in training, beam search repaired 25 sentences and broke 41. A better search finds what the model scores highly, and when the model's probabilities are wrong, it finds the wrong answer more reliably.
A face-recognition-style embedding did not generalise to new identities. A triplet-loss network trained on seven digits recognises new images of those digits from a single example 99% of the time, but on three digits it has never seen it lands near the raw-pixel baseline. Seven identities are not enough to learn what "same" means; that is why real systems train on millions.
How the notebooks and the site are built
Each notebook is generated by a small Python builder script, which keeps the text and code reviewable in plain diffs, then executed and saved with its outputs so that it can be read without running anything. A second script renders the executed notebooks into the course website with nbconvert, adding a syllabus, per-module navigation, equations, progress tracking in the browser, and download and Colab links. A GitHub Actions workflow builds the site on every push and publishes it.
What it costs to run
Nothing extra. The notebooks run on the reader's own machine, and the course is a set of static files served from infrastructure that already hosts everything else on this domain, with a free certificate and one extra DNS record. No model API is called anywhere, and the cover image above was drawn with Matplotlib from an actual 8×8 digit.
Try it
Start at module 01 and read straight through in the browser, or download any notebook and change it: every exercise at the end of a module is a small experiment, and several of them ask you to break the result the module just showed.
Take the course
Nine modules, about twelve hours of study, every model trained on a laptop CPU.
Open the course → View on GitHub →