Ended 6 months ago

Заключительный этап профиля “Искусственный интеллект” НТО

Распознайте рукописный текст на фото

Задача

Вам нужно разработать алгоритм, который способен распознать рукописный текст в школьных тетрадях. В качестве входных данных вам будут предоставлены фотографии целых листов. Предсказание модели — список распознанных строк с координатами полигонов и получившимся текстом.

Несмотря на схожесть задачи заключительного этапа с образовательным хакатоном, в котором вы могли принимать участие в феврале, вас ждет пара усложнений: 

  1. Вас ждет намного больше уникальных стилей в тестовых датасетах, соответственно задача усложняется - придумайте модель, которая способна приспособиться к абсолютно любому почерку в школьных тетрадях!
  2. В выборку добавлен английский язык, так что теперь ваша модель должна быть билингвальной.

Мы видим итоговый алгоритм как последовательность двух моделей: сегментации и распознавания. Сначала сегментационная модель предсказывает полигоны маски каждого слова на фото. Затем эти слова вырезаются из изображения по контуру маски (получаются кропы на каждое слово) и подаются в модель распознавания. В итоге получается список распознанных слов с их координатами.

При работе с предоставленными данными поcтарайтесь глубже погрузиться в них и попробовать различные аугментации. Но самое главное: подружите вместе две отдельных модели сегментации и распознавания, для получения качественной и эффективной общей системы.

Материалы, которые могут помочь справиться с задачей: 

Формат решений

В проверяющую систему необходимо отправить код алгоритма, запакованный в ZIP-архив. Решения запускаются в изолированном окружении при помощи Docker. Время и ресурсы во время тестирования ограничены.
В корне архива обязательно должен быть файл metadata.json со структурой:

{
    "image": "<docker image>",
    "entry_point": "<entry point or sh script>"
}

Например:

{
    "image": "skalinin1/baseline-ocr-segm:latest",
    "entry_point": "python run.py"
}

Здесь image – поле с названием docker-образа, в котором будет запускаться решение, entry_point – команда, при помощи которой запускается скрипт инференса. Решение запускается в Docker контейнере. Вы можете воспользоваться готовым образом "skalinin1/baseline-ocr-segm:latest" (создан на основе Dockerfile и requirements.txt, которые находятся в репозитории). При желании вы можете использовать свой образ, выложив его на https://hub.docker.com.

Структура данных

В контейнер помещается папка images, в которой находятся изображения, на которых необходимо сделать предсказания. Модель должна сформировать файл предсказания формата json, который содержит предсказания для каждого изображения из папки images. Пример содержимого json файла, который должен быть сгенерирован:

{
"img_0.jpg": {
        "predictions": [
            {
                "polygon": [
                    [0, 0],
                    [0, 1],
                    [1, 0],
                    [1, 1]
                ],
                "text": "test"
            }
        ]
    }
    "img_1.jpg": {
    "predictions": [
    ...
    ]
    }
}

Пути к данным для изображений (полный путь к папке images) и путь, куда необходимо сохранить результат (файл формата .json) передаются как первые два аргумента при запуске вашего решения. Их можно считать с помощью sys.argv[1:].

Пример решения
Вам доступен архив sample_submission.zip, в котором содержатся примеры загружаемого решения. В архиве вы найдете следующие файлы:
По данной ссылке находится архив sample_submission.zip, в котором содержатся примеры загружаемого решения. Следующие файлы в загружаемом архиве необходимы для формирования предсказаний модели:

  • metadata.json - обязательный файл для каждого решения; в нём должны быть указаны пути к образу и скрипту выполнения модели
  • run.py - основной скрипт для инференса модели
  • segm-model_final.pth и ocr-model-last.ckpt - веса моделей сегментации и OCR, которые подгружаются во время исполнения скрипта run.py

Для корректной проверки ваш сабмит должен иметь аналогичную структуру.

Доступные ресурсы:
8 ядер CPU
48Gb RAM
Видеокарта NVidia Tesla V100

Ограничения:
5Gb на архив с решением
25 минут на работу решения

Метрика

Метрика качества оценки решений определена в скрипте evaluate.py и представляет собой расчет CER для OCR-модели из пайплайна.

Так как текст распознается на предсказанных моделью полигонах, чтобы понять с каким текстом сравнивать предсказанный моделью, нужно соотнести предсказанные полигоны с ground truth полигонами.

Скрипт evaluate.py для каждого gt-полигона из тетради ищет соответствующий ему предсказанный полигон. Из предсказанных полигонов выбирается тот, который имеет наибольшее пересечение по IoU с gt-полигоном (при этом IoU должно быть больше нуля). Таким образом gt-текст из данного полигона соотносится с предсказанным текстом. Это true positive предсказания.

False negative случаи: если для gt-полигона не был сопоставлен предсказанный полигон, то предсказанный текст для такого полигона устанавливается как пустой "" (т.к. пайплайн не предсказал текст там, где он должен быть).

Для всех false positive предсказанных полигонов (т.е. тех, для которых отсутствуют gt-полигоны) gt-текст устанавливается как пустой "" (т.к. пайплайн предсказал текст там, где его нет).

CER считается по следующей формуле:

$$CER = \frac{\sum\limits_{i=1}^n dist_c (pred_i, true_i)}{\sum\limits_{i=1}^n len_c (true_i)}$$

Здесь $dist_c$ - это расстояние Левенштейна, посчитанное для токенов-символов (включая пробелы), $len_c$ - длина строки в символах.
Метрика CER изменяется от 0 до 1, где 0 – наилучшее значение, 1 - наихудшее.

IoU – это метрика, которая оценивает степень пересечения между двумя масками (предсказанной и правильной). Она вычисляется как отношение площади пересечения к площади объединения этих двух масок:
$$IoU = \frac{Intersection}{Union}$$

Baseline

Вам доступно базовое решение от разработчиков задачи. 
В файле baseline.ipynb представлен подход разработчиков задачи к объединению моделей сегментации и распознавания текста. Данный алгоритм не содержит обучение, только объединение 2 уже обученных моделей. Для запуска бейзлайна скачайте данные для обучения, должна получиться следующая структура:

  • baseline.ipynb (основной бейзлайн для текущего хакатона - объединение двух моделей)
  • segm-model_final.pth (веса модели сегментации)
  • ocr-model-last.ckpt (веса модели детекции)
  • baseline_segmentation.ipynb (бейзлайн из 1-ой части олимпиады)
  • baseline_recognition.ipynb (бейзлайн из 2-ой части олимпиады)
  • train_segmentation
    • images
    • annotations.json
    • annotations_extended.json
    • binary.npz
  • train_recognition
    • images
    • labels.csv

Файл baseline_segmentation.ipynb содержит базовое решение для модели сегментации текста. Для запуска модели скачайте данные для обучения и положите их в папку train_segmentation. 
Файл baseline_recognition.ipynb содержит базовое решение для модели распознавания текста. Для запуска модели скачайте данные для обучения и положите их в папку train_recognition.