Позиционное кодирование
Все этапы в блоке кодировщика модели трансформера [1] (feed forward, суммирование, нормализация, самовнимание) работают независимо для каждого токена. Это ускоряет работу модели, позволяя производить вычисления параллельно, однако при этом полностью теряется информация о позиции каждого токена последовательности.
Но эта информация важна. Например фразы "the mother loves the daughter" и "the daughter loves the mother" состоят из одних и тех же слов, но имеют совершенно разный смысл!
Для интеграции информации о позиции каждого токена используется позиционное кодирование (positional encoding), состоящее в том, что каждой позиции pos (каждого токена последовательности) сопоставляется свой -мерный эмбеддинг, а затем эти эмбеддинги прибавляются к эмбеддингам самих токенов.
Напомним, что позиционные эмбеддинги прибавляются только ко входам первого блока кодировщика. Последующие блоки кодировщика работают с выходными эмбеддингами предыдущего блока в неизменном виде.
Точно так же устроено и в блоках декодировщика - позиционное кодирование используется только для входов самого первого блока.
Вектор позиционного кодирования для токена на позиции заполняется синусами от этой позиции на чётных элементах вектора и косинусами от позиции - на нечётных, причем для разных элементов используются синусы и косинусы разных периодов от до :
Можно объединить эти вектора в матрицу .
Пример визуализации этой матрицы при кодировании последовательности из 32 токенов в 16 мерном пространстве приведён ниже [2]:
-му токену будет соответствовать -й столбец. Как видим, существует взаимно однозначное соответствие между номером позиции и её эмбеддингом.
Позиционное кодирование идейно повторяет кодирование номеров позиций в виде двоичного представления: