Перейти к основному содержимому

Позиционное кодирование

Все этапы в блоке кодировщика модели трансформера [1] (feed forward, суммирование, нормализация, самовнимание) работают независимо для каждого токена. Это ускоряет работу модели, позволяя производить вычисления параллельно, однако при этом полностью теряется информация о позиции каждого токена последовательности.

Но эта информация важна. Например фразы "the mother loves the daughter" и "the daughter loves the mother" состоят из одних и тех же слов, но имеют совершенно разный смысл!

Для интеграции информации о позиции каждого токена используется позиционное кодирование (positional encoding), состоящее в том, что каждой позиции pos (каждого токена последовательности) сопоставляется свой DD-мерный эмбеддинг, а затем эти эмбеддинги прибавляются к эмбеддингам самих токенов.

Момент прибавления

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

Точно так же устроено и в блоках декодировщика - позиционное кодирование используется только для входов самого первого блока.

Вектор позиционного кодирования epRD\mathbf{e}^p\in\mathbb{R}^D для токена на позиции p=1,2,...Tp=1,2,...T заполняется синусами от этой позиции на чётных элементах вектора и косинусами от позиции - на нечётных, причем для разных элементов используются синусы и косинусы разных периодов от 2π2\pi до 100002π10000\cdot 2\pi:

e2ip=sin(pos/100002i/D)e2i+1p=cos(pos/100002i/D)\begin{aligned} \mathbf{e}^p_{2i} & = \sin\left(pos/10000^{2i/D}\right)\\ \mathbf{e}^p_{2i+1} & = \cos\left(pos/10000^{2i/D}\right) \end{aligned}

Можно объединить эти вектора в матрицу ERT×DE\in \mathbb{R}^{T\times D}.

Пример визуализации этой матрицы при кодировании последовательности из 32 токенов в 16 мерном пространстве приведён ниже [2]:

jj-му токену будет соответствовать jj-й столбец. Как видим, существует взаимно однозначное соответствие между номером позиции и её эмбеддингом.

Позиционное кодирование идейно повторяет кодирование номеров позиций в виде двоичного представления:

0(0,0,0,)1(1,0,0,)2(0,1,0,)3(1,1,0,)4(0,0,1,)5(1,0,1,)6(0,1,1,)7(1,1,1,)0\to\left(0,0,0,\cdots\right)\\1\to\left(1,0,0,\cdots\right)\\2\to\left(0,1,0,\cdots\right)\\3\to\left(1,1,0,\cdots\right)\\4\to\left(0,0,1,\cdots\right)\\5\to\left(1,0,1,\cdots\right)\\6\to\left(0,1,1,\cdots\right)\\7\to\left(1,1,1,\cdots\right) \\ \cdots

Литература

  1. Vaswani A. Attention is all you need //Advances in Neural Information Processing Systems. – 2017.
  2. https://kikaben.com/transformers-positional-encoding/