3D Pose Estimation объектов фиксированной геометрии для складских роботов

7a45847186c7bef9fd18990e6a0fb8be.png

«Позабыты хлопоты, остановлен бег. Вкалывают роботы, а не человек» — соблазн автоматизировать физический труд знаком нам ещё с «Приключений Электроника». И точно актуален на складах, особенно в период пиковой сезонности. И тогда на помощь приходят роботы, забирая на себя большую часть задач. 

Привет, меня зовут Александр Тимофеев-Каракозов, я Senior ML/CV Engineer в Яндекс Роботикс. Я разрабатываю архитектуру ML-решений, обучаю нейросети для роботов и настраиваю MLOps, чтобы модели быстро адаптировались к новым складам и задачам. В этой статье я расскажу вам про нейросетевую жизнь складских роботов Яндекса и покажу, как один из них решает задачу 3D-локализации объектов в фиксированной геометрии. 

Какие роботы есть на наших складах

Давайте начнём с того, что посмотрим на жизненный цикл товара на складе:  

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

Наш робопарк насчитывает несколько видов складских роботов:

  1. АМР (автономный мобильный робот) — робот-извозчик, на который кладут товары, и он их возит. 

  2. Spectro — робот-инвентаризатор, который гоняет по складу и проводит инвентаризацию.

  3. Dilectus — робот-тотоносец (тоты — наше название коробок), который занимается перемещением товаров по всему складу. 

3050b09dd4e6489a39ebfd1d8cc03e38.png

А ещё у нас есть роборука с искусственным интеллектом — Пикер. Она собирает и упаковывает товары. О ней мы рассказывали в отдельной статье. И ещё есть роборука побольше — Депаллетайзер.

Для сегодняшней темы возьмём в качестве примера робота Dilectus. Операции, которые он выполняет на складе, в среднем составляют от 30 до 35% от общего количества операций, поэтому робот является важной частью автоматизации процессов. 

Dilectus работает по концепции «товар к человеку». Товары размещаются в коробках, робот находит тоты с нужными товарами, берёт их со стеллажей в зоне хранения, перевозит в зону комплектации. Затем пустой тот при необходимости возвращается на стеллаж. 

Dilectus может работать внутри склада автономно, то есть без людей. Он оснащён 3D-лидаром, который позволяет позиционироваться на складе, а также предотвращать столкновения. Также у робота есть механизм захвата — граббер, который позволяет снимать с полок не только ближайшие коробки, но и те, что лежат за ними. Поэтому на складе удастся разместить больше товаров без беспокойства, что робот дотянется не до всех коробок. А ещё он может перевозить тоты в себе — для этого в нём есть 5 слотов. Длина Dilectus — 2,4 м, ширина — 1,2 м, а высота — 4,1 м. 

425af6206f674adc868478581fa2e026.png

Робот управляется с помощью ПО, которое получает задания из единой умной системы управления роботами (Robot Management System, или RMS). Робот при знакомстве со складом запоминает, где и какой тот находится — он считывает коробки по специальным QR-кодам. 

Затем он начинает с ними работать: система направляет ему задание, какой тот нужно взять и куда отвезти. Первый пайплайн детектирует с помощью сегментации, наклеенной на полку дата-матрицы, положение робота относительно полки и калибрует его для дальнейших действий.  Второй пайплайн помогает взять коробку с полки. Он определяет 3D-положение коробки и отдаёт эти данные, чтобы процессы могли определить, как её захватить. А теперь давайте разберёмся, как ставить роботу подобные задачи. 

Формулируем задачу и ищем решение

Для начала сформулируем задачу: у нас есть картинки, и мы должны найти 3D-положение тота в системе координат камеры в виде восьми трёхмерных точек. Звучит как стандартная задача 3D-локализации (её ещё называют 6D Pose Estimation). Но, как обычно, есть условия:

  1. Ошибка не должна превышать 1 см. Общий запас надёжности захвата коробок латчами (лапками робота) — около 2 см, и по каждой стороне мы можем ошибиться не более чем на 1 см.

  2. Скорость обработки на Nvidia Jetson: 10 FPS. Такое значение выбрано с целью уложиться в скоростные ограничения всем пайплайном, а это не только нейросеть, но и обработка потоков данных с робота, локализация и т. д.

  3. Single-view. Опция Multi-view для нас, к сожалению, недоступна. То есть мы можем «посмотреть на коробку» один раз, а не как при Multi-view рассмотреть её с разных ракурсов, чтобы точнее определить локализацию. 

Но перед тем как решать нашу задачу, давайте поймём, как оценивать наше решение. У нас стандартные метрики:  

  1. Средняя квадратичная ошибка — возведённая в квадрат усреднённая разница между предсказанными и истинными значениями. Это стандартная метрика, которая показывает, насколько сильно ошибается модель. Чем меньше значение — тем лучше. Так как она квадратичная, все выбросы (очень большие ошибки) будут учитываться в квадрате, то есть делать очень большой вклад в ошибку, и мы увидим это по метрике. 

  2. Аналог accuracy в терминах максимального отклонения. Другими словами, это доля предсказаний, у которых максимальное отклонение каждой из точек не больше определённого порога. Чем больше доля — тем лучше, то есть если метрика равна 1.0 (100% точности), это значит, что все предсказания укладываются в диапазон 1 см.

d99f890506f0f8cf21a330f3f5d35f82.png

Всё это мы считаем по трёхмерным координатам XYZ в системе координат камеры. 

Условия есть, метрики тоже — пора решить нашу задачу! Для начала мы уходим по таргетам в 2D. Таргет — это то, что мы хотим предсказать с помощью модели, и сначала мы хотели предсказывать в 3D (XYZ). Но оказалось, что в 2D (XY) значительно проще — разметка в 3D делается на ограниченном множестве данных и она очень трудозатратная. К тому же мы используем краудсорсинг, чтобы размечать большое количество данных, а его в 3D сделать нельзя. 

cbf1d758298100b368393726112bed92.png

Возьмём переднюю грань нашей коробочки. Так как коробка в целевом кейсе всегда стоит лицом к камере, то это оправдано. Тут возникает вопрос — в 2D перешли, а как вернуться обратно? Как, зная четыре двухмерные координаты, получить восемь трёхмерных в системе координат камеры?

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

043e9003218aa6de79416da19fdfb231.png

На самом деле, это задача Perspective-n-Point, которая неплохо решается как раз, когда есть хотя бы четыре точки.

7009c3418cfb6d6d6bddfdd39a24dedb.png

Но самое главное, что, зная параметры проекции, мы можем использовать их, чтобы преобразовать систему координат коробки в систему координат камеры. Таким образом, для заранее полученных точек, которые можно просто снять в двухмерной системе координат, мы можем найти их проекции в трёхмерной системе координат камеры. А это значит, что мы решили задачу и проблему перехода из 2D в 3D. 

С учётом всего сказанного, наш пайплайн будет выглядеть достаточно просто:

d140e8bd612c4f5c74005292cd21cfdc.png

Сначала находим двухмерные точки передней грани, потом с помощью Perspective-n-Point находим итоговые трёхмерные точки. На всякий случай, тоже сформулируем задачу в 2D.

6b3aa941993ffd59032f7e4368b10373.png

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

f89eaa44ba9a144094bfc3195ee1885d.png

Мы начинали с самого простого — с метода двух моделей. Сначала детектировали наши коробки, потом каждую прогоняли через Keypoints Estimator и получали искомые точки. Потом пробовали решить в лоб одной моделью (E2E-подход). Далее вообще переосмыслили таргеты — решили предсказывать не точки, а линии. А в конце свернули в сегментацию. 

Расставляем все точки над тотом: нейросетевые подходы

Путь двух моделей

Мы начинали с двух моделей: YOLOX — детектор объектов и TransPose — детектор ключевых точек. 

74b6879581e081029b52df89dfe4b448.png

Простейший подход — берём детектор, находим передние грани коробки, каждую из них прогоняем через Keypoints Estimator и находим четыре нужные точки. Keypoints Estimator мы брали в виде TransPose — это небольшой трансформер с энкодером в виде ResNet-18. 

Плюсы:  

  • Высокое разрешение для вычисления ключевых точек. Количество информации на пиксель больше, чем при Е2Е-подходах. 

  • Single task для ключевых точек. Мы сначала нашли область, где наша коробка. И эту область подаём на вычисление точек, а алгоритм, который их вычисляет, занимается только одной задачей — непосредственно вычислением точек. 

  • Декомпозиция ошибки. Мы можем отдельно улучшать как детекцию коробок, так и локализацию точек. 

Самое главное, что тут Keypoints Estimator смотрит не на всю картинку, а только на ту область, где присутствует наша коробка. Именно поэтому количество информации на пиксель здесь больше, чем в остальных методах. Приятно то, что задача декомпозируется, но это ведёт и к минусам.

Минусы:

  • Детектор ошибается сильнее, чем при E2E-решении. На практике мы заметили, что детектор без дополнительных задач в виде определения ключевых точек чаще предсказывает фантомные коробки, которых нет на фотке. И на этих фантомных коробках локализатор точек находит какие-то точки. Такое предсказание — плохое предсказание, ведь коробки-то нет :)

  • Сложнее поддерживать. В этом методе используются две модели, а это в 2 раза больше работы.

  • Не E2E. А нам бы хотелось решать задачу только одной моделью.

  • Чувствительность к нечёткой разметке. Если люди разметили точки с ошибками, то модели будет тяжелее обучаться.

Мы решили попробовать другие подходы, и заодно сравнить Е2Е-решения с текущим, так как хотели избавиться от его минусов. 

Путь E2E

Потом мы попробовали решить задачу одной моделью YOLOX-Pose — так начался путь E2E. 

2d912b3cc7aeae77919a3b3ba747085d.png

YOLOX-Pose отличается от YOLOX только в реализации головной части, которая выполняет основную задачу — локализацию объектов:

d26f39bbf344be2e9b2f74dcbd493acd.png

YOLOX — это anchor-free детектор, а значит, якорем мы можем считать каждую точку на фича-мапе. У YOLOX три головы: классификация предсказывает классы для каждой якорной точки, регрессия предсказывает смещение bounding box и его размеры, а объектность предсказывает, что вообще какой-то объект есть. 

В YOLOX-Pose фичи отводятся ещё на решение задачи Pose Estimation. Одна голова предсказывает регрессию, а вторая — объектность. Она говорит, что точка существует (ключевая точка позы), а регрессия предсказывает смещение x и y для каждой якорной точки в сторону соответствующих ключевых точек позы. 

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

194e719b41c38ec717575e02fa07dc53.png

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

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

fe67163e68b27e6df7d209e2b060be72.png

В YOLOX мы выбираем якорные точки так, чтобы их было просто регрессировать в центр объекта. В YOLOX-Pose мы также выбираем якорную точку так, чтобы было проще регрессировать в центр объекта, а также в ключевые отметки поз. Если посмотреть на нашу геометрию, то опять мы выбираем якорные точки ближе к центру. Получается, что мы в центр будем регрессировать легко, потому что просто ближе находимся, а в ключевые точки регрессировать сложнее. Refinement-модуль как раз решает эту проблему.

506bc05ed5a74c7354801fb96ff03959.png

Мы берём предсказание от YOLOX-Pose для ключевых точек и якорные точки из Refinement-модуля. Они также предсказывают смещение до ближайшей ключевой точки. 

Плюсы:

  • E2E. То есть у нас одна модель, и это хорошо. 

  • Легко поддерживать, так как одна модель = только одна головная боль. 

Минусы:

  • Малое разрешение для вычисления ключевых точек. Теперь мы смотрим на картинку и сразу делаем предсказания, предварительно изменив размер картинки, чтобы скормить её нейросети. Поэтому мы уменьшаем количество информации на пиксель в несколько раз, и в итоге появляется гарантированное отклонение. 

  • Multitask сложнее обучать, так как одна модель делает сразу много всего.  

  • Чувствителен к нечёткой разметке, то есть всё ещё зависит от ошибок в разметке, сделанных людьми. 

По метрикам получается так:

8e55a319f306f1383c72d5c63216ea62.png

Даже с Refinement-модулем E2E-подход отстаёт от подхода с двумя моделями, но это, наверное, логично. Однако если применить хак в виде Test-Time Augmentation, то метрики мы пробиваем и при этом даже укладываемся в наши скоростные ограничения (на Jetson, напомню). 

Test-Time Augmentation — это метод, который используется для улучшения производительности и стабильности моделей машинного обучения. Он включает применение случайных преобразований к входным данным во время этапа тестирования или оценки модели, что позволяет получить несколько разных представлений одного и того же объекта. 

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

Дальше мы попробовали переосмыслить таргет: то есть не тюнить архитектуру, а просто посмотреть на топ проблем, которые вообще у нас есть. Оказалось, что самая большая из них — это проблема окклюзии точек, когда какие-то точки не видно, какие-то сильно засвечены. 

41e0ce1f52cb40d329164bdaf588f999.png

Если не видно двух точек, итоговую геометрию с помощью Perspective-n-Point мы найти, скорее всего, не сможем. А если не видно одной точки, то позу оценить можно. На самом деле Perspective-n-Point умеет решать задачу, даже если три точки известны. Однако получается сильно неустойчивое к шуму решение, и нам не очень это приятно. 

Путь линий

Немного поразмыслив, мы решили предсказывать линии, которые пересекаются в необходимых нам точках. Для этого мы немножко модернизировали YOLOX (я обозначил его как YOLOX-Lines). 

87798d0d173e58d07bfd844900f50a18.png

Когда мы находим четыре линии для каждой нашей коробки, мы находим и их четыре угловые координаты в виде их пересечения. От классического YOLOX это отличается только головой детектора.

9dcd55ce500ba6219d1efe72569c73a4.png

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

На самом деле даже угол можно параметризовать по-разному, поэтому вы видите здесь параметр Angle dim. Скажем, можно предсказывать градусы или представить угол как вектор, например, решая задачу классификации на сглаженных классах. В нашем случае Angle dim равен 180 градусам. В итоге получается так:

ddc7c8316da457d0d0be58d36cdf71e2.png

Мы также предсказываем смещение в центр объекта и в центральные точки на видимых частях каждой из граней из четырёх линий. 

Вы можете заметить, что тут нет Refinement-модуля. Но это не потому, что он здесь не сработает, а потому что мы просто не успели его добавить, так как у нас был дедлайн на эксперименты, а мы уже нашли решение, которое в перспективе сработает лучше. 

Плюсы:

  • Почти E2E. То есть нужно, как и в предыдущем методе, просто найти ещё пересечения точек по прямым, что очень просто. 

  • Легко поддерживать, так как это одна модель. 

  • Работает, даже если видно хотя бы две точки. 

Минусы:

  • Малое разрешение для вычисления ключевых точек. Вся информация подаётся на пиксель меньше, чем в первом методе. 

  • Одна шумная линия → две шумные точки. Если мы предсказали линию плохо, то две точки тоже будут предсказаны плохо. 

  • Нужно много всего предсказывать. Этот multitask ещё сложнее, чем в предыдущем подходе, и его надо оптимизировать. 

По метрикам получается негусто:  

10dfcd78c42f9bc7b71881fadef5d321.png

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

Путь сегментации 

Тут вообще всё просто. С помощью инстанс-сегментатора мы находим маски для каждой передней грани коробки, а потом каждую маску постпроцессим в точке.

163a4c5acd8a89e34affbc8a8ae5b547.png

Модель инстанс-сегментации на базе YOLOX выглядит так. 

85210b8303f3279bd7574dd35f2db85e.png

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

На самом деле все эти YOLO-подобные инстанс-сегментаторы (YOLOv8, YOLOv5 и пр.) выглядят примерно одинаково. Для каждой передней грани предсказываются только маски, и потом они постпроцессятся в точки. Возникает вопрос:, а как постпроцессить маски обратно в точки?

28987686cabf57c3c148b0ea66501ad8.png

Один из простых подходов: берём маску и какой-нибудь алгоритм Edge Detection, то есть детектируем граничные точки нашей маски. Например, можно взять алгоритм Canny из OpenCV. Далее по этим граничным точкам с помощью алгоритма Lines Detection предсказываем линии. Например, с помощью алгоритма Huff из OpenCV, который называется Hough Line. Потом мы кластеризуем эти линии, например, применяя K-means. Теперь мы понимаем, где какая линия, фитим наши лучи, опять получаем, как в предыдущем подходе, таргеты, линии. Их пересечение даёт нам искомые точки.

Мы используем следующий простой, но ёмкий подход:

  1. Берём маску ровно одной грани (то есть одного тота).

  2. Применяем какой-нибудь алгоритм Edge Detection. Например, сейчас мы используем обычный алгоритм Canny из OpenCV. В итоге мы получаем граничные точки нашей маски.

  3. Далее, когда у нас есть граничные точки, мы можем их «выровнять» путем применения алгоритма детекции линий. Например, мы используем алгоритм Хаффа — Hough Line из той же OpenCV. Тут мы получаем линии, которые аппроксимируют наши граничные точки, что помогает отфильтровать выбросы в точках в виде кривых участков границ.

  4. Полученное множество линий мы можем кластеризовать по углу и их соответствующим центрам (центрам линий). Это даст нам понимание, какие линии относятся, например, к левой границе грани, а какие — к правой, нижней или верхней. Кстати, кластеризацию мы проводим с помощью KMeans с небольшими эвристиками.

  5. В итоге для каждого кластера линий мы можем зафитить прямые. Это позволяют сделать FitLines из OpenCV, которые аппроксимируют наше множество линий. И для каждой грани нашей маски мы находим прямые, которые далее обрабатываем по аналогии с подходом из «пути двух линий».

b46a475c5d32a4b87f10e58b5e0ec262.png

Плюсы:

  • Легко поддерживать. Этот метод состоит всего из одной модели — не нужно сильно вкладываться в ресурсы.

  • Сегментация наименее чувствительна к нечёткой разметке по сравнению с остальными методами. Если, допустим, мы ошиблись на 1 см в разметке — это критично, а для маски не так фатально — это просто сделает её чуть хуже, но пересекаться с правильной она будет всё равно по большей площади.

Минусы:

  • Сегментация делает модель тяжелее остальных решений. 

  • Сложный постпроцессинг. В алгоритме перевода маски в точки много шагов, на практике он выглядит тяжело. 

  • Не совсем Е2Е, так как мы предсказываем не сразу точки, а маску. Потом нужно ещё многое сделать, чтобы перейти в точки. Но при этом всё делает одна модель.

И снова предлагаю посмотреть на замеры. В FPS вписались, квадратичная ошибка упала, а самое главное — доля ошибок до 1 см у нас выросла почти на 3% — это отлично.

ecb4417151450fb9a4875dd542b0b27a.png

Само собой, мы выбрали этот путь. Наш итоговый пайплайн выглядит так: сначала с помощью instance segmentation модели YOLOX-Seg мы находим маски для каждой коробки, потом из масок делаем 2D-точки, а дальше с помощью решения задачи PnP из 2D-точек делаем 3D и таким образом решаем нашу задачу. 

d08be291d3ab246444ef1e5ce9c29635.png

Этап Active Learning

Мы разобрались, как обучать модель и как получать итоговые 3D-координаты наших объектов. Но что делать с данными?

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

Мы задались вопросами:

  • Где найти данные для последующего обучения?

  • Какие данные отобрать из всего потока?  

  • Как все эти действия вообще автоматизировать?  

На эти вопросы нам помогает ответить активное обучение (Active Learning, или AL). Вкратце — это метод постоянного дообучения моделей с помощью майнинга сложных примеров. Благодаря AL мы можем собирать данные так, чтобы получить максимальный профит в последующем обучении. 

Active Learning хорошо ложится на кейс, когда у вас много моделей, которые нужно поддерживать и дообучать. Однако есть нюанс: пайплайн AL, как правило, автоматический, поэтому вряд ли получится добиться качества лучше, чем если бы мы исследовали модель руками, акцентируя внимание на неявные фичи. 

d5bd2359f56c1a8faa07f6389fc6f1ea.png

У нас катается много роботов, и они сыпят логи, в которых есть какие-то предсказания для каждой из моделей. По этим предсказаниям мы отбираем подозрительные семплы (изображения и предсказания модели), которые можно описать как примеры, где модель неуверенно себя чувствует. Всё это летит в базу данных или облачное хранилище. 

В кейсе робототехники нам приходится сильно подчищать данные, так как наша среда статична. Каждый день мы видим практически одно и то же и работаем с дубликатами и очень похожими изображениями. Мы чистим наши датасеты с помощью автоэнкодера, который может опознать сильно похожие друг на друга изображения. Фильтровать дубликаты очень важно, чтобы не просто как-то условно разбить выборку, но и при этом не разбить ваш Train Test Split (особенно, когда всё это автоматизировано). 

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

В итоге самые интересные данные попадают в датасет обучения. Мы готовим датасеты, выборки, параметры и начинаем обучать. Во время обучения мы тоже перебираем гиперпараметры, выбираем модели. Лучшая модель отправляется на CI/CD-пайплайн. Она проходит синхронное, асинхронное тестирование, считается онлайн, офлайн, отсматривается по интеграционным метрикам. В общем, проходит через все круги ада перед тем, как попасть в релиз :) 

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

Рассмотрим примеры сэмплеров для нашей задачи. 

Сэмплинг на углах. Мы можем посмотреть на углы, которые образуют предсказания с осью X, и оценить их разницу. Если она больше определённого порога, то пример считается неуверенным. Аналогично можно сделать и с задней поверхностью после 3D-локализации точек, использовать самые разные эвристики, чтобы по предсказаниям понять, что с примером что-то не так.

d37e7f945e77d8465bdc9279f805acd0.png

PnP-сэмплинг. После 2D Key Point Estimation мы используем решение задачи Perspective-n-Point, чтобы найти трёхмерные координаты целевых углов. 

b6c145fd25c8dd7299572d205ff2d60c.png

У нас есть предсказания от 2D Key Point Estimation и предсказания после решения задачи Perspective-n-Point. Мы можем посмотреть, насколько сильно поехали предсказания после решения этой задачи. 

dc66b49d47a8cf2673cba845a3b6fdd0.png

Если значения поехали больше обычного — с примером что-то не так. 

TTA-сэмплеры. Этот сэмплер более общий. Мы навешиваем Test-Time Augmentation, смотрим, как сильно меняется предсказание, и если изменения больше определённого порога — с примером что-то не то. 

b38ec82af8be6acd0632bfd665905260.png

Эти сэмплеры распределяются так:  

2dc75cea6abdb46e2dfa5356a6375073.png

Лёгкие сэмплеры делаются непосредственно на роботах для того, чтобы не сильно просадить их перф и не увеличивать сетевую нагрузку. Тяжёлые в виде Test-Time Augmentation сэмплера или больших языковых моделей (да и вообще любых моделей) делаются в облаке.

С такой конфигурацией получается следующее:  

df8fa91b72d5f40030a6ffbfdf02fb11.png

То есть пока мы были заняты другими делами, наша модель нарастила себе качество на 20%. Но самое главное, ради чего мы всё это делали — мы намайнили себе выборку, которая в 10 раз больше предыдущей и состоит из очень сложных и интересных примеров. 

И если мы говорим о метриках — не стоит забывать про бизнес.

eb63c5c7f74e8e2457324f3d6e2a48f3.png

Мы смотрим на метрику Success Rate, которая означает долю успешных заданий робота в определённом временном интервале. С июня метрика стала практически стопроцентной, что говорит о том, что задачу мы в целом уже решили, при этом — фоново. 

Также не стоит забывать про визуализацию наших пайплайнов. 

c984248390aa0c236cdfa31929169580.png

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

В заключении хочется сделать пару выводов:

  • Не всегда задачу 3D-локализации объектов фиксированной геометрии стоит решать в 3D. Можно упростить и решать задачи в знакомом 2D-домене, и, в случае нечёткой разметки, использовать методы, которые её не боятся. В 2D их не так мало. Например, у нас сработала сегментация, задачу мы на самом деле уже плюс-минус решили. 

  • Активное обучение — отличный помощник для поддержки модели в проде, который позволяет в равной степени наращивать качество нейросети и приспосабливаться к частой смене домена. Например, для вышеописанной задачи активное обучение помогло намайнить полезных данных, вследствие чего Success Rate вырос до 100%. Более того, мы внедрили AL почти во всех роботов и теперь просто пьём чай можем заниматься и другими, не менее интересными задачами.

© Habrahabr.ru