Вы еще живы после прочтения прошлых двух частей, смогли их осилить и готовы двигаться дальше? Хорошо. В этой части закрываем тему DETRов.
Pretraining
Да-да, мы помним, DETR долго обучается. А что если его предобучить, да ещё и в self-supervised манере?
UP-DETR (2020)
303 цитирования, 443 звёздочки
Идея максимально простая - берём рандомный кроп из изображения, засовываем его фичи в queries, и просим DETR предсказать координаты этого кропа. Авторы сразу подмечают, что если это сделать максимально просто, то мы столкнёмся с парой проблем:
раз мы просто сетку решать только задачу локализации, то мы уничтожим классификационные фичи
на одном изображении обычно много объектов, так что лучше просить сетку предсказать несколько кропов
Чтобы скормить кроп картинки декодеру, фичи кропа сначала преобразуются в вектор с помощью AdaptiveAvgPool2d, приводятся к нужному размеру (обычно 256) линейным слоем, а затем ещё зануляется 10% получившейся репрезентации. Получившуюся штуку приплюсовываем к традиционным learnable positional queries из DETR. Стоит отметить, что вся картинка и патч прогоняются через один и тот же CNN-бэкбоун раздельно.
Для решения проблемы отсутствия задачи классификации в такой схеме претрейна, вводится дополнительная задача - по аутпуту декодера будем восстанавливать исходные фичи кропа (после адаптивного пулинга). Кроме того CNN-бэкбоун во время претрейна заморожен и вместе с DETR не обучается.
Механизм предсказания нескольких кропов тоже реализован достаточно просто. Все queries делятся на количество групп, равное количеству кропов. К каждой группе добавляются фичи одного из кропов. Поскольку в реальных задачах queries не связаны ни в какие группы, для каждого батча порядок queries перемешивается, то есть, каждый раз образуются случайные группы. Логика группового разделения такая - это позволяет сети научиться делать дедубликацию похожих предиктов внутри группы queries. Традиционно группы не взаимодействуют между собой благодаря этеншн-маске.
Такой механизм позволяет претрейнуть DETR, если у вас есть большой неразмеченный датасет из такого же домена, что на практике встречается достаточно часто.
DETReg (2021)
44 цитирования, 302 звёздочки
Главный минус подхода UP-DETR - мы пытаемся предсказать расположение рандомных патчей, на которых может вообще не быть никаких объектов, может быть часть объекта или несколько объектов. Короче говоря, UP-DETR не учится находить реальные объекты. Подход DETReg отличается - давайте возьмём какой-нибудь простой метод поиска потенциальных мест интереса, например, Selective Search, который использовался ещё в R-CNN до появления RPN. Selective Search - это старый алгоритм, который эксплуатирует тот факт, что объекты часто однородны по цвету и имеют продолжительные непрерывные границы. Задача сетки - найти области, которые выплюнул этот алгоритм. Можно искать рандомные K областей или отсортировать их в иерархическом порядке - от наибольших регионов к наименьшим. Как и в UP-DETR, в такой задаче отсутствуют классы и задача классификации. Для решения этой проблемы найденные регионы кодируются отдельной претрейнутой сеткой, а задача DETReg - восстановить эти эмбеддинги. В общем-то это всё.
Дистилляция
DETRы могут бить по метрикам классические детекторы, но обучаются медленнее. А что если дистиллировать знание обученных детекторов в DETRы? К сожалению, оказывается, что известные методы дистилляции для детекторов не очень хорошо работают для передачи знаний DETRам. В этом разделе рассмотрим методы дистилляции, разработанные специально под эту архитектуру.
Teach-DETR (2022)
В качестве конкурентов своему подходу авторы берут три проверенных метода дистилляция для детекторов.
Первый метод - это FGD. Он основан на дистилляции на уровне фичей, только вот простая дистилляция для детекции работает плохо - слишком велик обычно дисбаланс FG и BG, а дистилляция только по FG не так уж и докидывает по метрикам. Авторы предлагают модуль фокальной дистилляции, который отдельно дистиллирует фичи бэкграунда и объектов. Добавляются всякие дополнительные фишки - учитываются размеры GT-объектов, степень FB-BG имбаланса, сильнее дистиллируются “пиксели” и каналы, которые играют более важную роль. Ещё используется модуль глобальной дистилляции, основанный на GcBlock. Не буду углубляться в детали, про дистилляцию детекторов можно писать отдельный пост, но вкратце мы пытаемся заставить сеть-ученика выучивать те же глобальные зависимости между фичами, которые есть в сети-учителе.
Второй метод - FKD. Снова похожее обоснование неуспешности обычных методов на детекторах, снова нелокальная дистилляция, и в целом довольно похожая статья.
Наконец, последний конкурсант - DeFeat, который тоже на основан на идее, что дистилляция бэкграунд-фичей полезна для сети-ученика. Но здесь дистиллируются уже не только фичи, но и вероятности из RPN. Аналогично фокальной дистилляции из FGD, фичи делятся на две части по бинарной GT-маске и дистиллируются с разными весовыми коэффициентами. Примерно то же самое делается и для вероятностей пропозалов из RPN.
Заканчиваем краткий экскурс в дистилляцию и возвращаемся к Teach-DETR. Напоминаю, что мы изначально в интересной ситуации - дистиллировать мы пытаемся модель Mask-RCNN, метрики которой ниже чем у DETR. В итоге все три упомянутые метода дистилляции через фичи ухудшают метрики. Идея следующая - раз архитектуры, лоссы и фичи двух сеток такие разные, давайте забьём на дистилляцию фичей и будем дистиллировать только конечные предикты - то есть, боксы.
Одна проблема всё равно остаётся - DETR использует one-to-one матчинг, и если просто добавить к GT набор предиктов Mask-RCNN, ничего хорошего не получится. Вместо этого используется идея, отдалённо похожая на Group DETR. Queries для разных групп GT-боксов (как оригинальных, так и учительских, которых может быть несколько в зависимости от количества моделей-учителей) используются одни и те же, а вот матчинг делается независимо для каждой группы. Лоссы в конце просто суммируются для всех групп.
На выходе получаем рост AP на 1 пункт по сравнению с оригинальным H-Deformable DETR. Почему это всё вообще работает? Авторы предлагают три объяснения:
От учителя приходят в том числе новые боксы, которые не были размечены в оригинальном датасете.
Учитель может исправлять классы для некоторых шумных боксов.
Учитель может передавать информацию о каких-то внутренних свойствах объектов - например, насколько сложен тот или иной объект для правильной классификации или локализации.
DETRDistill (2022)
В этой статье речь идёт о дистилляции между двумя DETRами разных размеров. Помимо дистилляции на уровне фичей в качестве опции рассматривается дистилляция на уровне предсказанных лоджитов. В качестве примера приводится Localization Distillation, которая в свою очередь базируется на идее из очень любопытной статьи Generalized Focal Loss. GFL использует IoU GT-коробки и предсказанной коробки в качестве софт-таргета вероятности, а координаты объекта предсказывает как распределение вероятностей по возможным координатам. Вообще у меня очень велик сейчас соблазн свалиться в эту кроличью нору, так что пишите комментарии и ставьте лайки, если хотите больше статей про детекцию. Если не терпится, то подробнее изучить код generalized focal loss можно здесь.
Короче говоря, предлагается три компонента, отвечающих за дистилляцию. Увы, кода нет, поэтому и описание будет довольно общее.
Во-первых, используем предикты учителя как псевдо-разметку и с помощью всё того же венгерского матчинга находим лучшее соответствие между предиктами учителя и ученика. Увы, наивная имплементация не приносит много буста - ведь используются только немногочисленные позитивные предикты, которые к тому же ещё и обычно похожи на GT-коробки. Так что матчим и queries, не предсказавшие объект, и по ним тоже проводим дистилляцию. Для матчинга используются только боксы, без лоджитов. Дистиллируется отдельно каждый слой декодера (в ученике может быть и меньше слоёв).
Дистиллируются и фичи, причём вес для каждого “пикселя” увеличивается, если на него него похожи content queries, которые хорошо предсказывают объекты на данном изображении. Немного странно, что берутся не усреднённые веса из cross-attention, а именно перемножение матрицы фичей (HxWxd) и матрицы queries (Mxd).
Наконец, чтобы облегчить проблему нестабильного матчинга между GT-боксами и queries, которая уже много раз упоминалась выше, предлагается использовать стабильные, хорошие queries учителя. С помощью них генерируется матчинг GT-боксов и queries ученика. Как - я (и некоторые ревьюеры) понял не до конца, кажется, что queries учителя матчятся с GT, а queries ученика уже заматчены с queries учителя. Получаем некий транзитивный матчинг.
Метод не только докидывает при self-distillation (одинаковая архитектура учителя и ученика), но и позволяет передавать знания от моделей с большим количеством слоёв энкодера/декодера и моделей с большим бэкбоуном.
D3ETR (2022)
Как и в DETRDistill, в качестве главной проблемы выделяется отсутствие явного матчинга между предиктами учителя и ученика. В общем-то прям в статье написано “DETRDistill is the most related work to ours”. Для матчинга используется две стратегии:
Адаптивный матчинг аналогично DETRDistill - матчатся предсказания с минимальной суммарной стоимостью матчинга.
Фиксированный матчинг - к ученическим queries добавляем вспомогательные учительские, и матчим их аутпуты с аутпутами учителя (не по стоимости матчинга, а просто по индексу). Несмотря на одинаковые исходные queries, аутпуты учителя и ученика могут по-разному заматчиться с GT-коробками, поэтому для ученика используется оптимальный матчинг учителя.
Дистилляция производится на трёх уровнях - веса self-attention, веса в cross-attention, предсказания.
KS DETR (2023)
1 звёздочка
Здесь DETR дистиллирует сам себя прямо внутри энкодера. В последний энкодер-слой добавляется два дополнительных этеншна, которые прокидывают информацию в первый, основной этеншн. Лишние слои на инференсе отбрасываются.
Основная идея заключается в том, чтобы помочь энкодеру выучить более релевантные веса для этеншна. Сначала на основе известных GT-коробок генерируется бинарная маска (красный квадрат на картинке выше) - есть в конкретном “пикселе” какой-то объект или нет. Эта маска используется для обогащения входных фичей X. Бэкграунд-“пиксели” не изменяются, а “пиксели” с объектами пропускаются через линейный слой с релу-активацией. Такое вот выборочное усиление сигнала. Во второй этеншн в качестве Q и K идут обогащённые фичи, в качестве V - обычные. В третьем наоборот - обогащается V.
Получается, что второй этеншн выдаёт более качественные этешн-веса, но использует те же V, что и основной этеншн, что “заставляет” выучивать более качественные V. Третьий этеншн получает более релевантные V и шарит этеншн-веса. Все три аутпута отдельно прогоняются через декодер, затем считается суммарный лосс. Читаю я, конечно, это описание - выглядит как бред сумасшедшего.
Но в целом идея не очень сложная - используем GT-разделение на FG и BG для ускорения обучения. Такая процедура позволяет этеншну легче обучаться, куда обращать внимание - ведь чаще всего нам нужны именно foreground-”пиксели” с объектами.
С облегчением
DETR, особенно оригинальный, является достаточно тяжёлой архитектурой. Cross-attention, несколько слоёв энкодера и декодера - всё это ведёт к высокой вычислительной сложности. Статьи в этом разделе предлагают способы решения именно этой проблемы.
Sparse DETR (2021)
44 цитирования, 133 звёздочки
Очень симпатичная статья с несложной идеей. Казалось бы, Deformable DETR решает проблему квадратичных вычислений в энкодере - теперь каждый токен этендится на фиксированное число токенов вне зависимости от размера картинки. Однако, инференс при этом становится медленнее! Как так?
Причина кроется в использовании multi-scale пирамиды фичей - в ней тупо очень большое число токенов. А нужно ли нам действительно их все обновлять в энкодере? На самом деле нет, ведь декодер смотрит на довольно ограниченное количество токенов - в основном на те, где есть какие-то объекты. Если мы сможем найти эти токены, то можно в энкодере обогащать глобальной инфой только их, и тем самым сэкономить нехилое количество вычислений.
Сделать это можно как-нибудь простым способом - например, с помощью RPN-модуля, который будет предсказывать по CNN-фичам, где находятся важные токены. Но это не очень хорошо, не факт, что мы сможем найти все токены, на которые важно будет смотреть декодеру. Авторы предлагают очень элегантное решение - давайте просуммируем все этеншн-веса со всех слоёв декодера и обучим сетку, которая по тем же CNN-фичам будет предсказывать, на какие токены будем смотреть этеншн. Для ванильного DETRа просуммировать эти веса очень просто, для Deformable DETR лишь капельку сложнее.
На каждой итерации будем суммировать эти веса и выбирать фиксированный процент самых важных токенов со всех уровней пирамиды. Этим токенам присваиваем лейбл 1, остальным - 0, и накладываем на предикты обычный BCE-лосс. Всё, теперь у нас есть модуль, который позволяет предсказывать токены, на которые, скорее всего, будет обращать внимание декодер. С целью экономии ресурсов “неважные” токены в энкодере обновлять не будем (то есть, не будем включать их в множество Q), но них могут этендиться “важные” токены - таким образом может происходить передача от невыбранных токенов к выбранным.
В общем-то это основная идея. В качестве дополнительных фишек предлагается:
Добавить вспомогательные лоссы не только в декодер, но и в энкодер. Каждый “важный” токен на каждом слое будет предсказывать какую-то коробку, и мы можем накладывать обычный matching loss.
Аналогично Efficient DETR предлагается инициализировать content queries из аутпута энкодера. Для этого мы можем взять top-k токенов согласно предсказанию дополнительной objectness головы.
Оказывается, что даже используя всего лишь 10% токенов, можно получить результаты аналогичные Deformable DETR.
PNP-DETR (2021)
30 цитирований, 123 звёздочки
В большинстве доменов картинки в основном состоят из бэкграунда без объектов. На эти области тратится большое количество вычислений в self-attention энкодера и в cross-attention декодера. При этом в бэкграунде всё-таки может содержаться полезная для детекции информация, хотя и в избытке. Поэтому в отличие от Sparse DETR авторы предлагают не отказываться от бэкграунда целиком, а компактнее упаковать его перед подачей в трансфомеры.
Первый новый модуль называется Poll Sampler. Это небольшая сеточка (конв-релу-конв-сигмоид), которая выдаёт скоры для каждого “пикселя” CNN-признаков. Сортируем все признаки (предположим, их L= H*W) по убыванию скора, берём топ-N из них - это наши основные фиче-векторы, на которых, вероятно, содержатся объекты. Отобранные фичи пропускаются через LayerNorm и домножаются на скор, чтоб Poll Sampler мог обучаться через бэкпроп (через индексы torch.topk градиент не течёт). N фиксирован и не зависит от картинки, хотя авторы и подмечают, что для разных картинок может быть оптимальным разное количество фичей.
Второй модуль называется Pool Sampler. В нём и заключается основная фишка архитектуры, он нужен для того чтобы собрать информацию из большого количества неотобранных фичей (K = L - N) и агрегировать их в M новых фичей такой же размерности, где M - какое-то небольшое число, скажем, 60. Эти K фичей пропускаются через ещё одну сеточку (линейный-релу-линейный), которая для каждой фичи выдаёт вектор из M весов. Далее софтмакс нормализует их по измерению фичей. То есть, если взять первый элемент этого вектора для каждой из фичей, то их сумма будет равна единице. Затем K неотобранных фичей пропускаются через линейный проекционный слой. Наконец, с помощью полученных векторов весов M раз складываем с разными весами K фичей. На письме звучит заумно, но идея по факту не такая сложная - разными способами агрегируем большое количество бэкграунд-фичей, чтоб получить их более сжатую репрезентацию. Positional-энкодинги для этих фичей получаются аналогичной агрегацией с использованием тех же весов.
Результаты работы Poll Sampler и Pool Sampler просто напросто конкатенируются и подаются в энкодер. На картинке справа изображены карты плотности весов. Отобранным фичам из Poll Sampler присваивается вес 1, а для остальных берётся суммарный вес из Pool Sampler. Мы видим, что большая часть выбранных фичей относится к объектам, а также используются некоторые бэкграунд-локации.
L-DETR (2022)
DETR можно облегчить просто - например, снизить количество слоёв энкодера и декодера, не использовать уровни фича-мап с большим разрешением, уменьшить размер feedforward-слоёв. Всё это снижает метрики, но часто не сильно.
Авторы L-DETR предлагают ещё пару несложных идей:
Заменить бэкбоун на более лёгкий, основанный на архитектуре PP-LCNet (для скорости)
Заменить релу-активации в трансформере на hard-версии из MobileNetV3 (для стабильности обучения и частично для скорости)
Заменить layer normalization на group normalization в декодере
Lite DETR (2023)
2 цитирования, 103 звёздочки
Описание будет добавлено на этой неделе
Архитектурные трюки
В этом разделе собрались DETRы с разными архитектурными трюками, которые не попали ни в одну из групп. О каких-то расскажу подробнее, о каких-то - коротко, а то статья уже подкатывается к ста тысячам знаков…
WB-DETR (2021)
15 цитирований
Попытка выкинуть CNN из игры - оставляем только энкодер и декодер, при этом энкодеру на вход идут патчи оригинального изображения как в ViT. Давайте покопаемся в архитектуре:
Первым делом режем картинку на патчи одинакового размера (можно с перекрытием), делаем их плоскими и прогоняем через линейную проекцию, чтоб привести к желаемой размерности. К получившимся токенам прикрепляем обучаемые positional embeddings.
При такой схеме обработки картинки локальная информация хранится только внутри токена. В теории токены могут обмениваться информацией, но в любом случае понятно, что моделирование локальной информации в таком подходе хуже, чем с использованием CNN. Это может быть критично для задачи детекции. Для решения этой проблемы в конце каждого слоя энкодера добавляется специальный модуль LIE-T2T. Он основан на модуле T2T, который работает очень просто - токены обратно собираются в матрицу, соседние патчи окном с перекрытием собираются в длинные токены (длины kxkxc, где k - сторона окна, на картинке k=2). Для усиления определённой локальной информации внутри токенов поверх обычного T2T на эти длинные токены дополнительно накладывается этеншн на каналы (а-ля Squeeze & Excitation). После этого токены можно вернуть в нужный размер линейной проекцией. Сама размерность фиче-мапы при этом будет уменьшаться, в статье ничего про это не говорится, но в T2T используется паддинг, полагаю, что и тут тоже.
Такие дела. Количество параметров падает, метрики не хуже, LIE-T2T докидывает по сравнению с T2T.
Miti-DETR (2021)
8 цитирований, 2 звёздочки
Статья, полностью основанная на выводах другой статьи с очень необычным названием Attention is Not All You Need. Оказывается, если из self-attention сетки убрать skip-connection и MLP, то её аутпут с большой скоростью скатывается к матрице с рангом 1, то есть, по сути все её строчки становятся одинаковыми независимо от инпута. На картинке ниже изображена стандартная self-attention сеть с H головами этеншна, между слоями обычно вставляют MLP (в оригинальном DETR с двумя линейными слоями).
Дальше следует немалое количество линейной алгебры, которое ведёт к тому, что результат работы такой сети с L слоями можно представить в виде суммы результатов работы всех возможных “путей”:
На картинке два разных “пути” обозначены красным и синим цветом. Например, из первого слоя мы берём результат работы второй головы этеншна, на втором идём через скип-конекшн и так далее. Таким образом, такую сеть можно интерпретировать как ансамбль более простых сетей с одной (или нулём) этеншн-головой в каждом слое.
Благодаря такой декомпозиции, можно облегчить анализ работы сетки и рассматривать упрощённую сеть с одной головой. Возьмём инпут-матрицу X и найдём для неё такой вектор x, который при вычитании из каждой строчки X, минимизирует L2-норму полученной матрицы (она здесь называется residual). Если эта норма в какой-то момент будет равна 0, это значит, что все строчки матрицы идентичны. Так вот, оказывается, что в чистых self-attention-сетях норма residual убывает с двойной экспоненциальной скоростью, соответственно и ранг X быстро скатывается в 1.
А skip-connection как раз помогает решить эту проблему - например, существует путь, который пропускает вообще все слои self-attention и множество неглубоких путей, которые используют только несколько голов этенша.
Возвращаясь к Miti-DETR - само изменение очень-очень простое, несмотря на относительную сложность лежащей за этим математики. По сути, в каждом слоё энкодера и декодера мы просто добавляем к выходу слоя его вход. Демонстрируется, что это ускоряет convergence и улучшает метрики по сравнению с ванильным DETR.
CF-DETR (2021)
7 цитирований
Сравнение всех моделей детекции всегда проходит одинаково - берём COCO и считаем AP@[.50:.05:.95] - то есть average precision с IoU-порогом от 0.5 до 0.95 с шагом 0.05. Такой выбор метрики благоволит моделям, которые очень точно локализуют боксы объектов. В этой статье предлагается очень разумная вещь - давайте посмотрим, как ведут себя модели на другом диапазоне IoU-порогов - например, с 0.1 до 0.5. Вообще, проблеме корректного выбора метрик уделяется слишком мало внимания - подробнее можно почитать здесь, здесь и здесь.
Так вот, оказывается, что при низких IoU-порогах DETR работает на маленьких объектах так же или даже лучше, чем классические детекторы Faster-RCNN и Sparse-RCNN. То есть, DETR нормально находит любые объекты, но не может их точно локализовать. Если для вашей задачи нужна корректная локализация небольших объектов - можно посмотреть на этот подход. Сама статья написана нудновато, постоянно везде в тему и не в тему суют слово “novel”, но в целом идея достаточно простая.
Основная идея - добавить в архитектуру несколько модулей, которые будут обогащать DETR локальной информацией и позволять более точно предсказывать координаты коробок:
Первый модуль на картинке называется “Transformer Enhanced FPN”. По сути, это обычный FPN, но фичи последнего уровня берутся из трансформер-энкодера. Следующий уровень (четвёртый) собирается из этих фичей и CNN-фичей того же уровня. По итогу получается пирамида фичей, обогащённая одновременно глобальными фичами энкодера и локальными CNN-фичами каждого уровня.
Декодер начинается как обычно - self-attention + cross-attention. По итогу получаем предикты координат, которые мы называем “coarse”, то есть грубые. Теперь мы хотим их уточнить с помощью некоего fine-слоя.
Аналогично классическим двухстадийным детекторам, мы с помощью coarse-координат и модуля RoIAlign можем спулить нужные фичи из пирамиды. Вместо использования эвристики для выбора уровня пирамиды используется особый модуль Adaptive Scale Fusion, который агрегирует RoI-фичи, спуленные со всех уровней. При этом используется информации из object query.
Наконец добавляется модуль local cross-attention, который выполняет роль обычного cross-attention, на спуленных локальных фичах. В качестве Q выступает object query (кажется, используется сумма positional и content, как в оригинале), расширенный до размеры фича-мапы, в качестве K - фичи после depthwise-конволюции, в качестве V - фичи после 1x1-конволюции. Почему так сложно? Да бог его знает, якобы для облегчения использования локальной информации. В итоге мы получаем аутпут декодера, обогащённый локальной информацией.
Эти дополнительные слои можно повторять несколько раз внутри одного слоя декодера. Да, я сам немного в шоке. Итоговые лоджиты берутся из последнего coarse-слоя, а коробки - из fine.
Вот такая вот несколько запутанная статья, но мне понравилась изначальная мотивация - поглубже изучить метрику и понять, в чём конкретно проблема (как в фреймворке TIDE).
DETR++ (2022)
3 цитирования
Я не очень понял, почему эта статья вышла в 2022, почему в ней не цитируются многие другие и много чего ещё не понял. Суть крайне простая - берём BiFPN-слой и накладываем его несколько раз на пирамиду фичей. В энкодер в итоге идёт последний уровень C5, обогащённый информацией из других слоёв пирамиды. Эту идею они сравнивают с несколькими другими вариациями, но особого внимания они не стоят. BiFPN докидывает на маленьких объектах по сравнению с ванильным DETR.
Backpropagating through Hungarian (2022)
Интересная деталь - форвард-пасс венгерского матчера в DETR обёрнут в torch.no_grad(). Действительно, венгерский матчинг - это комбинаторный оптимизационный алгоритм, и градиент через него не прокинуть. Вместо этого мы находим оптимальный матчинг, и используем только его, игнорируя
В этой статье рассматривается очень интересный вопрос - а можно ли честно оптимизировать сетку, если она содержит модуль с комбинаторной оптимизацией? В статье есть отдельная секция, посвящённая разным способом решения этой задачи. Метод, который в итоге используется, описан в статье Differentiable Combinatorial Losses through Generalized Gradients of Linear Programs.
Есть проблема - метрики с таким лоссом получаются намного хуже. Но мне всё равно статья показалось достаточно любопытной, так что решил её включить.
DESTR (2022)
7 цитирований
Вариант Conditional DETR с тремя основными модификациями:
Для генерации референс-точек и content queries используется отдельный мини-детектор, который навешивается на фичи энкодера. В данном случае используется FCOS.
Cross-attention в каждом слое декодера делится на две части - одна отвечает за классификацию, а другая за локализацию.
Самое эзотерическое изменение - self-attention в декодере превращается в некий pair self-attention. Идея такая - обычно наибольшее влияние на object query оказывает его ближайший сосед. Помимо этого, этеншн-вес между двумя объектами обычно снижается, если один из объектов частично закрыт каким-то соседним объектом. В общем, для каждого query находится его ближайший сосед (по IoU между предсказанными боксами), и этот сосед конкатенируется к object query, и attention вычисляется между этими парными репрезентациями.
Все три изменения суммарно добавляют почти три пункта AP по сравнению с ванильным Conditional DETR.
Honorable mentions
Хоть я и обещал рассказать только об обычной 2D-детекции, несколько статей всё-таки захотелось упомянуть.
What makes for end-to-end object detection? (2022)
Что позволяет DETRу (почти) не делать дублированных предиктов в отличие от классических детекторов? Ответ кажется очевидным - one-to-one матчинг между предиктами и GT (см. NMS Strikes Back (2022)) и self-attention. На самом деле ситуация чуть интереснее
Авторы заменяют one-to-many матчинг на основе IoU в RetinaNet, CenterNet и FCOS на one-to-one матчинг. Например, в RetinaNet в качестве единственного позитивного сэмпла для каждой GT-коробки берётся бокс с наибольшим IoU. Любопытно - при такой схеме обучения NMS всё ещё заметно повышает метрики. Оказывается, что дело не только в схеме матчинга, но и в критерии, по которому рассчитывается стоимость матчинга. В DETR при нахождении оптимального матчинга учитывается не только степень пересечения коробок, но и корректность предсказания класса. Если изменить критерий, и использовать не только IoU, но и предсказанные вероятности, то классические детекторы практически перестают предсказывать дубликаты. Такая модификация и отказ от NMS позволяют значительно поднять метрики на датасетах с большой плотностью объектов
Хорошее напоминание, что стоит изучать каждый компонент вашей сетки и подгонять его под вашу задачу. Например, в некоторых медицинских задачах для матчинга предиктов и GT-боксов можно использовать Boundary IoU или Intersection-over-Reference.
AO2-DETR (2022)
Модификация DETRа для решения задачи детекции, где коробки могут быть повёрнуты на любой угол. Я когда-то подумывал использовать Oriented-RCNN в задаче детекции полей на повёрнутых документах, но в итоге мы поступили проще - предварительно стали выравнивать сам документ. Но задача более чем актуальна для детекции объектов на спутниковых изображениях.
Основная идея тут такая же - просто добавляем угол поворота в список аутпутов, которые должна предсказывать сетка. Есть, конечно, куча нюансов - например, конволюционные фичи не очень приспособлены для по-разному повёрнутых объектов, которые ещё и имеют разный размер, так что авторы добавляют специальные модули, которые обогащают исходные фичи с учётом пропозалов, сгенерённых сеткой.
Omni-DETR (2022)
Интересный фреймворк для обучения, основанный на DETR. Он позволяет использовать любые аннотации, которые есть в наличии - точки на объектах без классов и с классами, классы без локализации, коробки без классов, количество объектов каждого типа. Поверьте, такой зоопарк лейблов встречается в медицине сплошь и рядом.
В сеть-учитель поступает исходное изображение с лёгкой аугментацией, для которого генерируется обычное предсказание - коробки и классы. Это предсказание фильтруется с помощью разметки, которая доступна для этой картинки. У нас есть K предсказаний и G каких-то лейблов, нам нужно найти оптимальный матчинг между ними, и оставить только те боксы, которые заматчились с GT-разметкой. Например, если мы знаем, что на изображении находятся три овцы и лошадь, то мы оставляем три топовых бокса для овец и один для лошади. Если нам дополнительно известна точка на объекте, то к стоимости матчинга добавляется расстояние между центром предикта и этой точкой. В общем, для любой комбинации слабых лейблов можно найти множество предиктов, которое лучше всего ему соответствует. Эти предикты и становятся GT-разметкой для сети-ученика, в которое поступает изображение с сильной аугментацией.
Мы у себя использовали такую фильтрацию для генерации псевдо-разметки, которая не противоречит известной слабой разметке (например, заключению врача). В общем-то, для реализации такой схемы обучения совсем необязательно использовать DETR.
Points as Queries (2021)
Ещё одна идея, направленная на использование более дешёвой разметки - предлагается вместо коробок использовать для каждого объекта любую точку внутри этого объекта. Для использования такой разметки вводится дополнительный модуль, который трансформирует точки в object queries.
HOI Transformer (2021)
Модификация для предсказания взаимодействия между людьми и объектами (human object interaction, HOI). Архитектурно всё достаточно просто - object queries заменяются на HOI queries, по которым затем предсказываются бибоксы человека, объекта, и конфиденсы человека, объекта и действия. Оптимальный матчинг тоже находится по всем пяти предиктам.
Не забудьте подписаться на Варим ML в ТГ!