0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于 Transformers 的编码器-解码器模型

深度学习自然语言处理 来源:深度学习自然语言处理 2023-06-16 16:53 次阅读

基于 transformer 的编码器-解码器模型是 表征学习 和 模型架构 这两个领域多年研究成果的结晶。本文简要介绍了神经编码器-解码器模型的历史,更多背景知识,建议读者阅读由 Sebastion Ruder 撰写的这篇精彩 博文。此外,建议读者对 自注意力 (self-attention) 架构 有一个基本了解,可以阅读 Jay Alammar 的 这篇博文 复习一下原始 transformer 模型。

本文分 4 个部分:

背景 - 简要回顾了神经编码器-解码器模型的历史,重点关注基于 RNN 的模型。

编码器-解码器 - 阐述基于 transformer 的编码器-解码器模型,并阐述如何使用该模型进行推理。

编码器 - 阐述模型的编码器部分。

解码器 - 阐述模型的解码器部分。

每个部分都建立在前一部分的基础上,但也可以单独阅读。这篇分享是第三部分 编码器

编码器

如前一节所述, 基于 transformer 的编码器将输入序列映射到上下文相关的编码序列:

仔细观察架构,基于 transformer 的编码器由许多 残差注意力模块 堆叠而成。每个编码器模块都包含一个 双向 自注意力层,其后跟着两个前馈层。这里,为简单起见,我们忽略归一化层 (normalization layer)。此外,我们不会深入讨论两个前馈层的作用,仅将其视为每个编码器模块 的输出映射层。双向自注意层将每个输入向量 与全部输入向量 相关联并通过该机制将每个输入向量 提炼为与其自身上下文相关的表征: 。因此,第一个编码器块将输入序列 (如下图浅绿色所示) 中的每个输入向量从 上下文无关 的向量表征转换为 上下文相关 的向量表征,后面每一个编码器模块都会进一步细化这个上下文表征,直到最后一个编码器模块输出最终的上下文相关编码 (如下图深绿色所示)。

我们对 编码器如何将输入序列 "I want to buy a car EOS" 变换为上下文编码序列这一过程进行一下可视化。与基于 RNN 的编码器类似,基于 transformer 的编码器也在输入序列最后添加了一个 EOS,以提示模型输入向量序列已结束 。

1e20e638-0c1f-11ee-962d-dac502259ad0.png

上图中的 基于 transformer 的编码器由三个编码器模块组成。我们在右侧的红框中详细列出了第二个编码器模块的前三个输入向量: , 及 。红框下部的全连接图描述了双向自注意力机制,上面是两个前馈层。如前所述,我们主要关注双向自注意力机制。

可以看出,自注意力层的每个输出向量 都 直接 依赖于 所有 输入向量 。这意味着,单词 “want” 的输入向量表示 与单词 “buy” (即 ) 和单词 “I” (即 ) 直接相关。 因此,“want” 的输出向量表征, 即 ,是一个融合了其上下文信息的更精细的表征。

我们更深入了解一下双向自注意力的工作原理。编码器模块的输入序列 中的每个输入向量 通过三个可训练的权重矩阵 ,, 分别投影至 key 向量 、value 向量 和 query 向量 (下图分别以橙色、蓝色和紫色表示):

请注意,对每个输入向量 ) 而言,其所使用的权重矩阵都是 相同 的。将每个输入向量 投影到 query 、 key 和 value 向量后,将每个 query 向量 ) 与所有 key 向量 进行比较。哪个 key 向量与 query 向量 越相似,其对应的 value 向量 对输出向量 的影响就越重要。更具体地说,输出向量 被定义为所有 value 向量的加权和 加上输入向量 。而各 value 向量的权重与 和各个 key 向量 之间的余弦相似度成正比,其数学公式为 ,如下文的公式所示。关于自注意力层的完整描述,建议读者阅读 这篇 博文或 原始论文。

好吧,又复杂起来了。我们以上例中的一个 query 向量为例图解一下双向自注意层。为简单起见,本例中假设我们的 基于 transformer 的解码器只有一个注意力头 config.num_heads = 1 并且没有归一化层。

1e43c89c-0c1f-11ee-962d-dac502259ad0.png

图左显示了上个例子中的第二个编码器模块,右边详细可视化了第二个输入向量 的双向自注意机制,其对应输入词为 “want”。首先将所有输入向量 投影到它们各自的 query 向量 (上图中仅以紫色显示前三个 query 向量), value 向量 (蓝色) 和 key 向量 (橙色)。然后,将 query 向量 与所有 key 向量的转置 ( 即 ) 相乘,随后进行 softmax 操作以产生 自注意力权重 。 自注意力权重最终与各自的 value 向量相乘,并加上输入向量 ,最终输出单词 “want” 的上下文相关表征, 即 (图右深绿色表示)。整个等式显示在图右框的上部。 和 的相乘使得将 “want” 的向量表征与所有其他输入 (“I”,“to”,“buy”,“a”,“car”,“EOS”) 的向量表征相比较成为可能,因此自注意力权重反映出每个输入向量 对 “want” 一词的最终表征 的重要程度。

为了进一步理解双向自注意力层的含义,我们假设以下句子: “ 房子很漂亮且位于市中心,因此那儿公共交通很方便 ”。 “那儿”这个词指的是“房子”,这两个词相隔 12 个字。在基于 transformer 的编码器中,双向自注意力层运算一次,即可将“房子”的输入向量与“那儿”的输入向量相关联。相比之下,在基于 RNN 的编码器中,相距 12 个字的词将需要至少 12 个时间步的运算,这意味着在基于 RNN 的编码器中所需数学运算与距离呈线性关系。这使得基于 RNN 的编码器更难对长程上下文表征进行建模。此外,很明显,基于 transformer 的编码器比基于 RNN 的编码器-解码器模型更不容易丢失重要信息,因为编码的序列长度相对输入序列长度保持不变, 即 ,而 RNN 则会将 压缩到 ,这使得 RNN 很难有效地对输入词之间的长程依赖关系进行编码。

除了更容易学到长程依赖外,我们还可以看到 transformer 架构能够并行处理文本。从数学上讲,这是通过将自注意力机制表示为 query 、 key 和 value 的矩阵乘来完成的:

输出 是由一系列矩阵乘计算和 softmax 操作算得,因此可以有效地并行化。请注意,在基于 RNN 的编码器模型中,隐含状态 的计算必须按顺序进行: 先计算第一个输入向量的隐含状态 ; 然后计算第二个输入向量的隐含状态,其取决于第一个隐含向量的状态,依此类推。RNN 的顺序性阻碍了有效的并行化,并使其在现代 GPU 硬件上比基于 transformer 的编码器模型的效率低得多。

太好了,现在我们应该对:
a) 基于 transformer 的编码器模型如何有效地建模长程上下文表征,以及
b) 它们如何有效地处理长序列向量输入这两个方面有了比较好的理解了。

现在,我们写一个 MarianMT 编码器-解码器模型的编码器部分的小例子,以验证这些理论在实践中行不行得通。

关于前馈层在基于 transformer 的模型中所扮演的角色的详细解释超出了本文的范畴。Yun 等人 (2017) 的工作认为前馈层对于将每个上下文向量 映射到目标输出空间至关重要,而单靠 自注意力 层无法达成这一目的。这里请注意,每个输出词元 都经由相同的前馈层处理。更多详细信息,建议读者阅读论文。

我们无须将 EOS 附加到输入序列,虽然有工作表明,在很多情况下加入它可以提高性能。相反地,基于 transformer 的解码器必须把 作为第 0 个目标向量,并以之为条件预测第 1 个目标向量。

fromtransformersimportMarianMTModel,MarianTokenizer
importtorch

tokenizer=MarianTokenizer.from_pretrained("Helsinki-NLP/opus-mt-en-de")
model=MarianMTModel.from_pretrained("Helsinki-NLP/opus-mt-en-de")

embeddings=model.get_input_embeddings()

#createidsofencodedinputvectors
input_ids=tokenizer("Iwanttobuyacar",return_tensors="pt").input_ids

#passinput_idstoencoder
encoder_hidden_states=model.base_model.encoder(input_ids,return_dict=True).last_hidden_state

#changetheinputslightlyandpasstoencoder
input_ids_perturbed=tokenizer("Iwanttobuyahouse",return_tensors="pt").input_ids
encoder_hidden_states_perturbed=model.base_model.encoder(input_ids_perturbed,return_dict=True).last_hidden_state

#compareshapeandencodingoffirstvector
print(f"Lengthofinputembeddings{embeddings(input_ids).shape[1]}.Lengthofencoder_hidden_states{encoder_hidden_states.shape[1]}")

#comparevaluesofwordembeddingof"I"forinput_idsandperturbedinput_ids
print("Isencodingfor`I`equaltoitsperturbedversion?:",torch.allclose(encoder_hidden_states[0,0],encoder_hidden_states_perturbed[0,0],atol=1e-3))

输出:

Lengthofinputembeddings7.Lengthofencoder_hidden_states7
Isencodingfor`I`equaltoitsperturbedversion?:False

我们比较一下输入词嵌入的序列长度 ( 即 embeddings(input_ids),对应于 ) 和 encoder_hidden_states 的长度 (对应于)。同时,我们让编码器对单词序列 “I want to buy a car” 及其轻微改动版 “I want to buy a house” 分别执行前向操作,以检查第一个词 “I” 的输出编码在更改输入序列的最后一个单词后是否会有所不同。

不出意外,输入词嵌入和编码器输出编码的长度, 即 和 ,是相等的。同时,可以注意到当最后一个单词从 “car” 改成 “house” 后, 的编码输出向量的值也改变了。因为我们现在已经理解了双向自注意力机制,这就不足为奇了。

顺带一提, 自编码 模型 (如 BERT) 的架构与 基于 transformer 的编码器模型是完全一样的。 自编码 模型利用这种架构对开放域文本数据进行大规模自监督预训练,以便它们可以将任何单词序列映射到深度双向表征。在 Devlin 等 (2018) 的工作中,作者展示了一个预训练 BERT 模型,其顶部有一个任务相关的分类层,可以在 11 个 NLP 任务上获得 SOTA 结果。你可以从 此处 找到 transformers 支持的所有 自编码 模型。
责任编辑:彭菁

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 解码器
    +关注

    关注

    9

    文章

    1133

    浏览量

    40694
  • 编码器
    +关注

    关注

    45

    文章

    3604

    浏览量

    134258
  • 数据
    +关注

    关注

    8

    文章

    6926

    浏览量

    88867

原文标题:编码器 | 基于 Transformers 的编码器-解码器模型

文章出处:【微信号:zenRRan,微信公众号:深度学习自然语言处理】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    怎么理解真正的编码器解码器

      在进入关于编码器解码器的现实之前,让我们对复用进行简要的思考。通常我们会在需要将一些输入信号一次一个地加载到一个单独负载的应用程序中。选择输入信号中的一个输入信号的过程称为多路复用。这种操作
    发表于 09-01 17:48

    编码器解码器的区别是什么,编码器用软件还是硬件好

    编码器指的是对视频信号进行压缩,解码器主要是将压缩的视频信号进行解压缩。目前做直播的很多都是采用的编码器,客户端可以采用解码器或软件播放
    发表于 08-02 17:23 3.4w次阅读

    基于结构感知的双编码器解码器模型

    ,在常见端到端翻译模型的基础上,利用代码抽象语法树将源代码的结构信息嵌入到编码器解码器翻译模型中,提出一种基于结构感知的双编码器
    发表于 05-26 15:38 5次下载

    详解编码器解码器电路:定义/工作原理/应用/真值表

    编码器解码器是组合逻辑电路,在其中,主要借助布尔代数实现组合逻辑。今天就大家了解一下编码器解码器电路,分别从定义,工作原理,应用,真值表几个方面讲述一下。
    的头像 发表于 11-03 09:22 7196次阅读
    详解<b class='flag-5'>编码器</b>和<b class='flag-5'>解码器</b>电路:定义/工作原理/应用/真值表

    PyTorch教程10.6之编码器-解码器架构

    电子发烧友网站提供《PyTorch教程10.6之编码器-解码器架构.pdf》资料免费下载
    发表于 06-05 18:12 0次下载
    PyTorch教程10.6之<b class='flag-5'>编码器</b>-<b class='flag-5'>解码器</b>架构

    PyTorch教程-10.6. 编码器-解码器架构

    -解码器架构(图 10.6.1),它由两个主要组件组成:一个 编码器,它以可变长度序列作为输入,以及一个 解码器,作为一个条件语言模型,接收编码
    的头像 发表于 06-05 15:44 829次阅读
    PyTorch教程-10.6. <b class='flag-5'>编码器</b>-<b class='flag-5'>解码器</b>架构

    基于transformer的编码器-解码器模型的工作原理

    与基于 RNN 的编码器-解码器模型类似,基于 transformer 的编码器-解码器模型由一
    发表于 06-11 14:17 2188次阅读
    基于transformer的<b class='flag-5'>编码器</b>-<b class='flag-5'>解码器</b><b class='flag-5'>模型</b>的工作原理

    基于 RNN 的解码器架构如何建模

      Vaswani 等人在其名作 Attention is all you need 中首创了 基于 transformer 的编码器-解码器模型,如今已成为自然语言处理 (natural
    的头像 发表于 06-12 17:08 784次阅读
    基于 RNN 的<b class='flag-5'>解码器</b>架构如何建模

    神经编码器-解码器模型的历史

    基于 transformer 的编码器-解码器模型是 表征学习 和 模型架构 这两个领域多年研究成果的结晶。本文简要介绍了神经编码器-
    的头像 发表于 06-20 15:42 840次阅读
    神经<b class='flag-5'>编码器</b>-<b class='flag-5'>解码器</b><b class='flag-5'>模型</b>的历史

    详解编码器解码器电路

    编码器解码器是组合逻辑电路,在其中,主要借助布尔代数实现组合逻辑。今天就大家了解一下编码器解码器电路,分别从定义,工作原理,应用,真值表几个方面讲述一下。
    的头像 发表于 07-14 09:07 3097次阅读
    详解<b class='flag-5'>编码器</b>和<b class='flag-5'>解码器</b>电路

    视频编码器解码器的应用方案

    视频解码器和视频编码器在数字通讯、音视频压缩领域有着广泛的应用。视频编码器作为视频源的发送端,若接收端如果是 PC 机或显示设备就需要通过解码器进行
    的头像 发表于 08-14 14:38 1316次阅读
    视频<b class='flag-5'>编码器</b>与<b class='flag-5'>解码器</b>的应用方案

    YXC丨视频编码器解码器的应用方案

    视频解码器和视频编码器是数字信号处理中常用的设备,它们在数据的传输和转换中发挥着重要作用。
    的头像 发表于 08-23 09:40 655次阅读
    YXC丨视频<b class='flag-5'>编码器</b>与<b class='flag-5'>解码器</b>的应用方案

    视频编码器解码器的应用方案

    视频解码器和视频编码器是数字信号处理中常用的设备,它们在数据的传输和转换中发挥着重要作用。
    的头像 发表于 08-28 11:31 565次阅读
    视频<b class='flag-5'>编码器</b>与<b class='flag-5'>解码器</b>的应用方案

    信路达 解码器/编码器 XD74LS48数据手册

    解码器/编码器?DIP164.75~5.25V封装:DIP16_19.3X6.4MM
    发表于 08-19 15:57 2次下载

    信路达 解码器/编码器 XD74LS47数据手册

    解码器/编码器DIP164.75~5.25V封装:DIP16_19.3X6.4MM
    发表于 08-19 15:57 0次下载