一文讲解Transformer

news2024/11/27 10:27:43

我们本篇文章来详细讲解Transformer:

首次提出在:Attention is all you need (arxiv.org)

简单来说,Transfomer就是一种Seq2seq结构,它基于多头自注意力机制,解决了传统RNN在计算过程中不能够并行化的问题。即相较于RNN而言,Transfomer所采用的多头自注意力机制更快,因为,对于每个单词(即被分割的每个单位),它可以并行计算。而不是向传统RNN那样,必须要在前面的单词(特征)计算出来之后,才可以对后面的单词(特征)进行计算。

对于Transformer的整体结构而言,它可以分成两块,即Encoder和Decoder,分别是编码器和解码器部分。在这两部分中,均采用了多头自注意力机制这样一个组件。

image-20230526002758625

如上图所示,左侧为Encoder,右侧为Decoder。

在Encoder中,先将inputs进行input Embedding(单词编码,可以有很多种方式,例如可以采用 Word2Vec、Glove 等算法预训练得到,也可以在 Transformer 中训练得到)。

紧接着进行位置编码(Positional Encoding),它的目的是为了防止该模型结构变成了一个词袋模型。因为从后面的介绍将会看出,自注意力机制所计算出来的结果是和位置无关的。具体来说,将输入的向量a加上一个向量e,也即位置编码。这个e是认为计算出来的。通常采用正弦位置编码方案。

P E ( p o s , 2 i ) = s i n ( p o s / 1000 0 2 i / d ) PE_{(pos,2i)}=sin(pos/10000^{2i/d}) PE(pos,2i)=sin(pos/100002i/d)

P E ( p o s , 2 i + 1 ) = c o s ( p o s / 1000 0 2 i / d ) PE_{(pos,2i+1)}=cos(pos/10000^{2i/d}) PE(pos,2i+1)=cos(pos/100002i/d)

其中,pos表示单词在句子中的位置,d表示PE的维度,其中2i表示偶数维度,2i+1表示奇数维度。

这样做的好处(即算出来,而不是train出来的好处):

1、使 PE 能够适应比训练集里面所有句子更长的句子,假设训练集里面最长的句子是有 20 个单词,突然来了一个长度为 21 的句子,则使用公式计算的方法可以计算出第 21 位的 Embedding。

2、可以让模型容易地计算出相对位置,对于固定长度的间距 k,PE(pos+k) 可以用 PE(pos) 计算得到。因为 Sin(A+B) = Sin(A)Cos(B) + Cos(A)Sin(B), Cos(A+B) = Cos(A)Cos(B) - Sin(A)Sin(B)。(中学时三角函数变换计算)

至于为什么是相加,解释起来有点复杂:

假设我不是加上去的,因为这样多多少少有些突兀,我是拼接上去的。也即,我把能够代表位置的向量拼接到原本的input Embedding中。

在input Embedding时,会乘以一个矩阵来进行编码变换的。我们设该矩阵为A,原本的单词向量我们设置为a,那么得到的就是 W = A T ⋅ a W = A^{T}·a W=ATa

接着,如果我要是拼上去的,那么我假设我需要用的矩阵就是A’ ,那么 W ′ = A ′ T ⋅ a W' = A'^{T}·a W=ATa。如下图所示:

image-20230526093052037

接下里,我们介绍多头自注意力机制。在此之前,我们先来介绍自注意力机制。

在传统的RNN当中,由于它存在无法并发执行、梯度丢失等问题。如果我们考虑CNN来去解决这类问题,但是想要用CNN来去解决又往往需要叠很多的卷积层。也不很合适。于是,就有人提出了一种基于自注意力机制的组件,来去解决这类问题。它可以做到,通过注意力机制,关联句子中长距离的语义关系,而且,Self-Attention可以比RNN更好地解决长时依赖问题。因为它的计算量比RNN低,它可以进行并行计算。

具体来说,自注意力机制可以这样解释:

在这里插入图片描述

如上图。对于输入的单词向量 x 1 x_1 x1 x n x_n xn,经过单词编码和位置编码,得到 a 1 a_1 a1 a n a_n an

然后,我们要得到三个不同的向量。分别成为query(q)、key(k)和value(v),其中,q和k是用来计算关联程度的,而v是用来进行关联度查询。这三个向量的得到,是由 a a a分别乘以 W Q W^Q WQ W K W^K WK W v W^v Wv得到。

也就是说,所有的 q q q,即 q 1 、 q 2 . . . q r q_1、q_2...q_r q1q2...qr,是由 a 1 、 a 2 . . . a r a_1、a_2...a_r a1a2...ar乘以 W Q W^Q WQ得到,

同理,所有的 k k k,即 k 1 、 k 2 . . . k r k_1、k_2...k_r k1k2...kr,是由 a 1 、 a 2 . . . a r a_1、a_2...a_r a1a2...ar乘以 W K W^K WK得到,

所有的 v v v,即 v 1 、 v 2 . . . v r v_1、v_2...v_r v1v2...vr,是由 a 1 、 a 2 . . . a r a_1、a_2...a_r a1a2...ar乘以 W V W^V WV得到。

接下来,计算q和k的Attention。即他们关联由多大。计算公式为 a i , j = q i T ⋅ k j d q , k a_{i,j} = \frac{q^{T}_{i}·k_{j}}{\sqrt{d_{q,k}}} ai,j=dq,k qiTkj,这里的d表示的是q、k的维数。需要注意的是,是每一个 q q q,和每一个 k k k都要计算。

以上图为例, q 1 q1 q1 k 1 k1 k1,那么得到的就是 a 1 , 1 = q 1 T ⋅ k 1 d q , k a_{1,1} = \frac{q^{T}_{1}·k_{1}}{\sqrt{d_{q,k}}} a1,1=dq,k q1Tk1,我们将结果记为 a 1 , 1 a_{1,1} a1,1,与此同时,按照同样的方法,得到 a 1 , 2 、 a 1 , 3 a_{1,2}、a_{1,3} a1,2a1,3

接着,再将所有的 a a a进行softmax函数操作。所谓softmax,和sigmod类似。函数表达式: s o f t m a x ( x ) = e x i ∑ j = 1 n e x j {softmax(x)=\frac{e^{x_i}}{\sum_{j=1}^n{e^{x^j}}}} softmax(x)=j=1nexjexi它的作用是求每一部分的概率,映射到同一区域内(输出为互斥类别,且只能选择一个类别)。这样以后,就得到 a ^ 1 , j {\hat{a}_{1,j}} a^1,j

最后,将 a 1 , j ( s o f t m a x 后的 ) a_{1,j}(softmax后的) a1,j(softmax后的)分别和 v j v_j vj相乘,然后求和,就得到 b 1 b_1 b1

同理,将 a 2 , j ( s o f t m a x 后的 ) a_{2,j}(softmax后的) a2,j(softmax后的)分别和 v j v_j vj相乘,然后求和,就得到 b 2 b_2 b2

直至全部输出 b 1 . . . b n b_1 ... b_n b1...bn

不过,与RNN相比较,可以看到,我们的transformer在计算到 b 1 . . . b n b_1 ... b_n b1...bn时,是可以同步的。因为它可以通过一个矩阵,来一次性全部计算完。如下图(右侧公式):

image-20230526102258921

在这样一个组件中,我们每一个 b b b的得到,和输入的每个 a a a都是相关的。所以,我们就可以通过学习,得到某些单词之间的相关性应该是高还是低。即便两个单词相距很远,但仍可以察觉到关联。因为在整个注意力机制中,它和位置是无关的。“天涯若比邻”。

这就是自注意力机制。

我们下面来介绍多头自注意力机制。

所谓多头,就是同时有多个自注意力机制。每个注意力机制中,所关注的关联有一定区别,从而,在训练过程中,可以充分考虑不同单词之间的关联程度,从而可以很好地实现泛化。

那多头注意力机制,是怎么训练的呢?答:和单个的自注意力机制一模一样。在Transformer模型中,一共用到了8个头。这样,一组输入通过八个自注意力机制,就得到了八个输出矩阵。然后,我们将这八个矩阵Contact(拼接)在一起,然后进行一个Liner变换,最终得到一个n×n的矩阵。具体过程如下图所示:

在这里插入图片描述

(原论文中的图,在此图中,直观地展示了多头自注意力的运转过程)

下图中,展示了具体过程:

image-20230526103327160

多头自注意力机制到此介绍完毕。接下来继续介绍Transformer。

还是刚刚的那个图image-20230526002758625

左侧,Encoder部分,经过了Multi-Head Attention后,得到的输出,和Multi-Head Attention的输入,进行Add&Norm,即残差连接加归一化(标准化)。

残差连接刚刚已说过,就是X(输入) + Multi-Head-Attention)(X)->输入加输出的方式,让其可以更好地只关注差异。

Norm这里指归一化,所使用的是 Layer Normalization,将每一层神经元的输入都转成均值方差都一样的,用来加快收敛。注意,这里的每一层,而不是每一个维度(每一个维度是Batch Normalization)。所采用的归一化公式是z-score归一化。因为样本范围不确定。

进行Add&Norm之后,进行Feed Forward运算。Feed Forward实际上很简单,是一个两层的全连接层,第一层的激活函数为 Relu,第二层不使用激活函数。因此,它的公式为: m a x ( 0 , X W 1 + b 1 ) W 2 + b 2 max(0,XW_1+b_1)W_2+b_2 max(0,XW1+b1)W2+b2

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

然后继续进行Add&Norm。

这样以后,算是经过了一个Encoder Block。通过多个 Encoder block 叠加就可以组成 Encoder(Transformer用到了N个)。

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


到此为止,Encoder解释完毕。

接下来看Decoder。我们先来看右下角的Masked Multi-Head Attention

需要明白,在Decoder中,需要根据之前的翻译,来去找到当前最可能的翻译。没有被翻译出来的内容不能被看到。

所以,这里引入了一个Masked自注意力机制。它的输入是已经输出出来的单词(因为需要根据之前的翻译来去推测之后的翻译)。而在最一开始的时候,是一个类似于标志位的东西。所谓Masked,就是对矩阵进行遮挡。把不知道的部分变成0。

如下图,对于原本的输入矩阵,在 Mask 可以发现单词 0 只能使用单词 0 的信息,而单词 1 可以使用单词 0, 1 的信息,即只能使用之前的信息。

注意,这里的Masked矩阵,在训练当中,由于我们已经提前知道了其正确答案,所以遮挡住有其必要性。否则拿未预测出的部分去预测自己,就相当于作弊了。

而在预测时,我们实际上本身就不知道后面的内容到底是什么。即便我们不遮挡,我们也是不知道后面是什么的——但换一种理解方式,就好似后面的内容被遮挡住了,所以我们看不见。
在这里插入图片描述

确定了输入矩阵之后,接下来的操作就和之前的self-Attention一样了。通过输入矩阵X,来去计算Q、K、V。然后计算Q和K的Attention score,然后再用Mask矩阵进行遮挡。遮挡操作如图:

image-20230526110417011

得到Mask Q K T QK^T QKT之后,再去进行softmax,然后和V相乘,然后再关联、做Liner变换、求和。

Masked Multi-Head Attention介绍完毕。

然后看上面的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 block。

Decoder block 最后的部分是利用 Softmax 预测下一个单词,在之前的网络层我们可以得到一个最终的输出 Z,因为 Mask 的存在,使得单词 0 的输出 Z0 只包含单词 0 的信息,如下:

在这里插入图片描述

与Encoder一样,Decoder也是由N个Decoder block组成(就是多个)

Transformer介绍到这里基本结束。

参考:

1、Transformer模型详解(图解最完整版) - 知乎 (zhihu.com)

2、1706.03762.pdf (arxiv.org)

3、Multi-headed Self-attention(多头自注意力)机制介绍 - 知乎 (zhihu.com)

4、Transformer,BERT模型介绍 - 知乎 (zhihu.com)

5、Transformer - YouTube

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

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

相关文章

c语言每日一练(14)【加强版】

前言:每日一练系列,每一期都包含5道选择题,2道编程题,博主会尽可能详细地进行讲解,令初学者也能听的清晰。博主有时会将一些难题综合成每日一练加强版,加强版是特殊的,它仅包含5道选择题&#x…

如何将home目录空间扩充到根目录下

目录 1、查看查看磁盘使用情况2、扩容思路3、卸载并删除/home4、扩大/root逻辑卷5、扩大/文件系统6、重建/home逻辑卷7、创建/home文件系统8、将新建的文件系统挂载到/home目录下9、恢复/home并删除备份10、再次查看看磁盘存储 系统:centos7.9 1、查看查看磁盘使用…

shell指令练习

一、使用cut截取出Ubuntu用户的家目录,要求:不能使用":"作为分割 ubuntuubuntu:01_day$ grep "^Ubuntu" /etc/passwd -ni | cut -d "/" -f 2,3 | cut -c 1-11 home/ubuntu

【算法专题突破】双指针 - 和为s的两个数字(6)

目录 1. 题目解析 2. 算法原理 3. 代码编写 写在最后: 1. 题目解析 题目链接:剑指 Offer 57. 和为s的两个数字 - 力扣(Leetcode) 这道题题目就一句话但是也是有信息可以提取的, 最重要的就是开始的那句话&#…

SonarQube介绍和安装

docker安装postgres数据库 docker安装sonarqube 安装前在官网上确定一下可用的版本号 创建sonarqube_docker目录 本实验中,jdk,maven,jenkins,postgres,sonarqube都安装在同一台服务器上。 docker compose启动 修改虚拟机内存 sonarqube启动成功 默认用户名和密…

Javase | 字符编码、转义字符、方法执行过程中的 “内存分配”

目录: 字符编码转义字符:转义字符在控制台上输出 “反斜杠字符”在控制台上输出 “单引号字符” 方法执行过程中的 “内存分配” 字符编码 为了让计算机可以表示现实世界中的文字,我们需要人为进行干涉,需要人负责提前制定 “文字…

Linux系统之mkdir与rmdir命令的基本使用

Linux系统之mkdir与rmdir命令的基本使用 一、mkdir命令介绍1.1 mkdir命令简介1.2 mkdir命令的由来 二、mkdir命令的使用帮助2.1 mkdir命令的help帮助信息2.2 mkdir命令的选项解释 三、mkdir命令的基本使用3.1 查看mkdir的版本3.2 创建一个新目录3.3 创建目录时设置目录权限3.4 …

【MySQL基础|第一篇】——谈谈SQL中的DDL语句

个人主页:兜里有颗棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【MySQL学习专栏】🎈 本专栏旨在分享学习MySQL的一点学习心得,欢迎大家在评论区讨论💌 前言&#xff…

vue优化首屏加载时间优化-cdn引入第三方包

前言 为什么要进行首屏加载优化,因为随着我们静态资源和第三方包和代码增加,压缩之后包会越来越大 随着网络的影响,在我们第一输入url请求资源时候,网络阻塞,加载时间长,用户体验不好 仔细观察后就会发现…

linux和macOS平台中python语言文件上传的一处不同实现

背景 linux系统, python语言,tornado框架 现象 x文件在macOS平台可正常上传, linux平台上传失败。 x文件说明 文件名:xxxx秘密 .mp3 文件格式:mp3 原因 文件名包含\x20\x7f导致, \x20是设备控制, \…

Android逆向工程【黑客帝国】

Android逆向是一门艺术,涵盖的范畴非常广,要学习的东西也很多,如果是为了就业目的,学习的偏向性一定要掌握好。而Android逆向必须掌握的技能有以下: 负责安卓程序的加解密和数据传输分析、拆解、逆向等工作;逆向APK,了…

Agisoft/PhotoScan手动对齐照片

所以我到网上查了一下资料,了解了如何通过添加标记的方式,手动对齐照片。参考文档是PhotoScan的用户手册(http://www.agisoft.com/pdf/photoscan-pro_1_4_en.pdf)。 手动对齐照片,需要在未对齐照片上添加四个及以上标记,并在已对…

Android——数据存储(一)(二十一)

1. 数据存储 1.1 知识点 (1)掌握Android数据存储的分类; (2)可以使用SharedPreferences存储数据。 1.2 具体内容 对于我们数据的存储而言,Android一共提供了5个数据存储的方式:SharedPrefe…

Swift 另辟蹊径极速生成图片的缩略图

功能需求 在 App 开发中,创建图片缩略图是一种很常见的操作。但是超大图片如何快速且便捷的生成指定尺寸的缩略图呢? 如上图所示:我们极速生成缩略图比常规方式快了将近 27 倍之多!且生成代码没有用任何第三方库,完全是  原生实现。 在上面演示中包含几张数码相机原始…

huggingface 使用入门笔记

概念 Hugging Face Hub​​和 Github 类似,都是Hub(社区)。Hugging Face可以说的上是机器学习界的Github。Hugging Face为用户提供了以下主要功能: ​模型仓库(Model Repository)​​:Git仓库可以让你管理代码版本、…

动态规划区间dp之647回文子串

题目: 给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度。 子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。 示例: 题目链接:647.…

Android 线程池源码详解(一)

线程池的创建是通过Executors 构造出来的,这是个典型的工厂类,使用了工厂模式。常用的有四种线程池: 分别是newFixedThreadPool,newSingleThreadExecutor, newCachedThreadPool,newScheduledThreadPool&am…

小白备战大厂算法笔试(二)——数组、链表、列表

常见数据结构 常见的数据结构包括数组、链表、栈、队列、哈希表、树、堆、图,它们可以从“逻辑结构”和“物理结构”两个维度进行分类。 逻辑结构可被分为“线性”和“非线性”两大类。线性结构比较直观,指数据在逻辑关系上呈线性排列;非线…

制药行业常见生产设备有哪些?

制药行业是一个关系到人民健康和生命安全的特殊领域,因此,生产质量和合规性是至关重要的。为了满足严格的生产质量管理规范(GMP)要求(>>制药行业GMP是什么?),制药企业需要使用…

公司办公文件加密防泄密软件哪个好?

天锐绿盾是一款专业的数据安全解决方案,旨在保护企业的核心数据。它采用基于Windows、Mac、Linux内核的文档透明加解密技术,对指定类型的文件进行实时、强制、透明加密,使得文件在操作时自动解密,关闭时自动加密,能够有…