原创:张春阳
数据集
- SQuAD
- QA
原始论文
- 论文中只介绍了原理和方法,并没有给出代码
- 找到的代码为第三方复现
- 需要注意,本篇中的 passage 就是之前我们说过的 context
任务样本
从原文中找到一个连续的 sub-span
Passage: Tesla later approached Morgan to ask for more funds to build a more powerful transmitter. When asked where all the money had gone, Tesla responded by saying that he was affected by the Panic of 1901, which he (Morgan) had caused. Morgan was shocked by the reminder of his part in the stock market crash and by Tesla’s breach of contract by asking for more funds. Tesla wrote another plea to Morgan, but it was also fruitless. Morgan still owed Tesla money on the original agreement, and Tesla had been facing foreclosure even before construction of the tower began.
Question: On what did Tesla blame for the loss of the initial money?
Answer: Panic of 1901
模型概览
- 对 question 和 passage 进行编码
- 获取与 question 相关的 passage 表达
- 在 passage 上应用 self-matching attention 去获得最终的表达
- 从 passage 中预测出 question 的 answer
- 这里使用了很多 RNN 的结构,训练采用 E2E 的方式
步骤1: Question and Passage Encoder
注意该步骤包含两个部分
- embedding
- text encoding
Embedding
每一个 word 被表示为两个向量的 concat,
- 一个向量是 GloVe 向量, (Question) 和 (Passage),当某些 word 在 GloVe 中是缺失的状态时(OOV),我们会把它的向量都设置成 0。
- 另一个是一个 character level 的向量, (Questi)和 (Passage)。
为了获取这个 character level 的向量,我们可以在 Embedding 后增加一个 bi-GRU 层。然后每一个 character 都被 embed 成一个 dimensional 的向量。
- 为 Passage 的长度
- 为 Question 的长度
- 为 25,表示26 个英文字母的编码长度
- 等于 75,代表 embedding 的维度
How does mask_zero in Keras Embedding layer work?
Encoding
下面的符号是在原始论文中的一些符号表达
- 表示 question 的向量
- 表示 passage 的向量
神经网络会继续使用 和 向量,把他们传递给 masking 并且再接 3 层的 bi-GRU。
Keras 中的遮盖和填充 | TensorFlow Core
在这一系列操作执行完后,我们得到 Passage 和 Question 的表示向量 和 。接下来让我们用这两个向量,来获取与 question 相关的 passage 表达。
步骤2: Question-Passage Matching
这个模块主要是计算把 Question 计算在内的 Passage 表达。我们使用下面的方法:
- 我们把想要得到的带有 Question 信息的 Passage 表达,使用 来表达;
- 表示 Question 的矩阵
- 表示 Passage 中第 t 个 word 的向量。
在 QuestionAttnGRU 中,我们首先要结合三个信息:
- 上一个状态的表达
- 用来表示 Question 的矩阵
- 用来表示 Passage 中的第 t 个单词
我们使用 dot product 处理 input 和相关的权重,然后使用 broadcast 到相同的 shape,再把它们进行相加。这里面 和 都是向量, 是一个矩阵,我们把前两个向量重复几次叠起来,使它们和矩阵的 shape 相同,最后计算这三个矩阵的和。 在这个和上,我们使用 激活函数。这个输出我们再用一个权重向量 进行 dot product,再使用 计算注意力的权重分布。 然后,我们在使用这个注意力的权重分布 dot product ,我们就得到了一个融合了 Question 信息的表示 Passage 的向量,表示为 。
因为只有 的信息并不足够,缺少了原始的从 中获取的原始信息。所以,作者把 和 进行了一个拼接,并把它传递给 GRU 结构。(Match-LSTM)
在论文中,作者为了决定到底使用哪里的信息更多一些,使用了一个 的参数和 进行相乘,并且应用一个 函数,用这个结构来充当 gate 的作用。然后再和 进行 element-wise 的乘法。这个值会作为 GRU 的输入。
步骤3: Passage Self-Matching
上一步的输出 (Question-Passage Matching) 的结果,我们表示为 。作者在原文中认为,对于 Passage 所表达的信息是非常的有限的,我们还需要从 Passage 的其他的部分,获取更多的信息给 。
接下来,我们要给 Passage 增加一个 self-attention 机制。
- Self-matching 的 GRU 结构的输出表示为 。
这个实现和之前的模块非常的相似。我们首先计算 和当前 word 的向量 ,还有 和矩阵 。然后,我们对它们进行加和操作,并且使用一个 函数作为激活函数。接下来,使用一个权重向量 并且运用一个 函数,这样就会生成一个 attention 的向量。
之后的操作流程,就和之前的一样。
步骤4: Answer Prediction
最后,我们要预测 Passage 中一段作为问题的答案。为了做到这些,我们使用 QuestionPooling Layer 和 PointerGRU。
QuestionPooling 是对 Question Vector 做的一个 attention pooling。这个操作的目的主要是为了创建输入给 PointerGRU 的第一个 hidden state。它和其他的 attention 机制非常的类似。 是前一个模块的对于 Passage 的表示,我们使用它来对最后的结果进行预测。
Pointer Network
Loss Function
复现笔记
Challenges of reproducing R-NET neural network using Keras