← Усі статті

Як навчити нейромережу читати рукописні цифри: від CNN до TrOCR

Практичний шлях від класифікації однієї цифри до розпізнавання послідовностей на реальних бланках: CNN, CTC, CRNN, TrOCR, розмітка з бази, експерименти та production-пайплайн без зайвої моделі.

Як навчити нейромережу читати рукописні цифри: від CNN до TrOCR
Зміст

Коли кажуть «OCR», зазвичай уявляють друкований текст: договір, рахунок, скан паспорта. Рукописні цифри в комірці таблиці — інша задача: інший шум, інший алфавіт, інша постановка. Одна картинка може означати клас 7, а може — рядок 783. Від формулювання залежить, чи потрібен простий класифікатор, CRNN з CTC чи повноцінний TrOCR.

Нижче — практичний розбір для інженерів, які будують розпізнавання на реальних фотографіях бланків, а не на датасеті MNIST. Ми пройдемо шлях від геометрії документа до порівняння архітектур, розберемо, як отримати розмітку з бази даних, і покажемо, чому найбільша модель рідко виявляється найкращим першим кроком. Матеріал доповнює контур OCR у завантаженні документів для RAG — там фокус на корпоративних PDF, тут — на вузькій, але типовій задачі польового вводу.

Ключові висновки

OCR — не одна задача. Класифікація однієї цифри та розпізнавання послідовності потребують різних моделей, метрик і даних.

Структура документа важливіша за нейромережу. Якщо шаблон бланка відомий, спочатку вирівнюєте геометрію і ріжете комірки — а не віддаєте цілу сторінку універсальному OCR.

Найкращий датасет — production-подібний. Висока точність на MNIST не переноситься на фотографії з перспективою, тінями та лініями таблиці.

Розмітка з бази може бути ціннішою за ручну. Коли фото пов’язане з записом у системі, ground truth уже є — лишається побудувати конвеєр cell image → label.

CNN — сильний baseline. Для однієї цифри у відомій комірці маленька згорткова мережа часто швидша, дешевша й зрозуміліша, ніж Transformer.

CRNN + CTC — природний крок для послідовностей. Кілька цифр у комірці без посимвольної розмітки — класична постановка Connectionist Temporal Classification.

TrOCR виправданий не завжди. Універсальна модель має сенс при складному тексті та розширенні алфавіту; для десяти цифр у фіксованій комірці спеціалізоване рішення часто виграє.

Production — це пайплайн. Детекція документа, корекція перспективи, правила валідації та human-in-the-loop не менш важливі, ніж вибір архітектури.

Дві різні задачі під одним словом «OCR»

Перш ніж порівнювати CNN і TrOCR, зафіксуйте, що саме ви розпізнаєте.

Класифікація зображення

Одна обрізана комірка містить одну цифру: картинка [ 7 ] → клас 7. Це класифікація на 10 класів (09). Модель видає розподіл ймовірностей за фіксованим набором міток. Довжина відповіді завжди дорівнює одному символу.

Така постановка можлива, коли шаблон бланка гарантує: у конкретному полі завжди одна цифра, або ви заздалегідь ріжете область так, що в кадрі лишається один символ.

Розпізнавання послідовності

Інша комірка містить кілька цифр: [ 7 8 3 ] → рядок "783". Модель повинна визначити символи, їхній порядок і кількість. Кількість класів на виході більше не фіксована одним числом — потрібен механізм декодування послідовності.

Це принципово інша задача. Класифікатор, навчений на окремих цифрах, не «додумає» порядок трьох символів без окремого етапу сегментації. А сегментація рукописних цифр на реальному бланку — окрема головний біль.

Чому MNIST — поганий проксі для реальних бланків

MNIST — 60 000 навчальних зображень рукописних цифр, 10 класів, одна цифра на картинку, нормалізований розмір 28×28, контрольовані умови зйомки. Для навчання основ computer vision датасет чудовий. Для обіцянок замовнику — небезпечний.

Реальні фотографії заповнених бланків додають фактори, яких у MNIST немає:

Фактор Що ламає
Перспектива і поворот Цифра спотворена, пропорції не збігаються з навчальною вибіркою
Нерівномірне освітлення Тіні, відблиски, локальний контраст
Сітка таблиці Лінії перетинають штрихи цифр
Фон паперу Текстура, плями, згини
Різна товщина пера Тонкі й жирні штрихи в одному датасеті
Різні почерки й розміри Один і той самий клас 3 виглядає по-різному
Якість камери Шум, розмиття, стиснення JPEG

Це domain gap: модель, натренована на MNIST, може показати 99% accuracy на тесті датасету і провалитися на фотографіях з телефона оператора.

Головний принцип простий: найкращий датасет для вашої задачі — дані, максимально схожі на production. Якщо в проді — фото бланків з полів, тренувальна вибірка повинна складатися з таких же фото, а не з нормалізованих гліфів 28×28.

Перший етап OCR — не нейромережа

Типова помилка — одразу шукати «найкращу OCR-модель» і віддавати їй цілу фотографію. На структурованих бланках виграє інший порядок:

фотографія → виявлення бланка → корекція перспективи →
прив’язка до шаблону → виділення комірок → попередня обробка → OCR

Чому відомий шаблон — величезна перевага

Якщо форма бланка фіксована:

  • координати полів відомі заздалегідь або обчислюються після вирівнювання;
  • рядки й стовпці таблиці передбачувані;
  • не потрібно розпізнавати всю сторінку цілком.

Замість фотографія → велика OCR-модель → весь текст працює схема фотографія → geometry → cell → маленька OCR-модель. Кожна комірка — окремий вхід з маленьким алфавітом і обмеженою довжиною. Задача спрощується на порядок.

Це той самий інженерний прийом, що й у промисловому завантаженні документів: спочатку структура й канон, потім витяг сенсу. Для бланків «канон» — вирівняне зображення з вирізаними комірками.

OCR лише там, де він потрібен

Універсальний OCR по всій сторінці витрачає обчислення на заголовки, підписи, друкований текст і порожні поля. На фіксованому шаблоні розумніше:

  1. Знайти кути бланка (контури, маркери, QR).
  2. Застосувати гомографію — вирівняти перспективу.
  3. Накласти маску шаблону.
  4. Вирізати лише комірки з рукописними показниками.
  5. Запустити вузьку модель на кожній комірці.

Найцінніша частина — ground truth

Без чесної розмітки будь-який експеримент з архітектурами — порівняння шуму.

Звідки взяти правильні відповіді

У багатьох прикладних системах фотографія бланка вже пов’язана з записом у базі. Оператор сфотографував показання лічильника, а правильне значення лежить у таблиці readings. Або диспетчер ввів дані вручну після дзвінка — і фото слугує підтвердженням.

У такому разі розмітка не потребує армії розмітників. Потрібен конвеєр:

фотографія → ідентифікація бланка/сесії → запит у БД →
правильне значення поля → пара (cell image, label)

Приклади:

  • cell_00001.png → "78"
  • cell_00002.png → "73"
  • cell_00003.png → "71"

Чому це краще за ручну розмітку

  • Масштаб: тисячі прикладів збираються автоматично в міру роботи системи.
  • Менше помилок: людина не переписує цифри вручну в окремий файл.
  • Актуальність: датасет оновлюється разом із потоком документів.
  • Зв’язок із бізнес-контекстом: мітки відповідають тому, що система вважає істиною.

Застереження: ground truth з БД чесний лише якщо запис у базі дійсно вірний. Якщо оператори систематично помиляються при вводі, модель вивчить ті самі помилки.

Data leakage — тихий вбивця метрик

При розбитті train/validation/test не можна випадково змішувати:

  • різні кропи одного й того ж бланка;
  • фотографії однієї людини з майже ідентичним почерком;
  • серії знімків, зроблених в однакових умовах освітлення.

Випадкове перемішування комірок без групування завищує метрики. Групуйте за документом, автором, сесією зйомки або датою — залежно від того, що реально «нове» в production.

Підхід до оцінки якості ШІ-систем загалом — у матеріалі «Оцінка корпоративного ШІ»; для OCR критичні саме групові спліти та метрики на рівні послідовності.

Перша модель — CNN як baseline

Convolutional Neural Network — згорткова нейромережа. Для задачі «одна цифра в комірці» це природна відправна точка.

Як CNN бачить цифру

Ієрархія ознак типова:

  1. Нижні шари — краї, лінії, кути.
  2. Середні — фрагменти штрихів, дуги, перетини.
  3. Верхні — цілий гліф, схожий на клас.

Схема: зображення → згортки → пулінг → ознаки → повнозв’язний шар → 10 класів.

Чому CNN — хороший baseline

Критерій CNN
Розмір моделі Десятки–сотні КБ – кілька МБ
Час навчання Хвилини–години на GPU, години на CPU
Inference Мілісекунди на комірку
Відладка Confusion matrix, візуалізація помилок
Деплой Легко упакувати в ONNX, TFLite, edge

На першому експерименті виміряйте не лише accuracy, а й confusion matrix, час inference, розмір артефакта. Ці цифри стануть аргументом проти «давайте одразу TrOCR» на нараді.

Мінімальний експеримент

# Псевдокод: класифікатор 10 класів
model = Sequential([
    Conv2D(32, 3, activation='relu'),
    MaxPooling2D(),
    Conv2D(64, 3, activation='relu'),
    MaxPooling2D(),
    Flatten(),
    Dense(128, activation='relu'),
    Dense(10, activation='softmax'),
])
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

Для production додайте нормалізацію розміру комірки, інверсію при темному фоні та логування впевненості (softmax probability).

Кілька цифр в одній комірці

Комірка [ 78 ] ламає постановку «один клас на картинку». Наївний шлях:

78 → сегментація → 7 | 8 → два прогони CNN → "78"

Чому сегментація — окрема проблема

  • Цифри різного розміру в одній комірці.
  • Відстань між символами непостійна.
  • Символи торкаються або перекриваються.
  • Лінії таблиці проходять крізь штрихи.
  • Почерк не дотримується моноширинної сітки.

Кожен із цих факторів додає етап, який сам по собі потребує розмітки й метрик. Простіше запитати: чи можна розпізнати всю послідовність одразу? Тут з’являється CTC.

CTC: послідовність без посимвольної розмітки

Connectionist Temporal Classification вчить відповідність між зображенням і рядком без розмітки меж кожного символу. Достатньо пари ціла комірка → "783".

Інтуїція

Модель на кожному часовому кроці видає розподіл за символами плюс спеціальний токен blank (порожній крок). Декодер CTC згортає повтори й прибирає blank:

сирій вихід: 7 → 7 → blank → 8 → 8 → 8 → blank → 3
після CTC:   7 → 8 → 3

Вам не потрібно вручну малювати bounding box навколо кожної цифри.

Обмеження CTC

  • Послідовність зазвичай моделюється зліва направо (для цифр у комірці це частіше за все ок).
  • Двовимірна структура тексту CTC переносить гірше, ніж seq2seq з attention.
  • Довжина вхідної послідовності ознак повинна бути порівнянна з довжиною рядка — для коротких чисел у комірці обмеження рідко заважає.

CRNN — класичний робочий кін OCR

Convolutional Recurrent Neural Network об’єднує згортки, рекурентні шари й CTC:

image → CNN → feature map → sequence → BiLSTM → CTC → "783"

Навіщо RNN між CNN і CTC

Текст має порядок: 7 потім 8 потім 3. Feature map після CNN можна розрізати на смуги зліва направо; кожна смуга — крок часу. BiLSTM дивиться в обидва боки й уточнює, який символ ймовірний з урахуванням сусідів.

Плюси й мінуси

Плюси Мінуси
Компактна модель RNN повільніший за паралельні Transformer на довгих послідовностях
Добре вивчений, багато рецептів Складніше тюнити, ніж простий CNN
Працює на CPU для коротких рядків Гірше масштабується на вільний текст
Пряме навчання end-to-end з CTC Менш гнучкий при зміні алфавіту, ніж generative decoder

Для комірок із двома–п’ятьма цифрами CRNN + CTC залишається сильним вибором у 2026 році — особливо якщо важливі розмір моделі й inference на CPU.

TrOCR — коли в гру входить Transformer

TrOCR (Transformer-based OCR) — end-to-end модель: Vision Transformer кодує зображення, Transformer decoder генерує текст посимвольно.

image → ViT encoder → visual tokens → text decoder → "783"

CRNN проти TrOCR

CRNN + CTC TrOCR
Енкодер CNN Vision Transformer
Декодер CTC (вирівнювання) Autoregressive Transformer
Попереднє навчання Зазвичай з нуля на своїх даних Доступні ваги на друкованому/рукописному тексті
Розмір Малий–середній Small / Base / Large
Сильна сторона Короткі цифрові рядки Складний текст, змішаний алфавіт

Fine-tuning pretrained

Типовий рецепт: взяти microsoft/trocr-base-handwritten або аналог, дообучити на своїх комірках з цифрами. Pretrained знання про штрихи й криві переносяться; останні шари адаптуються до вашого домену — ліній таблиці, шуму камери, локального почерку.

Важливо: більше параметрів ≠ краще на вашій вибірці. Large-модель може переобучитися на тисячі комірок, тоді як Small дасть ту саму CER при inference у десять разів швидше.

Чому TrOCR може бути надлишковим

Головний тезис: якщо задача формулюється як image → "7" у відомій комірці з алфавітом із десяти цифр, повноцінний OCR-Transformer — стрілянина з гармати по горобцях.

TrOCR стає цікавішим, коли:

  • у комірці змінна довжина (7835, 12, 0);
  • алфавіт розширюється (літери, десяткова крапка, знак мінус);
  • якість зйомки сильно варіює і pretrained дає помітний перенос;
  • планується єдина модель на цифри й короткий текст у сусідніх полях.

Якщо ж:

  • шаблон фіксований;
  • алфавіт — лише 0–9;
  • довжина обмежена (наприклад, не більше п’яти символів);
  • область тексту вирізана геометрією,

то спеціалізована CRNN або навіть каскад CNN часто виграє за latency, вартістю й простотою супроводу.

Експеримент: CNN vs CRNN vs TrOCR на одному датасеті

Порівняння архітектур має сенс лише на однакових даних і з чесним сплітом.

Розбиття вибірки

Типове співвідношення: 70% train, 15% validation, 15% test — але всередині груп:

  • за document_id (усі комірки одного бланка — в одному спліті);
  • за author_id / оператором;
  • за серією бланків або датою зйомки.

Випадкове перемішування комірок без групування завищує метрики.

Метрики

Для однієї цифри (CNN):

  • Accuracy;
  • Precision / Recall за класами;
  • Confusion matrix.

Для послідовності (CRNN, TrOCR):

  • CER (Character Error Rate);
  • Exact Match Accuracy;
  • Sequence Accuracy.

Інженерні метрики (часто вирішують спір на проді):

Метрика Навіщо
Розмір моделі Деплой на edge, мобільний додаток
Час inference на CPU/GPU Пропускна здатність на зміну
VRAM / RAM Батч на сервері
Throughput Комірок на секунду на лінії
Час навчання Як швидко переобучити після зміни бланка

Зафіксуйте залізо й batch size в звіті — інакше порівняння безглузде.

Аналіз помилок важливіший за одну цифру accuracy

accuracy = 98.7% звучить добре, доки не відкриєте confusion matrix. Типові пари плутанини на рукописних цифрах:

  • 1 ↔ 7
  • 3 ↔ 8
  • 5 ↔ 6
  • 0 ↔ 6
  • 4 ↔ 9

Що дивитися крім матриці

  • Почерк: які оператори чи контрагенти дають гірший CER;
  • Інструмент письма: гелева ручка vs олівець;
  • Освітлення: відблиск на ламінованому бланку;
  • Розмір цифр: дрібний почерк у вузькій комірці;
  • Артефакти зйомки: змаз, обрізаний край комірки.

Зберіть папку hard examples — 50–200 комірок, де всі моделі помиляються. Дообучення на hard set або ручна перевірка цих кейсів часто дає більше, ніж зміна Large на Base.

Цикл покращення:

звичайні приклади → помилки на val → hard examples →
аугментація / дообучення / правила → повтор

Спостережуваність такого конвеєра — логування впевненості, збереження кропів з низьким score, дашборд CER за полем і оператором — перетинається з практиками з AI observability.

Data augmentation: імітація камери, не фантазія

Аугментація допомагає при нестачі даних, якщо вона імітує реальні умови зйомки:

  • невеликий поворот і зсув;
  • масштаб;
  • зміна контрасту й яскравості;
  • гаусів шум;
  • легке розмиття;
  • невелика перспективна деформація;
  • випадкова обрізка зі збереженням цифри в кадрі.

Погана аугментація — та, якої немає в production: екстремальні спотворення, інверсія кольору без сенсу, накладання випадкових ліній не там, де бувають лінії таблиці.

Якщо лінії таблиці — головне джерело помилок, краще прибрати їх на етапі попередньої обробки (морфологія, кольорова маска, inpainting ліній), ніж сподіватися, що модель «звикне».

Semi-supervised learning і human-in-the-loop

Коли baseline уже працює, можна замкнути цикл:

впевнене розпізнавання → pseudo-label → нові training samples → переобучення

Confidence threshold

Якщо confidence > threshold (наприклад, 0.95 для CNN або низький CER beam search для CRNN), приклад додається в пул із псевдорозміткою. Нижче порогу — в чергу людині.

Human-in-the-loop

model → confidence → high: accept / low: human review → БД

Це знижує вартість розмітки й не дає моделі тихо деградувати: частка ручних перевірок — метрика здоров’я системи.

Обережно з feedback loop: якщо модель систематично плутає 5 і 6, псевдорозмітка посилить помилку. Періодично підмішуйте верифіковані людиною приклади й моніторьте confusion matrix на свіжому потоці.

Production pipeline: більше, ніж нейромережа

Підсумковий ланцюжок для структурованого бланка:

photograph → document detection → perspective correction →
template alignment → cell extraction → preprocessing →
OCR model → confidence → validation rules → database

Де працюють детерміновані правила

Нейромережа не повинна вирішувати те, що задано бізнес-логікою:

  • поле допускає лише цифри;
  • значення в діапазоні 0–100;
  • фіксована кількість знаків (наприклад, показання лічильника — рівно п’ять цифр);
  • контрольна сума або повторне читання сусіднього поля.

Якщо OCR повернув 783 для поля з максимумом 100, правило відхиляє результат незалежно від softmax.

Каскад моделей

Не обов’язково обирати одну архітектуру:

швидкий CNN → впевнений? → accept
              ↓ ні
         CRNN або TrOCR → впевнений? → accept
              ↓ ні
         human review

Чому це часто краще за одну велику модель:

  • дешевше в середньому на комірку;
  • швидше на «легких» прикладах;
  • простіше масштабувати навантаження;
  • складні випадки отримують більше обчислень, а не всі підряд.

Що обрати для реальної системи

Задача Рекомендація
Одна цифра в комірці CNN
Кілька цифр, свій датасет CRNN + CTC
Змішаний текст, розширення алфавіту TrOCR fine-tune
Фіксований бланк Geometry + вузька модель на комірку

Архітектурна карта:

ОДНА ЦИФРА          → CNN
КІЛЬКА ЦИФР          → CRNN + CTC
СКЛАДНИЙ ТЕКСТ       → TrOCR
СТРУКТУРОВАНИЙ       → Document AI + geometry + OCR на комірках
ДОКУМЕНТ

Що ця задача каже про вибір нейромереж

Не починайте з питання «яка зараз найпотужніша модель?». Починайте з «яка структура моєї задачі?»

  • 10 класів, одна цифра — не потрібен generative OCR.
  • Послідовність символів без посимвольних box — CTC / CRNN.
  • Складний текст і перенос pretrained — Transformer-моделі на кшталт TrOCR.
  • Відомий шаблон — Document AI на рівні геометрії знімає половину ML-складності.

Архітектура повинна слідувати структурі інформації, а не популярності моделі в стрічці.

Що зробити сьогодні

  1. Зафіксуйте постановку: одна цифра чи рядок? Яка максимальна довжина?
  2. Намалюйте пайплайн до ML: вирівнювання бланка й нарізка комірок у пріоритеті.
  3. Перевірте джерело розмітки: чи можна пов’язати фото з БД?
  4. Навчіть CNN baseline і збережіть confusion matrix.
  5. Якщо в комірці кілька цифр — CRNN + CTC на тих самих кропах.
  6. Порівняйте з TrOCR Small лише після чесного спліту за документами.
  7. Введіть поріг впевненості і чергу ручної перевірки до «повного автомата».

FAQ

Чи можна почати з готового Tesseract?

Так, як з дуже грубого baseline на вирізаних комірках. Tesseract розрахований на рядки тексту; на окремих рукописних цифрах у комірці з лініями сітки часто програє маленькій CNN. Має сенс для швидкої перевірки «чи є сигнал у даних», але рідко як фінальне рішення для польових бланків.

Скільки даних потрібно для CNN?

Порядок величини: від кількох сотень прикладів на клас для простого домену до кількох тисяч, якщо почерк сильно різнорідний. Без аугментації й без групового val/test цифри будуть оманливими.

Чи працює CTC для порожньої комірки?

Потрібен явний клас «порожньо» або окремий детектор порожнечі до OCR. Інакше модель буде «галюцинувати» цифри на шумі й лініях таблиці.

TrOCR Base чи Small для тисячі комірок?

Почніть зі Small: швидші ітерації, менший ризик переобучення. Base має сенс, якщо Small упирається в CER на validation, а не на train.

Як пов’язати OCR з ERP?

Після валідації поля пишіть в API ERP або в проміжну чергу з ідемпотентним ключем document_id + field_id. Патерни інтеграції — у ERP integration.

Чи потрібен GPU в production?

Для CNN на одній комірці — часто ні, CPU вистачає. Для батча TrOCR на сервері — бажано. Каскад «CNN на CPU → TrOCR на GPU для складних» — типовий компроміс.

Як не змішати train і test одного бланка?

Зберігайте document_id в метаданих кожного кропа й використовуйте GroupKFold або явний спліт за списком документів. Будь-який випадковий train_test_split без груп — червоний прапорець.

Що робити, якщо accuracy висока, а користувачі скаржаться?

Дивіться помилки на репрезентативному тесті (нові люди, нові умови зйомки), а не на випадкових кропах. Висока accuracy на «легкому» тесті при поганому досвіді в полі — класичний симптом leakage або зміщеної вибірки.