Attention Is All You Need论文阅读

免责声明:本人科研萌新,编写博客以记录精读过的论文,如有理解错误欢迎大佬指正,同时也欢迎大家在评论区交流。

本文为梳理Transformer结构的发展,以及存在的问题,通过网络上一些大佬的讲解和论文原文阅读。

Attention的由来

Attention的发展历程与机器翻译紧密相关:从Simple RNN -> Contextualize RNN -> Contextualized RNN with attention -> Transformer(2017),接下来分别简单介绍。

  • 普通RNN一个最大的问题在于:因为其encoder后最终得到一个固定维度的序列,以及通过累加的方式记忆前面的信息,这导致RNN会遗忘前面学到的信息。同时RNN的decoder只利用了前一个decoder输出的数据,随着解码时间过长,同样会导致解码时“遗忘”源端的信息。
  • 为了避免随着decoder时间过长,遗忘源端的信息,Contextualized RNN在decoder时,每次输入的序列不再只是前一个decoder的输出,而是(前一个decoder的输出+encoder的输出),这样就可以保证decoder不遗忘之前的源端信息。但encoder的输出结果是一个固定维度的序列,每次解码都应该用到的一样的静态序列吗?这就引出了Attention结构.
  • Attention在decoder时,会利用encoder中每一个位置的输出,自己计算一个注意力得分,从而决定每一个encoder的输出哪个更加重要,也就是为每一个encoder的输出分配一个权重,再求和,是一个动态序列,将这个结果和前一个decoder的输出拼接,而Contextualized RNN中仅仅是将每一个encoder编码最后的输出和decoder的每个输入拼接起来。

Attention注意力得分计算方式

字丑轻喷
图1 Attention原理图,标注了每一步矩阵的大小,假定batch_size=1

A t t e n t i o n ( Q , K , V ) = softmax ⁡ ( Q K T d k ) V Attention(Q, K, V)=\operatorname{softmax}\left(\frac{Q K^{T}}{\sqrt{d_{k}}}\right) V Attention(Q,K,V)=softmax(dk QKT)V (1)

  • 我们用 x n ∈ [ x 1 , x 2 , . . . , x N ] x_n\in[x_1, x_2, ..., x_N] xn[x1,x2,...,xN]代表encoder编码的序列的输出,其中N是输入的句子中单词的最大个数,每个单词由 d m o d e l d_{model} dmodel个数字表示,组成一个 X N × d m o d e l X^{N×d_{model}} XN×dmodel输出矩阵。
  • y j ∈ [ y 1 , y 2 , . . . , y M ] y_j\in[y_1, y_2, ..., y_M] yj[y1,y2,...,yM],表示decoder解码后的输出,其中M是输出的句子中单词的最大个数,每个单词同样由 d m o d e l d_{model} dmodel个数字表示, y m y_m ym ( y m − 1 , A t t n m ) (y_{m-1}, Attn_m) (ym1,Attnm)共同决定,其中 A t t n m Attn_m Attnm就是该位置对应的注意力得分,计算方式见公式(1)
  • 这个公式的左半部分是encoder每个位置的注意力得分, softmax ⁡ ( Q K T d k ) \operatorname{softmax}\left(\frac{Q K^{T}}{\sqrt{d_{k}}}\right) softmax(dk QKT),最外层的softmax用于得到encoder每个位置的注意力占总注意力的比重;
    • Q就是对 y m − 1 y_{m-1} ym1的一个线性映射组成的矩阵,原大小为[1× d m o d e l d_{model} dmodel],映射完的大小为[1× d k d_k dk],这里假定batch_size为1
    • K是对 X N × d m o d e l X^{N×d_{model}} XN×dmodel的映射,大小转换为[N× d k d_k dk],这里Q和K的映射结果大小需要一致,分母则是一个归一化操作,
  • 右半边部分的V同样是 X N × d m o d e l X^{N×d_{model}} XN×dmodel的线性映射组成的矩阵,大小转换为[N× d v d_v dv],这里的 d v d_v dv没有任何限制,和左半部分得到的注意力得分(权重)相乘,得到attention的得分,大小为[1× d v d_v dv],然后再经过一个线性映射,变为[1× d m o d e l d_{model} dmodel]的矩阵,作为当前 y m y_m ym的输入

Transformer

在这里插入图片描述
图2 Transformer论文原图
上述的Attention结构有一个关键的问题,他是和RNN一起结合使用的,也就是说,RNN容易“遗忘”的问题,他依然没有解决,Transformer是一种完全使用Attention的方案,不需要结合CNN或RNN架构
,如图2所示,Transformer整体可以分为:

1. Encoder层

  • 上图的左边为encoder层,原始的向量输入后会补充一位的位置信息,接着进入encoder模块,该模块会重复6次(原论文),该模块中包含两个子模块,每个子模块都包含残差连接和Layer Normalizaion,为了使残差连接方便,每个子模块的输出都是 d m o d e l = 512 d_{model}=512 dmodel=512维度,第二个子模块很简单,就是一个2层的全连接层,为了增加模型的非线性,使用了ReLU做激活函数,下面详细说一说多头Attention模块。
  • 这里的多头Attention并不是上述提到的原始的Attention,而是Self-attention,可以看到图中输入的三个分支q, k, v全部来自encoder模块,而原始的Attention的Q是来自decoder的一个线性映射,这里的Q来自当前输入的Encoder,剽窃李宏毅老师PPT中的一张图:
    在这里插入图片描述
    以计算 x 2 x^2 x2的注意力得分 b 2 b^2 b2为例,用 x 2 x^2 x2自身的 q 2 q^2 q2和每个(包含 x 2 x^2 x2自己)输入的k相乘,得到QK,然后在乘以各自的V,最后相加。可以看出,其实Self-Attention的就是把原本来自Attention的Q,换成了当前encoder编码向量的Q。
    在这里插入图片描述
  • 那么多头Attention是什么呢?其实就是比如原本输入的向量维度为512,然后我们将整个向量投入计算QKV,多头就是将512切分为多个子空间,比如8个,然后并行分别QKV,最后拼接,这样计算量几乎不变,但能够并行计算,同时能够让模型从不同的角度(子空间),考虑不同的输入,一举多得。
    • 值得注意的是,这里的子空间划分方式,我们以Q为例直接看代码:
self.W_Q = nn.Linear(d_model, d_k * n_heads)  # Q: [batch_size x len_q x d_model]
q_s = self.W_Q(Q).view(batch_size, len_q, n_heads, d_k).transpose(1, 2)  # q_s: [batch*n_heads*len_q*d_k]
# 为什么要这样切(view函数)再转置,而不是直接像下面这样切
# q_s = self.W_Q(Q).view(batch_size, n_heads, len_q, d_k)  # q_s: [batch*n_heads*len_q*d_k]
# 第一种分割方式其实是先分割各个单词,也就是说多头的q_i, k_i, v_i来自的是一个句子的每个单词的某些部分,比如“我爱你”,每个单词由512个数字表示,分8头,第一头就是“我”里取0-64位+“爱”里取0-64位+“你”里取0-64位
# 第二种分割方式直接是“我”里取0-512位
# 这也就是论文中想要的能够从多个角度(子空间)看待问题

2. Decoder层

  • 在Decoder中有三个模块,第三个模块还是个全连接,就不讲了。
  • 第一个模块,虽然也是一个多头Attention,但这个模块和encoder中的不太一样,因为,encoder中模型可以获得前后全部输入序列的信息,整合为K,但Decoder中,模型只能看到当前位置之前输出出来的数据,后面的推理数据是看不到的,这里为了表述一致还是使用QK,然后对于decoder未推理到的部分,添加掩码负无穷,这样Softmax的时候就被忽略了。
  • 第二个模块就是一个普通的Attention,KV来自encoder,Q来自decoder,和就是原始的Attention,不过换成多头的了

3. 一些补充

  1. 位置信息:
    在这里插入图片描述
    作者使用正余弦函数,表达第i个输入的位置信息,至于为什么使用这个,而不是用顺序标注的绝对定位,是因为作者假定该函数能够帮助模型很好的学习每个位置的相对信息。
  2. Attention有乘积,加和两种方式,也就是QK和Q+K,两者理论上相似,但由于矩阵乘法运算被优化的更快,更节约空间,因此实践中我们都使用乘法。同时当矩阵维度较小是乘和加的表现效果类似,但当矩阵变大,加的效果要更好,作者怀疑是大的矩阵使softmax进入梯度极小的区域,为了抵消这个效果,对于QK还要乘以一个 1 d k \frac{1}{\sqrt{d_{k}}} dk 1

参考文章

  • Attention发展历程:https://zhuanlan.zhihu.com/p/104393915
  • Attention和Transformer:https://zhuanlan.zhihu.com/p/38485843
  • 如何理解 Transformer 中的 Query、Key 与 Value:https://blog.csdn.net/yangyehuisw/article/details/116207892
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雨夜闭门

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值