【Transformer模型学习】第三篇:位置编码

news2025/4/6 2:13:25

文章目录

      • 0. 前言
      • 1. 为什么需要位置编码?
      • 2. 如何进行位置编码?
      • 3. 正弦和余弦位置编码
      • 4. 举个例子
        • 4.1 参数设置
        • 4.2 计算分母项
        • 4.3 计算位置编码
        • 4.4 位置编码矩阵
      • 5. 相对位置信息
      • 6. 改进的位置编码方式——RoPE
        • 6.1 RoPE的核心思想
        • 6.2 RoPE的优势
      • 7. 总结

0. 前言

按照国际惯例,首先声明:本文只是我自己学习的理解,虽然参考了他人的宝贵见解及成果,但是内容可能存在不准确的地方。如果发现文中错误,希望批评指正,共同进步。

本文是Transformer学习系列的第三篇文章:

  • 第一篇:提出背景、模型架构及推理过程
  • 第二篇:多头注意力机制
  • 第三篇:位置编码(本篇)

本文将介绍Transformer的重要(难点)内容——位置编码。
在这里插入图片描述

1. 为什么需要位置编码?

在第一篇文章就说明过:Transformer的优点在于可以并行化处理序列,这是因为注意力机制的引入,使得输入或输出序列中的(各个token的)距离将不会影响模型的处理,即注意力机制是排列不变的。并行处理加上排列不变就会带来一个麻烦:模型无法直接感知输入序列中元素的位置信息

与RNN相比,RNN可以通过其循环结构逐步处理序列中的每个元素,并将前一个时间步的隐藏状态传递到下一个时间步。这种机制使RNN能够自然地捕捉序列中的时间依赖关系和顺序信息。

所以,Transformer需要一种编码机制:让模型能够知道输入序列中的元素的位置信息,尤其是两个元素间的相对位置信息。

2. 如何进行位置编码?

“对一个序列中的元素进行位置编码”,这乍一看是个非常简单的任务,只要对其中所有元素进行编号[1, 2, 3…]不就行了吗?

但实际上,如此简单粗暴的位置编码方式是不可行的。主要是因为自然编号是离散的整数值,缺乏连续性和平滑性。自然编号的数值范围会随序列长度线性增长,导致训练不稳定,尤其是在长序列任务中。

因此,我们需要一种更聪明的位置编码,它要满足以下条件:

位置编码(Positional Encoding)在Transformer中起着至关重要的作用,它需要满足以下条件才能有效地为模型提供位置信息:

  1. 唯一性:每个位置的位置编码必须是唯一的,以便模型能够区分序列中不同位置的元素。

  2. 相对位置信息:位置编码应该能够捕捉到相对位置信息(如距离、方向等),而不仅仅是绝对位置。例如,模型应该能够知道“距离当前词3个位置的词”在哪里。

  3. 可扩展性:位置编码应该能够适应不同长度的序列,而不仅仅是训练时见过的序列长度。例如,模型在训练时可能只见过长度为100的序列,但在测试时可能需要处理长度为1000的序列。

3. 正弦和余弦位置编码

Attention is All You Need 提出了一种位置编码方法——正弦和余弦位置编码。

位置编码是一个与词嵌入维度相同的向量,直接加到词嵌入上:假设词嵌入的维度为 d model d_{\text{model}} dmodel,那位置编码的维度也为 d model d_{\text{model}} dmodel

对于位置 p o s pos pos和维度 i i i,位置编码的计算公式为:
P p o s , 2 i = sin ⁡ ( p o s 1000 0 2 i d model ) P_{pos, 2i} = \sin\left(\frac{pos}{10000^{\frac{2i}{d_{\text{model}}}}}\right) Ppos,2i=sin(10000dmodel2ipos)
P p o s , 2 i + 1 = cos ⁡ ( p o s 1000 0 2 i d model ) P_{pos, 2i+1} = \cos\left(\frac{pos}{10000^{\frac{2i}{d_{\text{model}}}}}\right) Ppos,2i+1=cos(10000dmodel2ipos)
其中:

  • p o s pos pos:序列中的位置索引(从0开始)。
  • i i i:维度索引(从0到 d model − 1 d_{\text{model}}-1 dmodel1)。
  • d model d_{\text{model}} dmodel:词嵌入的维度,例如设为512。
  • 10000 10000 10000:一个超参数,用于控制波长。

4. 举个例子

我们通过一个更简单的例子来计算位置编码。假设我们有一个序列长度为2(即2个词),词嵌入维度为4(即每个词用一个4维向量表示)。我们将使用正弦和余弦位置编码公式来计算位置编码。

4.1 参数设置
  • 序列长度 seq_len = 2 \text{seq\_len} = 2 seq_len=2
  • 词嵌入维度 d model = 4 d_{\text{model}} = 4 dmodel=4
  • 位置索引 p o s = 0 , 1 pos = 0, 1 pos=0,1
  • 维度索引 i = 0 , 1 i = 0, 1 i=0,1(因为 d model = 4 d_{\text{model}} = 4 dmodel=4,所以 i i i 的取值范围是0到1)。
4.2 计算分母项

首先计算分母项 div_term \text{div\_term} div_term
div_term = 1000 0 2 i d model \text{div\_term} = 10000^{\frac{2i}{d_{\text{model}}}} div_term=10000dmodel2i
对于 i = 0 , 1 i = 0, 1 i=0,1,计算结果如下:

  • i = 0 i = 0 i=0 时:
    div_term = 1000 0 0 4 = 1 \text{div\_term} = 10000^{\frac{0}{4}} = 1 div_term=1000040=1
  • i = 1 i = 1 i=1 时:
    div_term = 1000 0 2 4 = 1000 0 0.5 = 100 \text{div\_term} = 10000^{\frac{2}{4}} = 10000^{0.5} = 100 div_term=1000042=100000.5=100
4.3 计算位置编码

对于每个位置 p o s pos pos和维度 i i i,计算正弦和余弦值。

位置 p o s = 0 pos = 0 pos=0

  • 偶数维度( 2 i 2i 2i):
    • i = 0 i = 0 i=0
      P 0 , 0 = sin ⁡ ( 0 1 ) = sin ⁡ ( 0 ) = 0 P_{0, 0} = \sin\left(\frac{0}{1}\right) = \sin(0) = 0 P0,0=sin(10)=sin(0)=0
    • i = 1 i = 1 i=1
      P 0 , 2 = sin ⁡ ( 0 100 ) = sin ⁡ ( 0 ) = 0 P_{0, 2} = \sin\left(\frac{0}{100}\right) = \sin(0) = 0 P0,2=sin(1000)=sin(0)=0
  • 奇数维度( 2 i + 1 2i+1 2i+1):
    • i = 0 i = 0 i=0
      P 0 , 1 = cos ⁡ ( 0 1 ) = cos ⁡ ( 0 ) = 1 P_{0, 1} = \cos\left(\frac{0}{1}\right) = \cos(0) = 1 P0,1=cos(10)=cos(0)=1
    • i = 1 i = 1 i=1
      P 0 , 3 = cos ⁡ ( 0 100 ) = cos ⁡ ( 0 ) = 1 P_{0, 3} = \cos\left(\frac{0}{100}\right) = \cos(0) = 1 P0,3=cos(1000)=cos(0)=1
  • 位置 p o s = 0 pos = 0 pos=0 的位置编码:
    P 0 = [ 0 , 1 , 0 , 1 ] P_0 = [0, 1, 0, 1] P0=[0,1,0,1]

位置 p o s = 1 pos = 1 pos=1

  • 偶数维度( 2 i 2i 2i):
    • i = 0 i = 0 i=0
      P 1 , 0 = sin ⁡ ( 1 1 ) = sin ⁡ ( 1 ) ≈ 0.8415 P_{1, 0} = \sin\left(\frac{1}{1}\right) = \sin(1) \approx 0.8415 P1,0=sin(11)=sin(1)0.8415
    • i = 1 i = 1 i=1
      P 1 , 2 = sin ⁡ ( 1 100 ) = sin ⁡ ( 0.01 ) ≈ 0.0100 P_{1, 2} = \sin\left(\frac{1}{100}\right) = \sin(0.01) \approx 0.0100 P1,2=sin(1001)=sin(0.01)0.0100
  • 奇数维度( 2 i + 1 2i+1 2i+1):
    • i = 0 i = 0 i=0
      P 1 , 1 = cos ⁡ ( 1 1 ) = cos ⁡ ( 1 ) ≈ 0.5403 P_{1, 1} = \cos\left(\frac{1}{1}\right) = \cos(1) \approx 0.5403 P1,1=cos(11)=cos(1)0.5403
    • i = 1 i = 1 i=1
      P 1 , 3 = cos ⁡ ( 1 100 ) = cos ⁡ ( 0.01 ) ≈ 0.9999 P_{1, 3} = \cos\left(\frac{1}{100}\right) = \cos(0.01) \approx 0.9999 P1,3=cos(1001)=cos(0.01)0.9999
  • 位置 ( pos = 1 ) 的位置编码:
    P 1 = [ 0.8415 , 0.5403 , 0.0100 , 0.9999 ] P_1 = [0.8415, 0.5403, 0.0100, 0.9999] P1=[0.8415,0.5403,0.0100,0.9999]
4.4 位置编码矩阵

将每个位置的位置编码组合起来,得到位置编码矩阵 P P P
P = [ 0 1 0 1 0.8415 0.5403 0.0100 0.9999 ] P = \begin{bmatrix} 0 & 1 & 0 & 1 \\ 0.8415 & 0.5403 & 0.0100 & 0.9999 \\ \end{bmatrix} P=[00.841510.540300.010010.9999]

最终,将会把位置编码矩阵 P P P直接加到生成的词向量矩阵上。

5. 相对位置信息

前文我们说过:位置编码的重要性质之一是能捕获输入的相对位置信息,那正弦和余弦编码是如何获得相对位置信息的呢?

假设我们有两个位置 p o s pos pos p o s + k pos + k pos+k,它们的位置编码分别为 P p o s P_{pos} Ppos P p o s + k P_{pos + k} Ppos+k。我们需要分析它们之间的关系。

正弦和余弦函数是周期函数,具有以下性质:
sin ⁡ ( a + b ) = sin ⁡ a cos ⁡ b + cos ⁡ a sin ⁡ b \sin(a + b) = \sin a \cos b + \cos a \sin b sin(a+b)=sinacosb+cosasinb
cos ⁡ ( a + b ) = cos ⁡ a cos ⁡ b − sin ⁡ a sin ⁡ b \cos(a + b) = \cos a \cos b - \sin a \sin b cos(a+b)=cosacosbsinasinb

根据以上三角函数和差化积关系,容易得出:

  • 对于偶数维度( 2 i 2i 2i):

    P p o s + k , 2 i = P p o s , 2 i P k , 2 i + 1 + P p o s , 2 i + 1 P k , 2 i P_{pos + k, 2i} = P_{pos, 2i} P_{k, 2i+1} + P_{pos, 2i+1} P_{k, 2i} Ppos+k,2i=Ppos,2iPk,2i+1+Ppos,2i+1Pk,2i

  • 对于奇数维度( 2 i + 1 2i+1 2i+1):

    P p o s + k , 2 i = P p o s , 2 i + 1 P k , 2 i + 1 − P p o s , 2 i P k , 2 i P_{pos + k, 2i} = P_{pos, 2i+1} P_{k, 2i+1} - P_{pos, 2i} P_{k, 2i} Ppos+k,2i=Ppos,2i+1Pk,2i+1Ppos,2iPk,2i

6. 改进的位置编码方式——RoPE

RoPE(Rotary Positional Encoding)是一种创新的位置编码方法,旨在改进Transformer模型中位置信息的处理方式。与传统的绝对位置编码不同,RoPE通过旋转矩阵的方式将位置信息直接嵌入到词向量的计算过程中,特别是在自注意力机制中。

6.1 RoPE的核心思想

RoPE的基本思想是通过在计算Query和Key向量时动态地应用旋转矩阵来编码位置信息。这种方法允许模型不仅能够捕捉单词间的相对位置关系,还能保持对长距离依赖的有效建模能力。

具体来说,对于一个给定的位置 p o s pos pos和维度 i i i,RoPE会生成一个旋转角度 θ p o s , i \theta_{pos,i} θpos,i,然后使用这个角度对Query和Key向量进行旋转操作。旋转操作可以通过以下公式描述:

  • 对于偶数维度 i i i
    Q p o s , i ′ = Q p o s , i ⋅ cos ⁡ ( θ p o s , i ) − Q p o s , i + 1 ⋅ sin ⁡ ( θ p o s , i ) Q'_{pos,i} = Q_{pos,i} \cdot \cos(\theta_{pos,i}) - Q_{pos,i+1} \cdot \sin(\theta_{pos,i}) Qpos,i=Qpos,icos(θpos,i)Qpos,i+1sin(θpos,i)

    K p o s , i ′ = K p o s , i ⋅ cos ⁡ ( θ p o s , i ) − K p o s , i + 1 ⋅ sin ⁡ ( θ p o s , i ) K'_{pos,i} = K_{pos,i} \cdot \cos(\theta_{pos,i}) - K_{pos,i+1} \cdot \sin(\theta_{pos,i}) Kpos,i=Kpos,icos(θpos,i)Kpos,i+1sin(θpos,i)

  • 对于奇数维度(i):
    Q p o s , i ′ = Q p o s , i ⋅ cos ⁡ ( θ p o s , i − 1 ) + Q p o s , i − 1 ⋅ sin ⁡ ( θ p o s , i − 1 ) Q'_{pos,i} = Q_{pos,i} \cdot \cos(\theta_{pos,i-1}) + Q_{pos,i-1} \cdot \sin(\theta_{pos,i-1}) Qpos,i=Qpos,icos(θpos,i1)+Qpos,i1sin(θpos,i1)
    K p o s , i ′ = K p o s , i ⋅ cos ⁡ ( θ p o s , i − 1 ) + K p o s , i − 1 ⋅ sin ⁡ ( θ p o s , i − 1 ) K'_{pos,i} = K_{pos,i} \cdot \cos(\theta_{pos,i-1}) + K_{pos,i-1} \cdot \sin(\theta_{pos,i-1}) Kpos,i=Kpos,icos(θpos,i1)+Kpos,i1sin(θpos,i1)

这里的 θ p o s , i \theta_{pos,i} θpos,i通常基于一些预定义的规则来确定,例如 θ p o s , i = p o s / 1000 0 2 i / d m o d e l \theta_{pos,i} = pos / 10000^{2i/d_{model}} θpos,i=pos/100002i/dmodel

6.2 RoPE的优势
  1. 相对位置感知:由于RoPE直接在计算Query和Key的过程中融入了位置信息,这使得它天然支持对相对位置的感知,这对于理解句子结构非常关键。

  2. 简化模型设计:RoPE不需要额外的位置编码向量加到输入嵌入上,简化了模型的设计和实现。

  3. 增强表达能力:通过旋转矩阵的方式,RoPE能够在不同的维度上灵活地表示位置信息,从而增强了模型的整体表达能力。

  4. 适应性更强:RoPE可以自然地扩展到更长的序列长度,因为它不依赖于固定的最大序列长度,而是根据实际位置动态调整旋转角度。

RoPE提供了一种新颖且有效的方法来编码位置信息,尤其适用于需要精确捕捉元素间相对位置关系的任务。它的灵活性和有效性使其成为Transformer架构中的一个重要改进方向。

7. 总结

位置编码为Transformer模型提供序列中元素的位置信息,弥补自注意力机制的排列不变性。它通过引入位置信息,使模型能够区分不同位置的词,并捕捉相对位置关系。位置编码的设计需满足唯一性、连续性、可扩展性和计算效率等条件,以确保模型能够有效处理序列数据并提升性能。

本文详细介绍了常用的位置编码方式——正弦和余弦位置编码,并通过实例说明其应用方式。最后也介绍了改进的位置编码方式——RoPE。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2309072.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

(十 六)趣学设计模式 之 责任链模式!

目录 一、 啥是责任链模式?二、 为什么要用责任链模式?三、 责任链模式的实现方式四、 责任链模式的优缺点五、 责任链模式的应用场景六、 总结 🌟我的其他文章也讲解的比较有趣😁,如果喜欢博主的讲解方式,…

20250225-代码笔记03-class CVRPModel AND other class

文章目录 前言一、class CVRPModel(nn.Module):__init__(self, **model_params)函数功能函数代码 二、class CVRPModel(nn.Module):pre_forward(self, reset_state)函数功能函数代码 三、class CVRPModel(nn.Module):forward(self, state)函数功能函数代码 四、def _get_encodi…

面试常问的压力测试问题

性能测试作为软件开发中的关键环节,确保系统在高负载下仍能高效运行。压力测试作为性能测试的重要类型,旨在通过施加超出正常负载的压力,观察系统在极端条件下的表现。面试中,相关问题常被问及,包括定义、重要性、与负…

使用Java构建高效的Web服务架构

使用Java构建高效的Web服务架构 随着互联网技术的飞速发展,Web服务在现代应用中扮演着至关重要的角色。尤其是在企业级应用中,如何构建一个高效、可扩展且易维护的Web服务架构,成为了开发者和架构师面临的一项重要挑战。Java作为一种成熟、稳…

《Python实战进阶》No 10:基于Flask案例的Web 安全性:防止 SQL 注入、XSS 和 CSRF 攻击

第10集:Web 安全性:防止 SQL 注入、XSS 和 CSRF 攻击 在现代 Web 开发中,安全性是至关重要的。无论是用户数据的保护,还是系统稳定性的维护,开发者都需要对常见的 Web 安全威胁有深刻的理解,并采取有效的防…

蓝桥备赛(六)- C/C++输入输出

一、OJ题目输入情况汇总 OJ(online judge) 接下来会有例题 , 根据一下题目 , 对这些情况进行分析 1.1 单组测试用例 单在 --> 程序运行一次 , 就处理一组 练习一:计算 (ab)/c 的值 B2009 计算 (ab)/c …

企微审批中MySQL字段TEXT类型被截断的排查与修复实践

在MySQL中,TEXT类型字段常用于存储较大的文本数据,但在一些应用场景中,当文本内容较大时,TEXT类型字段可能无法满足需求,导致数据截断或插入失败。为了避免这种问题,了解不同文本类型(如TEXT、M…

[ISP] AE 自动曝光

相机通过不同曝光参数(档位快门时间 x 感光度 x 光圈大小)控制进光量来完成恰当的曝光。 自动曝光流程大概分为三部分: 1. 测光:点测光、中心测光、全局测光等;通过调整曝光档位使sensor曝光在合理的阈值内&#xff0…

小程序画带圆角的圆形进度条

老的API <canvas id"{{canvasId}}" canvas-id"{{canvasId}}" style"opacity: 0;" class"canvas"/> startDraw() {const { canvasId } this.dataconst query this.createSelectorQuery()query.select(#${canvasId}).bounding…

16. LangChain实战项目2——易速鲜花内部问答系统

需求简介 易束鲜花企业内部知识库如下&#xff1a; 本实战项目设计一个内部问答系统&#xff0c;基于这些内部知识&#xff0c;回答内部员工的提问。 在前面课程的基础上&#xff0c;需要安装的依赖包如下&#xff1a; pip install docx2txt pip install qdrant-client pip i…

FPGA开发,使用Deepseek V3还是R1(8):FPGA的全流程(简略版)

以下都是Deepseek生成的答案 FPGA开发&#xff0c;使用Deepseek V3还是R1&#xff08;1&#xff09;&#xff1a;应用场景 FPGA开发&#xff0c;使用Deepseek V3还是R1&#xff08;2&#xff09;&#xff1a;V3和R1的区别 FPGA开发&#xff0c;使用Deepseek V3还是R1&#x…

微服务学习(1):RabbitMQ的安装与简单应用

目录 RabbitMQ是什么 为什么要使用RabbitMQ RabbitMQ的安装 RabbitMQ架构及其对应概念 队列的主要作用 交换机的主要作用 RabbitMQ的应用 通过控制面板操作&#xff08;实现收发消息&#xff09; RabbitMQ是什么 RabbitMQ是一个开源的消息队列软件&#xff08;消息代理…

Starrocks入门(二)

1、背景&#xff1a;考虑到Starrocks入门这篇文章&#xff0c;安装的是3.0.1版本的SR&#xff0c;参考&#xff1a;Starrocks入门-CSDN博客 但是官网的文档&#xff0c;没有对应3.0.x版本的资料&#xff0c;却有3.2或者3.3或者3.4或者3.1或者2.5版本的资料&#xff0c;不要用较…

【北京迅为】itop-3568 开发板openharmony鸿蒙烧写及测试-第1章 体验OpenHarmony—烧写镜像

瑞芯微RK3568芯片是一款定位中高端的通用型SOC&#xff0c;采用22nm制程工艺&#xff0c;搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码&#xff0c;支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU&#xff0c;可用于轻量级人工…

Electron一小时快速上手

1. 什么是 Electron? Electron 是一个跨平台桌面应用开发框架&#xff0c;开发者可以使用 HTML、CSS、JavaScript 等 Web 技术来构建桌面应用程序。它的本质是结合了 Chromium 和 Node.js&#xff0c;现在广泛用于桌面应用程序开发。例如&#xff0c;以下桌面应用都使用了 El…

算法004——盛最多水的容器

力扣——盛最多水的容器点击即可跳转 当我们选择1号线和8号线时&#xff0c;下标为 1 和 8 形成容器的容积的高度是由 较矮的决定的&#xff0c;即下标为 8 的位置&#xff1b; 而宽度则是 1到8 之间的距离&#xff0c;为 8-17&#xff0c;此时容器的容积为 7 * 7 49。 当我…

Java Web-Filter

Filter 在 Java Web 开发中&#xff0c;Filter&#xff08;过滤器&#xff09;是 Servlet 规范中的一个重要组件&#xff0c;它可以对客户端与服务器之间的请求和响应进行预处理和后处理。以下从多个方面详细介绍 Java Web 中的 Filter&#xff1a; 一、概念和作用 概念&…

DeepSeek-R1训练时采用的GRPO算法数学原理及算法过程浅析

先来简单看下PPO和GRPO的区别&#xff1a; PPO&#xff1a;通过奖励和一个“评判者”模型&#xff08;critic 模型&#xff09;评估每个行为的“好坏”&#xff08;价值&#xff09;&#xff0c;然后小步调整策略&#xff0c;确保改进稳定。 GRPO&#xff1a;通过让模型自己生…

七星棋牌 6 端 200 子游戏全开源修复版源码(乐豆 + 防沉迷 + 比赛场 + 控制)

七星棋牌源码 是一款运营级的棋牌产品&#xff0c;覆盖 湖南、湖北、山西、江苏、贵州 等 6 大省区&#xff0c;支持 安卓、iOS 双端&#xff0c;并且 全开源。这个版本是 修复优化后的二开版本&#xff0c;新增了 乐豆系统、比赛场模式、防沉迷机制、AI 智能控制 等功能&#…

CSDN博客导出设置介绍

在CSDN编辑博客时&#xff0c;如果想导出保存到本地&#xff0c;可以选择导出为Markdown或者HTML格式。其中导出为HTML时有这几种选项&#xff1a;jekyll site&#xff0c;plain html&#xff0c;plain text&#xff0c;styled html&#xff0c;styled html with toc。分别是什…