Chris Collins

Tools · math

The maths of machine learning

The mathematics under machine learning, hands on — least squares with draggable points (residual squares, outliers, L1 vs L2, normal equations vs gradient descent and SGD), logistic regression and its cross-entropy bowl, a computation graph with forward and backward passes against dual numbers and finite differences, TF-IDF and BM25 search, entropy with a Huffman tree builder and KL divergence, and softmax temperature with an attention matrix.

Added · updated 14 October 2026

How to use it

Six tabs, each one idea from the book you can push around. Every setting can be put in a link, and every book example has a preset — see Linking to an example.

⛶ Full screen (or F) gives the open tab’s main picture — the draggable least-squares plot, the sigmoid, the computation graph, the Huffman tree or the temperature chart — the whole screen, the browser’s full screen where it is allowed, otherwise a full-window layer (iPhone); it is redrawn as the window changes, and the controls stay below it. Escape leaves.

Least squares

Drag the points (or focus one and use the arrow keys). The line, the red residuals and their squares — whose total area is the SSE — update as you drag. Squared error fits by the normal equations, shown with the four sums Σx, Σy, Σx², Σxy and the solve; absolute error fits by iteratively reweighted least squares, with the squared-error line dashed for comparison. Make an outlier (or drag one point far away) shows squared error chasing it while absolute error barely moves. The points slider goes from 2 to 20; the first five are the book’s study-hours data.

Underneath, gradient descent walks downhill on the MSE from θ = 0 over a contour picture of the loss in (b, w), with the excess loss per step on a log scale and the book’s table of steps 0, 10, 100, 1000 and 2000 next to the normal-equations answer. Raise η until it diverges. SGD runs mini-batch stochastic gradient descent on 1000 noisy points from y = 3x + 2 (batch size, epochs and η are sliders) and shows how it jitters around the exact answer.

Logistic regression

The book’s ten students (hours studied, passed or not) and the curve σ(wx + b), with sliders for w and b, the live cross-entropy and its gradient, the decision boundary −b/w, and the predicted pass probabilities. The second panel is the cross-entropy over (w, b) as a contour picture with a dot for the current setting; click to move it. Train runs gradient descent from the dot and draws its path down the convex bowl. Edit the data as hours,passed pairs.

Backpropagation and dual numbers

Build a computation graph either from an expression (sin(x*x), exp(2*x)/(1+x*x) — parsed by the site’s algebra parser) or step by step, one node per line: z = mul(w, x). The palette buttons append a node (+, ×, −, ÷, x², sin, exp, tanh, σ, ReLU, ln) fed by the current output. Names that are never defined are inputs; give them values below.

Forward ▶ animates the values flowing through the graph; ◀ Backward starts from 1 at the output and multiplies by the local derivative written on each edge, adding the contributions at nodes that feed several others — the result at each node is ∂output/∂node. Nodes can be dragged. The panels compare the reverse-mode gradient with forward-mode dual numbers (the table lists every node’s a + bε) and with a central finite difference.

Finding the sweet spot plots the error of forward and central differences against the step h on log–log axes for the graph’s output, with the theoretical best h (√ε and ∛ε) marked. Switch to 32-bit floats — every operation rounded to single precision — and the sweet spot moves to much larger h. Use f=sin(x), exp(x), x^3 or sqrt(x) near 0, as in the book’s lab.

TF-IDF and BM25

Type documents (one per line) and a query. The tool shows the vocabulary with document frequencies and idf = ln(N/df), the TF-IDF vectors as a table, and every document’s dot product, cosine and BM25 score, ranked by the one you choose. Raw counts turns off the idf weighting (the length-bias example). Stemming is a light suffix stripper (plurals, -ing, -ed), enough for “cats” to match “cat”. For BM25, move k₁ (term saturation) and b (length normalisation); the idf is the book’s ln(N/df) by default, or Lucene’s smoothed version.

Entropy and Huffman codes

Enter symbol probabilities (A:1/2,B:1/4,…) or paste text and count its letters. The tool gives the entropy, the Huffman code with each codeword’s length beside its surprise −log₂p, the average length against H, and a slider that builds the Huffman tree one merge at a time. Enter a wrong distribution q to build the code for q and pay for it with p: the cross-entropy H(p, q), D_KL in both directions, and the extra bits per symbol — exactly D_KL(p‖q) when the probabilities are powers of ½.

Softmax and attention

Scores (logits) and a temperature T: the softmax as bars, its entropy, how the probabilities move as T goes from 0.05 to 20, and what the naive formula does with scores like 1000 (it overflows; subtracting the maximum does not). Below, a tiny attention layer: tokens and the matrices Q, K and V, with the score matrix QKᵀ/√d_k, the row-wise softmax as a heat map, and the output rows as weighted averages of V. Untick √d_k to see the softmax saturate. Tick causal mask to see a decoder’s attention: every score above the diagonal becomes −∞, so a token gives zero weight to the tokens after it.

The sampling T buttons set the temperature to the usual sampling settings (greedy, 0.2, 0.7, 1, 1.5); the readout says what greedy decoding would pick and how often sampling picks it.

Heads sharing keys and values shows multi-head (MHA), grouped-query (GQA) and multi-query (MQA) attention: the query heads in coloured groups, each group reading one K/V head, and what that does to the KV cache — 2 × layers × KV heads × head dimension × bytes per token, for a context length you choose. Llama 3 70B (64 query heads, 8 KV heads, head dimension 128, 80 layers, FP16) keeps 327,680 bytes = 0.3125 MiB per token, 8× less than without sharing.

Limits

  • Least squares fits a straight line in one variable; for polynomial and other fits, R² and residual plots on your own data use the Statistics tool.

  • Graph expressions use single-letter variables; e is Euler’s number and pi is π. In the step form, names may be longer. Operations: add, sub, mul, div, pow, neg, sq, sin, cos, tan, exp, ln, log (base 10), sqrt, tanh, sigmoid, relu, abs.

  • The book’s SGD data come from NumPy’s random generator, which this page does not reproduce: its 1000 points are different, so its SGD estimate is close to, not equal to, the book’s 3.11 and 1.93. Everything else matches the book’s printed numbers.

  • The dual-number derivative of exp(2x)/(1 + x²) at 0.5 can differ from the book’s 2.609550555320683 in the last digit: the quotient rule is evaluated in a different order.

  • Stemming here is deliberately simple; real search engines use Porter-style stemmers or lemmatisers.

Related: Neural network designer (build and train whole networks), Matrix calculator (XᵀX θ = Xᵀy and other systems), Statistics (regression on your data, distributions, tests), Eigenvectors at work (PCA, SVD, LSI), and AI hardware calculator (the KV cache against GPU memory).

Companion to Part IX of AI Acceleration: From Transistors to Trillion-Parameter Models: what self-attention actually computes (the attention equation, GQA and MQA) and decode (a softmax over the vocabulary, then sample the next token).

Linking to an example

A link opens the tool with the given settings: /tools/ml-maths/?<parameters>#<tab>, where the tab is regression, logistic, autodiff, search, info or softmax. Share link (top right) builds one from whatever is on screen. Points are x,y pairs separated by semicolons; documents are separated by |. A ` typed straight into a link reaches the page as a space: in `f=` a space between two terms is turned back into `, so ?f=x^3+2*x works; elsewhere write %2B, or leave the + out.

Parameter Meaning Example

example

a book preset (list below); other parameters in the same link override it

ch33-regression

pts

points for least squares

1,2;2,4;3,5;4,4;5,5

loss

l2 (squared) or l1 (absolute) error

l1

opt

gd (gradient descent on the points) or sgd (1000 noisy points)

gd

eta

learning rate η for gradient descent or SGD

0.05

steps

gradient-descent steps

2001

batch

SGD batch size

32

epochs

SGD epochs

20

cls

logistic data as hours,passed pairs

0.5,0;1,0;2,1

w

logistic weight

1.353

b

logistic bias

-3.721

lr

logistic learning rate

0.1

f

expression for the computation graph (overrides prog)

sin(x*x)

prog

graph steps name=op(a,b) separated by ;

z=mul(w,x);a=tanh(z)

at

input values

w=0.3,x=2,t=0.5

wrt

input for dual numbers and finite differences

w

logh

log₁₀ of the finite-difference step h

-8

fp

64 or 32-bit floats for finite differences

32

docs

documents separated by |

the cat sat|the dog sat

query

search query

cat on mat

score

ranking: cos, dot or bm25

bm25

wt

tfidf or tf (raw counts)

tf

k1

BM25 k₁

1.2

bm25b

BM25 b

0.75

stem

stemming on (1/true)

1

idf

BM25 idf: plain (ln N/df) or lucene

lucene

p

probabilities, symbol:p or plain numbers

A:1/2,B:1/4,C:1/8,D:1/8

q

the wrong distribution q

A:1/4,B:1/4,C:1/4,D:1/4

src

p (probabilities) or text (count letters)

text

text

text whose letters are counted

abracadabra

step

Huffman merges shown

3

z

softmax scores

2,1,0.1

T

temperature

0.5

tokens

attention tokens

cat,sat,on,mat

Q, K, V

attention matrices, rows separated by ;

1,0;0,1

scale

divide scores by √d_k (1/0)

0

causal

causal mask on the attention matrix (1/0)

1

qh, kvh

query heads and key/value heads (kvh = qh is MHA, 1 is MQA)

qh=64&kvh=8

hd, nl

head dimension and number of layers

hd=128&nl=80

kvb

bytes per cached value (2 FP16/BF16, 1 FP8)

1

ctx

context length in tokens for the cache total

131072

Presets for example=:

Name Tab Shows

ch33-regression

regression

Hours studied against score: ŷ = 2.2 + 0.6x by the normal equations, SSE 2.4

ch33-gd

regression

Gradient descent from θ = 0 with η = 0.05 and the book’s table of steps

ch33-sgd

regression

Mini-batch SGD on 1000 noisy points from y = 3x + 2

ch33-drag-points

regression

The lab: twelve points to drag, with residual squares and the SSE

ch33-outlier

regression

One point far away, fitted with absolute error (squared-error line dashed)

ch31-load

regression

Response time against load: ŷ = 46 + 4x, R² = 0.959

ch33-logistic

logistic

The lab: pass/fail data from w = b = 0; press Train

ch33-logistic-fit

logistic

The fitted model w = 1.353, b = −3.721: boundary 2.75 hours

ch17-backprop

autodiff

The one-weight network tanh(wx) with target 0.5: dL/dw = 0.1055

ch33-neuron

autodiff

One sigmoid neuron: dL/dw = −0.5, dL/db = −0.25

ch33-neuron-exercise

autodiff

The exercise x = 1, y = 0, w = 1, b = 0: dL/dw ≈ 0.2875

ch17-dual

autodiff

Dual numbers: x³ + 2x at 2 gives 14

ch17-dual-sin

autodiff

sin(x²) at 1.5: −1.8845208681682175

ch17-dual-quotient

autodiff

exp(2x)/(1 + x²) at 0.5: 2.60955055532068

ch17-sweet-spot

autodiff

Forward and central differences of sin at 1 against h

ch17-sweet-spot-32

autodiff

The same in 32-bit floats

ch33-tfidf

search

“cat on mat”: q·d 2.578, 0.164, 0 and cosines 0.871, 0.056, 0

ch33-stemming

search

The same with stemming: “cats” now counts as “cat”

ch33-bm25

search

BM25 with k₁ = 1.2 and b = 0.75

ch26-tfidf

search

“vector arrow”: cosines 0.078, 0.000, 0.421

ch26-length-bias

search

Raw counts: dot products 20, 2, 2 against cosines 1, 0.707, 1

ch33-entropy

info

The skewed four-symbol source: H = 1.75 bits, code 0, 10, 110, 111

ch33-huffman-wrong

info

The code built for uniform q costs 2 bits = 1.75 + D_KL 0.25

ch33-kl-coin

info

Biased against fair coin: D(biased‖fair) = 0.531, D(fair‖biased) = 0.737

ch33-softmax

softmax

softmax(2, 1, 0.1) = 0.659, 0.242, 0.099

ch33-softmax-overflow

softmax

(1000, 999, 998.1): the naive formula overflows, the stable one does not

ch33-attention

softmax

Attention weights and outputs for four tokens

From AI Acceleration (Part IX):

Name Tab Shows

p09-attention

softmax

softmax(QKᵀ/√d_k)V: every token attending to every token

p09-causal-mask

softmax

The same with the causal mask: weights above the diagonal are 0

p09-gqa-70b

softmax

GQA in Llama 3 70B: 64 query heads share 8 KV heads; 320 KiB (0.3125 MiB) per token, 2.5 GiB at 8K tokens

p09-gqa-128k

softmax

The same cache at 128K tokens: 40 GiB (42.9 GB) for one sequence

p09-mha-70b

softmax

Without sharing (64 KV heads): 8× the cache

p09-mqa-70b

softmax

MQA: one KV head for all 64 query heads

p09-greedy

softmax

Temperature 0.05 on five next-token logits (3, 2.5, 1.5, 0.5, −1): effectively greedy

p09-temp-0.2

softmax

T = 0.2: the top token 92 % of the time

p09-temp-0.7

softmax

T = 0.7: 61 %

p09-temp-1

softmax

T = 1, the model’s own distribution: 52 %

p09-temp-1.5

softmax

T = 1.5: 43 %, with more surprising picks

For example, https://geekychris.github.io/tools/ml-maths/?example=ch17-backprop#autodiff opens the book’s backpropagation example, and https://geekychris.github.io/tools/ml-maths/?f=x^3+2*x&at=x=2#autodiff builds the graph of x³ + 2x at x = 2.

Runs entirely in your browser; nothing you type leaves this page.