Встраивания проникли в инструментарий специалистов по данным и кардинально изменили принципы работы НЛП, компьютерного зрения и рекомендательных систем. Однако многие специалисты по данным находят их архаичными и запутанными. Многие другие используют их вслепую, не понимая, что это такое. В этой статье мы подробно рассмотрим, что такое встраивание, как они работают и как они часто используются в реальных системах.

Что такое встраивание?

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

В нейронной сети ниже каждая из входных характеристик должна быть числовой. Это означает, что в таких областях, как рекомендательные системы, мы должны преобразовывать нечисловые переменные (например, элементы и пользователи) в числа и векторы. Мы могли бы попытаться представить товары по идентификатору продукта; однако нейронные сети обрабатывают числовые входные данные как непрерывные переменные. Это означает, что более высокие числа «больше» более низких чисел. Он также видит похожие числа как похожие предметы. Это имеет смысл для такого поля, как «возраст», но бессмысленно, когда числа представляют категориальную переменную. До встраивания одним из наиболее распространенных методов было горячее кодирование.

Быстрое кодирование

Быстрое кодирование было распространенным методом представления категориальных переменных. Этот неконтролируемый метод сопоставляет одну категорию с вектором и генерирует двоичное представление. Фактический процесс прост. Мы создаем вектор с размером, равным количеству категорий, со всеми значениями, установленными на 0. Затем мы устанавливаем строку или строки, связанные с данным идентификатором или идентификаторами, равным 1.

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

Это означает, что термины «хот-дог» и «гамбургер» не ближе друг к другу, чем «хот-дог» и «пепси». В результате у нас нет возможности оценить отношения между двумя объектами. Мы могли бы создать больше взаимно однозначных сопоставлений или попытаться сгруппировать их и найти сходства. Это требует обширной работы и ручной маркировки, что обычно невозможно.

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

Вложения решают проблему кодирования

Вложения - это плотные числовые представления реальных объектов и отношений, выраженные в виде вектора. Векторное пространство количественно определяет семантическое сходство между категориями. Близкие друг к другу вложения векторов считаются подобными. Иногда они используются непосредственно для раздела «Товары, похожие на этот» в интернет-магазине. В других случаях вложения передаются другим моделям. В таких случаях модель может обмениваться знаниями с похожими элементами, а не рассматривать их как две совершенно уникальные категории, как в случае с одним горячим кодированием. По этой причине вложения можно использовать для точного представления разреженных данных, таких как потоки кликов, текст и покупки в электронной коммерции, в качестве функций для последующих моделей. С другой стороны, вложения намного дороже вычислять, чем одноразовые кодировки, и их гораздо труднее интерпретировать.

Как создаются вложения?

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

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

Общие модели встраивания

Анализ главных компонентов (PCA)

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

СВД

Разложение по сингулярным значениям, также известное как SVD, - это метод уменьшения размерности. SVD сокращает количество функций набора данных с N-размерности до K-размерности с помощью матричной факторизации. Например, давайте представим рейтинги видео пользователя в виде матрицы размера (количество пользователей) x (количество элементов), где значение каждой ячейки - это оценка, которую пользователь поставил этому элементу. Сначала мы выбираем число k, которое является размером нашего вектора встраивания, и используем SVD, чтобы превратить его в две матрицы. Один будет (количество пользователей) x k, а другой будет k x (количество элементов).

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

Word2Vec

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

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

Одна из проблем Word2Vec заключается в том, что отдельные слова имеют одно векторное отображение. Это означает, что все семантические использования слова объединены в одно представление. Например, слова «играть» в фразах «Я собираюсь посмотреть спектакль» и «Я хочу сыграть» будут иметь одинаковое вложение, без возможности различать контекст.

БЕРТ

Двунаправленные представления преобразователей кодировщиком, также известные как BERT, - это предварительно обученная модель, которая решает проблемы контекста Word2Vec. BERT обучается в два этапа. Во-первых, он обучается на огромном массиве данных, таких как Википедия, для создания подобных вложений, как Word2Vec. Конечный пользователь выполняет второй шаг обучения. Они тренируются на корпусе данных, который хорошо соответствует их контексту, например, на медицинской литературе. BERT будет точно настроен для этого конкретного случая использования. Кроме того, чтобы создать вложение слова, BERT принимает во внимание контекст слова. Это означает, что слова «играть» в фразах «Я собираюсь посмотреть спектакль» и «Я хочу поиграть» будут иметь разные вложения. BERT стал моделью-преобразователем для создания встраиваемых текстов.

Вложения в реальный мир

Встраивание началось в исследовательских лабораториях и быстро стало современным. С тех пор встраивания нашли свое применение в производственных системах машинного обучения в самых разных областях, включая НЛП, рекомендательные системы и компьютерное зрение.

Рекомендательные системы

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

Семантический поиск

Пользователи ожидают, что панели поиска будут умнее регулярных выражений. Будь то страница поддержки клиентов, блог или Google, панель поиска должна понимать цель и контекст запроса, а не просто смотреть на слова. Раньше поисковые системы строились на основе TF-IDF, которая также создает встраивание из текста. Этот вид семантического поиска работал путем нахождения вложения документа, наиболее близкого к встраиванию запроса с использованием ближайшего соседа.

Сегодня семантический поиск использует более сложные вложения, такие как BERT, и может использовать их в последующих моделях. Фактически, даже Google использует BERT в большом проценте своих запросов: https://searchengineland.com/google-bert-used-on-almost-every-english-query-342193/.

Компьютерное зрение

В компьютерном зрении вложения часто используются как способ перевода между разными контекстами. Например, при обучении беспилотного автомобиля мы можем преобразовать изображение автомобиля во вложение, а затем решить, что делать, на основе этого встроенного контекста. Поступая так, мы можем выполнять трансферное обучение. Мы можем взять сгенерированное изображение из такой игры, как Grand Theft Auto, превратить его в вложение в том же векторном пространстве и обучить модель вождения, не загружая в нее тонны дорогих реальных изображений. Сегодня Tesla делает это на практике.

Другой интересный пример - AI Art Machine: https://colab.research.google.com/drive/1n_xrgKDlGQcCF6O-eL3NOd_x4NSqAUjK#scrollTo=TnMw4FrN6JeB. Он будет генерировать изображение на основе текста, введенного пользователем. Например, если мы введем Ностальгия, мы получим следующее изображение.

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

Встраивание операций

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

Усреднение

Используя что-то вроде word2vec, мы можем получить вложение для каждого слова, но нам часто требуется вложение для полного предложения. Точно так же в рекомендательных системах мы можем знать элементы, на которые пользователь нажимал недавно, но их пользовательское встраивание могло не быть переобучено за несколько дней. В этих ситуациях мы можем усреднить вложения для создания вложений более высокого уровня. В примере предложения мы можем создать вложение предложения, усреднив каждое из вложений слов. В системе рекомендаций мы можем создать встраивание пользователя, усредняя последние N элементов, по которым они щелкнули.

Вычитание / сложение

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

Ближайший сосед

Ближайший сосед (NN) часто является наиболее полезной операцией встраивания. Он находит вещи, похожие на текущее встраивание. В рекомендательных системах мы можем создавать пользовательские вложения и находить элементы, которые им наиболее подходят. В поисковой системе мы можем найти документ, наиболее похожий на поисковый запрос. Однако ближайший сосед - это дорогостоящая операция. Наивно выполняется это O (N * K), где N - количество элементов, а K - размер каждого вложения. Однако в большинстве случаев, когда нам нужны ближайшие соседи, достаточно приближения. Если мы порекомендуем пользователю пять элементов, и один технически является шестым ближайшим элементом, пользователю, вероятно, будет все равно. Алгоритмы приблизительного ближайшего соседа (ANN) обычно снижают сложность поиска до O (log (n)).

Реализации ИНС

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

Spotify's Annoy

В реализации ИНС Spotify (Annoy) вложения превращаются в лес деревьев. Каждое дерево строится с использованием случайных проекций. В каждом промежуточном узле дерева выбирается случайная гиперплоскость, которая делит пространство на два подпространства. Эта гиперплоскость выбирается путем выборки двух точек из подмножества и взятия гиперплоскости, равноудаленной от них. Это выполняется k раз для создания леса. Поиск осуществляется путем обхода ближайшего дерева по порядку. Подход Annoy позволяет разделить индекс на несколько статических файлов, индекс может быть отображен в памяти, а количество деревьев может быть изменено для изменения скорости и точности.

Вот как Annoy разбивает вложения на индекс из нескольких деревьев с помощью случайных проекций.

Хеширование с учетом местоположения (LSH)

Хеширование с учетом местоположения (LSH) - еще один распространенный подход. LSH использует хеш-таблицу и хранит близлежащие точки в соответствующих сегментах. Для создания индекса LSH запускает множество хеш-функций, которые помещают аналогичные точки в одно и то же ведро. При этом LSH хранит точки с большими расстояниями в отдельных ведрах. Чтобы найти ближайшего соседа, рассматриваемая точка хешируется, выполняется поиск и возвращается ближайшая точка запроса. Некоторые преимущества включают сублинейное время выполнения, нулевую зависимость от распределения данных и возможность точной настройки точности с существующей структурой данных.

FAISS от Facebook и иерархические навигационные графы малого мира (HNSW)

Реализация Facebook, FAISS, использует иерархические навигационные графы малого мира (HNSW). HNSW обычно хорошо показывает точность и отзывчивость. Он использует иерархический граф для создания среднего пути к определенным областям. Этот граф имеет иерархическую транзитивную структуру с небольшим средним расстоянием между узлами. HNSW просматривает граф и находит ближайший соседний узел на каждой итерации и отслеживает «лучших» соседей, замеченных на данный момент. HNSW имеет полилогарифмическую временную сложность (O (logN)).

HNSW работает, создавая иерархический индекс для более быстрого поиска ближайшего соседа.

Как встраивание осуществляется сегодня

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

Осуществить встраивание в производство непросто. Наиболее распространенные способы, с помощью которых сегодня внедряются вложения, - это Redis, Postgres и S3 + Annoy / FAISS. Мы расскажем, как обычно выглядит каждая из этих реализаций, и какие проблемы возникают с каждой из них.

Redis

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

Postgres

Postgres гораздо более универсален, но намного медленнее, чем Redis. Через плагины можно заставить выполнять некоторые векторные операции вручную. Однако у него нет эффективного индекса ближайшего соседа. Кроме того, наличие поиска Postgres на критическом пути модели может увеличить задержку. Наконец, у Postgres нет отличного способа кэшировать вложения на клиенте во время обучения, что вызывает очень и очень медленное обучение.

Файлы S3 + раздражение / FAISS

Annoy или FAISS часто используются для реализации встраиваний, когда требуется поиск ближайшего соседа. Обе эти системы создают индексы вложений для приближенных операций ближайшего соседа, но они не обрабатывают долговременное хранение или другие векторные операции. В одиночку они решают только одну проблему. Обычно компании хранят свои вложения в S3 или аналогичной службе хранилища объектов, чтобы заполнить оставшиеся пробелы. Они загрузят вложения и при необходимости создадут индекс ИНС непосредственно в модели. Обновление вложений становится сложной задачей, и в конечном итоге система обычно использует множество специальных правил для управления версиями и откатами. FAISS и Annoy великолепны, но для них нужен полноценный магазин встраивания.

Центр встраивания

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

- Долговечно и с высокой доступностью хранит свои вложения.

- Разрешить приблизительные операции ближайшего соседа

- Включите другие операции, такие как разбиение на разделы, субиндексы и усреднение.

- Безболезненно управляйте версиями, контролем доступа и откатами

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

Для магазина встраивания с открытым исходным кодом существует явный пробел, и мы решили попытаться его заполнить. Мы сделали первый выпуск Embedding Hub на Github. Не стесняйтесь опробовать его, оставляйте свои комментарии и проблемы и дайте нам звезду!

Заключение

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

Первоначально опубликовано на https://www.featureform.com.