Я уверен, вы видели модели машинного обучения, которые принимают текст и предсказывают, является ли он спамом. Аналогично модель может проанализировать отзыв о фильме и определить его тональность — положительную или отрицательную, понимать что «груша» связана с «яблоком» куда больше, чем с «теплоходом».
Первое правило обучения любой модели машинного обучения — это преобразование входных данных в числа. Любой цифровой объект можно представить как некое число: картинку, текст, аудио или видеофайл — практически всё что угодно.
Для того чтобы ввести этот объект в нашу ML модель как некое понятие, мы должны преобразовать его в определённый набор чисел. По этому набор чисел мы сможем определить, что, например, этот объект «яблоко», а не «груша».
С картинками всё просто. В чёрно-белом изображении (в градациях серого) самый яркий пиксель имеет значение 1, самый тёмный — 0, а оттенки серого имеют значения от 0 до 1. Такое числовое представление упрощает обработку изображений. Преобразовав изображение в цифровую форму на основе значений пикселей, мы можем использовать его в качестве входных данных для обучения нашей модели, позволяя нейронной сети обучаться на значениях пикселей.
Однако что делать с текстом? Как спроецировать буквы в числа?
У нас есть текст, и один из простых способов превратить его в числа — присвоить каждому уникальному слову уникальное число. Если вы знакомы с токенизацией, то знаете, что текст разбивается на токены, и каждому даётся уникальный номер (индекс).
Казалось бы, проблема решена: у нас есть числа, модель их принимает. Мы можем обучить модель, используя номера токенов в качестве входных данных. Однако этот метод подходит только для порядковых признаков (ordinal features) — случаев, когда числа подразумевают ранжирование.
Низкий, средний и высокий: где порядок токена имеет значение.
Взглянем на эти предложения.
The movie was good.
The movie was bad.
The movie was awesome.
Первое предложение имеет положительную окраску, второе — отрицательную, а третье — снова положительную. Ключевое различие между этими предложениями кроется в словах «good» (хороший), «bad» (плохой) и «awesome» (потрясающий).
Допустим, мы присвоили им случайные токены:
«good» = 6
«bad» = 26
«awesome» = 27
Числа 26 и 27 близкие по значению. Это может заставить модель предположить, что слова «bad» и «awesome» похожи, в то время как слово «good» кажется совершенно другим. В реальности же «good» и «awesome» семантически близки, но из-за того, как присвоены числа, модель может неверно интерпретировать их взаимосвязь. Такое искажение может привести к неверным прогнозам, что делает простые номера токенов неподходящими в качестве входных признаков для моделей машинного обучения.
Проблема ложной близости чисел решается техникой One Hot Encoding. Идея проста: каждое слово представляется уникальным вектором, размер которого равен полному размеру нашего словаря.
cловарь = [The, movie, was, good, bad, awesome] — всего 6 слов
Кодируем слова:
Каждому слову присваивается уникальный вектор, где только одна позиция содержит «1» (указывая на наличие слова), а все остальные позиции равны «0». Этот метод устраняет проблему ранжирования, присущую методу токенизации, и гарантирует, что все слова рассматриваются как равные, без каких-либо скрытых числовых взаимосвязей.
Теперь, используя векторы One Hot Encoding, мы можем преобразовать наши обучающие данные в числовой формат, подходящий для модели.
One Hot Encoding помогает устранить непреднамеренные числовые связи, и он прост в реализации. Однако у него есть серьёзные недостатки. Он создаёт разреженные векторы (где большая часть элементов равно «0»). Это означает, что если у нас есть словарь из 20 000 слов, каждое слово будет представлено 20 000-мерным разреженным вектором. Можете сами представить, сколько необходимо памяти и вычислительных ресурсов, чтобы обрабатывать такие данные.
Кроме того, этому методу не хватает семантического и контекстуального смысла, так как One Hot Encoding рассматривает слова как полностью независимые сущности. Он не улавливает связи между словами, например, то, что «good» и «awesome» близки по значению. Эти ограничения делают использование исключительно One Hot Encoding неэффективным для масштабных задач обработки естественного языка (NLP).
Можно пойти другим путём и использовать Bag of Words (Мешок слов). Мы просто считаем, сколько раз слово встречается в предложении.
Поскольку мы рассматриваем только подсчёт отдельных слов, эта техника также называется униграммой (unigram), так как каждое слово обрабатывается независимо. Вместо использования только униграмм, мы можем рассматривать контекст из двух слов — биграммы, и подсчитывать вхождения всех возможных комбинаций из двух слов для создания вектора признаков. Это добавляет больше контекста по сравнению с One Hot Encoding или подходом «Мешка слов».
Аналогично мы можем расширить это до контекста из N-слов, называемого N-граммами (N-gram) признаками, где модель захватывает контекстную информацию длиной до «N» слов.
При использовании N-грамм в качестве признаков всё равно возникают сложности. Если набор данных велик, опять же будет существовать множество возможных комбинаций N-грамм, что приведёт к очень большому и разреженному вектору признаков, что привёдет к использованию большого кол-ва памяти и бла-бла-бла...
Из-за того, что модель может учитывать только ограниченное количество слов одновременно и эти слова обязаны идти по порядку, то N-граммы не улавливают более глубокие смыслы или связи между словами. Например, в предложении:
Из‑за того, что слова «librarian» и «book» не являются соседними, N‑граммы не понимают, что они на самом деле связаны по смыслу.
Подходим к главному. Чтобы модель работала хорошо, она должна понимать семантику (смысл слова) и контекст (окружение).
Теперь давайте возьмём простой пример текста:
Допустим, мы хотим, чтобы наша модель предсказала следующее слово (токен) на основе этого текста. Чтобы сгенерировать следующий токен, модель должна понимать значение каждого слова (то есть иметь семантическое понимание), а также контекст предложения.
Например, как люди, мы можем спросить себя: где находится механик? Мы легко свяжем ответ со словом «гараж» или «мастерская». Аналогично рассмотрим слово «тяжёлый» в предложении. Относится ли оно к механику или маслу? Из структуры предложения мы понимаем, что «большой» и «тяжёлый» описывает предмет, который он взял в руки, а не самого человека.
Также контекст упоминает «верстак» и действие «взял». Мы можем сделать вывод, что объект — это его рабочий инструмент (¬‿¬ ).
Когда я говорю, что модель должна понимать семантическое значение, я имею в виду, что если мы заменим «механик» на «мастер» или «гараж» на «автосервис», смысл предложения должен остаться прежним, и это не должно кардинально изменить предсказываемое слово. Исходя из этого, мы можем предположить, как ни преобразуй, следующим словом будет... конечно, «молоток», «ключ» или «инструмент», так как эти объекты обычно тяжёлые, находятся на верстаке в гараже и используются механиками.
Чтобы обучить модель, которая может понимать такой семантический и контекстуальный смысл, нам нужен способ кодирования наших обучающих данных в векторы признаков, которые захватывают оба аспекта. Именно здесь Эмбеддинги слов (Word Embeddings) и механизм внимания играют решающую роль.
Word Embedding (векторное представление слов) — это техника в обработке естественного языка, при которой слова представляются как плотные (почти без нулей) числовые векторы в непрерывном n-мерном векторном пространстве. Каждое слово представляется вектором фиксированной размерности, который является плотным — в отличие от One Hot Encoding, где большинство значений равны нулю.
Идея эмбеддинга заключается в том, что два похожих вектора соответствуют двум похожим словам, а направление в векторном пространстве несёт определённый смысл. Например, в двумерном представлении похожие слова, такие как «кофе» и «чай», имеют векторы, которые находятся ближе друг к другу, чем к не связанному с ними слову, например, «кирпич».
Давайте разберём это на простом примере, начиная с одного измерения. Представьте числовую прямую, представляющую размер животного, и мы кодируем 10 животных, используя вектор признаков, где размер является единственным признаком. Отсюда мы видим, что животные с похожими габаритами находятся ближе друг к другу. Если мы расширим это до двух измерений — скажем, ось X представляет размер, а ось Y представляет хищность (опасность) — слова «тигр» и «лев» будут похожи и расположены ближе друг к другу (крупные и опасные), в то время как они будут дальше от слов «корова» (крупная, но безопасная) и «хомяк» (мелкий и безопасный).
Теперь, когда векторы признаков закодированы семантически, мы можем выполнять с ними математические векторные операции. Например:
вычитание вектора (V — сокр. от Vector) «мужчина» из «сына» и последующее добавление вектора «женщина» даёт вектор, близкий к «дочери». Это показывает, что разница между «сыном» и «дочерью» аналогична разнице между «мужчиной» и «женщиной».
Возьмём другой пример:
если мы возьмём слово «Мадрид», добавим «Германия» и вычтем «Испания», ближайшим полученным словом будет «Берлин». Это работает, потому что Мадрид — столица Испании. Когда мы убираем атрибуты, связанные с Испанией, и добавляем атрибуты, связанные с Германией, результирующий вектор тесно совпадает с Берлином, столицей Германии.
Мы не можем явно определить, какие признаки содержатся в пространстве эмбеддингов и не задаём их вручную, так как это полностью зависит от обучающих данных. Однако модель улавливает определённое семантическое понимание текста и представляет его в векторном пространстве меньшей размерности (несколько сотен или тысяч измерений, в отличие от сотен тысяч, требуемых для One Hot Encoding в больших словарях). Цель состоит в том, чтобы использовать плотный вектор, который может хранить значение слов в n-мерном пространстве, называемом пространством эмбеддингов.
Мы не можем напрямую визуализировать эмбеддинги с сотнями измерений, но с помощью математических инструментов, таких как метод главных компонент (PCA), мы можем спроецировать их в меньшее количество измерений.
Например, в обученной модели по Word2Vec мы можем увидеть, векторы, связанные с «кофе» (чай, сахар, сыр и др.).
Одной из техник обучения эмбеддингов слов является Word 2 Vec, представленная Google. В статье о Word 2 Vec демонстрируются две ключевые техники: Continuous Bag of Words (CBOW)(непрерывный мешок слов) и Skip-Gram.
Короче, в CBOW мы берём окно контекстных слов и пытаемся предсказать центральное целевое слово по его соседям.
Например, если входные слова — «Fox» и «over», целевым словом может быть «jumps». Модель представляет собой простую нейронную сеть.
Перед тем, как загружать это предложение в модель, применим к нему One Hot Encoding.
Входной слой принимает векторы One Hot Encoding контекстных слов. Скрытый слой содержит нейроны в количестве, равном размерности эмбеддинга, которую мы хотим изучить.
Выходной слой содержит нейроны, равные размеру словаря. Матрица весов между выходным и скрытым слоями становится матрицей эмбеддингов.
Матрица эмбеддингов размером 8 на 3 становится таблицей поиска для каждого слова. Это означает, что после обучения мы можем использовать матрицу эмбеддингов для получения трёхмерного вектора для каждого слова, где каждое слово имеет своё собственное фиксированное представление. Поскольку мы обучались только на восьми словах, размер матрицы эмбеддингов составляет 8 на 3. Количество строк в матрице эмбеддингов равно количеству уникальных слов (или размеру словаря), а количество столбцов соответствует размерности эмбеддинга, которую мы выбираем для представления слов в n-мерном пространстве.
Чтобы получить значение эмбеддинга для каждого слова, мы сначала преобразуем слово в его one-hot вектор, а затем берём скалярное произведение one-hot вектора с матрицей эмбеддингов, чтобы получить вектор эмбеддинга слова.
Теперь, когда мы понимаем модель Continuous Bag of Words, понять модель Skip-gram просто. В модели Skip-Gram процесс обратный. Вместо того чтобы предсказывать центральное слово, используя контекст, мы берём центральное слово в качестве входных данных и пытаемся предсказать окружающие контекстные слова.
Оба метода хорошо работают при обучении словесных эмбеддингов.
В современных архитектурах (GPT или BERT) подход немного изменился. Там слой эмбеддингов не обязательно брать готовым из Word 2 Vec. Этот слой является частью самой модели и обучается с нуля или дообучается вместе с ней под конкретную задачу. В основном это предсказание следующего токена.
Давайте посмотрим на эмбеддинг, используемый в части декодера архитектуры Трансформер.
Скрытый текст
Сначала мы преобразуем текст в токены.
Для шести токенов мы получаем матрицу эмбеддингов размером 6 на размерность эмбеддинга. Слой декодера не использует модель типа Word 2 Vec.
Вместо этого он использует простую неглубокую нейронную сеть для создания эмбеддингов.
Входной слой принимает one-hot закодированный вектор каждого слова. Количество нейронов равно размеру словаря, а скрытый слой имеет количество нейронов, равное размерности эмбеддинга, которую мы хотим, чтобы наша модель выучила.
Веса в этом слое эмбеддинга являются обучаемыми параметрами, которые учатся представлять слова в n-мерном пространстве. Так же, как и в Word 2 Vec, веса действуют как таблица поиска для токенов, где каждый токен получает обученное значение веса. После преобразования текста в токены слой эмбеддинга предоставляет векторное представление для каждого токена. При правильном обучении эти эмбеддинги могут улавливать семантическое значение слов.
В отличие от Word 2 Vec, где мы обучаем эмбеддинги отдельно, в слое декодера слой эмбеддинга обучается вместе со всей моделью. Поскольку мы хотим, чтобы наш декодер предсказывал следующий токен, мы используем специальный слой эмбеддинга, который выдаёт векторное представление нашего входного текста. Затем этот эмбеддинг проходит через повторяющиеся блоки декодера и, наконец, попадает в выходной слой, который предсказывает следующий токен. Затем модель вычисляет ошибку и выполняет обратное распространение ошибки через все слои, используя обучающий набор данных.
Выходной слой — это ещё один линейный слой, похожий на слой эмбеддинга в начале, но вместо того, чтобы иметь выходной размер, равный размерности эмбеддинга, здесь всё наоборот: он имеет количество нейронов, равное общему размеру словаря. Это позволяет модели присваивать вероятности возможным следующим токенам.
Глядя на этот процесс, мы видим, что модель сначала представляет токены в n-мерном пространстве эмбеддингов, а затем использует это представление для предсказания следующего токена. Это отличается от Word 2 Vec, где задача состояла в предсказании центрального слова с использованием контекстных слов. Однако в больших языковых моделях цель состоит в том, чтобы предсказать следующее слово с учётом всех предыдущих слов, при этом несколько слоёв декодера дополнительно обрабатывают эмбеддинги перед генерацией следующего токена. Мы рассмотрели почти всё, что касается эмбеддингов, но осталась одна небольшая деталь для обсуждения.
В отличие от RNN, которые обрабатывают каждый токен отдельно, архитектура Трансформер обрабатывает все слова параллельно. Из-за этого нам нужно сообщить модели о позиции каждого токена — по сути, какой токен идёт первым, а какой следует за ним. Чтобы достичь этого, после создания эмбеддинга мы добавляем позиционный вектор к вектору эмбеддинга, кодируя информацию о позиции каждого токена.
Эта позиционная информация может быть либо ещё одним обучаемым слоем, либо статическим числовым представлением, уникальным для каждого токена. Мы просто прибавляем этот позиционный вектор к вектору эмбеддинга, получая в результате новое представление, которое содержит как значение слова, так и информацию о его позиции. Важно отметить, что форма матрицы эмбеддингов не меняется; только её значения слегка корректируются в соответствии с позицией каждого токена.
Теперь эта матрица готова к подаче в механизм внимания (attention), который является первым слоем блока декодера. Как упоминалось ранее, слой эмбеддинга помогает уловить семантическое значение слов, но он не обеспечивает контекстуального понимания текста. Именно здесь механизм внимания играет решающую роль.
Механизм внимания — это сердце больших языковых моделей, позволяющее им улавливать взаимосвязи между словами, выходящие за рамки их самостоятельных значений. После прохождения через механизм внимания мы получаем контекстуальное представление каждого токена, которое отличается от его начального семантического представления. Потому что, например, «гаечный ключ» и «ключ от двери» это хоть и одинаковые, но разные по смыслу слова.
Детально про механизм внимания поговорим в другой раз :)
Вот так. Комбинируя простые решения вроде токенизации и подсчёта слов, можно постепенно прийти к трансформеру и механизму внимания.
Сегодня эмбеддинги используются везде. В рекомендательных системах, в поиске похожих картинок и, разумеется, в основе ChatGPT и других моделей.
Понимание того, как работают CBOW, Skip-Gram и Transformer — это база, с которой начинается глубокое погружение в NLP.
Спасибо за прочтение!
© 2026 ООО «МТ ФИНАНС»
Источник


