Transformer介绍

Transformer介绍

前言

Goole在2018年发表的一篇论文Attention is All You Need里首次提到Transformer,其目的是减少计算量、提高并行效率,同时不减弱最终的实验效果。本篇博文带大家来简单总结一下Transformer的大体原理。

1. 框架概览

首先我们来看一下模型的大致框架,不难看出Transformer大致分为两个结构:encoder和decoder,其中encoder包含两层结构,而decoder包含三层结构。
Transformer介绍_第1张图片
一般情况下,Transformer的结构为6个相同的encoder和6个相同的decoder,但是每一个encoder和decoder的weight都是独立存在的。
Transformer介绍_第2张图片
我们先来看一下encoder的具体结构,可以看出其分为两个子层,即self-attention机制外加一层前馈网。
Transformer介绍_第3张图片
Encoder在接受输入后,首先会通过一个self-attention层,其输出被传入一个全连接的前馈神经网络,每个encoder都有自己的功能。而对于decoder来讲,结构大致和encoder相似,只是多出了一个一个Attention层,其目的是能使系统更加关注编码层中的对应部分。
Transformer介绍_第4张图片
Transformer介绍_第5张图片
通过观察不难看出,在每个单词进入Self-Attention层后都会单独输出一个内容。Self-Attention层中的输入和输出是存在对应关系的,而前馈层则是独立的。

下面我用一个简短的句子作为例子,来一步一步推导transformer中每个子层的数据流动过程

2.Embedding

这里的Embedding由三种Embedding求和而成:
Transformer介绍_第6张图片
其中:

Token Embeddings是词向量,第一个单词是CLS标志,可以用于分类任务;
Segment Embeddings用来区别两种句子,因为预训练不光做语言模型还要做句子分类任务;
Position Embeddings和之前文章中的Transformer不一样,不是三角函数而是学习出来的。

假设位置向量是4维的,那么例子中的位置向量是这样:
Transformer介绍_第7张图片
下图中每行都代表一个字的位置向量,那么第一行就是位置中的第一个词,每行是512维的向量,每个值都是-1到1之间。 可以看到在一半的位置(第255维左右),图产生了一条明显的界限,因为左半边的值是为正弦出来的结果,而右半边是余弦函数的结果。
Transformer介绍_第8张图片

3. 例句

文中提到,Transformer中的每个Encoder接收一个512维度的向量的列表作为输入,然后通过self-attention层,同样产生一个512维向量列表,再进入到FFNN,输出一个512维的向量列表给encoder解码。

Transformer介绍_第9张图片
现在我们来分析下面这个例句:

”The animal didn’t cross the street because it was too tired”

如果你问一个人,句子中的“it”指代那个名次,这就是一个很简单的问题了。但是对于机器来说,处理这个问题肯定是纠结的。self attention就是旨在能帮助机器将“it”与“animal”联系到一起。 当模型处理单词序列的时候,self-attention层可以通过当前单词去查找序列中其他可能有关系的单词,并通过关系作为编码单词的线索。 如果你熟悉LSTM ,那么你应该理解LSTM在编码单词时是如何去通过长短时记忆来联系其他单词的。self-attention正是一种通过其上下文来理解当前词的一种办法。你会很容易发现,相比起传统的网络结构,transformer具有更好的并行性。
有关self-attention的介绍,请访问这个地址:https://mp.csdn.net/mdeditor/93230947#
Transformer介绍_第10张图片
如上图,是我们第五层Encoder针对单词’it’的图示,可以发现,我们的Encoder在编码单词‘it’时,注意力机制更加偏重于‘The’以及‘animal’上,SA中最终会通过更新权值,来参考这两个单词为‘it’实现编码。

3.encoder

在tensorflow的代码里面,增加了一个batch_size也就是输入的句子数,然后通过max_len控制的一句话的长度,外加字向量的维度大小。
上面说的是从下图中x1经过self-attention到了z1的状态,通过了self-attention的张量还需要进过Residual网络和LaterNorm的处理,然后进入到全连接的前馈网络中,前馈网络也是进行残差处理和正则化。最后输出的张量进入到了下一个encoder流程中,这样反复经过6次,最后就能进入到decoder中了。
Transformer介绍_第11张图片
每层由两个支层,attention层就是其中一个,而attention之后的另一个支层就是一个前馈的网络。公式描述如下:
在这里插入图片描述

4.decoder

对比单个encoder,decoder多出了一个encoder-decoder 注意力层,接收encoder部分输出的向量和decoder自身的self-attention产出的向量,然后再进入到全连接的前馈网络中去,最后向量输出到下一个的decoder。decoder中的attention层和encoder中的区别就在于:其自注意力层只能处理输出序列中当前词之前的序列,做法是在计算softmax之前把后面的词都设成 -inf。
Transformer介绍_第12张图片
最后一个decoder输出的向量会经过线性层和softmax层。线性层的作用就是对decoder部分出来的向量做映射成一个logits向量,softmax层是为了将其转换成概率值,这样方便找到概率较大的那个位置,以完成解码输出。
Transformer介绍_第13张图片

训练过程

在训练过程中,一个未经训练的模型会通过一个完全一样的前向传播。但因为我们用有标记的训练集来训练它,所以我们可以用它的输出去与真实的输出做比较。为了把这个流程可视化,我们假设输出的词表中仅仅包含6个单词(包络eos结束符):
Transformer介绍_第14张图片
一旦我们定义了我们的输出词表,我们可以使用一个词表大小宽度的向量来表示我们词汇表中的每一个单词。可以认为它是一个one-hot 编码。所以,我们可以用下面这个向量来表示单词“am”:
Transformer介绍_第15张图片

损失函数

如果我们想要一个表示单词“thanks”概率分布的输出。因此我们期望模型的输出结果如下:
Transformer介绍_第16张图片
未训练模型的输出向量都是随机生成的,因此既然是有监督训练,我们可以通过真实的输出来比较它,然后用反向传播算法来略调整所有模型的权重,生成更接近结果的输出。一个最常用的方法就是将原始输出与期望输出进行减法运算。
下面我们举出一个机器翻译的例子:
输入“je suis étudiant”并期望输出是“i am a student”。那我们就希望我们的模型能够成功地在这些情况下输出概率分布:

  • 每个概率分布被一个以词表大小(我们的例子里是6,但现实情况通常是3000或10000)为宽度的向量所代表。
  • 第一个概率分布在与“i”关联的单元格有最高的概率
  • 第二个概率分布在与“am”关联的单元格有最高的概率
  • 以此类推,第五个输出的分布表示“”关联的单元格有最高的概率

Transformer介绍_第17张图片
依据例子训练模型得到的目标概率分布。在一个足够大的数据集上充分训练后,我们希望模型输出的概率分布看起来像这个样子:
Transformer介绍_第18张图片
这个模型一次只产生一个输出,即每次只选择概率最高的单词,并把剩下的词抛弃。
另一个完成这个任务的方法是留住概率最靠高的两个单词(例如I和a),那么在后续步骤都要进行两次:其中一次假设第一个位置输出是单词“I”,而另一次假设第一个位置输出是单词“me”,并且最终都保留概率最高的两个翻译结果。然后我们为后续位置重复这一步骤。这个方法被称作集束搜索(beam search)。本例中集束宽度是2(因为保留了2个集束的结果),并且最终也返回两个集束的结果(top_beams也是2)。

你可能感兴趣的:(Transformer介绍)