深度学习基础篇之Transformer网络

Transformer的大名已经听过很久了,一直没有找到机会详细了解该模型的原理及架构,趁着这次要复习的机会把transformer的原理彻底搞懂。本文参考了沐神在B站的论文讲解以及一些其他人的transformer文章。

1、为什么要提出Transformer?

transformer最初源自Google团队的一篇论文:《Attention is all you need》,文章的目的是解决机器翻译中的问题。机器翻译是一种端到端的模型,input一个序列,output一个序列,如下图所示。
在这里插入图片描述
主流的文本翻译使用的是encoder-decoder结构,结构内使用RNN或者CNN进行特征提取和序列生成。
RNN的特点:从左往右一步步计算,对第 t t t个状态 h t h_t ht,由 h t − 1 h_{t-1} ht1和当前词 t t t计算。所带来的缺点如下:

  1. 难以并行
  2. 过早的历史信息可能会被丢掉
  3. 时序比较长的时候, h t h_t ht存储了很多历史信息,内存开销很大

CNN的特点:CNN相对于RNN的好处是可以并行计算,但是CNN对于较长的序列难以建模。因为卷积计算的时候一般是一个比较小的窗口,比如33的窗口。如果2个像素相隔的比较远,需要用很多33的卷积层,一层层的叠加上去,才能把间隔很远的2个像素联系起来。

综上,本文提出的transformer架构使用注意力机制,使得机器翻译任务的准确性大幅提升,同时提高了并行能力。其主要效果如下:

  • 英-德:提高2个BLEU
  • 英-法:达到了最好的效果,而且模型训练所耗的资源也很少

2、Transformer的模型结构

Transformer的整体结构如下图所示:
在这里插入图片描述
简单介绍下上图,图中的结构可以清晰的分成左右两个部分,左边的是encoder(将输入特征转化为模型认识的形式)、右边的是decoder(输出最终的预测结果)。

  • 把inputs进行embedding化
  • 与inputs的位置向量相加形成最终的inputs向量
  • 输入向量导入到encoder中
    • inputs向量进入到多头注意力机制中
    • 从注意力层进入到MLP层
  • encoder的计算结果输入到decoder中作为K值和V值
    • outputs实际上是decoder之前输出的结果
    • 对outputs进行embedding化
    • 与outputs的位置embedding加一起形成outputs向量
    • outputs向量输入到masked多层注意力机制中
    • masked的结果作为Q,encoder的结果作为K和V,一起输入到多头注意力机制中
    • 再经过一个MLP层
  • 通过一个线性层
  • 最后对结果做一个Softmax处理后输出预测结果

总结:Transformer是一个比较标准的encoder-decoder架构。encoder和decoder的内部结构不同,encoder的输出作为decoder的输入。

2.1 Encoder和Decoder结构

Encoder结构:重复6次下图的内容就是论文里的一个完整encoder结构。
在这里插入图片描述
每个layer有2个sub-layers。

  • 第一个sub-layer是multi-head self-attention
  • 第二个sub-layer是MLP

每个sub-layer的输出都会做残差连接和LayerNorm,转化成公式就是 L a y e r N o r m ( x + S u b l a y e r ( x ) ) LayerNorm(x+Sublayer(x)) LayerNorm(x+Sublayer(x)),sub-layer代表self-attention或者MLP。
layernorm相比batchnorm的不同在于:batchnorm是按照特征位置进行归一化、layernorm是从样本维度进行归一化。对于本文的机器翻译领域,由于序列的长度变化较大,按照特征进行归一化会出现一些样本没有该特征一些有该特征,归一化时的均值和方差变化较大。

2.2 注意力机制

注意力函数是将query和key-value对映射为一个输出的函数,其中所有的query、key、value和output都是向量。也可以说成output是value的加权和,value的权重由query和key的相似度决定。

2.2.1 Scaled Dot-Product Attention

不同的相似度函数对应的是不同的注意力机制,本节的注意力机制是最简单的一种,该函数的具体计算方法是对每一个query和key做内积,把内积的结果作为相似度。
A t t e n t i o n s c o r e = S o f t m a x ( q u e r y ∗ k e y d k ) ∗ V Attention_{score}=Softmax(\frac{query*key}{\sqrt{d_k}})*V Attentionscore=Softmax(dk querykey)V
query和key做内积:如果两个向量的大小一致,那么内积的值越大,向量的相似度就越高。如果内积的值为0,则这两个向量正交,没有相似度。

d k d_k dkquery和key的长度,其作用是防止Softmax函数的梯度消失:当 d k d_k dk不是很大的时候,÷不÷都可以,但是当值比较大的时候,query和key内积的结果差距会变大。导致最大值的softmax值更加靠近1,剩下的值更加靠近0,值就会更加向两段靠拢,计算梯度的时候就会比较小。

对于decoder部分的attention来说,该如何做mask呢?

为了避免在t时刻看到t时刻之后的输入,只需要在计算权重的时候把t时刻之后的query与key的乘积结果替换成一个很大的负数,如0.00000000000001

2.2.2 Multi-head Attention

前面讲的是一个注意力函数,在实际的使用中不会仅仅使用一个注意力函数,而是把query、key和value全部经过一个线性投影生成WQ、WK和WV。投影h次,然后再做h次的注意力函数,把每个函数的输出拼接到一起,再投影后得到最终的输出,具体结构如下图所示:
在这里插入图片描述
输入是原始的Q、K和V,把他们输入到一个线性层中,线性层会把他们投影到一个较低的维度,然后再经过左图的注意力函数计算。

由于线性层的投影会投h次,每次都会得到一个输出,把h个输出concat到一起,最后做一个线性投影得到最终多头注意力机制的输出结果。

这里就有一个问题出现了,为什么一样的注意力机制我要重复h次?为什么要在多头注意力机制前后加一个线性投影层?

首先回答第一个问题,单注意力函数虽然可以学习到序列的权重,但是也只能学习到一种权重。多头注意力机制会关注序列的不同模式,学习到不同的内容,方便我们更全面的理解序列。比如翻译“I like play basketball.”,对于‘play’而言,有的注意力函数更关注’I’,有的更关注’basketball’,会让我们更好的翻译这段话。
对于第二个问题,当我们引入多头注意力机制后,如果不做线性投影,每个注意力函数的Q、K和V都是一样的,没什么好学习的内容,多头注意力也发挥不了作用。一旦引入一个线性投影层之后,每一层的Q、K和V都是不一样的,每一层的投影函数W也是不一样的,可以根据不同的目标学习不同W。

2.3.3 注意力机制在模型中的应用

本文的模型涉及三种不一样的注意力层,分别是encoder里面的多头注意力层、decoder里面的多头注意力层和mask多头注意力层。

Encoder的注意力层
假设句子的长度是n,每个单词的词向量维度是d,则encoder的输入是一个n*d的矩阵。
在这里插入图片描述
Encoder的注意力层有三个输入,分别是query、key和value。一根线进来,复制了三下,同样的输入即作为query也是key和value,所以叫做自注意力机制。

输入了n个query,每个query对应一个输出,也就是n个输出。输出是value的加权和,当query和key的相似度越高,value的权重越大。不考虑多头机制和有线性投影的情况下,输出是输入的加权和,权重是当前向量与其它向量的相似度。

Decoder的masked多头注意力层
在这里插入图片描述
masked体现在模型看不到 t t t 时刻以后的decoder输入,也就是图左下角黄圈内的绿色权重是0

Decoder的多头注意力层
和前面两个注意力层不同的是,这里的注意力层不再是self-attention,注意力层的key-value来自encoder的输出而非decoder的输入。
在这里插入图片描述
query来自decoder里masked multi-head attention层的输出。
在这里插入图片描述

2.3 Position-wise Feed-Forward Networks

其实就是一个MLP,之所以加上Position-wise是由于MLP对每个词单独作用一次,且每个词使用的MLP是一样的。这里的MLP结构是两层网络,W1层把维度扩展至2048,最后W2层投影缩回到512维,方便后续的操作。

假设一种最简单的情况:没有残差连接、没有layernorm、没有投影,看看transformer和RNN的区别。

模型对比TransformerRNN
不同点(对序列的处理)Attention对输入做加权和,然后进入MLP,每个输入点独立计算输出(以为已经包含了序列信息)从上一时刻的信息输出作为下一时刻的输入
相同点(语义转化)用一个线性层或MLP做语义空间转化用一个线性层或MLP做语义空间转化
示意图在这里插入图片描述在这里插入图片描述

2.4 Embeddings and Softmax

embedding:将输入的一个词映射为一个长为 d d d 的向量,用这个长为 d d d 的向量表示整个词,这就是embedding,本文的d=512

Softmax:经过用于多分类的类别判定,其特点是所有的类别值加一起是1,其计算函数如下:
S o f t m a x ( z i ) = e z i ∑ c = 1 C e z c Softmax(z_i) = \frac{e^{z_i}}{\sum_{c=1}^Ce^{z_c}} Softmax(zi)=c=1Cezcezi
其中 z i z_i zi是第 i i i个节点的输出值,C是全部类别的个数。

2.5 Positional Encoding

为什么attention没有时序信息?
这是因为output是value的加权和(权重是query和key之间的相似度,和序列信息无关),一句话打乱后在attention的输出结果也是不变的,这样的效果肯定是我们不希望的。

这时候我们通过positional encoding的方法引入时序信息,假设一个词的embedding表示为一个512维的向量,用另一个512维的向量来表示词的位置(如1 2 3 4 5 6…)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值