Transformer(下)

本文讲解了Transformer模型的关键组成部分,如词向量、自注意力机制、Encoder和Decoder结构,以及如何处理位置信息和使用mask防止信息泄露。重点阐述了在机器翻译任务中的应用。
摘要由CSDN通过智能技术生成

77# Transformer(下)
链接: 参考文章Transformer
链接: transformer上

1. 前置知识点补充

1.1 词向量

词向量技术是将词转化成为稠密向量,并且对于相似的词,其对应的词向量也相近。
输入是一个个的词(token),需要映射成一个向量,embedding就是给任何一个词,学习一个长度为d的向量来表示它
对于神经机器翻译,想要被翻译的源语言被称为Source,想要翻译的目标语言被称为Target。训练数据为两种不同语言的句子对(Source Target Sentence Pair)。以英语(en)德语(de)翻译为例,一个训练数据样本为:
English(sources)

I declare resumed the session of the European Parliament adjourned on Friday 17 December 1999, and I would like once again to wish you a happy new year in the hope that you enj
oyed a pleasant festive period.

German(targets)

Ich erkläre die am Freitag, dem 17. Dezember unterbrochene Sitzungsperiode des Europäischen Parlaments für wiederaufgenommen, wünsche Ihnen nochmals alles Gute zum Jahreswechse
l und hoffe, daß Sie schöne Ferien hatten.

自然语言处理中通常将文本定义为由多个词条(Token)组成的序列。Token可以是单词,也可以是词干、前缀、后缀等。先把问题最简单化,将Token理解成单词。像英语和德语,单词之间有空格分隔,Tokenizer只需要将空格、标点符号等提取出来,就可以获得句子中的Token。
使用Tokenizer对原始语料进行切分后,生成大量的Token,这些Token共同组成了词表(Vocabulary)。比如,一个英文词表可以是:

I
declare
resumed
...

然而,如果将Token定义为单词,建立基于单词的模型有很多缺点。由于模型输出的是单词的概率分布,因此词表中单词数量很大情况下,模型会变得非常慢。如果单词表中包括拼写错误和各类派生单词,则词表的大小实际上是无限的。我们希望模型只处理最常见的单词,所以需要使用一些方式对单词的数量加以限制。词表大小通常设置为10,000到100,000。以单词作为Token的另一个缺点是该模型无法学习单词的常见“词干”。例如,对于“loved”和“loving”,尽管它们有共同的词干,但模型会认为他们是两种完全不同的词。

处理单词为Token问题的一种方法是使用统计的方法生成子词(Subword)。例如,单词“loved”可以被分为“ lov”和“ ed”,而“ loving”可以被分为“ lov”和“ ing”。这使模型在各类新词上有泛化能力,同时还可以减少词表大小。有许多生成Subword的技术,例如Byte Pair Encoding(BPE)。

2. Transformer原理

Transformer完整结构图
在这里插入图片描述
同样一个东西,一条线过来即作为key, value也作为query。
transformer全过程:
输入的一些序列,分成一个个词向量,进入attention之后我们就会得到同样长度的一些输出,attention就是对你的输入做一些加权的和,加权和之后进入mlp,每一个输出进行相同的mlp,每一个mlp对每一个输入的点操作后会得到一个输出,最后得到整个transformer块的的一个输出,attention起到把整个序列里面的信息抓取出来,做一次汇聚aggregation,经过attention我序列中感兴趣的东西已经抓取出来了,所以做投影和mlp的时候,映射成我更想要的那个语义空间的时候,每个输出都含有了我的序列信息,所以每个mlp只要在对每个点独立做就行了。
transformer和RNN都是通过一个线性层(mlp)来做一个语义空间的转换。不一样的是如何传递你的序列信息,RNN是把上一个时刻的信息输出传入下一个时刻做输入,但是在transformer里面它是通过一个attention层,然后再全局的去拿到整个序列里面的信息,然后用mlp做语义的转换。
在这里插入图片描述

2.1 第一部分inputs输入

输入一个序列,inputs是分词后的词向量。
输入inputs embedding后需要给每个word的词向量添加位置编码positional encoding。

为什么需要添加位置编码呢?
首先咱们知道,一句话中同一个词,如果词语出现位置不同,意思可能发生翻天覆地的变化,但是Transformer 是完全基于self-Attention地,而self-attention是不能获取词语位置信息的,就算打乱一句话中词语的位置,每个词还是能与其他词之间计算attention值,就相当于是一个功能强大的词袋模型,对结果没有任何影响。所以在我们输入的时候需要给每一个词向量添加位置编码。
在这里插入图片描述

这个positional encoding怎么获取呢?
Transformer使用的是正余弦位置编码。位置编码通过使用不同频率的正弦、余弦函数生成,然后和对应的位置的词向量相加。
在这里插入图片描述
pos表示单词在句子中的绝对位置,pos=0,1,2…,例如:Jerry在"Tom chase Jerry"中的pos=2;dmodel表示词向量的维度,在这里dmodel=512;2i和2i+1表示奇偶性,i表示词向量中的第几维,例如这里dmodel=512,故i=0,1,2…255。

Transformer 的 Decoder的输入与Encoder的输出处理方法步骤是一样地,一个接受source数据,一个接受target数据,对应到上面例子里面就是:Encoder接受英文"Tom chase Jerry",Decoder接受中文"汤姆追逐杰瑞"。只是在有target数据时也就是在进行有监督训练时才会接受Outputs Embedding,进行预测时则不会接收。

2.2 Encoder

2.2.1 Multi-Head Attention


首先回顾一下self-attention,假如输入序列是"Thinking Machines",x1,x2就是对应地"Thinking"和"Machines"添加过位置编码之后的词向量,然后词向量通过三个权值矩阵WQ, WK, Wv,转变成为计算Attention值所需的Query,Keys,Values向量。
在这里插入图片描述
因为咱们再实际使用中,每一个样本,也就是每一条序列数据都是以矩阵的形式输入地,故可以看到上图中,X矩阵是由"Tinking"和"Machines"词向量组成的矩阵,然后跟过变换得到Q,K,V。假设词向量是512维,X矩阵的维度是(2,512),WQ, WK, Wv均是(512,64)维,得到的Query,Keys,Values就都是(2,64)维。

计算Attention得分:

  1. 输入序列中每个单词之间的相关性得分, score = Q · KT, socre是一个(2,2)的矩阵
  2. 对于输入序列中每个单词之间的相关性得分进行归一化,dk就是K的维度,以上面假设为例,dk=64
  3. 通过softmax函数,将每个单词之间的得分向量转换成[0,1]之间的概率分布
  4. 根据每个单词之间的概率分布,然后乘上对应的Values值,α与V进行点积,V的为维度是(2,64),(2,2)x(2,64)最后得到的Z是(2,64)维的矩阵
    在这里插入图片描述

Multi-Head Attention:
在这里插入图片描述
Multi-Head Attention 很简单,就是在self-attention的基础上,对于输入的embedding矩阵,self-attention只使用了一组WQ, WK, Wv来进行变换得到Query,Keys,Values。而Multi-Head Attention使用多组WQ, WK, Wv 得到多组Query,Keys,Values,然后每组分别计算得到一个Z矩阵,最后将得到的多个Z矩阵进行拼接。Transformer里面是使用了8组不同的WQ, WK, Wv
在这里插入图片描述
在经过Multi-Head Attention得到矩阵Z之后,并没有直接传入全连接神经网络FNN,而是经过了一步:Add&Normalize。

2.2.2 Add&Normalize:

Add
Add,就是在Z的基础上加了一个残差块X,加入残差块X的目的是为了防止在深度神经网络训练中发生退化问题。退化的意思就是深度神经网络通过增加网络的层数,Loss逐渐减小,然后趋于稳定达到饱和,然后再继续增加网络层数,Loss反而增大。

ResNet 残差神经网络:

为什么深度神经网络会发生退化?
假如某个神经网络的最优网络层数是18层,但是我们在设计的时候并不知道到底多少层是最优解,本着层数越深越好的理念,我们设计了32层,那么32层神经网络中有14层其实是多余地,我们要想达到18层神经网络的最优效果,必须保证这多出来的14层网络必须进行恒等映射,恒等映射的意思就是说,输入什么,输出就是什么,可以理解成F(x)=x这样的函数,因为只有进行了这样的恒等映射咱们才能保证这多出来的14层神经网络不会影响我们最优的效果。
但现实是神经网络的参数都是训练出来地,要想保证训练出来地参数能够很精确的完成F(x)=x的恒等映射其实是很困难地。多余的层数较少还好,对效果不会有很大影响,但多余的层数一多,可能结果就不是很理想了。这个时候大神们就提出了ResNet 残差神经网络来解决神经网络退化的问题。

残差块是什么?
在这里插入图片描述
上图就是构造的一个残差块,可以看到X是这一层残差块的输入,也称作F(X)为残差,X为输入值,F(X)是经过第一层线性变化并激活后的输出,该图表示在残差网络中,第二层进行线性变化之后激活之前,F(X)加入了这一层输入值X,然后再进行激活后输出。在第二层输出值激活前加入X,这条路径称作shortcut连接。

为什么添加了残差块能防止神经网络退化问题呢?

残差连接:把输入输出加在一起,最后进入它的LayerNorm,
LayerNorm和BatchNorm基本一样。前者是对每一个样本(行)做均值为0,方差为1,后者是对每一个特征(列)。(输入是二维矩阵的时候)layernorm就是把数据转置一下放到batchnorm里面出来的结果再转置一下,就可以得到自己的东西。
在这里插入图片描述
transformer输入是一个三维的东西,输入的是一个序列的样本,一个样本有很多个元素。

batch是样本,seq(n)是序列长度,feature(d)是对序列的每个词有自己的向量。
用LayerNorm的原因是样本长度可能不同。如果batchnorm预测比自己长度长很多的不好预测,layernorm是根据自己样本预测的不会出现这个问题(稳定一些)。

为了简单起见,残差连接需要输入输出是一样大小,不一样大小要做投影,把每一个层的输出维度变成512。
这个模型很简单只有N = 6,和dmodel = 512两个参数可以调。

Normalize
为什么要进行Normalize呢?
在神经网络进行训练之前,都需要对于输入数据进行Normalize归一化,目的有二:1,能够加快训练的速度。2.提高训练的稳定性。

2.2.3 Feed-Forward Networks

全连接层公式如下:
在这里插入图片描述
这里的全连接层是一个两层的神经网络,先线性变换,然后ReLU非线性,再线性变换。
这里的x就是我们Multi-Head Attention的输出Z,还是引用上面的例子,那么Z是(2,64)维的矩阵,假设W1是(64,1024),其中W2与W1维度相反(1024,64),那么按照上面的公式:
FFN(Z)=(2,64)x(64,1024)x(1024,64)=(2,64),我们发现维度没有发生变化,这两层网络就是为了将输入的Z映射到更加高维的空间中(2,64)x(64,1024)=(2,1024),然后通过非线性函数ReLU进行筛选,筛选完后再变回原来的维度。

然后经过Add&Normalize,输入下一个encoder中,经过6个encoder后输入到decoder中。

2.3 Decoder

Decoder block也是由6个decoder堆叠而成,Nx=6,比Encoder多了一个Masked Multi-Head Attention,其他的结构与encoder相同。

注意力机制:假设我们现在给了一个query,这个query和第一个第二个key比较近,输出就是三个v的相加,但是前两个权重会比较大一点。这个权重等价于query对应key的相似度。
两个向量的长度一样的话,内积的值越大(余弦值)相似度越高,
向量点积:得到的是一个数。

2.3.1 Decoder的输入分为两类:

一种是训练时的输入,一种是预测时的输入。
训练时的输入就是已经对准备好对应的target数据。例如翻译任务,Encoder输入"Tom chase Jerry",Decoder输入"汤姆追逐杰瑞"。
预测时的输入,一开始输入的是起始符,然后每次输入是上一时刻Transformer的输出。例如,输入"“,输出"汤姆”,输入"汤姆",输出"汤姆追逐",输入"汤姆追逐",输出"汤姆追逐杰瑞",输入"汤姆追逐杰瑞",输出"汤姆追逐杰瑞"结束。

2.3.2 Masked Multi-Head Attention

与Encoder的Multi-Head Attention计算原理一样,只是多加了一个mask码。mask 表示掩码,它对某些值进行掩盖,使其在参数更新时不产生效果。Transformer 模型里面涉及两种 mask,分别是 padding mask 和 sequence mask。

1.padding mask
什么是 padding mask 呢?因为每个批次输入序列长度是不一样的也就是说,我们要对输入序列进行对齐。具体来说,就是给在较短的序列后面填充 0。但是如果输入的序列太长,则是截取左边的内容,把多余的直接舍弃。因为这些填充的位置,其实是没什么意义的,所以我们的attention机制不应该把注意力放在这些位置上,所以我们需要进行一些处理。
具体的做法是,把这些位置的值加上一个非常大的负数(负无穷),这样的话,经过 softmax,这些位置的概率就会接近0!
2.sequence mask
sequence mask 是为了使得 decoder 不能看见未来的信息。对于一个序列,在 time_step 为 t 的时刻,我们的解码输出应该只能依赖于 t 时刻之前的输出,而不能依赖 t 之后的输出。因此我们需要想一个办法,把 t 之后的信息给隐藏起来。这在训练的时候有效,因为训练的时候每次我们是将target数据完整输入进decoder中地,预测时不需要,预测的时候我们只能得到前一时刻预测出的输出。
那么具体怎么做呢?也很简单:产生一个上三角矩阵,上三角的值全为0。把这个矩阵作用在每一个序列上,就可以达到我们的目的。

在Encoder中的Multi-Head Attention也是需要进行mask地,只不过Encoder中只需要padding mask即可,而Decoder中需要padding mask和sequence mask。
先投影到一个低维
在这里插入图片描述
在这里插入图片描述
残差连接的存在,输入和输出的维度至少是一样的,投影的时候投影的就是输出的维度除以h(头的个数)

2.3.3 基于Encoder-Decoder 的Multi-Head Attention

Encoder中的Multi-Head Attention是基于Self-Attention的,Decoder中的第二个Multi-Head Attention就只是基于Attention,它的输入Query来自于Masked Multi-Head Attention的输出,Keys和Values来自于Encoder中最后一层的输出。

为啥Decoder中要搞两个Multi-Head Attention呢?
第一个Masked Multi-Head Attention是为了得到之前已经预测输出的信息,相当于记录当前时刻的输入之间的信息的意思。第二个Multi-Head Attention是为了通过当前输入的信息得到下一时刻的信息,也就是输出的信息,是为了表示当前的输入与经过encoder提取过的特征向量之间的关系来预测输出。

经过了第二个Multi-Head Attention之后的Feed Forward Network与Encoder中一样,然后就是输出进入下一个decoder,如此经过6层decoder之后到达最后的输出层。

2.4 输出

Output如图中所示,首先经过一次线性变换,然后Softmax得到输出的概率分布,然后通过词典,输出概率最大的对应的单词作为我们的预测输出。

3. 代码实现

1. 基础知识

  1. shape[]
    在Python中,a.shape[0]表示数组 a 的第一个维度(即行数)的大小。这适用于多维数组(如NumPy数组)或矩阵。

在NumPy中,数组的形状(shape)是一个元组,用于描述数组的维度大小。对于二维数组来说,形状通常表示为 (行数, 列数)。通过索引操作 a.shape[0],我们可以获取数组 a 在第一个维度上的大小。

以下是一个示例:

import numpy as np

a = np.array([[1, 2, 3],
              [4, 5, 6]])

print(a.shape)       # 输出:(2, 3)
print(a.shape[0])    # 输出:2

在上述示例中,a 是一个形状为 (2, 3) 的二维数组。通过 a.shape[0],我们获取到了数组 a 的行数,即 2。
需要注意的是,索引操作使用 0-based indexing,即第一个维度的索引为 0,第二个维度的索引为 1,依此类推。所以 a.shape[0] 表示的是第一个维度的大小。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值