Abstract
许多NLP任务,包括机器阅读理解、答案选择和文本涵义都需要进行序列之间的比较,寻找序列间的重要元素是解决这些问题的关键。在本文中,提出来一种较为通用的compare-aggregate框架,该框架先进行词级别的匹配,然后使用CNN进行聚合。主要用两种不同的比较函数去匹配两个向量。使用四种不同的数据集进行评价模型的性能。发现一些基于元素运算的简单比较函数(simple comparison functions)比一些标准的网络或者神经张量网络能更好的工作。
1. Introduction
许多NLP任务都是通过匹配两个或多个序列来进行解决的。例如:
- textual entailment(文本蕴含): 推断前提和假说之间的关系。最典型的任务SNLI
- machine comprehension(机器理解):给定一段话和一个问题,通过匹配找到正确的答案
这些任务虽然预测目标不一样,但是最本质的都是衡量句子之间的关系。
随着NLP领域中神经网络模型的提出,目前对于句子的处理有一个较为标准的模型:首先对句子进行embedding,得到embedding vector,然后通过RNN或者CNN将其encoder。
然后,为了匹配两个序列,最直接的方法就是将每个句子的encoder看作向量来比较。
但是研究发现,用单一的vector去encode整个句子并不十分有效,因此又出现了attention机制、记忆网络等
还有一种“compare-aggregate”框架。最早由Google在《A Decomposable Attention Model for Natural Language Inference》论文中提出来。
这类方法主要是先对小单元的vector进行比较,然后再将比较的结果进行聚合,做最后的判断。
比如:match-LSTM,在进行文本蕴含的时候,首先将假设中的每个单词与前提的注意加权进行比较,然后将比较的结果通过LSTM进行聚合;
交互模型,从两个句子里找出一对单词,然后进行单元比较。最后使用相似层和多层CNN将这些单词交互的结果组合在一起;
可分解attention模型,每个句子中的单词都和其他句子进行attention加权计算,产生一系列的比较向量,然后进行聚合加MLP进行最后的分类;
以上的研究都展示了“compare-aggregate”框架的有效性,但是存在两点限制:提出来的每个模型都只会用于一种或两种任务; 这些研究并没有重视比较两个小文本单元的比较功能。即本质上是要去关注两个序列在语义上的相似度,进行序列的小元素的比较只为了选择出更加合适的比较函数。
本文的贡献:
- 提出了统一的“compare-aggregate”框架,能有效应用于句子匹配任务上
- 用四种不同的数据集,分别是代表不同的任务,在其上进行了六种不同的比较函数的测试,最终发现基于元素的减法和乘法,结果最好
2. Method
Q
Q
Q和
A
A
A分别代表两个句子的word embedding,
y
y
y表示label, 所有的任务都是有监督的学习。下面先看下整个模型:
主要分为四层:
**Preprocessing:**首先对
Q
Q
Q和
A
A
A进行预处理,获得两个新的矩阵
Q
ˉ
\bar{Q}
Qˉ和
A
ˉ
\bar{A}
Aˉ,其目的是为每个序列中的每个单词获得一个新的embedding vector,使每个词都能获得句子的上下文信息。
比如
Q
ˉ
\bar{Q}
Qˉ里面的
q
i
ˉ
\bar{q_i}
qiˉ是
Q
ˉ
\bar{Q}
Qˉ的第
i
t
h
i^{th}
ith列向量,是通过对
Q
ˉ
\bar{Q}
Qˉ中的第
i
t
h
i^{th}
ith个字及其在
Q
Q
Q中的上下文进行编码。具体公式如下:
具体的代码如下:
function compAggWikiqa:new_proj_module()
local input = nn.Identity()()
local i = nn.Sigmoid()(nn.Linear(self.emb_dim, self.mem_dim)(input))
local u = nn.Tanh()(nn.Linear(self.emb_dim, self.mem_dim)(input))
local output = nn.CMulTable(){i, u}
local module = nn.gModule({input}, {output})
if self.proj_module_master then
share_params(module, self.proj_module_master)
end
return module
end
Attention: 就是传统的attention机制
用问题对答案加attention,可以得到attention的系数
G
G
G。即得到的就是
A
ˉ
\bar{A}
Aˉ里面和
Q
ˉ
\bar{Q}
Qˉ相关的权重系数;
然后将
Q
ˉ
\bar{Q}
Qˉ中的每个列向量
q
ˉ
j
\bar{q}_j
qˉj和
G
G
G的列向量相乘,得到了对应的向量
h
j
h_j
hj,代表
Q
Q
Q中最能匹配
A
A
A的第
j
j
j个单词。
具体代码如下:
function compAggWikiqa:new_att_module()
local linput, rinput = nn.Identity()(), nn.Identity()()
--padding
local lPad = nn.Padding(1,1)(linput)
--local M_l = nn.Linear(self.mem_dim, self.mem_dim)(lPad)
local M_r = nn.MM(false, true){lPad, rinput}
local alpha = nn.SoftMax()( nn.Transpose({1,2})(M_r) )
local Yl = nn.MM(){alpha, lPad}
local att_module = nn.gModule({linput, rinput}, {Yl})
if self.att_module_master then
share_params(att_module, self.att_module_master)
end
return att_module
end
**Comparison:**为了将
a
ˉ
j
\bar{a}_j
aˉj和
h
j
h_j
hj进行结合,以获得新的vector
t
j
t_j
tj。作者比较了多种comparison方式。其实就是找出来一个最好的函数,即论文里所谓的comparison layer,去匹配每个
a
ˉ
j
\bar{a}_j
aˉj和
h
j
h_j
hj(前者表示
A
A
A中的第
j
t
h
j^{th}
jth个单词,后者表示最匹配
a
ˉ
j
\bar{a}_j
aˉj的加权过的
Q
Q
Q
有很多方法:
Neuralnet:将两个向量进行拼接,过层神经网络。
Neuraltensornet: 用张量网络连接两个向量,过relu.
然后前面这两种是比较老的了,作者发现在很多论文里,使用的最好的就是欧氏距离和cosine相似度,因此又将两者的结果拼接起来:
但是作者觉得,这样结合还是会导致这两个原始的vector里面会丢失很多有用的信息,因此考虑到了利用这两个vector里面的元素直接进行计算,于是就提出了下面的两个比较函数:
然后作者还发现sub的计算方法和欧氏距离很相近,mul又比较接近于cosine.因此,又对这两个比较方式的结果进行拼接,过一层神经网络:
**Aggregation:**最后得到了一系列的
t
j
t_j
tj,用CNN聚合
最后利用向量
r
r
r,根据不同的任务对模型进行训练和预测。文本蕴含做三分类,答案选择任务,则是从多个候选答案中选择正确答案。
3. Experiments
word embedding: GloVe 在GloVe里面没有的直接初始化为0
hidden layer = 150
optimize: adamax
β
1
\beta _1
β1 = 0.9
β
2
\beta _2
β2 = 0.999
batch_size: 30
lr = 0.002
下面就在这四种数据集上进行了相关实验:
实验结果:
可以看出,这篇论文提出的模型在三个数据集上都取得了SOTA的效果。