白话transformer(五):位置编码

在前面其实讲过位置编码的完整内容,这次我们具体看看他的数学原理

B站视频讲解

白话transformer(五)

1、位置编码的位置

在这里插入图片描述
根据原论文的结构图我们可以看到,位置编码位于embedding后,在正式进入注意力机制前面。

也就是说这个位置编码不同于之前的RNN和LSTM模型是在模型中进行输入的,而是进入模型前输入的。

2、公式

P ( p o s , 2 i ) = s i n ( p o s 1000 0 2 i / d m o d e l ) P(pos,2i) = sin(\frac{pos}{10000^{2i/d_{model}}}) P(pos,2i)=sin(100002i/dmodelpos)

P ( p o s , 2 i + 1 ) = c o s ( p o s 1000 0 2 i / d m o d e l ) P(pos,2i+1) = cos(\frac{pos}{10000^{2i/d_{model}}}) P(pos,2i+1)=cos(100002i/dmodelpos)

我们用之前在讲QKV矩阵中用到的那个例子来看下
在这里插入图片描述

因为位置编码和embedding是相加的所以位置编码的形状大小必须和原始的embedding保持一致,应该也是8*10 的

为例来看下,我的位置是在第一行,那么他的pos=1(公式中的pos);

i是指向量长度上的维度,所以需要根据列的数值来确定,因为这里同时使用了sin \cos,所以我们需要注意在计算时i的取值不是embedding的长度10,而是embedding的长度的一半,也就是10/2 = 5;所以位置编码的i取值应该是【0,0,2,2,4,4,6,6,8,8,10,10】

所以根据上面的计算方法可以得到其他的位置编码信息,如下:

P = [ sin ⁡ ( p o s 1000 0 0 / 10 ) cos ⁡ ( p o s 1000 0 0 / 10 ) sin ⁡ ( p o s 1000 0 2 / 10 ) cos ⁡ ( p o s 1000 0 2 / 10 ) … … sin ⁡ ( p o s 1000 0 0 / 10 ) cos ⁡ ( p o s 1000 0 0 / 10 ) sin ⁡ ( p o s 1000 0 2 / 10 ) cos ⁡ ( p o s 1000 0 2 / 10 ) … … sin ⁡ ( p o s 1000 0 0 / 10 ) cos ⁡ ( p o s 1000 0 0 / 10 ) sin ⁡ ( p o s 1000 0 2 / 10 ) cos ⁡ ( p o s 1000 0 2 / 10 ) … … … … … … … … … … sin ⁡ ( p o s 1000 0 0 / 10 ) cos ⁡ ( p o s 1000 0 0 / 10 ) sin ⁡ ( p o s 1000 0 2 / 10 ) cos ⁡ ( p o s 1000 0 2 / 10 ) … … ] P = \left[\begin{array}{cccc} \sin\left(\frac{pos}{10000^{0/10}}\right) & \cos\left(\frac{pos}{10000^{0/10}}\right) & \sin\left(\frac{pos}{10000^{2/10}}\right) & \cos\left(\frac{pos}{10000^{2/10}}\right) &……\\[10pt] \sin\left(\frac{pos}{10000^{0/10}}\right) & \cos\left(\frac{pos}{10000^{0/10}}\right) & \sin\left(\frac{pos}{10000^{2/10}}\right) & \cos\left(\frac{pos}{10000^{2/10}}\right) &……\\[10pt] \sin\left(\frac{pos}{10000^{0/10}}\right) & \cos\left(\frac{pos}{10000^{0/10}}\right) & \sin\left(\frac{pos}{10000^{2/10}}\right) & \cos\left(\frac{pos}{10000^{2/10}}\right) &……\\[10pt] &……&……&……&……\\ \sin\left(\frac{pos}{10000^{0/10}}\right) & \cos\left(\frac{pos}{10000^{0/10}}\right) & \sin\left(\frac{pos}{10000^{2/10}}\right) & \cos\left(\frac{pos}{10000^{2/10}}\right) &……\\[10pt] \end{array}\right] P= sin(100000/10pos)sin(100000/10pos)sin(100000/10pos)sin(100000/10pos)cos(100000/10pos)cos(100000/10pos)cos(100000/10pos)……cos(100000/10pos)sin(100002/10pos)sin(100002/10pos)sin(100002/10pos)……sin(100002/10pos)cos(100002/10pos)cos(100002/10pos)cos(100002/10pos)……cos(100002/10pos)…………………………

3、位置编码的code

def positional_encoding(pos, d_model):
    """
    生成位置编码
    :param pos: 位置序号 (序列长度)
    :param d_model: 模型的维度
    :return: 位置编码矩阵 (pos, d_model)
    """
    # 初始化位置编码矩阵
    pos_encoding = np.zeros((pos, d_model))
    # 获取位置索引,并扩展维度以进行计算
    position = np.arange(pos)[:, np.newaxis]
    # 计算分母中的项
    div_term = np.exp(np.arange(0, d_model, 2) * -(np.log(10000.0) / d_model))
    # 将正弦应用于偶数索引
    pos_encoding[:, 0::2] = np.sin(position * div_term)
    # 将余弦应用于奇数索引
    pos_encoding[:, 1::2] = np.cos(position * div_term)

    return pos_encoding

初始化一个与输入矩阵大小一样的初始矩阵

# 设置位置序号和模型的维度
pos = 100  # 序列长度
d_model = 16  # 模型的维度

# 生成位置编码
pos_encoding = positional_encoding(pos, d_model)

获取位置索引,并扩展维度以进行计算


position = np.arange(pos)[:, np.newaxis]
print(position)

[[0]
 [1]
 [2]
 [3]
 [4]
 [5]
 [6]
 [7]]

  • np.arange(pos) 生成一个从 0 到 pos-1 的序列数组。如果 pos 是 8,它会生成一个数组 [0, 1, 2, …, 7]。

  • [:, np.newaxis] 这个部分是一种索引操作,它的作用是增加一个新的轴。: 表示选取数组中的所有项,np.newaxis 是一个特殊的索引器,它会增加一个轴。这里,它被用来将一维数组转换为二维的列向量。

计算分母中的项

div_term = np.exp(np.arange(0, d_model, 2) * -(np.log(10000.0) / d_model))
div_term
  • np.arange(0, d_model, 2) 创建了一个从 0 到 d_model(不包括 d_model)的数组,步长为 2。这意味着它会生成 [0, 2, 4, …, d_model-2](假设 d_model 是偶数)的数组。这个数组用于确定编码的频率:在原始 Transformer 论文中,每个维度的频率是根据这个维度的序号确定的。

  • np.log(10000.0) / d_model 计算了一个常数,这是用于调整频率的比例因子。10000 是一个超参数,可以根据需要调整。这个常数用于控制编码中频率的变化,使其对于模型的不同维度而言是不同的。

  • -(np.log(10000.0) / d_model) 将上述创建的数组中的每个元素乘以这个负的比例因子。乘以负数是因为指数函数 np.exp 会随着输入的增加而增加,而在位置编码中,我们希望随着维度的增加而减少频率。
  • np.exp(…) 将 e(自然对数的底数)的幂次应用于上面计算的每个元素。结果是对于模型中的每个偶数维度,我们得到了一个减小的指数尺度。

这个 div_term 数组用来缩放位置索引,用于生成位置编码中的波长。随着维度的增加,波长会指数级地减小,这样在模型的较高维度上,位置编码的变化会更加迅速,这有助于模型学习和区分不同位置的信息。

将正弦应用于偶数索引

pos_encoding[:, 0::2] = np.sin(position * div_term)
pos_encoding


在这里插入图片描述
偶数列上已经有了数据

将余弦应用于奇数索引

pos_encoding[:, 1::2] = np.cos(position * div_term)

在这里插入图片描述
全部数据生成

4、绘图

# 使用更圆滑的线条和不同的颜色绘制位置编码曲线图
plt.figure(figsize=(14, 8))
colors = plt.cm.viridis(np.linspace(0, 1, min(pos, 10)))
for i in range(2,min(pos, 6)):  # 只展示前10个位置的编码
    plt.plot(pos_encoding[:,i], label=f'Dimension {i}', color=colors[i], linewidth=2, linestyle='-', marker='', markersize=6)
plt.xlabel('Position')
plt.ylabel('PE value')
plt.title('Smooth Positional Encoding Curves for First Few Positions')
plt.legend()
plt.grid(True)
plt.show()

在这里插入图片描述

我们可以看到,取了2、3、4、5这4个维度来查看,发现维度2和3这两个形状很像只是发生了位移,因为他们的周期数值是一样的

5、优点

使用正弦(sin)和余弦(cos)函数来生成位置编码在 Transformer 模型中具有几个关键优点:

  1. 周期性和连续性
    正弦和余弦函数是周期性的,这使得模型能够自然地学习和利用序列的周期性模式。此外,由于这些函数是连续的,模型可以更容易地进行泛化,从而理解未见过的位置。

  2. 独特的位置信息
    由于 sin 和 cos 函数的值在每个周期内是唯一的,结合两者可以为序列中的每个位置生成独一无二的编码,从而帮助模型捕捉位置信息。

  3. 可扩展性
    正弦和余弦编码允许模型处理比训练期间遇到的序列更长的序列。由于其周期性,模型可以推断出序列中的相对位置,即使是在训练数据之外的位置。

  4. 可加性
    正弦和余弦函数使位置编码成为可加的。这意味着模型可以通过叠加两个位置的编码来理解位置偏移,这在某些序列到序列的任务中特别有用,如机器翻译。

  5. 编码相对位置
    正弦和余弦波的频率可以帮助模型理解位置之间的相对距离。由于这些波的相位差,模型可以通过位置编码的内积来推断两个位置之间的距离,这对于理解单词之间的关系很重要。

  6. 多尺度的位置编码
    在 Transformer 中,通过使用不同频率的正弦和余弦函数,位置编码可以在多个尺度上编码信息。这使得模型可以同时捕捉短距离和长距离的依赖关系。

  7. 与学习参数无关
    正弦和余弦位置编码不依赖于模型训练过程中的学习,这意味着它们在训练开始时就是固定的,并且可以作为对学习到的注意力权重的补充。

正弦和余弦波的这些特性使得位置编码不仅可以提供绝对位置信息,还可以帮助模型学习序列中元素的相对位置,这是理解自然语言等复杂序列数据的关键。

6、疑问

虽然我可以说清楚位置编码的流程和方法,但是没有搞明白为什么位置编码会有效,因为他是直接进行相加后再进行训练的,之前学习了大神李沐的课程也貌似没说明白,只是说实践证明确实有效。经过多方查找资料,找到一下信息,仅供参考:

在 Transformer 模型中,位置编码的有效性来自于其能力为模型提供关于输入序列中单词顺序的信息。Transformer 的核心是自注意力机制,它本质上是位置不变的,这意味着如果没有某种方式来考虑输入的顺序,模型将无法知道单词在序列中的位置。为了解决这个问题,位置编码被引入作为序列中每个单词的补充信息。

以下是为什么直接将位置编码加到输入嵌入(embeddings)并训练模型是有效的几个理由:

  1. 无损信息合并
    位置编码与词嵌入相加不会丢失信息,因为它们都参与模型的训练过程。位置编码被设计成有足够的变化,以确保即使在加到嵌入向量后也能保持唯一性。

  2. 保持上下文关联
    相加操作后的嵌入维持了单词的原始语义信息,并与位置信息结合,使模型能够关联单词的语义和其在序列中的位置。

  3. 端到端学习
    Transformer 通过端到端的学习逐渐适应位置编码。模型学习如何结合位置信息和词的含义,以便于执行翻译、问答等任务。

  4. 训练过程的优化
    位置编码是可微的,这意味着模型可以在训练过程中调整权重,以最优化对位置编码的利用。

  5. 相对位置关系
    由于正弦和余弦函数具有周期性特征,位置编码能够使模型捕捉到序列中元素的相对位置关系,这在处理诸如长距离依赖这样的语言特征时尤为重要。

  6. 不需要额外的参数学习
    位置编码是预先定义的,并不需要通过训练来学习,从而减少了模型训练的参数数量,同时也减轻了模型的过拟合风险。

总的来说,位置编码通过直接相加的方式提供了一种简单而有效的方法来将顺序信息融入模型中,而不需要改变原有的架构,也不需要增加额外的参数。这种编码策略证明了其在各种自然语言处理任务中的有效性。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【二叉树】算法例题

目录 九、二叉树 68. 二叉树的最大深度 ① 69. 相同的树 ① √ 70. 翻转二叉树 ① 71. 对称二叉树 ① 72. 从前序与中序遍历序列构造二叉树 ② 73. 从中序与后续遍历序列构造二叉树 ② 74. 填充每个节点的下一个右侧节点指针 II ② 75. 二叉树展开为链表 ② 76.…

蓝牙耳机品牌排行榜前十名,选购硬核机型,避免不必要的开销!

在现代社会,蓝牙耳机正逐渐取代传统有线耳机,成为主流的选择。尽管市场竞争激烈,但找到一款适合自己的蓝牙耳机并非易事。我在这里为你推荐几款我认为值得信赖的蓝牙耳机,希望能助你一臂之力,找到最适合你的那一款。 一…

一文读懂MES和ERP的区别

MES(Manufacturing Execution System)系统是制造执行系统,位于上层的计划管理系统与生产过程的直接工业控制系统之间,是面向车间层的管理信息系统,能够对整个车间制造过程进行优化,实时收集生产过程中的数据…

天翼云研发告诉我:AH封装的IPsec不能穿越NAT设备

正文共:1333 字 14 图,预估阅读时间:2 分钟 最近跟中国电信做VPN的研发交流了一下技术,发现技术爱好者跟研发之间的差距还是很明显的。 问题是我在配置天翼云的IPsec VPN连接时,发现IPsec策略的传输协议只有ESP协议可选…

YOLOv9改进策略:ECVBlock即插即用的多尺度融合模块,助力小目标涨点 | 顶刊TIP 2023 CFPNet

💡💡💡本文改进内容:ECVBlock即插即用的多尺度融合模块,助力检测任务有效涨点! yolov9-c-EVCBlock summary: 1011 layers, 68102630 parameters, 68102598 gradients, 252.4 GFLOPs 改进结构图如下&#x…

Centos7没有可用软件包 ifconfig问题解决

问题描述 在Centos7中查看ip没有ifconfig,使用yum安装ifconfig报错没有可用软件包 ifconfig问题解决 [rootlocalhost etc]# yum -y install ifconfig 已加载插件:fastestmirror base …

外贸网站常用的wordpress模板

零件配件WordPress外贸建站模板 汽车行业零配件WordPress外贸建站模板,卖配件、零件的外贸公司可以使用的WordPress主题。 https://www.jianzhanpress.com/?p4912 WordPress外贸独立站主题 简洁实用的WordPress外贸独立站主题,适合时尚服装行业搭建w…

酷开系统用电视为居家生活打开精彩窗口|酷开科技|酷开会员|

随着互联网的发展,电视也承载了更多的功能。相比于传统的电视,如今的智能电视屏幕更大、分辨率更高、色彩更加鲜艳,能够呈现出更加逼真的画面效果。当观众观看大屏电视时,仿佛置身于电影大幕的场景之中,感受到更为震撼…

SpringCloud Alibaba Nacos 服务注册和配置中心

一、前言 接下来是开展一系列的 SpringCloud 的学习之旅,从传统的模块之间调用,一步步的升级为 SpringCloud 模块之间的调用,此篇文章为第十二篇,即介绍 SpringCloud Alibaba Nacos 服务注册和配置中心。 二、Nacos 简介 2.1 为…

C++初阶:vector相关练习

目录 1. 只出现一次的数2. 杨辉三角3. 删除有序数组中的重复项4. 只出现一次的数II5. 只出现一次的数III6. 数组中出现次数超过一半的数7. 电话号码的字母组合(多叉树遍历) 1. 只出现一次的数 题目信息: 题目链接: 只出现一次的数…

【python】flask服务端响应与重定向处理

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…

Leetcode 3.15

Leetcode hot100 二叉树1.二叉搜索树中第K小的元素2.二叉树展开为链表3.从前序与中序遍历序列构造二叉树 二叉树 1.二叉搜索树中第K小的元素 二叉搜索树中第K小的元素 最重要的知识点:二叉树搜索树的中序遍历是升序的。 方法一:我们只需存储升序遍历&…

【蓝桥杯备赛】Day15:递推与递归(倒计时23天)

题目1:题目 2335: 信息学奥赛一本通T1422-活动安排 设有n个活动的集合E{1,2,…,n},其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源。每个活动i都有一个要求使用该资源的起始时间si和一个结束时间fi…

管易云·奇门对接打通金蝶云星空发货单查询接口与销售出库新增接口

管易云奇门对接打通金蝶云星空发货单查询接口与销售出库新增接口 ​​ ​​ 对接源平台:管易云奇门 管易云是上海管易云计算软件有限公司旗下的专注提供电商企业管理软件服务的品牌,总部位于中国上海张江高科技产业园区。管易云旗下拥有管易云C-ERP、EC-OMS、EC-W…

HarmonyOS卡片刷新服务,信息实时更新一目了然

如今衣食住行娱乐影音等App占据了大多数人的手机,一部手机可以满足日常大多需求,但对需要经常查看或进行简单操作的场景来说,总需要用户点开App操作未免过于繁琐。 针对该问题, HarmonyOS SDK为用户提供了Form Kit(卡…

为啥很多人觉得编程难学?

看到推特上网友菜脯写的一条推文: 菜脯:我大概知道,为啥很多人觉得编程难学了。 因为对我来说,编程过程就是 看资料——开始写——遇到问题——查资料——解决问题——继续写——继续遇问题——继续查资料… 这个循环似乎会一直持…

Retrieval Augmented Thoughts(RAT):检索增强思维,实现长视野生成中的上下文感知推理

论文地址:https://arxiv.org/pdf/2403.05313.pdf 原文地址:rat-retrieval-augmented-thoughts Github:Implementation of RAT 2024 年 3 月 14 日 介绍 让我首先从一些一般性观察开始...... 在生成式人工智能应用程序中实现效率与生成响应…

vulhub中Apache Shiro 认证绕过漏洞复现(CVE-2010-3863)

Apache Shiro是一款开源安全框架,提供身份验证、授权、密码学和会话管理。Shiro框架直观、易用,同时也能提供健壮的安全性。 在Apache Shiro 1.1.0以前的版本中,shiro 进行权限验证前未对url 做标准化处理,攻击者可以构造/、//、…

YOLOV9训练自己的数据集

1.代码下载地址GitHub - WongKinYiu/yolov9: Implementation of paper - YOLOv9: Learning What You Want to Learn Using Programmable Gradient Information 2.准备自己的数据集 这里数据集我以SAR数据集为例 具体的下载链接如下所示: 链接:https:/…

广州市高质量发展大会,东纺企服系统提出数智化新思路

近日,广州市海珠区凤阳街道高质量发展大会暨企业联盟沙龙荟在海珠区珠江国际纺织城D区6楼时尚馆召开。东纺科技作为海珠区企业代表,受邀出席参与活动。 本次大会对今年的高质量发展进行亮诺和展望。海珠区委常委、区纪委书记、区监委主任杨清谦以及海珠区…