![](https://habrastorage.org/webt/l1/2c/7b/l12c7bo_adfwi1v0tpyu9dqwxto.png)
На момент написания этой статьи большинство крупных технологических компаний (вроде IBM, Google, Microsoft и Amazon) предлагают простые в использовании API визуального распознавания. Аналогичные инструменты предлагают и более мелкие компании, например, Clarifai. Но никто из них не предлагает средств по обнаружению объектов (object detection).
![image](https://habrastorage.org/getpro/habr/post_images/016/14e/6ba/01614e6ba1d596f97abeee5c1573f0e8.gif)
На обеих картинках показаны примеры тегирования с помощью стандартного классификатора Watson Visual Recognition. Только первая картинка была сначала пропущена через модель обнаружения объектов.
![](https://habrastorage.org/webt/nt/cp/b_/ntcpb_w846yrouedr6ti6kbet5o.png)
Обнаружение объектов может значительно превосходить «простое» визуальное распознавание. Но если вы хотите реализовать обнаружение объектов, придётся потрудиться.
В зависимости от ситуации, вам может и не понадобиться кастомная модель обнаружения объектов. Соответствующий API TensorFlow предоставляет несколько моделей с разной производительностью и точностью, основанных на датасете COCO.
Для вашего удобства я собрал полный список объектов, которые могут обнаруживать модели COCO:
![](https://habrastorage.org/webt/wa/n0/yy/wan0yyttj6hkws0a8ikmyw20due.png)
Если хотите обнаруживать логотипы или что-то ещё, не вошедшее в список, то придётся писать собственный кастомный детектор. Я хотел, чтобы машина обнаруживала корабль Хана Соло Millennium Falcon и имперские истребители Tie Fighter. Очевидно, что это очень важная задача, ведь никогда не знаешь, когда это пригодится в жизни…
Аннотирование изображений
Обучение модели — задача трудоёмкая. Наверное, вы сейчас подумали: «Эй, я не хочу тут костьми ложиться!». Если так, то можете почитать мою статью об использовании готовой модели. Этот путь гораздо проще.
Вам нужно будет собрать много изображений и снабдить их аннотациями. Они включают в себя определение координат объекта и соответствующее обозначение. Для картинки с двумя Tie Fighter аннотации может выглядеть так:
<annotation>
<folder>images</folder>
<filename>image1.jpg</filename>
<size>
<width>1000</width>
<height>563</height>
</size>
<segmented>0</segmented>
<object>
<name>Tie Fighter</name>
<bndbox>
<xmin>112</xmin>
<ymin>281</ymin>
<xmax>122</xmax>
<ymax>291</ymax>
</bndbox>
</object>
<object>
<name>Tie Fighter</name>
<bndbox>
<xmin>87</xmin>
<ymin>260</ymin>
<xmax>95</xmax>
<ymax>268</ymax>
</bndbox>
</object>
</annotation>
Для своей модели, которая будет работать со «Звёздными войнами», я собрал 308 изображений, на каждом из которых по 2-3 объекта. Рекомендую собирать не менее 200-300 примеров каждого объекта.
«Ого», подумали вы, «придётся перелопатить сотни изображений и написать кучу XML для каждого?»
Конечно нет! Существует немало инструментов для аннотирования, например, labelImg или RectLabel. Я использовал RectLabel, но он только для macOS. Хотя и с инструментом придётся попотеть, уж поверьте. У меня ушло 3-4 часа непрерывной работы на аннотирование всего моего датасета.
Если есть деньги, может нанять для этого кого-нибудь. Или воспользоваться чем-то вроде Mechanical Turk. Если вы бедный студент, как я, и/или вам нравится многочасовая монотонная работа, то можете сделать аннотации самостоятельно.
Если не хотите писать скрипт преобразования, то при написании аннотаций удостоверьтесь, что они экспортированы в формате PASCAL VOC. Его используют многие, в том числе и я, так что можете позаимствовать вышеприведённый скрипт (я его и сам позаимствовал у кого-то).
Перед запуском скрипта нужно подготовить данные для обработки TensorFlow.
Клонирование репозитория
Сначала клонируйте мой репозиторий. Структура директорий должна выглядеть так:
models
|-- annotations
| |-- label_map.pbtxt
| |-- trainval.txt
| `-- xmls
| |-- 1.xml
| |-- 2.xml
| |-- 3.xml
| `-- ...
|-- images
| |-- 1.jpg
| |-- 2.jpg
| |-- 3.jpg
| `-- ...
|-- object_detection
| `-- ...
`-- ...
Я включил туда свои обучающие данные, так что можете запускать всё из коробки. Но если хотите создать модель со своими данными, придётся добавлять обучающие изображения в images, XML-аннотации — в annotations/xmls, а также придётся обновить trainval.txt и label_map.pbtxt.
trainval.txt — это список файлов, позволяющий найти и коррелировать JPG- и XML-файлы. Ниже приведено содержимое списка trainval.txt, позволяющего найти abc.jpg, abc.xml, 123.jpg, 123.xml, xyz.jpg и xyz.xml:
abc
123
xyz
Примечание: проверьте, чтобы за исключением расширений имена JPG- и XML-файлов совпадали.
label_map.pbtxt — список объектов, которые мы хотим обнаруживать. Он должен выглядеть примерно так:
item {
id: 1
name: 'Millennium Falcon'
}
item {
id: 2
name: 'Tie Fighter'
}
Запуск скрипта
Установите Python и pip, а затем установите требования скрипта:
pip install -r requirements.txt
Добавьте
models
и models/slim
в PYTHONPATH
:export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim
Важно: эта команда должна выполняться при каждом запуске терминала. Или добавьте её в файл
~/.bashrc
.Запускаем скрипт:
python object_detection/create_tf_record.py
Когда он закончит работу, у вас появятся файлы train.record и val.record. Мы будем использовать их для обучения модели.
Скачивание базовой модели
Обучение с нуля детектора объектов может занять дни, даже при использовании нескольких видеокарт. Для ускорения процесса мы возьмём уже обученный на другом датасете детектор и воспользуемся некоторыми его параметрами для инициализации нашей новой модели.
Можете скачать модель отсюда. Здесь все модели различаются точностью и скоростью работы. Я использовал
faster_rcnn_resnet101_coco
.Извлеките и перенесите все файлы model.ckpt в корневую директорию вашего репозитория.
У вас должен быть файл faster_rcnn_resnet101.config. Это настройки для работы с моделью
faster_rcnn_resnet101_coco
. Если вы взяли другую модель, можете найти соответствующий конфигурационный файл здесь. Можно обучать
Запускаем скрипт, после чего должно начаться обучение!
python object_detection/train.py --logtostderr --train_dir=train --pipeline_config_path=faster_rcnn_resnet101.config
Примечание: замените
pipeline_config_path
на путь к своему конфигурационному файлу.global step 1:
global step 2:
global step 3:
global step 4:
...
Ура! Работает!
10 минут спустя.
global step 41:
global step 42:
global step 43:
global step 44:
...
Компьютер начинает дымиться.
global step 71:
global step 72:
global step 73:
global step 74:
...
Сколько же это будет продолжаться?
Модель, которую я использовал в заглавной гифке, прошла примерно через 22 000 циклов.
Чего?!
Я использовал MacBook Pro. Если вы запустили эту модель на подобной машине, то предполагаю, что каждый цикл занимает около 15 секунд. Такими темпами на получение приличной модели уйдёт 3-4 дня непрерывной работы.
Это глупо, у меня нет столько времени
PowerAI спешит на помощь!
PowerAI
PowerAI позволяет обучить нашу модель на IBM Power Systems с графическими процессорами P100!
У меня ушёл всего час на 10 000 циклов. И это была лишь один графический процессор. Реальная мощь PowerAI заключается в способности выполнять распределённое обучение с помощью сотен графических процессоров с 95-процентной эффективностью.
Благодаря PowerAI корпорация IBM недавно установила новый рекорд по обучению распознаванию изображений с точностью 33,8 % за 7 часов. Предыдущий рекорд принадлежал Microsoft?—?точность 29,9 % за 10 дней.
ОООООЧЕНЬ быстро!
Поскольку я обучаю не на миллионах изображений, мне точно не нужны такие ресурсы. Достаточно одного процессора.
Создание аккаунта в Nimbix
Nimbix предоставляет разработчикам пробные аккаунты с 10 часами бесплатной работы на платформе PowerAI. Зарегистрироваться можно здесь.
Примечание: регистрация не автоматическая, так что её одобрение может занять до 24 часов.
После одобрения регистрации вы получите письмо с инструкциями по подтверждению и созданию аккаунта. У вас попросят промокод, оставьте поле пустым.
Теперь можете залогиниться здесь.
Развёртываем приложение PowerAI Notebooks
Поищите по запросу PowerAI Notebooks.
![](https://habrastorage.org/webt/yo/y6/ax/yoy6axo9uas1ovyaaxychpd4zb8.png)
Кликните на результате и выберите TensorFlow.
![](https://habrastorage.org/webt/le/zx/tu/lezxtuszwxwhres9unqxwbjjzxa.png)
Выберите тип машины 32 thread POWER8, 128GB RAM, 1x P100 GPU w/NVLink (np8g1).
![](https://habrastorage.org/webt/5v/hb/kk/5vhbkkrzxcwf4nfgbdkuibva3ca.png)
Появится панель, как на картинке ниже. Когда статус сервера станет Processing, можно к нему обращаться.
Получите пароль, кликнув на (click to show).
Потом для запуска Notebooks кликните Click here to connect.
![](https://habrastorage.org/webt/xm/1d/uf/xm1duf0uxgm5oxvfnsc0coen_lg.png)
Залогиньтесь с именем nimbix и полученным паролем.
![](https://habrastorage.org/webt/co/8n/9e/co8n9eoccp68jsgyqul6lmbwntg.png)
Начинаем обучение
Кликните на выпадающее меню New и выберите Terminal, чтобы открыть новое окно терминала.
![](https://habrastorage.org/webt/cb/fl/0a/cbfl0a7j1acvy_bdqijurydn6ic.png)
Вас встретит знакомый интерфейс:
![](https://habrastorage.org/webt/iu/s4/0r/ius40ravmkcq4qwpufhowftlv30.png)
Примечание: терминал может не работать в Safari.
Процесс обучения запускается так же, как и на локальном компьютере. Если используете мои обучающие данные, то просто клонируйте мой репозиторий с помощью команды:
git clone github.com/bourdakos1/Custom-Object-Detection.git
Или же клонируйте свой репозиторий. Затем внутри корневой директории выполните cd:
cd Custom-Object-Detection
Выполните нижеприведённый код, скачивающий заранее обученную модель faster_rcnn_resnet101_coco, которую мы уже скачивали ранее.
wget http://storage.googleapis.com/download.tensorflow.org/models/object_detection/faster_rcnn_resnet101_coco_11_06_2017.tar.gz
tar -xvf faster_rcnn_resnet101_coco_11_06_2017.tar.gz
mv faster_rcnn_resnet101_coco_11_06_2017/model.ckpt.*
Затем снова обновите PYTHONPATH, поскольку у вас новый терминал:
export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim
Теперь можно выполнять команду запуска обучения:
python object_detection/train.py --logtostderr --train_dir=train --pipeline_config_path=faster_rcnn_resnet101.config
Скачивание своей модели
Когда модель будет готова? Зависит от ваших обучающих данных. Чем их больше, тем больше циклов нужно прогнать. У меня получилась довольно толковая модель после примерно 4500 циклов. А своего пика она достигла примерно за 20 000 циклов. Вообще я прогнал 200 000 циклов, но лучше модель не стала.
Рекомендую скачивать вашу модель каждые 5000 циклов или около того, и оценивать её работу, чтобы понимать, двигаетесь ли вы в нужном направлении. Кликните на логотип Jupyter в левом верхнем углу, затем идите по дереву файлов до Custom-Object-Detection/train.
Скачайте все файлы model.ckpt с самым большим числом в названии.
•model.ckpt-STEP_NUMBER.data-00000-of-00001
•model.ckpt-STEP_NUMBER.index
•model.ckpt-STEP_NUMBER.meta
Примечание: скачивать можно только по одному файлу за раз.
![](https://habrastorage.org/webt/pq/at/5l/pqat5lyrb1ip1l1cozb8_cn_fuc.png)
Примечание: после завершения обучения кликните на красную кнопку, иначе часы будут идти бесконечно.
Экспорт результирующего графа
Чтобы использовать в коде вашу модель, нужно конвертировать файлы контрольных точек (checkpoint files) (model.ckpt-STEP_NUMBER.*) в фиксированный результирующий граф (inference graph).
Перенесите скачанные файлы контрольных точек в корневую папку вашего репозитория.
Затем выполните эту команду:
python object_detection/export_inference_graph.py --input_type image_tensor --pipeline_config_path faster_rcnn_resnet101.config --trained_checkpoint_prefix model.ckpt-STEP_NUMBER --output_directory output_inference_graph
Не забудьте export
PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim
.Должна появиться новая директория
output_inference_graph
с файлом frozen_inference_graph.pb
. Он-то нам и нужен.Тестирование модели
Теперь выполните команду:
python object_detection/object_detection_runner.py
Она применит вашу модель обнаружения объектов, расположенную в output_inference_graph/frozen_inference_graph.pb, ко всем изображениям в директории test_images и запишет результаты в директорию output/test_images.
Результаты
Вот что мы получим, когда прогоним модель по всем кадрам отрывка из «Звёздные войны: Пробуждение силы».
Комментарии (5)
nektotrishin
22.12.2017 18:52308 изображений train. Модель должна работать и на других эпизодах звездных войн.
Nick_mentat
Нам, людям, со зрением очень сильно помогает контекст. В данной задаче можно улучшить точность если явно указать что в кадре не может быть более одного Фалкона. И, пожалуй, добавить информацию о последнем обнаруженном положении на предыдущих кадрах. Если модель возвращает вектор вероятности для окошек, то реализация такая: можно подкорректировать его вероятности сообразно с удалённостью координат и масштаба от предыдущего положения, и выбрать не все подходящие по порогу, а не более одного среди тех, кто подходит по порогу.
Тогда вот это дополнительное зелёное окно, которое порой появляется на доли секунды — его не будет.