Эта система распознавания текста — небольшое введение в создание современных систем распознавания текста при помощи глубокого обучения. Вы узнаете о том, как использовать Keras и Supervisely для создания платформы. Этот гид предназначен для всех, кто заинтересован в применении глубокого обучения для распознавания текста, для всех, кто не знает, с чего начать.
Мы рассмотрим простой пример реального мира: распознавание номерных знаков. Это хорошая начальная точка, и вы можете легко подстроить полученное решение для своей задачи. Простой туториал о том, как обнаруживать номерные знаки, вы можете найти здесь.
Когда мы вступили в эту область, мы столкнулись с недостатком материалов в Интернете. Благодаря долгому исследованию и чтению многих статей мы поняли основные принципы создания эффективных систем распознавания. И поделились своими знаниями с сообществом в двух небольших видео-лекциях (часть 1 и часть 2) — объяснили, как это работает понятным языком. Мы считаем, что этот контент чрезвычайно ценен, потому что невозможно найти хорошее и простое объяснение того, как создавать современные системы распознавания. Мы настоятельно рекомендуем посмотреть эти видео перед тем, как вы начнете чтение, потому что они дадут вам много знаний по предметной области.
Чтобы пройти это обучение без проблем, вам понадобятся Ubuntu, GPU и Docker. Все источники доступны на GitHub, а исходный код с комментариями и визуализацией можно найти здесь.
Система распознавания текста: где взять данные для обучения?
Для этого туториала мы создали искусственный набор данных с более чем 10 тысячами изображений, которые очень похожи на настоящие номера. Изображения выглядят так.
Вы можете получить этот набор на Supervisely. В DeepSystems мы разрабатываем множество решений, связанных с компьютерным зрением, например, беспилотные автомобили, систему распознавания квитанций, обнаружение дефектов на дорогах и т.д. Мы, как специалисты по данным, тратим много времени на работу с данными для обучения: создание аннотаций изображений, объединение наших данных с общедоступными наборами данных, дополнение данных и т. д. Supervisely упрощает работу с обучающими данными и автоматизирует многие рутинные задачи. Мы считаем, что сервис будет полезен в вашей повседневной работе.
Первый шаг — регистрация в Supervisely. Следующий — вкладка Import -> Datasets library, нажмите на проект “anpr_ocr”.
Затем введите название “anpr_ocr” и нажмите Next.
Затем нажмите кнопку Upload. Это все. Теперь проект «anpr_ocr» добавлен в ваш аккаунт.
Он состоит из двух наборов данных: train и test.
Если вы хотите просмотреть изображения, просто нажмите на набор данных, и вы сразу попадете в инструмент аннотации. Для каждого изображения у нас есть текстовое описание, которое будет использоваться в качестве эталона для обучения нашей системы. Чтобы просмотреть его, просто нажмите на маленькую иконку напротив выбранного изображения (выделено красным).
Теперь мы должны загрузить его в определенном формате. Для этого просто перейдите на страницу Export и вставьте эту конфигурацию в текстовую область. Это будет выглядеть так.
На скриншоте выше вы можете увидеть схему, иллюстрирующую шаги экспорта. Мы не будем вникать в технические детали (вы можете прочитать документацию, если это необходимо), но попробуем объяснить этот процесс ниже. В нашем проекте “anpr_ocr” у нас есть два набора данных. База данных test экспортируется как есть. Набор данных train разделен на два набора: train и val. Случайные 95 процентов изображений будут добавлены в набор train, а остальные 5 процентов — в val.
Теперь вы можете нажать кнопку Start exporting и подождать две минуты, пока система готовит архив для загрузки. Нажмите Export -> Task status -> Три вертикальные точки -> Download, чтобы получить данные обучения (отмечены красным цветом).
Начнем эксперимент
Мы подготовили все нужное в нашем репозитории. Скопируйте его со следующими командами.
git clone https://github.com/DeepSystems/supervisely-tutorials.git cd supervisely-tutorials/anpr_ocr
Структура директория будет такой.
. ├── data ├── docker │ ├── build.sh │ ├── Dockerfile │ └── run.sh └── src ├── architecture.png ├── export_config.json └── image_ocr.ipynb
Поместите скачанный архив в директорий data и запустите указанную ниже команду:
unzip <archive name>.zip -d .
В моем случае команда была такой:
unzip test1–1703.zip -d .
Теперь давайте создадим и запустим контейнер докеров с подготовленной рабочей средой (tensorflow и keras). Просто зайдите в каталог Docker и выполните следующие команды:
./build.sh ./run.sh
После этого вы попадете в контейнер. Запустите следующую команду, чтобы запустить блокнот Jupyter.
jupyter notebook
В терминале вы увидите нечто подобное:
Вам нужно скопировать выбранную ссылку и вставить её в браузер. Ваша ссылка будет немного отличаться от моей.
Последний шаг — запустить блокнот “image_ocr.ipynb”. Нажмите Cell -> Run all.
Блокнот состоит из нескольких основных частей: загрузка и визуализация данных, обучение модели, оценка модели на тестовом наборе. В среднем для этого набора данных процесс обучения занимает около 30 минут.
Если все будет в порядке, вы увидите следующий результат.
Как вы можете видеть, предсказанная строка будет такой же, как и истина. Таким образом, мы создали современную OCR-систему в одном довольно простом блокноте jupyther. Наша система распознавания текста работает! В следующей главе этого урока мы рассмотрим и объясним все основные принципы работы.
Как это работает
Что касается нас, то понимание архитектуры нейронной сети является ключевым. Пожалуйста, потратьте 15 минут, чтобы посмотреть нашу небольшую и простую видеолекцию с кратким обзором архитектуры нейронных сетей, о которой упоминалось в начале. Это даст вам общее понимание.
Здесь я попытаюсь дать вам краткое объяснение.
Во-первых, изображение загружается в сверточную нейронную сеть для извлечения функций изображения. Следующим шагом будет применение рекуррентной нейронной сети для этих функций, за которой следует специальный алгоритм декодирования. Этот алгоритм декодирования принимает lstm выходы с каждого временного шага и производит окончательную маркировку.
Далее показана подробная архитектура. FC — полностью подключенный слой, SM — слой softmax.
Изображение имеет следующие размеры: высота равна 64, ширина равна 128 и количество каналов равно трем.
Как вы видели раньше, мы подаем этот тензор изображения на экстрактор признаков сверточной нейронной сети, и он создает тензор с размерами 4*8*4. Мы помещаем изображение apple в тензор объектов, чтобы вы могли понять, как его интерпретировать. Высота равна 4, ширина равна 8 (это пространственные размеры), а число каналов равно 4. Таким образом, мы преобразуем входное изображение с 3-мя каналами в 4-канальный тензор. На практике количество каналов должно быть намного больше, но мы построили небольшую демонстрационную сеть, чтобы все поместилось на слайде.
Затем мы переформируем операцию. После этого мы получаем последовательность из 8 векторов из 16 элементов. После этого мы подаем эти 8 векторов в сеть LSTM и получим ее выход — также векторы из 16 элементов. Затем мы применяем полностью связанный слой, за которым следует слой softmax, и получаем вектор из 6 элементов. Этот вектор содержит распределение вероятностей распознавания символов алфавита на каждом шаге LSTM.
На практике число выходных векторов нейронной сети может достигать 32, 64 или более. Выбор будет зависеть от конкретной задачи. Также в производстве лучше использовать многослойную двунаправленную LSTM. Но этот простой пример объясняет только самые важные понятия.
Но как работает алгоритм декодирования? На приведенной выше диаграмме мы имеем восемь векторов вероятностей на каждом шаге времени LSTM. Возьмем наиболее вероятный символ на каждом временном шаге. В результате мы получаем строку из восьми символов — одну наиболее вероятную букву на каждом временном шаге. Затем мы должны склеить все последовательные повторяющиеся символы в один. В нашем примере две буквы «e» приклеены к одной. Специальный пустой символ позволяет нам разделить знаки, которые повторяются в оригинальной маркировке. Мы добавили пустой символ в алфавит, чтобы научить нашу нейронную сеть предсказать пробел между такими символами. Затем мы удалим все пустые символы. Посмотрите на иллюстрацию ниже.
Когда мы тренируем нашу сеть, мы заменяем алгоритм декодирования слоем CTC-Loss. Это объясняется в нашей второй видеолекции.
В нашей реализации система распознавания текста использует немногим более сложную архитектуру нейронной сети, но основные принципы здесь все те же.
После обучения модели мы применяем ее на изображениях из тестового набора и получаем очень высокую точность. Мы также визуализируем распределения вероятностей с каждого шага рекуррентной нейронной сети в виде матрицы. Вот пример.
Строки этой матрицы соответствуют всем символам алфавита и пробелу. Столбцы соответствуют шагам нейронной сети.
Заключение
Мы рады поделиться своим опытом с сообществом. Мы считаем, что видеолекции, этот туториал, готовые к использованию искусственные данные и исходный код помогут вам создать современную систему распознавания с нуля.