Forward Forecasting logo FORWARDFORECASTING

Field Notes · Neural Networks 1001

Neural Networks 1001: A Course Honest Enough to Say When a Technique Didn't Help

Nine runnable notebooks, from a single neuron to a GPT, all small enough to train on a laptop CPU. Building them meant running every textbook claim as an experiment, and four of them came back different from the story I expected to tell.

Fernando Borbón Deep learning study notes, rebuilt from the original papers Live at neural-networks.academy.forwardforecasting.eu
An 8 by 8 pixel handwritten digit in gold on a dark background, feeding into a layered network of gold nodes and connections

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

Foundations
01 the neuron, 02 backpropagation, 03 training deep networks well
Classic architectures
04 CNNs, 05 RNNs and forecasting, 06 word embeddings and translation
Modern deep learning
07 transformer, 08 a GPT from scratch, 09 segmentation, detection, metric learning
~40 min
to execute all nine end to end on an 8-core laptop

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 class10.3% → 5.8% error
Default LSTM vs plain RNN, dependence 50 steps back8.2e-12 vs 7.6e-12
LSTM with forget-gate bias 3, same measure2.0e-2
Beam search on an undertrained translator: fixed vs broken25 vs 41
Triplet embedding, one-shot: seen digits vs unseen digits99.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.

NumPyEvery core idea first written by hand: neurons, backprop, attention, dropout, batch norm.
PyTorch (CPU)The framework versions, once the hand-written ones have been checked against them.
scikit-learnBundled datasets and a few metrics, so nothing is ever downloaded.
nbconvertRenders saved notebook outputs into the course pages; nothing is re-executed at deploy time.
GitHub ActionsBuilds and publishes the static site on every push to main.
MathJaxThe equations on the course pages.

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 →