Views
No views yet
[0, 1]: 1 = legible, human-style handwriting, 0 = corrupted or
illegible output. Trained to filter synthetic handwriting produced by
Graves-style generative models before it's used downstream.[B, 256, 256, 1] (MLX NHWC), float320.0 = background, 1.0 = inkrender.py (or graves_handwriting_mlx.quality.render_strokes)
fits each stroke bbox isotropically into the canvas with 12 px paddingmx.sigmoid for a probability in [0, 1].graves-handwriting-mlx package installed:1import mlx.core as mx
2from graves_handwriting_mlx.quality import QualityClassifier, render_strokes
3
4model = QualityClassifier.from_pretrained("breitburg/penpal-quality-assurance")
5
6# `strokes` is the project's nested word -> stroke -> point schema
7image = render_strokes(strokes) # [256, 256, 1]
8score = mx.sigmoid(model(mx.array(image)[None]))[0] # float in [0, 1]1from huggingface_hub import hf_hub_download
2weights_path = hf_hub_download("breitburg/penpal-quality-assurance", "weights.safetensors")1.0) and corrupted-synthetic (label 0.0) strokes are
rasterized through the same renderer so the classifier cannot use
rendering style as a shortcut.κ scale,
attention β floor, hidden-state Gaussian noise) in a 10 / 70 / 20
mixture of very mild / mild / gibberish corruption ranges0.5) — clean samples from
breitburg/penpal,
which sit between the real and corrupted clusters{0.0, 0.5, 1.0} labels.| Source | Mean | Median | p10 | p25 | p75 | p90 | ≥0.3 | ≥0.5 | ≥0.7 | ≥0.9 |
|---|---|---|---|---|---|---|---|---|---|---|
| held-out real handwriting | 0.675 | 0.669 | 0.390 | 0.500 | 0.881 | 0.969 | 96.4 % | 75.0 % | 46.0 % | 22.8 % |
breitburg/penpal (clean synthetic) | 0.418 | 0.396 | 0.321 | 0.352 | 0.452 | 0.529 | 100 % | 13.8 % | 3.0 % | 0.6 % |
0.3 — lenient: keeps essentially all of penpal, drops only the obvious failures0.5 — balanced: drops ~86 % of penpal, keeps 75 % of real0.7 — strict: keeps only confidently human-looking rows (~46 % of real)weights.safetensors — trained parametersconfig.json — architecture widths and input contractmodel.py — QualityClassifier / BasicBlock reference implementationrender.py — render_strokes for stroke → 256×256 raster