Transformer 位置编码

✅作者简介:人工智能专业本科在读,喜欢计算机与编程,写博客记录自己的学习历程。
🍎个人主页:小嗷犬的个人主页
🍊个人网站:小嗷犬的技术小站
🥭个人信条:为天地立心,为生民立命,为往圣继绝学,为万世开太平。


本文目录

    • Transformer
    • 位置编码
      • 什么是位置编码以及为什么需要位置编码
      • Transformer 中的位置编码
      • 直观理解
      • 位置编码如何结合到词向量中
      • 相对位置
    • 其他问题
      • 为什么位置编码与词向量结合是使用相加而不是连接
      • 位置编码信息如何传递到模型深层
      • 为什么要同时使用正弦和余弦函数


Transformer

Attention Is All You Need 是 Google 于 2017 年发表的论文,这篇论文提出了一种新的神经网络架构: Transformer,它完全摒弃了传统的 CNN 和 RNN 结构,基于 Attention 机制来实现 Seq2Seq 的建模。

Transformer 的出现是人工智能领域的重大突破,它不仅在机器翻译任务上取得了 SOTA 的效果,而且在其他 NLP 任务上也有着非常好的表现,后续更是被广泛应用于 CV 领域。

位置编码

本文主要介绍 Transformer 中的位置编码,它是 Transformer 中非常重要的一部分。

Transformer 结构

什么是位置编码以及为什么需要位置编码

词的位置和顺序是任何语言的重要组成部分。它们决定着语法,因此也决定了句子的实际语义。

卷积神经网络(CNN)使用卷积核来捕获单词之间的相对位置信息,但其仅能捕获固定大小的局部上下文信息。

循环神经网络(RNN)在处理序列信息上会有更好的效果,其依靠循环结构,将序列信息逐步传递,这其中就引入了单词的位置和顺序信息。但随着序列长度的增加,RNN 会慢慢忘记早前的信息,这就导致了长期依赖问题。除此之外,循环结构也使得 RNN 无法并行计算,这使得 RNN 的训练速度十分缓慢。

Transformer 放弃了循环结构,而采用了自注意力机制,这使得 Transformer 可以并行计算,从而大大提高了训练速度。同时,自注意力机制也使得 Transformer 可以捕获任意距离的依赖关系,从而解决了长期依赖问题。

但由于 Transformer 不包含任何循环结构,各个单词在 Transformer 中都同时经过 Decoder-Encoder 的变换,这就导致了 Transformer 无法捕获单词的位置信息
为了解决这个问题,我们需要在输入的单词向量中加入某种信息,以区分每个单词的位置。这一信息被称为位置编码

一个简单的想法是:我们可以将单词的位置信息映射到 [ 0 , 1 ] [0,1] [0,1] 的范围上,第一个单词的位置信息为 0 0 0,最后一个单词的位置信息为 1 1 1,中间的单词按照固定间隔均匀分配。但这显然会带来一个问题,即在不同长度的句子中,单词位置信息的间隔不统一

另一个容易想到的做法是:我们可以线性地为单词分配位置编号,第一个单词为 1 1 1,第二个单词为 2 2 2,以此类推。显然,这样可能会导致位置编码在数值上很大,并且模型可能会在后续遇到更长的句子,这其中包含了模型在训练中从未遇见过的位置编号,这可能会影响模型的泛化能力

因此,一个好的位置编码方式通常需要满足以下条件:

  • 它应当为每个时间步(单词在句子中的位置)输出唯一编码
  • 在不同长度的句子中,任何两个时间步之间的距离都应保持一致
  • 这个方法应当能够推广到任意长的句子,即位置编码的数值应当是有界
  • 位置编码应当是确定的,即对于相同长度的输入,应当输出相同的位置编码

Transformer 中的位置编码

Transformer 中的位置编码方式满足上述所有条件,是一种简单而有效的位置编码方式。它没有为每个时间步输出单一的数字,而是为每个时间步输出一个 d 维向量,这个向量的维度与 Transformer 的词向量维度相同,这个向量被加到输入的单词向量中,从而为单词向量添加了位置信息。

t t t 为单词在句子中的位置, p t ⃗ ∈ R d \vec{p_t} \in \mathbb{R}^d pt Rd 为其对应的位置编码, d d d 为位置编码的维度, d ≡ 0 ( m o d    2 ) d \equiv 0 (\mod 2) d0(mod2),则函数 f : N → R d f : \mathbb{N} \rightarrow \mathbb{R}^d f:NRd 即为位置编码函数,其定义如下:

p t ⃗ ( i ) = f ( t ) ( i ) : = { sin ⁡ ( ω k . t ) , if  i = 2 k cos ⁡ ( ω k . t ) , if  i = 2 k + 1 \begin{align*} \vec{p_t}^{(i)} = f(t)^{(i)} & := \begin{cases} \sin({\omega_k} . t), & \text{if}\ i = 2k \\ \cos({\omega_k} . t), & \text{if}\ i = 2k + 1 \end{cases} \end{align*} pt (i)=f(t)(i):={sin(ωk.t),cos(ωk.t),if i=2kif i=2k+1

其中

ω k = 1 1000 0 2 k / d \omega_k = \frac{1}{10000^{2k / d}} ωk=100002k/d1

从定义中我们可以看出三角函数的频率 ω k \omega_k ωk 沿着向量维度不断减小,因此它的波长形成了一个 2 π 2 \pi 2π 10000 ⋅ 2 π 10000 \cdot 2 \pi 100002π 的等比数列。

对于第 t t t 个单词的位置编码 p t ⃗ \vec{p_t} pt ,可以看成由不同频率的正弦余弦对组成的向量( d d d 为偶数):

p t ⃗ = [ sin ⁡ ( ω 1 . t ) cos ⁡ ( ω 1 . t ) sin ⁡ ( ω 2 . t ) cos ⁡ ( ω 2 . t ) ⋮ sin ⁡ ( ω d / 2 . t ) cos ⁡ ( ω d / 2 . t ) ] d × 1 \vec{p_t} = \begin{bmatrix} \sin({\omega_1}.t)\\ \cos({\omega_1}.t)\\ \\ \sin({\omega_2}.t)\\ \cos({\omega_2}.t)\\ \\ \vdots\\ \\ \sin({\omega_{d/2}}.t)\\ \cos({\omega_{d/2}}.t) \end{bmatrix}_{d \times 1} pt = sin(ω1.t)cos(ω1.t)sin(ω2.t)cos(ω2.t)sin(ωd/2.t)cos(ωd/2.t) d×1

直观理解

你可能会想知道为什么要用不同频率的正弦余弦对的组合来编码位置信息?

其实这是一个很简单的想法,考虑用二进制编码来表示一个数字的情况:

0 :      0    0    0    0 8 :      1    0    0    0 1 :      0    0    0    1 9 :      1    0    0    1 2 :      0    0    1    0 10 :      1    0    1    0 3 :      0    0    1    1 11 :      1    0    1    1 4 :      0    1    0    0 12 :      1    1    0    0 5 :      0    1    0    1 13 :      1    1    0    1 6 :      0    1    1    0 14 :      1    1    1    0 7 :      0    1    1    1 15 :      1    1    1    1 \begin{align*} 0: \ \ \ \ \color{orange}{\texttt{0}} \ \ \color{green}{\texttt{0}} \ \ \color{blue}{\texttt{0}} \ \ \color{red}{\texttt{0}} & & 8: \ \ \ \ \color{orange}{\texttt{1}} \ \ \color{green}{\texttt{0}} \ \ \color{blue}{\texttt{0}} \ \ \color{red}{\texttt{0}} \\ 1: \ \ \ \ \color{orange}{\texttt{0}} \ \ \color{green}{\texttt{0}} \ \ \color{blue}{\texttt{0}} \ \ \color{red}{\texttt{1}} & & 9: \ \ \ \ \color{orange}{\texttt{1}} \ \ \color{green}{\texttt{0}} \ \ \color{blue}{\texttt{0}} \ \ \color{red}{\texttt{1}} \\ 2: \ \ \ \ \color{orange}{\texttt{0}} \ \ \color{green}{\texttt{0}} \ \ \color{blue}{\texttt{1}} \ \ \color{red}{\texttt{0}} & & 10: \ \ \ \ \color{orange}{\texttt{1}} \ \ \color{green}{\texttt{0}} \ \ \color{blue}{\texttt{1}} \ \ \color{red}{\texttt{0}} \\ 3: \ \ \ \ \color{orange}{\texttt{0}} \ \ \color{green}{\texttt{0}} \ \ \color{blue}{\texttt{1}} \ \ \color{red}{\texttt{1}} & & 11: \ \ \ \ \color{orange}{\texttt{1}} \ \ \color{green}{\texttt{0}} \ \ \color{blue}{\texttt{1}} \ \ \color{red}{\texttt{1}} \\ 4: \ \ \ \ \color{orange}{\texttt{0}} \ \ \color{green}{\texttt{1}} \ \ \color{blue}{\texttt{0}} \ \ \color{red}{\texttt{0}} & & 12: \ \ \ \ \color{orange}{\texttt{1}} \ \ \color{green}{\texttt{1}} \ \ \color{blue}{\texttt{0}} \ \ \color{red}{\texttt{0}} \\ 5: \ \ \ \ \color{orange}{\texttt{0}} \ \ \color{green}{\texttt{1}} \ \ \color{blue}{\texttt{0}} \ \ \color{red}{\texttt{1}} & & 13: \ \ \ \ \color{orange}{\texttt{1}} \ \ \color{green}{\texttt{1}} \ \ \color{blue}{\texttt{0}} \ \ \color{red}{\texttt{1}} \\ 6: \ \ \ \ \color{orange}{\texttt{0}} \ \ \color{green}{\texttt{1}} \ \ \color{blue}{\texttt{1}} \ \ \color{red}{\texttt{0}} & & 14: \ \ \ \ \color{orange}{\texttt{1}} \ \ \color{green}{\texttt{1}} \ \ \color{blue}{\texttt{1}} \ \ \color{red}{\texttt{0}} \\ 7: \ \ \ \ \color{orange}{\texttt{0}} \ \ \color{green}{\texttt{1}} \ \ \color{blue}{\texttt{1}} \ \ \color{red}{\texttt{1}} & & 15: \ \ \ \ \color{orange}{\texttt{1}} \ \ \color{green}{\texttt{1}} \ \ \color{blue}{\texttt{1}} \ \ \color{red}{\texttt{1}} \\ \end{align*} 0:    0  0  0  01:    0  0  0  12:    0  0  1  03:    0  0  1  14:    0  1  0  05:    0  1  0  16:    0  1  1  07:    0  1  1  18:    1  0  0  09:    1  0  0  110:    1  0  1  011:    1  0  1  112:    1  1  0  013:    1  1  0  114:    1  1  1  015:    1  1  1  1

可以看到每个位置的比特都在以特定的频率周期性变化,最低位每过一个数字就会变化一次,次低位每过两个数字就会变化一次,依次类推。

对于浮点数空间,使用二进制编码是极其浪费的。因此我们可以使用更适合浮点数空间的三角函数来引入周期性。在位置编码中,正弦余弦函数相当于二进制编码中的比特位,通过改变它们的频率,我们相当于控制了不同的比特位。

一个长度为 50 的句子的 128 维正弦编码

位置编码如何结合到词向量中

在 Transformer 中,位置编码是通过加法的方式结合到词向量中的,即对于一个句子 [ w 1 , . . . w n ] [w_1,...w_n] [w1,...wn] 中的第 t t t 个单词 w t w_t wt,Transformer 的输入为:

ψ ′ ( w t ) = ψ ( w t ) + p t ⃗ \begin{align*} \psi^\prime(w_t) = \psi(w_t) + \vec{p_t} \end{align*} ψ(wt)=ψ(wt)+pt

其中 ψ ( w t ) \psi(w_t) ψ(wt) 为单词 w t w_t wt 的词向量, p t ⃗ \vec{p_t} pt 为单词 w t w_t wt 的位置编码。

由上式可知,位置编码的维度 d d d 必须与词向量的维度相同,这样才能保证它们可以相加。

相对位置

正弦位置编码的另一个特点是,它能让模型更加轻松地捕捉到相对位置信息。下面是原论文中的一段话:

We chose this function because we hypothesized it would allow the model to easily learn to attend by relative positions, since for any fixed offset k k k, P E p o s + k PE_{pos+k} PEpos+k can be represented as a linear function of P E p o s PE_{pos} PEpos.

即对于任意固定的偏移量 k k k,位置编码 P E p o s + k PE_{pos+k} PEpos+k 总能被 P E p o s PE_{pos} PEpos 线性表示。

笔者水平有限,在这里就不进行证明了。

除此之外,正弦位置编码的另一个特点是,相邻时间步长之间的距离是对称的(正弦位置编码对距离的衡量是无向的),即 P E p o s ⋅ P E p o s + k = P E p o s ⋅ P E p o s − k PE_{pos} \cdot PE_{pos+k} = PE_{pos} \cdot PE_{pos-k} PEposPEpos+k=PEposPEposk

所有时间步位置编码的点积

其他问题

为什么位置编码与词向量结合是使用相加而不是连接

首先,连接位置编码与词向量会提高输入的维度,这将提高模型的参数量

其次,从前文的图中可以看出,位置编码的信息并不是均匀分布于每个维度之上,而是几乎所有的位置信息都分布在较低的维度之内(在原文中,词向量的维度为 512 512 512 维)。由于 Transformer 的 Word Embedding 层是重新训练的,因此可能 Word Embedding 层在训练过程中根本没有往靠前维度存储语义信息,以免干扰位置编码。在这种情况下, 512 512 512 维的位置编码与 512 512 512 维的词向量相加似乎就等价 x x x 维的位置编码与 512 − x 512-x 512x 维的词向量连接。

位置编码信息如何传递到模型深层

理论上,位置编码信息在经过自注意力机制层或者前馈神经网络层后,就会被丢失。但 Transformer 为各个网络层添加了残差连接,这使得位置编码信息可以通过残差链接来逐步传递到模型的深层。

为什么要同时使用正弦和余弦函数

只有同时使用正弦和余弦函数才能将 sin ⁡ ( x + k ) \sin(x+k) sin(x+k) cos ⁡ ( x + k ) \cos(x+k) cos(x+k) 表示为 sin ⁡ ( x ) \sin(x) sin(x) cos ⁡ ( x ) \cos(x) cos(x) 的线性变换,即位置编码 P E p o s PE_{pos} PEpos 一定要包含正弦和余弦函数才能线性表示 P E p o s + k PE_{pos+k} PEpos+k,这对模型捕获相对位置信息具有很大的帮助。

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

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

相关文章

中仕公考:2024年度国考笔试分数公布,进面名单已出

2024年度考试录用公务员笔试成绩和合格分数线已经公布,考生们可以自行登录公务员专题网站查询成绩。 进面人员名单根据规定的面试比例,按照笔试成绩从高至低的顺序,1月14日已经公布进面名单。 没有进入面试人员名单的考生可以关注调剂&…

面试Java岗老喜欢盯着JVM问,有那么多项目要调优吗?

面试Java岗老喜欢盯着JVM问,有那么多项目要调优吗? 在开始前我有一些资料,是我根据网友给的问题精心整理了一份「Java的资料从专业入门到高级教程」, 点个关注在评论区回复“888”之后私信回复“888”,全部无偿共享给…

Qt 快捷键设置

以 “在编辑时自动补齐”快捷键 为例: 位置:红色 搜索快捷键:蓝色 修改方式:绿色 快捷键:黄色

C++ 类的静态成员

我们可以使用 static 关键字来把类成员定义为静态的。当我们声明类的成员为静态时,这意味着无论创建多少个类的对象,静态成员都只有一个副本。 静态成员在类的所有对象中是共享的。如果不存在其他的初始化语句,在创建第一个对象时&#xff0…

内存泄漏检测方式

一 、 日志记录 通过宏定义重载了 malloc 和 free 函数,以在分配和释放内存的时候记录一些信息,包括文件名和行号,并将这些信息写入到相应的文件中。然后在 main 函数中演示了使用这些宏进行内存分配和释放。 _malloc 函数: 在分配…

【Frontiers】“神仙期刊”,JCR1区,发文量3000+,录用率75%,1-2个月录用!

发表说 截图来源:LetPub 01 期刊概况 Frontiers in Endocrinology 【出版社】Frontiers Media S.A. 【ISSN】1664-2392 【检索情况】SCI&Scopus双检 【WOS收录年份】2012年 【期刊官网】 https://www.frontiersin.org/journals/endocrinology 【投稿系统…

【电商API】DIY网络爬虫收集电商数据

DIY网络爬虫收集电商数据 网络爬虫是最常见和使用最广泛的数据收集方法。DIY网络爬虫确实需要一些编程知识,但整个过程比一开始看起来要简单得多。 当然,爬虫的有效性取决于许多因素,例如目标的难度、网站方的反爬虫措施等。如果将网络抓取用…

为啥4位单片机那么LOW,还没被淘汰?

我以为8位的51单片机已经够低端了,没想到竟然还有4位单片机!它到底有什么优势?用在什么领域? 在刚开始学习单片机的时候,我一直以为用越高端的芯片就越牛逼。 而现实,公司做产品和我们单片机学习者&#xf…

人工智能专业必须需要考哪些证书呢?

我们来看看2024年人工智能专业的企业和个人都在紧张报考的两项AI认证证书报考: 为进一步贯彻落实中共中央印发《关于深化人才发展体制机制改革的意见》和国务院印发《关于“十四五”数字经济发展规划》等有关工作的部署要求,深入实施人才强国战略和创新驱…

两整数之和

题目链接 两整数之和 题目描述 注意点 不使用 运算符 和 - ​​​​​​​&#xff0c;计算并返回两整数之和-1000 < a, b < 1000 解答思路 需要用位运算来模拟加法&#xff0c;关键是要找到相加的和以及进位1的部分。如果不考虑进位的话&#xff0c;相加可以运用异…

30天精通Nodejs--第十七天:express-路由配置

目录 引言基础路由配置路由参数与查询参数路由前缀与子路由路由重定向结语 引言 上篇文章我们简单介绍了express的基础用法&#xff0c;包括express的安装、创建路由及项目启动&#xff0c;对express有了一个基础的了解&#xff0c;这篇开始我们将详细介绍express的一些高级用…

PlatformIO中ESP8266使用GxEPD库和U8G2库驱动 2.9寸黑白墨水屏显示中文

Content 0. 前言1. 安装platformIO环境2. 新建工程3. 添加外部库4. 修改U8g2_for_Adafruit_GFX库5. 代码和烧录 0. 前言 墨水屏是黄鱼淘的&#xff0c;效果还不错。 U8G2库一直编译不进去&#xff0c;显示汉字始终不太美观&#xff0c;个人一直不太喜欢汉字取模的方法&#x…

字节、字符与字符编码的区别与联系

字节、字符与字符编码的区别与联系 字节 位(bit)是计算机中信息的最小单元。位是由电路实现的&#xff0c;硬件底层使用数字电路&#xff0c;以电压的高低作为记录信息的方式&#xff1a;较高的电压表示数值“1”&#xff0c;较低的电压表示数字“0”。因此&#xff0c;一个位…

微信预约挂号系统源码,公众服务号(小程序)预约挂号,适用于各级公立和民营医院,用来搭建互联网医院平台,可对接院内his、lis、pacs系统

掌上智慧医院、公众服务号&#xff08;小程序&#xff09;预约挂号、互联网平台源码 系统介绍 “移动智慧医院”平台既可以让患者足不出户就可以利用微信进行在线挂号&#xff0c;实现分时段就诊&#xff0c;就诊后也可以直接使用手机微信缴费&#xff0c;还可以通过微信实现查…

NFS网络共享存储服务技术攻略

目录 一.NFS 1.定义 2.特点 3.原理 二.服务端NFS配置文件 1.主配置文件 2.文件格式 3.相关命令 三.实验&#xff1a;NFS共享存储服务配置 1.服务端安装nfs-utils和rpcbind软件包 2.服务端新建共享目录给权限 3.服务端修改配置文件/etc/exports 4.服务端关闭防火墙…

FlinkAPI开发之水位线(Watermark)

案例用到的测试数据请参考文章&#xff1a; Flink自定义Source模拟数据流 原文链接&#xff1a;https://blog.csdn.net/m0_52606060/article/details/135436048 Flink中的时间语义 哪种时间语义更重要 从《星球大战》说起 数据处理系统中的时间语义 在实际应用中&#xff0c…

CC工具箱使用指南:【获取所有字段信息】

一、简介 这个工具的目的简单易懂&#xff0c;就是获取选定要素图层的所有字段信息。 本身不对要素图层作任何处理&#xff0c;只是一个查看属性的工具。 问我要用在什么地方&#xff0c;我也不知道-_- 二、工具参数介绍 点击【信息获取】组里的【获取所有字段信息】工具&a…

解决flask中jinja2插值变量变成字符串的办法

今天在通过使用{{ variable_name }}这种方式插入html内容时&#xff0c;发现变量内容到了页面中全部变成了字符串&#xff0c; python代码&#xff1a; return render_template(FilePath.file_path_to_page,md_contenthtml_content # 返回html内容 )html代码中插入&#xff1…

【运维杂谈】为什么docker镜像推送至harbor上就变小了?

为什么docker镜像推送至harbor上就变小了&#xff1f;我们以一个游戏镜像为例&#xff0c;在Linux显示295MB。 [rootWorker232 ~]# docker images | grep v0.6 harbor.koten.com/koten-games/games v0.6 30ec3e6e4747 25 hours ago 295MB […

C# Cad2016二次开发HelloWorld(一)

1 新建类库 二 引用 acdbmgd.dll、acmgd.dll、accoremgd.dll 三 HelloWorld代码 public class Class1{/// <summary>/// 程序入口标识/// </summary>[CommandMethod("HelloWorld")]public void HelloWorld(){Document adoc Autodesk.AutoCAD.Applicatio…