Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Safety-Calibrated Detection of Cancelled Handwriting (Exam OCR)

A production-minded ML system that finds and masks cancelled / scribbled-out regions on handwritten answer sheets before an OCR/grading model reads them — with a statistically certified guarantee on the one error that actually matters: hiding a real answer.

pipeline

TL;DR

  • The hard part isn't detection — it's safety. Missing a scribble is cheap; hiding a student's real answer is not. The system is built precision-first and abstains when unsure.
  • Certified ≤ 2% chance of hiding a valid answer at 95% confidence (conformal risk control); empirically ~0.1% on a frozen, human-labeled test set.
  • RF-DETR transformer detector, trained cost-efficiently on serverless GPUs, with post-hoc confidence calibration so a masking threshold is actually trustworthy.
  • A two-tier architecture (cheap detector + VLM-as-teacher) validated with controlled experiments — including the negative results that ruled out the wrong paths.

Why this might be worth a recruiter's 30 seconds

🎯 Safety as a guarantee, not a hope Conformal prediction (Hoeffding–Bentkus RCPS) turns a noisy confidence score into a provable error bound.
🔬 Calibration done right Per-class isotonic / Platt scaling; reliability diagrams; the masking threshold is derived from a risk target, not hand-picked.
💸 Cost-aware engineering L4 over A100 (the model isn't compute-bound); bulk inference ≈ pennies per 1k pages; the expensive VLM is used only offline as a teacher.
🧪 Honest evaluation Frozen, leakage-safe split; confusion matrices (detection and decision); compression-robustness; documented negative results.

The problem

Students cross out, scribble over, and cancel work on exam pages. An OCR/grading model that reads that noise produces wrong transcriptions and wrong grades. The task: detect cancelled regions and mask them before OCR — cheaply enough to run on every page, and safely enough to (almost) never hide a real answer.

A cost asymmetry drives every design choice:

  • False negative (miss a scribble) → grader sees struck-out work. Mild, recoverable.
  • False positive (mask a real answer) → possible wrong grade. Dangerous.

→ optimize precision + a calibrated abstain policy, not raw accuracy.

What I built

  1. Data pipeline — normalized multi-reviewer annotations into a clean 6-class dataset; frozen train/val/test split, leakage-safe (1,195 / 149 / 150 pages).
  2. Detector — fine-tuned RF-DETR (DINOv2-backbone transformer detector) on serverless GPUs; benchmarked against YOLO across model sizes and resolutions.
  3. Confidence calibration — per-class isotonic / Platt scaling so a score of "0.8" means ~80% precision (reliability diagram below).
  4. Certified thresholdConformal Risk Control (Hoeffding–Bentkus) selects the most aggressive masking threshold that still provably keeps the valid-answer-hidden rate ≤ α.
  5. Two-tier architecture — a cheap detector for small marks (runtime) + a VLM-as-teacher for large cancelled blocks (offline labeling → distillation). Both directions validated experimentally.
  6. Evaluation harness — detection + decision confusion matrices, per-class precision/recall, compression robustness; re-runnable on the frozen set for regression tracking.

Results (frozen, human-labeled test set)

Safety vs. coverage is an explicit, certified dial:

Guaranteed valid-answer-hidden Coverage (cancellations caught) Empirical harm
≤ 2% (95% conf) ~24% ~0.1%
≤ 3% ~28% ~0.1%
≤ 5% ~46% ~0.9%

Left — mask/keep decision matrix: 0 valid answers hidden at the safe threshold. Right — the safety↔coverage curve: coverage is a tunable dial, bounded by the safety guarantee.

Calibration works — raw confidence is miscalibrated; post-hoc calibration pulls it onto the diagonal:

Engineering decisions & lessons (the part I'm most proud of)

  • Cost-aware to the cent. Chose L4 over A100 (small model → not compute-bound → ~3–5× cost for ~1.3× speed). Bulk inference over 10k pages ≈ $0.25–1.20.
  • Smoke-test before spend. A 1-epoch probe + reading the resolved training config caught that a proposed focal-loss / repeat-factor-sampling change was a no-op (the model already uses IA-BCE; the kwargs were silently ignored) — saving a wasted multi-hour GPU run.
  • Knowing what doesn't work is the result. Off-the-shelf VLMs are useless as box detectors (0% box recall, and they masked whole valid answers) but excellent as offline teachers for large cancelled blocks (54% recall / 78% precision). That asymmetry is the architecture.
  • Calibration ≠ accuracy. Calibration made the threshold trustworthy; raising coverage needs more data — diagnosed, not conflated.

Tech stack

Python · RF-DETR / PyTorch · serverless GPU (Modal) · scikit-learn (isotonic / Platt) · conformal prediction (RCPS) · OpenCV / Pillow · vision-language models (offline teacher)

Repo structure

scripts/        training, calibration, confusion-matrix, inference, VLM probe
knowledge_base/ distilled, fully-grounded engineering docs (00–13)
research/        raw research outputs (calibration methods, citations)
docs/assets/     charts used in this README

Status & honest caveats

  • Proof-of-concept, not deployed. The detector is safe-but-conservative (~24% coverage at the safe threshold); raising coverage is a data problem, not a threshold one.
  • A ≤1% guarantee isn't certifiable yet (needs ~300+ labeled calibration pages; currently 149).
  • Every number is reported at a stated operating point on frozen, human-labeled data — no cherry-picking.

Trained and evaluated on anonymized handwritten answer-sheet data. No PII or student work is included in this repository. All metrics are measured on a frozen, leakage-safe split.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages