写点什么

初步了解 RNN, Seq2Seq, Attention 注意力机制

作者:Studying_swz
  • 2023-06-06
    天津
  • 本文字数:1788 字

    阅读完需:约 6 分钟

初步了解RNN, Seq2Seq, Attention注意力机制

@TOC


</font>


<hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1">


循环神经网络 RNN 结构被广泛应用于自然语言处理、机器翻译、语音识别、文字识别等方向。本文主要介绍经典的 RNN 结构,以及 RNN 的变种(包括 Seq2Seq 结构和 Attention 机制)。希望这篇文章能够帮助初学者更好地入门。

1.经典的 RNN 结构


这就是最经典的 RNN 结构,它的输入是:



输出为:



也就是说,输入和输出序列必有相同的时间长度!









2.Sequence to Sequence 模型


在 Seq2Seq 结构中,编码器 Encoder 把所有的输入序列都编码成一个统一的语义向量 Context,然后再由解码器 Decoder 解码。在解码器 Decoder 解码的过程中,不断地将前一个时刻 t-1 的输出作为后一个时刻 **t **的输入,循环解码,直到输出停止符为止。





3.Embedding

还有一点细节,就是如何将前一时刻输出类别 index(数值)送入下一时刻输入(向量)进行解码。假设每个标签对应的类别 index 如下:







4.Seq2Seq 训练问题


5.Attention 注意力机制


在 Seq2Seq 结构中,encoder 把所有的输入序列都编码成一个统一的语义向量 Context,然后再由 Decoder 解码。由于 context 包含原始序列中的所有信息,它的长度就成了限制模型性能的瓶颈。如机器翻译问题,当要翻译的句子较长时,一个 Context 可能存不下那么多信息,就会造成精度的下降。除此之外,如果按照上述方式实现,只用到了编码器的最后一个隐藏层状态,信息利用率低下。


所以如果要改进 Seq2Seq 结构,最好的切入角度就是:利用 Encoder 所有隐藏层状态 h(t)解决 Context 长度限制问题。



上下文 context 表示成如下的方式(h 的加权平均):



那么权重 alpha(attention weight)可表示成 Q 和 K 的乘积,小 h 即 V(下图中很清楚的看出,Q 是大 H,K 和 V 是小 h):



6.乘法 VS 加法 attention

加法注意力:


还是以传统的 RNN 的 seq2seq 问题为例子,加性注意力是最经典的注意力机制,它使用了有一个隐藏层的前馈网络(全连接)来计算注意力分配:



乘法注意力:


就是常见的用乘法来计算 attention score:



乘法注意力不用使用一个全连接层,所以空间复杂度占优;另外由于乘法可以使用优化的矩阵乘法运算,所以计算上也一般占优。论文中的乘法注意力除了一个 scale factor:



论文中指出当 dk 比较小的时候,乘法注意力和加法注意力效果差不多;但当 d_k 比较大的时候,如果不使用 scale factor,则加法注意力要好一些,因为乘法结果会比较大,容易进入 softmax 函数的“饱和区”,梯度较小。

7.Luong Attention(简单了解)




注:这里就是把 Decoder 中的每一次的输入:上一层的输出 y 换成了 Attention。

8.Self-Attention

9.《Attention is all you need》

9.1 encoder


注: 词向量加上了 positional embedding,即给位置 1,2,3,4...n 等编码(也用一个 embedding 表示)。然后在编码的时候可以使用正弦和余弦函数,使得位置编码具有周期性,并且有很好的表示相对位置的关系的特性(对于任意的偏移量 k,PE[pos+k]可以由 PE[pos]表示):



输入的序列长度是 n,embedding 维度是 d,所以输入是 n*d 的矩阵,N=6,6 个重复一样的结构,由两个子层组成:子层 1:


  • Multi-head self-attention

  • 残余连接和 LN: Output = LN (x+sublayer(x))


子层 2:


  • Position-wise fc 层(跟卷积很像):对 n*d 的矩阵的每一行进行操作(相当于把矩阵每一行铺平,接一个 FC),同一层的不同行 FC 层用一样的参数,不同层用不同的参数(对于全连接的节点数目,先从 512 变大为 2048,再缩小为 512),这里的 max 表示使用 relu 激活函数

  • 残差连接(待)


输出:


  • 整个 encoder 的输出也是 n*d 的矩阵

9.2 Decoder


输入:假设已经翻译出 k 个词,向量维度还是 d,同样使用 N=6 个重复的层,依然使用残余连接和 LN3 个子层,比 encoder 多一个 attention 层,是 Decoder 端去 attend encoder 端的信息的层(待)Sub-L1:


  • self-attention,同 encoder,但要 Mask 掉未来的信息,得到 k*d 的矩阵 (这个暂且不懂代码实现)


Sub-L2:


  • 和 encoder 做 attention 的层,输出 k*d 的矩阵,这里就不是 self-Attention 了。


Sub-L3:


  • 全连接层,输出 k*d 的矩阵,用第 k 行去预测输出 y

10.mutli-head attention



获取每个子任务的 Q、K、V:


  • 通过全连接进行线性变换映射成多个 Q、K、V,线性映射得到的结果维度可以不变、也可以减少(类似降维)

  • 或者通过 Split 对 Q、K、V 进行划分(分段)



如果采用线性映射的方式,使得维度降低;或者通过 split 的方式使得维度降低,那么多个 head 做 attention 合并起来的复杂度和原来一个 head 做 attention 的复杂度不会差多少,而且多个 head 之间做 attention 可以并行。

发布于: 刚刚阅读数: 4
用户头像

Studying_swz

关注

还未添加个人签名 2020-12-23 加入

还未添加个人简介

评论

发布
暂无评论
初步了解RNN, Seq2Seq, Attention注意力机制_6 月优质更文活动_Studying_swz_InfoQ写作社区