---
doc_type: hypothesis-highlights
url: 'https://blog.csdn.net/Tink1995/article/details/105012972'
---

## Metadata
- Author: [blog.csdn.net]()
- Title: 史上最小白之Attention详解_Stink1995的博客-CSDN博客_attention小白解释
- Reference: https://blog.csdn.net/Tink1995/article/details/105012972
- Category: #source/article🗞
- Tags:

## Highlights

![image](https://myonemanager.lzybetter.repl.co/picbed/picbed/20200321225923264.png)

- 上图就是引入了Attention 机制的Encoder-Decoder框架。咱们一眼就能看出上图不再只有一个单一的语义编码C，而是有多个C1,C2,C3这样的编码。当我们在预测Y1时，可能Y1的注意力是放在C1上，那咱们就用C1作为语义编码，当预测Y2时，Y2的注意力集中在C2上，那咱们就用C2作为语义编码，以此类推，就模拟了人类的注意力机制。

>*笔记*：
> encoder-decoder模型的问题是encoder会将整个输入都转换为唯一的语义编码C，之后C会作用于整个decoder的解码过程，这会导致两个问题：1. 在解码过程中输入对输出的每个部分影响是相同的，这与实际情况不符；2. 对于较长的输入，全部压缩成一个语义编码会导致信息的丢失；attention机制就是为了解决这两个问题提出的；

- 将Source中的构成元素想象成是由一系列的<Key,Value>数据对构成（对应到咱们上里面的例子，key和value是相等地，都是encoder的输出值h），此时给定Target中的某个元素Query（对应到上面的例子也就是decoder中的$h_i$），通过计算Query和各个Key的相似性或者相关性，得到每个Key对应Value的权重系数，然后对Value进行加权求和，即得到了最终的Attention数值。所以本质上Attention机制是对Source中元素的Value值进行加权求和，而Query和Key用来计算对应Value的权重系数

>*笔记：*
>注意力机制计算过程：
>1. 利用encoder的输出$h_1, h_2, h_3, ..., h_j$与当前时刻decoder的隐藏值$H_i$计算相关性$F_i$；
>2. 利用softmax函数处理$F_1$得到注意力分配权重$\alpha_{ij}$(j是encoder的时刻，i是decoder的时刻)；
>3. 将encoder的输出值h与对应的注意力分配权重α进行点乘求和，就得到注意力attention；


- 相似度计算方法1： 点积：就是将Query和Keyi进行点积，Transformer中就是用的这种方法。
$$
Similarity(Q,K_i) = Query \times Key_i
$$
>*笔记*
>就是将decoder的隐藏值$H_i$分别与encoder的输出值$h_j$进行点乘

- 相似度计算方法2：：Cosine相似性-余弦相似度： 
$$
Similarity(Q,K_i) = \frac{Query\times Key_i}{||Query||·||Key_i||}
$$
- 分子就是两个向量Query与Key的点积 分母就是两个向量的L2范数，(L2范数：指向量各元素的平方和然后求平方根)

- 相似度计算方法3：MLP网络：
$$
Similarity(Q,K_i) = MLP(Query, Key_i)
$$

- 计算出Query和Keyi的相似性后，第二阶段引入类似SoftMax的计算方式对第一阶段的相似性得分进行数值转换，一方面可以进行归一化，将原始计算分值整理成所有元素权重之和为1的概率分布；另一方面也可以通过SoftMax的内在机制更加突出重要元素的权重；
$$
\alpha_i=Softmax(Sim_i)=\frac{e^{Sim_{i}}}{\sum_{j=1}^{L_X}{e^{Sim_i}}}
$$

- 第二阶段的计算结果 $\alpha_i$ 即为 $Value_i$ 对应的权重系数，然后进行加权求和即可得到Attention数值：
$$
Attention(Query, Value) = \sum_{i=1}^{L_x}{\alpha_i·Value_i}
$$

![image](https://myonemanager.lzybetter.repl.co/picbed/picbed/20200322210257300.png)

- 阶段1：Query与每一个Key计算相似性得到相似性评分s 
- 阶段2：将s评分进行softmax转换成\[0,1\]之间的概率分布 a
- 阶段3：将$[a_1,a_2,a_3…a_n]$作为权值矩阵对Value进行加权求和得到最后的Attention值

> Attention中：
> Query是上个步长的decoder的hidden_state；
> Key是encoder的output的线性变换；
> Value是encoder的output的线性变换；

- 优缺点：
- 优点： 1.速度快。Attention机制不再依赖于RNN，解决了RNN不能并行计算的问题。这里需要说明一下，基于Attention机制的seq2seq模型，因为是有监督的训练，所以咱们在训练的时候，在decoder阶段并不是说预测出了一个词，然后再把这个词作为下一个输入，因为有监督训练，咱们已经有了target的数据，所以是可以并行输入的，可以并行计算decoder的每一个输出，但是再做预测的时候，是没有target数据地，这个时候就需要基于上一个时间节点的预测值来当做下一个时间节点decoder的输入。所以节省的是训练的时间。
- 2.效果好。效果好主要就是因为注意力机制，能够获取到局部的重要信息，能够抓住重点。 
- 缺点： 1.只能在Decoder阶段实现并行运算，Encoder部分依旧采用的是RNN，LSTM这些按照顺序编码的模型，Encoder部分还是无法实现并行运算，不够完美。 
- 2.就是因为Encoder部分目前仍旧依赖于RNN，所以对于中长距离之间，两个词相互之间的关系没有办法很好的获取。

>*笔记：*
>总结来说，attention机制主要集中于对decoder的优化，并没有对encoder有太多优化；

- Self Attention顾名思义，指的不是Target和Source之间的Attention机制，而是Source内部元素之间或者Target内部元素之间发生的Attention机制，也可以理解为Target=Source这种特殊情况下的注意力计算机制。其具体计算过程是一样的，只是计算对象发生了变化而已，相当于是Query=Key=Value，计算过程与attention一样

<div align="center"><img src="https://myonemanager.lzybetter.repl.co/picbed/picbed/20200322231248341.png"></div>
- 我们想知道这句话中的its，在这句话里its指代的是什么，与哪一些单词相关，那么就可以将its作为Query，然后将这一句话作为Key和Value来计算attention值，找到与这句话中its最相关的单词。通过self-attention我们发现its在这句话中与之最相关的是Law和application，通过我们分析语句意思也十分吻合。

- 如此引入Self Attention后会更容易捕获句子中长距离的相互依赖的特征，因为如果是RNN或者LSTM，需要依次序序列计算，对于远距离的相互依赖的特征，要经过若干时间步步骤的信息累积才能将两者联系起来，而距离越远，有效捕获的可能性越小。但是Self Attention在计算过程中会直接将句子中任意两个单词的联系通过一个计算步骤直接联系起来，所以远距离依赖特征之间的距离被极大缩短，有利于有效地利用这些特征。除此外，Self Attention对于增加计算的并行性也有直接帮助作用。正好弥补了attention机制的两个缺点，这就是为何Self Attention逐渐被广泛使用的主要原因。

