(一)Transformer及其attention详解

GPT-2是基于海量数据集上训练的基于Transformer的巨大模型。本文探索GPT-2模型架构,重点阐述其中关键的自注意力(self-attention)层。

Part1 GPT2和语言模型

GPT应用与语言模型上理解为根据前面的词推理出后一个要写的词。

GPT各版本模型 参数量
gpt-2 small 117M parameters
gpt-2 medium 345M parameters
gpt-2 large 762M parameters
gpt-2 extra large 1,542M parameters

读者可以用DEMO AllenNLP 体验下GPT-2模型,根据给定输入文本输出后一个预测词的top5。

1.1使用Transformer进行语言建模

NLP中由encoder和decoder组成的语言模型,二者其实都是由Transformer模块的部分堆叠而成。这种架构在机器翻译任务中是成功证明了有效性。该任务最好方法目前也是基于encoder-decoder架构的。
6层encoder-decoder堆叠

Transformer后续的展开工作是尝试去掉编码器或解码器,也就是只使用一套堆叠的transformer模块,然后使用海量文本,耗费大量的算力进行训练。比如GPT是只用Decoder的堆叠,BERT则主要是Encoder的堆叠,Transformer XL采用Recurrent Decoder的堆叠。
然后堆叠深度的不同,就是各个模型架构下不同模型的因素之一。GPT-2 small堆叠了12层,medium 24层,larger 36层,extra-large 48层

1.2GPT2与BERT的区别

GPT使用[Transformer解码器模块]构建的,BERT则是通过[Transformer编码器模块] 构建的。GPT类似传统语言模型,一次只输出一个单词,其效果好的原因也是每次新生成单词会接在之前生成的单词序列后面,这个序列会成为模型下一步的新输入,该机制为自回归(auto-regression),这个也是rnn模型的思想。其中TransfomerXL和XLNet本质上都是auto-regression。而Bert不是,但是Bert获得了上下文信息的能力。

1.3 Transformer模块的演进
1.3.1 编码器(encoder)模块
Encoder结构

以下继续分析每个encoder的详细结构,在 transformer的encoder中,数据经过一个self-attention模块,得到一个加权后的特征向量Z, 这个Z就是论文公式1中的Attention.

Attention(Q, K, V) = softmax(\frac{QK^{T}}{\sqrt{d_k}}) V

得到 Z 以后会传递给encoder的下一个模块, 即FeedForward Neural Network, 这个全连接由两层,第一层是ReLU, 第二层是线性激活函数,可以表示为:
FFN(Z)=max(0,ZW_1+b_1)W_2+b_2

1.3.2 解码器(decoder)模块
Decoder结构

Decoder模块和encoder不同地方在于Decoder中多了一个Encoder-Decoder Attention, 两个Attention分别用于计算输入和输出的权值:
① Self-attention: 当前翻译和已经翻译的前文之间的关系;
② Encoder-Decoder Attention: 当前翻译和编码的特征向量之间的关系。
(以上为Transformer的主要框架,后续会逐个介绍。)

1.3.3 PS:

关于GPT2中Masked self-attention 可以参考此篇文章介绍 图解GPT2 attention

Part2 自注意力(self-attention)

Self-Attention是Transformer最核心的内容,然而论文作者没有详细解释,以下补充和介绍细节。其核心思想是为每个单词学习一个权重,例如以下例子中,我们判断it 代指内容:

The animal don't cross the street because it was too tired.

通过加权得到类似图8的加权情况。

如图为正在encoding encoder#5中“it“,一部分attention机制专注在”The animal“上,并且拷贝了一部分它的表示到"it"的encoding上

在self-attention中,每个单词有3个不同的向量,分别是Query向量(), Key向量()和Value向量(V), 长度都是64,通过三个不同的权值矩阵由向量乘以这三个不同的矩阵, , 得到,其中三个矩阵的尺寸都是相同的,都是 。
image.png

具体计算如上图,以下为总结的Attention的计算方法,整个过程可以分成6步:

  1. 输入为词嵌入向量;
  2. 根据词嵌入向量计算到q,k,v 三个向量;
  3. 为每个向量计算一个score: score = \frac{q * k}{\sqrt{d_k}}
  4. 对score结果进行softmax激活函数处理;
  5. softmax 点乘Value值v ,得到加权后每个输入向量的评分 v;
  6. 对结果进行相加,得到结果向量z, z=\sum_{i=1}^{n} v

self attention计算示例图
$q$的矩阵计算,k ,v 与此相同
Softmax矩阵计算

在self-attention中最后强调的就是残差网络的short-cut结构,目的就是觉得退化问题和梯度消失。
image.png
residual netword和encoder细节

在此自注意基础上,加入了多头注意力机制,更好的提高了self-attention的表现。
多头注意力的计算示例
”it“单词其中一个attention head是关注The animal, 另一个关注在tired,所以"it"拷贝了”animal“ 和"tired"的向量

但是如果我们把所有head的表达都放在图片上,会比较难解释这个attention的关注点,如下图
8 heads attention

在Decoder解码器中,多了一个encoder-decoder attention, 来源于解码器上个输出,和则来源于(encoder)编码器的输出, 这里的可以让decoder关注于输入序列的合适的位置。解码是一个顺序操作的过程,也就是在解码第个特征向量时,我们只能看到第及其之前的解码结果,论文中把这种multi-head attention叫做masked multi-head attention.
Transformer的完整结构

Part3 位置编码

到现在Transformer并没有捕捉到顺序序列能力,因此引入位置编码(Position Embedding)的特征。位置编码在词向量中加入位置信息,这样Transformer就能区分不同位置的单词了。位置编码的方法不只有这一种。需要注意的是,编码方法需要能够处理未知长度的序列
论文给出编码公式:
PE(pos, 2i) = sin(\frac{pos}{1000^{\frac{2i}{d_model} }})
PE(pos, 2i+1) = cos(\frac{pos}{1000^{\frac{2i}{d_model} }})
pos表示单词位置,i表示单词维度,位置编码实现由Google开源的算法中 get_timing_signal_id()函数 获取对应代码。
设计原因,考虑到NLP任务中除了单词绝对位置,单词相对位置也非常重要。由公式sin(\alpha+\beta) = sin(\alpha) cos(\beta) + cos(\alpha)sin(\beta) 以及 cos(\alpha+\beta) = cos(\alpha)cos(\beta)-sin(\alpha)sin(\beta), 这表示位置k+p的位置向量可以表示为位置k的特征向量的变化,这个为模型捕捉单词间相对位置提供了一定的便利。

Part4 总结

优点:

(1)虽然Transformer最终也没有逃脱传统学习的套路,Transformer也只是一个全连接(或者是一维卷积)加Attention的结合体。但是其设计已经足够有创新,因为其抛弃了在NLP中最根本的RNN或者CNN并且取得了非常不错的效果,算法的设计非常精彩,值得每个深度学习的相关人员仔细研究和品位。
(2)Transformer的设计最大的带来性能提升的关键是将任意两个单词的距离是1,这对解决NLP中棘手的长期依赖问题是非常有效的。
(3)Transformer不仅仅可以应用在NLP的机器翻译领域,甚至可以不局限于NLP领域,是非常有科研潜力的一个方向。
(4)算法的并行性非常好,符合目前的硬件(主要指GPU)环境。

缺点:

(1)粗暴的抛弃RNN和CNN虽然非常炫技,但是它也使模型丧失了捕捉局部特征的能力,RNN + CNN + Transformer的结合可能会带来更好的效果。
(2)Transformer失去的位置信息其实在NLP中非常重要,而论文中在特征向量中加入Position Embedding也只是一个权宜之计,并没有改变Transformer结构上的固有缺陷

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。