Привет! Я занимаюсь разметкой данных для ИИ: экспертно и с большой любовью. Задачи компьютерного зрения — одни из самых популярных и поэтому поговорим про них.
Прочитав статью вы узнаете как алгоритму отличить гейшу от китаянки, кто такая майко, как не перепутать лапшу с автобусом и правильно найти тунца.
Практически сразу после выхода zero-shot модели SAM (Segment Anything Model) для компьютерного зрения мы с командой активно ее внедрили в свою платформу разметки данных и стали использовали в разных задачах.
Хочется поделиться опытом и ответить на самый популярный вопрос — насколько SAM ускоряет разметку данных?
В статье будет очень много гифок и интерактива.
Коротко о SAM, и почему он полетел в Осаку
В двух словах о том, что вообще это за штука SAM (если сильно упростить) — это модель, которая на входе получает картинку, а на выходе выдает автоматически размеченные объекты на ней. Ее можно прицепить к вебу — и это будет интерактивная разметка по клику, то есть, мы кликаем в произвольную область картинки, а модель подсказывает что за объект находится в этой области. Этот принцип лучше сразу показать визуально, что на множестве примеров и будет сделано ниже.
Статью про наш опыт с реальными задачами использования SAM я пытался написать раза четыре, но каждый раз ̶с̶ж̶и̶г̶а̶л̶ ̶р̶у̶к̶о̶п̶и̶с̶и̶ то упирался в NDA по заказчикам и результатам, то получалось много цифр и было ничего не понятно. SAM это в первую очередь вау-визуал, поэтому было решено вместо цифр просто набрать множество интерактива и прицепить его к реальным задачам из жизни.
Причем здесь Япония?
Япония здесь пригодилась тем, что на ней получилось найти элегантное решение, а именно — совместить технологии и лёгкий блоггинг. То есть, написать такой отчет о туристической поездке, где под каждой фото будет интересный факт о стране и вытекающая из него абстрактная задача японского быта и способы ее решения с помощью компьютерного зрения и SAM в частности.
Все фотографии мои, и они самые обычные на самый обычный телефон — это сделано специально, чтобы показать как модель работает в реальных условиях. И если фото реальны, то задачи абсолютно вымышлены, а все совпадения или аналогии с нами реально решаемыми — случайны.
Поехали!
Что вы знаете про Японию?
Про Японию часто принято думать, что там уже давно наступило то самое кинографичное будущее с летающими автомобилями, но в жизни все сильно проще. Японская культура необычна и удивительна, сама страна очень комфортная для туризма и продуманная в мелочах, но именно поэтому обновлять свой быт технологиями японцы не очень спешат. Вот тут-то мы им и поможем. (ᵔᴥᵔ)
Все точно знают про гейш. Начнем с них!
Здесь важно пояснить, что многие задачи можно решать очень разными способами и только замеры и эксперименты подскажут что эффективнее. Поэтому примеры ниже — это максимально упрощенные и разбавленные юморком задачи для более простой демонстрации SAM в них.
Определяем гейшу на фото
Скорее всего, первая «гейша», которую вы увидите в Японии будет обычный туристкой (вот как на фото выше), которая взяла костюм в аренду (это жутко популярная услуга в крупных городах).
Но настоящую гейшу (а их всего несколько тысяч осталось) отличает строгое следование традициям. Весь культ гейш в Японии не описать в две строчки, но нам будет достаточно того, что у внешнего вида гейши (и у юных учениц на гейш, которых зовут майко) есть явные отличительные черты.
Мне посчастливилось сфоткать на улице гейшу, а точнее — ученицу майко. Вот на ней все и отработаем — сделаем разметку данных.
Мы будем определять майко по кимоно, поясу и прическе (прическа так вообще целый отдельный японский мир). Прическа причудливой формы называется варэсинобу и состоит из шелковой ленты (красная или зеленая - зависит от возраста), шпильки и украшения.
Так как в гифку маленького размера ОЧЕНЬ сложно уложить много смысла (и из-за лимитов их пришлось переделывать много раз), я буду вырезать все лишнее и на каждом примере показывать анимацию только самого яркого момента.
На правах первой задачи ниже выделение в увеличенном масштабе (400%) чтобы еще лучше оценить как это работает. Обратите внимание, что клики бывают двух типов — добавляющие контекст (у нас — зеленые) или убавляющие его (красные).
А вот картинкой финальный итог выделения вместе с тегированиями каждого выделения. Для спокойного изучения, так сказать.
Какие-то цифры, чтобы сделать вывод насколько SAM ускоряет разметку, кажется, тут и не очень нужны, а мы ведь только начали этот эксперимент. Феноменально, и это все сделано исключительно на кликах.
Но что же нужно проделать, чтобы такая интерактивная разметка в браузере заработала?
Технический комментарий
Если опустить все детали, то простыми словами магия случается следующим образом.
Есть большая тяжелая модель на бэкенде, которая обсчитывает картинку и строит по ней эмбединг (embedding или low resolution tensor, как зовут его авторы) — закодированное техническое представление всех объектов и их характеристик внутри картинки.
В браузер встраивается легкая декодирующая модель (через wasp и onnx бинарные файлы), которая запускается на основе определенной постобработки эмбединга с кликами и на выходе отдает onnx-маску, которая затем трассируется в svg. И как итог — мы получаем набор точек полигона, которые уже можно вывести поверх картинки.
Сложности в этом процессе — будут в конце статьи.
Находим офисного работника
Если гейши наряжаются как слоеный пирог самыми разными вещицами, то современные офисные самураи носят только один костюм — собственно, костюм. Черный. Строго черный! Давайте возьмем фотку в обычный обеденный перерыв в деловом квартале Токио и найден нам ней офисных работников.
Обратите внимание, как интересно модель спроектирована — иногда при клике на более контрастную часть тела, выделяется именно она, а не весь силуэт. Но при следующем клике на другую часть — модель не плюсует одну к другой, а выдает сразу силуэт — как наиболее ожидаемый пользователем вариант.
Про это стоит сделать визуал подробнее. Здесь же модель смогла угадать продолжение объекта (третий выделяемый человек), хотя его часть перекрыта другим объектом.
Это работает и в обратную сторону — если сначала выдался силуэт, то убавляющими кликами модель может разбить маску на те объекты, из которых предположительно она состоит.
Грубо говоря, первоначально каждый большой (или отличающийся) объект складывается из трех меньших масок (с разными весами), и относительно текущего клика выбирается та, что наиболее подходит по контексту.
Модель можно дообучить под ваши данные или переконфигурировать и тем самым варьировать в глубину количество масок на объект, но это точно не нужно для офисников в Японии — если вы научились определять силуэт в черном костюме, то дообучение больше не требуется и задача решена.
Вставай в очередь!
Я выше писал только про клики, но клики это лишь один из способов промпта (вводных данных для поиска маски). SAM может работать еще и с прямоугольниками (bounding box, они же — bbox), то есть, мы можем выделить прямоугольником кусок картинки, а модель будет искать наиболее подходящую маску внутри этих границ.
Или же, более интересный вариант — попробовать выбрать объект текстом. И для демонстрации этого нам идеально подойдет такая удивительная вещь в Японии, как очереди.
Очереди в кафе в Японии везде. Если подходит время завтрака, обеда или ужина, то будьте готовы везде на улицах видеть длинные вереницы очередей.
Давайте попробуем посмотреть на фото обычных обеденных будней Осаки глазами SAM.
Примерно так выглядит визуализация первого слоя эмбединга. И если в модель для данной картинки подать на вход тестовый промпт «person», то будут выбраны силуэты всех стоящих в очереди людей, которых мы можем даже без участия человека посчитать.
Сложность здесь в том, что это работает с объектами, которым можно дать однозначное определение.
Страна интровертов и cash only
Настоящие причины очередей выяснить не удалось, скорее всего, это сочетание безумной интровертности (японцы вместо 1 бара на 200 человек сделают 50 баров на 4 человека каждый), жесткой иерархии социума и железной дисциплины (страной много столетий как правили, так и правят милитаристы-сёгуны, просто они теперь в дорогих черных костюмах), специфичных представлений о прекрасном (можно стоять в очереди, а потом узнать что внутри есть свободные места) и повсеместного cash only, который принимают смешную форму.
Японцы по максимуму отодвинуты от прямого контакта с деньгами. Возле каждого небольшого кафе есть автомат, где вы вставляете купюры и делаете заказ, а вам выдаются купончики с блюдами, которые вы все равно руками передаете персоналу. Почему сразу автомат не соединить на кухне с планшетом? Because Japan, That's Why!
Меньше слов, давайте размечать тунца!
Здесь модель вначале приняла два куска тунца за единый объект, но после добавления контекста разъединила их.
Этот же эффект «слипающихся объектов» на другой фотографии:
Здесь удивительным является тот факт, что вряд ли модель тренировали на разметке кусков рыбы, имбиря и гунканов (так зовутся черные штукенции), но она все равно их умеет отличать. Это и есть тот самый zero-shot, упоминаемый в названии, то есть, возможность угадывать объект, который мы не видели до этого.
Но, на опыте могу сказать, что не всё и в целом не всегда объекты такого рода получается моделью из «стока» определять, но результат все равно очень хорош.
Факт: японцы немного удивляются нашему привычному и странному для них взаимодействию с едой, когда сворачиваются роллы из всего на свете, а затем еще и индивидуально тщательно вымачиваются в соевом соусе. Роллов в Японии нет (можно штучно найти в туристических местах) и суши существуют в основном в тех форматах, что на фото выше — кусок риса (со встроенным внутрь васаби) и кусок рыбы сверху. После чего нужна лишь легкая капелька соуса, так как главная ценность японской кухни — не алхимия вкуса, а усиление его естественной первозданности.
Выделяем еду в тарелках
Морепродукты являются важной частью кухни, но далеко не единственной, часто в ходу свинина, говядина и множество всяких не совсем привычных нам овощей. Буднично японцы едят то, у чего часто нет явного рецепта, а лишь обозначенные границы. А массово привычная нам японская кухня — скорее адаптация в разной степени.
Давайте распознаем и протегируем традиционный японский завтрак, причем только двумя классами — тарелка и еда.
Обратите внимание, что класс «еда» всегда находится внутри класса «тарелка», поэтому в таких случаях имеет смысл сразу выделять только внешний класс — «тарелку», так как для его выделения на выходе формируются сразу два объекта, один поверх другого. Так будет сильно быстрее.
Посчитаем людей в масках
Если вы сначала прилетаете не в Токио, а в другой японский город, то по приезду в столицу будет казаться, что вы вернулись в город с пляжа. Токио местами сильно урбанистичен и очень драйвовый, а самая драйвовая его точка — перекресток Shibuya — самый нагруженный перекресток на планете (в интернетах много видео с ним).
Давайте на нем посчитаем людей в масках, ведь японцы носили маски еще до того, как весь мир узнал что это такое вообще.
Здесь мы возьмем фото, где толпа самых разных людей, и будем кликать на тех, кто в маске и посмотрим как будет работать выделение. Повторюсь, нам важно только количество, поэтому доводить до ума силуэт совершенно не требуется.
Это очень сложное фото (высокая детализация, много разных объектов, множественные перекрытия одних объектов другими), есть не совсем точные срабатывания, но и контекст не уточнялся, в целом — отличный результат для мелких сложных объектов.
Трафик на дороге и IoU
Задача, с результатами работы которой так или иначе сталкивались все водители — определение объектов на дороге висящей камерой. Мы просто возьмем обычное фото перекрестка и попробуем определить объекты нем.
Причем, в целом по полученной геометрии мы сможем сделать автоматическую классификацию авто — ведь автобус сильно отличается от легковушки и мопеда.
На таком жизненном абстрактном примере рассмотрим как можно построить простейший алгоритм, повышающий безопасность дорожного движения. Для этого нам потребуется коэффициент Жаккара (IoU — Intersection Over Union), а если по простому — перекрытие одного объекта другим.
Как только на кадре площадь протегированного объекта «пешеходный переход» начинает иметь пересечение с площадью объектов на дороге (автомобилями) — мы компьютерным зрением можем понимать, что происходит в кадре, а именно что один из авто находится на пешеходном переходе в данном кадре.
В реальной жизни этот пример на пару порядков сложнее, но здесь важно было простыми словами объяснить суть.
Сложные объекты издалека
Природа Японии — фантастическая. Давайте разметим вообще все, что видим на фото. Домик японского интроверта в лесу, конечно же, определится с первого же клика.
Здесь особенно интересны примеры не только того, что сложная визуальная геометрия (реки, берега, деревьев) выделяется первым же кликом, а то что это сработало даже для слаборазличимых объектов типа дороги внизу. Модель смогла отделить даже облако, правда, для этого пришлось немного покликать на убавление.
Определение положение человека
И еще одна задача, которая позволит определять «странности поведения» живых объектов на фото (или чаще видео). На примере — аэропорт Пекина, где на обратном пути по нам проехался каток Поднебесной бюрократии и всех прилетевших заперли в аэропорту на 23 часа, не дав транзитную визу, даже при наличии китаистов на рейсе.
Допустим, мы владельцы аэропорта и хотим автоматически найти по камерам людей, кто в итоге спит в неположенных местах.
Наша задача — не просто определить объект, а попытаться воссоздать является ли естественным (в нашем случае — лежачим) положение объекта. И хотя SAM снова с блеском справляется с выделением самого объекта, сказать об объекте мы ничего не можем, поэтому для глубокой детализации необходимо объекты внутри доразмечать маской из точек — так называемым skeleton detection, я для визуализации поверх выделения фигуры добавил нашу skeleton-маску по умолчанию (ее можно подстраивать в зависимости от конкретных потребностей).
В целом это другой класс задач, но для широты примеров решил все же его привести, так как SAM для таких задач может быть первым фильтром.
Стресс-тест на московской стройке
В качестве завершающего бонуса мы отправимся на реальную стройку в солнечной Москве и разметим все объекты на фото с условием не делать больше 3 кликов на объект.
До/После, если интересует картинка в целом. Я ставлю твердую пятерку, так как даже самые маленькие объекты без их приближения выделяются в правильных контурах.
Что с этим можно сделать? Найти алгоритмом людей без каски, посчитать количество и определить тип рабочей техники, найти посторонних или оценить порядок на стройке — да любую задачу компьютерного зрения.
Важное дополнение
Вся постановка задач — выдуманная и без ограничений, а в реальной жизни ограничения придется учитывать — такие как сроки, скорость работы, условия (в реальном времени или отложенно, с фото или на видео), качество картинки и ее вариативность, объем данных (и его конечность), шумы, специфика, количество клиентов и то, на каком оборудовании конечный продукт будет работать. Живую задачу нужно ставить исходя из совокупности всех этих и многих других факторов и это — очень важный момент.
Поэтому в статье почти все задачи были на выделение объектов по всей их геометрии, в реальной жизни часто такая детализация не требуется. Чем сложнее выделен объект, тем больше мощности потребуется для его обсчета, поэтому если вам не нужна детализация, то в таком случае для разметки можно оставить SAM, так как он хорош, но полигоны на готовой разметке преобразовывать в прямоугольники bbox, которые требуют на порядок меньше ресурсов.
Или же вообще использоваться SAM в разметке лишь как способ определения бинарного параметра о наличии объекта в кадре или его количестве.
Детализацию нужно использовать там, где она важна, это простая идея, но очень важная.
Как же эту модель построили?
Заглянем чуть под капот SAM (очень-очень упрощая): чтобы построить модель был взят датасет из 11 миллионов изображений, где вручную кисточкой попиксельно разметили 1.1 миллиарда объектов, после чего модель на этих данных была обучена. По итогу модель внутри себя «знает» как выглядит большое количество самых разных объектов, и при этом обладает свойством обобщаемости, то есть может «додумать» объект, даже если никогда его не видела до этого.
Благодаря этому модель хорошо справляется со множеством даже новых для нее объектов. Но если перед вами стоит задача выделять визуально искаженный объект (например, вмятину на авто) или части сложного объекта, а не объект целиком, то ох и ах, тут SAM начинает чудить. Или же объекты, которые по разному воспринимаются людьми, например, в какой момент растительность на лице уже можно выделять в класс "борода"? А где проходят границы губ? Люди трактуют это очень по разному.
Мы прошли через это в задаче подготовки данных для сложной задачи EasyPortrait. Лицо — очень сложный для разметки объект и с лицами SAM справляет не всегда хорошо.
Ложка дегтя и технические сложности
Основная проблема SAM — это очень сложная в обслуживании вещь. Если нужно прицепить SAM к себе на проект, чтобы отчитаться боссу — такое можно сделать дней за пять, но наладить промышленную работу на большом объеме данных — задачка с жирной звездочкой.
Чтобы SAM работал в браузере — встроить это все очень легко, но туда под каждую картинку нужно доставить эмбединг, а вот его нужно посчитать (передав в модель картинку и дождавшись расчета) и по сети передав обратно. Каждый эмбединг весит около 5.6 мб, независимо от содержания картинки. Здесь есть два варианта, я опишу их на чуть более программистском, чтобы не удлинять описание.
1) Сделать подсчет налету
Более легкий вариант, который не масштабируется и не оптимизируется. Разметчик получив фото отправляет его на некий бэк с моделью, который в ответ присылает эмбединг. Минусы здесь в том, что разметчик должен каждый раз ждать, пока фото сначала перекачается в модель, построется эмбединг и вернется обратно. Это — драгоценное ожидание, оплачиваемого времени работы разметчика, которое тратится впустую.
Здесь же мы создаем очень неравномерную нагрузку — люди в среднем работают в одинаковое рабочее время, поэтому ночью мощности будут простаивать, а днем — будет большая очередь (как в Японии). И в таком варианте нет возможности контролировать количество запускаемых инстансов модели, а модель к ресурсам требовательна, мягко говоря.
2) Сделать подсчет в фоне
Здесь мы перекладываем подсчет на крон (или сувервизорд), который размазывает всю нагрузку равномерно. То есть, при появлении новых картинок в задачах SAM, мы запускаем контейнер, внутри которого модель (или несколько ее инстансов/контейнеров) спокойно обсчитывает все данные и статически кладет в хранилище каждый эмбединг. Разметчик, получив фото, просто запрашивает нужный эмбединг и время уходит только на его перекачку по сети. Здесь сложность в том, что объемные эмбединги надо где-то хранить, при этом иметь доступ до самих файлов, чтобы подать их в модель (а данные часто бывают в S3 с кредами, либо иметь персуху, которую нужно согласовывать с безопасниками и так далее). Плюс здесь же надо хранить связку о том, какому элементу внутри системы соответствует какой эмбединг. Это прям очень сложно, но решаемо.
Мы в свою очередь сделали второй вариант + схема по запросу (on demand), то есть — режим SAM активируется только тогда, когда он вам нужен. От обсчета эмбединга никуда не деться, но если на фото нет нужного вам объекта, то можно сразу перейти к следующей фотографии, чтобы хотя бы для пустых случаев не грузить эмбединг по сети.
Для ручной разметки достаточно же просто картинки, которая доступна по вебу. Поэтому если ваша задача выделить несколько простых объектов — применение SAM будет стрельбой из ядерной пушки по воробьям.
Подводим итоги:
SAM — мощнейший инструмент, который, как по мне, сильно удешевит создание технологий компьютерного зрения за счет сокращения времени и стоимости разметки данных. SAM прекрасно справляется со множеством бытовых задач, такими как определение всех типов одежды, еды в посуде и без, машин на дороге, людей и животных, наличия предметов в кадре или трекинга любого рода объекта.
Для большинства объектов SAM скорее покрывает их, нежели наоборот, но все зависит от специфики и поставленной задачи.
Плюсы:
SAM очень сильно ускоряет разметку данных, по разному в зависимости от задачи и качества фото
SAM хорошо работает там, где объект логически закончен и однозначно определяется
SAM можно доучивать под конкретно вашу задачу
Минусы:
SAM почти всегда будет строить одни и те же эмбединги, поэтому вариативность разметки снижается почти до нуля. Иногда — это важно.
SAM тяжелая в обслуживании вещь, требующая серверных мощностей и требовательная к скорости сети
SAM плохо справляется с «искаженными» объектами, например, объектами за стеклом или с размытыми границами
Надеюсь, вам было интересно и познавательно. За помощь в подготовке статьи благодарю @VSRobotics(за то, что позволяют делать такие крутые штуки) и @hukenovs(за то, что с командой сложными задачами держат нас в бодром тонусе) и сильно причастных к разработке @rockindolphin и @d_i_frolov.
Я искренне считаю, что разметка данных сильно недооценена в пользу алгоритмов, поэтому если вам понравилась статья или интересна разметка в целом, то приглашаю в свой только созданный персональный телеграм-канал ей посвященный (где не очень часто будут заметки и статьи про разнообразный опыт работы с разметкой): t.me/aimarkup (а по вопросам можно писать напрямую t.me/antipov_d).
И, кстати, SAM — очень подходящий пример подтверждения мнения о недооценке разметки, ведь это далеко не первая разработка такого рода, но именно качественный скачок у нее случился именно когда идеальные алгоритмы наложились на идеальную разметку.
Большое спасибо за прочтение или, как говорится, аааригато!