深度解析 Transformer 模型中的位置嵌入(Positional Embedding)

在上一篇中,我们探讨了 词嵌入(Word Embedding) ,它根据词嵌入矩阵将文本序列转换为数值向量,使得计算机能够理解和处理自然语言。现在,让我们进一步了解位置嵌入(Positional Embedding),这是让 Transformer 模型“知晓”词语顺序的关键。

Transformer架构

1. 位置嵌入的作用

想象一下,如果我们只用词嵌入,那么无论一个词出现在句子的开头还是结尾,它的表示都是相同的。然而,在自然语言中,词语的位置往往影响其意义。例如,“苹果”在“我吃了一个苹果”和“苹果公司发布了新产品”这两个句子中的含义截然不同。因此,我们需要一种机制来告诉模型这些信息,这就是位置嵌入的作用。

位置嵌入通过给每个词赋予一个与它在句子中位置相关的独特向量,使得模型不仅能够捕捉到词语的语义,还能理解它们之间的相对顺序,从而更好地建模句子结构和依赖关系。

2. 位置嵌入的原理

为了让模型能够学习到位置信息,最直接的方法是为每个位置分配一个固定的、预定义的向量。在原始的 Transformer 模型中,位置嵌入是由正弦余弦函数组成的,这样设计的原因在于它具有周期性,可以帮助模型处理比训练时更长的序列,同时保持一定的泛化能力。

具体来说,对于模型维度 d 、位置 pos 和维度 i,位置嵌入 PE(pos, 2i)(偶数维)和 PE(pos, 2i+1) (奇数维)分别由以下公式计算:

位置嵌入算法

下面是位置嵌入计算的 Python 代码实现:

import torch
import torch.nn as nn
import mathclass PositionalEncoding(nn.Module):def __init__(self, d_model, max_len=5000):super(PositionalEncoding, self).__init__()# 创建一个位置编码矩阵 [max_len, d_model]pe = torch.zeros(max_len, d_model)position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)  # [max_len, 1]div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model))  # [d_model/2]pe[:, 0::2] = torch.sin(position * div_term)  # 偶数维pe[:, 1::2] = torch.cos(position * div_term)  # 奇数维pe = pe.unsqueeze(0)  # [1, max_len, d_model]self.register_buffer('pe', pe)  # 不作为模型参数更新def forward(self, x):seq_len = x.size(1)x = x + self.pe[:, :seq_len, :]return x

这段代码创建了一个PositionalEncoding类,用于生成位置嵌入,并将其添加到输入的词嵌入上。d_model是模型的维度,而max_len则是可以处理的最大序列长度。

3. 词嵌入和位置嵌入的作用

为了更好地理解词嵌入和位置嵌入是如何协作的,我们以一句简单的英语句子为例:“The cat sat on the mat.”。首先,我们会将每个词转换成对应的词嵌入向量;然后,为每个词添加与其位置相关的位置嵌入;最后,我们将两者相加,得到最终的隐藏层输入向量。

特别注意:

  • 为了方便演示,老牛同学此处简化为2 维,实际预训练模型的隐藏层远不止 2 维(如:Qwen2.5 有 1536 维)。
  • 同时,我们把 Token 简化为单词,实际使用的分词算法,如 BPE 分词算法,Token 可能并不一定与单词相同。

步骤一:词嵌入

首先,我们需要将句子中的每个词转换为词嵌入,假设我们得到了如下简化版的词嵌入向量(实际预训练模型的维度远高于此):

W{The} = [0.1, 0.2]
W{cat} = [0.3, 0.4]
W{sat} = [0.5, 0.6]
W{on}  = [0.7, 0.8]
W{the} = [0.9, 1.0]
W{mat} = [1.1, 1.2]

步骤二:位置嵌入

接下来,我们需要为每个词添加位置嵌入。我们可以根据上述公式计算出每个位置的嵌入向量。假设我们得到了如下位置嵌入向量(同样简化为2 维):

P_0 = [0.0, 1.0]
P_1 = [0.8, 0.6]
P_2 = [0.5, 0.8]
P_3 = [0.2, 0.9]
P_4 = [0.9, 0.4]
P_5 = [0.7, 0.2]

步骤三:词嵌入 + 位置嵌入

现在,我们将词嵌入和位置嵌入相加,得到最终的输入向量。这一步操作使得每个词的表示不仅包含了其语义信息,还包含了它在句子中的位置信息。具体来说,我们有:

X{The} = W{The} + P_0 = [0.1, 0.2] + [0.0, 1.0] = [0.1, 1.2]
X{cat} = W{cat} + P_1 = [0.3, 0.4] + [0.8, 0.6] = [1.1, 1.0]
X{sat} = W{sat} + P_2 = [0.5, 0.6] + [0.5, 0.8] = [1.0, 1.4]
X{on}  = W{on}  + P_3 = [0.7, 0.8] + [0.2, 0.9] = [0.9, 1.7]
X{the} = W{the} + P_4 = [0.9, 1.0] + [0.9, 0.4] = [1.8, 1.4]
X{mat} = W{mat} + P_5 = [1.1, 1.2] + [0.7, 0.2] = [1.8, 1.4]

词嵌入+位置嵌入

步骤四:隐藏层的输入

最终,这些带有位置信息的词嵌入向量 XThe, Xcat, Xsat, Xon, Xthe, Xmat 将作为 Transformer 模型的隐藏层的输入。通过这种方式,模型不仅能够理解每个词的语义,还能捕捉到它们在句子中的相对位置,从而更好地建模句子的结构和依赖关系。

4. 总结

位置嵌入是现代 NLP 模型中不可或缺的一部分,它使得模型能够理解词语的顺序,进而提升对文本的理解能力。通过引入位置嵌入,Transformer 架构克服了传统自注意力机制对词序“不可知”的局限,为各种自然语言处理任务提供了强有力的支持。

希望这篇文章能帮助你更深入地理解位置嵌入及其在 Transformer 模型中的作用。如果你还有任何疑问或想要了解更多细节,请随时留言交流!


Transformers 框架序列:

01.包和对象加载中的设计巧思与实用技巧

02.AutoModel 初始化及 Qwen2.5 模型加载全流程

03.Qwen2.5 大模型的 AutoTokenizer 技术细节

04.Qwen2.5/GPT 分词流程与 BPE 分词算法技术细节详解

05.嵌入(Embedding)机制和 Word2Vec 实战

Pipeline NLP 任务序列:

零·概述 丨 01.文本转音频 丨 02.文本分类 丨 03.词元分类和命名实体识别 丨 04.问答 丨 05.表格问答 | 06.填充蒙版

往期推荐文章:

Bolt.new 用一句话快速构建全栈应用:本地部署与应用实战(Ollama/Qwen2.5 等)

基于 Qwen2.5-Coder 模型和 CrewAI 多智能体框架,实现智能编程系统的实战教程

vLLM CPU 和 GPU 模式署和推理 Qwen2 等大语言模型详细教程

基于 Qwen2/Lllama3 等大模型,部署团队私有化 RAG 知识库系统的详细教程(Docker+AnythingLLM)

使用 Llama3/Qwen2 等开源大模型,部署团队私有化 Code Copilot 和使用教程

基于 Qwen2 大模型微调技术详细教程(LoRA 参数高效微调和 SwanLab 可视化监控)

ChatTTS 长音频合成和本地部署 2 种方式,让你的“儿童绘本”发声的实战教程

微信公众号:老牛同学

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java8--方法--格式化输出--printf--索引

System.out.printf("%1$s %2$tB %2$te %2$tY","Due date",new Date()); 效果图:ps: 1.一个字符串需要有多个格式化单词,通过建立索引实现,索引值用%$包围,$后紧跟格式化的目标类型,后面按顺序传入变量或填写内容 2.t指定日期类型,b指定填充月份的完…

前端重学之Number

Number (尾附IEEE754解读) mdn文档 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Numberjs里的number是双进度浮点数 用IEEE745 编码 0b 0o 0x 分别表示 二进制 八进制 十六进制```js 0.tostring() //报错 0 .tostring()//正确 ```IEEE7…

DVWA靶场搭建及错误解决教程

前言 DVWA(Damn Vulnerable Web Application)靶场是一个旨在帮助安全人员和开发人员学习和提高网络安全技能的开源项目。它是一个故意存在多种安全漏洞的 PHP/MySQL 网络应用程序,通常用于学习和测试各种网络攻击技术 工具下载链接:https://pan.quark.cn/s/49ef556eb32b 搭…

招行面试:万亿GB网盘, 从0到1设计,如何实现?

本文原文链接 文章很长,且持续更新,建议收藏起来,慢慢读!疯狂创客圈总目录 博客园版 为您奉上珍贵的学习资源 : 免费赠送 :《尼恩Java面试宝典》 持续更新+ 史上最全 + 面试必备 2000页+ 面试必备 + 大厂必备 +涨薪必备 免费赠送 :《尼恩技术圣经+高并发系列PDF》 ,帮你 …

代码随想录——动态规划01背包

暴力:每一件物品其实只有两个状态,取或者不取,所以可以使用回溯法搜索出所有的情况,那么时间复杂度就是O(2^n),这里的n表示物品数量。 所以暴力的解法是指数级别的时间复杂度。进而才需要动态规划的解法来进行优化! 二维dp数组01背包确定dp数组及下标含义 dp[i][j]表示前…

2024-2025-1 学号20241315《计算机基础与程序设计》第十四周学习总结

作业信息这个作业属于哪个课程 2024-2025-1-计算机基础与程序设计)这个作业要求在哪里 <作业要求的链接>https://www.cnblogs.com/rocedu/p/9577842.html#WEEK14这个作业的目标 <写上具体方面>《C语言程序设计》第13-14章并完成云班课测试作业正文 https://www.cn…

2024-2025-1 20241415《计算机基础与程序设计》第十四周学习总结

2024-2025-1 20241415《计算机基础与程序设计》第十四周学习总结 作业信息这个作业属于哪个课程 2024-2025-1-计算机基础与程序设计这个作业要求在哪里 2024-2025-1计算机基础与程序设计第十四周作业这个作业的目标 自学《C语言程序设计》第13-14章作业正文 https://www.cnblog…

kubectl 命令行快速操作-2

9、对外暴露服务 参考:详解kubernetes五种暴露服务的方式 - 滴滴滴 - 博客园 前面只介绍了Nodeport方式,还有NodePort、LoadBalancer、ExternalName、Ingress方式,重点讲解Ingress方式。 nginx-ingress:GitHub - kubernetes/ingress-nginx: Ingress NGINX Controller for K…

主动式AI(代理式)与生成式AI的关键差异与影响

大型语言模型(LLMs)如GPT可以生成文本、回答问题并协助完成许多任务。然而,它们是被动的,这意味着它们仅根据已学到的模式对接收到的输入作出响应。LLMs无法自行决策;除此之外,它们无法规划或适应变化的环境。 主动式AI(代理式)的出现正是为了解决这一问题。与生成式AI…

docker之旅

物理机上部署:1 部署复杂,成本高; 会造成资源的浪费 ; 不支持跨平台部署 ;无法支持进行服务的迁移 虚拟化:1 在一台宿主机上虚拟出多台虚拟机, 虚拟机会部署一个完整的操作系统,要分配系统资源。部署缺点: 部署复杂,无法进行迁移3 虚拟化与容器对比容器直接使用的宿主…

kubernetes之旅

k8s 架构 https://kubernetes.io/核心组件ETCD 分布式高性能键值数据库,存储整个集群的所有元数据 Apiserver 集群的资源访问控制入口,提供restAPI 和安全访问控制 scheduler: 调度器,负责将业务pod调度到合适的节点上 controller manager : 控制器,确保集群 按照期望方式…

asdfasdfasdf

阿斯蒂芬 阿萨德发生的发生阿斯蒂芬 阿萨德发生的发生代发收到飞 阿斯蒂芬 撒旦法撒地方 阿萨德发生的发生 金阿奎猎杀对决菲拉斯代发件 unit main;interfaceusesWinapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,Vcl.Contro…