MegaDepth: Обучение предсказателя глубины по одной фотографии, на картинках из интернета
В одной из предыдущих статей, в которой рассказывали про D2-Net фигурировал датасет, на котором собственно происходило обучение. Датасет называется MegaDepth и хотелось бы остановится на нем по-подробнее. В основном на том как его собрали и для чего использовали авторы исходной статьи.
Итак, авторы статьи планируют натренировать нейронную сеть, которая умела бы определять глубину. Т.е. на вход сети можно было бы подать фотографию и на выходе получить карту глубин, для каждого пикселя изображение расстояние от камеры до объекта. Прекрасная идея, у которой авторы видят только один недостаток, а именно отсутствие хорошего датасета на котором сеть можно было бы обучить.
Авторы сетуют на то, что доступные простым людям сенсоры типа Kinect применимы для сбора только датасета с глубинами внутри помещений, а серьёзные приборы, которыми можно собирать глубины и на вольном воздухе либо дорогие и сложные в использовании, либо выдают только разреженную карту глубин (как, например, лидары, при помощи которых собирался датасет KITTI). К тому же датасеты вне помещений собираются в специфических сценариях и не факт, что сеть натренированная на таких данных сумеет хорошо обобщиться.
Опираясь на эти обстоятельства, авторы решают собрать себе датасет самостоятельно.
Датасет MegaDepth
Для этого они первым делом, скачивают много фотографий вокруг нескольких особо посещаемых мест, и для каждого места на наборе фотографий используют SfM и MVS методы. В качестве инструмента SfM и MVS используется COLORMAP, это приложение позволяет определить параметры и положение камеры, набор 3Д точек (разреженный), и затем для каждой фотографии восстановить карту глубины (возможно не полностью, т.е. для части пикселей глубина не определена).
Казалось бы задача сбора датасета выполнена, но карта глубины, которая получается в результате работы COLORMAP, к сожалению, имеет ряд существенных недостатков, в силу объективных причин:
-
временные объекты (люди, машины и т.п.), которые появляются только на одной фотографии, и соответственно, сопоставить им глубину невозможно в приниципе.
-
разрывы в карте глубины
-
“протекание глубины” объектов с заднего плана на объекты переднего плана
Поэтому авторы решили модифицировать MVS алгоритм, исходя из тезиса, что лучше у них будет меньше тренировочных данных, но они будут правильные. Для этого они во-первых, сделали процесс получения карты глубин итеративным. При этом на каждой итерации, получив новую карту глубин, для каждого пикселя они обновляли глубину, только если она не слишком сильно увеличивалась относительно текущего значения глубины для данного пикселя. Так же после того как все итерации пройдены и карта глубины сформирована, они применяли к ней медианный фильтр $5 \times 5$ и для пикселей у которых глубина сильно отличалась от средней также сбрасывали значение глубины в неопределенное состояние. С одной стороны это заметно улучшило качество, с другой сильно “подъело” глубины для объектов на переднем плане.
В среднем столбце карта глубины, полученная без применения улучшений, в правом столбце вариант полученный с использованием алгоритма, улучшающего карту глубины.
Во-вторых, авторы решили, что если разметить фотографию при помощи семантической сегментации, то это также позволит улучшить качество карты глубины. Они разбили все классы на которые натренирована сеть, используемая для семантической сегментации, на три метакласса:
-
Объекты переднего плана (люди, машины, цветы, знаки дорожного движения и т.п.)
-
Объекты заднего плана (здания, водопады, горы и т.п.)
-
Небо
Глубина для пикселей попавших в третий класс, сразу объявлялась неопределенной (что вполне логично), а для объектов переднего плана, перебирались все связные наборы пикселей, и если для такого набора глубина была определена менее чем для 50% пикселей, то для всех пикселей набора глубина выставлялась неопределенной.
Таким образом, был получен датасет в котором каждому изображению была сопоставлена карты глубин (возможно не для всех пикселей изображения глубина определена).
Однако, не все изображения выглядели одинаково полезными для тренировки. Авторы исключили из тренировки “детектора расстояний” те изображения у которых глубина была определена меньше чем для 30% пикселей (30% берется от пикселей оставшихся после выбрасывания “неба”). Как показали исследования авторов оставшиеся изображения не содержат большого количества временных объектов (т.е. хорошие изображения можно условно назвать “не селфи”).
Но “плохие” фотографии, авторы не выбросили совсем, оказалось, что такие “селфи” полезны для обучения детектора на определение отношения порядка по глубине объектов. На плохих фотографиях авторы научились автоматически выделять набор пикселей переднего плана $F_{ord}$ и пикселей заднего плана $B_{ord}$, соответственно устанавливая отношение порядка. Они предлагают следующий простой подход дающий 95% точность (т.е. в 95% случаев $F_{ord}$ действительно находится ближе чем $B_{ord}$). В качестве $F_{ord}$ берётся максимальное связное множество пикселей переднего плана (исходя из разбиения на классы семантической сегментацией), а $B_{ord}$ - связный набор пикселей заднего плана, такой, что в нем есть пиксели с глубиной из последнего квартеля глубин всех пикселей на данном изображении.
Описанный выше подход позволил авторам реконструировать 3Д модели для 200 различных точек мира. При этом у них осталось 130’000 различных фотографий с картой глубин. Порядка 100’000 фотографий были оставлены для тренировки определения глубины, и еще около 30’000 были помечены как “селфи”, но на них удалось выделить объекты переднего и заднего плана и они были оставлены для тренировки отношения порядка.
Нейронная сеть предсказатель глубины
В качестве базовой свёрточной сети авторы пробовали три варианта: VGG, ResNet и “hourglass” (см.
Weifeng Chen, Zhao Fu, Dawei Yang, Jia Deng. “Single-Image Depth Perception in the Wild”).
Поскольку напрямую сравнивать предсказанные и размеченные глубины нельзя, можно только с точностью до коэффициента масштабирования (либо, если рассматривать логарифм глубины, до разностной константы). В качестве штрафной функции авторы предлагают функцию инвариантную к масштабированию:
\[\mathcal{L}_{si} = \mathcal{L}_{data} + \alpha\mathcal{L}_{grad} + \beta \mathcal{L}_{ord}\]Функция ошибки глубины
Первое слагаемое это собственно инвариантный к масштабу штраф за неправильное предсказание. Обозначим через $R_i$ разность значений логарифма глубины предсказанной сеткой и размеченной датасете для пикселя $i$, тогда:
\[\mathcal{L}_{data} = \frac 1 n \sum_{i \in I_D}\left(R_i\right)^2 - \frac 1 {n^2} \left(\sum_{i \in I_D}R_i\right)^2\]здесь суммирование идёт по всем пикселям изображения, для которых определена глубина $I_D$ и таких пикселей всего $n$ штук.
Функция сравнения градиентов
Второе слагаемое штрафной функции, штрафует разницу в градиентах логарифмов глубины:
\[\mathcal{L}_{grad} = \frac 1 n \sum_{k}\sum_{i \in I_D}\left(\vert \nabla_x R_i^k \vert + \vert \nabla_y R_i^k \vert \right)\]Это делается на разных масштабах ($R_i^k$ - разность логарифмов глубины для пикселя $i$ и масштабе $k$). Авторы используют четыре масштаба. Это слагаемое, в чем то аналогично, применяемому в алгоритмах вычисления оптического потока и выполняет туже функцию - сглаживает скорость изменения глубины в предсказываемой карте. Влияние этого слагаемого на результат можно оценить по следующей картинке:
здесь в среднем столбце карта глубины предсказанны без использования слагаемого $\mathcal{L}_{grad}$, а в правом столбце с использованием этого слагаемого в штрафной функции.
Функция ошибки порядка глубин
Последнее слагаемое, использует автоматически определенное отношение порядка из “селфи” фотографий. Во время тренировки для каждой картинки из набора “селфи” изображений, выбирается пара пикселей $i$ и $j$ принадлежащих либо переднему $F_{ord}$, либо заднему $B_{ord}$ плану. Для пары этих пикселей считаем разницу глубин $L_i - L_j$, предсказанных сеткой, и домножаем на $r_{ij} = -1$, если $i$-й пиксель “глубже” чем $j$-й получаем $P_{ij} = r_{ij}(L_i - L_j)$, который используем в штрафной функции:
\[\mathcal{L}_{ord} = \begin{cases} \log(1 + \exp(P_{ij})), & P_{ij} \leq \tau\\ \log(1 + \exp\left(\sqrt{P_{ij}}\right)) + с, & P_{ij} > \tau \end{cases}\]здесь $c$ - константа, которая выбирается таким образом, чтобы функция $\mathcal{L}_{ord}$ была непрерывной. Добавление данного слагаемого к штрафной функции иллюстрируется следующей картинкой (авторы выбрали $\tau = 0.25$):
В среднем столбце вариант без добавления третьего слагаемого в функцию ошибки, в правом - с использованием $\mathcal{L}_{ord}$.
Результаты
Результаты обнадёживающие, но не сказать, чтобы поражают воображение. Таблички с цифрами можно посмотреть в оригинальной статье. Из них следует, что
-
Два дополнительных слагаемых в штрафной функции действительно улучшают качество конечной сети.
-
“hourglass” сеть показывает результат лучший чем VGG и RasNet.
-
Сетка с одной стороны неплохо обобщается, т.е. проверка тренировки только на датасете MageDepth с последующим тестированием на Make3D и KITTI показывает качество почти такое же как у сетей, которые тренировались на самих Make3D и KITTI, такое же, но всё же хуже чем лучшие представители. Если же тренировать на MegaDepth с добавлением тренировочной части конкретного датасета, то результат становится лучше из всех представленных для сравнения.
Вывод.
Конечно, наиболее интересен сам MegaDepth и подход продемонстрированный при его сборке. Т.е. фактически был набран очень большой и представительный датасет для решения задачи определения глубины по одному изображению, с использованием фотографий из интернета и инструментов автоматической разметки. Полученная в результате сеть показательна как демонстрация возможностей собранного датасета.