介绍
一般来说,自然语言是由词汇和句法组成的,但是标准的语言模型一般都只用RNN对词汇进行建模,句法信息都是隐式的学习到的,没有办法显式地拿出来使用。所以本文提出的语言模型的变体可以结合结构上的attention,在中间过程中学习到结构信息,然后这层结构信息可以拿来生成句法树,用来做无监督的句法分析。
那么为什么要做无监督的句法分析呢?主要原因还是一些小语种标注语料太少了甚至没有,不能用监督句法分析来做。而且无监督句法分析学到的信息还可以用来增强语言模型或者更为下游的任务的性能,使它们能更好的融合句法结构信息。
本文提出的模型(PRPN)主要有如下三个组成部分:
- 可微分的Parsing Network 主要用来学习句子的句法距离(syntactic distance),这个在之前的博客中有讲到,是同一个组做的工作,链接:Straight to the Tree:Constituency Parsing with Neural Syntactic Distance 然后产生出门函数(gate function),也就是句子中每个词的权重,这样跑RNN的时候就没有必要考虑之前的所有信息了,只需要考虑句法距离最近的,也就是同一个短语中的信息。这里可微分后面会详细讲到,也就是不能直接预测离散的序列,不然梯度没办法反向传播,所以预测的是一个分布。
- Reading Network。这个部分就和普通的RNN差不多,区别就是利用了上面的attention,然后每个时刻的输入不仅仅是上一个时刻的隐含层状态,还包括了历史所有相关的隐含层状态。
- Predict Network。最后预测下一个词也不是直接采用当前时刻的隐含层输出,而是采用所有attention后的历史隐含层信息。
最后模型训练好之后,用Parsing Network学习到的句法距离就可以产生出无监督的句法树,当然这里只能产生unlabeled的句法树,也就是说,无监督的成分句法分析都是只评测unlabeled F1值,因为nonterminal信息实在是无法无监督的预测出来,除非结合外部标注器或者人工制定规则?
由于我觉得这篇论文写作有点粗糙,很多地方写的很乱,甚至还有公式变量和图片不对应,所以下面的公式我有些自行修改过了,如果觉得有疑问的,可以参考原文,并且告诉我。
动机
下图是一个输入句子及其对应的句法树示例:
其中实线表示成分句法树的结构,而虚线表示同一棵子树的若干个子结点之间的联系。我们用 表示输入句子,用 表示句法树中的某一个结点,用 r 表示根结点。定义 所表示的短语范围是 ,例如在上图中 表示的范围是 ,所以有 。
下图是模型的Reading Network和Predict Network大致框架:
其中实线表示Reading Network中RNN每个时刻的输入依赖于之前的哪些时刻,虚线表示Predict Network中预测下一个词时需要考虑哪些时刻的隐含层输出(这里有个小错误,图中最上面一行函数参数从开始,但实际上虚线表明应该从开始)。
首先是Parsing Network。这种和之前状态的连接在这里被叫做“跨越连接”(skip connection),而具体和哪些状态连接,就要用到门 ,表示当前处在 t 时刻,和之前的第 i 时刻有没有关联,有就是1,没有就是0。在这里先定义变量 为 和之前最远到哪个位置的单词有关联,分成两种情况:如果 不是某个子树最左边的叶子结点,那么 就定义为它的父结点的最左边那个叶子结点,也就是 最左边那个兄弟结点。比如上图中的 ,因为它在子树中位于中间,所以 ,也就是说它最远和 有一定关联,而再往前的单词由于不在同一个短语里,关联就不大了。如果 是某一个子树 最左边的子结点,那么 就定义为 最左边那个兄弟结点的最左边的叶子结点。比如上图中 ,因为 的最左边的子结点,而 最左边的兄弟结点, 最左边的叶子结点,也就是说 最远和之前的 x2 有关联,它们共同组成了更大的短语 。(这里定义又不是很严谨,例如对于上面那个例子,的最左子结点,这种情况下不能按照来计算,因为它没有最左的兄弟结点!所以按照来算的话得到。)
根据这个 就可以将 定义为:
但是因为这是离散的决策,没法传递梯度,所以之后会介绍用概率来替代这里的0和1。
然后是Reading Network。得到了gates之后,就可以修改RNN,用下面公式计算 t 时刻的隐含层状态:
具体是怎么使用这个gates的,后面再具体介绍,反正只要知道多考虑了很多个历史状态就行了,每个状态都有一个权重,表示考虑了多少。
最后就是Predict Network,用来预测下一个单词 ,用到的是历史多个隐含层状态信息:
这里后面也会具体讲到。
模型
这里我不按照论文上的顺序讲,论文是倒序,变量定义都得看完整篇论文才出来,实在是看的太杂乱了。。。
Parsing Network
第1步: 首先第一步要预测出相邻两个单词的句法距离,用宽度为 的卷积核来对单词进行卷积。例如要预测 的句法距离,那么就对 进行卷积(其实就是两层前馈神经网络),得到如下输出(注意原文中这一段里的词向量 e 应该都是 x ,并且这里原文中定义为 h 是和后面符号冲突的,有误):
当然了,第二行也可以看做是窗口大小为1的卷积核,第一个单词之前要补上 个0。
最后得到的句法距离反映出了相邻两个词之间的语义相关程度,如果距离比较大,说明两个词可能位于两个不同的短语中,否则就位于同一个短语。一个形象化的句法距离就是相邻两个单词的最近公共祖先的高度。
下面这个图就是一个例子,卷积核窗口宽度为2:
第2步: 然后就可以根据句法距离,求出 最远到哪个位置有联系。用 来衡量 与 的分别与前一个单词的句法距离的差距:
这里的 就是当输入大于1或者小于-1时,截取掉,给它限制在-1到1这个范围内,所以最后 的范围就是0到1。可以看出,如果 很大,那么 ,否则的话 。这也很合乎直观上的认知,如果 ,那么说明 的最近公共祖先的高度比较低,那么说明 在同一棵子树中,差值自然大,反之的话 是当前子树的最左边的子结点,差值就很小。
所以模型只需要一步步往左寻找第一个 最接近0的点,也就是之前提到过的 。为了实现这个目标,可以定义 的概率
注意到这个概率密度函数在 时值基本很小接近于0,而大于等于它时很大,越来越接近于1。这和设计的初衷已经很像了,所以可以近似用来作为 。
这里要提几点证明,可看可不看。