Как я обучил модель с нуля для обнаружения и сегментации печатей

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Привет хабр! Сегодня хочу поделиться своим кейсом. Распознавание печатей позволило бы автоматизировать множество рутиных задач, упростив работу человека. Для своей задачи я использую модель Mask R-CNN.

Mask R-CNN представляет собой двухэтапную структуру: на первом этапе сканируется изображение и генерируются предложения (области, которые могут содержать объект). На втором этапе предложения классифицируются и создаются ограничивающие рамки и маски.

Что такое сегментация?

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

Классификация: на этом изображении есть кошка.

Обнаружение объектов: на этом изображении в этих местах есть две кошки, одна собака и утка. Мы начинаем учитывать перекрывающиеся объекты.

Сегментация: в этих местах есть 4 всплывающих окон, и это пиксели, принадлежащие каждому из них.

Подготовка набора данных для обучения

Так как, нет открытых наборов данных для печатей(по крайне мере я не нашел), я решил создать набор данных с нуля. Я искал изображения с открытых каналов глобальной паутины. Я собрал около 2 тысяч изображений разделил их на обучающий набор и набор для проверки. Искать изображения очень просто. Аннотировать их - сложная часть.

Вы наверное задаётесь вопросом, разве нам не нужен больше изображений, чем 2 тысяч для обучения модели глубокого обучения? Иногда да, но часто нет. Я полагаюсь на трансферное обучение. Это просто означает, что вместо обучения модели с нуля я начинаю с файла весов, который был обучен на наборе данных COCO (в репозитории Mask R-CNN они предоставляют его). Хотя набор данных COCO не содержит класса печатей, он содержит много других изображений (~ 120 тысяч), поэтому обученные веса уже изучили множество функций, общих для естественных изображений, что действительно помогает.

Для аннотирования изображений я использовал  VIA (VGG Image Annotator). Это отдельный HTML-файл, который вы загружаете и открываете в браузере. Аннотирование первых нескольких изображений было очень медленным, но как только я привык к пользовательскому интерфейсу, я начал аннотировать объект около 20 секунд.

Загрузка набора данных

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

Инструмент VIA сохраняет аннотации в файле JSON, и каждая маска представляет собой набор точек многоугольника. Я не нашел документации по формату, но это довольно легко понять, просмотрев сгенерированный JSON. Я включил в код комментарии, чтобы объяснить, как выполняется синтаксический анализ.

Совет по коду:простой способ написать код для нового набора данных - скопировать coco.py и изменить его в соответствии с вашими потребностями. Что я и сделал. Я сохранил новый файл как seal.py

Мой SealDataset класс выглядит так:

class SealDataset(utils.Dataset):
    def load_balloons(self, dataset_dir, subset):
        ...
    def load_mask(self, image_id):
        ...
    def image_reference(self, image_id):
        ...

load_balloonsсчитывает файл JSON, извлекают аннотации и итеративно вызывает внутренние add_classи add_imageфункцию для создания набора данных.

load_mask генерирует растровые маски для каждого объекта изображения путем рисования многоугольников.

image_referenceпросто возвращает строку, которая идентифицирует изображение для целей отладки. Здесь он просто возвращает путь к файлу изображения.

Вы могли заметить, что мой класс не содержит функций для загрузки изображений или возврата ограничивающих рамок. Функция по умолчанию load_imageв базовом Datasetклассе обрабатывает загрузку изображений. И ограничивающие прямоугольники генерируются динамически из масок.

Проверить набор данных

Чтобы убедиться, что мой новый код реализован правильно, я добавил эту записную книжку Jupyter . Он загружает набор данных, визуализирует маски и ограничивающие рамки, а также визуализирует якоря, чтобы убедиться, что размеры моих якорей подходят для размеров моих объектов. Вот пример того, что вы должны ожидать:

Совет по коду:чтобы создать этот блокнот, я скопировал файл inspect_data.ipynb , который мы написали для набора данных COCO, и изменил один блок кода вверху, чтобы вместо него загрузить набор данных Seal.

Конфигурации

Конфигурации для этого проекта аналогичны базовой конфигурации, используемой для обучения набора данных COCO, поэтому мне просто нужно было переопределить 3 значения. Как и в случае с Datasetклассом, я наследую от базового Configкласса и добавляю свои переопределения:

class BalloonConfig(Config):
    # Give the configuration a recognizable name
    NAME = "seal"
    # Number of classes (including background)
    NUM_CLASSES = 1 + 1  # Background + seal
    # Number of training steps per epoch
    STEPS_PER_EPOCH = 100

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

Обучение

Маска R-CNN - довольно большая модель. Вам нужен современный графический процессор. Я пробовал на Quadro M2000 c 4 ГБ памяти. Обучение заняло около 3-4 часов.

Начните обучение с этой команды, запущенной из seal. Здесь мы указываем, что тренировка должна начинаться с предварительно натренированных весов COCO. Код автоматически загрузит веса из нашего репозитория:

python seal.py train --dataset=/путь/к/датасету --model=coco

И возобновить тренировку, если она остановилась:

python seal.py train --dataset=/путь/к/датасету --model=last

Проверка результатов

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

Предобученные весы для обнаружения и сегментации можете скачать здесь. Чтобы использовать, добавьте проект в папку samples в Mask R-CNN. Если есть необходимость датасета, напишите мне в почту: galym55010@gmail.com

Источник: https://habr.com/ru/post/531540/


Интересные статьи

Интересные статьи

Библиотеки и сервисы AutoML вошли в мир машинного обучения. Для дата-сайентиста это очень полезные инструменты, но иногда они должны быть адаптированы к потребностям бизнес-контекста, в к...
SWAP (своп) — это механизм виртуальной памяти, при котором часть данных из оперативной памяти (ОЗУ) перемещается на хранение на HDD (жёсткий диск), SSD (твёрдотельный накоп...
Для написания эффективных и корректных многопоточных приложений очень важно знать какие существуют механизмы синхронизации памяти между потоками исполнения, какие гарантии предоставл...
Привет, Хабравчане. Для тех кто не знает, совсем недавно Рикардо начал новый курс, который посвящен реверсингу и эксплоитингу. Это продолжение предыдущего оригинального авторского курса, котор...
За рубежом все большую популярность набирает использование искусственного интеллекта в промышленности для предиктивного обслуживания (predictive maintenance) различных систем. Цель этой методики ...