Skip to main content

Keyboard shortcuts

Project & model card

Reading the ASL alphabet, in the browser

An end-to-end computer-vision project: a MobileNetV2 transfer model that classifies the 26 static letters of the American Sign Language alphabet, exported to ONNX and run entirely client-side. This page is the honest story of how it works and where it falls short.

The problem

What this project is

The American Sign Language alphabet is fingerspelled with 26 distinct static hand shapes (A–Z). The goal here is narrow and concrete: given a single image of a hand, predict which letter it is — and do it fast, privately, and on-device, with no server in the loop.

It is built as a full ML-engineering lifecycle rather than a one-off notebook: dataset ingestion and stratified splitting, augmentation-aware training, rigorous confusion-matrix evaluation, explainability, ONNX export with a numerical parity test, and a static, in-browser demo. The point is to show the whole pipeline done carefully — including being honest about its limits.

Architecture

From pixels to a predicted letter

The classifier is a MobileNetV2 backbone pretrained on ImageNet with its final classifier head replaced by a 26-way head. The ImageNet backbone is frozen for a short warm-up, then the whole network is fine-tuned end-to-end at a 10× lower learning rate. One deliberate choice in the augmentation pipeline: no horizontal flip — ASL signs are not flip-invariant, since pairs like b/d and p/q are mirror images of each other.

Architecture diagram. The model is a MobileNetV2 backbone pretrained on ImageNet, with its classifier head replaced by a 26-way head, taking a 3 by 128 by 128 RGB image and producing 26 class logits for the letters A through Z. The inference flow runs entirely in the browser: a webcam frame or uploaded image is cropped to the hand with MediaPipe, resized and normalized with ImageNet statistics into channel-first layout, run through the ONNX model with onnxruntime-web, and passed through a softmax to produce the predicted letter.

Model

In-browser inference flow

Accuracy, honestly

Benchmark vs. real world

Two numbers, told honestly. The headline figures below are benchmark numbers, measured on the held-out test split of the deployed model's training union (Marxulia + aliciiavs + Hemg, ~21k images, 26 classes A–Z). They are real and reproducible with make eval-real — but they describe performance on data that resembles the training set, not the messy real world (see the honest cross-dataset number below).

Benchmark

96.9%

Held-out test accuracy

26 classes A–Z, 3,170 test images (3-source merge)

Benchmark

0.969

Macro F1

averaged equally across all 26 classes

Benchmark

97.3%

Validation accuracy

best epoch during fine-tuning

The honest cross-dataset number

Measured

The benchmark above is inflated: train and test images come from the same uniform dataset, so the test set looks like the training set. The number that actually matters is cross-dataset accuracy — evaluated on a different dataset (EitanG98/asl_letters, different signers and real backgrounds) the model never trained on. It is 59.8% on the 24-letter A–Y headline (J and Z are dynamic motion signs a single frame can't capture), or 55.5% across all 26 classes. Reproduce with make eval-realworld-diverse-hemg.

That number was earned by data diversity, the only lever that moved it: single-source 33.4% → add a multi-signer dataset 47.6% → add a third source 55.5%. Preprocessing tricks, augmentation, calibration, and architecture swaps were all measured and found not to help — documented as honest negatives in the repo's docs/.

A robustness experiment, reported honestly

We retrained the same MobileNetV2 with aggressive domain augmentation (wide crops/rotations, strong lighting and contrast jitter, random grayscale, blur, and erasing) aimed at the cluttered-webcam case — reproducible with make train-robust.

Measured on the same held-out test split, the robust model scored 92.3% versus the then-baseline's ~97% — heavy augmentation cost ~4.5 points on the benchmark. Once we had a real cross-dataset test set, augmentation proved neutral there too: it was data diversity, not augmentation or architecture, that moved the honest number. The deployed model is now the diverse multi-source one — chosen because it measured better on the cross-dataset gate, not because we hoped it was better.

Explainability

What is the model looking at?

Grad-CAM highlights the image regions the network leaned on for its prediction — a sanity check that the model attends to the hand, not the background. Below is the real saliency overlay for class V, produced by src/gradcam.py.

Grad-CAM saliency overlay for the ASL letter V: a heatmap over the hand-sign image showing which regions most influenced the model's prediction, concentrated on the extended fingers.
Grad-CAM saliency for class V

This is one real overlay, not a full gallery — overlays for any class can be generated locally with make gradcam.

In-browser inference

How it runs without a server

There is no inference backend. The trained model is exported to ONNX and executed in your browser tab, so every prediction happens locally.

Runs with onnxruntime-web

The model is exported to ONNX and executed by onnxruntime-web, which runs the network via a WebAssembly (WASM) backend — with a WebGPU path where the browser supports it.

Frames never leave your device

Webcam frames and uploaded images are preprocessed and classified entirely in the browser tab. No pixels are uploaded anywhere — the inference is fully client-side and private.

No server, static deploy

The whole site is a static export: plain HTML, JS, and the .onnx weights served as files. There is no inference backend to run, scale, or pay for.

Low latency, on-device

Because there is no network round-trip, predictions update locally as fast as the device can run the forward pass — no API calls per frame.

Under the hood

Tech stack

Modeling & training
PyTorch 2.xtorchvisionMobileNetV2 (transfer learning)AdamW + cosine LRCUDA / Apple-Silicon MPS / CPU
Evaluation & explainability
scikit-learn (confusion matrix, F1)Grad-CAMdistribution-shift suite
Serving & in-browser inference
ONNX exportonnxruntime-web (WASM / WebGPU)MediaPipe hand crop
Web showcase
Next.js 15 (App Router)React 19TypeScript (strict)Tailwind CSS
Engineering
GitHub Actions CIpytest + coverage gateruff + black + mypy

Honesty

Ethics & limitations

A model is only as trustworthy as the caveats shipped with it. These are drawn directly from the project’s model card.

Limitations

  • Not an accessibility or medical tool

    This is an educational / portfolio demonstration of a computer-vision pipeline. It is not a certified accessibility, communication, medical, legal, or otherwise safety-critical product and must not be relied on as one.

  • Alphabet only, static frames

    It classifies single still frames of the ASL alphabet. It does not recognize continuous signing, words, or grammar, and the motion-based letters (J, Z) are inherently ambiguous as single frames.

  • Benchmark optimism

    The training data is fairly homogeneous, so a random split can leak near-duplicate frames across train and test. The benchmark accuracy is therefore optimistic; a group-aware split would lower it.

  • Shared hand shapes get confused

    Letters that share a hand shape are the usual error sources — P/Q, V/W, and M/N/S are classic confusions.

Ethical considerations

  • Demographic representation

    The training data appears to feature a narrow range of skin tones and a single signing environment, so the model will likely underperform for under-represented skin tones and settings. Any production or accessibility use would require a diverse, consented, group-split dataset and per-group fairness evaluation.

  • Respect for the Deaf community

    ASL is a complete language with its own grammar; alphabet fingerspelling is a small part of it. This project should not be presented as "translating ASL." Accessibility tools should be built with the Deaf and hard-of-hearing community, not merely for it.

  • Honest reporting

    Benchmark accuracy is reported alongside its leakage caveat specifically to avoid overstating real-world capability.