attention详解

在seq2seq+attention入门里曾经提到一点attention,感觉这个东西很有意思,模型千变万化,也非常符合人类的思想,在这里详细介绍下attention

1. 定义

剥离开seq2seq模型,Google给了attention模型一个更加形式化的定义

attention是由query和一系列对组成的,query依次与{key_1,key_2...}计算相似度,得到的结果作为权重与value相乘(这里结果有一步softmax操作确保权值和为1)

attention详解_第1张图片

AttnValue=softmax(f(query,key_i))*value_i

不同任务中attention在结构上大同小异,所不同的是query、key、value所代表的含义。以翻译为例,在seq2seq模型中,query代表h_{i-1},即decoder上一时刻的隐藏状态。key是encoder所输出的结果,即每一个词在encoder端编码的结果,有n个词就有n个key。query要和这n个key分别计算相似度,结果softmax后生成权重后与value相乘。在这里value与key含义相同,也是encoder每时刻的输出。记得在seq2seq模型中每一时刻decoder的输入有(h_{i-1},y_{i-1},c_i),这个c_i就是上述加权value的相加。也就是说,之前的c_i我们用encoder最后时刻的hidden来表示encoder句子的编码,但现在我们每一时刻都有一个带权重的encoder句子编码。

2. 相关性计算

初学attention的时候,比较疑惑的一点就是这个相关性是怎么得到的,权重是一个数,也就是说我之前相关性计算的结果需要是一个数。这里相关性计算有三种方式

1. 点乘 两个向量dot是对应维相乘再求和,结果是一个数字

2. 余弦相似 余弦相似其实就是第一种点乘的情况下再除一个两个向量模的乘积。这种方式可以限制相似度结果在一个较小的范围,Google的attention在实现的时候就是这样做的

3. 生成式 既然是在神经网络里,那么就把权值生成的任务都交给网络来做,即weight=MLP(query,key),这时我们输入的就是query和所有key的和了,输出的维度就是attention权值的个数。也许看上去不太合理,但是模型可以学到这种表示方法,实际做是可以的。

3. self attention

attention家族中的新兴,谷歌大佬将其发扬光大,实际使用确实很好使,效果提升这种玄学东西先放在一边,训练速度可是比用rnn类型的方式快了不少。self attention的结构和上面是一样的,但是它的Q,K,V是一样的,Q=K=V。例如在encoder端,每一个词都要和余下的所有词计算attention,为了学习到句子本身的结构和词与词之间的依赖关系。

self attention的细节见下图,之前一直不解的是self attention是怎么在encoder端(或decoder端)内部做attention,算完权重又要乘回到那个向量中去。其实rnn中每一个时间步都有一个输出output,我们把这个看做是这个单词的表示,在self attention中做的是一样的事情。如下图,在计算thinking的时候,thinking这个词先embedding成x1向量,q,k,v分别都是x1和矩阵w_q,w_k,w_v相乘得来的,其实就是做了个线性变换。现在有两个词thinking和machines,所以x1和两个词做attention,包括它自己。z1=0.88*v1+0.12*v2,z1就是thinking经过self attention之后新的表示。所以一句话经过self attention后还是一句话。因为这个操作是可以并行的,所以比rnn要快不少。

attention详解_第2张图片

 

参考

https://www.cnblogs.com/robert-dlut/p/8638283.html

https://blog.csdn.net/mpk_no1/article/details/72862348

https://jalammar.github.io/illustrated-transformer/     attention详解

https://zhuanlan.zhihu.com/p/39034683

你可能感兴趣的:(机器学习,机器学习基础)