Назад
182

YOLO history (Part 6)

182

Введение

  • Погружение в дивный мир YOLO-семейства 😎
    • Part 1. Знакомимся с архитектурой Yolo, её уникальностью, сильными и слабыми сторонами YOLOv1.
    • Part 2. Рассказываем о трюках YOLOv2 и о том, как авторы смогли обучить модель предсказывать более 9000 классов.
    • Part 3. Подробно рассматриваем нововведения от создателя архитектуры YOLO — Джозафа Редмона.
    • Part 4. Разбираемся со внушительным числом аббревиатур, которые появились в новой версии YOLO после ухода Джозафа.
    • Part 5. Отвечаем на животрепещущий вопрос: в чём разница между 4-ой и 5-ой версиями YOLO.

Выход новой версии YOLO снова создал инфоповод в научном сообществе. И причиной этому послужили не только технические нововведения, но и неожиданный порядок выхода моделей. Как и две предыдущие части, 6-ая и 7-ая версии появились практически одновременно. При этом YOLOv7 вышла на 2 месяца раньше YOLOv6! YOLOv7 — 6-го июля 2022 года, а YOLOv6 — 7-го сентября 2022 года.

Почему так произошло? Всё просто: YOLOv6 создавалась исследователями из AI-лаборатории в Meituan (Китайский ритейлер), а разработкой YOLOv7 занималась другая команда. Возможно, авторы заранее договорились о нейминге, но в последний момент что-то пошло не так. Забавный факт: в статье про YOLOv6 есть сравнение с YOLOv7.

Рисунок 1. Мем, подходящий для описания этой ситуации 🙂

У вас может возникнуть вопрос: с чем связано двухлетнее затишье? Ведь даже пока мы публикуем эту серию статей в DeepSchool, вышло ещё две новых архитектуры! 🤯

Давайте вспомним, чем весь мир занимался в 2020-2021 годах? Сидел дома и ничего не делал пережидал ковид. Скорее всего, исследователи решили пропустить конференции 2021 года, спокойно дописать статьи и подать их на конференции 2022 года.

Тем не менее в это время научное сообщество активно выпускало новые версии семейства, называя их с помощью заглавных букв. Например, группа исследователей, написавших YOLOv4, создала версию YOLOR. В ней авторы работали над многозадачным обучением (multi-task learning): создавали модель, способную решать несколько задач одновременно.

Ещё одна интересная работа — YOLOX. Она вышла в свет в 2021 году благодаря команде Megvii (Face++). От неё авторы YOLOv6 позаимствовали anchor-free decoupled head, которую мы подробно разберём чуть позже.

Также после выхода YOLOv4 развивается параллельная версия YOLO-моделей — PP-YOLO. Это семейство разработано в Baidu с использованием их платформы для обучения PaddlePaddle. Поэтому они и имеют префикс PP. Всего было создано три архитектуры: PP-YOLO, PP-YOLOv2 и PP-YOLOE. Авторы YOLOv6 пробовали использовать некоторые наработки из PP-YOLOE, однако в финальную архитектуру они не вошли.

YOLOv6: A Single-Stage Object Detection Framework for Industrial Applications

YOLOv6 не так популярна, как YOLOv5. Однако её активно используют в Китае, поэтому авторы до сих пор развивают свою модель, но об этом поговорим чуть позже. А сейчас давайте рассмотрим исходную версию архитектуры, которую предложили авторы.

Основные изменения YOLOv6:

  • применение различных блоков в бэкбоне для ахритектур разного размера:
    • RepBlock для маленьких моделей (N и S)
    • CSPStackRep для больших (M и L)
  • модифицированная архитектура PAN в качестве шеи — Rep-PAN;
  • слегка изменённая Anchor-Free Decoupled Head из YOLOX в качестве старой головы — Efficient Decoupled Head;
  • новый лосс как следствие anchor-free подхода;
  • использование Task Alignment Learning (TAL) для назначения лейблов и повышения качества итоговой модели;
  • множество пост-оптимизаций (квантизация, дистилляция) для улучшения производительности.

RepBlock vs CSPStackRep Backbone

Зачем нужно было использовать различные бэкбоны для разных размеров модели? Чтобы улучшить качество и ускорение инференса. Что ж, логично. Давайте рассмотрим особенности блоков, которые используются в различных бэкбонах:

💡 Справка, которая пригодится чуть ниже:

  • single-path — модели, где есть всего один путь, по которому проходят данные. Нет скипов, конкатенаций фичей и др. Например, AlexNet, VGG.
  • multibranch — остальные модели с более сложной архитектурой, наличием скипов и др. Например, ResNet, DenseNet.

RepBlock — максимально простой single-path блок, который состоит из нескольких RepVGG блоков:

Рисунок 2. RepBlock (a) — основной блок в YOLOv6n и YOLOv6s при обучении модели. RepConv (b) — тот же блок, но во время инференса

Используя reparameterization trick при инференсе, мы можем представить RepVGG как один конволюционный блок 3х3 (см. Рисунок 2 (b)). Это значительно сокращает время инференса.

Кроме того, авторы RepVGG показали, что маленькие single-path модели:

  1. Обладают большей обобщающей способностью в сравнении с multibranch.
  2. Гораздо лучше параллелятся, что позволяет значительно сократить время обучения и инференса.

CSPStackRep — уже multibranch-блок, максимально приближенный к блокам С3 из YOLOv5. Выглядит он следующим образом:

Рисунок 3. CSPStackRep

Итоговый бэкбон авторы назвали EfficientRep Backbone. Это RepBlock или CSPStackRep, идущие вперемешку с одиночными конволюциями.

Rep-PAN Neck

Шея YOLOv6 практически не отличается от шеи предыдущих моделей. Тут также используется PAN-архитектура, но вместо блоков С3 из YOLOv5 здесь либо RepBlock’и (для N и S моделей), либо CSPStackRep блоки (для М и L моделей).

Рисунок 4. Итоговая архитектура YOLOv6

Efficient Decoupled Head

В предыдущих версиях YOLO применяется Coupled Head — одна конволюция 1х1, которая выравнивает число каналов для предсказания ббоксов и классов. Соответственно, один конволюционный слой решает одновременно две задачи: классификацию и регрессию.

На самом деле такой подход негативно влияет на качество модели. Другие детекторы того времени используют головы, где фичи для классификации и регрессии проходят через разные конволюционные слои. Например, голова YOLOX выглядит так:

Рисунок 5. Сверху: Coupled Head. Снизу: Decoupled Head в YOLOX

То есть сначала фичи проходят через конволюцию 1х1, затем случается разделение на две параллельные ветки с двумя конволюционными слоями 3х3. Классификационный выход проходит через один дополнительный конволюционный слой 1х1 для выравнивания числа каналов, а регрессионный выход делится ещё на две ветви для предсказания расположения ббокса и objectness score.

В YOLOv6 авторы внесли два изменения:

  1. Убрали один коноволюционный слой 3×3.
  2. Начали шкалировать количество параметров внутри блока (например, для YOLOv6n — 32, 64, 128 соответственно).

Anchor-based vs Anchor-free

Anchor-based подход обладает одним серьёзным недостатком: перед обучением детекционной модели нужно определить размеры исходных анкеров. От выбора анкеров напрямую зависит качество модели. Поэтому есть множество способов определения самых подходящих анкеров для конкретного датасета.

💡 Recap: в предыдущих версиях YOLO все три выхода имели набор карт фичей разного размера (для изображения 640х640 выходы будут 52х52, 26х26, 13х13 соответственно). Каждый вектор фичей имеет длину \( 3х(5+C) \), где \( 3 \) — количество анкеров (или якорей); 5 — количество фичей для определения положения итогового ббокса, а также уверенности в наличии объекта в этом месте; С — количество классов датасете. Подробное описание вы можете почитать тут.

Чтобы не тратить время на выбор анкеров и не откладывать обучение модели, авторы использовали anchor-free подход. Из названия мы видим, что здесь нет необходимости подбирать анкеры. Как тогда он работает?

Перед ответом на этот вопрос предлагаем минутку на размышление: а была ли такая YOLO, где нет якорей?

Ответ 🙂

В первой версии YOLO нет якорей! Там координаты ббокса предсказываются относительно границы ячейки, а итоговый ббокс выбирается из самых близких к центру объекта. Вот круг и замкнулся!

Рассмотрим один из трёх выходных векторов YOLOv6: у них одинаковые фичи, которые различаются только размером.

Выход модели — вектор фичей:

\( output = (x,\ y,\ w,\ h,\ c,\ p_0, …,\ p_{(n-1)}) \)

\( x,\ y \) — координаты центральной точки ббокса относительно ячейки с предсказанием;

\( w,\ h \) — ширина и высота ббокса;

\( c \) — confidence score, или уверенность наличия центра объекта в заданной ячейке;

\( p_0,…,\ p_{(n-1)} \) — вероятности принадлежности к каждому из $n$ классов.

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

\( c_x = x + i*s\\c_y=y+j*s \)

где \( i,j \) — координаты ячейки с предсказанием;

\( s \) — stride, или расстояние между соседними ячейками относительно исходного изображения. Для каждого выхода сети оно будет разным.

Действительно, очень схоже с YOLOv1, однако 6-ая версия в разы обгоняет её по качеству. Почему так произошло? Во-первых, Rep-PAN архитектура позволила проще детектировать объекты разного размера. Во-вторых, по-другому стала решаться проблема bbox assignment’a. Что это и зачем нужно решать? Давайте разбираться 🙂

Bbox assignment

На самом деле мы уже разговаривали об этом в предыдущих частях. Напомним, что bbox assignment отвечает за выбор ббоксов, которые будут учитываться при расчёте регрессионного лосса, значит, напрямую влиять на предсказание размеров будущих ббоксов.

Для anchor-based детекторов мы подробно описали весь процесс в прошлой части (тык). В двух словах: в лоссе участвуют только якоря из ячеек, пересечение которых с таргетом больше трешхолда \( anchor_t \). Это делается ещё до предикта модели с поправкой на аугментации.

В случае с anchor-free подходом всё обстоит сложнее. У нас уже нет якорей, чтобы определить положительные ббоксы для конкретного объекта. Есть несколько вариантов решения этой задачи, самый простой из них: учитывать в регрессионном лоссе только предсказание из ячейки, расположенной в центре объекта. Или предсказывать вероятность того, что в конкретной ячейке расположен центр объекта, как в YOLOv1. В новых статьях используют другие методы:

Рисунок 6. Пример различных методов bbox assignment’a [источник]

На картинках видно, какие пиксели (или фичи выходного слоя) будут участвовать в регрессионном лоссе. В нашем случае всё будет даже сложнее, ведь у YOLO три выходных слоя — для каждого из них нужно делать отдельную процедуру отбора подходящих ячеек. Например, для FCOS-детектора с несколькими выходами отбор пикселей, из которых будут выбраться ббоксы, выглядит следующим образом:

Рисунок 7. Отбор позитивных ячеек (синий цвет) для выходов разного размера на примере FCOS-детектора [источник]

Авторы YOLOv6 для решения bbox assignment’а выбрали подход Task Alignment Learning (TAL).

Task Alignment Learning

Большинство методов для bbox assignment’a при выборе ббоксов использует размеры и положение ббоксов, но при этом никак не учитывает класс, предсказанный для заданного ббоска.

Чтобы учитывать как пересечение предсказанных ббоксов с таргетами, так и предсказанные классы, авторы использовали алгоритм Task Alignment Learning. Его придумали исследователи TOOD — ещё одного one-stage детектора, идейно схожего с YOLO.

Основные шаги Task Alignment Learning:

  1. Посчитать значение метрики для одного предсказанного ббокса (pred): \( t = s^\alpha * u^\beta \) где \( s \) — classification score, или вероятность принадлежности предсказанного ббокса к классу реального ббокса; \( u \) — IoU между предсказанным (pred) и реальным ббоксами (gt); \( \alpha,\ \beta \) — нормализационные константы, обычно \( \alpha = 6.0, \ \beta = 1.0 \).
  2. Отфильтровать pred на основе gt. Тогда последующей выбор предсказаний будет проводиться только среди pred, сделанных в ячейках, центры которых расположены внутри любого gt.
  3. Для каждого gt выбрать несколько (обычно 5) самых подходящих pred ббоксов.
  4. Если pred рассматривается в качестве подходящего для нескольких gt — выбрать gt с наибольшим пересечением по IoU.

В итоге получаем набор предсказаний, для которого и будет считаться лосс. На самом деле первые 4 эпохи обучаются с использованием автосгенерированных якорей через ATSS — это позволяет сделать первые шаги обучения более стабильными.

Обучение

Для обучения модели авторы применяли два типа лоссов: классификационный и регрессионный. Давайте рассмотрим каждый из них подробнее.

Классификационный лосс

В качестве классификационного лосса был выбран VariFocal Loss (VFL). В отличие от своего предшественника, Focal Loss’а, VFL учитывает негативные и позитивные примеры асимметрично. Формула выглядит следующим образом:

Рисунок 8. Varifocal loss. Верхняя часть используется для положительных примеров (когда предсказание пересекается с реальным ббоксом), нижняя — для отрицательных

Где p — предсказание модели, q — так называемый таргет IACS, \( \gamma,\ \alpha \) — параметры из Focal Loss’a для нивелирования дисбаланса классов.

IACS таргет (q) — обычный таргет с поправкой на IoU между предсказанным ббоксом и таргетом. Схематично он выглядит так:

Рисунок 9. Varifocal Loss [описание из статьи]

На рисунке представлено 2 ббокса: предсказанный (синий) и истинный (красный). Для этой пары q будет примерно равен 0.8 для правильного класса (пункт (b) выше). То есть даже классификационный лосс косвенно учитывает положения ббоксов. Фактически в этом лоссе зашит как локализационный лосс из предыдущих частей серии (подробнее можно прочитать здесь), так и focal loss, позволяющий перевзвешивать классы.

Регрессионный лосс

Авторы не остановились на одном варианте и выбрали несколько лоссов для моделей разного размера. Для обучения YOLOv6-N и YOLOv6-T они использовали SIoU, для остальных версий — GIoU.

С IoU и различными модификаторами мы знакомились в посте про 4-ую версию, поэтому напомним здесь только его общий вид:

\( IoU = \frac{B \cap B^{gt}}{B \cup B^{gt}} \), где

  • \( B \) — предсказанный ббокс;
  • \( B^{gt} \) — истинный ббокс.

SIoU, или SCYLLA Intersection over Union

Верхнеуровнево SIoU состоит из 4-х частей: поправка за угол, расстояние, размер и IoU. В нашем посте мы не будем раскрывать эту тему подробно, но при желании вы можете прочитать статью авторов тут.

GIoU, или Generalized Intersection over Union

GIoU добавляет к исходному IoU коэффициент С — он показывает размер минимально выпуклой оболочки, покрывающей оба ббокса. Выглядит он так:

\( GIoU = IoU — \frac{(C \backslash (B \cup B^{gt})}{|C|} \)

Это позволяет модели лучше исправлять ошибки, если предсказание не совпадает с истинным ббоксом: чем ближе будет предсказание к нему (даже без пересечений), тем меньше будет GIoU.

Другие фишки

  • Помимо классификационного и регрессионного лоссов авторы проводили эксперименты с другими добавками. Например, при обучении YOLOv6-M/L они использовали вероятностный лосс, в качестве которого выступал Distribution Focal Loss (DFL).
  • Для увеличения итогового качества и ускорения инференса авторы отключали mosaic агументации на последних эпохах обучения. Чтобы лучше распознавать объекты по краям, к исходному изображению можно допаддить серую границу (так делали в YOLOv5 и YOLOv7). Авторы выяснили, что падение качества связано с наличием паддинга серыми границами в mosaic аугментации. Поэтому удаление аугментации позволило повысить устойчивость модели.

Результаты

Рисунок 10. Метрики YOLOv6 в текущем мастере
Рисунок 11. Метрики YOLOv5 в текущем мастере

Мы видим, что YOLOv6 на всех размерах показывает результат выше, чем YOLOv5. На момент выхода версии метрики 6-ой YOLO были ниже, но и YOLOv5 тогда была хуже. Авторы приводят следующий график:

Рисунок 12. Сравнение архитектур YOLO на датасете COCO

Из графика видно, что новая архитектура значительно опережает предыдущие (и не только) версии YOLO на всех размерах. Всё ещё удивительно видеть тут YOLOv7, которая работает хуже, но об этом мы поговорим в следующей части 😉

Помимо опережения по качеству модель сильно выходит вперёд и по скорости. Для этого авторы использовали несколько трюков. Их можно применять прямо из коробки в их репозитории:

  • дистилляция: можно включить при обучении, если поставить флаг --distill или --distill_feat;
  • квантизация: туториалы;
  • репараметризация с использованием RepOptimizer: туториал.

Заключение

Выход новой модели был хорошо принят в сообществе, особенно в Китае, поэтому авторы не остановились на достигнутом и продолжили её развитие.

За 2 года они успели сделать 4 крупных релиза в репозитории, повысив качество исходных моделей, а в 2023 году выпустили новую статью — YOLOv6 v3.0. В ней авторы значительно трансформировали основную модель и добавили большие версии исходных моделей. Главным изменением стало появление anchor-aided training’а (AAD), который позволил обучаться с использованием anchor-free и anchor-based подходов одновременно, при этом не снижать скорость инференса!

Полезные ссылки

Телеграм-канал

DeepSchool

Короткие посты по теории ML/DL, полезные
библиотеки и фреймворки, вопросы с собеседований
и советы, которые помогут в работе

Открыть Телеграм

Увидели ошибку?

Напишите нам в Telegram!