А вы купили новую женскую одежду на майские праздники?
Когда дело доходит до покупки одежды, у вас должен был быть следующий опыт: идя по улице и вдруг увидев кого-то в крутой одежде (нв) одежде (чжуан), вы не можете не задаться вопросом, где вы купили такую красивую одежду, я действительно хотите Купить предмет одежды, но не знаете других, поэтому можете только смотреть на «одежку» и вздыхать. Но что, если бы теперь существовал способ находить онлайн-продавцов по фотографиям одежды?
В Германии есть программист Александр Мовчан, который специально назвал эту задачу——"Улица в магазин"(Street-to-Shop) покупки, и решил использоватьдистанционное метрическое обучение(Дистанционное метрическое обучение или DML) решает эту проблему. (Больше не бойтесь, что не сможете купить любимую женскую одежду!)
метрическое обучение
Прежде чем представить этот учебник по покупкам, давайте кратко поговорим об обучении метрикам. Метрическое обучение также известно как обучение по сходству.Если необходимо рассчитать сходство между двумя изображениями, то как измерить сходство между изображениями, чтобы сходство изображений разных категорий было небольшим, а сходство изображений одной категории большим, является целью метрического обучения.
В математике метрика (или функция расстояния) — это функция, определяющая расстояние между элементами множества. Набор с метриками называется метрическим пространством. Например, если наша цель — распознавать лица, то нам нужно построить функцию расстояния, чтобы усилить соответствующие признаки (такие как цвет волос, форма лица и т. д.), а если наша цель — распознать позы, то нам нужно построить сходство позы захвата функция расстояния. Чтобы справиться с широким спектром сходства признаков, мы можем вручную построить функции расстояния, выбрав соответствующие признаки для конкретной задачи. Однако этот метод требует много ручного ввода, а также может быть очень устойчивым к изменениям данных. В качестве идеальной альтернативы метрическое обучение может самостоятельно изучать функцию метрического расстояния для конкретной задачи в соответствии с разными задачами.
Методы метрического обучения можно разделить на метрическое обучение посредством линейного преобразования и нелинейные модели с метрическим обучением. Некоторые очень классические алгоритмы уменьшения линейной размерности без учителя также можно рассматривать как метрическое обучение Махаланобиса без учителя, например, анализ основных компонентов, преобразование многомерного масштабирования и т. д.
Метричное обучение применялось для поиска и классификации изображений в компьютерном зрении, распознавании лиц, распознавании человеческой деятельности и оценке позы, анализе текста и некоторых других областях, таких как анализ музыки, автоматическая отладка проектов, анализ данных микрочипов и т. д. Давайте взглянем на конкретный учебник ниже.
Создайте набор данных
Во-первых, как и в случае любой проблемы машинного обучения, нам нужен набор данных. На самом деле, когда однажды я увидел большое количество фотографий одежды на AliExpress, у меня возникла идея: я могу использовать эти данные, чтобы сделать функцию поиска на основе фотографий. Чтобы все было просто и удобно, я решил сосредоточиться на женской одежде, а девочки (и некоторые мальчики) любят покупать одежду.
Вот категория женской одежды, для которой я собираю изображения:
-
юбка
-
Футболка женская
-
Толстовки и толстовки
-
свитер
-
Куртки и пальто
я использовал запросыrequestsиBeautifulSoupСканирование изображений. Фотографии одежды продавца можно получить на главной странице категории одежды, а фотографии, загруженные покупателями, необходимо получить в области оценки. На странице одежды есть свойство «цвет», которое можно использовать для определения того, является ли одежда другим цветом или даже совершенно другой одеждой. Поэтому мы относимся к одежде разных цветов как к разным товарам.
вы можете нажатьздесьПосмотрите код, который я использую, чтобы получить всю информацию об одежде.
Нам просто нужно выполнить поиск на странице одежды по категории одежды, получить URL-адреса всей одежды, использовать приведенный выше код, чтобы получить информацию для каждой одежды.
В итоге мы получаем два набора изображений для каждого предмета одежды: изображения от продавца (поле URL для каждого элемента в элементе ['colors']) и изображения от покупателя (каждое в элементе item['feedbacks']). поле URL).
Для каждого цвета мы получаем только одну фотографию от продавца, но от покупателя может быть несколько фотографий, а иногда даже нет одной фотографии (это то же самое, что покупатель показывает на Tmall, некоторые будут больше Показать специальное шоу, а некоторые и не шоу).
очень хороший! Мы получили нужные данные. Однако в результирующем наборе данных много зашумленных данных: В данных изображений от покупателей много шума, например, фотографии экспресс-посылок, фотографии, на которых видна только фактура одежды и только ее часть, а также некоторые фотографии, сделанные, когда посылка только что была разорвана.
Чтобы смягчить эту проблему, мы разбили 5000 изображений на две категории: фотографии без помех и фотографии с шумом. Сначала я планировал обучить классификатор для обоих классов, а затем использовать его для очистки набора данных. Но потом я решил оставить эту работу и просто добавить чистые данные в тестовые и проверочные наборы данных.
Вторая проблема заключается в том, что иногда несколько продавцов продают одну и ту же одежду, а иногда несколько магазинов одежды показывают одни и те же фотографии одежды (или просто немного обрабатывают). Как решить эту проблему?
Самый простой способ — ничего не делать и использовать надежный алгоритм дистанционного метрического обучения. Однако этот способ повлияет на производительность проверки набора данных, потому что у нас будет одинаковая одежда в данных проверки и обучения. Так что это приведет к утечке данных. Другой способ — найти похожие (или даже идентичные) предметы одежды и объединить их в один предмет одежды. Мы можем использовать перцептивное хеширование, чтобы найти одинаковые фотографии одежды, или мы можем обучить модель с зашумленными данными, чтобы найти те же фотографии одежды. Я выбрал второй способ, потому что он позволяет объединить одинаковые фотографии в одну, даже слегка отредактированную фотографию.
дистанционное метрическое обучение
Одним из наиболее часто используемых методов дистанционного метрического обучения является потеря триплетов:
где 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³ возможных троек. Это означает, что нам нужно потратить много времени на обход всех возможных триплетов. Но на самом деле нам этого делать не нужно, потому что после нескольких итераций обучения многие мета-триплеты уже укладываются в лимит триплетов (например, 0 потерь), а значит, эти триплеты для обучения бесполезны.
Одним из наиболее распространенных способов выделения триплетов является жесткий отрицательный майнинг:
Выбор самых сложных выборок может фактически привести к плохим локальным минимумам в начале обучения. В частности, это вызывает сжатие модели (например, F(x) = 0). Чтобы решить эту проблему, мы можем использовать полужесткий негативный майнинг.
Полужесткие образцы находятся немного дальше от привязки, чем положительные образцы, но они все равно неразличимы (не удовлетворяют ограничениям триплета), поскольку находятся внутри границы M.
Существует два способа создания полутвердых (и жестких) семплов: онлайн и офлайн.
-
Онлайн-метод означает, что мы можем случайным образом выбрать несколько выборок из набора обучающих данных, чтобы сформировать мини-пакет данных, и выбрать триплет из выборок внутри. Но в онлайн-режиме нам также нужны большие пакеты данных. В нашем случае это было невозможно, потому что у меня была только GTX 1070 с 8 ГБ ОЗУ.
-
В автономном режиме нам нужно через определенные промежутки времени останавливать обучение, предсказывать векторы для определенного количества выборок, выбирать триплеты и использовать эти триплеты для обучения модели. Это означает, что нам нужно выполнить два форвардных расчета, что является небольшой платой за использование автономного метода.
очень хороший! Теперь мы можем обучить модель с потерей триплетов и автономным полужестким извлечением образцов. но! (Есть «но» каждый раз, когда что-то хорошее близко, и на этот раз это не так.) Нам также нужен какой-то способ идеально решить проблему «с улицы в магазин». Наша задача найти фотографии одежды самого высокого уровня как для продавцов, так и для покупателей.
Однако часто качество фотографий у продавцов намного лучше, чем у фотографий, загруженных покупателями (вспомните и об этом, фотографии, размещенные интернет-магазинами, как правило, проходят N-стороннюю PS-обработку), поэтому у нас будет два домена: фотографии продавца и фотографии покупателя. Чтобы получить эффективную модель, нам нужно сократить разрыв между этими двумя областями. Эта проблема называется адаптацией домена.
Я предлагаю очень простой способ сократить разрыв между этими двумя доменами: мы выбираем анкоры из фотографий продавца и положительные и отрицательные образцы из фотографий покупателя. Это оно! Простой, но эффективный.
выполнить
Чтобы быстро реализовать свою идею и поэкспериментировать, я использовал библиотеку Keras и бэкэнд TensorFlow.
Я выбрал Inception V3 в качестве базовой сверточной нейронной сети для своей модели. Как и в обычной работе, я инициализировал сверточную нейронную сеть с весами ImageNet. Затем добавьте два полносвязных слоя в конце сети после регуляризации с помощью L2. Размер вектора 128.
def get_model():
no_top_model = InceptionV3(include_top=False, weights='imagenet', pooling='avg')
x = no_top_model.output
x = Dense(512, activation='elu', name='fc1')(x)
x = Dense(128, name='fc2')(x)
x = Lambda(lambda x: K.l2_normalize(x, axis=1), name='l2_norm')(x)
return Model(no_top_model.inputs, x)
Нам также необходимо реализовать функцию потерь триплетов, которая может передавать якорные, положительные и отрицательные выборки в функцию в виде отдельных мини-пакетных данных и делить эти мини-пакетные данные на 3 тензора в функции. Функция расстояния представляет собой квадрат евклидова расстояния.
def margin_triplet_loss(y_true, y_pred, margin, batch_size):
out_a = tf.gather(y_pred, tf.range(0, batch_size, 3))
out_p = tf.gather(y_pred, tf.range(1, batch_size, 3))
out_n = tf.gather(y_pred, tf.range(2, batch_size, 3))
loss = K.maximum(margin
+ K.sum(K.square(out_a-out_p), axis=1)
- K.sum(K.square(out_a-out_n), axis=1),
0.0)
return K.mean(loss)
и оптимизировать модель:
#utility function to freeze some portion of a function's arguments
from functools import partial, update_wrapper
def wrapped_partial(func, *args, **kwargs):
partial_func = partial(func, *args, **kwargs)
update_wrapper(partial_func, func)
return partial_func
opt = keras.optimizers.Adam(lr=0.0001)
model.compile(loss=wrapped_partial(margin_triplet_loss, margin=margin, batch_size=batch_size),
Результаты экспериментов
Мера производительности модели называется R@K. Давайте посмотрим, как рассчитать R@K. Для каждой фотографии покупателя в проверочном наборе в качестве запроса нам нужно найти соответствующую фотографию продавца. Каждый раз, когда мы запрашиваем фотографию, мы вычисляем вектор встраивания и ищем ближайшего соседа этого вектора среди всех фотографий продавца. Мы будем использовать не только фотографии продавца в наборе для проверки, но и фотографии продавца в наборе для обучения, так как это увеличивает количество отвлекающих факторов и усложняет нашу задачу.
Таким образом, мы получаем фотографию запроса и список наиболее похожих фотографий продавца. Мы возвращаем 1 для этого запроса, если среди K наиболее похожих фотографий есть соответствующая фотография продавца, и 0, если нет. Теперь нам нужно вернуть такой результат для каждого запроса в наборе проверки, а затем найти средний балл для каждого запроса. Это Р@К.
Как я уже говорил выше, я очистил небольшое количество фотографий покупателей от зашумленных данных. Поэтому я проверил качество модели с двумя наборами проверки: полный набор проверки и подмножество только с чистыми данными.
Результаты модели не очень идеальны, мы также можем сделать это для оптимизации:
-
Очистите данные покупателя от зашумленных данных. В связи с этим я сделал первый шаг, очистив небольшой набор данных.
-
Более точно объединяйте фотографии одежды (по крайней мере, в проверочном наборе).
-
Дальнейшее сокращение разрыва между доменами. Я думаю, что это можно сделать с помощью конкретных методов улучшения предметной области (например, повышения освещенности изображения) и других конкретных методов (таких какЭто эссеметод в).
-
Используя другой метод дистанционного метрического обучения, я попыталсяЭто эссеметод, но эффект хуже.
-
И, конечно же, собрать больше данных.
Демонстрация, код и обученная модель
Я сделал демо для модели, вы можете нажатьздесьПроверять.
Вы можете сфотографировать одежду любимой девушки на улице (будьте осторожны) или найти случайную из проверочного набора и загрузить ее в модель, чтобы посмотреть, как она работает.
нажмитездесь, просмотрите кодовую базу этого проекта.