ИНТУИТИВНЫЕ ТРАНСФОРМАТОРЫ СЕРИИ NLP

Визуальное объяснение трансформаторов (часть 2): как это работает, шаг за шагом

Нежное руководство по трансформатору под капотом и его непрерывной эксплуатации.

Это вторая статья из моей серии о трансформерах. В первой статье мы узнали о функциональности Transformers, о том, как они используются, об их высокоуровневой архитектуре и их преимуществах.

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

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

  1. Обзор функциональности (Как используются трансформаторы и почему они лучше, чем RNN. Компоненты архитектуры и поведение во время обучения и вывода)
  2. Как это работает - эта статья (Сквозная внутренняя операция. Как потоки данных и какие вычисления выполняются, включая матричные представления)
  3. Многоголовое внимание (внутренняя работа модуля Внимание во всем Трансформаторе)
  4. Почему внимание повышает производительность (Не только то, что делает внимание, но и почему оно так хорошо работает. Как внимание отражает взаимосвязь между словами в предложении)

А если вас интересуют приложения НЛП в целом, у меня есть несколько других статей, которые могут вам понравиться.

  1. Поиск луча (алгоритм, обычно используемый приложениями преобразования речи в текст и NLP для улучшения предсказаний)
  2. Bleu Score (Bleu Score и Word Error Rate - два важных показателя для моделей НЛП)

Обзор архитектуры

Как мы видели в Части 1, основными компонентами архитектуры являются:

Входные данные для кодировщика и декодера, которые содержат:

  • Встраиваемый слой
  • Уровень кодирования позиции

Стек энкодеров содержит несколько энкодеров. Каждый кодировщик содержит:

  • Слой Multi-Head Attention
  • Слой прямой связи

Стек декодера содержит несколько декодеров. Каждый декодер содержит:

  • Два уровня внимания с несколькими головами
  • Слой прямой связи

Вывод (вверху справа) - генерирует окончательный вывод и содержит:

  • Линейный слой
  • Слой Softmax.

Чтобы понять, что делает каждый компонент, давайте рассмотрим работу Transformer, пока мы обучаем его решению задачи перевода. Мы будем использовать один образец наших обучающих данных, который состоит из входной последовательности («Добро пожаловать!» На английском языке) и целевой последовательности («De nada» на испанском языке).

Встраивание и кодирование позиции

Как и любая модель НЛП, Трансформатору нужны две вещи в каждом слове - значение слова и его позиция в последовательности.

  • Слой встраивания кодирует значение слова.
  • Слой кодирования позиции представляет позицию слова.

Трансформер объединяет эти две кодировки, добавляя их.

Встраивание

Трансформатор имеет два слоя внедрения. Входная последовательность подается на первый уровень встраивания, известный как входной встраиваемый.

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

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

Кодирование позиции

Поскольку RNN реализует цикл, в котором каждое слово вводится последовательно, он неявно знает позицию каждого слова.

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

Как и в случае с двумя уровнями внедрения, существует два уровня кодирования позиции. Кодирование позиции вычисляется независимо от входной последовательности. Это фиксированные значения, которые зависят только от максимальной длины последовательности. Например,

  • первый элемент - это постоянный код, указывающий на первую позицию
  • второй элемент - это постоянный код, обозначающий вторую позицию,
  • и так далее.

Эти константы вычисляются по следующей формуле, где

  • pos - позиция слова в последовательности.
  • d_model - длина вектора кодирования (такая же, как вектор внедрения) и
  • i - значение индекса в этом векторе.

Другими словами, он чередует синусоидальную кривую и кривую cos со значениями синуса для всех четных индексов и значениями cos для всех нечетных индексов. В качестве примера, если мы кодируем последовательность из 40 слов, мы можем увидеть ниже значения кодирования для нескольких комбинаций (позиция слова, кодировка_индекса).

Синяя кривая показывает кодировку 0-го индекса для всех 40 позиций слова, а оранжевая кривая показывает кодировку 1-го индекса для всех 40 позиций слова. Аналогичные кривые будут и для остальных значений индекса.

Размеры матрицы

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

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

Это дает представление о размерах 3D-матрицы в Transformer. Однако, чтобы упростить визуализацию, отсюда мы отбросим первое измерение (для образцов) и будем использовать 2D-представление для одного образца.

Встраивание входных данных отправляет свои выходные данные в кодировщик. Точно так же встраивание вывода подается в декодер.

Кодировщик

Стеки кодировщика и декодера состоят из нескольких (обычно шести) кодеров и декодеров соответственно, соединенных последовательно.

Первый кодировщик в стеке получает входные данные от кодирования встраивания и позиционирования. Другие кодировщики в стеке получают входные данные от предыдущего кодировщика.

Кодировщик передает свои входные данные в слой самовнимания с несколькими головками. Выходные данные «Самовнимание» передаются на уровень прямой связи, который затем отправляет свои выходные данные вверх следующему кодировщику.

Подуровни «Самовнимание» и «Прямая связь» имеют остаточную пропускную связь вокруг себя, за которой следует нормализация уровня.

Выходные данные последнего кодировщика подаются в каждый декодер в стеке декодеров, как описано ниже.

Декодер

Структура декодера очень похожа на структуру кодировщика, но с некоторыми отличиями.

Как и кодировщик, первый декодер в стеке получает входные данные из выходного встраивания и позиционного кодирования. Другие декодеры в стеке получают входные данные от предыдущего декодера.

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

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

Выходные данные «Самовнимание» передаются на уровень прямой связи, который затем отправляет свои выходные данные вверх следующему декодеру.

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

Внимание

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

  • Собственное внимание в кодировщике - последовательность ввода обращает внимание на себя
  • Самовнимание в декодере - целевая последовательность обращает внимание на себя
  • Кодер-декодер-внимание в декодере - целевая последовательность обращает внимание на входную последовательность

Слой внимания принимает входные данные в виде трех параметров, известных как запрос, ключ и значение.

  • В режиме самовосприятия кодировщика входные данные кодировщика передаются всем трем параметрам: запросу, ключу и значению.

  • В режиме «Собственное внимание» декодера входные данные декодера передаются всем трем параметрам: «Запрос», «Ключ» и «Значение».
  • Вниманию декодера, кодировщика-декодера, выходные данные последнего кодировщика в стеке передаются параметрам Value и Key. Выходные данные модуля Self-внимания (и Layer Norm) ниже передаются в параметр Query.

Многоголовое внимание

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

Каждый запрос, ключ и значение проходят через отдельные линейные уровни, каждый со своими собственными весами, что дает три результата, называемые Q, K и V соответственно. Затем они объединяются вместе с использованием формулы внимания, как показано ниже, для получения оценки внимания.

Здесь важно понимать, что значения Q, K и V несут закодированное представление каждого слова в последовательности. Затем вычисления внимания объединяют каждое слово с каждым другим словом в последовательности, так что оценка внимания кодирует оценку для каждого слова в последовательности.

Обсуждая недавно декодер, мы кратко упомянули маскировку. Маска также показана на диаграммах выше. Посмотрим, как это работает.

Маски внимания

При вычислении показателя внимания модуль «Внимание» реализует этап маскирования. Маскировка служит двум целям:

В кодировщике «Собственное внимание» и «Кодировщик-декодер-внимание»: маскирование служит для вывода нулевого внимания, когда во входных предложениях есть отступы, чтобы гарантировать, что они не влияют на самовнимание. . (Примечание: поскольку входные последовательности могут иметь разную длину, они расширяются маркерами заполнения, как в большинстве приложений NLP, так что векторы фиксированной длины могут быть введены в преобразователь.)

Точно так же внимание Encoder-Decoder.

В самовнимании декодера: маскирование служит для предотвращения «заглядывания» декодером вперед остальной части целевого предложения при предсказании следующего слова.

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

Например, при прогнозировании «Word 3» декодер должен ссылаться только на первые 3 входных слова от цели, но не на четвертое слово «Ketan».

Поэтому декодер маскирует входные слова, которые появляются позже в последовательности.

При подсчете показателя внимания (см. Рисунок, на котором показаны расчеты ранее), маскирование применяется к числителю непосредственно перед Softmax. Скрытые элементы (белые квадраты) устанавливаются на отрицательную бесконечность, поэтому Softmax обнуляет эти значения.

Сгенерировать вывод

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

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

Затем слой Softmax превращает эти оценки в вероятности (которые в сумме составляют 1,0). В каждой позиции мы находим индекс для слова с наибольшей вероятностью, а затем сопоставляем этот индекс с соответствующим словом в словаре. Эти слова затем образуют выходную последовательность Трансформатора.

Функция тренировки и потери

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

Предположим, наш целевой словарь содержит всего четыре слова. Наша цель - получить распределение вероятностей, которое соответствует нашей ожидаемой целевой последовательности «De nada END».

Это означает, что распределение вероятностей для первой позиции слова должно иметь вероятность 1 для «De» с вероятностями для всех других слов в словаре равными 0. Точно так же «nada» и «END» должны иметь вероятность 1 для вторая и третья позиции слова соответственно.

Как обычно, потери используются для вычисления градиентов для обучения Трансформатора через обратное распространение.

Заключение

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

Модуль Multi-Head Attention - это то, что дает трансформатору мощность. В следующей статье мы продолжим наше путешествие и пойдем на один шаг глубже, чтобы действительно понять детали того, как вычисляется внимание.

И, наконец, если вам понравилась эта статья, возможно, вам понравится и другая моя серия об архитектурах Audio Deep Learning, Geolocation Machine Learning и Image Caption.







Продолжаем учиться!