Введение
Как-то я столкнулся с довольно тривиальной, но новой для себя задачей - оптического распознавания символов (OCR). Так сложилось, что готовые инструменты (типа tesseract-ocr) мне не подошли, поэтому пришлось изобретать велосипед. Но к этому процессу я решил подойти со всей отвественностью: проверить несколько подходов, определить их примущества, недостатки и выбрать наиболее подходящий для конкретной задачи. По итогу это мини-исследование вылилось в данную обзорную статью. Здесь я хочу привести примеры нейросетевых моделей, характерных для различных этапов становления области компьютерного зрения (далее - CV) в том виде, в котором мы его знаем сейчас. Итак, начнём...
Постановка задачи
Подготовка данных
Довольно актуальной является задача получения текста с фотографии или скана документа. Самым простым способом является разбиение текста на отдельные буквы с дальнейшим распознавание каждой буквы по отдельности.
Таким образом, сравнивать модели будем в контексте задачи классификации изображения.
Датасет для обучения генерировался на основании написания русских букв 11-ю шрифтами:
К каждой букве применялись аугментации из следующего списка:
Зеркальное отображение (по вертикали и/или горизонтали)
Размытие
Поворот на случайный угол (до 15 градусов) по или против часовой стрелки
Каждая аугментация применялась к изображению со своим шансом. При этом сохранялись все изображения: исходные и после каждой аугментации. После этого к некоторым из них применялось зашумление.
Условия сравнения
Сравнивать модели будем по следующим параметрам:
Точность (CategoricalAccuracy) - процент “угаданных“ букв;
Значение функции потерь (CategoricalCrossentropy) - не всегда информативный параметр, но при равных точностях может дать дополнительную информацию;
Число параметров и скорость работы - для обработки текста по букве крайне важно, чтобы модель была небольшой и работала быстро;
Время обучения и вес модели - чисто прикладные характеристики. Наиболее полезны будут, если кто-то захочит повторить этот эксперимент.
Эксперимент
Выбор конкурсантов
Для эксперимента я отобрал 5 моделей:
Простая свёрточная нейросеть;
VGG-16;
DenseNet;
Vision Transformer (ViT)
SWin
По моему мнению, такой выбор довольно репрезентативен. Если у читателя на этот счёт другое мнение - прошу им поделиться.
Непосредственно классифицирующая часть у всех моделей имеет одинаковое строение. Также для ускорения процесса обучения было использовано 2 колбека:
ReduceLROnPlateau - уменьшение learning rate если длительное время нет улучшения целевой метрики.
EarlyStopping - если длительное время целевая метррика не растёт, то обучение прекращается.
В качестве целевой метрики в обоих случаях было значение функции потерь на валидационных данных (val_loss)
Всё было написано с помощью библиотеки keras, которая с недавнего времени совместима как с tensorflow, так и с pytorch. Для детального ознакомления код и данные доступны в репозитории.
Модели будем обозревать в логико-хронологическом порядке. Что это такое - поймёте сразу.
Convolution Neural Network (CNN)
Для начала разберёмся с базовым подходом. Свёрточные нейросети изначально разрабатывались для классификации изображений, поэтому использование свёрточной архитектуры напрашивается в первую очередь.
Эксперименты показали, что самым оптимальным решением с точки зрения соотношения скорости обучения и финальной точности является использование трёх свёрточных слоёв. Структура модели приведена на рисунке.
Значения метрик для этой и прочих моделей будут приведены в конце, а здесь отмечу, что по сравнению с конкурентами эта модель обучалась довольно быстро. Также к преимуществам можно отнести семантическую простоту (для понимания принципа работы эта архитектура самая простая). Однако существенным недостатком является её размер. Обученная модель весит более 100 Мб, что в разы больше, чем у конкурентов.
Принцип работы свёрточной сети заключается в том, что свёрточные слои выделяют из изображения определённые признаки, формируя новое изображение - "карту признаков" - из которого в дальнейшем также можно извлечь признаки. В конце для классификации все эти признаки, выделенные из признаков, выделенные из... и. д. подаются на вход обычного многослойного перцепртона (MLP), который в данном случае является классификатором.
Таким образом, качество классификации изображения свёрточной (да и, в принципе, любой другой) нейросетью определяется двумя вещами: качеством выделения признаков и качеством классификатора. Если с классификатором всё понятно: всё, что нужно, это перебрать различные числа слоёв и нейронов и выбрать те, которые дадут самую высокую точность, то с выделением признаков не всё так просто. Логическим продолжением идей простой свёрточной нейросети стало появление более сложных моделей, способных выделять более мелкие, сложные или неочевидные признаки.
VGG-16
Схематически структуру этой модели традиционно изображают так:
В ней свёрточные слои (чёрные) извлекают признаки, а операция "max pooling" отбирает из них наиболее значимые. И так 5 раз. Затем идёт уже знакомый нам MLP-классификатор.
Как можно заметить, авторы решили пойти по пути увеличения числа слоёв. Действительно, это одна из первых мыслей, которая приходит в голову, когда ты остаёшься недоволен своей свёрточной нейросетью. Однако, в представленной модели имеют место целых 16 (что и отражено в названии) слоёв, 12 из которых - свёрточные. Используйся эти слои без каких-либо ухищрений (что, конечно же не так), это привело бы к просто непомерной "тяжести" модели.
К счастью, ухищрения, всё-таки, присутствуют. Здесь используется конструкция из нескольких свёрточных слоёв подряд. Это позволяет охватывать большую область для определения признаков, не слишком сильно увеличивая число обучаемых и хранимых весов.
Возвращаясь к нашей задаче, эта (и следующая) модель были использованны в предобученном виде. Т.е. оставалось только обучить классификатор. В конечном счёте эта модель показала достойную точность при меньшем, чем у простой свёрточной, объёме занимаемой памяти. Однако, в скорости она уступила.
Увеличивать число слоёв свёрточных моделей до бесконечности нельзя. Точнее, конечно, можно, но рано или поздно пришлось бы для обучения таких моделей использовать квантовые суперкомпьютеры. Поэтому, в развитии свёрточных архитектур следующим шагом стала передача признаков с одного слоя на другой минуя промежуточные.
DenseNet
Характерным примером модели-классификатора, использующей этот приём (т.н. "skip connection") является DenseNet:
Как видно из иллюстрации, модель состоит из нескольких блоков и информация передаётся от предыдущего к последующему двумя путями: через все промежуточные блоки и напрямую - минуя их.
Модель довольно громоздкая и расчитана на задачи куда сложнее, чем опредение буквы на чёрно-белой картинке, поэтому в эксперименте выдающихся результатов не показала. Но всё же модель гораздо больше всех своих конкурентов и гораздо медленнее VGG-16.
Свёрточные архитектуры продолжают развиваться до сих пор и всё ещё являются отличными классификаторами (занимая первое место на соревнованиях по типу ImageNet) , но среди многих из них прослеживается общая тенденция: не слишком впечатляющая скорость работы и огромные размеры. Это и стало причиной появления принципиально нового подхода.
Vision Transformer (ViT)
Как это часто случается в науке, прорыв произошёл благодаря тому, что кто-то обратил внимание на разработки коллег в другой области. В данном случае - области обработки естественного языка. А именно, вдохновением послужила модель Transformer. Эта модель представляет собой автоэнкодер с добавлением механизма внимания.
Визуальный трансформер - это адаптация традиционно языковой архитектуры для задач компьютерного зрения. В оригинальной статье предлагается разделять картинку на фрагменты, затем генерировать для них позиционное кодирование и обрабатывать это всё как последовательность. Т.к. в нашем случае картинки довольно маленькие, то было решено упростить архитектуру до предела: отбросить позиционное кодирование и подавать на вход никак не изменённую картинку:
Внутри для более качественного извлечения признаков стоит сразу 4 слоя TransformerEncoder. Такая архитектура не уступает свёрточной по скорости обучения, но сильно выигрывает в размере. Правда, скорость обработки у неё пониже.
Модели на базе визуальных трансофрмеров сразу же стали активно развиваться. Одним из наследников стала модель с забавным для русскоговорящео человека названием SWin.
Vision Transformer using Shifted Windows (SWin):
Swin - это одна из самых совершенных архитектур на базе трансформеров. У неё есть 2 главных улучшения по сравнению с оригинальным ViT:
Иерархическая структура. Он разбивает изображение не на фрагменты одного размера, как это делает базовый ViT, а сначала крупные, затем эти крупные фрагменты разбивает на фрагменты помельче и т.д.
Матрицы внимания вычисляются 2 раза: для разбитой картинки и для такой же картинки, разбитой на фрагменты такого же размера, но со смещением
На самом деле усовершенствований там довольно много. Есть статья, в которой это всё разобрано.
В нашем случае, опять же, сильно усложнять нужды нет. Поэтому упрощаем. В данном случае код практически без изменений был скопирован с официальной документации.
Swin на голову опережает CNN и ViT по всем параметрам, кроме одного: скорости обучения. И точность у него примерно такая же, как и у всех остальных. Обучается он в 5-10 раз дольше и на первых эпохах обучения значения метрик у него крайне низкие (после 5 эпохи точность у него была около 50% при том, что ViT к этому моменту уже преодолел порог точности на обучающей выборке в 95%).
Эта архитектура показала отличную точность классификации, обойдя все "трансформерные" модели и практически все свёрточные на ImageNet в момент выхода, чем по праву заслужила внимание, уделённое ей. Она получила улучшение в виде модели SWin-2 в апреле 2022 года и духовного преемника в виде NAT - в мае 2023.
Итоги соревнования
Численные сравнения приведены ниже. Жирным шрифтом выделены лучшие результаты по каждому критерию
CNN | VGG16* | DenseNet* | ViT | SWin | |
---|---|---|---|---|---|
categorical_accuracy | 0.9864 | 0.9593 | 0.8482 | 0.9917 | 0.9242 |
loss (categorical crossentropy) | 0.0504 | 0.4027 | 0.9709 | 0.0386 | 1.1309 |
число обучаемых весов | 10 530 849 | 1 189 921 | 2 762 785 | 1 993 793 | 946 289 |
вес модели, Мб | 126,4 | 73,2 | 268,4 | 24,1 | 11,5 |
время обучения**, с | 160 | 114 | 400 | 110 | ~3300 |
скорость обработки изображений, FPS | 5 333 | 4 571 | 2 156 | 2 000 | 16 000 |
*модели были взяты с весами ImageNet согласно официальной документации keras
**обучение проводилось на видеокарте NVidia 4060 для ноутбуков.
Если обобщать, то в задаче оптического распознавания символов есть смысл использовать архитектуру на базе SWin, однако, стоит учитывать, что более сложные модели требуют гораздо больше времени и данных для обучения. В случае, если датасет небольшой и расширению поддаётся плохо, неплохо себя показывает базовая модель ViT, а если добавить позиционное кодирование, то точность можно повысить ещё больше.
Полезные ссылки
Документация Keras (примеры кода, инструкции по применению и объяснения)
keras-nlp - библиотека со всякими штуками для обработки естественного языка(устанвливается отдельно)
Пример с использованием трансформера в задаче компьютерного зрения
Статьи на хабре
Официальные публикации крутых дядек
Attention is All You Need- про транформер
An Image is Worth 16x16 Words- про визуальный трансформер (ViT)
Swin Transformer: Hierarchical Vision Transformer using Shifted Windows - вершина эволюции визуальных трансформеров
Swin Transformer V2 - как SWin,только лучше
Neighborhood Attention Transformer - и ещё лучше
Densely Connected Convolutional Networks - DenseNet