diff --git a/chapter_natural-language-processing/attention.md b/chapter_natural-language-processing/attention.md index 410b1b1971b8cd444883b0090ac42b1a2bf3f237..2ec0e43648b3f1624f3b7523ce720cbd384c733a 100644 --- a/chapter_natural-language-processing/attention.md +++ b/chapter_natural-language-processing/attention.md @@ -1,55 +1,59 @@ # 注意力机制 +在上一节里的解码器设计中,输出序列的各个时间步使用了相同的背景变量。如果解码器的不同时间步可以使用不同的背景变量呢?这样做有什么好处? -在以上的解码器设计中,各个时间步使用了相同的背景变量。如果解码器的不同时间步可以使用不同的背景变量呢? -## 设计 +## 动机 +以英语-法语翻译为例,给定一对输入序列“They”、“are”、“watching”、“.”和输出序列“Ils”、“regardent”、“.”。解码器可以在输出序列的时间步1使用更多编码了“They”、“are”信息的背景变量来生成“Ils”,在时间步2使用更多编码了“watching”信息的背景变量来生成“regardent”,在时间步3使用更多编码了“.”信息的背景变量来生成“.”。这看上去就像是在解码器的每一时间步对输入序列中不同时间步编码的信息分配不同的注意力。这也是注意力机制的由来。它最早由Bahanau等提出 [1]。 -以英语-法语翻译为例,给定一对输入序列“they are watching”和输出序列“Ils regardent”,解码器在时间步1可以使用更多编码了“they are”信息的背景变量来生成“Ils”,而在时间步2可以使用更多编码了“watching”信息的背景变量来生成“regardent”。这看上去就像是在解码器的每一时间步对输入序列中不同时间步分配不同的注意力。这也是注意力机制的由来。它最早[由Bahanau等在2015年提出](https://arxiv.org/abs/1409.0473)。 -现在,对上面的解码器稍作修改。我们假设时间步$t^\prime$的背景变量为$\boldsymbol{c}_{t^\prime}$。那么解码器在$t^\prime$时间步的隐含层变量 +## 设计 -$$\boldsymbol{s}_{t^\prime} = g(\boldsymbol{y}_{t^\prime-1}, \boldsymbol{c}_{t^\prime}, \boldsymbol{s}_{t^\prime-1})$$ +本节沿用上一节的符号。 +我们对上一节的解码器稍作修改。在时间步$t^\prime$,设解码器的背景变量为$\boldsymbol{c}_{t^\prime}$,输出$y_{t^\prime}$的特征向量为$\boldsymbol{y}_{t^\prime}$。 +和上一节输入的特征向量一样,这里每个输出的特征向量也可能是模型参数。解码器在时间步$t^\prime$的隐藏状态 -令编码器在$t$时间步的隐含变量为$\boldsymbol{h}_t$,解码器在$t^\prime$时间步的背景变量为 +$$\boldsymbol{s}_{t^\prime} = g(\boldsymbol{y}_{t^\prime-1}, \boldsymbol{c}_{t^\prime}, \boldsymbol{s}_{t^\prime-1}).$$ -$$\boldsymbol{c}_{t^\prime} = \sum_{t=1}^T \alpha_{t^\prime t} \boldsymbol{h}_t$$ +令编码器在时间步$t$的隐藏状态为$\boldsymbol{h}_t$,且时间步数为$T$。解码器在时间步$t^\prime$的背景变量为 -也就是说,给定解码器的当前时间步$t^\prime$,我们需要对编码器中不同时间步$t$的隐含层变量求加权平均。而权值也称注意力权重。它的计算公式是 +$$\boldsymbol{c}_{t^\prime} = \sum_{t=1}^T \alpha_{t^\prime t} \boldsymbol{h}_t,$$ -$$\alpha_{t^\prime t} = \frac{\exp(e_{t^\prime t})}{ \sum_{k=1}^T \exp(e_{t^\prime k}) } $$ +其中$\alpha_{t^\prime t}$是权值。也就是说,给定解码器的当前时间步$t^\prime$,我们需要对编码器中不同时间步$t$的隐藏状态求加权平均。这里的权值也称注意力权重。它的计算公式是 -而$e_{t^\prime t} \in \mathbb{R}$的计算为: +$$\alpha_{t^\prime t} = \frac{\exp(e_{t^\prime t})}{ \sum_{k=1}^T \exp(e_{t^\prime k}) },$$ -$$e_{t^\prime t} = a(\boldsymbol{s}_{t^\prime - 1}, \boldsymbol{h}_t)$$ +其中$e_{t^\prime t} \in \mathbb{R}$的计算为 -其中函数$a$有多种设计方法。在[Bahanau的论文](https://arxiv.org/abs/1409.0473)中, +$$e_{t^\prime t} = a(\boldsymbol{s}_{t^\prime - 1}, \boldsymbol{h}_t).$$ -$$e_{t^\prime t} = \boldsymbol{v}^\top \tanh(\boldsymbol{W}_s \boldsymbol{s}_{t^\prime - 1} + \boldsymbol{W}_h \boldsymbol{h}_t)$$ +上式中的函数$a$有多种设计方法。Bahanau等使用了 -其中的$\boldsymbol{v}$、$\boldsymbol{W}_s$、$\boldsymbol{W}_h$和编码器与解码器两个循环神经网络中的各个权重和偏移项以及嵌入层参数等都是需要同时学习的模型参数。在[Bahanau的论文](https://arxiv.org/abs/1409.0473)中,编码器和解码器分别使用了[门控循环单元(GRU)](../chapter_recurrent-neural-networks/gru-scratch.md)。 +$$e_{t^\prime t} = \boldsymbol{v}^\top \tanh(\boldsymbol{W}_s \boldsymbol{s}_{t^\prime - 1} + \boldsymbol{W}_h \boldsymbol{h}_t),$$ +其中$\boldsymbol{v}$、$\boldsymbol{W}_s$、$\boldsymbol{W}_h$以及编码器与解码器中的各个权重和偏差都是模型参数 [1]。 -在解码器中,我们需要对GRU的设计稍作修改。 -假设$\boldsymbol{y}_t$是单个输出$y_t$在嵌入层的结果,例如$y_t$对应的one-hot向量$\boldsymbol{o} \in \mathbb{R}^y$与嵌入层参数矩阵$\boldsymbol{B} \in \mathbb{R}^{y \times s}$的乘积$\boldsymbol{o}^\top \boldsymbol{B}$。 -假设时间步$t^\prime$的背景变量为$\boldsymbol{c}_{t^\prime}$。那么解码器在$t^\prime$时间步的单个隐含层变量 +Bahanau等在编码器和解码器中分别使用了门控循环单元 [1]。在解码器中,我们需要对门控循环单元的设计稍作修改。解码器在$t^\prime$时间步的隐藏状态为 -$$\boldsymbol{s}_{t^\prime} = \boldsymbol{z}_{t^\prime} \odot \boldsymbol{s}_{t^\prime-1} + (1 - \boldsymbol{z}_{t^\prime}) \odot \tilde{\boldsymbol{s}}_{t^\prime}$$ +$$\boldsymbol{s}_{t^\prime} = \boldsymbol{z}_{t^\prime} \odot \boldsymbol{s}_{t^\prime-1} + (1 - \boldsymbol{z}_{t^\prime}) \odot \tilde{\boldsymbol{s}}_{t^\prime},$$ 其中的重置门、更新门和候选隐含状态分别为 -$$\boldsymbol{r}_{t^\prime} = \sigma(\boldsymbol{W}_{yr} \boldsymbol{y}_{t^\prime-1} + \boldsymbol{W}_{sr} \boldsymbol{s}_{t^\prime - 1} + \boldsymbol{W}_{cr} \boldsymbol{c}_{t^\prime} + \boldsymbol{b}_r)$$ - -$$\boldsymbol{z}_{t^\prime} = \sigma(\boldsymbol{W}_{yz} \boldsymbol{y}_{t^\prime-1} + \boldsymbol{W}_{sz} \boldsymbol{s}_{t^\prime - 1} + \boldsymbol{W}_{cz} \boldsymbol{c}_{t^\prime} + \boldsymbol{b}_z)$$ +$$ +\begin{aligned} +\boldsymbol{r}_{t^\prime} &= \sigma(\boldsymbol{W}_{yr} \boldsymbol{y}_{t^\prime-1} + \boldsymbol{W}_{sr} \boldsymbol{s}_{t^\prime - 1} + \boldsymbol{W}_{cr} \boldsymbol{c}_{t^\prime} + \boldsymbol{b}_r),\\ +\boldsymbol{z}_{t^\prime} &= \sigma(\boldsymbol{W}_{yz} \boldsymbol{y}_{t^\prime-1} + \boldsymbol{W}_{sz} \boldsymbol{s}_{t^\prime - 1} + \boldsymbol{W}_{cz} \boldsymbol{c}_{t^\prime} + \boldsymbol{b}_z),\\ +\tilde{\boldsymbol{s}}_{t^\prime} &= \text{tanh}(\boldsymbol{W}_{ys} \boldsymbol{y}_{t^\prime-1} + \boldsymbol{W}_{ss} (\boldsymbol{s}_{t^\prime - 1} \odot \boldsymbol{r}_{t^\prime}) + \boldsymbol{W}_{cs} \boldsymbol{c}_{t^\prime} + \boldsymbol{b}_s). +\end{aligned} +$$ -$$\tilde{\boldsymbol{s}}_{t^\prime} = \text{tanh}(\boldsymbol{W}_{ys} \boldsymbol{y}_{t^\prime-1} + \boldsymbol{W}_{ss} (\boldsymbol{s}_{t^\prime - 1} \odot \boldsymbol{r}_{t^\prime}) + \boldsymbol{W}_{cs} \boldsymbol{c}_{t^\prime} + \boldsymbol{b}_s)$$ +我们将在下一节中实现含注意力机制的编码器和解码器。 -我们将在本章稍后的[“机器翻译”](nmt.md)一节中实现含深度循环神经网络的编码器和解码器。 ## 小结 @@ -58,21 +62,15 @@ $$\tilde{\boldsymbol{s}}_{t^\prime} = \text{tanh}(\boldsymbol{W}_{ys} \boldsymbo ## 练习 -* 了解其他的注意力机制设计。例如论文[Effective Approaches to Attention-based Neural Machine Translation](https://nlp.stanford.edu/pubs/emnlp15_attn.pdf)。 - -* 在[Bahanau的论文](https://arxiv.org/abs/1409.0473)中,我们是否需要重新实现解码器上的GRU? - -* 除了机器翻译,你还能想到seq2seq的哪些应用? +* 不修改[“门控循环单元(GRU)——从零开始”](../chapter_recurrent-neural-networks/gru-scratch.md)一节中的`gru_rnn`函数,应如何用它实现本节介绍的解码器? * 除了自然语言处理,注意力机制还可以应用在哪些地方? ## 扫码直达[讨论区](https://discuss.gluon.ai/t/topic/6759) -![](../img/qr_seq2seq-attention.svg) +![](../img/qr_attention.svg) ## 参考文献 [1] Bahdanau, Dzmitry, Kyunghyun Cho, and Yoshua Bengio. “Neural machine translation by jointly learning to align and translate.” arXiv:1409.0473 (2014). - -[2] Luong, Minh-Thang, Hieu Pham, and Christopher D. Manning. “Effective approaches to attention-based neural machine translation.” arXiv:1508.04025 (2015). diff --git a/chapter_natural-language-processing/seq2seq.md b/chapter_natural-language-processing/seq2seq.md index 18e616aa6098ea2717424eaecc1b3d167bfbec9a..402c375a07a976f4867c9b25d53d4c464abb979c 100644 --- a/chapter_natural-language-processing/seq2seq.md +++ b/chapter_natural-language-processing/seq2seq.md @@ -14,7 +14,8 @@ 编码器的把一个不定长的输入序列变换成一个定长的背景变量$\boldsymbol{c}$,并在该背景变量中编码输入序列信息。常用的编码器是循环神经网络。 让我们考虑批量大小为1的时序数据样本。 -在时间步$t$,循环神经网络将输入$x_t$的特征向量$\boldsymbol{x}_t$和上个时间步的隐藏状态$\boldsymbol{h}_{t-1}$变换为当前时间步的隐藏状态$\boldsymbol{h}_t$。因此,我们可以用函数$f$表达循环神经网络隐藏层的变换: +在时间步$t$,循环神经网络将输入$x_t$的特征向量$\boldsymbol{x}_t$和上个时间步的隐藏状态$\boldsymbol{h}_{t-1}$变换为当前时间步的隐藏状态$\boldsymbol{h}_t$。 +其中,每个输入的特征向量可能是模型参数,例如[“循环神经网络——使用Gluon”](../chapter_recurrent-neural-networks/rnn-gluon.md)一节中需要学习的每个词向量。我们可以用函数$f$表达循环神经网络隐藏层的变换: $$\boldsymbol{h}_t = f(\boldsymbol{x}_t, \boldsymbol{h}_{t-1}). $$ @@ -64,13 +65,10 @@ $$\boldsymbol{s}_{t^\prime} = g(y_{t^\prime-1}, \boldsymbol{c}, \boldsymbol{s}_{ ## 练习 -* 了解其他的注意力机制设计。例如论文[Effective Approaches to Attention-based Neural Machine Translation](https://nlp.stanford.edu/pubs/emnlp15_attn.pdf)。 - -* 在[Bahanau的论文](https://arxiv.org/abs/1409.0473)中,我们是否需要重新实现解码器上的GRU? - * 除了机器翻译,你还能想到seq2seq的哪些应用? -* 除了自然语言处理,注意力机制还可以应用在哪些地方? +* 有哪些方法可以设计解码器的输出层? + ## 扫码直达[讨论区](https://discuss.gluon.ai/t/topic/4523) diff --git a/img/qr_attention.svg b/img/qr_attention.svg new file mode 100644 index 0000000000000000000000000000000000000000..236fe2fe391a0a915a8d3682139fa7a3273702bd --- /dev/null +++ b/img/qr_attention.svg @@ -0,0 +1,444 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file