Khmer Handwritten Text Recognition (CRNN + CTC + character LM)
A small (9.5M parameters) model that reads one cropped line or word of Khmer text (handwritten, printed, or scene text) and returns Unicode Khmer text. It runs on CPU in about 0.15 s per line.
Built for a Year 4 thesis in Data Science and Engineering, Royal University of Phnom Penh (Oun MengHeang).
Results
Character error rate (CER) and word error rate (WER), lower is better. Words are segmented with khmercut.
| Test set | CER (greedy) | CER (+ LM) | WER (+ LM) |
|---|---|---|---|
| SoyVitou handwritten (211 Khmer samples) | 13.4% | 8.0% | 22.3% |
| CADT handwritten (444 samples, unseen pages) | 4.8% | 3.1% | 10.3% |
| WildKhmerST scene text (1,499 lines) | 9.9% | 8.8% | 21.1% |
| SoyVitou printed (1,000 samples) | 0.5% | β | 1.5% |
For comparison, Tesseract (khm, single-line mode) on the same images: 61.4% / 88.0% / 49.2% / 46.6% CER.
Usage
# pip install torch numpy pillow safetensors huggingface_hub
from huggingface_hub import snapshot_download
import sys
folder = snapshot_download("mengheang/khmer-handwritten-ocr")
sys.path.insert(0, folder)
from khmer_ocr import KhmerOCR
ocr = KhmerOCR(folder) # loads model + language model
print(ocr.read("line.png")) # beam search + language model
print(ocr.read("line.png", use_lm=False)) # faster greedy decoding
Input: an image of one text line or word (crop it first; the model does not detect text on a full page).
Model
| Part | Details |
|---|---|
| Input | Grayscale, height 64 px, width scaled with aspect ratio (max 1,800 px) |
| CNN | ResNet-style, 4 stages, reduces width by 4 (one output frame per 4 pixels) |
| Sequence model | 2-layer bidirectional LSTM, hidden size 256 |
| Output | 241 symbols (Khmer block, Khmer symbols, digits, ASCII) + CTC blank |
| Decoding | Greedy, or CTC prefix beam search (beam 16) + character 6-gram language model (alpha 0.6, beta 1.5, tuned on validation) |
The language model was trained only on general text (synthetic Wikipedia-style lines, printed and scene-text labels), not on any handwritten labels.
Training
- Pre-training (3 epochs) on 386k synthetic and printed images: KimkosalYon 200k synthetic lines, emhengly 136k printed words, SoyVitou 62k printed.
- Fine-tuning (20 epochs) on all real data: SoyVitou handwritten (2,894 Khmer samples) and CADT handwritten (3,152), each repeated 4x, plus WildKhmerST scene text (26,348 lines) and SoyVitou printed.
AdamW, one-cycle learning rate (1e-3 pre-training, 3e-4 fine-tuning), mixed precision, augmentation (rotation, blur, stroke width, width scaling). One RTX 5070 Ti laptop GPU.
Training data and credits
| Dataset | License |
|---|---|
| SoyVitou Khmer handwritten 4.2k | MIT |
| LaySopanha Khmer Handwritten Dataset (CADT capstone: Ly Leab, Lay Sopanha, Narith Sopheakleap, Hinge Sothida, Sok Sothika) | CC BY 4.0 |
| WildKhmerST | CC BY-NC 4.0 |
| KimkosalYon Khmer OCR 200k | MIT |
| SoyVitou 62k printed | MIT |
| emhengly Khmer text recognition | Apache 2.0 |
Because WildKhmerST is non-commercial, this model is released under CC BY-NC 4.0 (non-commercial use only).
Limitations
- Reads one line or word at a time; text must be cropped first.
- Trained on a few thousand handwritten samples from a limited number of writers; unusual handwriting styles will have more errors.
- Common errors: similar-looking consonants (α/α, α/α) and small vowel signs.
- Test splits are our own (SoyVitou Khmer-only test samples; CADT split by page), so numbers are not directly comparable to other papers.
- Downloads last month
- -