跟着问题学18——大模型基础transformer模型详解(4)解码器

 3 Decoder层

图中可以看到,解码器Decoder其实和编码器Encoder大同小异,核心区别是在最下面额外多了一个掩码多头注意力层masked mutil-head attetion。在解码器中,自注意力层仅被允许“注意”输出序列中前面的单词信息。这是通过在自注意力计算中的softmax步骤之前屏蔽未来位置(将其设置为-inf)来完成的。 下面我们详细介绍一下各部分,尤其是差异点。

3.1 Decode的输入

从图中可以看到,解码器的输入来源有2个,一个是掩码后的词向量+位置编码向量,经由掩码自注意力层和残差正则化传递;第二个输入则是解码层中最后一个解码器的输出,储存着编码层的全部信息(类似seq2seq框架的中间向量)。二者结合经过解码器-编码器的注意力层,再经由残差正则化传递给前馈网络层,再次经由残差正则化结构传递给下个解码器,直至最后的输出。

3.2 Mask

接着我们学习一下Mask机制。Mask 表示掩码,它对某些值进行掩盖,使其在参数更新时不产生效果。它经常被用于NLP任务中,按照作用总体来说可以分成两类:

  1. 用于处理非定长序列的padding mask;
  2. 用于防止标签泄露的sequence mask。

Transformer中同时用到了这两种Mask机制。

其中,padding mask 在所有的 scaled dot-product attention 里面都需要用到(包括前面的编码器),而 sequence mask 只有在解码器decoder 的 self-attention 里面用到。

padding mask

在NLP任务中,文本通常是不定长的,计算注意力得分时attention score会出现偏差,所以在输入一个样本长短不一的批量数据batch(这里的batch指有多个句子)到网络前,要对batch中的样本进行truncating截断/padding补齐操作,以便能形成一个张量的形式输入网络,如下图所示。

具体的做法是,对于一个长度不足的样本,往往采用特殊字符"<PAD>"进行padding,把这些位置的值加上一个非常大的负数(负无穷),这样的话,经过 softmax,这些位置的概率就会接近0!在训练时利用Mask矩阵将补全的位置给mask掉。Mask矩阵中可以用1表示有效字,0代表无效字(也可以用True/False)。值为 false 的地方就是我们要进行处理的地方,也就是说输出矩阵和Mask矩阵为false的对应位置处补一些无穷小(负无穷)的值。

分为如下两步:

1)padding(补齐)操作在batch输入网络前完成同步生成padding mask矩阵(用于记录后续输出矩阵需要mask的位置);

2)根据padding mask矩阵,Q和K在点积之后,需要先经过mask,将输出矩阵和Mask矩阵为false的对应位置处补一些无穷小(负无穷)的值,再进行softmax.

def attention(query, key, value, mask=None, dropout=None):
    "Compute 'Scaled Dot Product Attention'"
    d_k = query.size(-1)
    scores = torch.matmul(query, key.transpose(-2, -1)) / math.sqrt(d_k)
    if mask is not None:
        scores = scores.masked_fill(mask == 0, -1e9) # mask步骤,用 -1e9 代表负无穷
    p_attn = F.softmax(scores, dim = -1)
    if dropout is not None:
        p_attn = dropout(p_attn)
    return torch.matmul(p_attn, value), p_attn

sequence mask

sequence mask 是为了使得 decoder 不能看见未来的信息。也就是对于一个序列,在 time_step 为 t 的时刻,我们的解码输出应该只能依赖于 t 时刻之前的输出,而不能依赖 t 之后的输出。最常见的应用场景是在需要预测下一个词的时候,如果用self attention 或者是其他同时使用上下文信息的机制,会导致模型”提前看到“待预测的内容,这显然不行,所以为了不泄露要预测的标签信息,需要想一个办法,把 t 之后的信息给隐藏起来,就需要 mask 来“遮盖”它。

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

如下图所示,这也是Transformer中Decoder的Masked Multi-Head self-attention使用的Mask机制

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

除了在decoder部分加入mask防止标签泄露以外,还有模型利用这种填空机制帮助模型学的更好,比如说BERT和ERNIE模型中利用到的Masked LM(MLM)。(注意:BERT模型只有Transformer的Encoder层,是可以学习上下文信息的

3.3 Decoder

 “编码器-解码器-注意力”层的工作原理与多头自注意力类似,只是它从下面的解码器创建查询矩阵,并从编码器堆栈的输出中获取键和值矩阵。编码器通过处理输入序列,然后将顶部编码器的输出转换为一组注意向量k和v。

每个解码器将在其“encoder-decoder attention”层中使用这些注意向量,这有助于解码器将注意力集中在输入序列中的适当位置。

解码阶段的每个步骤从输出序列(本例中为英语翻译句)输出一个元素。
以下步骤重复此过程,一直到达到表示解码器已完成输出的符号。每一步的输出在下一个时间步被送入底部解码器,解码器像就像我们对编码器输入所做操作那样,我们将位置编码嵌入并添加到这些解码器输入中,以表示每个字的位置。

3.4 输出层linear 和softmax

解码器堆栈输出一个浮点向量。我们如何将其转化为一个词?这是最后一个线性层的工作,后面是Softmax层。假如我们的词典是1w个词,那最终softmax会输入1w个词的概率,概率值最大的对应的词就是我们最终的结果。
         线性层是一个简单的全连接神经网络,它将解码器堆栈产生的向量投影到一个更大的向量中,称为logits向量。

让我们假设我们的模型知道10000个独特的英语单词(我们模型的“输出词汇表”),这些单词是从训练数据集中学习的。这将使logits矢量宽度为10000个单元格——每个单元格对应一个唯一单词的分数。这就是我们解释线性层后面的模型输出的方式。

softmax层然后将这些分数转换为概率(全部为正,加起来为1.0)。选择具有最高概率的单元,并产生与其相关联的字作为该时间步长的输出。

4 网络模型框架小结

5 模型训练

现在我们已经通过一个经过训练的Transformer介绍了整个前向传递过程,最后看看模型是如何训练的。

在训练过程中,未经训练的模型会经历完全相同的正向传递。但由于我们在标记的训练数据集上训练它,我们可以将其输出与实际的正确输出进行比较。

为了形象化这一点,假设输出词汇表只包含六个单词(“a”、“am”、“i”、“thanks”、“student”和“<eos>”(“句末”的缩写))。

一旦我们定义了输出词汇表,我们就可以使用相同宽度的向量来指示词汇表中的每个单词。这也被称为一个热编码。例如,我们可以使用以下向量来表示单词“am”: 注意这里的独热编码是监督量,实际上是和decoder层最后softmax输出的预测概率向量作比较的。

示例:我们的输出词汇表的一个热门编码

再讨论一下模型的损失函数——我们在训练阶段优

假设我们正在训练我们的模型。假设这是我们在培训阶段的第一步,我们正在以一个简单的例子进行培训——将“merci”翻译成“谢谢”。

这意味着,我们希望输出是一个概率分布,表示单词“谢谢”。但由于这个模型还没有经过训练,目前还不太可能实现。

由于模型的参数(权重)都是随机初始化的,(未经训练的)模型为每个单元/单词产生具有任意值的概率分布。我们可以将其与实际输出进行比较,然后使用反向传播调整模型的所有权重,使输出更接近所需输出。

你如何比较两种概率分布?我们只是从另一个中减去一个。

但请注意,这是一个过于简单化的例子。更现实地说,我们将使用比一个单词更长的句子。例如,输入:“je suisétudant”,预期输出:“我是一名学生”。这真正意味着,我们希望我们的模型连续输出概率分布,其中:

每个概率分布由宽度为vocab_size的矢量表示(在我们的示例中为6,但更实际的是一个类似30000或50000的数字)

第一个概率分布在与单词“i”相关联的单元处具有最高概率

第二个概率分布在与单词“am”相关联的单元格处具有最高概率

依此类推,直到第五个输出分布指示“<句子结束>”符号,该符号也有一个与10000元素词汇表中的单元格相关联。

我们将在一个样本句子的训练示例中针对目标概率分布来训练我们的模型。

在足够大的数据集上训练模型足够长的时间后,我们希望产生的概率分布如下所示:

希望通过培训,该模型能够输出我们期望的正确翻译。当然,这并不能真正表明这个短语是否是训练数据集的一部分(请参阅:交叉验证)。请注意,每个位置都有一点概率,即使它不太可能是该时间步长的输出——这是softmax的一个非常有用的特性,有助于训练过程。

现在,因为模型一次产生一个输出,我们可以假设模型从概率分布中选择概率最高的单词,然后扔掉其余的。这是一种方法(称为贪婪解码)。另一种方法是抓住前两个单词(例如“I”和“a”),然后在下一步中运行模型两次:一次假设第一个输出位置是单词“I”,另一次假设第二个输出位置为单词“a”,无论哪个版本在考虑位置#1和#2的情况下都会产生较小的错误。我们对位置#2和#3重复此操作…等。这种方法被称为“波束搜索”,在我们的例子中,beam_size是两个(意味着在任何时候,两个部分假设(未完成的翻译)都保存在内存中),而top_beams也是两个(这意味着我们将返回两个翻译)。这两个超参数都可以进行实验。

参考资料

The Illustrated Transformer – Jay Alammar – Visualizing machine learning one concept at a time.

李宏毅transformer视频课程

https://zhuanlan.zhihu.com/p/338817680

Transformer:注意力机制(attention)和自注意力机制(self-attention)的学习总结_注意力机制和自注意力机制-CSDN博客

10.1. 注意力提示 — 动手学深度学习 2.0.0 documentation

跟着问题学18——万字长文详解Transformer-CSDN博客

【深度学习】batch normalization和layer normalization区别_layer normalization和batch normaliza

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

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

相关文章

day-102 二叉树中的链表

思路 DFS,先将链表转换为字符串s在进行匹配 解题过程 对二叉树进行遍历&#xff0c;每到一个新节点判断当前的字符串t长度是否大于等于的长度&#xff0c;如果满足&#xff0c;再将t从末尾截取s.length()长度的子串与s进行匹配&#xff0c;若匹配成功&#xff0c;结果为true&a…

RACI矩阵在项目管理中的应用:优化任务管理

在团队合作中&#xff0c;最怕的就是责任不清、任务分工混乱。谁该做什么&#xff0c;谁对结果负责&#xff0c;谁需要提供帮助&#xff0c;谁需要被通知&#xff1f;如果这些问题没有理清楚&#xff0c;就很容易出现任务没完成、团队内耗或者“甩锅”的情况。RACI责任矩阵正是…

uniapp - 小程序实现摄像头拍照 + 水印绘制 + 反转摄像头 + 拍之前显示时间+地点 + 图片上传到阿里云服务器

前言 uniapp&#xff0c;碰到新需求&#xff0c;反转摄像头&#xff0c;需要在打卡的时候对上传图片加上水印&#xff0c;拍照前就显示当前时间日期地点&#xff0c;拍摄后在呈现刚才拍摄的图加上水印&#xff0c;最好还需要将图片上传到阿里云。 声明 水印部分代码是借鉴的…

Fetch处理大模型流式数据请求与解析

为什么有的大模型可以一次返回多个 data&#xff1f; Server-Sent Events (SSE)&#xff1a;允许服务器连续发送多个 data: 行&#xff0c;每个代表一个独立的数据块。 流式响应&#xff1a;大模型服务通常以流式响应方式返回数据&#xff0c;提高响应速度。 批量处理&#x…

怎么在电脑桌面上设置备忘录,桌面工作提醒小工具哪个好?

在现代的工作和生活中&#xff0c;我们经常需要记录重要的事项和提醒。而在电脑上设置备忘录&#xff0c;无疑是最方便和有效的方法之一。那么&#xff0c;怎么在电脑桌面上设置备忘录&#xff1f;又有哪个工作提醒小工具值得推荐呢&#xff1f; 以Windows系统为例&#xff0c…

EasyExcel简介和读写操作

EasyExcel简介 官网地址&#xff1a;EasyExcel官方文档 - 基于Java的Excel处理工具 | Easy Excel 官网 EasyExcel 的主要特点如下&#xff1a; 1、高性能&#xff1a;EasyExcel 采用了异步导入导出的方式&#xff0c;并且底层使用 NIO 技术实现&#xff0c;使得其在导入导出大…

【网络协议】路由信息协议 (RIP)

未经许可&#xff0c;不得转载。 路由信息协议&#xff08;Routing Information Protocol&#xff0c;简称 RIP&#xff09;是一种使用跳数&#xff08;hop count&#xff09;作为路由度量标准的路由协议&#xff0c;用于确定源网络和目标网络之间的最佳路径。 文章目录 什么是…

MySQL5.7.26-Linux-安装(2024.12)

文章目录 1.下载压缩包1.访问MySQL版本归档2.找到5.7.26并下载3.百度网盘 2.Linux安装1.卸载原来的MySQL8.0.26&#xff08;如果没有则无需在意&#xff09;1.查看所有mysql的包2.批量卸载3.删除残留文件**配置文件**&#xff08;默认路径&#xff09;&#xff1a; 4.**验证卸载…

《云原生安全攻防》-- K8s安全配置:CIS安全基准与kube-bench工具

在本节课程中&#xff0c;我们来了解一下K8s集群的安全配置&#xff0c;通过对CIS安全基准和kube-bench工具的介绍&#xff0c;可以快速发现K8s集群中不符合最佳实践的配置项&#xff0c;及时进行修复&#xff0c;从而来提高集群的安全性。 在这个课程中&#xff0c;我们将学习…

Flink源码解析之:如何根据算法生成StreamGraph过程

Flink源码解析之&#xff1a;如何根据算法生成StreamGraph过程 在我们日常编写Flink应用的时候&#xff0c;会首先创建一个StreamExecutionEnvironment.getExecutionEnvironment()对象&#xff0c;在添加一些自定义处理算子后&#xff0c;会调用env.execute来执行定义好的Flin…

RoboMIND:多体现基准 机器人操纵的智能规范数据

我们介绍了 RoboMIND&#xff0c;这是机器人操纵的多体现智能规范数据的基准&#xff0c;包括 4 个实施例、279 个不同任务和 61 个不同对象类别的 55k 真实世界演示轨迹。 工业机器人企业 埃斯顿自动化 | 埃夫特机器人 | 节卡机器人 | 珞石机器人 | 法奥机器人 | 非夕科技 | C…

sentinel集成nacos启动报[check-update] get changed dataId error, code: 403错误排查及解决

整合nacos报403错误 因为平台写的一个限流代码逻辑有问题&#xff0c;所以准备使用sentinel来限流。平台依赖里面已经引入了&#xff0c;之前也测试过&#xff0c;把sentinel关于nacos的配置加上后&#xff0c;启动一直输出403错误 [fixed-10.0.20.188_8848-test] [check-upda…

【Redis】 数据淘汰策略

面试官询问缓存过多而内存有限时内存被占满的处理办法&#xff0c;引出 Redis 数据淘汰策略。 数据淘汰策略与数据过期策略不同&#xff0c; 过期策略针对设置过期时间的 key 删除&#xff0c; 淘汰策略是在内存不够时按规则删除内存数据。 八种数据淘汰策略介绍 no evision&…

【畅购商城】详情页模块之评论

目录 接口 分析 后端实现&#xff1a;JavaBean 后端实现 前端实现 接口 GET http://localhost:10010/web-service/comments/spu/2?current1&size2 { "code": 20000, "message": "查询成功", "data": { "impressions&q…

Kafka高性能设计

高性能设计概述 Kafka高性能是多方面协同的结果&#xff0c;包括集群架构、分布式存储、ISR数据同步及高效利用磁盘和操作系统特性等。主要体现在消息分区、顺序读写、页缓存、零拷贝、消息压缩和分批发送六个方面。 消息分区 存储不受单台服务器限制&#xff0c;能处理更多数据…

HTML——13.超链接

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>超链接</title></head><body><!--超链接:从一个网页链接到另一个网页--><!--语法&#xff1a;<a href"淘宝网链接的地址"> 淘宝…

LVS 负载均衡原理 | 配置示例

注&#xff1a;本文为 “ LVS 负载均衡原理 | 配置” 相关文章合辑。 部分内容已过时&#xff0c;可以看看原理实现。 使用 LVS 实现负载均衡原理及安装配置详解 posted on 2017-02-12 14:35 肖邦 linux 负载均衡集群是 load balance 集群的简写&#xff0c;翻译成中文就是负…

Docker 快速搭建 GBase 8s数据库服务

1.查看Gbase 8s镜像版本 可以去到docker hub网站搜索&#xff1a;gbase8s liaosnet/gbase8s如果无法访问到该网站&#xff0c;可以通过docker search搜索 docker search gbase8s2.拉取Gbase 8s镜像 以下演示的版本是目前官网最新版本Gbase8sV8.8_3.5.1 docker pull liaosn…

使用Lodash工具库的orderby和sortby进行排序的区别

简介 _.orderBy 和 _.sortBy 是 Lodash 库中用于排序数组的两个函数。 区别 _.orderBy 允许你指定一个或多个属性来排序&#xff0c;并为每个属性指定排序方向&#xff08;升序或降序&#xff09;。默认所有值为升序排&#xff0c;指定为"desc" 降序&#xff0c…

uniapp中Nvue白屏问题 ReferenceError: require is not defined

uniapp控制台输出如下 exception function:createInstanceContext, exception:white screen cause create instanceContext failed,check js stack ->Uncaught ReferenceError: require is not defined 或者 exception function:createInstanceContext, exception:white s…