YOLO history (Part 1)
В этом году вышла уже восьмая версия одной из самых известных архитектур в области компьютерного зрения — YOLO. Если первая версия решала только задачу детекции, хоть и в режиме реального времени, то у последней итерации хорошее качество и скорость в целом спектре задач от классификации до pose estimation. Предлагаем вам вспомнить историю создания этого семейства архитектур.
Введение
Возвращаемся в 2016 год и вспоминаем о том, что Faster R-CNN — SOTA в задаче детекции на тот момент вышла около года назад. Она показывала хорошее качество, но работала медленно (всего 17 fps у самой быстрой модели). Почему? Использование нескольких последовательных нейросетей и наличие сложного алгоритма обработки ббоксов. Детекцию в 17 fps сложно назвать детекцией в режиме реального времени. С этим нужно было что-то делать. Исследователи из Вашингтонского университета решили создать архитектуру, которая будет быстро и точно решать задачу детекции. И 9-го мая 2016 года они выпустили статью, с которой все началось — You Only Look Once: Unified, Real-Time Object Detection.
Давайте сегодня с вами погрузимся в историю и разберемся со всеми трюками самой первой версии YOLO.
YOLOv1 (You Only Look Once: Unified, Real-Time Object Detection)
Архитектура
Основная цель авторов — сделать быструю модель, которая будет хорошо, но не обязательно лучше всех решать задачу детекции. Для этого они выбрали single shot подход: фактически модель должна решать задачу детекции без стадии предварительного выделения proposals (как было в Faster R-CNN), сразу предсказывать ббоксы и классы.
С этой целью авторы предложили использовать следующую архитектуру:
В ее основе лежит GoogLeNet с небольшими изменениями: модель состоит из 24-х коволюционных и 2-х полносвязных слоев. Архитектуру можно разделить на 2 части:
- Классификационная часть представляет собой первые 20 сверточных слоев, предобученных на ImageNet 1000-class . На самом деле вместо GoogLeNet могла быть любая другая предобученная архитектура (в статье авторы экспериментируют и с VGG).
- Детекционная часть объединяет последние слои сети (4 конволюционных и 2 полносвязных). Эту часть мы будем называть детекционной головой (голова — сленговое название для последних слоев сети). Выходной тензор модели (или feature map) имеет размер 7х7х30. Давайте разбираться почему.
Каждую фичу из выходного тензора можно спроецировать на входное изображение. Такая проекция в литературе называется receptive field. Она показывает область картинки, за которую отвечает конкретный вектор фичей выходного слоя. Давайте мысленно поделим входное изображение на сетку размером 7х7. Тогда каждая ячейка будет размером 64х64. Для каждой такой ячейки YOLOv1 предсказывает целый вектор фичей, внутри которого скрывается описание 2х ббоксов и набор вероятностей. Последний отвечает за класс объекта внутри ббокса. Теперь представим это все схематично:
Важное дополнение: ббоксов было больше одного. Авторы предположили, что использование нескольких ббоксов позволит легче отлавливать объекты разных размеров.
В итоге для каждой ячейки сетки модель предсказывает вектор из 30 фичей:
- Первые 10 из них отвечают за положение двух ббоксов:
- x, y — координаты центра ббокса внутри ячейки относительно ее границ;
- w, h — ширина и высота ббокса, отнормированные по размеру картинки;
- c — confidence score, или уверенность модели в наличии центра объекта в этой ячейке или же IOU между предсказанными ббоксом и разметкой.
- Остальные 20 содержат вероятности классов объектов внутри ячейки. Почему 20? Это количество классов в датасете Pascal VOC2007.
Еще раз обратим ваше внимание — предсказываемые значения координат и ширины ббоксов расположены в интервале от 0 до 1, это сильно упрощает процесс обучения.
Обучение
Сначала авторы дообучали детекционную голову на увеличенных изображениях (448х448 вместо 224х224 у ImageNet). Это позволяло им значительно увеличить точность модели.
Для получения качественной модели нужно было соблюдать баланс в лоссе. Тогда модель обучается и правильно детектировать объект, и корректно определять его класс. Модель бесполезна, если она правильно детектирует объект, но неправильно классифицирует его, и наоборот.
Полностью лосс выглядит следующим образом:
Так, не будем пугаться, для упрощения восприятия мы сейчас разобьем его на части 🙂
Лосс классификации
Начнем с самой простой части:
Это стандартный квадратичный лосс, но без усреднения (да, они использовали mse для классификации. Почему? А я не знаю почему… Если вы знаете, напишите об этом в комментариях 🙂). Фигурная единица — это индикаторная функция, которая принимает значение 1 при наличии в
\( p_i(c) \) — исходная из разметки вероятность того, что в \( i \)-ой ячейке объект имеет класс \( c \). Она принимает значение 0 для всех классов, кроме правильного.
\( \hat{p}_i(c) \) — предсказанная моделью вероятность того, что в \( i \)-ой ячейке объект имеет класс \( c \).
Несколько важных ремарок перед тем, как мы перейдем к детекционной части лосса:
- авторы акцентируются на том, что большинство ячеек на любой картинке не будет содержать объекта, поэтому нужно обязательно учитывать ячейки с объектами и без объектов по-разному. Для этого они перевзвешивают части лосса: вес для ячеек с объектами обозначается как \( \lambda_{coord}=5 \), а без — как \( \lambda_{noobj}=0.5 \). Лосс классификации и регрессия ббоксов по координатам и размерам считается только для тех ячеек, где есть объекты;
- для каждой клетки в лоссе будет учитываться только ббокс, имеющий большее пересечение (IOU) с разметкой. Авторы утверждают, что это позволяет ббоксам лучше подстраиваться под объекты разного размера.
Центрирование ббокса
Здесь индикаторная функция говорит о том, что мы учитываем лосс для
Размер ббокса
Чтобы по-разному учитывать ошибки для маленьких и больших ббоксов, авторы предсказывают квадратный корень из ширины (\( \sqrt{\hat{w}_i} \)) и высоты (\( \sqrt{\hat{h}_i} \)) ббоксов.
Разверни меня, если утверждение выше вызывает сомнение 🙂
Представим, у нас есть два ббокса: \( w_1, h_1 = 100, 100 \) и \( w_2, h_2 = 10, 10 \). Плюс два предсказания модели \( \hat{w}_1, \hat{h}_1 = 95, 95 \) и \( \hat{w}_2, \hat{h}_2 = 5, 5 \).
В двух случаях мы ошибаемся на 5, но что будет с лоссом?
Обычный квадратичный лосс будет одинаковым:
\( (100 — 95)^2 + (100 — 95)^2 = 50 \)
\( (10 — 5)^2 + (10 — 5)^2 = 50 \)
А если взять корень:
\( (\sqrt{100} — \sqrt{95})^2 + (\sqrt{100} — \sqrt{95})^2 = 0.128 \)
\( (\sqrt{10} — \sqrt{5})^2 + (\sqrt{10} — \sqrt{5})^2 = 1.71 \)
Разница заметна сразу — ошибка на маленьком ббоксе в несколько раз выше, чем на большом.
Уверенность модели (Confidence score)
Особенность этой части лосса заключается в том, что уверенность для ячеек без объектов берется с меньшим весом ( \( \lambda_{noobj}=0.5 \)). Таким образом, первая часть позволяет модели не переобучаться и не предсказывать везде 0, а вторая штрафует модель за предсказание ненулевых значений там, где объектов нет.
Инференс
И все же остался один важный вопрос. Как делать итоговое предсказание? У нас сейчас даже классы никак не привязаны к ббоксам!
Для определения класса внутри каждого из ббоксов нужно перемножить вероятности и confidence score ббоксов. Делаем это для всех ббоксов на изображении и получаемм 7*7*2 = 98 ббоксов. А чтобы выбрать какие ббоксы оставить, а какие убрать, авторы используют алгоритм Non-Maximum Suppression(NMS).
Итоги
В результате модель смогла показать mAP в 63.4% на датасете PASCAL VOC2007, сохраняя при этом возможность работать в режиме реального времени — 45 FPS. Для сравнения отметим, что у Faster R-CNN была только одна модель, которая может работать почти в реальном времени (18 FPS) и которая имеет более низкое качество — 62.1%. Однако в задаче детекции, когда FPS не важен, Faster R-CNN с VGG-16 работает лучше — 73.2% против 66.4% у YOLO VGG-16.
На датасете PASCAL VOC2012 YOLO набрала 57.4% против 70.4% у Faster R-CNN.
Авторы проанализировали ошибки и выделили основные недостатки модели:
- Плохая локализация объектов, особенно маленьких или расположенных группами, например, птицы или стада животных.
- Низкий recall.
Фан факт в подтверждение проблем с качеством: во время презентации YOLO на CVPR в 2016 году модель классифицировала выход за выступающим как туалет 🙂
Послесловие
В этой статье мы с вами подробно разобрали самую первую версию YOLO. YOLOv1 — глобальный прорыв в плане скорости и качества работы single shot подхода. Хоть она и не побила SOTA того времени, зато показала потенциал, скрывающийся в single shot детекторах.
В следующих частях мы узнаем, что смогли придумать авторы всего за пол года, чтобы создать SOTA детектор и как дальше развивалась история известной архитектуры. Продолжение следует, не пропустите!
Ссылки
Статьи:
- https://arxiv.org/abs/1506.02640 — YOLOv1;
Датасеты:
- http://host.robots.ox.ac.uk/pascal/VOC/voc2007/ — VOC 2007;
- http://host.robots.ox.ac.uk/pascal/VOC/voc2012/ — VOC 2012;
Полезные ссылки:
- https://en.wikipedia.org/wiki/Jaccard_index — описание IOU;
- https://ml.i-neti.ru/map-mean-average-precision/ — описание mAP;
- https://learnopencv.com/non-maximum-suppression-theory-and-implementation-in-pytorch/ — описание алгоритма Non-Maximum Suppression.