Vol. XII · No. 04 · Apr 2026
Jake Cuth.

Drawing, classified
live.

A small neural network that runs entirely in your browser. Trained once, deployed everywhere, costs nothing per call. The deployment shape every shippable ML demo needs.

Draw any of 30 categories on the canvas below. A classifier trained on 90,000 sketches from Google's Quick Draw dataset predicts what it sees on every stroke. Inference runs on your laptop in under 50 ms. Nothing phoned home, no preloaded answers.


Most ML demos route every prediction through a server. A model sits behind an API, the page calls it, money meters tick. That shape works, but it forecloses an entire class of product: anything that needs to be free, offline, instant, or private can't be built that way.

The browser can run real neural networks. A small CNN trained on the right data fits in under a megabyte and predicts in tens of milliseconds on a five-year-old laptop. Once the page loads, every prediction is free and local. The model in the demo below weighs roughly 300 kilobytes, less than a poorly-compressed JPEG.

The story this page tells is not "look at this neat trick." It's that the deployment pattern, training in Python and shipping the weights to the user's machine via ONNX, is a real production shape that under-uses its capacity in most teams.


Mouse or finger. Strokes interpolate. Predictions update at the end of each stroke. The model knows 30 categories total but handles structured shapes (house, bicycle, guitar) much better than free-form ones (bird, cat) — see § IV for what it gets wrong. Pick a suggestion below for the best demo.

start drawing
strokes 0 classified this session 0
Try drawing one of these:

A · Dataset

90,000 sketches, 30 categories

Google's Quick Draw dataset, released as part of the Quick, Draw! game in 2016. Fifty million doodles across 345 categories, freely downloadable as 28×28 bitmap arrays. We use a 30-category subset chosen for visual distinctness; 3,000 training sketches per class plus 500 held out for evaluation.

B · Model

A small fully-connected network

784 input pixels → 256 ReLU → 128 ReLU → 30 softmax. Roughly 235,000 parameters total. Trained with Adam in scikit-learn, early-stopping on a 10% validation split. A small CNN would beat this, but the MLP is intentionally chosen for portability: it ships from any environment, no GPU, no framework dance.

C · Deployment

PyTorch-style → ONNX → browser

Trained model exported through skl2onnx to opset-13 ONNX. The browser uses onnxruntime-web with the WASM backend to run inference single-threaded on the user's CPU. First load ~3 seconds (model + runtime). Each subsequent prediction is under 50 milliseconds.


No model is honest unless it knows where it fails. These are the confusion pairs the classifier consistently mistakes on the held-out test set. Drawn from the actual confusion matrix, not invented.

loading evaluation results…


Pipeline

Pure Python training in notebooks/sketch_model.py ↗ — downloads the bitmap dataset, balances classes, trains the MLP, evaluates on held-out data, exports the ONNX model and the methodology JSON consumed by the receipts panel above. Re-runnable end-to-end with one command.

Inference

The browser canvas is captured at 480×480, downsampled to 28×28 grayscale, inverted to match Quick Draw's white-on-black format, and flattened. The 784-vector becomes the input tensor for an ONNX Runtime Web session. session.run() returns a 30-class probability vector; we render the top three.

Reading list

Ha & Eck · A Neural Representation of Sketch Drawings (sketch-rnn) ↗
The Quick, Draw! dataset ↗
ONNX Runtime Web tutorials ↗

Limitations

An MLP discards spatial structure; a CNN would hit higher accuracy at the same parameter budget. Quick Draw drawings are from a quick-game context (people drew under a 20-second timer) so the training distribution skews loose; careful drawings can confuse a model trained on hurried ones. Long-tail categories are deliberately omitted from the 30-class subset.