一文搞懂Transformer的边角料知识:位置编码

news2024/12/28 20:19:45

目录

一、为什么需要位置编码

二、位置编码分类

1.表格型

2.函数型

三、Transformer的位置编码

1.位置编码应有的特点

2.Transformer的位置编码公式

3.三角函数

4.线性相关

5.相对位置关系

四、总结


一、为什么需要位置编码

        在Transformer出现以前,NLP任务大多是以RNN、LSTM为代表的循环处理方式,即一个token一个token的输入到模型当中。模型本身是一种顺序结构,天生就包含了token在序列中的位置信息。但是这种模型有很多天生的缺陷,比如:

        1.会出现“遗忘”的现象,无法支持长时间序列,虽然LSTM在一定程度上缓解了这种显现,但是这种缺陷仍然存在;

        2.句子越靠后的token对结果的影响越大;

        3.只能利用上文信息,不能获取下文信息;

        4.计算的时间复杂度比较高,循环网络是一个token一个token的输入的,也就是句子有多长就要循环多少遍;

        为了解决上述问题,Transformer出现了,Transformer将一哥token序列一次性输入到模型,不使用循环的形式。因为是一次性接收所有token作为输入进行并行处理,“遗忘”的问题没有了、所有的token都一视同仁了、上下文的信息能同时获取到、时间复杂度也降下来了。但是这又出现了新的问题,因为所有token一视同仁了,模型就没有办法知道每个token在句子中的相对和绝对的位置信息,而位置关系对于NLP任务来说是有着决定性影响的。比如下面的两句话token完全一样,但含义截然相反:

1.我把小姐姐按在地上摩擦

2.小姐姐把我按在地上摩擦

        为了解决这个问题,Transformer把token的顺序信号加到词向量上帮助模型学习这些信息,这就位置编码(Positional Encoding)。下面这张图不用解释,大家再熟悉不过,接下来的内容不会涉及Self-Attention等牛逼的创新设计,只讨论位置编码,也就是红框的内容。

二、位置编码分类

        位置编码用来标记token的前后顺序,总的来说,位置编码分为两个类型:表格型和函数型。

1.表格型

        表格型位置编码就是建立一个长度为L的词表,按词表的长度来分配位置id。

        最简单的想法就是从1开始向后排列,我们使用单字分词,如:

我  把  小  姐  姐  按  在  地  上  摩  擦

1    2    3   4    5    6   7    8    9  10  11

        但是这种方式存在很大的问题,句子越长,后面的值越大,数字越大说明这个位置占的权重也越大,这样的方式无法凸显每个位置的真实的权重。

        当然可以将上述编码进行归一化然后组成等差数列,但是这种方式也有问题,当句子长度不一样,每个位置的编码尺度不同,也就是说不同长度的句子,同一位置的编码是不一样的,如下面两句话:

  我     把     小      姐     姐      按     在     地     上     摩     擦

0.09  0.18  0.27  0.36  0.45  0.54  0.63  0.72  0.81  0.9  0.99

  看     你     往      哪     跑

 0.2    0.4    0.6    0.8    1.0

2.函数型

        函数型位置编码通过输入token的位置信息,得到相应的位置编码。这种方式并不使用上述绝对位置关系,而是使用相对位置的关系。

        可以看到,使用相对位置的方法,我们可以清晰的知道单词之间的距离远近的关系,单独看某一个token的位置编码可能不知所谓,但是放在整个token序列中,就能表征token的相对位置关系。

        比如下面这句话,我站在“按”字的位置,计算其它字距离“按”的相对距离,有正负可以区分前后:

我     把     小      姐     姐      按     在     地     上     摩     擦

-5      -4     -3      -2      -1       0       1      2       3      4       5

        上面的句子只是一个演示,真实情况不会是这样。我要说明的是,相对位置编码需要线性相关,Transformer的位置编码就属于这种类型。

三、Transformer的位置编码

1.位置编码应有的特点

        好的位置编码应该有如下特点:

        1.每个时间步都有唯一的编码。

        2.在不同长度的句子中,两个时间步之间的距离应该一致。

        3.模型不受句子长短的影响,并且编码范围是有界的。(不会随着句子加长数字就无限增大)

        4.同一时间序列中,每个连续的编码应该是等步长的,即线性相关的。

        5.位置编码应该能表示token的绝对或相对位置关系。

        下面我们就来看一下Transformer的位置编码,是否符合上面几点要求。

2.Transformer的位置编码公式

        使用正余弦函数表示绝对位置,通过两者乘积得到相对位置:

PE_{pos,2i}=sin(\frac{pos}{10000^{\frac{2i}{d_{model}}}})                                (1)

PE_{pos,2i+1}=cos(\frac{pos}{10000^{\frac{2i}{d_{model}}}})                            (1)

        其中PE表示位置编码;pos表示一句话中token的位置;每个token的位置编码是一个向量(或者叫embedding),i表示这个向量中每个元素的index;d_{model}表示位置编向量的维度。

        式1,其实是一个式子,看起来非常复杂,写的直观一点是下面这个样子:

PE_{pos}=\begin{bmatrix}sin(\omega_1\cdot pos) \\ cos(\omega_1\cdot pos) \\ sin(\omega_2\cdot pos) \\ cos(\omega_2\cdot pos) \\ \vdots \\ sin(\omega_{d/2}\cdot pos) \\ cos(\omega_{d/2}\cdot pos) \end{bmatrix}                                 (2)

        其中\omega i = \frac{1}{10000^{\frac{2i}{d_{model}}}},可以看到,每个位置编码向量都是sin和cos交替。

3.三角函数

        从式(2)中可以发现Transformer的位置编码使用了三角函数,三角函数是周期函数,那为什么要把每个维度设计成周期形式呢,可以看下面这个图,二进制格式表示一个数字:

十进制二进制
00000
10001
20010
30011
40100
50101
60110
70111
81000
91001
101010
111011
121100
131101
141110
151111

        可以看到以列为单位,不同位置上的数字都会出现0、1的交替变化。规律是第i位置上第2^i个数据交替一次。比如第0列(右面数第一列)是每1次都切换,第1列(右面数第二列)是每两次切换。但是在浮点数的世界中使用二进制值是对空间的浪费,所以我们可以用正弦函数代替。事实上,正弦函数也能表示出二进制那样的交替。随着波长的变长,带来的是数据变化的变慢,就如同上面的提到的。

        Transformer的位置编码选择三角函数的官方解释是这样的:

位置编码的每个维度都对应于一个正弦曲线。波长形成一个从2π到10000·2π的几何轨迹。我们之所以选择这个函数,是因为我们假设它可以让模型很容易地通过相对位置进行学习,因为对于任何固定的偏移量k,PEpos+k都可以表示为PEpos的线性函数。

        也就是说,每个维度都是波长不同的正弦波,波长范围是2π到10000·2π,选用10000这个比较大的数是因为三件函数式有周期的,在这个范围基本上,就不会出现波长一样的情况了。然后谷歌的科学家们为了让PE值的周期更长,还交替使用sin/cos来计算PE的值,就得到了最终的公式(1)。

        下图可以比较清晰的表现这过程。相同颜色的是同一个token的词向量,为了方便展示,波形图只使用sin,而且波形图只是展示使用,并不是实际波形图:

        可以看到,每个维度(即每一行)都是三角函数的波形,随着pos的增加,波长越来越长,这就很好的实现了低位变化快、高位变化慢的情况。那每个pos内(即每一列)的元素是否为线性相关呢?

4.线性相关

        我们知道某一个token的位置是pos,如果某一个token表示为 pos+k ,那就表明这个位置距上一个token为k。

        如果这时我们需要看看一个位置pos和pos+k 这两个token的关系。按照位置编码的的公式,我们可以计算pos+k 的位置编码,其结果如下:

PE_{(pos+k,2i)}=sin(\omega _i\cdot (pos+k))                                                (3)

PE_{(pos+k,2i+1)}=cos(\omega _i\cdot (pos+k))                                            (3)

        因为

sin(\alpha+ \beta )=sina(\alpha) \cdot cos(\beta )+cos(\alpha )\cdot sina(\beta )                     (4)

cos(\alpha+ \beta )=cos(\alpha) \cdot cos(\beta )-sina(\alpha )\cdot sina(\beta )                   (4)

        所以

                        PE_{(pos+k,2i)}=sin(\omega _i\cdot (pos+k))

                                               =sin(\omega _i\cdot pos)cos(\omega _i\cdot k)+cos(\omega _i\cdot pos)sin(\omega _i\cdot k)                 (5)

                        PE_{(pos+k,2i+1)}=cos(\omega _i\cdot (pos+k))

                                                   =cos(\omega _i\cdot pos)cos(\omega _i\cdot k)-sin(\omega _i\cdot pos)sin(\omega _i\cdot k)             (5)

        将式(1)中的\frac{1}{10000^{\frac{2i}{d_{model}}}}\omega _i代替,得到:

PE_{pos,2i}=sin(\frac{pos}{10000^{\frac{2i}{d_{model}}}})=sin(\omega_{i}k)                                        (6)

PE_{pos,2i+1}=cos(\frac{pos}{10000^{\frac{2i}{d_{model}}}})=cos(\omega_{i}k)                                    (6)

        将式(6)带入式子(5),得到:

PE_{(pos+k,2i)}=cos(\omega _i\cdot k)PE_{(pos,2i)}+sin(\omega _i\cdot k)PE_{(pos,2i+1)}       (7)

PE_{(pos+k,2i+1)}=cos(\omega _i\cdot k)PE_{(pos,2i+1)}-sin(\omega _i\cdot k)PE_{(pos,2i)}      (7)   

        因为k是一个常数,所有上面公式中sin() 和cos() 的计算值也是常数,可以表示为:

u=cos(\omega _i\cdot k)                                                                                (8)

v=sin(\omega _i\cdot k)                                                                                (8)

        这样,就可以将PE_{pos+k}写成矩阵乘法的形式:

\begin{bmatrix}PE_{(pos+k,2i)} \\ PE_{(pos+k,2i+1)}) \end{bmatrix} = \begin{bmatrix} u & v\\ -v & u \end{bmatrix} \times \begin{bmatrix} PE_{(pos,2i)}\\ PE_{(pos,2i+1)} \end{bmatrix}                        (9)

        至此可以发现,位置 pos的编码与位置pos+k的位置编码是线性关系。

        那么问题来了,上面的推导过程可以看到线性关系,那怎么表示每个token的相对距离关系呢?

5.相对位置关系

        我们将PE_{pos}PE_{pos+k}相乘 (两个向量的内积),可以得到如下结果:

        ​​​​​​​        ​​​​​​​        ​​​​​​​        PE_{pos}\cdot PE_{pos+k}=\sum_{i=0}^{\frac{d}{2}-1}sin(\omega _i\cdot pos)\cdot sin(\omega _i(pos+k))

                                                                =\sum_{i=0}^{\frac{d}{2}-1}cos(\omega _i(pos-(pos+k)))

                                                                =\sum_{i=0}^{\frac{d}{2}-1}cos(\omega _i\cdot k)                                        (10)

        我们发现相乘后的结果为一个余弦的加和。这里影响值的因素就是k 。如果两个token的距离越大,也就是K越大,根据余弦函数的性质可以知道,两个位置的PE相乘结果越小。这样的关系可以得到,如果两个token距离越远则乘积的结果越小,所以位置编码可以表示相对位置关系。

四、总结

        问我们上面提到了位置编码应该有的特点,我们再总结一下,Transformer的位置编码简称PE:

        1.每个时间步都有唯一的编码:根据公式(1),d_{model}是确定的,根据pos和i能计算出确定的值,这一点无疑是符合的;

        2.在不同长度的句子中,两个时间步之间的距离应该一致:根据公式(1),d_{model}(词向量的长度)是一个定值,原版Transform的512,所以就算输入句子长度不一样,到计算编码这一步,两个时间步之间的距离也是一致的;

        3.编码范围是有界的。(不会随着句子加长数字就无限增大):PE使用三角函数,振幅是1,所以范围是[-1,1];

        4.同一时间序列中,每个连续的编码应该是等步长的,即线性相关的:根据上一节的推导过程可以证明;

        5.位置编码应该能表示token的绝对或相对位置关系:任意两个位置的token距离与PE内积结果成反比,真很好的反映了token的相对位置关系。

        就简单介绍到这里,关注不迷路(*^▽^*)

        

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

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

相关文章

白话教你认识 Kafka,秒懂原理

一、Kafka 基础 消息系统的作用 应该大部份小伙伴都清楚,用机油装箱举个例子 所以消息系统就是如上图我们所说的仓库,能在中间过程作为缓存,并且实现解耦合的作用。 引入一个场景,我们知道中国移动,中国联通&#x…

谷歌浏览器从c盘剪切到d盘书签消失的找回方式

目录 1.在以下路径找到这两个文件(Bookmarks和Bookmarks.bak) 2.我们只需要将上述的两个文件Bookmarks和Bookmarks.bak先备份到一个地方,替换文件: 3.重启谷歌浏览器 1.在以下路径找到这两个文件(Bookmarks和Bookmarks.bak) 移动后的新路径\Google\C…

vue自行封装错误提示信息——$message——技能提升

在使用vue的过程中,我们经常用到的是这一种的提示信息: 该组件提供的属性有以下几个: 但是,如果想要自定义提示信息,则可以使用下面的方式来处理: 1.自定义提示信息组件 import Vue from vue export fu…

Linux基本指令二

Linux基本指令二 一、more指令1、语法2、功能3、常用操作 二、less指令1、语法2、功能3、常用选项4、常用操作 三、head指令1、语法2、功能3、常用选项4、示例 四、tail指令1、语法2、功能3、常用选项4、示例 五、date指令1、语法2、功能3、常用的标记4、设置时间5、时间戳6、示…

VxeTable 表格组件推荐

VxeTable 表格组件推荐 https://vxetable.cn 在前端开发中,表格组件是不可或缺的一部分,它们用于展示和管理数据,为用户提供了重要的数据交互功能。VxeTable 是一个优秀的 Vue 表格组件,它提供了丰富的功能和灵活的配置选项&…

linux上negix部署静态页面

1.看配置文件 进入cndf.d 这里的是配置部署项目中的文件 进入一个查看下 上面的是服务的域名,服务是http://test.fun-med.cn/#/,后面加服务名(你的前端) 2.看下页面位置 和上面的路径要匹配

IDEA工具的 CTRL + Shift + F 全局搜索失效

失效原因:快捷键冲突,与输入法默认的简繁体切换快捷键冲突了。 解决方式: 1、微软输入法 1.1 、任务栏 – 微软任务 – 语言首选项 1.2、微软拼音 – 选项 1.3、按键 – 热键(简体/繁体中文输入切换)关闭或修改 …

华为云CodeArts Check代码检查插件(VSCode IDE版本)使用指南

CodeArts Check VSCode IDE代码检查插件 本插件致力于守护开发人员代码质量,成为开发人员的助手和利器。秉承极简、极速、即时看护的理念,提供业界规范(含华为云)的检查、代码风格一键格式化及代码自动修复功能。 感兴趣的小伙伴…

并网型虚拟同步发电机控制仿真(Matlabsimulink仿真实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

【Python_PyQtGraph 学习笔记(八)】基于PyQtGraph将X轴坐标设置为系统时间

【Python_PyQtGraph 学习笔记(八)】基于PyQtGraph将X轴坐标设置为系统时间 前言正文1、获取plotItem的bottom轴对象2、设置刻度值,即获取时间3、刻度值与显示数值绑定4、设置bottom轴的刻度数值显示前言 基于PySide2、PyQtGraph和PySide2动态绘图,将X轴坐标设置为系统事件…

Linux 实践项目之论坛搭建

目录 一、思路 1、环境搭建(lamp--Linux apache mysql php ) 2、关闭防火墙SELinux启动服务 3、将论坛源代码上传至/var/www/html路径下 4、设置MySQL数据库名称和密码 5、浏览器上搭建Discuz论坛 二、实操 1、安装 2、关闭防火墙SELinux启动服务…

Activiti工作流引擎详解与应用

一、简介 Activiti是一个开源的工作流引擎,基于BPMN2.0标准进行流程定义。它可以将业务系统中复杂的业务流程抽取出来,使用专门的建模语言BPMN2.0进行定义,业务流程按照预先定义的流程进行执行,实现了系统的流程由Activiti进行管…

第三节:AntDisgn安装与导入

AntDisgn官网 1.安装:npm install -g vue/cli或者 yarn global add vue/cli 2.导入(我这进行的是全局使用在main.js里边进行配置) import { createApp } from vue import ./style.css import App from /App.vue import router from /router/index 导入路由 import …

18369-2022 玻璃纤维无捻粗纱 课堂随笔

声明 本文是学习GB-T 18369-2022 玻璃纤维无捻粗纱.pdf而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本文件规定了玻璃纤维无捻粗纱(以下简称"无捻粗纱")的分类和标记、技术要求、试验方法、检验 规则、标志、包装、运输和储存。…

unity脚本_MonoBehaviour c#

在MonoBehaviour里可以获取: 自己物体身上的属性 和 位置 及 其他类物体身上的属性 和 位置 this.gameObject.属性 this.transform.position this.transform.eulerAngles this.transform.lossyScale 如果是其他类 需要创建一个类对象 然后用类对象去 点 另外…

DRM全解析 —— encoder详解(1)

本文参考以下博文: Linux内核4.14版本——drm框架分析(3)——encoder分析 特此致谢! 1. 简介 encoder是编码器/输出转换器,负责将CRTC输出的timing时序转换成外部设备所需要的信号,如HDMI转换器或DSI Controller。 具体来讲&a…

【生成模型】解决生成模型面对长尾类型物体时的问题 RE-IMAGEN: RETRIEVAL-AUGMENTED TEXT-TO-IMAGE GENERATOR

介绍 尽管最先进的模型可以生成常见实体的高质量图像,但它们通常难以生成不常见实体的图像,例如“Chortai(狗)”或“Picarones(食物)”。为了解决这个问题,我们提出了检索增强文本到图像生成器…

超实用的蓄电池小技巧,不会用就太可惜了!

蓄电池在现代社会中扮演着重要的角色,用于供电备份、电动交通工具、可再生能源储存等各种应用。然而,蓄电池的性能监控和维护管理对于确保其可靠性和寿命至关重要。 随着科技的不断进步,蓄电池监控系统成为了一种关键工具,帮助用户…

3D目标检测:DFA3D: 3D Deformable Attention For 2D-to-3D Feature Lifting

论文作者:Hongyang Li,Hao Zhang,Zhaoyang Zeng,Shilong Liu,Feng Li,Tianhe Ren,Lei Zhang 作者单位:South China University of Technology; The Hong Kong University of Science and Technology; International Digital Economy Academy (IDEA); Ts…

大数据软件项目的数据清洗

大数据软件项目中的数据清洗是数据预处理过程中的重要环节,用于识别和纠正数据集中的错误、不一致性和不完整性。虽然没有专门的"数据清洗开发框架",但有许多工具和库可用于数据清洗任务。以下是一些常见的数据清洗工具和库,可以与…