Предисловие
Данная статья рассчитана на читателя, который уже знаком со сверточными сетями (CNN) и хотя бы примерно понимает, как они работают. А тем, кто не знаком, советую просто поискать объяснения в интернетах и возвращаться обратно, так как тема CNN уже многократно пережевана и снято множество видео с разборами:)
Первая часть будет посвящена постановке задачи детекции и обзору первых алгоритмов. Последующие части будут уже про актуальные модели, в частности, про YOLO.
Введение. Кто такой детектор?😳
Ранее с CNN мы решали задачу классификации, где на вход модели подавалось изображение, а на выходе мы получали вектор вероятностей, где каждая компонента соответствует вероятности какого‑то класса.
В задаче детекции мы не только хотим знать КТО на изображении, но ещё и ГДЕ он находится. Положение объекта определяет прямоугольник, охватывающий объект и называется он Bounding box или в народе ббокс (красный прямоугольник на картинке сверху).
Ббокс описывается пятью числами: x, y, w, h, c
:
x, y
- иксовая и игрековая компоненты центраw, h
- ширина и высота соответственноc
- уверенность в том, что внутри этого ббокса вообще находится хоть какой-то объект
+ для каждого ббокса нам надо предсказать класс содержащегося внутри объекта.
Вот список популярных датасетов с разметкой для детекции:
Итак, еще разок. Модель должна предсказывать прямоугольники, в которых содержатся объекты + определять, к каким классам они принадлежат. Давайте немного погрузимся в историю и посмотрим, как люди начинали решать эту задачу.
Первый подход к решению задачи детекции. Sliding-window (скользящее окно)
Представим, что нам поставили задачу выделить прямоугольником лицо. Как бы мы её решали, если у нас уже есть обученная модель классификатора изображений?
Ну поскольку классификатор уже есть, и нужно просто понять, где находится объект — давайте сделаем окно, которое будет попиксельно двигаться по изображению и кропать (обрезать) его, а затем кропнутые изображения кидать в модель классификатора. Если классификатор выдаст высокую вероятность лица, значит оно нашлось и нашелся соответствующий прямоугольник🤩
Мы также хотим варьировать размер окна, чтобы улавливать объекты разной формы и масштаба, поэтому будет вложенный цикл по параметрам окна и по изображению. В целом такая схемка работает, но она очень неэффективная... Вот гифка того, как оно происходит для окна фиксированного размера:
Двухстадийные детекторы
Окей, скользящее окно не очень эффективно, поэтому надо думать дальше. А что если не перебирать втупую все возможные варианты положения объекта, а попробовать как‑то сузить круг поиска? Именно эта идея легла в основе архитектур двухстадийных детекторов. Двухстадийными они называются, так как сначала мы находим Default Boxes (наши гипотезы о местонахождении объекта), а затем уже, опираясь на них, даем ответ.
Архитектура R-CNN
R-CNN сужает поиск возможных положений объекта при помощи алгоритма Region Proposal (Selective Search). Данный алгоритм получает на вход изображение, а на выходе выдает массив прямоугольников, в которых возможно находится объект. При этом в основе алгоритма лежит классический Computer Vision (вдаваться в подробности этого алгоритма думаю нет смысла, так как на практике он уже давно не используется).
Итак, сначала мы запускаем на изображении Selective Search, а далее в цикле подаем кропы с этих регионов в классификатор. Ниже приведена архитектура из оригинальной статьи:
Помимо метки класса мы так же предсказываем поправки (offset) к прямоугольникам. т. е. дополнительно предсказываем соответствующие поправки к x, y, w, h
и строим функцию потерь для обучения, состоящую из потери для классификации и регрессии.
Теперь алгоритм стал эффективнее, чем просто полный перебор всех возможных местоположений, НО все равно не достаточно эффективно. Ведь для каждого региона нужно запускать классификатор. Например, что если Selective Search выдал 100 регионов, а наш классификатор это жирный VGG, который будет работать около секунды? Получается больше минуты на поиск объекта на одном изображении. Тут ни о каком риалтайме и речи идти не может, поэтому нужно думать дальше.
Архитектура Fast R-CNN
Что нам не понравилось в прошлой архитектуре? Конечно же запуск сверточной сетки для каждой гипотезы, полученной из Selective Search. Именно эту проблему решает новая архитектура Fast R‑CNN. Делает она это следующим образом:
Сначала мы прогоняем изображение через сверточную сеть и получаем Feature Map
Запускаем на изображении Selective Search и проецируем прямоугольники прямо на Feature Map. Например, если тензор исходного изображения был размерности
[3, 244, 244]
, а размерность выходного тензора после сверток[1, 32, 32]
, то для того, чтоб спроецировать координаты ббоксов, нам нужно просто посчитать aspect ratio и умножить на него соответствующие координаты ббоксов. Дальше уже просто делать кропы с feature map.Приводим ббоксы на feature map к одному размеру и в цикле пробрасываем их в полносвязный слой. За этот пункт отвечает процедура RoI Pooling (RoI — region of interest)
Что же поменялось? И тогда и сейчас мы запускали цикл по каждому предположению. НОО сейчас в цикле не запускается сверточная сеть, так как прямоугольники мы отмечали прям на feature map. Поэтому архитектура стала в разы эффективнее. Вот, кстати, схема из статьи с моим небольшим рисунком:
Ранее я говорил, что мы решаем две задачи в детекции: классификацию и регрессию (для корректировки прямоугольников), поэтому после FCs
мы видим разветвление. Выход из полносвязных слоев идет в softmax (для классификации) и в bbox regressor (для поправок к ббоксам). Далее строится мульти‑таск лосс, который выглядит примерно так (b — это поправки к прямоугольникам, c — вектор вероятностей классов):
Faster R-CNN
Это улучшение заменяет Selective Search на нейронную сеть. Теперь поиск ббоксов — это тоже обучаемый алгоритм под названием RPN. Цитата из оригинальной статьи: «The RPN is thus a kind of fully convolutional network (FCN) and can be trained end‑to‑end specifically for the task for generating detection proposals».
Идейно это единственное отличие. т. е. раньше у нас был Selective Search, который брал на вход картинку, генерил нам боксы, ресайзил их с нужным коэффициентом и накладывал на Feature Map, а теперь, в Faster R‑CNN, это делает отдельный модуль Region Proposal Network, который так же нам генерирует боксы на основе нашего датасета.
Думаю далее вдаваться в подробности RPN не имеет смысла, так как архитектура не актуальна на сегодняшний день. Тут скорее хотелось дать качественное описание того, что менялось:)
Заключение
Итак, мы разобрались с тем, что такое детекция, и какие были первые подходы к решению этой задачи. Некоторые идеи из двухстадийных детекторов продолжили своё существование в новых одностадийных детекторах, которым будет посвящена моя следующая статья. Если быть конкретнее, то речь пойдет про архитектуру YOLO и то, чем она так всем угодила.