Спираль времени, или новый End-to-End Object Detection with Transformers

На днях прочитал новую статью от Facebook AI, и прямо таки воспоминания ударили в голову, заставляя написать эту статью. Ведь это мои любимые темы:

  • “Всё новое – это хорошо забытое старое”
  • “Почему не стоит гнаться за бэкбоном, когда можно подобрать правильную логику сети и функции потерь”
  • “Почему бы не рассказать офигенную байку!”

Когда-то давным давно, когда я только только приходил к тому что нейроночки изменят ComputerVision окончательно (октябрь 2014), к нам пришёл потенциальный заказчик и сказал примерно следующее:

…. нужен следующий функционал:
Фотографируем витрину через мобильное приложение,
фото подвергается обработке, на выходе мы должны получить:
1. Название продукции, например, то что на полке стоит порошок Tide
2. Количество товара определенной продукции на витрине (например, порошок Tide – 4 упаковки, Ariel – 10 и т.д.)
3. цена соответствующего товара, например, Tide – 200 рублей. Ariel – 250 рублей и т.д.

На тот момент ещё не было:

Короче, мы немного потыкались, погуглили, попробовали плюс-минус стандартные на тот момент методы, да поняли что работать будет максимум на хорошо расставленных бутылках. Заказчик посмотрел-посмотрел, погрустил. На этом и разошлись.

Но с тех пор идея того “как же распознать эти чёртовы товары на полках” не покидала меня следующие пару лет.
И если в части “что делать после детекции” было более-менее понятно, то в части “как детектировать в хламе данных” – мозг вырубался.
Конечно, не сложно было распознать товары, когда их 5-6 в кадре. Но когда сотни?

Я понимал, что никакие SSD и YOLO не справятся из-за слишком простой функции NMS . Конечно, можно было бы делать свою логику поверх сегментации, но не было понимания как сделать это гарантированно работающим за конечное время.
На ресёрч без хотя бы какой-то оценки результата никакой заказчик не соглашался (хотя я такое предлагал).
Потом, сильно позже, множество таких подходов всплыло уже в 2017 в ходе Каггловского детектирования котиков (https://www.kaggle.com/c/noaa-fisheries-steller-sea-lion-population-count https://www.youtube.com/watch?v=PZfD-StZltk).

Время шло.. И в 2016 я внезапно натолкнулся на статью ReInspect (абсолютно непопулярная статья 2015 года, сорсы которой были выложены в 2016).

Статья была абсолютно безумна:

  • На тот момент TensorFlow ещё не существовало. А в Caffe не было рекуррентных сетей. Так что автор создал свой фреймворк поверх Caffe (назывался ApolloCaffe), в котором была поддержка lstm.
  • Функцию потерь которую использовал автор я встречал либо в работать о целераспределении из лохматых 60х годов, либо в модных фреймворках последние пару лет

Но в статье просматривалась логичная концепция что делать в случае перегруженности поля зрения объектами + были исходники чтобы проверить + приводились абсолютно офигенные примеры работы.

Я не поленился. Потратил несколько дней чтобы собрать этот проклятый фреймворк который даже на тот момент был устаревший (единственное что я нашёл на просторах инета про него – https://kenoung.github.io/week7post/ ).
Несколько дней потратил чтобы разметить те пару сотен картинок прилавков которые у меня были.
И несколько дней чтобы обучить.
Меня ждало чудо:

Конечно, по сегодняшним временам это может и выглядит просто. Но на 2016 меня пропёрло.

Потом мы внедрили эти подходы в 3 разных проекта, переписали на классический Caffe, чтобы это можно было хоть как-то эксплуатировать:

Ту сетку я всё же смог переписать на классический Caffe, что хоть и потребовало некоторое количество сноровки

Свой стартап, конечно, на эту тему делать не стали. Но на хлеб с маслом какое-то время хватало. Да и те две фирмы куда мы эти подходы внедрили – неплохо себя чувствуют, и присутствуют на рынке по сегодняшний день.

В чём была прелесть той работы?

Основной прикол был в том, чтобы используя бэкбон из Google-LeNet спрогнозировать несколько суперпикселей (каждый из которых соответствовал примерно квадрату 32*32 на входе + имел достаточно большую размерность). А потом поверх этих суперпикселей запустить рекуррентку, которая бы вместо NMS разобрала весь хлам.

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

Нужно ли говорить что эта статья вышла одновременно с YOLO и за пару месяцев до SSD (где была та же самая логики, но вместо рекуррентки была обычная регрессия по ближайшему объекту+ NMS).

Почему эта работа не стала популярна?

Гугл сколаршип говорит что-то типо 200 цитирований, звёзд на гитхабе было примерно столько же. Я думаю и вы не слышали про эту статью.

А не стала популярна она по простой причине: на всех популярных на тот момент датасетах, типа того же COCO – она давала бы низкую точность. Да и не могла особо работать. Работала она хорошо только на датасетах где было много объектов одного класса.
А таких датасетов открытых и известных на тот момент не было.

В результате авторы запускали на каком-то очень простом и тривиальном датасете, показывая абсолютно феерическую картинку:

Я уж не говорю что запустить ApolloCaffe могли единицы

End-to-End Object Detection with Transformers

Я думаю вы уже догадались почему статья FaceBook натолкнула меня на эти воспоминания? Потому что, блин, окружающий мир наконец развился до проблем того что близко расположенные объекты распознаются не очень. Конечно, есть синтетические методы как использовались в Kaggl.
Конечно, есть Mask-RCNN и разные Instance Segmentation.

Но хорошего End-to-end способного работать с bbox так и не появилось.

И что мы видим?

  • Эмбединги изображения
  • Позиционные энкодеры для этих эмбедингов (что в ReInspect задавалось неявно гиперпикселя)
  • Венгерский алгоритм для распределения целей

Очевидно, что DETR лучше чем ReInspect. Хотя бы потому что его сильно проще обучить, он поддерживает большое разнообразие классов (что позволило ему отбенчмаркаться на классических датасетах типа COCO):

Но, если честно, то больше всего меня возмущает отсутствие упоминания работы которая сделала всё то же самое пять лет назад:)

З.Ю.

В последнее время свои статьи я публикую на очень разных платформах.
И, так получилось, что единое место куда я их свожу тут – https://vk.com/cvml_team

Так что советую подписаться!