Self-Attention and Transformer Architecture: BERT, GPT, and Multi-Head Attention

Hyacehila

我们再来研究序列的输入与神经网络的记忆这个话题,不过区别于我们前面介绍的 RNN 这种经典的神经网络,我们这次来聊一点新的东西——自注意力机制与Transformer架构和他们的基础自监督学习,这个2016年才问世,但是如今大放异彩的发明

自监督学习

自监督学习(Self-Supervised Learning,SSL)是一种无标注的学习方式,假设我们有一篇文章xx 那么自监督学习可以将其分为模型的输入xx^{\prime} 与 模型的标签xx^{\prime\prime} 然后就可以正常的训练一个监督学习的模型,无需人工的标注过程。

这里我们主要介绍两种典型的自监督学习模型:BERT 和 GPT.他们都是目前在语言模型领域取得了相当不错的效果的存在。也是自监督学习之所以在现在被重视的核心原因.

来自 Transformers 的双向编码器表示(BERT)

BERT 模型是自监督学习的经典模型,BERT 是一个 Transformer 的EncoderOnly结构,BERT 的架构与 Transformer 的编码器完全相同,里面有很多自注意力和残差连接、归一化等等. BERT 可以输入一行向量,输出另一行向量. 输出的长度与输入的长度相同.

BERT 一般用在自然语言处理中,BERT 的输入是一段文字. 接下来需要随机掩码一些输入文字,被掩码的部分是随机决定的.一般用特殊符号替换句子中的单词,使用“MASK”词元来表示特殊符号,可以将其看成一个新的汉字,它不在字典里,它的意思是掩码原文.

掩码后,向 BERT 输入了一个序列,BERT 的相应输出就是另一个序列. 接下来,查看输入序列中掩码部分的对应输出。对这个向量使用线性变换(线性变换是指输入向量会乘以一个矩阵). 然后做 softmax 并输出一个分布.我们训练的目标就是输出一个尽可能接近真实答案的字符。我们需要联合训练 BERT 和线性模型并尝试预测被掩码的字.

经过了这样的训练之后,BERT就学会了填空的问题。但是,后来它可以用来做各种感兴趣的下游任务.这些任务不一定与填空有关,它可能是完全不同的东西。当 BERT 学习完成这些任务时,仍然需要一些标注的数据.

给 BERT 一些有标注的数据,它可以学习各种任务,将 BERT 分化并用于各种任务称为微调(fine-tuning)在微调之前产生此 BERT 的过程称为预训练. 所以产生 BERT 的过程就是自监督学习,也可以将其称为预训练.

BERT的使用方式

在前面的研究中,我们只训练了一个只会填空的模型,这对于各个应用场景显然是不够的,现在我们需要针对场景进行模型的微调,来适应它。

假设下游任务是输入一个序列并输出一个类别. 这是一个分类问题,只是输入是一个序列.例如情感分析就是这样的一个问题,为了解决这样的问题,我们需要在原始的文本序列前端增加CLS词元,也就是特殊词元分类符号。

现在BERT会输出等长的序列,我们关注的是CLS词元对应的输出,把他乘以一个线性变换在通过Softmax转换为分类用的向量。这样我们就把一个序列对序列的模型和一个分类问题联系了起来。(实际上在BERT的训练中也使用了CLS词元,用来处理句序预测或下一句预测的问题)

BERT 没有办法从头开始解决情感分析问题,其仍然需要一些标注数据,需要提供很多句子以及它们的正面或负面标签来训练 BERT 模型. 在训练过程中,BERT 与这种线性变换放在一起,称为完整的情感分析模型. 在训练时,线性变换和 BERT 模型都利用梯度下降来更新参数. 线性变换的参数是随机初始化的,而 BERT 初始的参数是从学习了做填空题的 BERT 来的。 实际上BERT的骨干本质就是一个巨大的Transformer编码器,使用这样预训练的BERT,会比随机初始化的BERT 更好的性能.

BERT理论上没有长度限制,但是由于BERT 模型是一个 Transformer 编码器,其中的自注意力机制需要极大的运算量,如何在修改注意力机制来获得更好的计算性能是一个非常重要的问题.

实质上,使用BERT处理实际问题,就是微调与预训练的组合。由于预训练工作开销非常大,因此对于大部分普通开发者而言只需要研究微调模型来适配自己的任务.

BERT的有效性

为什么 BERT 有用?最常见的解释是,当输入一串文字时,每个文字都有一个对应的向量,这个向量称为嵌入. BERT可以考虑上下文,根据上下文的不同,他可以输出不同的向量,计算这些向量之间的余弦相似度,我们发现BERT 在填空的过程中学会了每个字的意思. 也许它真的理解中文,对它而言,中文的符号不再是没有关系的. 因为它了解中文的意思,所以它可以在接下来的任务中做得更好.

这样的想法在 BERT 之前就已经存在了. 有一种技术是词嵌入,词嵌入中有一种技术称为连续词袋(Continuous Bag Of Words,CBOW). 连续词袋模型所做的与 BERT 完全相同,把中间挖空,预测空白处的内容. 连续词袋模型可以给每个词汇一个向量,代表词汇的意思. 连续词袋模型是一个非常简单的模型,它使用了两个变换.实际上BERT目前也做到了词嵌入。BERT 还可以根据不同的上下文从相同的词汇中产生不同的嵌入称为语境化的词嵌入(contextualized word embedding)

训练在文字上的 BERT 也可以用来对蛋白质、DNA 和音乐进行分类.这看似非常的荒谬。如果将 DNA 序列预处理成一个无意义的序列,那么 BERT 的目的是什么?BERT 可以分析有效句子的语义,怎么能给它一个难以理解的句子?但实际上在文本上训练出来的BERT就是比随机的初始化更好,在很多问题上都是这样的,或许BERT 可能本质上只是一组比较好的初始化参数.

生成式预训练(GPT)

在自监督学习中,除了 BERT 系列的模型,还有一个非常有名的模型—–GPT 系列的模型. BERT 做的是填空题,而 GPT 就是改一下在自监督学习的时候要模型做的任务. GPT 要做的任务是预测接下来会出现的词元. GPT利用了Transformer的DecoderOnly结构.

给 GPT 输入词元 BOS(beginning of sentence),GPT 会输出一个嵌入(embedding). 接下来用这个嵌入去预测下一个应该出现的词元. 然后我们就像在Transformer的解码器结构一样,继续将下一个BOS以及下一个词元输入给解码器结构,直到这个句子结束。训练GPT就是在训练这个Transformer编码器与解码器结构。

实际上不会只用一笔句子训练 GPT,而是用成千上万个句子来训练模型,GPT 用了很多数据训练了一个非常大的模型. GPT 模型建立在 Transformer 的解码器的基础上,由于掩码注意力机制,GPT 可以预测下一个词元,所以它有生成的能力,可以让它不断地预测下一个词元产生完整的文章。(哪怕GPT的解码器认为这个句子结束了,我们也可以把整个段落输入给编码器,然后继续预测)

GPT 系列可以把一句话补完,如何把一句话补完用在下游的任务上呢?例如,怎么把GPT 用在问答或者是其他的跟自然语言处理有关的任务上呢?GPT 可以跟 BERT 用一样的做法,也可以把 GPT 拿出来接一个简单的分类器,这也是会有效的,但是在 GPT 的论文没有这样做.

假设要 GPT 做翻译,我们先输入“把英语翻译成法语(Translate English to French)”,这个句子代表问题的描述. 然后给它几个范例,之后就可以输入英文,期待他把翻译给出。

在这个学习过程中完全没有梯度下降, 这种训练称为上下文学习(in-context learning),仅仅从模型获得的上下文中就得到了更好的输出结果.

自监督学习不仅可以用在文字上,还可以用在语音和计算机视觉(Com-puter Vision,CV)上。训练的思路是完全一样的,BERT训练语音的填空,GPT训练语音的预测。语音的自监督模型已经有了很好的效果。

GPT模型采用纯Decoder的架构,Bert模型采用纯Encoder的架构,事实证明Decoder架构在目前的使用效果上是更好的.

自注意力机制

向量序列输入

我们的目标还是一样的,现在我们需要模型可以接受一个可以变长度的向量序列作为输入。实际上就是我们在基本网络架构中的循环神经网络 RNN中需要进行的行为。

在那里我们介绍了可以使用 基本网络架构中的独热编码 帮助我们将句子组成一个向量序列。当然基于学习的 词嵌入(word embedding) 也可将词汇表示成向量。

相较于One-Hot编码的每个维数代表一个单词,词嵌入机制可以在处理大规模的文本的时候保证向量的维数不会过高,并且保证向量之间的距离有实际意义。

向量序列输入可以有着不同的输出形式,我们主要考虑下面几种,在RNN中我们也有着简单的介绍

  • 输入与输出数量相同,词性标注,网络节点划分都是这一类问题
  • 输出标签, 也就是经典的分类与回归问题,虽然输入是序列,但输出依旧是单一标签
  • 序列到序列,我们不知道输出序列的长度,需要自行学习,机器翻译,LLM实现的对话都是序列到序类技术

自注意力机制的基本原理

我们首先介绍第一个类型:输入跟输出数量一样多的状况,以词性标注为例,序列标注要给序列里面的每一个向量一个标签。

为了让全连接网络能够考虑到序列前后的信息,我们需要将整个序列输入给网络,比如音频识别中我们一般会传入一个窗口,包含当前音频帧和前后五个音频帧(每个音频帧是按照一定音频处理规则处理原始音频文件得到的,一般是一个25ms的窗口)。这种为网络传入一个窗口的操作可以让我们很好的利用前后文信息,但是选择窗口的大小非常困难,这就要考虑使用自注意力机制。

自注意力模型会“吃”整个序列的数据,输入几个向量,它就输出几个向量。此时输出的向量均考虑了整个序列的数据才得到,然后我们就可以把他加入全连接网络,得到进一步输出,此时我们就利用自注意力模型处理了整个序列。如果需要的话,我们也可以将自注意力模型与全连接网络模型多层堆叠。将自注意力模型发扬光大的文章是Google实验室发表的 Attention Is All You Need

自注意力机制按照下图发挥作用,输入的一串向量可以是xx,也可以是某个隐藏层的输出,因此使用aa,他在处理整个输入序列后输出一组向量bb 自注意力机制示意图 接下来介绍下向量 b1b^1 产生的过程,借此了解向量bb的产生。首先我们需要根据 a1a^1 找出输入序列里面跟 a1a^1 相关的其他向量。自注意力的目的是考虑整个序列,但是又不希望把整个序列所有的信息包在一个窗口里面。所以引入注意力机制,这个机制是根据向量 a1a^1 找出整个很长的序列里面哪些部分是重要的,每一个向量跟 a1a^1 的关联的程度可以用数值 α\alpha来表示。

注意力机制模型需要输入两个向量,返回一个标量,一般使用点积来实现。将输入的向量分别乘以矩阵Wq,WkW^q,W^k得到向量q,kq,k,然后将向量q,kq,k点积得到标量,这个乘以矩阵一方面是想引入一些新的线性,另一方面是调整向量的大小。这个方法也是后面介绍的Transformer中使用的注意力计算方法。

自注意力模型一般采用查询-键-值(Query-Key-Value,QKV)模式。分别计算 a1a^1a2a^2a3a^3a4a^4 之间的关联性。首先把a1a^1乘上WqW^q得到查询qq,然后 a2a^2a3a^3a4a^4 乘上WkW^k得到键kk,将查询qq与键kk计算内积,就可以得到注意力分数,衡量关联性。一般我们也会计算a1a^1与自身的关联性。接下来会对所有的关联性进行Softmax处理得到一组关联性α\alpha^{\prime}

α1,i=exp(α1,i)/jexp(α1,j)\alpha_{1,i}^{\prime}=\exp\left(\alpha_{1,i}\right)/\sum_j\exp\left(\alpha_{1,j}\right)

得到关联性之后,我们就可以通过下式计算b1b^1

b1=iα1,ivi\boldsymbol{b}^1=\sum_i\alpha_{1,i}^{\prime}\boldsymbol{v}^i

其中aia^iWvW^v 的积就是viv^i ,对于较高关联性的元素,其viv^i 就会有更高的加权值,最后的输出b1b^1就会更接近他,这就是注意力机制的作用。

整个自注意力模块实际上就是一些非常简单的代数模块的堆叠,但正是这样简单的矩阵运算,最后产生了强大的智能

接下来从矩阵乘法的角度再重新讲一次自注意力的运作过程,实际上我们一般把整个aia^i重构为列矩阵II,将矩阵II分别和矩阵Wq,Wk,WvW^q,W^k,W^v相乘,就可以得到矩阵Q,K,VQ,K,V 他们中的每个列向量就是我们要考查的q,k,vq,k,v

kk重构为列矩阵KK qq 重构为列矩阵QQ 实际上,计算KTQK^{T}Q 得到矩阵AA 里面的每个列就是我们前面研究的注意力向量α\alpha 然后Softmax计算就可以得到α\alpha^{\prime} 记为AA^{\prime}

再重构vv为列矩阵VV,计算VAVA^{\prime} 就可以得到矩阵OO 其中的每一个列就是自注意力的输出bb 在目前的整个矩阵运算解释中,只有矩阵Wq,Wk,WvW^q,W^k,W^v需要我们在模型中学习。当然这仅仅是单头注意力的情况,当我们研究多头注意力的时候,可训练的参数矩阵会增加.

其他自注意力机制

多头注意力

自注意力有一个进阶的版本——多头自注意力(multi-head self-attention)。多头自注意力的使用是非常广泛的,在很多任务中可以得到比较好的结果。至于需要用多少的头,这个又是另外一个超参数。

原本的自注意力机制使用qq 去找 kk 这被称为一个头,现在我们把这个结构直接复制粘贴,原本考虑一组Wq,Wk,WvW^q,W^k,W^v 得到一组q,k,vq,k,v 现在我们直接考虑两组不同的Wq,Wk,WvW^q,W^k,W^v 用来衡量另一种相关性。在实际操作的时候,我们一把直接把前面得到的q,k,vq,k,v 分别乘上两个矩阵,得到不同的头。

通过多头的自注意力机制,我们在原本的一个bib^i的位置上会得到多个bb,我们一般把他通过一个变换,最后将一个序列向量传给下一层。这个变化用的矩阵我们一般称为 WOW^O 也就是说在多头注意力矩阵中 关于注意力机制的部分将会有四个可训练的矩阵,分别为 Wq,Wk,Wv,WOW^q,W^k,W^v,W^O

位置编码

讲到目前为止,自注意力层少了一个也许很重要的信息,即位置的信息。对一个自注意力层而言,每一个输入是出现在序列的最前面还是最后面,它是完全没有这个信息的。也就是位置的信息在目前的模型中被忽略了,这在处理序列问题的时候并不是可以接受的。

需要考虑位置信息时,就要用到位置编码(positional encoding),我们为序列中的每一个位置定义一个向量。不同的位置都有一个专属的 ee,把 ee 加到 aia^i 上面就结束了。在最早的 “Attention Is All You Need” 论文中,其位置向量是通过正弦函数和余弦函数所产生的,避免了人为设定向量固定长度的尴尬。具体什么样的位置向量更好是一个悬而未决的东西,正弦函数只是习惯,而非规则。

位置编码在部分结构中也是可学习的,但这一般只出现在关于预训练技术的技术报告中,微调一般不考虑位置编码的问题

截断自注意力

自注意力的应用很广泛,在自然语言处理(Natural Language Processing,NLP)领域,除了 Transformer,还有 BERT 也用到了自注意力。但是他不仅能用于NLP领域,只需要一点小小的改动。

在计算注意力矩阵的时候,其复杂度(complexity)是长度的平方。假设该矩阵的长度为 LL,计算注意力矩阵需要做 L×LL \times L次的内积,如果 LL 的值很大,计算量就很可观,并且需要很大内存(memory)才能够把该矩阵存下来。

截断自注意力(truncated self-attention)可以处理向量序列长度过大的问题。截断自注意力在做自注意力的时候不要看一整句话,就只看一个小的范围就好,这个范围是人设定的。

自注意力与CNN和RNN

自注意力与CNN

自注意力还可以被用在图像上。到目前为止,在提到自注意力的时候,自注意力适用的范围是输入为一组向量的时候。一张图像也可以看作是一个向量序列。一张分辨率为 5 × 10 的图像可以表示为一个大小为 5 × 10 × 3 的张量。,每一个位置的像素可看作是一个三维的向量,整张图像是5 × 10 个向量。这样就完全可以用自注意力来处理一张图像。

如果我们比较卷积神经网络跟自注意力会发现,卷积神经网络可以看作是一种简化版的自注意力,因为在做卷积神经网络的时候,只考虑感受野里面的信息。而在做自注意力的时候,会考虑整张图像的信息。在卷积神经网络里面,我们要划定感受野。每一个神经元只考虑感受野里面的信息,而感受野的大小是人决定的。而用自注意力去找出相关的像素,就好像是感受野是自动被学出来的,网络自己决定感受野的形状,位置,大小。

自注意力只要设定合适的参数,就可以做到跟卷积神经网络一模一样的事情。既然卷积神经网络是自注意力的一个子集,说明自注意力更灵活。更灵活的模型需要更多的数据。如果数据不够,就有可能过拟合。而比较有限制的模型,它适合在数据少的时候使用,它可能比较不会过拟合。如果限制设的好,也会有不错的结果。

Google的An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale 把自注意力应用在图像上面,把一张图像拆成 16 × 16 个图像块(patch),它把每一个图像块就想像成是一个字(word)。然后利用自注意力机制处理。在数据量较大的时候,这种方法能比卷积神经网络取得更好的效果。

自注意力与RNN

我们来比较一下自注意力跟循环神经网络。目前,循环神经网络的角色很大一部分都可以用自注意力来取代了。因为他们都是为了处理序列而产生的。

自注意力跟循环神经网络有一个显而易见的不同,自注意力的每一个向量都考虑了整个输入的序列,而循环神经网络的每一个向量只考虑了左边已经输入的向量,它没有考虑右边的向量。

哪怕考虑双向循环神经网络,随着序列长度的增加,RNN更容易忘记前面很久的时候输入的内容,因为其记忆元不一定能保存这么久。但自注意力输出一个查询,输出一个键,只要它们匹配(match)得起来,“天涯若比邻”。自注意力可以轻易地从整个序列上非常远的向量抽取信息,这对于长文本来说性能明显更好了。

自注意力跟循环神经网络还有另外一个更主要的不同是,循环神经网络在处理输入、输出均为一组序列的时候,是没有办法并行化的。比如计算第二个输出的向量,不仅需要第二个输入的向量,还需要前一个时间点的输出向量。当输入是一组向量,输出是另一组向量的时候,循环神经网络无法并行处理所有的输入,但自注意力可以。

Transformer架构

Transformer 是一个基于自注意力的序列到序列模型,与基于循环神经网络的序列到序列模型不同,其可以能够并行计算。

本章从两方面介绍 Transformer,一方面介绍 Transformer 的结构,即编码器和解码器与编码器-解码器注意力,另一方面介绍 Transformer 的训练过程以及 序列到序列 模型的训练技巧。

序列到序列模型输入和输出都是一个序列,输入与输出序列长度之间的关系有两种情况。第一种情况下,输入跟输出的长度一样;第二种情况下,机器决定输出的长度。包括语音识别,机器翻译,聊天机器人(问答机器人),语音合成,多标签分类器(不能使用传统分类模型处理),都需要利用序列到序列机制。

一般的序列到序列模型会分成编码器和解码器,编码器负责处理输入的序列,再把处理好的结果“丢”给解码器,由解码器决定要输出的序列。这也是Transformer结构的选择。

Transformer编码器

接下来介绍下 Transformer 的编码器,编码器输入一排向量,输出另外一排向量。Transformer 的编码器使用的是自注意力,输入一排向量,输出另外一个同样长度的向量。

编码器里面会分成很多的块(block),每一个块都是输入一排向量,输出一排向量。输入一排向量到第一个块,第一个块输出另外一排向量,以此类推,最后一个块会输出最终的向量序列。

Transformer 的编码器的每个块并不是神经网络的一层,在每个块里面,输入一排向量后做自注意力,考虑整个序列的信息,输出另外一排向量。接下来这排向量会“丢”到全连接网络网络里面,输出另外一排向量,这一排向量就是块的输出。

真实的Transformer比这还要复杂一些,里面加入了残差连接(residual connection)的设计。向量 bb 输入到(多头)自注意力层后得到向量 aa,输出向量 aa 加上其输入向量 bb 得到新的输出。经过这样一个残差连接后,再做层归一化(layer normalization)。将层归一化的结果输入给一个全连接神经网络,并且将其输入和全连接网络的输出形成一个新的残差连接,再将其进行一个层归一化,这就得到了一个块的完整结构。

特别的,为了在网络结构中保持位置信息,我们还需要每个块的输入端嵌入其位置信息。在重复NN个块之后,我们就得到了Transformer中的一层,他也是Transformer中的编码器结构。 Transformer 编码器结构示意图

Transformer解码器

接下来介绍解码器,解码器比较常见的称为自回归的(autoregressive)解码器。

解码器把编码器的输出先“读”进去。要让解码器产生输出,首先要先给它一个代表开始的特殊符号 BOS,即 Begin Of Sequence,这是一个特殊的词元(token)。也在我们制定的词表(vocabulary)里面,使用向量编码,在本来解码器可能产生的文字里面多加一个特殊的符号 BOS。

在接受BOS后,解码器根据获得的编码器的输入吐出一个向量,他经过了Softmx的处理,这个向量是一个词表中各个词的概率分布,其和为1,现在我们就可以根据这个向量找到分数最高的那个词,他就是解码器的第一个输出。

接下来把刚才解码器的输出当成解码器新的输入。根据两个输入(BOS和刚才的输出词),解码器再输出一个向量,对应一个词表中的词,然后把这个步骤重复下去,也就是说解码器的输入是它在前一个时间点的输出,其会把自己的输出当做接下来的输入。

由于这种一个词一个词输出的结构,可能会产生误差传播(error propagation)的问题,由于一步输出了错误的词导致后面全部出错。

Transformer 里面的解码器也采用了和编码器类似的结构,也包括一个多头自注意力+残差连接+层归一化,全连接前馈神经网络+残差连接+层归一化的多层堆叠结构。解码器最后再做一个 softmax,使其输出变成一个概率。

此外,解码器使用了掩蔽自注意力(masked self-attention),掩蔽自注意力可以通过一个掩码(mask)来阻止每个位置选择其后面的输入信息。他本质上就是禁止原本的自注意力机制访问其之后的输出,即序列a1,a2,a3,...a_1,a_2,a_3,... 在计算b2b_2的时候,只利用a1,a2a_1,a_2 不使用a3a_3及之后的输入,包括 q k 的查询与 v 的计算。

为什么需要在注意力中加掩码? 一开始解码器的输出是一个一个产生的,所以是先有 a1a_1 再有 a2a_2,再有 a3a_3,再有a4a_4。这跟原来的自注意力不一样,原来的自注意力 a1a_1a4a_4 是一次整个输进去模型里面的。解码器的输出是一个一个产生的,所以只能考虑其左边的东西,没有办法考虑其右边的东西。

Transformer 解码器掩码注意力示意图

要让解码器停止运作,需要特别准备一个特别的符号 EOS。解码器输出EOS后模型的输出终止。

前面介绍的这种模型结构属于自回归的解码器,自回归的输出是一个字一个进行的,这意味着他是一个顺序的结构,并不可以平行运行,这导致其运行的整体速度无法太高。

还有一种非自回归的解码器,非自回归的解码器可能“吃”的是一整排的 BOS 词元,一次产生产生一排词元。具体输入多少个BOS没有确定的定论,有些模型采用额外的分类器决定,有些模型则是输入很多BOS,并且抛弃输出中EOS之后的部分。

非自回归的解码器有很多优点。第一个优点是平行化。另外一个优点是非自回归的解码器比较能够控制它输出的长度。但是其性能往往不如自回归解码器。

编码器-解码器注意力

前面对解码器的介绍实际上缺少了一部分,我们未能详细解释编码器的输出是如何被解码器利用的,图上的结构也没有完全解释明白这个问题。这就是编码器-解码器注意力机制。

还是根据前面的示意图解释,编码器输入一排向量,然后输出一排向量a1,a2,a3,...a_1,a_2,a_3,... 。接下来解码器会先“吃” BOS,经过掩蔽自注意力得到一个向量。接下来把这个向量乘上一个矩阵,做一个变换(transform),得到一个查询 qq 于此同时a1,a2,a3,...a_1,a_2,a_3,...也乘上一个矩阵产生键k1,k2,...k_1,k_2,... 然后计算注意力分数,进行Softmax,最后计算加权输出vv 这个vv 会交给全连接网络 ,得到输出。这样就得到了块的输出向量。

这个步骤 qq 来自于解码器,kkvv 来自于编码器,该步骤就叫做编码器-解码器注意力,所以解码器就是凭借着产生一个 qq,去编码器这边抽取信息 出来,当做接下来的解码器的全连接网络的输入。最后经由全连接网络得到块的输出。

在后续的块中,掩码自注意力机制获取前面的块的输出,然后根据此时要求的掩码长度限制访问,再得到新的输出,去计算qq 然后交给编码器-解码器注意力处理。

当已经有了多个输出的时候,解码器吃掉 BOS 以及其他输出,然后依旧产生等长的向量,然后产生多个qq,再交给编码器-解码器注意力和全连接网络处理,最后得到输出再交给下一个块。

关于模型的训练

最基本的思想,我们会去计算标准答案(Ground Truth)跟分布之间的交叉熵,毕竟实际上我们的输出在Softmax之后是一个概率分布,是一个非常自然的分类问题。

在训练的时候,我们一般将前几个正确的输出给他,让他预测一个词,然后计算整个句子的交叉熵,这被称为教师强制(teacher forcing)

前面的思路后,我们评估的标准用的是 BLEU(BiLingual Evaluation Under- study)分数。虽然 BLEU 最先是用于评估机器翻译的结果,但现在它已经被广泛用于评价许多应用输出序列的质量。解码器先产生一个完整的句子,再去跟正确的答案一整句做比较,拿两个句子之间做比较算出 BLEU 分数。但训练的时候,每一个词汇是分开考虑的,最小化的是交叉熵,最小化交叉熵不一定可以最大化 BLEU 分数。但在做验证的时候,并不是挑交叉熵最低的模型,而是挑 BLEU 分数最高的模型。

实际上,采用交叉熵逐个字计算,是因为 BLEU 无法微分,因此无法优化。但是遇到优化无法解决的问题,可以用强化学习训练。具体来讲,遇到无法优化的损失函数,把损失函数当成强化学习的奖励,把解码器当成智能体。这是目前非常常用的方法,在推理模型的训练中获得了很大的成功。

Bert与GPT的嵌入

无论是Bert还是GPT,模型的读取原始句子与预测的形式都是基于token的,这意味着我们需要把原始的句子转换为token再输入给模型处理。将词变为token向量的方法叫作Embedding嵌入。

原始的语句中的词汇全部采用Onehot编码,是高维的稀疏向量。通过建立字向量表将每个字转换成一个一维向量得到。特别的,英文词汇会做更细粒度的切分,比如playing 或切割成 play 和 ##ing。

Token Embeddings 层会将每个词转换成 DD 维向量。利用下面的线性变换实现

vn=Exnv_{n}= E x_n

对于每一个One-hot编码的向量xnx_n 维数为KK,是One-hot编码空间的维数,一般会很大,vnv_n是词向量嵌入,大小为DD Bert中采用768维。EE是嵌入矩阵,也是通过反向传播进行学习的。

为了保证模型也能学习到语序的信息,我们需要在嵌入层增加Position Embeddings。他在每个位置也产生一个DD维的向量,我们后续会将这个向量与前面的token Embeddings求和,得到最终的token,输入给后续的模型。

  • Title: Self-Attention and Transformer Architecture: BERT, GPT, and Multi-Head Attention
  • Author: Hyacehila
  • Created at : 2024-11-14 14:50:47
  • Link: https://hyacehila.github.io//blog/2024/11/14/self-attention-and-transformer-architecture/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments