目录
attention is all you need的解读可以参考
https://daiwk.github.io/posts/platform-tensor-to-tensor.html
各种attention model可以参考:
https://daiwk.github.io/posts/dl-attention-models.html
本文参考自然语言处理中的自注意力机制(Self-Attention Mechanism)
论文作者之一Lukasz Kaiser的ppt:https://daiwk.github.io/assets/attention-is-all-you-need-lkaiser.pdf
Attention函数的本质可以被描述为一个查询(query)与一系列(键key-值value)对一起映射成一个输出。分为以下3步:
\[
attention(Q,K,V)=softmax(\frac{QK^T}{\sqrt {d_k}})V
\]
目前在NLP研究中,key和value常常都是同一个,即 key=value(如下例中的源语言的编码器输出)。
对比https://daiwk.github.io/posts/nlp-nmt.html#4-%E6%B3%A8%E6%84%8F%E5%8A%9B%E6%9C%BA%E5%88%B6以及https://daiwk.github.io/posts/platform-tensor-to-tensor.html#422-attention可以发现:
\(h_j\)
就是\(V\)
\(h_j\)
同样是\(K\)
\(z_i\)
就是\(Q\)
\(e_{ij}\)
就是\(\frac{QK^T}{\sqrt {d_k}}\)
\(a_{ij}\)
就是\(softmax(\frac{QK^T}{\sqrt {d_k}})\)
\(c_i\)
就是最终的\(attention(Q,K,V)\)
所以说,机器翻译的attention,本质就是想给源语言的encoder输出的每一个元素\(h_j\)
(即V) 搞一个权重,然后加权求和。而这个权重是通\(h_j\)
它自己 (即K=V) 与目标语言的隐层状态\(z_i\)
(即Q) 进行变换得到的。所以:
k=v=源语言的encoder输出,q=目标语言的隐层状态。
再理解回nmt里(不理那个\(\sqrt{d_k}\)
)。Q是mx1,K是nx1,i=1->m,j=1->n,\(e_{ij}=QK^T\)
是一个m行目标语言,n列源语言的矩阵,那么\(a_{ij}\)
是对\(e_{ij}\)
求softmax,分母就是第i行每个元素(即这第i个目标语言的词,对应的所有源语言词)的exp之和,分子就是第i行第j列(第i个目标语言词对应的第j个源语言词)的exp。
再强调一次,一定要记得i、Q、m是目标语言的,j、K、n是源语言的,所以是\(QK^T\)
,我们要拿attention来对源语言也就是V=K来做加权。做加权这步,就是一个mxn的矩阵,乘一个nx1的矩阵,得到最后mx1矩阵。就是第i行和nx1的这一列对应相乘相加,得到一个元素,最后总共得到m个元素。相当于对于目标语言的第i个词来讲,他和源语言的每个词(共n个词)分别有个相关性(mxn矩阵的一行),然后作为这次输入的n个词的权重,求个和,当做这第i个目标语言的词的表示,即最终mx1的第i个元素。
另外,得到的context只是作为产出下一个目标语言词的输入之一,还有前一个目标语言的词,及前一个目标语言的隐层状态。
再来理解一下其中的softmax那步:
类比一个分类任务,m行n列,m个样本,n个类别,每一行就是对这个样本而言,他在这个分类的概率,所以分子是这个类别,分母是所有类别(这一行求和)
类似地,对于这个attention矩阵,一行就是一个目标语言的词,表示这个词和目标语言每个词的相关程度,所以分母是所有目标语言的词(这一行求和)。
\(d_{model}\)
维,各自通过h个线性变换拆成h部分,每一部分的大小是\(d_k\)
,\(d_k\)
和\(d_v\)
(\(d_k=d_v=d_{model}/h\)
)。不同之处在于进行了h次计算而不仅仅算一次,论文中说到这样的好处是可以允许模型在不同的表示子空间里学习到相关的信息。
Self-Attention即K=V=Q,例如输入一个句子,那么里面的每个词都要和该句子中的所有词进行Attention计算。目的是学习句子内部的词依赖关系,捕获句子的内部结构。
使用self-attention的原因: