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

Набор данных

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

Ниже приведен список категорий, которые я использовал для утилизации:

  • Платья
  • Блузки и рубашки
  • Толстовки с капюшоном и свитера
  • Свитера
  • Куртки и пальто

Я использовал запросы и BeautifulSoup для скрапинга. Изображения продавцов можно получить с главной страницы товара, но для изображений пользователей нам необходимо просмотреть страницы отзывов. На странице товара есть такая штука, как цвета. Цвет может быть просто предметом другого цвета или даже совсем другим предметом. Поэтому мы будем рассматривать разные цвета как разные предметы.

Вы можете найти код, который я использовал для получения всей информации об одном предмете (он отбрасывает даже больше, чем нам нужно для нашей задачи), по ссылке https://github.com/movchan74/street_to_shop_experiments/blob/master/get_item_info.py .

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

Наконец, у нас будет два набора изображений для каждого товара: изображения от продавца (поле url для каждого элемента вitem['colors']) и изображения от пользователей (поле imgs для каждого элемента вitem['feedbacks']).

Для каждого цвета у нас есть только одно изображение от продавца, но это может быть более одного изображения для каждого цвета от пользователей (иногда изображения для цвета отсутствуют вообще).

Большой! У нас есть данные. Однако собранный набор данных зашумлен:

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

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

  • Вторая проблема - это товары, которые продают несколько продавцов. Продавцы иногда даже имеют одни и те же изображения (или слегка отредактированные изображения). Но как с этим бороться? Самый простой способ - ничего не делать и использовать надежный алгоритм дистанционного обучения метрикам. Однако это может повлиять на валидацию, потому что у нас может быть один и тот же элемент в данных валидации и обучения. Так что это приводит к утечке данных. Другой способ - использовать что-то, чтобы найти похожие (или даже идентичные изображения) и объединить их в один элемент. Мы можем использовать перцептивное хеширование, чтобы найти идентичные изображения (например, phash или whash), или мы можем обучить модель на зашумленных данных и применить модель для поиска похожих изображений. Я выбрал второй вариант, потому что он позволяет объединять даже слегка отредактированные изображения.

Дистанционное метрическое обучение

Один из самых популярных методов дистанционного метрического обучения - тройная потеря:

где max (x, 0) - функция шарнира, d (x, y) - функция расстояния между x и y , F (x) - глубокая нейронная сеть, M - граница, a - привязка, p - положительная точка , n - отрицательная точка.

F (a), F (p), F (n) - это точки в многомерном пространстве (вложения), созданные глубокой нейронной сетью. Стоит отметить, что вложения часто необходимо нормализовать, чтобы иметь единичную длину, то есть || x || = 1, чтобы быть устойчивым к изменениям освещения и контрастности, а также для стабильности тренировки. Якорь и положительные образцы принадлежат к одному классу, отрицательный образец является экземпляром другого класса.

Таким образом, основная идея потери триплета состоит в том, чтобы отделить вложения положительной пары (якорной и положительной) от вложений отрицательной пары (якорной и отрицательной) с помощью запаса расстояния M.

Но как выбрать тройку (a, p, n)? Мы можем просто случайным образом выбрать сэмплы как тройку, но это вызовет следующие проблемы. Во-первых, существует N³ возможных троек. Значит, нам нужно много времени, чтобы перебрать все возможные тройни. Но на самом деле нам не нужно этого делать, потому что после нескольких итераций обучения будет много триплетов, которые не нарушают ограничение триплетов (дают нулевые потери). Значит, эти тройни бесполезны для тренировки.

Один из наиболее распространенных способов выбора триплетов - это жесткий негативный майнинг:

Выбор самых сложных негативов на практике может привести к плохим локальным минимумам на ранних этапах тренировки. В частности, это может привести к свертыванию модели (т. Е. F (x) = 0). Чтобы смягчить это, мы можем использовать полужесткий отрицательный майнинг.

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

Есть два способа создания полужестких (и жестких) отрицательных образцов: онлайн и офлайн.

  • Онлайн означает, что мы случайным образом выбираем образцы из набора данных поезда в виде мини-пакета и выбираем триплеты из образцов внутри него. Однако нам нужен большой размер мини-партии для онлайн-метода. В моем случае это невозможно, потому что у меня только одна GTX 1070 с 8 ГБ ОЗУ.
  • В автономном методе нам нужно остановить обучение через некоторое время, спрогнозировать вложения для некоторого количества выборок, выбрать триплеты и обучить модель с этими триплетами. Это означает, что нам нужно выполнить прямой проход два раза, но это плата за автономный метод.

Хороший! Мы уже можем приступить к обучению модели с триплетным проигрышем и полужестким отрицательным майнингом в автономном режиме. Но! В этом несовершенном мире всегда есть одно «но». Нам нужен еще один прием, чтобы успешно решить проблему «с улицы до магазина». Наша задача - найти изображение продавца, максимально приближенное к изображению пользователя. Однако обычно изображения продавца имеют гораздо лучшее качество (с точки зрения освещения, камеры и положения), чем изображения пользователя, поэтому у нас есть два домена: изображения продавца и изображения пользователя. Чтобы получить эффективную модель, нам нужно уменьшить разрыв между этими двумя областями. Эта проблема называется адаптацией домена.

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

Реализация

Для реализации своих идей и проведения быстрых экспериментов я использовал библиотеку Keras с бэкэндом Tensorflow.

Я выбрал модель Inception V3 в качестве базовой CNN для своей модели. Как обычно, я инициализировал CNN с весами ImageNet. Я добавил два полностью связанных слоя после глобального пула с L2-нормализацией в конце сети. Размер вложения 128.

Нам также необходимо реализовать тройную функцию потерь. Мы передаем привязку, положительные / отрицательные выборки как одну мини-серию и делим ее на 3 тензора внутри функции потерь. Функция расстояния - это квадрат евклидова расстояния.

И скомпилируйте модель:

Результаты экспериментов

Производительность измеряется с точки зрения отзыва на K (R @ K).

Давайте посмотрим, как рассчитать R @ K. Изображение каждого пользователя из набора для проверки использовалось в качестве запроса, и нам нужно найти соответствующее изображение продавца. Берем одно изображение запроса, вычисляем вектор встраивания и ищем ближайших соседей этого вектора среди векторов всех изображений продавца. Мы используем не только изображения продавца из набора для валидации, но и изображения из набора поезда, потому что это позволяет увеличить количество отвлекающих факторов и усложняет нашу задачу.

Итак, у нас есть изображение для запроса и список изображений наиболее похожих продавцов. Если в K наиболее похожих изображениях есть соответствующее изображение продавца, мы возвращаем 1 для этого запроса, иначе возвращаем 0. Теперь нам нужно сделать это для каждого изображения пользователя в наборе проверки и найти средние оценки по каждому запросу. Это будет R @ K.

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

Результаты далеки от идеала, есть много чего:

  • Очистите изображения пользователя от шума. Я уже сделал первый шаг в этом направлении, очистив небольшой набор.
  • Более точное слияние элементов (по крайней мере, в проверочном наборе).
  • Уменьшить разрыв домена. Я полагаю, что это можно сделать с помощью доменно-зависимых расширений (например, увеличения освещения) и с помощью специализированных методов (например, https://arxiv.org/abs/1409.7495).
  • Примените другой метод дистанционного метрического обучения. Я пробовал этот https://arxiv.org/abs/1703.07464, но в моем случае он работает хуже.
  • Конечно, собирайте больше данных.

Демо, код и обученная модель

Я сделал демонстрацию модели. Вы можете проверить это здесь: http://vps389544.ovh.net:5555/. Вы можете загрузить собственное изображение для поиска или использовать случайное изображение из набора для проверки.

Код и обученная модель: https://github.com/movchan74/street_to_shop_experiments

Спасибо за прочтение. Если вам понравилась статья, дайте мне знать, хлопнув в ладоши. Если вам нужна дополнительная информация, вы можете связаться со мной в LinkedIn.