Update README.md
Browse files
README.md
CHANGED
|
@@ -48,8 +48,12 @@ TrorYongOCR is a tiny encoder-decoder model for Scene Text Recognition task.
|
|
| 48 |
It prepends the encoding of image patches to the "begin of sequence" token to condition next character token generation.
|
| 49 |
Using LLM analogy, patch encodings can be simply seen as a prefill prompt.
|
| 50 |
The single text decoder block of TrorYongOCR generates character tokens based on the prefill prompt in an autoregressive manner without cross-attention mechanism.
|
| 51 |
-
|
| 52 |
Current pre-trained weight supports 2 languages: Khmer and English.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 53 |
|
| 54 |
|
| 55 |
## Model Details
|
|
@@ -76,22 +80,22 @@ This model has been pushed to the Hub using the [PytorchModelHubMixin](https://h
|
|
| 76 |
### Model Configuration
|
| 77 |
|
| 78 |
The choice of model configuration can be found as the following.
|
| 79 |
-
While preserving aspect ratio, the input image is resized to $min(
|
| 80 |
This is to reduce computation cost in the training as images with high resolution and big aspect ratio incur very long sequence of patches.
|
| 81 |
The image patch size is $(8, 4)$ where $8$ is along the width of input image.
|
| 82 |
The context length for character sequence is up to $1024$.
|
| 83 |
Transformer configuration is the following: there are $4$ blocks, each has embedding dimension $d_{model}=384$ and $h=6$ heads.
|
| 84 |
-
In particular, encoding blocks (block $1$ to $3$) have MLP dimension $d_{MLP}=
|
| 85 |
|
| 86 |
|
| 87 |
<div align="center">
|
| 88 |
|
| 89 |
|Layer| $d_{model}$ | $h$ | $d_{MLP}$ | Role |
|
| 90 |
|:---:|:-----------:|:---:|:---------:|:-------:|
|
| 91 |
-
|1 | 384 | 6 |
|
| 92 |
-
|2 | 384 | 6 |
|
| 93 |
-
|3 | 384 | 6 |
|
| 94 |
-
|4 | 384 | 6 |
|
| 95 |
</div>
|
| 96 |
|
| 97 |
|
|
@@ -103,7 +107,8 @@ TrorYongOCR is implemented as a `PyPI` package and can be installed via
|
|
| 103 |
pip install tror-yong-ocr
|
| 104 |
```
|
| 105 |
|
| 106 |
-
|
|
|
|
| 107 |
|
| 108 |
|
| 109 |
### KhmerSynthetic1M
|
|
@@ -119,53 +124,32 @@ This implies that there are images with aspect ratio largely higher than $4$.
|
|
| 119 |
|
| 120 |
This dataset by [`Mr. Yat Seanghay`](https://huggingface.co/seanghay) contains images with a variety of background colors and character colors.
|
| 121 |
|
| 122 |
-
###
|
| 123 |
|
| 124 |
-
|
|
|
|
|
|
|
| 125 |
|
| 126 |
-
-
|
| 127 |
-
- 997 indoor scenes
|
| 128 |
-
- 547 outdoor scenes
|
| 129 |
|
| 130 |
-
|
|
|
|
| 131 |
|
| 132 |
-
- flat and raised text
|
| 133 |
-
- low illumination
|
| 134 |
-
- distant and partially occluded text.
|
| 135 |
|
| 136 |
-
|
| 137 |
|
| 138 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 139 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 140 |
|
| 141 |
-
### Weight Initialization
|
| 142 |
-
|
| 143 |
-
We initialize weights as what SOTA models reguarly do.
|
| 144 |
-
The code to initialize the weight is given below.
|
| 145 |
-
|
| 146 |
-
Exceptionally, for position embedding used in the decoding block, I initialized it with $std=1.0$.
|
| 147 |
-
|
| 148 |
-
```python
|
| 149 |
-
def init_weights(self, module: nn.Module, name: str = '', exclude: Sequence[str] = ('')):
|
| 150 |
-
"""Initialize the weights using the typical initialization schemes used in SOTA models."""
|
| 151 |
-
if any(map(name.startswith, exclude)):
|
| 152 |
-
return
|
| 153 |
-
if isinstance(module, nn.Linear):
|
| 154 |
-
nn.init.trunc_normal_(module.weight, std=0.02)
|
| 155 |
-
if module.bias is not None:
|
| 156 |
-
nn.init.zeros_(module.bias)
|
| 157 |
-
elif isinstance(module, nn.Embedding):
|
| 158 |
-
nn.init.trunc_normal_(module.weight, std=0.02)
|
| 159 |
-
if module.padding_idx is not None:
|
| 160 |
-
module.weight.data[module.padding_idx].zero_()
|
| 161 |
-
elif isinstance(module, nn.Conv2d):
|
| 162 |
-
nn.init.kaiming_normal_(module.weight)
|
| 163 |
-
if module.bias is not None:
|
| 164 |
-
nn.init.zeros_(module.bias)
|
| 165 |
-
elif isinstance(module, (nn.LayerNorm, nn.BatchNorm2d, nn.GroupNorm)):
|
| 166 |
-
nn.init.ones_(module.weight)
|
| 167 |
-
nn.init.zeros_(module.bias)
|
| 168 |
-
```
|
| 169 |
|
| 170 |
## Citation
|
| 171 |
|
|
|
|
| 48 |
It prepends the encoding of image patches to the "begin of sequence" token to condition next character token generation.
|
| 49 |
Using LLM analogy, patch encodings can be simply seen as a prefill prompt.
|
| 50 |
The single text decoder block of TrorYongOCR generates character tokens based on the prefill prompt in an autoregressive manner without cross-attention mechanism.
|
| 51 |
+
TrorYongOCR can process input images of arbitrary aspect ratio.
|
| 52 |
Current pre-trained weight supports 2 languages: Khmer and English.
|
| 53 |
+
Testing on challenging [WildKhmerST](https://l3i-share.univ-lr.fr/2025WildKhmerST/) dataset, TrorYongOCR (5.5M parameters) achieves `cer` of `42.97%` while fine-tuned `DeepSeek-OCR` (3B parameters) achieves `cer` of `67.66%`.
|
| 54 |
+
So, TrorYongOCR has less parameters, performs relatively better for Khmer text and faster for inference.
|
| 55 |
+
It is suitable for local or edge-device usage such as License Plate Recognition application.
|
| 56 |
+
TrorYongOCR is deployed on Huggingface Space [here](https://krorngai-troryongocr-demo.hf.space) for demonstration.
|
| 57 |
|
| 58 |
|
| 59 |
## Model Details
|
|
|
|
| 80 |
### Model Configuration
|
| 81 |
|
| 82 |
The choice of model configuration can be found as the following.
|
| 83 |
+
While preserving aspect ratio, the input image is resized to $min(W, H) = 32$ where $W$ and $H$ are width and height of the image respectively.
|
| 84 |
This is to reduce computation cost in the training as images with high resolution and big aspect ratio incur very long sequence of patches.
|
| 85 |
The image patch size is $(8, 4)$ where $8$ is along the width of input image.
|
| 86 |
The context length for character sequence is up to $1024$.
|
| 87 |
Transformer configuration is the following: there are $4$ blocks, each has embedding dimension $d_{model}=384$ and $h=6$ heads.
|
| 88 |
+
In particular, encoding blocks (block $1$ to $3$) have MLP dimension $d_{MLP}=\frac{4d_{model}}{3}=512$ and the decoding block has $d_{MLP}=\frac{8d_{model}}{3}=1024$.
|
| 89 |
|
| 90 |
|
| 91 |
<div align="center">
|
| 92 |
|
| 93 |
|Layer| $d_{model}$ | $h$ | $d_{MLP}$ | Role |
|
| 94 |
|:---:|:-----------:|:---:|:---------:|:-------:|
|
| 95 |
+
|1 | 384 | 6 | 512 | Encoder |
|
| 96 |
+
|2 | 384 | 6 | 512 | Encoder |
|
| 97 |
+
|3 | 384 | 6 | 512 | Encoder |
|
| 98 |
+
|4 | 384 | 6 | 1024 | Decoder |
|
| 99 |
</div>
|
| 100 |
|
| 101 |
|
|
|
|
| 107 |
pip install tror-yong-ocr
|
| 108 |
```
|
| 109 |
|
| 110 |
+
The pre-trained weight of TrorYongOCR can be found [here](https://huggingface.co/KrorngAI/TrorYongOCR).
|
| 111 |
+
It is obtained by pre-training on [`seanghay/khmer-hanuman-100k`](https://huggingface.co/datasets/seanghay/khmer-hanuman-100k) and [`SoyVitou/KhmerSynthetic1M`](https://huggingface.co/datasets/SoyVitou/KhmerSynthetic1M) datasets and fine-tuning on [Wild Khmer Scene Text](https://l3i-share.univ-lr.fr/2025WildKhmerST/) dataset.
|
| 112 |
|
| 113 |
|
| 114 |
### KhmerSynthetic1M
|
|
|
|
| 124 |
|
| 125 |
This dataset by [`Mr. Yat Seanghay`](https://huggingface.co/seanghay) contains images with a variety of background colors and character colors.
|
| 126 |
|
| 127 |
+
### WildKhmerST: A Dataset for Khmer Scene Text Detection and Recognition in the Wild
|
| 128 |
|
| 129 |
+
This dataset of Khmer scene text comprises 29,601 annotated text lines from 10,000 unique images.
|
| 130 |
+
It is highly diverse and challenging, encompassing artistic text, blurred text, low-light conditions, curved text, text in complex backgrounds, and occluded text.
|
| 131 |
+
Each text line is annotated with polygonal bounding box coordinates and line-level transcriptions, alongside attributes describing background complexity, character appearance, and text style.
|
| 132 |
|
| 133 |
+
To fine-tune TrorYongOCR, I cropped the quadrilateral bounding boxes to get only text images. Then, warp operation is used to transform quadrilateral image into rectangle one.
|
|
|
|
|
|
|
| 134 |
|
| 135 |
+
For the sake of benchmarking, `WildKhmerST` is processed and split into 3 parts: `train`, `validate`, and `test`.
|
| 136 |
+
It can be found [here](https://huggingface.co/datasets/KrorngAI/WildKhmerST-Warped)
|
| 137 |
|
|
|
|
|
|
|
|
|
|
| 138 |
|
| 139 |
+
## Evaluation
|
| 140 |
|
| 141 |
+
I fine-tuned [`DeepSeek-OCR`](https://huggingface.co/unsloth/DeepSeek-OCR), one of the most well-known Vision Language model, on `WildKhmerST` and compare its performance with TrorYongOCR.
|
| 142 |
+
`DeepSeek-OCR` has 3 billions parameters and be can be used for text recognition task.
|
| 143 |
+
Following the notebooks from `Unsloth`, the fine-tuned model can be found [here](https://huggingface.co/Kimang18/deepseek_ocr_Khmer_finetuned).
|
| 144 |
+
Despite the fine-tuning, it still hallucinates on some images of `test` split.
|
| 145 |
+
Ignoring the hallucination instances, the fine-tuned model achieves `cer` of `67.66%`.
|
| 146 |
+
This is relatively worst compared to TrorYongOCR who achieves `cer` of `42.97%`.
|
| 147 |
|
| 148 |
+
Moreover, due to its size, `DeepSeek-OCR` needs a lot of compute which can slow down its inference speed.
|
| 149 |
+
TrorYongOCR has only 5.5 millions parameters.
|
| 150 |
+
So, it enjoys faster inference and is suitable for local or edge-device usage.
|
| 151 |
+
For instance, TrorYongOCR can be further fine-tuned for License Plate Recognition dataset and integrated into traffic system to enhance traffic security.
|
| 152 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 153 |
|
| 154 |
## Citation
|
| 155 |
|