Назад
219

YOLO history (Part 4)

219

Введение

Здесь можно почитать о том, как начиналась наша серия статей 🙂
  • Part 1. Мы познакомились с архитектурой YOLO, ее уникальностью, сильными и слабыми сторонами YOLOv1.
  • Part 2. Узнали о новых трюках YOLOv2 и о том, как авторы смогли обучить модель предсказывать более 9000 классов.
  • Part 3. Детально рассмотрели последние изменения создателя архитектуры YOLO — Джозафа Редмона.

Итак, Джозаф Редмон сообщает о прекращении работы над YOLO (по идеологическим соображениям), но не выступает против ее развития другими. После этой новости целых два года мир не увидит новой версии архитектуры. А в апреле 2020, в разгар ковида, Алексей Бочковский и группа исследователей из Тайваня выпустят новую версию YOLO.

Возникает закономерный вопрос: почему именно эти авторы? На самом деле, имя Алексея здесь появляется не случайно. Он много лет активно участвовал в развитии darknet-фреймворка (на нем написаны предыдущие YOLO), а еще создал программу для разметки с целью наиболее легкого обучения YOLOv2/v3.

Джозаф прокомментировал выход статьи:

Рисунок 1. Вольный перевод твита: “Не важно, что я думаю! Каноничная версия darknet и yolo принадлежит Алексею Бочковскому, он вложил много сил в их развитие, и все этим пользуются, теперь это не мое, хаха”

Поэтому несмотря на смену авторов, YOLOv4 — каноничное продолжение семейства. Более того, новая архитектура полностью соответствует философии YOLO — это небольшая и быстрая модель на darknet’e, которая за один проход решает задачу детекции.

YOLOv4 (YOLOv4: Optimal Speed and Accuracy of Object Detection)

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

Изменения коснулись и архитектуры, и самого подхода к обучению и постпроцессингу. Следовательно, авторы вводят два понятия:

  1. Bag-of-freebies — набор методов для увеличения точности модели за счет усложнения обучения (и без влияния на скорость инференса). К таким методам относятся, например, аугментации, изменение лосса, шедулерры.
  2. Bag-of-specials — набор методов для увеличения точности модели за счет небольшого уменьшения скорости инференса. Это изменения в архитектуре и методы постпроцессинга.

В статье авторы экспериментируют с широким набором аугментаций и блоков. Мы сосредоточимся только на тех методах, которые повысили итоговое качество модели:

Рисунок 2. Список bag-of-freebies и bag-of-specials для предобучения бекбоуна и обучения основного детектора (источник: https://arxiv.org/abs/2304.00501 table 3)

Первый столбец таблицы показывает трюки для создания и обучении бекбоуна, второй — для YOLOv4.

Backbone’s bag-of-specials

Давайте начнем распутывать клубок под названием YOLOv4 с устройства бекбоуна.

В луших традициях YOLO, в качестве бекбоуна была выбрана обновленная версия Darknet53 — CSPDarknet53. Авторы экспериментировали также с CSPResNeXt50 и EfficientNet-B3, но Darknet их победил.

Основные отличия CSPDarknet53 от Darknet53:

  • использование Cross Stage Partial блоков вместо residual блоков;
  • замена активации LeakyRelu на Mish.

Cross Stage Partial (CSP) block

Для начала напомним, как выглядит Darknet53:

Рисунок 3. Архитектура Darknet53 из residual блоков. Один блок Conv2D — последовательное применение конволюции, батч-нормализации и функции активации (С → BN → A)

Для улучшения качества авторы заимствовали из статьи CSPNet идею разделения фич на 2 группы и использования сверток только к одной из этих групп (правая ветка на рисунке 4). Ко второй части применяется конволюция 1х1 для выравнивания числа каналов. Затем 2 группы фичей снова конкатенируются вместе. Итоговый блок выглядит так:

Рисунок 4. CSP Residual block — основной блок в CSPDarknet53. Первая конволюция выполняется со страйдом 2, размер изображения уменьшается в 2 раза (обозначается \2)

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

В зависимости от места в сети количество CSP Res Unit-ов меняется.

Mish

Mish — это ReLU-подобная активация с непрерывной производной в районе нуля.

Рисунок 5. График mish-активации

Математически она записывается следующим образом: \( f(x) = x * tanh(ln(1 + e^x)) \) , где \( ln(1 + e^x) \) — это softplus.

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

Backbone’s bag-of-freebies

Как и раньше, бекбоун обучали решать задачу классификации на ImageNet. Ради хорошего качества авторы перепробовали много трюков. Интересный факт: модель с наилучшим качеством классификации не смогла показать тот же результат в задаче детекции.

Самой лучшей классификационной моделью стала CSPResNeXt50, но среди детекторов выиграл CSPDarknet50.

Для обучения оптимального бекбоуна использовали mosaic augmentation, CutMix, DropBlock, class label smoothing. Давайте разбираться со всем по порядку 🙂

Mosaic augmentation

Основная идея аугментации — случайное совмещение 4-х картинок из датасета. Она должна научить сеть распознавать объекты без опоры на контекст. Выглядит это вот так:

Рисунок 6. Пример mosaic augmentation

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

Примерные лейблы для картинки выше:

labels = {
	"anemone_fish": 0.2,
	"ice_bear": 0.25,
	"african_elephant": 0.35,
	"lemon": 0.2
}

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

Рисунок 7. Пример работы mosaic augmentation для задачи детекции

CutMix

Идея аугментации — замена некоторой части картинки на другую картинку. Например, замена головы собаки на голову кошки, как на рисунке ниже. Такой подход также позволяет модели избежать переобучения под контекст.

Рисунок 8. Пример CutMix

Как и в случае с mosaic augmentation, лейблы заменяются пропорционально долям классов на изображении. Для примера выше итоговые лейблы будут выглядить таким образом:

labels = {
	"dog": 0.6,
	"cat": 0.4
}

DropBlock

Это своего рода dropout для конволюционных слоев. Поскольку в сверточных сетях есть большая пространственная корреляция, зануление случайных одиночных фичей никак не повлияет на обобщающую способность слоя. Например, на центральном изображении (рисунок 9) видно, как после зануления фичей важная пространственная информация о наличии собаки в кадре сохраняется. DropBlock, в свою очередь, позволяет занулить целые области фичей. Это побуждает модель искать новый контекст, на который можно опереться.

Рисунок 9. Исходная картинка (слева), зануление случайных фичей (центр), DropBlock (справа)

Class label smoothing

Class label smoothing — метод, который уменьшит переобучение модели за счет сглаживания лейблов.

На практике он заменит единицу у правильного класса в векторе лейблов на меньшее значение, например, на 0.9. Тогда из вектора labels = [0.0, 0.0, 0.0, 1.0, 0.0] получится вектор smoothed_labels = [0.0, 0.0, 0.0, 0.9, 0.0].

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

Detector’s bag-of-specials

Также как и в YOLOv3, детектор YOLOv4 можно разделить на 3 части:

  1. Бекбоун — CSPDarknet53.
  2. Шея (neck) на основе модифицированной версии Path Aggregation Network (PAN) с использованием Spatial Pyramid Pooling layer’a (SPP) и Spatial Attention Module (SAM).
  3. Голова (head) из YOLOv3 (3 выходных тензора разного размера).

Detector’s neck

Архитектура YOLOv3 построена на основе Feature Pyramid Network. Ее основная идея — создание UNet-образной модели со скипконекшеннами и несколькими головами. Схематично это выглядит так:

Рисунок 10. FPN в YOLOv3

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

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

PAN пытается решить данную проблему за счет добавления дополнительного потока обогащения признаков:

Рисунок 11. YOLOv4 на основе PAN

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

Авторы YOLOv4 использовали модифицированную реализацию PAN — вместо операции сложения в блоке аггрегации (блок “С” на рисунке 11) авторы применили конкатенацию.

Spatial Pyramid Pooling (SPP)

Этот слой сети находится сразу после CSPDarknet53. Схематично его можно представить следующим образом:

Рисунок 12. SPP для YOLOv4 (источник)

То есть к исходному набору фичей одновременно применяется несколько max pooling слоев с паддингом для сохранения изначального размера. Затем итоговые фичи конкатенируются обратно.

Идея этого слоя — получить глобальный контекст всего изображения. Ведь после бекбоуна рецептивное поле (receptive field) все еще не будет покрывать изображение целиком. В YOLO использовались пуллинги размером 13, 9 и 5.

Spatial Attention Module (SAM)

Авторы не обошли стороной и популярный на тот момент механизм внимания. Они взяли SAM за основу, убрали операции пуллинга и оставили один конволюционный слой:

Рисунок 13. Spatial Attention Module: исходная реализация (верх) и YOLOv4 SAM (низ)

После применения сигмойды значение фичей ограничится между 0 и 1, поэтому его можно воспринимать как степень важности каждой отдельно взятой фичи в исходном наборе.

Идея слоя — перевзвешивать карту фичей для выделения самых важных признаков и зануления неважных. Особенность механизма внимания в YOLO: для каждой фичи в исходном наборе подбирается уникальный вес, а не один вес для пространственного вектора фичей, как обычно.

Изменения выходных фичей (Eliminate grid sensitivity)

Итак, нам осталось поговорить о выходе сети. В статье авторы сообщают, что используют подход из YOLOv3 без изменений. На самом деле, это не совсем так. Они нашли крайний случай, где этот подход работает плохо. Давайте вспомним предыдущие части, чтобы понять суть проблемы.

На выходе из сети мы получаем около 10 тысяч векторов длиной 255 (при условии 3-х якорей на каждый выход сети: формально 3х(5+C), где C — количество классов, C=80 для COCO). Каждый вектор хранит в себе информацию о размерах ббокса, вероятность нахождения в текущей ячейке центра объекта и вероятность принадлежности к классам. Во второй части наших статей мы рассказывали, что размеры ббокса хранятся в виде смещений по формуле:

\( b_x=\sigma(t_x)+c_x\\ b_y=\sigma(t_y)+c_y\\ b_w=p_we^{t_w}\\ b_h=p_he^{t_h}\\ \)

  • где \( t_x, t_y, t_w, t_h \) — предсказания модели
  • \( c_x,c_y \) — координаты левого верхнего угла ячейки
  • \( p_w, p_h \) — априорные значения высоты и ширины анкера
  • \( \sigma \) — сигмойда
  • \( b_w, \ b_h \) — размеры ббокса
  • \( b_x, \ b_y \) — координаты центра ббокса соответственно

Подход работает плохо, если истинная координата центра находится на границе ячейки, то есть \( b_x = c_x \) или \( b_x = c_x + 1 \). Поскольку \( t_x \) должен принимать либо большое отрицательное значение, либо большое положительное. Другими словами, это крайние случаи, когда нам нужно либо занулить сигмойду, либо приблизить ее к единице.

Для решения проблемы авторы выполняют следующие операции: сначала определяют константу больше 1. Она называется scale_x_y в конфиге YOLO. Итоговые размеры ббокса считаются следующим образом (для х и у одинаково):

\( b_x = (\sigma(t_x) * S — \frac{S-1}{2}) + c_x \)

\( b_y = (\sigma(t_y) * S — \frac{S-1}{2}) + c_y \)

\( b_w=p_w*(\sigma(t_w) * S)^2 \)

\( b_h=p_h*(\sigma(t_h) * S)^2 \), где S — та самая константа.

Изменения постпроцессинга, или DIoU-NMS

Вместо Non Maximum Suppression (NMS) как раньше, авторы решили использовать его улучшенную версию — Distance-IoU Non Maximum Suppression.

Главное отличие DIoU-NMS от NMS: применение Distance IoU вместо IoU.

Если IoU считает долю пересечения между ббоксами, DIoU еще учитывает расстояние между центрами ббоксов.

Формально это выглядит следующим образом:

\( IoU = \frac{B \cap B^{gt}}{B \cup B^{gt}}; \quad DIoU = IoU — \frac{\rho^2(b,\ b^{gt})}{c^2} \)

  • где \( B \) — предсказанный ббокс
  • \( B^{gt} \) — истинный ббокс
  • \( \rho \) — евклидово расстояние между координатами центров предсказанного (\( b \)) и истинного (\( b_{gt} \)) ббоксов (красная линия на рисунке 15)
  • \( с \) — длина диагонали минимального прямоугольника (синия линия на рисунке 15), покрывающего два ббокса
Рисунок 14. Визуализация IoU
Рисунок 15. Визуализация добавочной части DIoU

В результате DIoU-NMS выглядит так:

Рисунок 16. DIoU-NMS. Решение отбросить ббокс принимается на основе IoU и расстояния между ббоксами

Здесь \( R_{DIoU}(M, B_i) = \frac{\rho^2(b,\ b^{gt})}{c^2} \), где \( s_i \) — уверенность, предсказанная для ббокса, а \( \varepsilon \) — трешхолд из NMS.

Тут \( M \) — ббокс c наибольшим скором, \( B_i \) — ббокс-кандидат на удаление.

Запись выше означает, что все ббоксы, DIoU которых будет больше трешхолда, удалятся.

Таким образом, добавленное расстояние позволит не удалять ббоксы, которые сильно пересекаются, но имеют большое расстояние между центрами. Это означает, что ббоксы соответствуют разным объектам на картинке.

Detector’s bag-of-freebies

Для обучения детектора авторы использовали очень много трюков: от аугментаций (Mosaic, Self-Adversarial Training) и регуляризаций (DropBlock) до особого подхода к работе с ббоксами (Eliminate grid sensitivity, Multiple anchors for single gt) и обучению сети (CIoU-loss, CmBN, Cosine annealing scheduler). Но обо всем по порядку 🙂

Для обучения детектора использовалась аугментация Self-Adversarial Training. Сначала мы делаем обычный форвард: пропускаем изображение через сеть, считаем лосс и градиенты. Затем посчитанные градиенты применяем к изображению так, чтобы максимально ухудшить предсказание сети (это еще называется self adversarial attack). На последнем этапе снова отправляем изображение в модель, считаем лосс и градиенты, а веса модели обновляются. Такая аугментация помогает модели генерализовать предсказания и избежать переобучения.

Cross mini-Batch Normalization (CmBN)

При обучении на батчах большого размера обычно используют процедуру gradient accumulation: разбивают большой батч на несколько мини-батчей, для которых поочередно делается forward модели. Затем полученные градиенты аггрегируются и применяются к модели. Обычная батч-нормализация в таком случае будет считать статистики по каждому отдельному мини-батчу, следовательно, статистики получатся очень шумными (мини-батчи маленькие по определению). CmBN же предлагает накапливать статистики следующим образом:

Рисунок 17. Пример использования CmBN для 4-х мини-батчей

На картинке выше представлен пример для 4-х мини-батчей. Нам важны индексы над accumulate BN. На первом мини-батче статистики считаются (и применяются) только по первому мини-батчу (обозначение t_3). На втором — уже по двум мини-батчам (t_3 и t_2). На следующем — по трем и так далее.

Обучение

Авторы обучили модель с помощью тренировки на разных размерах, как и в предыдущих версиях YOLO. Но они изменили лосс функцию для обработки ббоксов. Во-первых, авторы заменили квадратичный лосс, который использовался в YOLOv3 на CIoU-loss.

Мы уже разобрали выше IoU и DIoU. CIoU — модификация DIoU, которая плюсом к расстоянию между центрами учитывает соотношение сторон ббоков. Формально CIoU считается следующим образом:

\( CIoU = IoU — \frac{\rho^2(b,\ b^{gt})}{c^2} — \alpha \upsilon, \text{ где } \alpha = \frac{\upsilon}{(1-IoU) + \upsilon} \)

По словам авторов, \( \upsilon \) отвечает за консистентность соотношения сторон ббоксов:

\( \upsilon = \frac{4}{\pi^2}(arctan\frac{w^{gt}}{h_{gt}} — arctan\frac{w}{h})^2 \)

Где \( {w^{gt}}\text{ и }{h^{gt}} \) — ширина и высота истинного ббокса, а \( w \text{ и } h \) — предсказанного.

Поскольку мы хотим минимизировать функцию потерь, CIoU лосс будет записываться таким образом:

\( \mathcal{L}_{CIoU} = 1 — IoU + \frac{\rho^2(b,\ b^{gt})}{c^2} + \alpha \upsilon \)

В остальном численный расчет лосса не изменился (подробнее про него можно почитать в предыдущей части).

Другие изменения

Помимо всех вышеперечисленных трюков авторы использовали и другие:

  1. Сosine annealing scheduler — шедулер для изменения лернинг рейта у оптимизатора. Авторы не применяли restart, то есть learning rate постепенно уменьшался со старта обучения и до самого конца:
Рисунок 18. График уменьшения learning rate в зависимости от количества эпох
  1. Подбор гиперпараметров для сети с помощью эволюционных алгоритмов (фактически они случайным образом выбирали несколько наборов параметров для обучения модели, а затем выбирали лучшие из моделей и переобучали их).
  2. Использование нескольких якорей для одного истинного ббокса при расчете лосса. Так как из-за особенностей якорныых методов детекции, для целевого объекта может подходить несколько якорей, поэтому в YOLOv4 используется подход при котором в лоссе могут учитываться несколько позитиынвх пар якорь — целевой объект. Формирование таких пар определяется по следующему критерию: IoU (truth, anchor) > IoU threshold.

Итоги

  1. Авторы смогли сохранить философию YOLO и внести огромный вклад в развитие этого семейства.
  2. Они переосмыслили модель YOLO, что позволило достичь топ 1 качества в задаче детекции на MS COCO среди real-time моделей.
  3. Итоги в цифрах: \( AP_{50} \) у YOLOv4 = 64.9% против 55.3% у YOLOv3 для моделей с FPS ≥ 30.

Интересный факт: практически во всех реализациях YOLOv4 вы не найдете SAM блоков перед выходами. Его нет даже в конфиге, который авторы приложили в статье на медиуме. Если вы знаете причины — поделитесь своим мнением в комментариях 😊

Заключение

С выходом YOLOv4 Алексей и команда доказали, что семейство real-time моделей может развиваться без участия Джозафа Редмона. YOLOv4 — модель, которая идет в ногу со временем и использует самые современные (на 2020 год) решения в области (от новых блоков и аттеншенов до использования другого лосса и постпроцессинга).

Интересно, что же придумают исследователи, чтобы побить качество данной модели? Об этом мы узнаем в следующих частях серии ☺️

Ссылки

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

DeepSchool

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

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

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

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