论文笔记 – Marrying Up Regular Expressions with Neural Networks: A Case Study for Spoken Language Understanding

Bingfeng Luo, Yansong Feng, et.al, “Marrying Up Regular Expressions with Neural Networks: A Case Study for Spoken Language Understanding”, ACL 2018

1 简介

这篇文章做的任务是 SLU(Spoken Language Understanding,下一部分介绍)。算法大致是把正则匹配到的标签,用三种方式(input level, network level, output level)加入到 Bi-LSTM 网络的不同位置,这样就用上了正则的规则信息。

为什么要加正则的信息呢?作者认为,一方面,数据少的时候(文章用的是 FSL N-way K-shot 的 setting),人工提取的正则非常有用;另一方面,正则准确率高、泛化能力弱,这正和神经网络相反,结合便能互补(我觉得这完全是作者在吹牛逼升华,毕竟只用到了正则匹配得到的标签)。

对于这个第二方面,导师曾对我指出,将正则融入模型,就是希望可以 ① 让正则在模型中发挥限制的作用(模型学到一条条正则表达式的规则)② 通过模型的学习来泛化正则(一条正则表达式里总有不太重要的,可以不完全匹配,模型学的的正则就能有一些泛化能力)。本以为这篇文章至少达到第一点,结果…… 当然,这篇文章年代比较久远,倒也情有可原。

2 问题背景

SLU 任务分成两个部分:意图检测(intent detection)和槽填充(slot filling)。前者就是一个分类任务,输入句子,求句子的 intent label;后者即序列标注,输入句子,求句子每个词的 label sequence。

在使用正则这方面,文章里说使用 REtags,就是用某个 intent label 对应的正则匹配到句子,那么这个句子意图检测的 REtags 就是这个 intent label,槽填充的 REtags 就是句子在正则表达式的槽位的 RE group label(比如这个位置上可以是伦敦纽约洛杉矶,写正则时就把这个 group 的 label 定为 fromloc.city)。

后面所有对于模型的改进,都是基于这个 REtags(i/o level 的槽填充把 fromloc.city 简化成了 city,其他的全都是直接用 REtags)。

3 算法

两个小任务的 baseline 都是 Bi-LSTM + attention + softmax。

意图检测

attention 计算句子 embedding $\textbf{s}$ 的表达式为:$$\textbf{s} = \sum_i\alpha_i\textbf{h}_i,\quad\alpha_i = \frac{\exp(\textbf{h}_i^T\textbf{Wc})}{\sum_i\exp(\textbf{h}_i^T\textbf{Wc})}$$

其中 $\alpha_i$ 是词 $i$ 的 attention值,$\textbf{c}$ 是去找匹配词的向量,baseline 里面 $\textbf{c}$ 是随机初始化的,$\textbf{W}$ 是要训练的参数。

softmax 层计算句子分类计算如下:$$p = \frac{\exp(logit)}{\sum\exp(logit)}, \quad logit = \textbf{ws} + b $$

这里称呼后面分类的式子为 logit,只因为是这一部分过 softmax 得到概率。logit 是 softmax 的反函数嘛,所以这部分也可以是概率做 logit 得到,故称之 logit。为什么要拆出来这个 logit?后文有详解。

槽填充

在 attention 部分,与上面不同,要词与词两两之间互相 attention:$$\textbf{s}_{i} = \sum_j\alpha_{ij}\textbf{h}_j,\quad\alpha_{ij} = \frac{\exp(\textbf{h}_j^T\textbf{Wh}_i)}{\sum_j\exp(\textbf{h}_j^T\textbf{Wh}_i)}$$

attention 其实在 baseline 里并没有被用到,这里写出来就是为了和后面的改动对比时比较方便。(图上明明画出来了,结果文中说“图上画的 attention aggregation 只在 3.2 network level 的改动上用到了,其它地方都没用”,只看图的话一定会被误导吧👎🏻)

所以预测 slot 时,其实直接是 Bi-LSTM 输出的向量 $\textbf{h}_i$ 过 softmax 得到。

这篇文章对 baseline 做了三种改进,如下图的 ① ② ③ 虚线所示,分别对应下面的 3.1 3.2 3.3 三个部分:

3.1 Input level

意图检测

把 REtags 的 embedding 加到 softmax 的输入上。即拼到 $\textbf{s}$ 后面。

槽填充

把 REtags 的 embedding 直接拼到 Bi-LSTM 输入的词向量上,就相当于把序列标注的标签直接拼到输入上。只不过这里的标签是正则匹配得到的,也不一定准。

作者还提到,一句话可能被好几条正则匹配到,怎么办呢?平均一下即可

3.2 Network module level

修改了网络的 attention 和 softmax layer:

意图检测

原来句子的 attention score 计算与 intent label 无关,作者把 attention score 的计算改成了跟 intent label 有关的:$$\textbf{s}_k = \sum_i\alpha_{ki}\textbf{h}_i,\quad\alpha_{ki} = \frac{\exp(\textbf{h}_i^T\textbf{W}_a\textbf{c}_k)}{\sum_i\exp(\textbf{h}_i^T\textbf{W}_a\textbf{c}_k)}$$

主要是修改了 $\textbf{c}_k$,它对应 intent label $k$,其它的都没变,最后算出来的句子 embedding $\textbf{s}_k$ 也就对应着 intent label $k$ 了。至于 $\textbf{c}_k$ 怎么算?没说【#TODO 1】

对于 softmax 层,作者改了两点:

  1. softmax 中的每个步骤也都跟着变成了“intent k 专属”:

$$p_k = \frac{\exp(logit_k)}{\sum_k\exp(logit_k)}, \quad logit_k = \textbf{w}_k\textbf{s}_k + b_k $$

  1. softmax 中的 logit 用上正负例:

$$logit_k = logit_{pk} – logit_{nk}$$

正例就是正则匹配到的 intent 的 REtags,负例就是没匹配到的。

为什么在 logit 这一步使用正负例,而非在概率上呢?作者在 output level 部分给出了废话一般的解释,稍后再对其进行批斗。

  1. 在 loss 中加入了正负例的 attention 损失项:

$$loss_{att} = \sum_{k,i}t_{ki}\log(\alpha_{ki})$$

就是句子里每个词 $i$ 对于每个 intent $k$ 的 attention 值加权求和。这里的权重 $t_{ki}$ 是对 intent 词的长度的归一化,即如果句子没匹配到 intent $k$,$t_{ki}$ 就是 0;匹配到了,就是 intent $k$ 长度的倒数。

计算正负例的 $loss_{att}$,加到原来的 loss 上,就是作者魔改的结果了。$$loss = loss_c + \beta_ploss_{att_p} + \beta_nloss_{att_n}$$

槽填充

attention 要是也都改成 intent k 专属,还得求每个词的 attention,太复杂了,算了,还是不变了:$$\textbf{s}_{pi} = \sum_j\alpha_{pij}\textbf{h}_j,\quad\alpha_{pij} = \frac{\exp(\textbf{h}_j^T\textbf{W}_{sp}\textbf{h}_i)}{\sum_j\exp(\textbf{h}_j^T\textbf{W}_{sp}\textbf{h}_i)}$$

这里的 $p$ 就是正例的 positive,对应的,也要算负例的那一套,得到 $\textbf{s}_{ni}$,那么词 $i$ 的分类概率为:$$p_i = \text{softmax}\big((\textbf{W}_p[\textbf{s}_{pi};\textbf{h}_i] + \textbf{b}_p) – (\textbf{W}_n[\textbf{s}_{ni};\textbf{h}_i] + \textbf{b}_n)\big)$$

这里就是用上了 attention 层,并把 attention 的结果拼到了 $\textbf{h}_i$ 上输入 softmax。

3.3 Output level

output level 在两个小任务上用了同样的修改方式,即修改 logit:$$logit_k = logit’_k + w_kz_k$$

这里 $logit’_k$ 是原来的 logit 🌚,$z_k$ 是一个取值为 0 或 1 的指示向量,表示这句话有没有被 intend k 正则匹配到,$w_k$ 是要训练的参数。

为什么修改 logit 不修改概率呢?作者说 “because a logit is an unconstrained real value, which matches the property of $w_kz_k$ better than probability.” 这我还是没有明白。【#TODO 2】

4 实验结果

使用 ATIS 数据集。

一个 trick:把 Miami’s 这种词分成 Miami 和 ’s,就减少了 OOV,这在 FSL 很有用。

4.1 实验一:N-way 5/10/20-shot FSL setting

意图检测:

  1. network module level 最好,因为 attention 使用 REtags,要比其他方法直接拼,利用了更多的信息
  2. 小数据情况下,只用正例要比只用负例差;但是到了 20-way,就反了过来,作者觉得是因为这时负例的数量远远多于正例了
  3. 数据多的时候(20-way),network module level 的 loss 中加入了正负例的 attention 损失项是有用的
  4. output level 好于 input level,作者认为是因为 ① 参数更少 ② 计算梯度更直接。不过由于 output 就直接改 logit,logit 的变动直接就导致结果的变动,因此 output level 对数据敏感,5-way 表现很差。

槽填充:

  1. attention loss 没用。因为结果其实更多取决于那个词本身,而非整句话里词之间的关系。而且,本身词和邻居的和关系在 Bi-LSTM 中也能学到
  2. input level 比 output level 好,因为 input level 是把 REtags 拼到每个词上

共同的特点:在 FSL setting,都比之前做 SLU 的 SOTA 强

总结:意图检测 attention loss 最有用,槽填充 input level 最好。

4.2 实验二:Partial FSL setting

这个实验室是想把自己的修改放到 FSL 的算法(memory network)上,看看有没有用。

结论:有用。还是和上面一样,意图检测 attention loss 最有用,槽填充 input level 最好。

4.3 实验三:SLU

这是在全部数据上进行实验。

结论:

  1. 意图检测: input level 和 output level 没有用了,因为 REtags 和标注本身也差不多。不过修改 attention 还是有用的。
  2. 槽填充:三种都有用

4.4 实验四:正则复杂度的影响

影响正则复杂度的因素有两方面:① RE groups 的数量 ② RE groups 的大小。① 越大,匹配越精准,但是覆盖范围小,② 正相反

结论:把正则缩减到每条最多两个 group,对于 baseline 也有很大提升,不过当然,复杂的性能更好

5 结论

收回开头的言论,这个 network module level 的改动还是挺有意思的,但是具体的训练怎么不详细说呢!

6 TODO

  1. $\textbf{c}_k$ 的计算
  2. 为什么改 logit

Leave a Comment

电子邮件地址不会被公开。