常用5种位置编码方式总结(附论文出处与原理解析)
在使用 Transformer 或其他序列模型时,引入位置编码(Positional Encoding)是为了让模型捕捉 元素之间的位置关系或顺序信息。尤其在视觉、语言、推荐、视频等任务中,不同的位置编码方式适用于不同的场景。本文总结了几种常用的位置编码方式,附带其提出的论文出处、设计动机、核心原理与应用对象与物理意义,供大家参考。
1. Sinusoidal Positional Encoding
📄 论文出处
Attention is All You Need (Vaswani et al., 2017)
https://arxiv.org/abs/1706.03762
🎯 动机
Transformer 架构是无序的,为了提供 token 的位置信息,需要引入一个固定的位置编码。
⚙️ 原理
使用正弦/余弦函数编码位置信息:
P
E
(
p
o
s
,
2
i
)
=
sin
(
p
o
s
/
10000
2
i
/
d
m
o
d
e
l
)
PE_{(pos, 2i)} = \sin(pos / 10000^{2i / d_{model}})
PE(pos,2i)=sin(pos/100002i/dmodel)
P
E
(
p
o
s
,
2
i
+
1
)
=
cos
(
p
o
s
/
10000
2
i
/
d
m
o
d
e
l
)
PE_{(pos, 2i+1)} = \cos(pos / 10000^{2i / d_{model}})
PE(pos,2i+1)=cos(pos/100002i/dmodel)
- 不依赖训练
- 可推广到任意长度的序列
🧠 应用对象
- 自然语言处理(NLP)任务
- 小规模视觉任务(如ViT)
🧲 物理意义
这种正弦函数的形式使得不同位置之间的编码具有周期性和可微性,便于模型通过内积或注意力机制感知位置差异。类似于“波”的传播,每个位置都映射为一个独特的角度,使得相对位置具有可比较性。
2. Learnable Positional Encoding
📄 论文出处
- BERT4Rec (Sun et al., CIKM 2019) https://arxiv.org/abs/1904.06690
- ViT: An Image is Worth 16x16 Words https://arxiv.org/abs/2010.11929
- TimeSformer (NeurIPS 2021) https://arxiv.org/abs/2102.05095
🎯 动机
固定编码方式(如 Sinusoidal)缺乏表达灵活性,不适应任务特异性的时间或空间关系。
⚙️ 原理
直接为每一个位置分配一个可学习的向量参数:
self.position_embedding = nn.Parameter(torch.zeros(1, max_len, embed_dim))
- 与 token embedding 同维度
- 可自动学习任务相关的位置关系
🧠 应用对象
- 用户行为序列建模
- 图像 patch 或视频帧序列建模(如 TimeSformer)
- 推荐系统、行为预测等非周期任务
🧲 物理意义
每个位置作为一个“锚点”,用独立的向量来表示其时空含义,类似在空间中打上标签。这种方法允许模型自动学习“某个时间步”或“某块区域”的独特意义,适应非周期或局部性强的任务。
3. 随机位置编码(注册为 buffer)
📄 论文出处
Segment Anything Model (SAM), Meta AI, 2023
https://arxiv.org/abs/2304.02643
🎯 动机
引入非结构化的、固定的空间位置信息,避免模型过拟合过度结构化的位置特征。
⚙️ 原理
初始化一个随机高斯矩阵(不参与训练),通过 register_buffer
固定:
pos = torch.randn(1, H, W, D) # D 是嵌入维度
self.register_buffer("positional_encoding", pos)
- 保证每次调用一致
- 不更新,不依赖具体顺序结构
🧠 应用对象
- 图像语义分割(如 SAM)
- 空间感知任务
🧲 物理意义
这类位置编码可看作是对空间中每个位置赋予一个“纹理印记”,帮助模型区分像素块或区域的位置,而不引入任何偏见(如线性顺序)。其物理意义更偏向“空间随机初始化标签”。
4. Rotary Positional Encoding(RoPE)
📄 论文出处
RoFormer: Enhanced Transformer with Rotary Position Embedding (Su et al., 2021)
https://arxiv.org/abs/2104.09864
🎯 动机
实现 相对位置信息建模,提升对 token 顺序的微小变动的鲁棒性。
⚙️ 原理
将位置信息嵌入到 Q/K 中,并进行二维旋转变换:
RoPE ( x t ) = x t cos + x t sin \text{RoPE}(x_t) = x_t^{\cos} + x_t^{\sin} RoPE(xt)=xtcos+xtsin
- 保持嵌入空间结构
- 支持推理时 token 动态插入
🧠 应用对象
- 语言模型(如 LLaMA, GPT-NeoX)
- 任意需要相对顺序建模的 Transformer
🧲 物理意义
RoPE 相当于给特征向量应用一个“角度旋转”,将位置编码转化为空间旋转操作。其几何含义是:不同位置的特征处于不同角度,使得点积自带位置差异,适合捕捉相对距离和顺序。
5. 2D/Spatial Positional Encoding
📄 论文出处
- DETR: End-to-End Object Detection (Carion et al., ECCV 2020)
https://arxiv.org/abs/2005.12872
🎯 动机
Transformer 应用于图像任务时,需要显式编码二维空间信息(x,y)。
⚙️ 原理
分别对 x 轴、y 轴进行 Sinusoidal 编码后拼接或加和:
P E ( x , y ) = P E x ( x ) + P E y ( y ) PE(x, y) = PE_x(x) + PE_y(y) PE(x,y)=PEx(x)+PEy(y)
也可学习二维编码矩阵:
self.spatial_pos_embedding = nn.Parameter(torch.zeros(1, H, W, embed_dim))
🧠 应用对象
- 目标检测(如 DETR)
- 图像生成/理解任务
🧲 物理意义
空间位置编码相当于为图像的每个像素块(或 patch)注入其二维坐标的“空间指纹”。这类似在地球上给每个城市分配经纬度,从而让模型识别“在哪发生了什么”。
🔚 总结对比表
编码方式 | 是否可学习 | 支持相对位置 | 推荐场景 | 提出论文 |
---|---|---|---|---|
Sinusoidal | ❌ | 部分支持 | NLP/周期任务 | Transformer 2017 |
Learnable | ✅ | ❌ | 行为/推荐/视频任务 | BERT4Rec, ViT |
Random(buffer) | ❌ | ❌ | 图像语义任务 | SAM 2023 |
RoPE | ✅/❌ | ✅ | 大模型/语言模型 | RoFormer 2021 |
2D Spatial | ✅/❌ | ❌ | 图像/目标检测 | DETR 2020 |