Tool

LeNet-5 / live digits

CNN ONNX Runtime Web Client-side

A 61,706-parameter convolutional network from 1998, trained from scratch in PyTorch and running on your webcam entirely inside this tab.

How it works, from the bytes up

LeNet-5 live digit recognition

Live Inference

Loading runtime

The camera stays on your device. Nothing is uploaded, recorded, or sent anywhere.

Hold a dark, thickly written digit on white paper inside the guide box. The inner box shows what the preprocessor cropped.

Waiting for input

model: MNIST, 99.30% test accuracy

what the network sees · 28×28

FPS
—
Preprocess
—
Inference
—
Runtime
ONNX Runtime · WASM

LeNet-5 (ReLU/max-pool) · loading model card…

Training

LeNet-5 with the original layer shapes, swapping tanh and average pooling for ReLU and max pooling. Trained from scratch in PyTorch on MNIST with Adam and mild affine jitter, on the Apple silicon GPU through the mps backend. 15 epochs, about 90 seconds, 99.30% on the 10,000 held-out test images. What those two swaps were actually worth, measured across four seeds

Export and parity

The checkpoint is exported to ONNX at opset 13, then every test image is run through both PyTorch and ONNX Runtime and the logits compared. The shipped file agrees on all 10,000 predictions with a maximum drift of 1.3e-5, so the browser and the trainer are the same model. Why an unchecked export is the bug that costs you a weekend

In the browser

A worker thread holds the ONNX Runtime Web session so inference never blocks the camera loop. Each frame is cropped to the guide box, thresholded, rescaled so the ink reaches full brightness the way MNIST strokes do, cropped again to the ink, scaled to a 20×20 box and centred by centre of mass in a 28×28 field. If the guide box catches the edge of the page rather than the writing, it looks again inside the page. The runtime is served from this domain rather than a CDN, so no third party sees that you opened this page. The five preprocessing steps, and why each one exists