【Bert101】变压器模型背后的复杂数学【01/4】

news2025/1/16 20:51:51

一、说明

        众所周知,变压器架构是自然语言处理(NLP)领域的突破。它克服了 seq-to-seq 模型(如 RNN 等)无法捕获文本中的长期依赖性的局限性。变压器架构被证明是革命性架构(如 BERT、GPT 和 T5 及其变体)的基石。正如许多人所说,NLP正处于黄金时代,说变压器模型是一切开始的地方并没有错。

二、对变压器架构的需求

        如前所述,需求是发明之母。传统的 seq-to-seq 模型在处理长文本时并不好。这意味着模型在处理输入序列的后半部分时,往往会忘记输入序列前半部分的学习。这种信息丢失是不可取的。

        尽管像 LSTM 和 GRU 这样的门控架构通过丢弃在记住重要信息的过程中无用的信息,在处理长期依赖关系方面表现出一些改进,但这仍然不够。世界需要更强大的东西,2015年,Bahdanau等人引入了“注意力机制”。 它们与RNN / LSTM结合使用,以模仿人类行为,专注于选择性事物,而忽略其余事物。Bahdanau建议为句子中的每个单词分配相对重要性,以便模型专注于重要的单词而忽略其余单词。它被认为是对神经机器翻译任务的编码器-解码器模型的巨大改进,很快,注意力机制的应用也在其他任务中推广。

变压器模型时代

        变压器模型完全基于一种注意力机制,也称为“自我注意”。这种架构在 2017 年的论文“注意力是你所需要的一切”中向世界介绍。它由编码器-解码器架构组成。

无花果。高级转换器模型体系结构(来源:作者)

在高层次上,

  • 编码器负责接受输入的句子并将其转换为隐藏的表示形式,丢弃所有无用的信息。
  • 解码器接受此隐藏表示形式并尝试生成目标句子。

在本文中,我们将深入研究变压器模型的编码器组件的详细细分。在下一篇文章中,我们将详细介绍解码器组件。让我们开始吧!

三、变压器编码器

        变压器的编码器块由一堆按顺序工作的N个编码器组成。一个编码器的输出是下一个编码器的输入,依此类推。最后一个编码器的输出是馈送到解码器块的输入句子的最终表示形式。

无花果。带堆叠编码器的Enoder模块(来源:作者)

如下图所示,每个编码器块可以进一步分成两个组件。

        无花果。编码器层的组件(来源:作者)

        让我们逐一详细研究这些组件中的每一个,以了解编码器块的工作原理。编码器模块中的第一个组成部分是多头注意力,但在我们进入细节之前,让我们先了解一个基本概念:自我注意

3. 1 自我注意机制

        每个人脑海中可能出现的第一个问题:注意力和自我注意力是不同的概念吗? 是的,他们是。(咄!

        传统上,注意力机制是为神经机器翻译任务而存在的,如上一节所述。因此,本质上应用了注意力机制来映射源句和目标句。当 seq-to-seq 模型逐个令牌执行翻译任务时,注意机制可帮助我们在为目标句子生成标记 x 时识别源句子中的哪些标记需要更多关注。为此,它利用编码器和解码器的隐藏状态表示来计算注意力分数,并根据这些分数生成上下文向量作为解码器的输入。如果您想了解有关注意力机制的更多信息,请跳到这篇文章(精彩的解释!

        回到自我注意,主要思想是计算注意力分数,同时将源句子映射到自身。如果你有这样的句子,

“男孩没有过马路因为它太宽了。

        我们人类很容易理解上面句子中的“它”一词指的是“道路”,但是我们如何使我们的语言模型也理解这种关系呢?这就是自我关注的地方!

在高层次上,将句子中的每个单词与句子中的每个其他单词进行比较,以量化关系并理解上下文。出于表示目的,您可以参考下图。

让我们详细看看这种自我注意是如何计算的(真实)。

  • 为输入句子生成嵌入

查找所有单词的嵌入并将它们转换为输入矩阵。这些嵌入可以通过简单的标记化和独热编码生成,也可以通过嵌入算法(如BERT等)生成。输入矩阵的维度将等于句子长度 x 嵌入维度。我们称此输入矩阵为 X 以供将来参考。

  • 将输入矩阵转换为Q,K和V

为了计算自我注意,我们需要将X(输入矩阵)转换为三个新矩阵:
- 查询 (Q)- 键 (K)- 值 (V)

 

为了计算这三个矩阵,我们将随机初始化三个权重矩阵,即Wq,Wk和Wv。输入矩阵X将与这些权重矩阵Wq,Wk和Wv相乘,分别获得Q,K和V的值。在此过程中将学习权重矩阵的最佳值,以获得更准确的Q,K和V值。

  • 计算 Q 和 K 转置的点积

从上图中,我们可以暗示 qi、ki 和 vi 表示句子中第 i 个单词的 Q、K 和 V 的值。

无花果。Q 和 K 转置的点积示例(来源:作者)

输出矩阵的第一行将告诉您由 q1 表示的 word1 如何与使用点积的句子中的其余单词相关。点积的值越高,单词越相关。为了直观地了解计算此点积的原因,您可以在信息检索方面理解 Q(查询)和 K(键)矩阵。所以在这里,
- Q 或查询 = 您正在搜索的术语
- K 或 Key = 搜索引擎中的一组关键字,与 Q 进行比较和匹配。

  • 缩放点积

与上一步一样,我们正在计算两个矩阵的点积,即执行乘法运算,该值有可能爆炸。为了确保这种情况不会发生并且梯度稳定,我们将 Q 和 K 转置的点积除以嵌入维度 (dk) 的平方根。

  • 使用 softmax 规范化值

使用 softmax 函数进行归一化将产生介于 0 和 1 之间的值。具有高比例点积的单元格将进一步升高,而低值将减少,使匹配的单词对之间的区别更加清晰。生成的输出矩阵可以视为分数矩阵S

  • 计算注意力矩阵 Z

        将值矩阵或V乘以从上一步获得的分数矩阵S,以计算注意力矩阵Z。

        但是等等,为什么要乘法?

        假设 Si = [0.9, 0.07, 0.03] 是句子中第 i 个单词的分数矩阵值。将此向量与 V 矩阵相乘以计算 Zi(第 i 个单词的注意力矩阵)。

Zi = [0.9 * V1 + 0.07 * V2 + 0.03 * V3]

        我们是否可以说,为了理解第 i 个单词的上下文,我们应该只关注 word1(即 V1),因为注意力分数值的 90% 来自 V1?我们可以清楚地定义重要的单词,在这些单词中,应该更加注意理解第i个单词的上下文。

        因此,我们可以得出结论,一个词在Zi表示中的贡献越高,单词之间的批判性和相关性就越大。

        现在我们知道了如何计算自我注意力矩阵,让我们了解多头注意力机制的概念。

3.2 多头注意力机制

        如果您的分数矩阵偏向于特定的单词表示,会发生什么?它会误导您的模型,结果不会像我们预期的那样准确。让我们看一个例子来更好地理解这一点。

        S1:“一切都很好

        Z(井) = 0.6 * V(全部) + 0.0 * v(是) + 0.4 * V(井)

        S2:“狗吃了食物,因为它饿了

        Z(它) = 0.0 * V(的) + 1.0 * V(狗) + 0.0 * V(吃) + ...... + 0.0 * V(饥饿)

        在 S1 情况下,在计算 Z(well) 时,对 V(all) 给予了更多的重要性。它甚至比V(好吧)本身还要多。无法保证这有多准确。

        在 S2 的情况下,在计算 Z(it) 时,所有的重要性都给了 V(dog),而其余单词的分数也是 0.0,包括 V(it)。这看起来可以接受,因为“it”这个词是模棱两可的。将它更多地与另一个词联系起来而不是将这个词本身联系起来是有意义的。这就是计算自我注意力的全部目的。处理输入句子中歧义单词的上下文。

        换句话说,我们可以说,如果当前单词是模棱两可的,那么在计算自我注意时可以更加重视其他单词,但在其他情况下,这可能会对模型产生误导。那么,我们现在该怎么办?

        如果我们计算多个注意力矩阵而不是计算一个注意力矩阵并从中导出最终的注意力矩阵会怎样?

        这正是多头注意力的全部意义所在!我们计算注意力矩阵z1,z2,z3,.....,zm的多个版本,并将它们连接起来以得出最终的注意力矩阵。这样我们就可以对自己的注意力矩阵更有信心。

        转到下一个重要概念,

3.3 位置编码

        在seq-to-seq模型中,输入的句子被逐字输入到网络,这允许模型跟踪单词相对于其他单词的位置。

        但在变压器模型中,我们遵循不同的方法。它们不是逐字逐句地输入,而是并行馈送,这有助于减少训练时间和学习长期依赖性。但是使用这种方法,单词顺序就丢失了。但是,要正确理解句子的含义,词序非常重要。为了克服这个问题,引入了一种称为“位置编码”(P)的新矩阵。

        该矩阵 P 与输入矩阵 X 一起发送,以包含与词序相关的信息。出于显而易见的原因,X 和 P 矩阵的维度是相同的。

        为了计算位置编码,使用下面给出的公式。

        fig。计算位置编码的公式(来源:作者)

在上面的公式中,

  • pos = 单词在句子中的位置
  • d = 字/标记嵌入的维度
  • i = 表示嵌入中的每个维度

在计算中,d 是固定的,但 pos 和 i 会有所不同。如果 d=512,则 i ∈ [0, 255],因为我们取 2i。

如果您想了解更多信息,本视频将深入介绍位置编码。

转换器神经网络可视化指南 — (第 1 部分)位置嵌入

我正在使用上述视频中的一些视觉效果来用我的话来解释这个概念。

无花果。位置编码向量表示(来源:作者)

上图显示了位置编码向量的示例以及不同的变量值。

无花果。具有常数 i 和 d 的位置编码向量(来源:作者)

fig。具有常数 i 和 d 的位置编码向量(来源:作者)

上图显示了如果 i 是常量并且只有 pos 变化,PE(pos, 2i) 的值将如何变化。众所周知,正弦波是一个周期函数,倾向于在固定间隔后重复。我们可以看到 pos = 0 和 pos = 6 的编码向量是相同的。这是不可取的,因为我们需要不同的位置编码向量来表示不同的 pos 值

这可以通过改变正弦波的频率来实现。

无花果。具有不同 pos 和 i 的位置编码向量(来源:作者)

随着i的值变化,正弦波的频率也随之变化,导致不同的波,因此,导致每个位置编码向量的值不同。这正是我们想要实现的目标。

位置编码矩阵(P)被添加到输入矩阵(X)并馈送到编码器。

无花果。将位置编码添加到输入嵌入(来源:作者)

编码器的下一个组件是前馈网络

3.4 前馈网络

        编码器块中的这个子层是具有两个密集层和 ReLU 激活的经典神经网络。它接受来自多头注意力层的输入,对同一层执行一些非线性变换,最后生成上下文化向量。全连接层负责考虑每个注意力头并从中学习相关信息。由于注意力向量彼此独立,因此它们可以以并行方式传递到变压器网络。

        编码器块的最后一个也是最后一个组件是Add&Norm组件

3.5 添加和规范组件

这是一个残差层,然后是层归一化。残差层确保在处理过程中不会丢失与子层输入相关的重要信息。而规范化层可促进更快的模型训练并防止值发生大量变化。

无花果。包含添加和规范层的编码器组件(来源:作者)

        在编码器中,有两个添加层和规范层:

  • 将多头注意力子层的输入连接到其输出
  • 将前馈网络子图层的输入连接到其输出

        至此,我们总结编码器的内部工作。总结本文,让我们快速回顾一下编码器使用的步骤:

  • 生成输入句子的嵌入或标记化表示。这将是我们的输入矩阵 X。
  • 生成位置嵌入以保留与输入句子的词序相关的信息,并将其添加到输入矩阵 X 中。
  • 随机初始化三个矩阵:Wq,Wk和Wv,即查询,键和值的权重。这些权重将在变压器模型训练期间更新。
  • 将输入矩阵X与Wq,Wk和Wv中的每一个相乘,以生成Q(查询),K(键)和V(值)矩阵。
  • 计算 Q 和 K 转置的点积,通过将其除以 dk 的平方根或嵌入维数来缩放乘积,最后使用 softmax 函数对其进行归一化。
  • 通过将 V 或值矩阵乘以 softmax 函数的输出来计算注意力矩阵 Z。
  • 将此注意力矩阵传递给前馈网络以执行非线性转换并生成上下文化嵌入。

四、后记 

        在下一篇文章中,我们将了解转换器模型的解码器组件的工作原理。这就是本文的全部内容。我希望你觉得它有用。如果你这样做了,请不要忘记鼓掌并与您的朋友分享。

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

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

相关文章

ARTS 挑战打卡的第8天 ---volatile 关键字在MCU中的作用,四个实例讲解(Tips)

前言 (1)volatile 关键字作为嵌入式面试的常考点,很多人都不是很了解,或者说一知半解。 (2)可能有些人会说了,volatile 关键字不就是防止编译器优化的吗?有啥好详细讲解的&#xff1…

清除pip安装库时的缓存

目录 1、命令清除缓存 2、路径手动清除 在使用pip安装Python库时,如果之前已经下载过该库,pip会默认使用缓存来安装库,而不是重新从网络上下载。缓存文件通常存储在用户目录下的缓存文件夹中,具体位置因操作系统和Python版本而异…

C语言中几种常见数据类型所占字节数

**16位编译器: char/unsigned char :1字节 char :2字节 short int:2字节 int/unsigned int:2字节 long int:4字节 float:4字节 double:8字节* 32位编译器: *char/unsi…

腾讯云服务器标准型CVM实例详细介绍S5/S6/SA2/SR1/SA3/S4等

腾讯云CVM服务器标准型实例的各项性能参数平衡,标准型云服务器适用于大多数常规业务,例如:web网站及中间件等,常见的标准型云服务器有CVM标准型S5、S6、SA3、SR1、S5se等规格,腾讯云服务器网来详细说下云服务器CVM标准…

悬崖传感器调试问题总结

悬崖传感器原理 使用ADC采样电路,周期的进行开/关灯,获取ADC采样值。根据预先设置好ADC门限,判断是否为悬崖。ADC的精度是12位,对应电路的电压是3.3伏,悬崖传感器通过开灯和关灯,接收的不同灯光强度&#x…

【福建事业单位-数学运算】02工程问题-行程问题

【福建事业单位-数学运算】02工程问题-行程问题 一、工程问题1.1给完工时间型(给多个完工时间)——从时间赋值总量例题 1.2 给效率比例型(给效率的比例关系)直接给效率间接给效率(★)特殊给效率 1.3 给具体…

掌握Python的X篇_30_使用python解析网页HTML

本篇将会介绍beutifulsoup4模块,可以用于网络爬虫、解析HTML和XML,对于没有接触过前端,不了解HTML是如何工作的,需要先解释一下什么事HTML。 1. HTML 网页中的各种布局等的背后都是非常简单的纯文本格式,那种格式称为…

【JDBC系列】- 扩展提升学习

扩展提升学习 😄生命不息,写作不止 🔥 继续踏上学习之路,学之分享笔记 👊 总有一天我也能像各位大佬一样 🏆 博客首页 怒放吧德德 To记录领地 🌝分享学习心得,欢迎指正&#xff0…

Golang 基本常量声明及 iota 使用

文章目录 一、局部常量声明二、全局常量声明三、多行常量定义,值表达式为空时自动继承前一个四、常量声明 - iota 一、局部常量声明 package mainimport "fmt"func main() {//局部常量声明//方式一:主动声明类型const lengthA int 10//方式二…

tomcat设置PermSize

最近tomcat老是报错,查看了日志出现PermGen 内存不够用,重启tomcat后查询使用情况 通过启动参数发现没有设置 PermGen,继续通过jmap查看 jmap -heap 21179 发现99%已使用,而且默认是30.5M,太小了,这里设置成256M 1. 创建setenv.sh文件 在/usr/local/tomcat/bin目录下创建一个…

CDN是什么?CDN的好处

近段时间开组会的时候组内的大佬多次提及CDN这个名词,因为以前没有接触过,所以上网查询后写一篇博客来巩固自己对于CDN的理解 1、什么是CDN CDN的全称是Content Delivery Network,即内容分发网络。其目的是通过在现有的Internet中增加一层新…

Linux命令200例:ls用于列出指定目录下的文件和子目录

🏆作者简介,黑夜开发者,全栈领域新星创作者✌。CSDN专家博主,阿里云社区专家博主,2023年6月csdn上海赛道top4。 🏆数年电商行业从业经验,历任核心研发工程师,项目技术负责人。 &…

Java实现对称加密(DES,AES)快速入门示例

对称加密是使用相同的密码进行加密和解密, 对称加密实现简单,安全性相比非对称加密较弱, 常用的对称加密算法有 DES,AES以及PDE等,关于对称加密相关概念参考: 对称加密、非对称加密深度解析 本篇介绍Java的…

【CSH 入门基础 5 -- csh 文件监控脚本实现】

文章目录 背景CSHLL 代码实现cshell 中 unset 的介绍bash 中监控文件的方法 背景 由于开发代码是在外网编译,而镜像的烧写是在内网中的EDA工具中进行的,所以就需要先将代码在外网编译好后,再通过FTP工具将镜像传输到内网中,然后在…

MyBatis配置文件:配置连接数据库的环境,实现数据库连接

目录 1、MyBatis配置数据库环境的连接方式 1.1连接方式一:MyBatis核心配置文件配置数据库连接信息 1.2连接方式二:在MyBatis核心配置文件中引入properties文件,配置数据库的环境 2、MyBatisd核心配置文件连接数据库的环境完整配置信息 3…

Win11麦克风说话别人听不见解决办法

Win11麦克风说话别人听不到声音怎么办?麦克风没有声音可能有三种原因造成的,第一种声音设置里面确认麦克风设备是否启用,第二种查看麦克风的访问权限,第三种是检查驱动是否有问题,下面就简单的讲一下解决方法&#xff…

【loadbalancer】还在用Ribbon?试试Spring自带的LoadBalancer吧

Spring Cloud LoadBalancer是Spring Cloud官方自己提供的客户端负载均衡器, 用来替代Ribbon。 Spring官方提供了两种客户端都可以使用loadbalancer: RestTemplate:Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程…

【第二阶段】it关键字

1.invoke()函数 meThod1(1,2,3)等价meThod1.invoke(1,2,3) fun main() {val meThod1:(Int,Int,Int)->String{n1,n2,n3->val num"kotlin"println("num$num,n1$n1,n2$n2,,n3$n3")"num$num,n1$n1,n2$n2,,n3$n3,"}//调…

Vue响应式数据的原理

在 vue2 的响应式中,存在着添加属性、删除属性、以及通过下标修改数组,但页面不会自动更新的问题。而这些问题在 vue3 中都得以解决。 vue3 采用了 proxy 代理,用于拦截对象中任意属性的变化,包括:属性的读写、属性的…

前端使用ReadableStream.getReader来处理流式渲染

文章目录 前言一、纯css二、vue-typed-js插件1.安装2.注册3.使用总结 三、ReadableStream1.ReadableStream是什么?2.ReadableStream做什么?3.ReadableStream怎么用 前言 需求:让接口返回的文章根据请求一段一段的渲染,同时可以点击…