基于注意力机制的循环神经网络(Attention-Based RNN)

算法原理

Attention-Based RNN 是一种基于注意力机制的 RNN 变体模型,它通过引入注意力机制来对序列中的不同部分进行加权,从而能够更好地捕捉序列数据中的重要信息。Attention-Based RNN 的主要思想是在每个时间步对序列中的不同部分赋予不同的权重,从而能够更好地捕捉序列中的重要信息。这个思想是符合直觉的,我们很容易理解:一个句子中每个单词的重要程度应该是不同的,所以希望模型能捕捉这个特点,即通过设置额外的注意力参数来显式的建模这个特性。从公式角度定义Attention-Based RNN:

假设输入序列为 \(\boldsymbol{x}_{1: T}\), 第 \(t\) 个元素的向量表示为 \(\boldsymbol{h}_t\), 输出序列为 \(\boldsymbol{y}_{1: T} \circ\) 在 Attention-Based RNN 中, 每个时间步的输出可以通过下面的公式计算:
$$
\begin{gathered}
\boldsymbol{s}_t=\tanh \left(\boldsymbol{W}_h \boldsymbol{h}_t+b_h\right) \\
\boldsymbol{\alpha}_t=\frac{\exp \left(\boldsymbol{s}_t^{\top} \boldsymbol{e}\right)}{\sum_{i=1}^T \exp \left(\boldsymbol{s}_i^{\top} \boldsymbol{e}\right)} \\
\boldsymbol{y}_t=\sum_{i=1}^T \boldsymbol{\alpha}_{t, i} \boldsymbol{h}_i
\end{gathered}
$$

其中, \(\boldsymbol{W}_h\) 和 \(b_h\) 是映射向量的权重和偏置, \(\boldsymbol{e}\) 是用来计算注意力权重的权重向量, \(\boldsymbol{\alpha}_t\) 是第 \(t\) 个时间步计算得到的注意力权重, 它是由所有元素的权重经过 softmax 处理得到的, \(\boldsymbol{y}_t\) 是第 \(t\) 个时间步的输出, 它是所有元素的加权平均, 这个加权求和的过程实际上就是实现句子中每个单词重要程度重分配的过程。

具体来说, 第一步将序列中的每个元素通过前馈神经网络映射为一个向量 \(s_t\), 这个 \(s_t\) 实际上就是当前时刻 RNN 输出的隐藏状态。然后, 计算每个元素的注意力权重 \(\boldsymbol{\alpha}_{t, i}\), 通过将 \(\boldsymbol{s}_t\)与一个固定的权重向量 \(\boldsymbol{e}\) 进行点积, 然后经过 softmax 处理得到。最后, 将所有元素的加权平均作为输出 \(\boldsymbol{y}_t\) 。值得注意的是, 选择合适的注意力权重的权重向量 \(\boldsymbol{e}\) 是 Attention-Based RNN 中的关键, 它对模型的性能影响很大。一般来说, \(\boldsymbol{e}\) 可以由以下几种方式来得到:

1. 解码器的隐藏状态:

在一些序列到序列的模型(如机器翻译)中,\(\boldsymbol{e}\) 可以是解码器在前一个时间步的隐藏状态。这种情况下,\(\boldsymbol{e}\) 代表了到目前为止已经生成的输出序列的累积信息。通过将这个查询向量与输入序列的每个时间步的隐藏状态 ℎ​ 进行对比,模型可以决定接下来最需要关注输入序列的哪个部分。

2. 可学习的参数:

在某些模型中,\(\boldsymbol{e}\) 可能是一个独立的、可以通过训练学习的参数。在这种情况下,\(\boldsymbol{e}\) 不是由模型的其他部分直接生成的,而是通过模型训练的过程逐渐调整,以便更好地协助模型确定注意力的焦点。

3. 固定或预设的向量:

在某些特定应用或简化的模型中,\(\boldsymbol{e}\) 可能是一个预先定义的固定向量,可能与特定任务或数据集的某些特性相关。这种情况比较少见,通常出现在特定的研究或实验场景中。

不管 \(\boldsymbol{e}\) 的具体形式是什么,它的主要作用都是作为一种参考,帮助模型判断在处理序列数据时应该把注意力集中在哪里。通过与输入序列的每个时间步的隐藏状态的交互,\(\boldsymbol{e}\) 影响着最终的注意力权重 α,从而影响模型的输出。这种机制使得模型能够动态地调整对输入数据的关注点,这在处理长序列或需要理解复杂关系的任务中尤为重要。

最后,关于注意力权重\(a_t\)的计算其实有很多种方式,常见的计算注意力权重的方式有以下几种。

点积注意力

点积注意力(Dot Product Attention)是一种简单的计算注意力权重的方法,它通过计算输入序列中每个词向量与当前时刻的隐状态之间的点积来得到注意力权重。具体来说,假设输入序列中的词向量为 \(\boldsymbol{e}_1, \boldsymbol{e}_2, \cdots, \boldsymbol{e}_T\), 当前时刻的隐状态为 \(\boldsymbol{s}_t\), 则点积注意力权重 \(\boldsymbol{\alpha}_t\) 可以表示为:
$$
\boldsymbol{\alpha}_t=\frac{\exp \left(\boldsymbol{s}_t^{\top} \boldsymbol{e}_i\right)}{\sum_{j=1}^T \exp \left(\boldsymbol{s}_t^{\top} \boldsymbol{e}_j\right)}
$$

其中, \(\boldsymbol{s}_t^{\top} \boldsymbol{e}_i\) 表示当前时刻的隐状态 \(\boldsymbol{s}_t\) 与第 \(i\) 个词向量 \(\boldsymbol{e}_i\) 之间的点积, 当前时刻的隐状态 \(\boldsymbol{s}_t\)和输入序列中每个单词的向量 \(\boldsymbol{e}_i\) 都是用来表示语义信息的向量。在 Attention-Based RNN 中,通过将当前时刻的隐状态 \(s_t\) 与输入序列中每个单词的向量进 \(\boldsymbol{e}_i\) 行点积, 可以得到一个标量值,用于表示当前时刻 \(t\) 下, 每个单词对输出结果的贡献大小。

根据线性代数的知识, 当 \(s_t\) 与 \(e_i\) 两个向量之间的相似度越高时, 点积的结果越大, 意味着当前时刻的隐状态 \(\boldsymbol{s}_t\) 和输入序列中的该单词 \(\boldsymbol{e}_i\) 具有更相似的语义信息,也就是说,在当前时刻 \(t\) 下, 该单词对输出结果的贡献更大。因此, 该单词在当前时刻的重要性就越高。

例如, 在机器翻译任务中, 当 \(s_t\) 表示待翻译的目标句子中已经翻译出的部分的隐状态时,
\(\boldsymbol{e}_i\) 表示原句子中的每个单词向量。如果当前时刻的隐状态 \(\boldsymbol{s}_t\) 与原句子中的某个单词向量 \(\boldsymbol{e}_i\) 之间的相似度越高, 那么该单词在当前时刻的重要性就越大, 模型就需要更多地关注它,从而提高模型的翻译准确性。

因此, 当前时刻的隐状态 \(\boldsymbol{s}_t\) 与该单词的向量 \(\boldsymbol{e}_i\) 之间的相似度越高, 该单词在当前时刻的重要性就越大, 这是因为相似度的提高反映了两者之间的语义相关性增强, 从而该单词对输出结果的贡献也相应增大。所以, \(\exp \left(\boldsymbol{s}_t^{\top} \boldsymbol{e}_i\right)\) 表示这个点积的重要程度, \(\sum_{j=1}^T \exp \left(\boldsymbol{s}_t^{\top} \boldsymbol{e}_j\right)\) 表示所有点积的加权和, 通过这个加权和可以将所有点积的重要程度归一化到 0 到 1 的范围内,从而得到注意力权重 \(\boldsymbol{\alpha}_t\) 。

实际上, 上述对于注意力权重 \(\boldsymbol{\alpha}\) 为什么表征注意力的解释, 只是科学家赋予点积操作这个算法的一种类比而已。从另一个角度说, 注意力权重 \(\boldsymbol{\alpha}_t\) 是通过训练得到的参数, 到底是什么, 究竟是不是真的表示注意力只有模型自己才知道, 或许仅仅是增加了模型的可学习参数, 让模型的潜力有机会学到更好的表征也未可知, 这就是深度学习模型的黑盒性质。

缩放点积注意力

为了避免在点积注意力中点积结果过大或过小的问题,可以采用缩放点积注意力(Scaled Dot Product Attention)的方法。具体来说, 缩放点积注意力将点积结果除以 \(\sqrt{d}\),其中 \(d\) 表示向量 \(\boldsymbol{e}_i\) 的维度, 从而缩放点积结果的大小, 缩放点积注意力的公式如下:
$$
\boldsymbol{\alpha}_t=\frac{\exp \left(\boldsymbol{s}_t^{\top} \boldsymbol{e}_i / \sqrt{d}\right)}{\sum_{j=1}^T \exp \left(\boldsymbol{s}_t^{\top} \boldsymbol{e}_j / \sqrt{d}\right)}
$$

加性注意力

加性注意力(Additive Attention)是一种将当前时刻的隐状态和输入序列中每个词向量连接起来后通过一个全连接层计算注意力权重的方法。具体来说,假设当前时刻的隐状态为\(\boldsymbol{s}_t\), 输入序列中的词向量为 \(\boldsymbol{e}_1, \boldsymbol{e}_2, \cdots, \boldsymbol{e}_T\), 全连接层的权重矩阵为 \(\boldsymbol{W}\), 则加性注意力权重 \(\boldsymbol{\alpha}_t\)可以表示为:
$$
\boldsymbol{\alpha}_t=\frac{\exp \left(\boldsymbol{v}^{\top} \tanh \left(\boldsymbol{W} \boldsymbol{s}_t+\boldsymbol{U} \boldsymbol{e}_i\right)\right)}{\sum_{j=1}^T \exp \left(\boldsymbol{v}^{\top} \tanh \left(\boldsymbol{W} \boldsymbol{s}_t+\boldsymbol{U} \boldsymbol{e}_j\right)\right)}
$$

其中, \(\boldsymbol{W}\) 和 \(\boldsymbol{U}\) 是全连接层的权重矩阵, \(\boldsymbol{v}\) 是一个用来计算注意力权重的随机初始化向量。全连接层可以学习输入序列中每个词向量与当前时刻的隐状态之间的关系, 从而计算每个单词在当前时刻的注意力得分。然而, 全连接层中的参数数量较大, 可能会导致过拟合, 因此引入一个额外的注意力向量 \(\boldsymbol{v}\) 可以用较少的参数量来计算注意力得分, 提高模型的泛化能力。具体来说, 注意力向量 \(\boldsymbol{v}\) 可以将全连接层的计算结果从向量映射为一个标量, 用于计算该单词在当前时刻的注意力得分。这样可以有效地减少模型参数, 降低模型的过拟合风险。实际上, 这个加性注意力分数完全可以使用一个简单的 MLP 实现, 如下图所示。

图片[1]-基于注意力机制的循环神经网络(Attention-Based RNN)-点头深度学习网站
用MLP实现加性注意力分数

用 MLP 实现加性注意力分数时, 输入就是向量 \(s_t\) 和 \(\boldsymbol{e}_j\) 的拼接, 第一个隐藏层中要学习的参数就是 \(\boldsymbol{W}\) 和 \(\boldsymbol{U}\), 第二个隐藏层中要学习的参数就是 \(\boldsymbol{v}\), 最后输出一个标量。我们希望这个MLP最后输出的标量可以通过训练,学习成为注意力分数。

此外,经典的注意力计算方法还有自注意力机制,在预测下一个单词的任务中,Attention-Based RNN 通常使用的是源-目标注意力(source-target attention),即将当前时刻的隐状态\(s_t\)与输入序列中每个单词的向量\(e_i\)进行加性或乘性注意力计算,得到每个单词在当前时刻的注意力得分,用于加权求和,生成下一个单词的输出。在这种情况下,没有自注意力机制(self-attention)的应用。

自注意力机制是指模型对于输入序列中每个位置的向量,不仅可以通过与其它位置的向量计算注意力权重来表达其对输出的贡献,同时还可以通过与自身进行注意力计算,表示该位置向量内部的不同部分之间的关系。自注意力机制被广泛应用于自然语言处理任务中,如文本分类、机器翻译、文本摘要等。但在预测下一个单词的任务中,通常没有自注意力机制的应用,因为模型主要关注当前时刻的隐状态与输入序列中的每个单词的关系,而不是在单词内部建立注意力关系。

然而,在某些特定的情况下,也可以将自注意力机制应用于预测下一个单词的任务中。例如,在文本生成任务中,模型需要根据之前生成的单词预测下一个单词,此时可以使用自注意力机制帮助模型关注之前已经生成的单词,并从中学习到相应的语义信息。此外,在一些序列到序列的任务中,如文本摘要和机器翻译,还可以将自注意力机制应用于解码器端,以帮助解码器生成更加准确的输出序列。我们将在Transformer算法讲解的章节中,进行自注意力机制的详细讲解。

© 版权声明
THE END
喜欢就支持一下吧
点赞14 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容