Skip to content

Latest commit

 

History

History
144 lines (95 loc) · 5.67 KB

File metadata and controls

144 lines (95 loc) · 5.67 KB

DigitOCR

Небольшой OCR-проект на C++ для распознавания рукописных цифр.

Идея проекта была не только в том, чтобы получить рабочий классификатор на MNIST, но и в том, чтобы пройти несколько уровней реализации: от простого baseline'а до своей нейросети и более быстрой, уже более практичной версии MLP.

Сейчас проект состоит из нескольких baseline'ов, каждый из которых решает свою задачу:

  • KNN — как простой и сильный baseline;
  • scalar neural network + autodiff — как educational-реализация, чтобы понять backprop изнутри;
  • fast MLP — как более практичная и быстрая нейросеть.

Что есть в проекте

  • загрузка MNIST;
  • чтение BMP-изображений;
  • preprocessing для реальных картинок;
  • handcrafted features для классической модели;
  • несколько baseline'ов;
  • логирование и сравнение результатов экспериментов.

Baselines

1. KNN

Первый и самый простой baseline.

Для KNN используются признаки, собранные из:

  • raw pixels;
  • zoning features;
  • projection features.

Зачем это полезно:

  • чистая точка отсчёта;
  • быстрый способ проверить pipeline;
  • baseline, с которым можно сравнивать нейросети.

По текущим экспериментам KNN показывает очень хорошую accuracy и остаётся сильным ориентиром для остальных моделей.


2. Scalar NN + autodiff

Это более учебная часть проекта.

Здесь цель была не в скорости, а в том, чтобы руками пройти весь путь:

  • вычислительный граф;
  • forward pass;
  • backward pass;
  • градиенты;
  • обновление параметров.

Эта реализация не самая быстрая и не самая практичная, но хорошо показывает, что происходят внутри NN и backpropagation.

Её главный минус — производительность. На реальном обучении быстро становится видно, что scalar-граф и большое количество мелких операций создают слишком большой overhead по времени и памяти.


3. Fast MLP

Более практичный neural baseline.

Здесь используется более прямой и быстрый подход:

  • плотные массивы (2D to 1D);
  • mini-batch training;
  • ручной forward/backward для dense-слоёв;
  • без scalar tape на каждую операцию.

Текущие результаты

KNN

На последних прогонах KNN показывал около 96.8% accuracy на evaluation по 500 test samples.

Для baseline без нейросети это очень сильный результат.

Fast MLP

Первые рабочие запуски fast MLP выглядели так:

  • trainLimit=2000, testLimit=500, lr=0.05, batch=64, epochs=5
    71.8%

После этого начался более полноценный подбор гиперпараметров.

Лучшие результаты из текущих экспериментов:

trainLimit testLimit lr batch epochs accuracy
5000 500 0.02 64 10 86.6%
5000 500 0.01 64 10 86.8%
5000 500 0.03 64 10 93.0%
5000 500 0.02 128 20 91.2%
5000 500 0.04 128 10 91.6%
5000 500 0.02 32 10 92.4%

Пока это ещё не финальные результаты на полном test set, а промежуточные результаты для подбора hyperparameters.


Что уже удалось понять по экспериментам

  • fast MLP действительно работает и обучается корректно;
  • batch size сильно влияет на поведение модели;
  • слишком большой batch при фиксированном числе эпох делает меньше gradient descent update steps и может обучаться хуже;
  • диапазон batch = 32..64 и lr ≈ 0.02..0.03 пока выглядит наиболее promising.

Сейчас лучший найденный setup для fast MLP — lr=0.03, batch=64, epochs=10.


Структура проекта

  • app/ — CLI и общий orchestration-код;
  • core/ — базовые структуры, например ImageMatrix;
  • data/ — загрузка MNIST;
  • io/ — чтение и запись BMP;
  • preprocess/ — preprocessing и выделение цифр;
  • baselines/knn/ — KNN и handcrafted features;
  • baselines/neural_network/ — scalar/autodiff NN;
  • baselines/nn_mlp_fast/ — fast MLP;
  • test/ — тесты и проверки.

Сборка

cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j
./build/ocr_engine

or

make clean-run