Transformer位置编码(Position Embedding)理解

本文介绍了四种在NLP(如Transformer)和视觉任务(如ViT)中常见的位置编码策略,包括1D绝对位置编码的硬编码和可训练版本,以及SwinTransformer和MAE中的位置编码。通过实例展示了Transformer中的位置编码计算和维数扩展过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文主要介绍4种位置编码,分别是NLP发源的transformer、ViT、Sw-Transformer、MAE的Position Embedding


一、NLP transformer 

使用的是1d的绝对位置编码,使用sin+cos将每个token编码为一个向量【硬编码】

Attention Is All You Need

在语言中,单词的顺序及其在句子中的位置非常重要。 如果重新排列单词,整个句子的意思可能会发生变化。 因此,位置信息被明确地添加到模型中,以保留有关句子中单词顺序的信息。

 

1、why 位置编码?

位置编码描述了序列中每个单词(token)的位置或位置,以便为每个位置分配一个唯一的表示。 不使用单个数字(例如索引值)来表示位置的原因有很多。 对于长序列,索引的幅度可能会变大, 如果将索引值规范化为介于 0 和 1 之间,则可能会为可变长度序列带来问题,因为它们的规范化方式不同。

Transformers 将每个单词的位置都映射到一个向量。 因此,一个句子的位置编码是一个矩阵,其中矩阵的每一行代表序列中的一个token与其位置信息相加。 下图显示了仅对位置信息进行编码的矩阵示例:

2、位置编码计算公式:

1D absolute sincos constant position embedding 位置编码的计算公式:

  • k:token在输入序列中的位置,0<=k<=L-1
  • d: 位置编码嵌入空间的维度
  • P(k,j): 位置函数,用于映射输入序列中k处的元素到位置矩阵的(k,j)处
  • n:用户定义的标量,由 Attention Is All You Need 的作者设置为 10,000。
  • i: 用于映射到列索引,0<=i<d/2,单个值i映射到正弦和余弦函数【这是因为使用了sin+cos,所以一次可以给张量的两个维度计算position value,所以只需要d/2个i就可以了】

3、位置编码计算示例

让我们以 n=100 和 d=4 的短语“I am a robot”为例。

这样就将每个单词的position映射到一个4维度的张量中了,并且每个单词对应的张量是不同的

一个简单的实现:

import torch

# Section : 1. 1D absolute sincos constant position embedding
def create_1d_absolute_sincos_embedding(n_pos_vec, dim):
    # n_pos_vec: torch.arange(n_pos, dtype=torch.float)
    # dim: torch.arange(dim)
    assert dim % 2 == 0, "dim must be even"
    # 常数初始化一下position_embedding
    position_embedding = torch.zeros(n_pos_vec.numel(), dim, dtype=torch.float)
    # 完成指数部分的初始化
    omege = torch.arange(dim // 2, dtype=torch.float)
    omege /= dim / 2.
    omege = 1./(100 ** omege)
    # 扩充列向量和行向量:行数为pos, 列数为dim/2
    out = n_pos_vec[:, None] @ omege[None, :]
    emb_sin = torch.sin(out)
    emb_cos = torch.cos(out)
    # 交替填充:偶数列为sin, 奇数列为cos
    position_embedding[:, 0::2] = emb_sin
    position_embedding[:, 1::2] = emb_cos

    return position_embedding

if __name__ == "__main__":
    n_pos = 4
    dim = 4
    n_pos_vec = torch.arange(n_pos, dtype=torch.float)
    position_embedding = create_1d_absolute_sincos_embedding(n_pos_vec, dim)
    print(position_embedding.shape)
    print(position_embedding)

输出: 

二、Vision Transformer

使用的是1d的绝对位置编码,但是这个位置编码是可训练的(可学习的)。【软编码】

其实我感觉这种软编码,相对于硬编码来说不是很好,因为它并没有将位置的归纳偏置给模型,这种方式更像是增加了模型参数量的感觉。

【ICLR 2021】An Image is Worth 16x16 Words + Transformers for Image Recognition at Scale

代码实现:

import torch
import torch.nn as nn

# Section : 2. 1D absolute trainable position embedding
def create_1d_absolute_trainable_embedding(n_pos_vec, dim):
    # 创建一个n_pos_vec * dim维度的绝对位置编码的embedding,这个embedding是可以训练的。【与torch.nn.Parameter()用法有一些类似】
    position_embedding = nn.Embedding(n_pos_vec.numel(), dim)
    # 初始化嵌入层的权重为0
    nn.init.constant_(position_embedding.weight, 0)
    return position_embedding

if __name__ == "__main__":
    n_pos = 3
    dim = 4
    n_pos_vec = torch.arange(n_pos, dtype=torch.float)
    position_embedding = create_1d_absolute_trainable_embedding(n_pos_vec, dim)
    print(position_embedding)

三、Swin Transformer

四、Masked AutoEncoder(MAE)

# TODO:待更新...懒得写了,大概你知道PE的意思就行了

transformer计算位置编码的过程示例_哔哩哔哩_bilibili

Transformer位置编码图解 - BimAnt

46、四种Position Embedding的原理与PyTorch手写逐行实现(Transformer/ViT/Swin-T/MAE)_哔哩哔哩_bilibili

### 回答1: Transformer位置编码是一种用于在Transformer模型中对输入序列中每个位置进行编码的技术。它通过将每个位置映射到一个唯一的向量表示来实现。这些向量表示被添加到输入嵌入中,以便Transformer模型可以更好地理解输入序列中不同位置之间的关系。Transformer位置编码通常使用正弦和余弦函数来生成向量表示,这些函数具有周期性和可重复性,可以帮助模型更好地处理输入序列中的周期性模式。 ### 回答2: Transformer是一种用于处理序列数据的神经网络模型,它在自然语言处理领域的应用非常广泛。Transformers中的位置编码position encoding)是一个非常重要的概念,它是该模型在处理文本序列时能够保留位置信息的关键。 位置编码是通过一种特殊的方式将每个输入序列中的单词位置信息嵌入到向量空间中。在Transformer中,位置编码是通过一个矩阵生成的,这个矩阵的维度大小为(序列长度 × 向量维度),其中序列长度是输入序列中单词的数量,而向量维度则是每个位置编码向量的维度。这个矩阵中的每一行都代表着一个位置编码向量,在输入序列中,每个单词都对应一个位置编码向量,通过将这个位置编码向量加入到单词向量中,模型可以在处理文本序列时保留单词的位置信息。 通常,位置编码向量是通过计算一个一组三角函数的结果来获得的。这个函数的参数是位置和索引,位置指的是在序列中的位置,而索引则是维度,它可以用来控制位置编码向量的不同特征,例如奇偶性和周期性等等。在计算这个函数的结果时,位置的信息被嵌入到向量中,并且这个位置编码向量会通过加权和的形式被嵌入到输入向量中,从而影响模型的输出。 总之,Transformer中的位置编码是非常重要的一步,它可以帮助模型保存输入序列中的位置信息,从而更好地处理序列数据。位置编码向量是通过一个特殊的函数计算得出的,它是由位置信息和索引信息组成的,通过加入到输入向量中,使得输入的向量不仅包含单词本身的信息,同时也包含了位置信息。 ### 回答3: Transformer 的编码器和解码器在进行自注意力机制计算时,需要为每一个输入或输出单词分配一个位置编码,以便模型在计算注意力时能够准确反映文本中的语序信息。这个位置编码的目的是为了能够让模型能够明确区分不同位置的单词,从而保留这些单词在文本中的相对位置关系。 位置编码是作为输入到模型中的一个向量,其维度和单词的嵌入向量的维度一致。在Transformer中,提出了两种位置编码的方式: 基于正弦函数和基于学习的方式。 基于正弦函数的位置编码,其计算公式如下: $PE_{pos,2i}=sin(\frac{pos}{10000^{2i/d_{model}}})$ $PE_{pos,2i+1}=cos(\frac{pos}{10000^{2i/d_{model}}})$ 其中,$pos$表示单词的位置,$i$和$d_{model}$表示位置向量的对应维度。 基于学习的方式,就是通过训练来学得位置编码,这种方式可以在避免手工编码时引入的误差的同时,也可以更好地适应特定任务的要求。 无论使用哪种方式,位置编码的作用都是为了让模型能够区分不同位置的单词以及它们在文本中的相对位置关系,从而更好地捕捉到文本中的序列信息,提高模型的性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Pengsen Ma

太谢谢了

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值