Был вечер пятницы, и мы с моим другом Лукой собирались покататься на велосипеде. Поскольку час пик все еще был в разгаре, мы свернули в пробке, чтобы прорваться на менее загруженные местные дороги, подходящие для езды. Воодушевленные случайными гудками нервных водителей, мы начали дискуссию о том, почему водители так ненавидят велосипедистов, на что Лука ответил: Ну, они не любят нас, велосипедистов, но они ненавидят пассажиров пригородных поездов. Ах да, знаменитый велосипедист или пригородный спор. Если вы не знакомы с предметом, посмотрите это забавное видео от Casually Explained. Так родилась идея создать простое приложение, которое сможет сфотографировать человека с велосипедом и вывести класс: велосипедист или пассажир пригородных поездов. Идея заключалась в том, чтобы создать приложение просто для удовольствия и тратить на него как можно меньше времени, поскольку мы оба работаем полный рабочий день с другими проектами на стороне.

Если вы хотите использовать этот процесс для своих собственных проектов, убедитесь, что на вашем компьютере установлены TensorFlow и TensorFlow Object Detection API.

Сбор данных

Google Images и Pixaby использовались для сбора изображений велосипедистов с помощью расширения Google Chrome под названием Download All Images. С помощью этого расширения вы можете заархивировать и загрузить все изображения со страницы одним щелчком мыши, что избавит вас от необходимости вручную загружать изображения одно за другим.

Я пометил изображения велосипедистов с помощью labelImg, который стал стандартом для этой задачи. Это сценарий Python с простым пользовательским интерфейсом, разработанный с использованием Qt для Python. Процесс маркировки прост, и с помощью горячих клавиш он может быть выполнен эффективно. Ярлыки для каждого изображения хранятся в файле XML, и вы можете вернуться и изменить уже помеченные изображения. Примечание: людей причисляли к велосипедистам или пассажирам только по моему субъективному ощущению, но если вас неправильно классифицируют, не вините меня, это вина сети 🙂.

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

Сетевые модели

Использовать Tensorflow Object Detection API довольно просто, и вам даже не нужно быть знакомым с используемой сетевой моделью. Фактически, большая часть времени в подобных проектах будет тратиться на подготовку данных. Однако сетевая архитектура - самая интересная часть машинного обучения, поэтому давайте посмотрим на архитектуру сети и то, как она может научиться обнаруживать объекты.

В этом проекте используется сеть Faster RCNN ResNet50. Как и большинство моделей, работающих с изображениями, это сверточная сеть, что означает, что она использует серию сверток в своих скрытых слоях. Он состоит из двух частей: детектора объектов (Faster RCNN) и экстрактора функций (ResNet).

Детекторы объектов

Детектор объектов - это часть, которая, очевидно, отвечает за определение местонахождения объекта. Точнее, он выводит ограничивающие рамки, окружающие найденные объекты. Если вы думаете о том, как решить эту проблему, первая идея, которая приходит вам в голову, может быть подход со скользящим окном. Возьмите коробку фиксированного размера и, начиная с верхнего левого угла, проведите ею по изображению с определенным шагом, пока не дойдете до нижнего правого угла. Обнаружение запуска для каждой позиции и выходных регионов с наивысшими баллами. Конечно, этот процесс следует повторить с несколькими размерами ящиков, чтобы учесть разные формы и размеры объектов. Хотя этот подход является законным, он чрезвычайно медленный, и современные детекторы объектов используют гораздо более умные и эффективные методы.

В 2014 году Росс Гиршик и др. Предложили метод, который они назвали R-CNN: Regions with CNN features. Их метод включал предложение около 2000 регионов, а затем вычисление характеристик для каждого региона. Преемник R-CNN, Fast R-CNN, использовал все изображение в качестве входных данных для CNN вместо каждой предложенной области, что значительно улучшило время обработки. Faster R-CNN - это современный детектор объектов, предложенный Shaoqing Ren et al. Они представили Сеть региональных предложений (RPN), которую можно обучить от начала до конца, чтобы предсказывать высококачественные региональные предложения. RPN заменил алгоритм выборочного поиска, используемый R-CNN и Fast R-CNN, что еще больше повысило производительность обнаружения.

Экстракторы функций

Средство извлечения признаков - это основная часть CNN, которая, очевидно, извлекает признаки из изображения. Большинство экстракторов признаков работают аналогично, выполняя серию операций свертки и объединения на входном изображении. Tensorflow предлагает коллекцию современных моделей, предварительно обученных на наборе данных COCO, под названием Detection Model Zoo. Другая коллекция моделей, называемая Keras Applications, предлагает реализации Keras, предварительно обученные с помощью набора данных ImageNet. При выборе модели необходимо учитывать два основных параметра: размер модели и точность. Размер модели относится к количеству обучаемых параметров. Более крупные модели, как правило, лучше обучаются, но для обучения требуется больше времени, время обнаружения медленнее и они больше по размеру. Последнее может быть важно при развертывании модели на мобильном устройстве, как в этом проекте.

За последние несколько лет я экспериментировал с множеством архитектур моделей, и остаточная сверточная сеть (ResNet), кажется, обеспечивает высокую точность при достаточно быстрой работе. В то время как более старые сетевые архитектуры, используемые в таких моделях, как LeNet-5, AlexNet и VGGNet, страдали от проблем с исчезающими градиентами и не могли выиграть от добавления дополнительных слоев, введение остаточных соединений в ResNets позволило использовать более глубокие сети. Модель ResNet50, используемая в этом проекте, состоит из 50 сверточных слоев, где за каждой сверткой следует пакетная нормализация, активация ReLU и заполнение. Всего модель состоит из 25 миллионов обучаемых параметров.

Обучение сети и результаты

Как упоминалось ранее, обучение - это процесс изменения весов сети для минимизации функции потерь. Функция потерь определяет, насколько далеко прогнозируемый результат от истинного значения. Есть разные функции потерь. Наиболее популярными являются потеря L1 (средняя абсолютная ошибка), потеря L2 (среднеквадратическая ошибка) и ошибка среднего смещения, используемые для регистрации, а также потери на шарнире и потери перекрестной энтропии для классификации. Обучение заканчивается, когда завершено заранее определенное количество шагов обучения, но также может быть остановлено раньше, если потери перестают уменьшаться с увеличением количества тренировок. Об этом свидетельствует сглаживание кривой обучения.

Давайте накормим сеть фотографиями моих друзей, катающихся на велосипедах. Сеть выводит ограничивающие рамки с принадлежащими классами и вероятностями принадлежности объектов к определенным классам.

Заключение

API обнаружения объектов Tensorflow значительно упростил создание пользовательских детекторов объектов. При выборе между библиотеками машинного обучения я настоятельно рекомендую использовать Tensorflow 2 (или PyTorch для этого) вместо версии Tensorflow 1.x. Tensorflow 2 проще и удобнее в использовании, поддерживается Keras API и реализовано нетерпеливое выполнение (больше никаких сеансов 🥳), что упростило отладку. Этот проект в основном реализовывался в Google Colaboratory, данные загружались на Google Диск и с него. Я бы посоветовал использовать Colab для небольших проектов из-за бесплатных процессоров Google и TPU, которые значительно сокращают время обучения.