Изменения

Перейти к: навигация, поиск

Трансформер

926 байт добавлено, 22:26, 14 июня 2022
м
добавлены уточнения
==Архитектура трансформера==
[[Файл:TransformerSimpleArchitecture.png|350px|thumb|right|Архитектура трансформера<ref>https://jalammar.github.io/illustrated-transformer/</ref>]]
Устройство трансформера состоит из кодирующего и декодирующего компонентов. На вход принимается некая последовательность, создается ее [[:Векторное_представление_слов|векторное представление]] (англ. ''embedding''), векторизованная последовательность прибаляется вектор позиционного кодирования, после чего набор слов без учета порядка в последовательности поступает в кодирующий компонент, а затем декодирующий компонент получает на вход часть этой последовательности и выход кодирующего. В результате получается новая выходная последовательность.
Кодирующий В основе лежит архитектура похожая на базовую архитектуру Seq2seq<ref>http://neerc.ifmo.ru/wiki/index.php?title=%D0%9C%D0%B5%D1%85%D0%B0%D0%BD%D0%B8%D0%B7%D0%BC_%D0%B2%D0%BD%D0%B8%D0%BC%D0%B0%D0%BD%D0%B8%D1%8F&mobileaction=toggle_view_desktop#.D0.91.D0.B0.D0.B7.D0.BE.D0.B2.D0.B0.D1.8F_.D0.B0.D1.80.D1.85.D0.B8.D1.82.D0.B5.D0.BA.D1.82.D1.83.D1.80.D0.B0_Seq2seq</ref>: кодирующий компонент {{---}} это стек кодировщиков (англ. ''encoders''), а декодирующий компонент {{---}} это стек декодировщиков (англ. ''decoders''). Каждый кодировщики последовательно передает результат своей работы следующему кодировщику на вход. Декодировщики последовательно передают друг другу на вход результат работы вместе с результатом кодирующего компонента.
Ниже рассмотрим архитектуру кодировщика и декодировщика подробнее.
==Архитектура трансформера-кодировщика==
[[Файл:TransformerEncoderArchitecture.png|150px|thumb|left|Архитектура трансформера-кодировщика<ref>https://arxiv.org/abs/1706.03762</ref>]]
Рассмотрим последовательно шаг за шагом этапы работы кодировщика:
1. На вход поступает последовательность элементов <math>w_i</math>, по ней создается последовательность эмбедингов, где каждый <math>x_i</math> это векторное представление элемента <math>w_i</math>.
4. Затем необходима конкатенация, чтобы вернуться в исходную размерность: <math> h'_i = M H_j (h^j_i) = [h^1_i...h^J_i] </math>
5. Добавим сквозные связи (англ. ''skip connection'') {{---}} по факту просто добавление из входного вектора к выходному (<math>h'_i + h_i</math>). После делаем нормировку уровня нормализацию слоя (англ. ''layer normalization''): <math>h''_i = \mathrm{LN}(h'_i + h_i; \mu_1, \sigma_1)</math>. У нее два обучаемых параметра, для каждой размерности вектора вычисляется среднее и дисперсия.
6. Теперь добавим преобразование, которое будет обучаемым {{---}} полносвязную двухслойную нейронную сеть:
<math> h'''_i = W_2 \mathrm{ReLU} (W_1 h''_i + b_1) + b_2 </math>
7. Повторим пункт 5 еще раз: добавим сквозную связь и нормировку уровнянормализацию слоя: <math>z_i = \mathrm{LN}(h'''_i + h''_i; \mu_2, \sigma_2)</math>
После, в кодирующем компоненте пункты кодировщика 3-7 повторяются еще несколько раз, преобразовывая друг за другом из контекста контекст. Тем самым мы обогащаем модель и увеличиваем в ней количество параметров.
===Позиционное кодирование===
[[Файл:PositionalEncoding.png|400px|thumb|right|Визуализация работы позиционного кодирования<ref>http://www.machinelearning.ru/wiki/indeximages/e/e6/Voron-ML-TopicModeling-slides.phppdf</ref>]]Так как в архитектуре трансформер обработка последовательности заменяется на обработку множества мы теряем порядок элементов последовательности. Чтобы отобразить информацию о позиции элемента в исходной последовательности мы используем позиционное кодирование.
Позиционное кодирование (англ. ''positional encoding'') {{---}} позволяет модели получить информацию о порядке элементов в последовательности путем прибавления специальных меток к вектору входных элементов. Позиции элементов <math>i</math> кодируются векторами <math>p_i</math>, <math>i = 1, 2, ..., n</math>, так, что чем больше <math>|i - j|</math>, тем больше <math>||p_i - p_j||</math>, и <math>n</math> не ограничено:
<math>p_{(i, s)} = \sin \left(i \cdot 10000^{\frac{-2s}{d_{model}}}\right)</math>,
<math>p_{(i, s + \frac{d}{2})} = \cos \left(i \cdot 10000^{\frac{-2s}{d_{model}}}\right)</math>
 
По сути мы свели задачу обработки последовательности (''seq'') к множеству (''set'').
===Self-attention===
* Значение (''value'') <math>v_i = V x_i</math>
Векторы <math>q_i</math> и <math>k_i</math> будем использовать, что чтобы посчитать важность элемента <math>x_j</math> для элемента <math>x_i</math>. Чтобы понять, насколько для пересчета вектора элемента <math>x_i</math> важен элемент <math>x_j</math> мы берем <math>k_j</math> (вектор ключа элемента <math>x_j</math>) и умножаем на <math>q_i</math> (вектор запроса элемента <math>x_i</math>). Так мы скалярно перемножаем вектор запроса на все векторы ключей, тем самым понимаем, насколько каждый входной элемент нам нужен, чтобы пересчитать вектор элемента <math>x_i</math>.
Далее считаем важность влияния элемента <math>x_j</math> для кодирования элемента <math>x_i</math>:
<math>w_{ji}=\frac{
\exp \left(\frac{\langle q_i, k_j \rangle}{\sqrt{d}} \right)
<math> h''_t = \mathrm{LN} \circ M H_j \circ \mathrm{Attn}(Q^j h_t, K^j Z, V^j Z) </math>
4. Линейная полносвязная сеть (по аналогии, как и в кодировщикес кодировщиком):
<math> y_t = \mathrm{LN} \circ FNN(h''_t) </math>
5. В самом конце мы хотим получить вероятностную порождающую модель для элементов. Результат (индекс слова с наибольшей вероятностью): <math>\mathrm{SoftArgMax}(W_y y_t + b_y) </math>, где <math> W_y </math>, <math> b_y </math> {{---}} обучаемые параметры линейного преобразования. Для каждой позиции <math>t</math> выходной последовательности мы строим вероятностную модель языка, то есть все элементы из выходного словаря получают значение вероятности. Эти значения как раз получаются из векторов <math>y_t</math> из предыдущего пункта, которые мы берем с последнего блока трансформера-декодировщика.
Последний этап выполняется только после того, когда повторились пункты 1-4 для всех декодировщиков. На выходе получаем вероятности классов, по факту для каждой позиции решаем для каждого класса задачу многоклассовой классификации, для того, чтобы понять какие элементы лучше поставить на каждые позиции.
==Источники информации==
23
правки

Навигация