Transformer原理理解

本文介绍Transformer的基本原理,主要记录一下自己的学习过程。

 

论文:https://arxiv.org/abs/1706.03762

参考:

  1. http://jalammar.github.io/illustrated-transformer/
  2. https://zhuanlan.zhihu.com/p/338817680
  3. https://blog.csdn.net/longxinchen_ml/article/details/86533005

主要参考了链接1中的内容,链接3是其翻译版本。

Transformer架构完全依赖于Attention机制,解决了输入输出的长期依赖问题,并且拥有并行计算的能力。整体结构如下图所示:

结构分四个部分:输入、encoder、decoder、输出

输入

这里说的是encoder的输入,Transformer输入是一个序列数据,在NLP中,Encoder 的 inputs就是分词后的词向量。可以是任意形式的词向量,如word2vec,GloVe,one-hot编码。

输入embedding后需要给每个word的词向量添加位置编码positional encoding,为什么需要添加位置编码呢?

因为一句话中,如果词语出现位置不同,意思可能发生变化。但是Transformer 的是完全基于self-Attention地,而self-attention是不能获取词语位置信息的,就算打乱一句话中词语的位置,每个词还是能与其他词之间计算attention值。

图片来自参考2:https://zhuanlan.zhihu.com/p/338817680

positional encoding怎么获取

1.可以通过数据训练学习得到positional encoding,类似于训练学习词向量,Google在之后的bert中的positional encoding便是由训练得到地。

2.《Attention Is All You Need》论文中Transformer使用的是正余弦位置编码。位置编码通过使用不同频率的正弦、余弦函数生成,然后和对应的位置的词向量相加,位置向量维度和词向量的维度一致。过程如上图,PE(positional encoding)计算公式如下:

为什么使用正余弦位置编码? 

可以看出,对于 pos+k 位置的位置向量某一维 2i 或 2i+1 而言,可以表示为,pos 位置与 k 位置的位置向量的2i 与 2i+1维的线性组合,这样的线性组合意味着位置向量中蕴含了相对位置信息。

Encoder

编码器部分包括Multi-Head Attention、Add&Norm和Feed Forward,下面分别介绍。

Multi-Head Attention

  上图右侧就是 Multi-Head Attention部分,其中h代表有h个head,每个head部分的注意力计算,就是上图中左侧的过程。

其中Q、K、V是输入通过参数运算得到的:

假如输入X维度是(4,512),权重W的维度是(512,64),得到的Q、K、V的维度就是(4,64)。

得到Q,K,V之后,接下来就是计算Attention值了。

 

示例:

用当前词的q向量和所有的k向量计算点积,得到一个得分,这个得分意味着,我们在编码当前词的时候,需要在其他位置的词上集中多少的注意力。

 

之后将得分先除以8(\sqrt{_{d_k}},q维度的平方根),再经过softmax进行归一化。

为什么要进行scale?

假设向量 q 和 k的各个分量是互相独立的随机变量,均值是0,方差是1,那么$$ q.k$$的均值为0,方差为$$d_k$$,方差较大时,$$ q.k$$的值会处于softmax的梯度平缓的区域,除以\sqrt{_{d_k}}之后,可以使方差为1。

然后将结果和v向量进行加权求和。 

 

通过增加一种叫做“多头”注意力(“multi-headed” attention)的机制,论文进一步完善了自注意力层,并在两方面提高了注意力层的性能:

1.它扩展了模型专注于不同位置的能力。在上面的例子中,虽然每个编码都在z1中有或多或少的体现,但是它可能被实际的单词本身所支配。如果我们翻译一个句子,比如“The animal didn’t cross the street because it was too tired”,我们会想知道“it”指的是哪个词,这时模型的“多头”注意机制会起到作用。

2.它给出了注意力层的多个“表示子空间”(representation subspaces)。接下来我们将看到,对于“多头”注意机制,我们有多个查询/键/值权重矩阵集(Transformer使用八个注意力头,因此我们对于每个编码器/解码器有八个矩阵集合)。这些集合中的每一个都是随机初始化的,在训练之后,每个集合都被用来将输入词嵌入(或来自较低编码器/解码器的向量)投影到不同的表示子空间中。

计算公式:

将八个输出矩阵压缩成一个输出矩阵: 

 

整个Multi-Head Attention 模块的过程合并如下: 

Multi-Head Attention 输出的矩阵Z与其输入的矩阵X的维度是一样的。

Add&Norm

在每个编码器中的每个子层(自注意力、前馈网络)的周围都有一个残差连接,并且都跟随着一个“层归一化”步骤。残差连接参考的是resnet网络。

Position-wise Feed-Forward Networks

 

全连接层是一个两层的神经网络,先线性变换,然后ReLU非线性,再线性变换。

X是输入,Feed Forward 最终得到的输出矩阵的维度与X一致。

通过上面描述的 Multi-Head Attention,Add & Norm,Feed Forward,就可以构造出一个 Encoder block,Encoder block 接收输入矩阵 X(n×d) ,并输出一个矩阵 O(n×d) 。通过多个 Encoder block 叠加就可以组成 Encoder。

第一个 Encoder block 的输入为句子单词的表示向量矩阵,后续 Encoder block 的输入是前一个 Encoder block 的输出,最后一个 Encoder block 输出的矩阵就是编码信息矩阵 C,这一矩阵后续会用到 Decoder 中。

Decoder

此部分来自参考2:https://zhuanlan.zhihu.com/p/338817680

Decoder block 结构,与 Encoder block 相似,但是存在一些区别:

  • 包含两个 Multi-Head Attention 层。
  • 第一个 Multi-Head Attention 层采用了 Masked 操作。
  • 第二个 Multi-Head Attention 层的K, V矩阵使用 Encoder 的编码信息矩阵C进行计算,而Q使用上一个 Decoder block 的输出计算。
  • 最后有一个 Softmax 层计算下一个翻译单词的概率。

Masked Multi-Head Attention

Decoder block 的第一个 Multi-Head Attention 采用了 Masked 操作,因为在翻译的过程中是顺序翻译的,即翻译完第 i 个单词,才可以翻译第 i+1 个单词。通过 Masked 操作可以防止第 i 个单词知道 i+1 个单词之后的信息。下面以 "我有一只猫" 翻译成 "I have a cat" 为例,了解一下 Masked 操作。

Decoder 可以在训练的过程中并行化训练,即将正确的单词序列 (<Begin> I have a cat) 和对应输出 (I have a cat <end>) 传递到 Decoder。那么在预测第 i 个输出时,就要将第 i+1 之后的单词掩盖住,注意 Mask 操作是在 Self-Attention 的 Softmax 之前使用的,下面用 0 1 2 3 4 5 分别表示 "<Begin> I have a cat <end>"。

第一步:是 Decoder 的输入矩阵和 Mask 矩阵,输入矩阵包含 "<Begin> I have a cat" (0, 1, 2, 3, 4) 五个单词的表示向量,Mask 是一个 5×5 的矩阵。在 Mask 可以发现单词 0 只能使用单词 0 的信息,而单词 1 可以使用单词 0, 1 的信息,即只能使用之前的信息。

第二步:接下来的操作和之前的 Self-Attention 一样,通过输入矩阵X计算得到Q,K,V矩阵。 

第三步:在得到 QKT 之后需要进行 Softmax,计算 attention score,我们在 Softmax 之前需要使用Mask矩阵遮挡住每一个单词之后的信息,遮挡操作如下: 

得到 Mask QKT 之后在 Mask QKT上进行 Softmax,每一行的和都为 1。但是单词 0 在单词 1, 2, 3, 4 上的 attention score 都为 0。

第四步:使用 Mask QKT与矩阵 V相乘,得到输出 Z,则单词 1 的输出向量 Z1 是只包含单词 1 信息的。

第五步:通过上述步骤就可以得到一个 Mask Self-Attention 的输出矩阵 Zi ,然后和 Encoder 类似,通过 Multi-Head Attention 拼接多个输出Zi 然后计算得到第一个 Multi-Head Attention 的输出ZZ与输入X维度一样。

Multi-Head Attention

Decoder block 第二个 Multi-Head Attention 变化不大, 主要的区别在于其中 Self-Attention 的 K, V矩阵不是使用 上一个 Decoder block 的输出计算的,而是使用 Encoder 的编码信息矩阵 C 计算的。

根据 Encoder 的输出 C计算得到 K, V,根据上一个 Decoder block 的输出 Z 计算 Q (如果是第一个 Decoder block 则使用输入矩阵 X 进行计算),后续的计算方法与之前描述的一致。

这样做的好处是在 Decoder 的时候,每一位单词都可以利用到 Encoder 所有单词的信息 (这些信息无需 Mask)。

输出

Decoder 输出经过一个线性层,然后接softmax,得到输出概率,获取概率值最大的位置,其在词表中对应的单词即为预测结果(也可以采用beam search的方法得到预测结果)。

预测流程如下:

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

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

相关文章

复习第四课 C语言-分支语句和循环

目录 【1】字符输入输出 【2】C语言下的垃圾字符回收 【3】分支语句 【4】循环 练习&#xff1a; 【1】字符输入输出 按字符的输入输出 int getchar(void); 功能&#xff1a;从终端输入一个字符 参数&#xff1a;无 返回值&#xff1a;输入字符的ASCII值int putchar(int…

使用python get post数据 http https

0、目的 目的比较简单&#xff0c;测试&#xff0c;使用python来提交数据是非常简洁的&#xff0c;修改代码也容易&#xff0c;除了做人工智能&#xff0c;本身也是一个非常好的测试端工具 1、简单的post 一个简单的示例程序&#xff0c;将 headers 内容置为’application/j…

2023华为产品测评官-开发者之声 | 华为云CodeArts征文活动,多重好礼邀您发声!

"2023华为产品测评官&#xff0d;开发者之声"活动激发了众多开发者和技术爱好者的热情&#xff0c;他们纷纷递交了精心编写的产品测评报告。活动社群充满活力&#xff0c;参与者们热衷于交流讨论&#xff0c;互相帮助解决问题&#xff0c;一起探索云技术的无限可能。…

【机器人模拟-02】 模拟移动机器人设置里程计

一、说明 在本教程中,我将向您展示如何设置移动机器人的测程。本教程是“机器人模拟”指南中的第二个教程。测量位移是仿真中的重要内容,设置测程的官方教程在此页面上,但我将逐步引导您完成整个过程。 您可以在此处获取此项目的完整代码。让我们开始吧! 二、ROS 2 中的里程…

最火爆的大模型框架LangChain七大核心及案例剖析上(三)

最火爆的大模型框架LangChain七大核心及案例剖析上 10.6 GPT内容创建者案例详细剖析 我们回到“LangChain GPT内容创建者”案例,一行一行的解析代码,为了更好的看这个代码,先看一下它具体执行的整个日志过程,然后再看一下代码的部分。 首先,在控制台执行脚本,启动web页面…

微信小程序(二)

目录 1、input标签 一、表单绑定 1、数据绑定 2、输入获取 二、网络请求 1、介绍 2、注意 3、使用 4、基于Promise封装 三、自定义组件 1、创建 2、父向子组件通信 3、子向父组件通信 4、生命周期 四、vant weapp组件库 1、配置 2、使用 进入本章前的拓展&#…

用ChatGPT解析Wireshark抓取的数据包样例

用Wireshark抓取的数据包&#xff0c;常用于网络故障排查、分析和应用程序通信协议开发。其抓取的分组数据结果为底层数据&#xff0c;看起来比较困难&#xff0c;现在通过chatGPT大模型&#xff0c;可以将原始抓包信息数据提交给AI进行解析&#xff0c;本文即是进行尝试的样例…

河钢数字项目管理部负责人杨笑瑾受邀为第十二届中国PMO大会演讲嘉宾

河钢数字技术股份有限公司项目管理部负责人杨笑瑾女士受邀为由PMO评论主办的2023第十二届中国PMO大会演讲嘉宾&#xff0c;演讲议题&#xff1a;项目群管理赋能组织变革。大会将于8月12-13日在北京举办&#xff0c;敬请关注&#xff01; 议题简要&#xff1a; 谈到组织变革自然…

DynaSLAM代码详解(5) — Tracking.cc跟踪线程

目录 5.1 DynaSLAM中Tracking线程简介 5 .2 RGBD模式下跟踪流程 5.3 DynaSLAM的低成本跟踪 (1) Tracking::LightTrack() 低成本跟踪函数 (2) Tracking::LightTrackWithMotionModel() 低成本的恒速模型跟踪流程 5.4 DynaSLAM的正常跟踪 文章着重将与ORB-SLAM2不同的地方&a…

SpringBoot2+Vue2实战(十八)修改密码

一、修改密码&#xff1a; Header.vue <el-dropdown-item style"font-size: 14px; padding: 5px 0"><router-link to"/password" style"text-decoration: none">修改密码</router-link></el-dropdown-item> router/i…

Kafka 深度剖析

1、应用场景 1.1 kafka场景 Kafka最初是由LinkedIn公司采用Scala语言开发&#xff0c;基于ZooKeeper&#xff0c;现在已经捐献给了Apache基金会。目前Kafka已经定位为一个分布式流式处理平台&#xff0c;它以 高吞吐、可持久化、可水平扩展、支持流处理等多种特性而被广泛应用…

牛客HJ99 - 自守数【暴力 + 换位取模】

原题传送门 原题描述 首先我们来看一下原题是怎么描述的&#xff0c;题面很简单&#xff0c;输入n&#xff0c;然后让我们去统计从1 ~ n之间的自守数有几个&#xff0c;那什么是【自守数】呢&#xff0c;上面也说到了&#xff0c;即一个数在平方之后该数的尾数等于该数自身的自…