Pull to refresh

ИИ в 3D: Где мы сейчас и какое будущее нас ждёт? (Часть 2)

Level of difficultyMedium
Reading time7 min
Views3.8K

В предыдущей статье мы уже затрагивали задачу реконструкции 3D-объектов по их 2D-изображениям. В этой же углубимся в реконструкцию с головой! Вообще говоря, как мне кажется, сейчас мы рассмотрим гораздо более концептуально интересные методы, а именно - HSP и Mesh R-CNN. Это база, которая просто должна осесть в головах всех любителей ИИ в 3D!

HSP

Hierarchical Surface Prediction (HSP) можно попробовать перевести, как иерархическое предсказание поверхности. Это метод воксельной реконструкции 3D-объектов по их 2D-изображениям. 

Воксели

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

Воксели часто называют трёхмерным аналогом обычных пикселей, что неплохо отображено на следующей картинке

Пиксели vs Воксели
Пиксели vs Воксели

Они очень удобны для представления 3D-объектов сложной топологии, да и сами по себе являются достаточно естественным способом отображения нашего мира, как структурированного набора маленьких кирпичиков.

Какая основная проблема стоит перед нами, когда мы используем воксельную сетку? В первую очередь - это проклятие размерности, которое проявляется при увеличении детализации 3D-модели. Например, если мы будем напрямую хранить воксели в виде трёхмерного массива array[x][y][z], то для того, чтобы представить 3D-модель с детализацией хотя бы в 512 точек, нам понадобится 512^3байт, что в свою очередь равно 128 Мб. Короче, так себе история, имеем O(n^3)по памяти. 

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

Октодеревья

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

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

Вот пример того, как при помощи октодерева можно представить 3D-модель снеговика:

Ближе к границе объекта разбиение увеличивается, что позволяет сделать детализированную поверхность. А вот внутри снеговика разбиения большие: нам не нужно детализировать внутренний объём, который и так не сможем увидеть. Вот тут мы потихоньку и подобрались к сути метода HSP.

Суть метода

Для начала взглянем на схему:

Можем видеть, что HSP получает на вход RGB-изображение, преобразует его в вектор признаков C и не берётся за генерацию всей воксельной сетки разом. Вместо этого он последовательно получает пространства признаков F^i и на основании этого продолжает строить октодерево, решая, лежит вершина и соответствующий ей воксель внутри объекта, вне объекта или на его границе. Для 2D домика такая классификация выглядела бы следующим образом:

Здесь 

  • красный контур - истинный объект дома

  • белые пиксели - пиксели вне объекта

  • чёрные пиксели - пиксели на границе объекта

  • синие пиксели - пиксели внутри объекта

Если модель решает, что воксель лежит на границе объекта, производим дальнейшее построение дерева из данной ноды на 8 дочерних и получаем новое более детализированное разбиение. Для него повторяем всё снова, пока, либо не получим отсутствие предсказанных граничных вокселей, либо не пройдём все 5 уровней детализации. Почему 5? Просто авторы посчитали, что подобной детализации будет достаточно, да и по всей видимости улучшение было бы не сильно значимым в сравнении с увеличением потребляемых ресурсов. 

В конечном счёте генерируется воксельная 3D-модель с детализацией в 256^3вокселей:

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

Таким образом, HSP - это end-to-end подход, который, используя датасет ShapeNet с полигональными 3D-моделями различных классов объектов, учится по одной фотографии объекта строить его детализированную воксельную модель.

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

Технические детали и прочие нюансы реализации данного метода можете прочитать в двух оригинальных статьях:

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

Mesh R-CNN

У нас уже существует огромное количество моделей, способных сегментировать и классифицировать объекты на 2D-изображении, взять те же U-Net и Mask R-CNN:

Пример работы Mask R-CNN
Пример работы Mask R-CNN

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

Тут на сцене появляется Mesh R-CNN, которая использует в процессе работы как уже известные нам воксели, так и полигональную сетку, удобную для прикладных задач. 

Вспомним для наглядности схему Mask R-CNN:

И рассмотрим подробнее устройство Mesh R-CNN:

Из сравнения двух схем вытекает важное для дальнейшего понимания замечание: Voxel Branch и Mesh Refinement Branch являются 3D-аналогом Box Branch и Mask Branch из Mask R-CNN. Voxel Branch даёт грубую аппроксимацию нашего объекта в 3D, как и Box Branch в 2D, а вот Mesh Refinement Branch уже при помощи последовательных свёрток даёт точную сегментацию в пространстве, аналогично Mask Branch на плоскости.

Начнём разбор Mesh R-CNN по порядку. Будем в точности идти по схеме: 

1. RoIAlign

Аналогично Mask R-CNN, перед тем как строить аппроксимацию найденного объекта, нам необходимо его признаковое описание. Получаем его точно также при помощи RoIAlign и передаём дальше в Voxel Branch.

2. Voxel Branch

Ветка вокселей представляет собой небольшую свёрточную сеть, которая на основании карты признаков с предыдущего шага предсказывает G × G × G воксельную сетку. Она является грубым приближением рассматриваемого 3D-объекта. 

Результат работы ветки вокселей
Результат работы ветки вокселей

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

3. Cubify: Voxel to Mesh

После получения воксельной сетки наступил момент, когда мы переходим к треугольному мешу. Как это сделать? Есть разные способы, включая маршевые кубы, но авторы статьи выбрали метод попроще: так называемая кубификация. Каждый занятый воксель заменяется кубовидной треугольной сеткой с 8 вершинами, 18 ребрами и 12 гранями. Соседние вершины и рёбра, коих довольно много, склеиваются, а соответствующие им грани удаляются. Выглядит это всё как-то так:

Результат кубификации воксельной модели стола
Результат кубификации воксельной модели стола

Уже не воксели, но ещё и не 3D-модель. Как раз для того, чтобы всё это "причесать", переходим к следующему этапу.

4. Mesh Refinement Branch

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

  1. Vertex alignment

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

  1. Graph convolution

CNN vs GCN
CNN vs GCN

Для начала, если вы никогда не встречались с нейронками на графах, советую посмотреть видеоролик, в котором неплохо поясняется, как работают GCNs. Лично я с конволюциями на неевклидовых данных встречался не так уж и часто. В основном она появляется в физических структурах, моделировании движения частиц, молекул и т.д. Однако, в нашей задаче графовое представление данных также вполне оправдано - поверхность 3D-меша с его вершинами и ребрами идеально переносится на графы. 

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

f^{'}_i=ReLU(W_0f_i+\sum_{j\in N(i)}W_1f_j)

гдеN(i)- множество индексов всех соседей i-й вершины,
W_0, W_1 - обучаемые матрицы весов,
f_j- признаковое описание вершины.

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

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

  1. Vertex refinement

А теперь займёмся магией! Этот шаг непосредственно отвечает за “причёсывание” 3D-модели. Имея на руках признаки в конкретной вершине, мы можем найти необходимое для неё смещение по формуле ниже:

v^{'}_i = v_i+tanh(W_{vert}[f_i;v_i])

гдеv^{'}_i- новое положение i-й вершины,
v_i- старое положение i-й вершины,
W_{vert}- обучаемая матрица весов.

Далее обучаем end-to-end нейросеть, используя в качестве лосса расстояние между облаком точек исходной модели и предсказанной.

Результаты

По итогу имеем следующий результат на нестерильных реальных данных: 

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

Заключение

Немного рефлексии по недавним событиям:

Процесс написанияй этой статьи выпал на анонс Sora от OpenAI. И она удивительна, правда. Если честно, Sora поразила меня даже сильнее, чем ChatGPT в своё время. Раньше я думал, что ключ к стабильной генерации долгих видео лежит именно в предоставлении нейросети понимания концепта объёма и времени (понимание 4D-пространства, которое есть у нас, у людей). Однако, как оказалось, это понимание можно и не инкорпорировать напрямую, оно способно возникнуть само по себе, если навалить кучу трансформеров и воспринимать видео, не как последовательность изображений, а как нечто единое, целое. 

Ещё посмотрим, как будет развиваться эта область. Лично мне кажется, что истина где-то посередине и к 3D всё так или иначе вернётся. Когда понадобится покорить новые горизонты генерации и потребуется произвести пару идейных оптимизаций - тогда поглядим, куда свернёт индустрия 😏

Tags:
Hubs:
Total votes 12: ↑12 and ↓0+12
Comments0

Articles