Хабрахабр

Как и зачем мы делали распознавание достопримечательностей в Облаке Mail.ru

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

Для этого мы — команда машинного зрения Mail.ru — создали и внедрили системы «умной» обработки фотографий: поиск по объектам, сценам, лицам и др. Одной из целей Облака Mail.ru является обеспечение наиболее удобного доступа и поиска по своему фото и видеоархиву. И сегодня я расскажу про то, как с помощью Deep Learning мы решили эту задачу.
Представьте ситуацию: вы съездили в отпуск и привезли кучу фотографий. Еще одной такой яркой технологией является распознавание достопримечательностей. Вы начинаете судорожно скролить папку с фотографиями, пытаясь найти нужную. И в разговоре с друзьями вас попросили показать, как вы побывали у какого-нибудь дворца, замка, пирамиды, храма, озера, водопада, горы и т.п. Скорее всего, вы её не находите среди сотен изображений, и говорите, что покажете потом.

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

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

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

  • Во-первых, мы не можем ясно описать, что такое «достопримечательность». Мы не можем сказать, почему одно здание является достопримечательностью, а стоящее рядом с ним — не является. Это не формализованное понятие, что усложняет постановку задачи распознавания.
  • Во-вторых, достопримечательности крайне разнообразны. Это могут быть исторические или культурные здания — храмы, дворцы, замки. Это могут быть самые разнообразные памятники. Это могут быть природные объекты — озёра, каньоны, водопады. И одна модель должна уметь находить все эти достопримечательности.
  • В-третьих, изображений с достопримечательностями крайне мало, по нашим подсчётам, они встречаются лишь на 1—3 % пользовательских фотографий. Поэтому мы не можем себе позволить ошибки в распознавании, потому что если покажем человеку фото без достопримечательности, это будет сразу заметно и вызовет недоумение и негативную реакцию. Или, напротив, мы показали человеку фото с достопримечательностью в Нью-Йорке, а он никогда в Америке не был. Так что модель для распознавания должна иметь низкий FPR (false positive rate).
  • В-четвертых, около 50 % пользователей, а то и больше, отключают сохранение геоинформации при фотографировании. Нам это нужно учитывать и определять место исключительно по изображению. Большинство сервисов, которые сегодня каким-то образом умеют работать с достопримечательностями, делают это благодаря геоданным. У нас же исходные требования были жёстче.

Покажу теперь на примерах.

Левый — это Амьенский собор, посредине Реймсский собор, справа — Нотр-Дам-де-Пари. Вот похожие объекты, три французских готических собора.

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

Фотографии получились очень разные, но их все нужно распознавать и находить. А вот пример другого затруднения: эти три фотографии на слайде — Нотр-Дам-де-Пари, снятый с разных ракурсов.

Слева — Кейсария в Израиле, справа — Английский парк в Мюнхене. Природные объекты полностью отличаются от архитектурных.

На этих фотографиях очень мало характерных деталей, за которые модель может «зацепиться».

Наш метод полностью основан на глубоких свёрточных нейронных сетях. В качестве подхода к обучению выбрали так называемое curriculum learning — обучение в несколько этапов. Чтобы эффективнее работать как при наличии геоданных, так и при их отсутствии, мы сделали особый inference (вывод). Расскажу про каждый из этапов подробнее.
Топливом для машинного обучения являются данные. И в первую очередь нам нужно было собрать датасет для обучения модели.

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

Результаты получались плохие. Сначала мы попробовали обучить на получившейся базе нашу модель. На каждую достопримечательность приходилось большое количество мусора. Стали анализировать, и оказалось, что данные очень «грязные». Вручную пересматривать весь огромный объём данных дорого, муторно и не очень умно. Что делать? Получается довольно быстро, потому что объём таких эталонных данных небольшой относительно всей базы. Поэтому мы сделали автоматическую чистку базы, в ходе которой лишь на одном шаге используется ручная обработка: для каждой достопримечательности мы вручную отобрали 3—5 эталонных фотографий, которые точно содержат нужную достопримечательность в более-менее правильном ракурсе. Затем уже выполняется автоматическая чистка на основе глубоких свёрточных нейронных сетей.

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

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

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

достопримечательностей из более чем 500 городов в 70 странах мира — свыше 2,3 млн фотографий. В итоге мы получили базу, которая содержит более 11 тыс. Эту информацию нужно каким-то образом рассказывать нашим моделям. Теперь пора вспомнить, что большая часть фотографий вообще не содержит достопримечательностей. фотографий без достопримечательностей, и обучили на получившемся датасете нашу модель. Поэтому мы добавили в нашу базу 900 тыс.

Исходя из того, что достопримечательности встречаются лишь примерно на 1—3 % фотографий, мы вручную составили набор из 290 снимков, на которых достопримечательности есть. Для измерения качества обучения мы ввели оффлайн-тест. По тому же принципу мы отобрали 11 тыс. Это разные, достаточно сложные фотографии с большим количеством объектов, снятых с разных ракурсов, чтобы тест был как можно сложнее для модели. фотографий без достопримечательностей, тоже достаточно сложных, причём постарались найти объекты, которые сильно похожи на достопримечательности, имеющиеся в нашей базе.

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

В научной литературе относительно мало информации по распознаванию достопримечательностей. Большинство решений основаны на локальных признаках. Идея в том, что у нас есть некая картинка-запрос и картинка из базы. На этих картинках мы находим локальные признаки — ключевые точки, и сравниваем их. Если количество совпадений достаточно большое, мы считаем, что нашли достопримечательность.

Прогоняя входное изображение через свёрточную сеть, мы получаем некоторые DELF-признаки. На сегодняшний день лучшим является метод, предложенный Google, — DELF (deep local features), в котором сравнение локальных признаков скомбинировано с глубоким обучением.

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

Для Deep Learning крайне важно предварительное обучение. Поэтому мы взяли базу сцен и предобучили на ней нашу нейронную сеть. Почему именно так? Сцена — это комплексный объект, который включает в себя большое количество других объектов. А достопримечательность является частным случаем сцены. Предобучая модель на такой базе, мы можем дать модели представление о некоторых низкоуровневых признаках, которые потом можно обобщать для успешного распознавания достопримечательностей.

Главной их особенностью является то, что они используют residual block, который включает в себя skip connection, позволяющий сигналу проходить свободно, не попадая в слои с весами. В качестве модели мы использовали нейронную сеть из семейства Residual network. С такой архитектурой можно качественно обучать глубокие сети и бороться с эффектом размытия градиента, что очень важно при обучении.

Наша модель — это Wide ResNet 50-2, модификация ResNet 50, в которой в два раза увеличено количество сверток во внутреннем bottleneck-блоке.

Мы провели тесты на нашей базе сцен и вот, что получили: Сеть работает очень эффективно.

Wide ResNet оказалась практически вдвое быстрее, чем довольно большая сеть ResNet 200. А скорость работы очень важна для эксплуатации. По совокупности этих обстоятельств мы и взяли Wide ResNet 50-2 в качестве нашей основной нейронной сети.

Обучение

Для обучения сети нам нужен loss (функция потерь). Для его подбора мы решили использовать подход metric learning: нейронная сеть обучается так, чтобы представители одного и того же класса стягивались в один кластер. При этом кластеры для разных классов должны быть как можно дальше друг от друга. Для достопримечательностей мы использовали Center loss, который стягивает точки одного и того же класса к некоторому центру. Важной особенностью этого подхода является то, что он не требует негативного сэмплирования, которое на поздних этапах обучения является достаточно трудной процедурой.

Мы подразумеваем, что достопримечательность — это один и тот же объект, и в нём есть структура, поэтому целесообразно считать для него центр. Напомню, что у нас есть n классов достопримечательностей и ещё один класс «не достопримечательности», для него Center loss не используется. А не достопримечательностью может быть всё, что угодно, и считать для него центр неразумно.

Она состоит из трёх основных частей: Затем мы собрали всё это вместе и получили модель для обучения.

  • Свёрточная нейросети Wide ResNet 50-2, предобученной на базе сцен;
  • Части эмбеддинга, состоящей из полносвязного слоя и слоя Batch norm;
  • Классификатора, который является полносвязным слоем, за которым следует пара из Softmax loss и Centre loss.

Эти 4 части мы используем в рамках парадигмы curriculum learning. Как вы помните, наша база разделена на 4 части по регионам мира. На каждом этапе у нас есть текущий датасет, мы добавляем к нему ещё одну часть света и получается новый обучающий датасет.

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

Нужно понять, как она работает. Итак, мы обучили модель. На картинке ниже в первом ряду входные изображения, а во втором на них наложена class activation map от сетки, которую мы обучили на предыдущем этапе. Давайте с помощью class activation map посмотрим, на какую часть изображения больше всего реагирует наша нейронная сеть.

Из class activation map видно, что наша нейронная сеть успешно выучила понятие достопримечательности. Тепловая карта показывает, каким частям изображения сеть уделяет больше внимания.

Inference

Теперь нужно каким-то образом использовать это знание, чтобы получать результат. Поскольку для обучения мы использовали Center loss, то представляется вполне логичным на inference также вычислять цетроиды для достопримечательностей.

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

Вначале ответ представляется ясным и логичным: один центроид. Но возникает вопрос: сколько центроидов на одну достопримечательность имеет смысл вычислять? Сначала мы тоже решили сделать по одному центроиду и получили достаточно неплохой результат. Но это оказалось не совсем так. Так почему надо брать несколько центроидов?

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

Я хочу посчитать для него центроид. Например, у меня есть класс достопримечательности Зимний дворец. Если считать центроид по всем изображениям, то получится не слишком устойчиво. Но в наборе оказалось некоторое количество фотографий с Дворцовой площадью и аркой Главного штаба. Нужно каким-то образом кластеризовать их эмбеддинги, которые получены из обычной сетки, взять только тот центроид, который отвечает за Зимний дворец, и уже по этим данным посчитать среднее.

Во-вторых, фотографии могут быть сняты в разных ракурсах.

Для неё посчитано два центроида. Приведу в качестве иллюстрации такого поведения колокольню Белфорт в Брюгге. В верхнем ряду изображения те фото, которые ближе к первому центроиду, а во втором ряду — те, что ближе ко второму центроиду:

А второй центроид отвечает за фотографии, сделанные издали, с сопредельных улиц. Первый центроид отвечает за более «парадные» фотографии с близкого расстояния, которые сделаны с рыночной площади Брюгге.

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

К наборам данных для каждой достопримечательности мы применяем иерархическую кластеризацию — complete link. Итак, как же мы находим эти множества для вычисления центроидов? Под валидными кластерами мы понимаем те, которые в результате кластеризации содержат не меньше 50 фотографий. С её помощью мы находим валидные кластеры, по которым будем вычислять центроиды. В результате у нас получилось, что около 20 % достопримечательностей имеют более одного центроида. Остальные кластеры мы отбрасываем.

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

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

Мы сравнили нашу модель с DELF, для которой взяли параметры, при которых она показала лучшие результаты на нашем тесте. Результаты оказались практически одинаковые.
Затем мы разделили достопримечательности на два типа: частые (более 100 фотографий), которые составляют 87 % от всех достопримечательностей в тесте, и редкие. На частых наша модель работает хорошо: точность 85,3 %. С редкими достопримечательностями мы получили 46 %, что тоже очень неплохо — даже при малом количестве данных наш подход показывает приличные результаты.
После мы провели А/B-тестирование на пользовательских фотографиях. В результате конверсия покупки места в облаке увеличилась на 10 %, конверсия удаления мобильного приложения упала на 3 %, а количество просмотров альбомов увеличилось на 13 %.

На GPU DELF требует 7 прогонов сетки, потому что использует 7 масштабов изображения, а наш подход использует только 1 прогон. Сравним скорость работы нашего подхода и DELF. В результате наш метод на CPU оказался в 15 раз быстрее. На CPU DELF использует более долгий поиск по методу ближайших соседей и очень долгую геометрическую верификацию. В обоих случаях наш подход выигрывает в скорости, что крайне важно при эксплуатации.

В начале статьи я упомянул о решении проблемы скролинга и поиска нужных картинок с достопримечательностями. Вот оно.

Есть альбом «Люди», «Объекты», «Достопримечательности». Это мое облако, и в нём все фотографии разбиты на альбомы. Если кликнуть по Цвингеру в Дрездене, то откроется альбом с фотографиями только этой достопримечательности. Внутри него достопримечательности разбиты по альбомам, которые сгруппированы по городам.

А когда захотелось залить их в Instagram или поделиться с друзьями и близкими, не придётся долго искать и выбирать, всего несколько кликов — и вы найдёте нужные фотографии. Очень полезная фича: съездил в отпуск, пофоткал, сложил в облако.

Напомню о главных моментах нашего решения.

  1. Полуавтоматическая чистка базы. Немного ручного труда для начальной разметки, а дальше нейронная сеть справляется сама. Это позволяет быстро чистить новые данные и дообучать на них модель.
  2. Мы используем глубокие свёрточные нейронные сети и deep metric learning, который позволяет нам эффективно выучивать структуру в классах.
  3. В качестве парадигмы обучения мы использовали curriculum learning — обучение по частям. Этот подход нам очень сильно помог. На inference мы применяем несколько центроидов, которые позволяют использовать более чистые данные и находить разные ракурсы достопримечательностей.

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

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть