Как играть в квиддич с помощью TensorFlow Object Detection API

1656670573 kak igrat v kviddich s pomoshhyu tensorflow object detection api

от Бхарат Радж

1*BBePdi1BimXkPlh1pwO98g
TensorFlow лучший искатель, чем Гарри?

Глубокая учеба не перестает меня удивлять. Он оказал глубокое влияние на несколько доменов, превзойдя тесты слева и справа.

Классификация изображений с помощью сверточных нейронных сетей (CNN) сегодня достаточно проста, особенно с появлением мощных интерфейсных оберток, таких как Keras с серверной частью TensorFlow. Но что, если вы хотите идентифицировать более одного объекта на изображении?

Эта проблема называется «локализация и обнаружение объекта». Это гораздо сложнее, чем простая классификация. На самом деле, до 2015 года локализация изображений с помощью CNN была очень медленной и неэффективной. Просмотрите эту публикацию в блоге Dhruv, чтобы прочитать об истории обнаружения объектов в Deep Learning, если вам это интересно.

1*Mj8WKVKf_RpiAsX3SC1ZdQ
Источник: CS231n Лекция 8 (2016)

Звучит вкрутую. Но трудно ли кодировать?

Не беспокойтесь, API обнаружения объектов TensorFlow приходит на помощь! Они сделали большую часть тяжелой работы за вас. Все, что вам нужно сделать это подготовить набор данных и установить некоторые конфигурации. Вы можете научить свою модель и использовать ее для выводов.

TensorFlow также предоставляет предварительно подготовленные модели, обученные наборам данных MS COCO, Kitti или Open Images. Вы можете использовать их как таковые, если вы просто хотите использовать это для стандартного обнаружения объектов. Недостатком является то, что они заранее определены. Он может включать только классы, определенные наборами данных.

1*ZeDQGWRoERxO9dW9Sqgc_w
API обнаружения объектов TensorFlow в работе

Но что если бы вы хотели обнаружить что-то такое нет на возможный список занятий? Это цель этой публикации в блоге. Я предлагаю вам создать собственную программу обнаружения объектов, используя интересный пример квиддича из вселенной Гарри Поттера! (Для всех вас, поклонников «Звездных войн», вот подобная публикация в блоге, которая может вам понравиться).

Начинаем

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

Кроме того, вы можете клонировать хранилище моделей TensorFlow. Если вы выберете последнее, вам понадобятся только папки с названиями slim и object_detection, поэтому смело удаляйте остальные. Не переименовывайте ничего в папках (если вы не уверены, что это не испортит код).

Зависимости

Если предположить, что у вас установлен TensorFlow, может потребоваться установить еще несколько зависимостей, что можно сделать, выполнив следующее в базовом каталоге:

pip install -r requirements.txt

API использует Protobufs для настройки и обучения параметрам модели. Перед их использованием необходимо скомпилировать библиотеки Protobuf. Сначала вам нужно установить компилятор Protobuf с помощью следующей команды:

sudo apt-get install protobuf-compiler

Теперь вы можете скомпилировать библиотеки Protobuf с помощью такой команды:

protoc object_detection/protos/*.proto --python_out=.

Вам нужно добавить путь вашего базового каталога, а также вашего тонкого каталога к вашему переменному пути Python. Обратите внимание, что вам нужно выполнять этот шаг всякий раз, когда вы открываете новый терминал. Вы можете сделать это, выполнив приведенную ниже команду. Кроме того, вы можете добавить его в свой ~/.bashrc файл для автоматизации процесса

export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim

Подготовка входных материалов

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

Но потом я решил поднять ставки. Как попробовать идентифицировать все подвижные части оборудования, используемые в квиддиче?

1*ml_9ni6QrX8I654Rnw1k2g
Квиддич состоит из трех (уникальных) движущихся объектов. Два бладжера, один кваффл и один снитч.

Начинаем с подготовки label_map.pbtxt файл. Он содержит все названия целевых меток, а также идентификационный номер для каждой метки. Обратите внимание, что идентификатор метки должен начинаться с 1. Вот содержимое файла, которое я использовал для своего проекта.

item { id: 1 name: ‘snitch’}
item { id: 2 name: ‘quaffle’}
item { id: 3 name: ‘bludger’}

Теперь пора собрать набор данных.

весело! Или скучно, в зависимости от вкуса, но все равно обыденная задача.

Я собрал набор данных, выбрав все кадры видеоклипа о Гарри Поттере, используя небольшой фрагмент кода, который я написал, используя фреймворк OpenCV. Когда это было сделано, я использовал другой фрагмент кода для случайной выборки 300 изображений с набором данных. Фрагменты кода доступны в utils.py в моем репо GitHub, если вы хотите сделать то же самое.

Вы правильно меня услышали. Всего 300 изображений. Да, мой набор данных был невелик. Это главным образом потому, что я не могу позволить себе аннотировать многие изображения. Если вы хотите, вы можете выбрать платные услуги, такие как Amazon Mechanical Turk, чтобы добавлять инструкции к своим изображениям.

Аннотации

Любая задача локализации изображения требует аннотаций правдивости. Используемые здесь аннотации являются XML-файлами с 4 координатами, представляющими расположение рамки, окружающей объект, и его метку. Мы используем формат Pascal VOC. Образец аннотации будет выглядеть так:

<annotation>  <filename>182.jpg</filename>  <size>    <width>1280</width>    <height>586</height>    <depth>3</depth>  </size>  <segmented>0</segmented>  <object>    <name>bludger</name>    <bndbox>      <xmin>581</xmin>      <ymin>106</ymin>      <xmax>618</xmax>      <ymax>142</ymax>    </bndbox>  </object>  <object>    <name>quaffle</name>    <bndbox>      <xmin>127</xmin>      <ymin>406</ymin>      <xmax>239</xmax>      <ymax>526</ymax>    </bndbox>  </object></annotation>

Вы можете подумать: «Действительно ли мне вручную вводить аннотации в XML-файлы?» Абсолютно нет! Существуют инструменты, позволяющие использовать графический интерфейс для рисования рамок над объектами и добавления к ним примечаний. весело! LabelImg является отличным инструментом для пользователей Linux/Windows. Как альтернатива, RectLabel является хорошим выбором для пользователей Mac.

Несколько примечаний перед тем, как начать собирать набор данных:

  • Не переименовывайте файлы изображений после добавления аннотации. Код пытается найти изображение, используя название файла, указанное в вашем XML-файле (который LabelImg автоматически заполняет название файла изображения). Кроме того, убедитесь, что ваши изображение и XML файлы имеют то же имя.
  • Убедитесь, что вы изменить размер изображение до нужного размера раньше вы начинаете комментировать их. Если вы сделаете это позже, аннотации не будут иметь смысла, и вам придется масштабировать значения аннотаций в XML-файлах.
  • LabelImg может выводить некоторые дополнительные элементы в файл XML (например, , , ). Вам не нужно их удалять, поскольку они не будут мешать коду.

Если вы что-то напутали, utils.py файл имеет некоторые служебные функции, которые могут помочь вам. Если вы просто хотите попробовать в квиддич, вы можете вместо этого скачать мой аннотированный набор данных. Оба доступны в моем репозитории GitHub.

Наконец, создайте текстовый файл с названием trainval. Он должен содержать имена всех файлов изображений/XML. Например, если в вашем наборе данных есть img1.jpg, img2.jpg и img1.xml, img2.xml, файл trainval.txt должен выглядеть так:

img1img2

Разделите набор данных на две папки, а именно изображение и аннотации. Разместите label_map.pbtxt и trainval.txt в папке аннотаций. Создайте папку с названием xml в папку инструкций и разместите в ней все свои XML-файлы. Ваша иерархия каталогов должна выглядеть примерно так:

-base_directory|-images|-annotations||-xmls||-label_map.pbtxt||-trainval.txt

API принимает входные данные в TFRecords формат файла Не беспокойтесь, вы можете легко преобразовать текущий набор данных в нужный формат с помощью небольшой служебной функции. Использовать create_tf_record.py файл, предоставленный в моем репо, для преобразования вашего набора данных в TFRecords. Вы должны выполнить такую ​​команду в своем базовом каталоге:

python create_tf_record.py \    --data_dir=`pwd` \    --output_dir=`pwd`

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

Обучение модели

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

Короче говоря, SSD являются быстрыми, но могут не обнаруживать меньшие объекты с достойной точностью, тогда как более быстрые RCNN относительно медленнее и больше, но имеют лучшую точность.

TensorFlow Object Detection API предоставил нам кучу предварительно обученных моделей. Настоятельно рекомендуется инициализировать обучение с помощью предварительно обученной модели. Это может значительно сократить время обучения.

1*WF_iKJBo9__XstR9_fwLFA
Куча моделей, предварительно обученных на наборе данных MS COCO

Загрузите одну из этих моделей и извлеките содержимое в базовый каталог. Поскольку я больше сосредотачивался на точности, но тоже хотел приемлемое время выполнения, я выбрал версию ResNet-50 модели Faster RCNN. После удаления вы получите контрольные точки модели, замороженный график выводов и файл pipeline.config.

Осталось одно! Вы должны определить «учебную работу» в pipeline.config файл. Разместите файл в базовом каталоге. Что действительно имеет значение, так это несколько последних строк файла – вам нужно лишь установить выделенные значения для соответствующих размещений файлов.

gradient_clipping_by_norm: 10.0  fine_tune_checkpoint: "model.ckpt"  from_detection_checkpoint: true  num_steps: 200000}train_input_reader {  label_map_path: "annotations/label_map.pbtxt"  tf_record_input_reader {    input_path: "train.record"  }}eval_config {  num_examples: 8000  max_evals: 10  use_moving_averages: false}eval_input_reader {  label_map_path: "annotations/label_map.pbtxt"  shuffle: false  num_epochs: 1  num_readers: 1  tf_record_input_reader {    input_path: "val.record"  }}

Если у вас есть опыт установки лучших гиперпараметров для вашей модели, вы можете сделать это. Создатели дали здесь довольно краткие указания.

Теперь вы готовы тренировать свою модель! Выполните указанную ниже команду, чтобы начать обучение.

python object_detection/train.py \--logtostderr \--pipeline_config_path=pipeline.config \--train_dir=train

Графический процессор моего ноутбука не мог совладать с размером модели (Nvidia 950M, 2 ГБ), потому мне пришлось запустить его на ЦБ. На моем устройстве это занимало примерно 7–13 секунд в шаге. После примерно 10 000 невыносимых шагов модель достигла достаточно хорошей точности. Я прекратил тренировку по достижении 20 000 шагов исключительно потому, что это заняло уже два дня.

Вы можете восстановить обучение с контрольной точки, изменив атрибут «fine_tune_checkpoint» с model.ckpt на model.ckpt-xxxx, где xxxx представляет глобальный номер шага сохраненной контрольной точки.

Экспорт модели для заключения

Каков смысл обучать модель, если вы не можете использовать ее для обнаружения объектов? API снова в помощь! Но здесь есть загвоздка. Их модуль вывода требует в качестве входной модели замороженного графа. Но не беспокойтесь: с помощью следующей команды вы можете экспортировать обученную модель в модель замороженного графика.

python object_detection/export_inference_graph.py \--input_type=image_tensor \--pipeline_config_path=pipeline.config \--trained_checkpoint_prefix=train/model.ckpt-xxxxx \--output_directory=output

аккуратно! Вы получите файл с названием frozen_inference_graph.pbвместе с кучей файлов контрольных точек.

Вы можете найти файл под названием inference.py в моем репо GitHub. Вы можете использовать его для тестирования или запуска модуля обнаружения объектов. Код достаточно понятен и похож на демонстрацию обнаружения объектов, представленную создателями. Вы можете выполнить его, введя следующую команду:

python object_detection/inference.py \--input_dir={PATH} \--output_dir={PATH} \--label_map={PATH} \--frozen_graph={PATH} \--num_output_classes={NUM}

Замените выделенные символы {PATH} с названием файла или путем соответствующего файла/каталога. Заменить {NUM} с количеством объектов, которые вы определили для своей модели для обнаружения (в моем случае 3).

Результаты

Просмотрите эти видео, чтобы сами увидеть его эффективность! Первое видео демонстрирует способность модели различать все три объекта, в то время как второе видео демонстрирует ее мастерство как соискателя.

Весьма поразительно, я бы сказал! У него есть проблема с отличием голов от объектов для квиддича. Но учитывая размер нашего набора данных, производительность достаточно хорошая.

Слишком длительная тренировка привела к массовой чрезмерной подгонке (она больше не была неизменной по размеру), хотя и уменьшила количество ошибок. Вы можете преодолеть это с большим набором данных.

Спасибо, что прочли эту статью! Нажмите эту кнопку, если да! Надеюсь, это помогло вам создать собственную программу обнаружения объектов. Если у вас есть вопросы, вы можете связаться со мной на LinkedIn или отправить мне электронное письмо (bharathrajn98@gmail.com).

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *