NLP学习笔记——attention和transformer
一、Attention
在引入attention之前先要讨论下seq2seq。
1、序列到序列(seq2seq)模型
1)输入:一个(单词、字母、图像特征)序列;
2)输出:另外一个序列。
3)组成:
a.编码器(Encoder)
b.解码器(Decoder)
4)模型原理
a.-> 编码器(Encoder):(处理)输入序列中的每个元素,把这些信息转换为一个向量(称为上下文(context));
(注:1.在机器翻译任务中,上下文(context)是一个向量(基本上是一个数字数组);
2.转换为向量是使用 word embedding 算法来完成的;
)
b.-> 编码器把上下文(context)(发送)给解码器(Decoder),解码器逐项(生成)输出序列中的元素。
(注:RNN网络结构的过程:在每个时间步接受 2 个输入:
- 输入序列中的一个元素(在解码器的例子中,输入是指句子中的一个单词,最终被转化成一个向量)
- 一个 hidden state(隐藏层状态,也对应一个向量)
)
5)缺点:上下文context向量是这类模型的瓶颈。这使得模型在处理长文本时面临非常大的挑战。
–> 引出新的模型Attention:Attention机制可以使得模型可以根据需要,关注到输入序列的相关部分。
2.Attention
1)相比seq2seq,attention的优点
a.编码器把所有时间步的 hidden state(隐藏层状态)传递给解码器,而不是只传递最后一个 hidden state(隐藏层状态):
b.注意力模型的解码器在产生输出之前,做了一个额外的处理。为了把注意力集中在与该时间步相关的输入部分。解码器做了如下的处理:
1. 查看所有接收到的编码器的 hidden state(隐藏层状态)。其中,编码器中每个 hidden state(隐藏层状态)都对应到输入句子中一个单词。
2. 给每个 hidden state(隐藏层状态)一个分数(我们先忽略这个分数的计算过程)。
3. 将每个 hidden state(隐藏层状态)乘以经过 softmax 的对应的分数,从而,高分对应的 hidden state(隐藏层状态)会被放大,而低分对应的 hidden state(隐藏层状态)会被缩小。
2)attention模型的整个执行过程:
1. 注意力模型的解码器 RNN 的输入包括:一个embedding 向量,和一个初始化好的解码器 hidden state(隐藏层状态)。
2. RNN 处理上述的 2 个输入,产生一个输出和一个新的 hidden state(隐藏层状态 h4 向量),其中输出会被忽略。
3. 注意力的步骤:我们使用编码器的 hidden state(隐藏层状态)和 h4 向量来计算这个时间步的上下文向量(C4)。
4. 我们把 h4 和 C4 拼接起来,得到一个向量。
5. 我们把这个向量输入一个前馈神经网络(这个网络是和整个模型一起训练的)。
6. 前馈神经网络的输出的输出表示这个时间步输出的单词。
7. 在下一个时间步重复这个步骤。
二、transformer
1)最直观优点:使得模型训练过程能够并行计算。
(注:能够并行计算是因为:其计算过程经过 Self Attention 计算,使得整个运算过程可以并行化计算。)
(注:在 RNN 中,每一个 time step 的计算都依赖于上一个 time step 的输出,这就使得所有的 time step 必须串行化,无法并行计算)
2)组成:
左边是编码部分(encoding component),右边是解码部分(decoding component)。
(注:编码部分是多层的编码器(Encoder)组成,解码部分也是由多层的解码器(Decoder)组成)
3)使用self attention过程:
首先会经过一个 Self Attention 层,这个层处理一个词的时候,不仅会使用这个词本身的信息,也会使用句子中其他词的信息
(你可以类比为:当我们翻译一个词的时候,不仅会只关注当前的词,也会关注这个词的上下文的其他词的信息)
4)Encoder(编码器)
编码器(Encoder)接收的输入都是一个向量列表,输出也是大小同样的向量列表,然后接着输入下一个编码器。
注:每个单词转换成一个向量之后,进入self-attention层,每个位置的单词得到新向量,然后再输入FFN神经网络。
5)使用向量来计算 Self Attention的过程
第 1 步:对输入编码器的每个词向量,都创建 3 个向量,分别是:Query 向量,Key 向量,Value 向量。这 3 个向量是词向量分别和 3 个矩阵相乘得到的,而这个矩阵是我们要学习的参数
第 2 步:计算 Attention Score(注意力分数)。
第 3 步:把每个分数除以
(
d
k
e
y
)
\sqrt(d_{key})
(dkey) (
d
k
e
y
d_{key}
dkey是 Key 向量的长度)
第 4 步:接着把这些分数经过一个 Softmax 层,Softmax可以将分数归一化,这样使得分数都是正数并且加起来等于 1。
第 5 步:得到每个位置的分数后,将每个分数分别与每个 Value 向量相乘。
(注:这种做法背后的直觉理解就是:对于分数高的位置,相乘后的值就越大,我们把更多的注意力放到了它们身上;
对于分数低的位置,相乘后的值就越小,这些位置的词可能是相关性不大的,这样我们就忽略了这些位置的词。)
第 6 步:把上一步得到的向量相加,就得到了 Self Attention 层在这个位置(这里的例子是第一个位置)的输出。