Прошлым летом группа художников и программистов создала Terrapattern, новаторскую демонстрацию визуального поиска по спутниковым изображениям. Нам это понравилось. Демо соответствовало многим идеям, которые мы выдвигали в Descartes Labs, и было здорово видеть, как кто-то просто вышел и сделал это. Это заставило нас задуматься о том, как расширить визуальный поиск за пределы городов, целых стран или даже всего мира.

Сегодня мы делимся собственной демонстрацией этой технологии GeoVisual Search. Основная идея:

• разделить поверхность Земли на небольшие перекрывающиеся изображения;
• извлечь «вектор визуальных признаков» из каждого изображения с помощью сверточной нейронной сети;
• по изображению запроса выполните поиск «визуальных соседей» в этом пространство функций.

Давайте углубимся в некоторые технические детали.

Изображения

Мы ищем изображения в двух источниках:

  • Аэросъемка над США. Мы используем 1-метровые изображения, полученные в рамках Национальной программы аэрофотосъемки (NAIP) и Техасской программы ортоизображений, которые охватывают 48 штатов нижнего этажа.
  • Landsat 8 над Землей. Недавно мы сделали 15-метровую глобальную композицию, используя все данные со спутника Landsat 8, жемчужины программы NASA по наблюдению за Землей.

Мы использовали здесь изображения RGB, но методы обобщаются на другие длины волн света, такие как инфракрасный или SAR, или на более чем три полосы. Мы разрезаем эти изображения на небольшие перекрывающиеся плитки, по 128 пикселей по бокам, и приступаем к созданию элементов.

Возможности

Мы начинаем с 50-слойной архитектуры ResNet, предварительно обученной на Imagenet, и все это удобно предоставляется пакетом глубокого обучения Keras. Похоже на этот 34-слойный ResNet, только длиннее:

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

Двоичные функции. Мы решили, что в конечном итоге хотим искать по двоичным функциям из-за их меньшего объема памяти. С этой целью мы рекомендовали сети создавать характеристики, очень близкие к 0,0 или 1,0 на интересующем слое, вводя шум (во время обучения) с амплитудой, сравнимой с шириной функции активации слоя. Сеть учится создавать на этом слое почти бинарные объекты - в противном случае шум уничтожает информацию, которую слой пытается передать. Наконец, мы бинаризуем функции с плавающей запятой, установив порог 0,5.

Настройка для спутниковых изображений. Мы настроили эту сеть для работы с каждым источником спутниковых изображений. Что касается NAIP, мы последовали примеру Terrapattern и настроили сеть, чтобы разделить ее примерно на 100 классов OpenStreetMap (OSM), таких как парковки или поля для гольфа. В итоге мы добавили пару полностью связанных слоев и извлекли 512 двоичных функций из одного из них. Для Landsat 8 классы OSM были менее полезны, поэтому вместо этого мы использовали автоэнкодер для сжатия исходных 2048 функций Imagenet с плавающей запятой в 512 двоичных функций.

В конце этого процесса мы сопоставили 393216 бит (исходное изображение 128x128x3) с 512 битами (вектор признаков). Эти функции образуют компактное представление визуальной информации, присутствующей в каждом изображении.

Мы предварительно вычисляем векторы признаков для всех плиток в каждом наборе данных: около 2 миллиардов плиток для NAIP и около 200 миллионов плиток для Landsat 8. Мы распределили это вычисление между десятками тысяч процессоров в облачной платформе Google.

Поиск

Теперь, когда у нас есть векторы признаков, как нам искать похожие векторы?

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

Затем нам нужно найти k векторов, ближайших к вектору запроса. Мы используем два метода:

  • Прямой поиск. Используя низкоуровневые инструкции для сравнения байтов и подсчета битов, мы можем выполнить прямой поиск методом перебора более 200 миллионов изображений примерно за 2 секунды. Это решение работает для набора данных Landsat 8, который содержит около 200 миллионов изображений.
  • Поиск на основе хэшей. Набор данных NAIP содержит около 2 миллиардов изображений, и хотя прямой поиск здесь работает, он слишком медленный для интерактивного использования. Вместо этого мы используем приближенный метод битовой выборки, который представляет собой простую форму хеширования с учетом локальности. В частности, мы используем семейство из 32 хэш-функций, каждая из которых проверяет 16 бит полного 512-битного вектора признаков. Каждая хеш-функция возвращает набор соседей-кандидатов, и мы выполняем перебор полного (но относительно небольшого) списка кандидатов. Мы храним хеш-таблицы в Google Cloud Bigtable, и поиск занимает около 0,1 секунды.

Результат всего этого: вы нажимаете на какой-то кусок земли, и мы возвращаем похожие изображения примерно через одну секунду. "Попытайся"!

Это основные части GeoVisual Search, но за кулисами работает так много технологий, которые мы здесь не рассмотрели: наш конвейер изображений, наш API Python для доступа к этим изображениям, наша настраиваемая виртуальная файловая система для хранения облачных объектов, серверы карт с автоматическим масштабированием, пользовательский интерфейс и многое другое. Следите за новостями в нашем техническом блоге.

Это был действительно интересный проект, который направил нас в новые направления применения компьютерного зрения к спутниковым изображениям в большом масштабе. Следите за новостями, и если вы думаете, что можете присоединиться к нашей команде, мы нанимаем!