一文详解大语言模型Transformer结构

目录

  • 1. 什么是Transformer
  • 2. Transformer结构
    • 2.1 总体结构
    • 2.2 Encoder层结构
    • 2.3 Decoder层结构
    • 2.4 动态流程图
  • 3. Transformer为什么需要进行Multi-head Attention
  • 4. Transformer相比于RNN/LSTM,有什么优势?为什么?
  • 5. 为什么说Transformer可以代替seq2seq?
  • 6. 代码实现
  • 7. 参考文献

1. 什么是Transformer

《Attention Is All You Need》是一篇Google提出的将Attention思想发挥到极致的论文。这篇论文中提出一个全新的模型,叫 Transformer,抛弃了以往深度学习任务里面使用到的 CNN 和 RNN。目前大热的Bert就是基于Transformer构建的,这个模型广泛应用于NLP领域,例如机器翻译,问答系统,文本摘要和语音识别等等方向。

2. Transformer结构

2.1 总体结构

Transformer的结构和Attention模型一样,Transformer模型中也采用了 encoer-decoder 架构。但其结构相比于Attention更加复杂,论文中encoder层由6个encoder堆叠在一起,decoder层也一样。

alt

每一个encoder和decoder的内部结构如下图:

alt
  • encoder,包含两层,一个self-attention层和一个前馈神经网络,self-attention能帮助当前节点不仅仅只关注当前的词,从而能获取到上下文的语义。
  • decoder也包含encoder提到的两层网络,但是在这两层中间还有一层attention层,帮助当前节点获取到当前需要关注的重点内容。

2.2 Encoder层结构

首先,模型需要对输入的数据进行一个embedding操作,也可以理解为类似w2c的操作,enmbedding结束之后,输入到encoder层,self-attention处理完数据后把数据送给前馈神经网络,前馈神经网络的计算可以并行,得到的输出会输入到下一个encoder。

alt
2.2.1 Positional Encoding

transformer模型中缺少一种解释输入序列中单词顺序的方法,它跟序列模型还不不一样。为了处理这个问题,transformer给encoder层和decoder层的输入添加了一个额外的向量Positional Encoding,维度和embedding的维度一样,这个向量采用了一种很独特的方法来让模型学习到这个值,这个向量能决定当前词的位置,或者说在一个句子中不同的词之间的距离。这个位置向量的具体计算方法有很多种,论文中的计算方法如下:

alt

alt 其中pos是指当前词在句子中的位置,i是指向量中每个值的index,可以看出,在偶数位置,使用正弦编码,在奇数位置,使用余弦编码

最后把这个Positional Encoding与embedding的值相加,作为输入送到下一层。

alt
2.2.2 Self-Attention

接下来我们详细看一下self-attention,其思想和attention类似,但是self-attention是Transformer用来将其他相关单词的“理解”转换成我们正在处理的单词的一种思路,我们看个例子:

The animal didn't cross the street because it was too tired

这里的 it 到底代表的是 animal 还是 street 呢,对于我们来说能很简单的判断出来,但是对于机器来说,是很难判断的,self-attention就能够让机器把 it 和 animal 联系起来,接下来我们看下详细的处理过程。

  1. 首先,self-attention会计算出三个新的向量,在论文中,向量的维度是512维,我们把这三个向量分别称为Query、Key、Value,这三个向量是用embedding向量与一个矩阵相乘得到的结果,这个矩阵是随机初始化的,维度为(64,512)注意第二个维度需要和embedding的维度一样,其值在BP的过程中会一直进行更新,得到的这三个向量的维度是64。

    alt
  2. 计算self-attention的分数值,该分数值决定了当我们在某个位置encode一个词时,对输入句子的其他部分的关注程度。这个分数值的计算方法是Query与Key做点成,以下图为例,首先我们需要针对Thinking这个词,计算出其他词对于该词的一个分数值,首先是针对于自己本身即q1·k1,然后是针对于第二个词即q1·k2。

    alt
  3. 接下来,把点成的结果除以一个常数,这里我们除以8,这个值一般是采用上文提到的矩阵的第一个维度的开方即64的开方8,当然也可以选择其他的值,然后把得到的结果做一个softmax的计算。得到的结果即是每个词对于当前位置的词的相关性大小,当然,当前位置的词相关性肯定会会很大。

    alt
  4. 下一步就是把Value和softmax得到的值进行相乘,并相加,得到的结果即是self-attetion在当前节点的值。

    alt

在实际的应用场景,为了提高计算速度,我们采用的是矩阵的方式,直接计算出Query, Key, Value的矩阵,然后把embedding的值与三个矩阵直接相乘,把得到的新矩阵 Q 与 K 相乘,乘以一个常数,做softmax操作,最后乘上 V 矩阵。

这种通过 query 和 key 的相似性程度来确定 value 的权重分布的方法被称为scaled dot-product attention。

alt
alt
2.2.3 Multi-Headed Attention

这篇论文更牛逼的地方是给self-attention加入了另外一个机制,被称为“multi-headed” attention,该机制理解起来很简单,就是说不仅仅只初始化一组Q、K、V的矩阵,而是初始化多组,tranformer是使用了8组,所以最后得到的结果是8个矩阵。

alt
alt
2.2.4 Layer normalization

在transformer中,每一个子层(self-attetion,Feed Forward Neural Network)之后都会接一个残缺模块,并且有一个Layer normalization。

alt

Normalization有很多种,但是它们都有一个共同的目的,那就是把输入转化成均值为0方差为1的数据。我们在把数据送入激活函数之前进行normalization(归一化),因为我们不希望输入数据落在激活函数的饱和区。

Batch Normalization

BN的主要思想就是:在每一层的每一批数据上进行归一化。我们可能会对输入数据进行归一化,但是经过该网络层的作用后,我们的数据已经不再是归一化的了。随着这种情况的发展,数据的偏差越来越大,我的反向传播需要考虑到这些大的偏差,这就迫使我们只能使用较小的学习率来防止梯度消失或者梯度爆炸。BN的具体做法就是对每一小批数据,在批这个方向上做归一化。

Layer normalization

它也是归一化数据的一种方式,不过LN 是在每一个样本上计算均值和方差,而不是BN那种在批方向计算均值和方差!公式如下:

alt=\alpha*\frac{x_i-\mu_L}{\sqrt{\sigma_L^2+\varepsilon}}+\beta)

alt
2.2.5 Feed Forward Neural Network

这给我们留下了一个小的挑战,前馈神经网络没法输入 8 个矩阵呀,这该怎么办呢?所以我们需要一种方式,把 8 个矩阵降为 1 个,首先,我们把 8 个矩阵连在一起,这样会得到一个大的矩阵,再随机初始化一个矩阵和这个组合好的矩阵相乘,最后得到一个最终的矩阵。

alt

2.3 Decoder层结构

根据上面的总体结构图可以看出,decoder部分其实和encoder部分大同小异,刚开始也是先添加一个位置向量Positional Encoding,方法和 2.2.1 节一样,接下来接的是masked mutil-head attetion,这里的mask也是transformer一个很关键的技术,下面我们会进行一一介绍。

其余的层结构与Encoder一样,请参考Encoder层结构。

2.3.1 masked mutil-head attetion

mask 表示掩码,它对某些值进行掩盖,使其在参数更新时不产生效果。Transformer 模型里面涉及两种 mask,分别是 padding mask 和 sequence mask。其中,padding mask 在所有的 scaled dot-product attention 里面都需要用到,而 sequence mask 只有在 decoder 的 self-attention 里面用到。

  1. padding mask

    什么是 padding mask 呢?因为每个批次输入序列长度是不一样的也就是说,我们要对输入序列进行对齐。具体来说,就是给在较短的序列后面填充 0。但是如果输入的序列太长,则是截取左边的内容,把多余的直接舍弃。因为这些填充的位置,其实是没什么意义的,所以我们的attention机制不应该把注意力放在这些位置上,所以我们需要进行一些处理。

    具体的做法是,把这些位置的值加上一个非常大的负数(负无穷),这样的话,经过 softmax,这些位置的概率就会接近0!

    而我们的 padding mask 实际上是一个张量,每个值都是一个Boolean,值为 false 的地方就是我们要进行处理的地方。

  2. Sequence mask

    文章前面也提到,sequence mask 是为了使得 decoder 不能看见未来的信息。也就是对于一个序列,在 time_step 为 t 的时刻,我们的解码输出应该只能依赖于 t 时刻之前的输出,而不能依赖 t 之后的输出。因此我们需要想一个办法,把 t 之后的信息给隐藏起来。

    那么具体怎么做呢?也很简单:产生一个上三角矩阵,上三角的值全为0。把这个矩阵作用在每一个序列上,就可以达到我们的目的

  • 对于 decoder 的 self-attention,里面使用到的 scaled dot-product attention,同时需要padding mask 和 sequence mask 作为 attn_mask,具体实现就是两个mask相加作为attn_mask。
  • 其他情况,attn_mask 一律等于 padding mask。
2.3.2 Output层

当decoder层全部执行完毕后,怎么把得到的向量映射为我们需要的词呢,很简单,只需要在结尾再添加一个全连接层和softmax层,假如我们的词典是1w个词,那最终softmax会输入1w个词的概率,概率值最大的对应的词就是我们最终的结果。

2.4 动态流程图

编码器通过处理输入序列开启工作。顶端编码器的输出之后会变转化为一个包含向量K(键向量)和V(值向量)的注意力向量集 ,这是并行化操作。这些向量将被每个解码器用于自身的“编码-解码注意力层”,而这些层可以帮助解码器关注输入序列哪些位置合适:

alt

在完成编码阶段后,则开始解码阶段。解码阶段的每个步骤都会输出一个输出序列(在这个例子里,是英语翻译的句子)的元素。

接下来的步骤重复了这个过程,直到到达一个特殊的终止符号,它表示transformer的解码器已经完成了它的输出。每个步骤的输出在下一个时间步被提供给底端解码器,并且就像编码器之前做的那样,这些解码器会输出它们的解码结果 。

解码器动态图请点击

3. Transformer为什么需要进行Multi-head Attention

原论文中说到进行Multi-head Attention的原因是将模型分为多个头,形成多个子空间,可以让模型去关注不同方面的信息,最后再将各个方面的信息综合起来。其实直观上也可以想到,如果自己设计这样的一个模型,必然也不会只做一次attention,多次attention综合的结果至少能够起到增强模型的作用,也可以类比CNN中同时使用多个卷积核的作用,直观上讲,多头的注意力有助于网络捕捉到更丰富的特征/信息

4. Transformer相比于RNN/LSTM,有什么优势?为什么?

  1. RNN系列的模型,并行计算能力很差。RNN并行计算的问题就出在这里,因为 T 时刻的计算依赖 T-1 时刻的隐层计算结果,而 T-1 时刻的计算依赖 T-2 时刻的隐层计算结果,如此下去就形成了所谓的序列依赖关系。

  2. Transformer的特征抽取能力比RNN系列的模型要好。

    具体实验对比可以参考:放弃幻想,全面拥抱Transformer:自然语言处理三大特征抽取器(CNN/RNN/TF)比较

    但是值得注意的是,并不是说Transformer就能够完全替代RNN系列的模型了,任何模型都有其适用范围,同样的,RNN系列模型在很多任务上还是首选,熟悉各种模型的内部原理,知其然且知其所以然,才能遇到新任务时,快速分析这时候该用什么样的模型,该怎么做好。

5. 为什么说Transformer可以代替seq2seq?

seq2seq缺点:这里用代替这个词略显不妥当,seq2seq虽已老,但始终还是有其用武之地,seq2seq最大的问题在于将Encoder端的所有信息压缩到一个固定长度的向量中,并将其作为Decoder端首个隐藏状态的输入,来预测Decoder端第一个单词(token)的隐藏状态。在输入序列比较长的时候,这样做显然会损失Encoder端的很多信息,而且这样一股脑的把该固定向量送入Decoder端,Decoder端不能够关注到其想要关注的信息。

Transformer优点:transformer不但对seq2seq模型这两点缺点有了实质性的改进(多头交互式attention模块),而且还引入了self-attention模块,让源序列和目标序列首先“自关联”起来,这样的话,源序列和目标序列自身的embedding表示所蕴含的信息更加丰富,而且后续的FFN层也增强了模型的表达能力,并且Transformer并行计算的能力是远远超过seq2seq系列的模型,因此我认为这是transformer优于seq2seq模型的地方。

参考文献

  • Transformer模型详解
  • 图解Transformer(完整版)
  • 关于Transformer的若干问题整理记录

本文由 mdnice 多平台发布

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

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

相关文章

Vue项目之Element-UI(Breadcrumb)动态面包屑效果 el-breadcrumb

效果预览 需要导航的页面Vue.js 最笨的方法就是在每个需要面包屑的页面中固定写好 <template><div class="example-container"><el-breadcrumb separator="/"

【Linux】指令和权限的这些细节,你确定都清楚吗?

&#x1f680;个人主页&#xff1a;奋斗的小羊 &#x1f680;所属专栏&#xff1a;Linux 很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~ 目录 前言&#x1f4a5;一、Linux基本指令&#x1f4a5;1.1 mv 指令&#x1f4a5;1.2 cat 指令&#x1f4a5;…

HarmonyOS鸿蒙开发实战(5.0)自定义全局弹窗实践

鸿蒙HarmonyOS开发实战往期文章必看&#xff1a; HarmonyOS NEXT应用开发性能实践总结 最新版&#xff01;“非常详细的” 鸿蒙HarmonyOS Next应用开发学习路线&#xff01;&#xff08;从零基础入门到精通&#xff09; 非常详细的” 鸿蒙HarmonyOS Next应用开发学习路线&am…

新手上路:在Windows CPU上安装Anaconda和PyCharm

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一. 确认自己是CPU为什么选择CPU教程&#xff1f;GPU与CPU的区别如何判断自己是CPU 二. Anaconda 安装包 和 Pycharm 安装包步骤1&#xff1a;下载Anaconda步骤2&am…

Golang开发的OCR-身份证号码识别(不依赖第三方)

身份证号码识别&#xff08;golang&#xff09; 使用golang的image库写的身份证号码识别&#xff0c;还有用了一个resize外部库&#xff0c;用来更改图片尺寸大小&#xff0c;将每个数字所在的图片的大小进行统一可以更好的进行数字识别&#xff0c;库名 &#xff1a;“github…

上海我店平台 8月新增注册用户89w 两年破百亿销售额!

近年来&#xff0c;网络空间内涌现了一个备受瞩目的新平台——“上海我店”&#xff0c;其公布的业绩数据显示&#xff0c;短短三年内&#xff0c;该平台交易流水已突破百亿大关&#xff0c;上月更是迎来了近百万的新增注册用户&#xff0c;这一消息迅速吸引了众多商家的目光。…

系统架构设计师 需求分析篇一

&#x1f4d8; 结构化分析SA 思想 自顶向下&#xff1a;像剥洋葱一样&#xff0c;层层深入&#xff0c;大问题拆成小问题&#xff0c;再拆成更小的问题。 核心模型 数据字典 &#x1f4d4;&#xff1a;记录数据元素的点点滴滴&#xff0c;从属性到使用方式&#xff0c;无所…

Java基础面试题——异常

目录 关系图 1. Throwable和Exception之间的关系 2.异常分为哪两大类 3.常见的 RuntimeException 4. 常见的 Error 5.什么是已检查异常和未检查异常&#xff1f;它们的区别是什么&#xff1f; 6.Java 中如何自定义异常&#xff1f; 7.throw 和 throws 的区别是什么&…

简述混沌神经网络

混沌神经网络是一种结合了神经网络与混沌理论的新型智能信息处理系统。以下是对混沌神经网络的详细解析&#xff1a; 一、定义与背景 混沌神经网络是由于神经网络具有高度非线性动力学系统的特性&#xff0c;而混沌又具有无规则性、遍历性、随机性等特点&#xff0c;因此神经网…

端侧 AI 的新突破:面壁智能 MiniCPM 3.0

在人工智能领域&#xff0c;每一次技术的革新都可能引发一场小小的革命。 ChatGPT-3.5 曾经凭借其惊人的表现赢得了大众的关注&#xff0c;但如今&#xff0c;随着国内AI公司面壁智能推出的新端侧基座模型&#xff0c;人们开始重新审视端侧AI的潜力和未来。 这款名为MiniCPM …

linux----进程地址空间

前言 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、空间分布 二、栈和堆的特点 &#xff08;1&#xff09;栈堆相对而生&#xff0c;堆是向上增长的&#xff0c;栈是向下增长的。 验证&#xff1a;堆是向上增长的 这里我们看到申请的堆&#xff…

Ubuntu 20.04安装pycharm2022及配置快捷方式

一、下载与安装 1. 下载 在 官网 下载所需版本&#xff0c;如&#xff1a;下载 2022.3.3 - Linux (tar.gz) 2. 安装 设置自定义安装路径(推荐在 /opt/ 路径下)并安装 mkdir -p ~/Documents/software/pycharm/ cd ~/Documents/software/pycharm/ mv ~/Downloads/pycharm-c…

解决 TortoiseGitPlink Fatal Error:深入解析

解决 TortoiseGitPlink Fatal Error&#xff1a;深入解析 在 Windows 平台上&#xff0c;开发者使用 Git 和 TortoiseGit 进行版本控制时&#xff0c;有时会遇到 TortoiseGitPlink Fatal Error。该错误通常是在推送/拉取代码时&#xff0c;客户端未能提供正确的 SSH 密钥。 1…

单相电多相电

目录 1. 单相电 2. 多相电 3. 其他多相电系统 单相电和多相电是电力系统中常见的两种供电方式&#xff0c;主要区别在于电力传输的相数。以下分别介绍它们的基本概念、特征、以及应用场景。 1. 单相电 定义&#xff1a; 单相电指的是只有一根火线和一根零线的电力系统。这…

企业微信应用消息收发实施记录

一、前置配置 1.1 进入我的企业页面&#xff0c;记录下企业ID。 1.2 创建企微应用&#xff0c;记录下应用的 AgentId 和 Secret。 1.3 设置应用的企业可信IP&#xff0c;将服务器公网 IP 填入即可。 1.4 设置应用接收消息API 填入服务器 API 地址&#xff0c;并记录下随机获取…

JAVA精准匹配同城找搭子交友系统小程序源码

精准匹配&#xff0c;同城找搭子交友系统 &#x1f50d; 开篇&#xff1a;告别盲目&#xff0c;迎接精准交友新时代 在这个快节奏的城市生活中&#xff0c;你是否厌倦了无效的社交和孤独的夜晚&#xff1f;是时候告别那些盲目的交友尝试&#xff0c;迎接“精准匹配同城找搭子…

SpringBoot启动横幅输出到控制台。

在Spring Boot应用中&#xff0c;banner.txt 文件通常放置在项目的资源目录下&#xff08;通常是 src/main/resources&#xff09;&#xff0c;当Spring Boot应用启动时&#xff0c;会自动读取这个文件并将其内容作为启动横幅输出到控制台。这可以用来个性化你的应用程序启动时…

docker|Oracle数据库|docker快速部署Oracle11g和数据库的持久化(可用于生产环境)

一、 容器数据持久化的概念 docker做为容器化的领先技术&#xff0c;现在广泛应用于各个平台中&#xff0c;但不知道什么时候有一个说法是docker并不适用容器化数据库&#xff0c;说容器化的数据库性能不稳定&#xff0c;其实&#xff0c;这个说法主要是因为对docker的数据持…

路径处理 | 关键点提取之Douglas–Peucker算法(附ROS C++/Python实现)

目录 0 专栏介绍1 路径关键点提取2 道格拉斯-普克算法Douglas–Peucker3 算法实现与可视化3.1 ROS C仿真3.2 Python仿真 0 专栏介绍 &#x1f525;课设、毕设、创新竞赛必备&#xff01;&#x1f525;本专栏涉及更高阶的运动规划算法轨迹优化实战&#xff0c;包括&#xff1a;…

MateBook 16s 2023在Deepin下开启性能模式,调节风扇转速到最大,全网首发!

方法 在Deepin下按住Fnp快捷键&#xff0c;开启性能模式。 验证 首先去debian下载acpi-call-dkms https://packages.debian.org/sid/all/acpi-call-dkms/download 然后使用root用户执行&#xff1a; apt install --simulate ./acpi-call-dkms_1.2.2-2.1_all.deb apt inst…