Instructions to use inviolus/InviolusOCR with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Keras
How to use inviolus/InviolusOCR with Keras:
# !pip install -U keras tensorflow huggingface_hub # Keras needs TensorFlow installed to read "hf://" paths, so the tensorflow backend is selected here; # "jax" and "torch" also work for computation once TensorFlow is installed. import os os.environ["KERAS_BACKEND"] = "tensorflow" import keras model = keras.saving.load_model("hf://inviolus/InviolusOCR") - Notebooks
- Google Colab
- Kaggle
|
Download README.md from inviolus/InviolusOCR: direct link, hf CLI and curl.
- Browser
- Download file 6.31 kB
-
https://huggingface.co/inviolus/InviolusOCR/resolve/main/README.md
- Command line
-
hf download hf://inviolus/InviolusOCR/README.md
-
curl -L -o README.md https://huggingface.co/inviolus/InviolusOCR/resolve/main/README.md
6.31 kB
| license: cc-by-nc-sa-4.0 | |
| language: | |
| - tr | |
| library_name: keras | |
| pipeline_tag: image-to-text | |
| tags: | |
| - ocr | |
| - text-recognition | |
| - turkish | |
| - tinyml | |
| - tflite | |
| - int8 | |
| - ctc | |
| - microcontroller | |
| # InviolusOCR: tiny Turkish line OCR for microcontrollers | |
| A compact convolutional CTC recognizer for **one cropped line of printed | |
| Turkish text**: 560,954 parameters and a **598 KB full-int8 TensorFlow Lite** | |
| file that keeps almost all of the float model's accuracy. A half-width **tiny** | |
| variant is **171 KB**. | |
| *Keywords: Turkish OCR, Türkçe OCR, tiny OCR, text recognition, TFLite, int8, | |
| TinyML, ESP32, microcontroller.* | |
| > **Türkçe özet:** Mikrodenetleyiciler için tek satır Türkçe metin okuyan, | |
| > 561 bin parametreli, int8 TFLite dosyası 598 KB olan küçük bir OCR modeli. | |
| > int8 hâli, ayrılmış test satırlarının %77,3'ünü, gerçek sahne metni | |
| > (TS-TR) kırpıntılarının %56,2'sini ve basılı belge satırlarının (donut) | |
| > %46,5'ini harfi harfine doğru okuyor. 171 KB'lık küçük sürüm daha düşük | |
| > doğrulukta çalışıyor (%64,4 / %32,6 / %20,1). Ticari olmayan kullanım içindir | |
| > (CC BY-NC-SA 4.0). | |
| This replaces [inviolus/erdem-ocr-tr-tinyml](https://huggingface.co/inviolus/erdem-ocr-tr-tinyml) | |
| (2026-10-09), whose int8 file lost most of its accuracy. | |
| ## Files | |
| | File | What it is | | |
| |---|---| | |
| | `inviolusocr.keras` | Float model, input `(batch, 32, 160, 1)`, output `(batch, 40, 90)` softmax | | |
| | `inviolusocr_int8.tflite` | Full-int8 export, input `[1, 32, 160, 1]` int8 (scale 0.007843, zero point -1), output `[1, 40, 90]` int8 (scale 0.00390625, zero point -128) | | |
| | `inviolusocr_tiny.keras`, `inviolusocr_tiny_int8.tflite` | Half-width variant, 144,330 parameters, same input, output and alphabet | | |
| | `alphabet.json` | Character set used to decode the output | | |
| | `benchmark.json`, `benchmark_T.json` | Scores for this model and the earlier versions; scores for tiny | | |
| ## Model | |
| - **Input:** one horizontal text line, grayscale, resized to 160×32, scaled | |
| to `[-1, 1]` (`pixel / 127.5 - 1`). | |
| - **Architecture:** 4 conv + batch-norm + pool blocks, a dense projection, | |
| then four residual dilated 1-D convolutions (dilation 1, 2, 4, 1) instead of | |
| an LSTM, and a dense softmax. Only ops that quantize cleanly to int8. | |
| - **Output:** 40 timesteps × 90 classes. Class `0` is padding, `1..88` are the | |
| characters of `alphabet.json` in order, `89` is the CTC blank. | |
| - **Character set:** digits, ASCII letters, `ç ğ ı İ ö ş ü Ç Ğ Ö Ş Ü`, space | |
| and `.,:;!?-_/()'%`. Up to 24 characters per line. | |
| - **Not included:** text detection. The line must already be cropped. | |
| ## Usage | |
| ```python | |
| import json | |
| import numpy as np | |
| import tensorflow as tf | |
| alphabet = json.load(open("alphabet.json", encoding="utf-8"))["alphabet"] | |
| BLANK = len(alphabet) + 1 | |
| def preprocess(path): | |
| image = tf.io.decode_image(tf.io.read_file(path), channels=1, expand_animations=False) | |
| image = tf.image.resize(image, [32, 160]) | |
| return (tf.cast(image, tf.float32) / 127.5 - 1.0).numpy() | |
| def decode(ids): | |
| text, previous = [], None | |
| for i in ids: | |
| if i != previous and 0 < i < BLANK: | |
| text.append(alphabet[i - 1]) | |
| previous = i | |
| return "".join(text) | |
| # int8 TFLite (the file meant for devices) | |
| interpreter = tf.lite.Interpreter(model_path="inviolusocr_int8.tflite") | |
| interpreter.allocate_tensors() | |
| inp, out = interpreter.get_input_details()[0], interpreter.get_output_details()[0] | |
| scale, zero = inp["quantization"] | |
| x = np.clip(np.round(preprocess("line.png") / scale + zero), -128, 127).astype(np.int8) | |
| interpreter.set_tensor(inp["index"], x[np.newaxis]) | |
| interpreter.invoke() | |
| print(decode(interpreter.get_tensor(out["index"])[0].argmax(-1))) | |
| ``` | |
| ## Results | |
| Exact-line accuracy (the whole line correct), all models scored on the same | |
| rows: 12,093 held-out lines (synthetic, Zenodo, TS-TR, esengul3, STS-TR) and | |
| the 2,078-crop official TS-TR test split (real scene text, never trained on), | |
| plus 2,563 printed-document rows from the donut 200k test list. | |
|  | |
| | Model, int8 file | Params | Size | Held-out | TS-TR | Donut test | | |
| |---|---:|---:|---:|---:|---:| | |
| | erdem-ocr 2026-10-09 (LSTM) | 631,226 | 665 KB | 32.9% | 33.5% | not measured | | |
| | InviolusOCR 2026-10-31 (previous version here) | 560,954 | 598 KB | 78.4% | 58.2% | 9.3% | | |
| | **InviolusOCR 2026-11-01 (main)** | **560,954** | **598 KB** | **77.3%** | **56.2%** | **46.5%** | | |
| | **InviolusOCR tiny 2026-11-02** | **144,330** | **171 KB** | 64.4% | 32.6% | 20.1% | | |
| Character error rate of the int8 files: main 10.0% held-out, 18.8% TS-TR, 12.6% | |
| donut; tiny 14.1%, 31.3%, 24.1%. | |
| ## Limitations | |
| - Printed text only; no handwriting, curved text or full pages. | |
| - Real scene text is still the weak spot (56% exact). | |
| - **Licence plates are not read** (2% exact on 250 plate crops in a first, | |
| unchecked test). | |
| - Not yet measured on a microcontroller (speed, memory). | |
| - Text detection and line cropping must be done before this model runs. | |
| ## Training data | |
| About 106,000 training crops. The main model was continued from earlier | |
| weights; tiny was trained from scratch for 260 minutes on CPU. | |
| - Synthetic Turkish lines rendered from a 50k-word Turkish word list. | |
| - [Turkish OCR Text Image Dataset](https://zenodo.org/records/21923181), Zenodo, CC BY 4.0. | |
| - [Turkish Scene Text Recognition (TS-TR)](https://www.kaggle.com/datasets/serdaryildiz/turkish-scene-text-recognition-dataset), Serdar Yıldız, CC BY-NC 4.0. | |
| - [Synthetic Turkish Scene Text (STS-TR)](https://www.kaggle.com/datasets/serdaryildiz/synthetic-turkish-scene-text-recognition-dataset), Serdar Yıldız, CC BY-NC 4.0. | |
| - [Turkish Word OCR](https://huggingface.co/datasets/esengul3/turkish-word-ocr), esengul3, CC BY-SA 4.0. | |
| - Turkish recognition 200k v4 (donut), turgutguvercin, CC BY-SA 4.0. | |
| ## License | |
| Because of the non-commercial (TS-TR, STS-TR) and share-alike (esengul3, donut) | |
| terms of the training data, this model is released under | |
| **[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/)**: | |
| non-commercial use only, credit this model and the datasets above, and share | |
| adaptations under the same license. | |
| Training code (MIT): [ErdemWilkinson/InviolusOCR](https://github.com/ErdemWilkinson/InviolusOCR). | |