LSTM作为序列模型一直是自然语言处理的最佳选择之一,即使transformer出现了也依然无法撼动LSTM在NLP界的江湖地位。
然而,语言虽然看起来是一个序列,实际上内部是有复杂的层次结构的,这也是NLP的难点所在。复杂的层次结构,意味着序列即使看起来相同,也可能应为内部层次结构的不同而有语义的差别。
在斯坦福CS224n上提到了这样的一个例子:
The police killed the man with a knife.
这个句子,可以有两种理解:
上面两种解释对应的句法树分别是这样的:
这个根据我自己的理解画的,不一定对啊,但是我想表达的意思就是,序列看起来一样,但是内部的层级结构可能很不一样。
因此很多学者在思考如何将语言的树形结构融入到训练过程中,从而让模型具有更加强大的表示能力。
今天介绍的这篇论文,就设计了一个特殊的LSTM结构,使得模型可以将句子的层级结构给编码进去,从而增强了LSTM的表达能力。这篇论文也是ICLR2019的最佳论文之一。
ICLR 2019 Best paper
[LSTM运算流程示意图,来源:苏剑林的博客:https://kexue.fm/archives/6621]
上面这个图是我看到过的画的最清晰的LSTM结构图了。我们跟着图再来回顾一下LSTM的原理。
图中
都可以看做是历史信息
和当前输入
经过一个全连接层得到,即一个单层神经网络。
三者的激活函数是sigmoid,输出是0-1之间,所以相当于一个控制开关,因此在这里称作“门”。
相当于是把历史信息和当前信息进行一个融合后得到的当前状态。
是历史状态,如何得到输出状态
呢:
意思就是让历史状态经过
这个门,然后当前状态经过
这个门,就得到输出的状态。
所以,我们称
为遗忘门,它控制是否要遗忘历史的状态;而
称为输入门,它控制当前输入的多少。
这个就是LSTM的内部主要结构。总的公式是这样的:
论文中一直在扯什么神经元有序无序,独不独立这种问题,搞得人头大,其实我感觉就是故弄玄虚,只是看上去好像是修改后的LSTM的神经元有序了一样,实际上只为了给模型取一个名字。所以下面我们不讲神经元的问题,我们从cell state的角度去理解。
LSTM的核心就是cell state:
信息在cell state这个传送带上流动,伴随着一些简单的线性变换,乘和加,分别由“遗忘门”和“输入门”来控制cell state的信息更新。
然而,我们会发现,每次更新,cell state这个向量的每一维都会更新:
记住,我们的信息流就是存在这个cell state中,如果我们希望模型可以刻画出语言的结构信息,那么我们就希望这个cell state中隐含着层次结构的信息。所以我们希望,能够让这个cell state的不同维度,对应到语言的不同层级上,让不同的层级使用不一样的方式进行更新,具体来说就是层次越高的更新越少。这样的话,cell state就包含了层次信息了。
于是作者们举了个例子:
假设我们有一个很简单的句子,三个词组成[x1,x2,x3],有三个层次,用下图的最左边的图表示,分别是句子(S)、短语(NP,VP)、词(N,V)。我们希望cell state中也可以有对应的三个层次,层次就体现在不同的更新频率上。
层次越高的,自然其信息应该保留的时间更久,所以其更新频率应该越低。上图的最右边是三个词分别对应的cell states。颜色越深代表更新频率越高。
这样,语言的层次就和cell states的不同区间对应上的。
这样,就相当于给cell states加了一个顺序,从某种意义上讲也相当于是给LSTM的神经元加了顺序,因此作者称这种结构是Ordered-Neurons,对应的LSTM称为ON-LSTM。所以并不是真的给神经元排序。
然而,上面给cell states这样分区间,是因为我们提前知道了句子的结构,但我们真正使用LSTM进行建模、训练的时候,是不知道语言的真实层次的,除非你先把每个句子都解析成语法树,再显示的加入到LSTM中的,但是这种方法不仅开销大,而且不一定可靠,所以我们需要设计一种结构,让模型可以学习到如何给cell state去分区。
我们定义两个层级:
,分别代表历史(history)信息辐射到的最低层级和当前(now)信息的触及的最高层级,他们就决定了历史信息信息和当前信息的势力范围。他们应该是
的函数,记为:
下图表示了历史信息和当前信息影响的范围:
怎么理解呢,还是用这个图来举例子:
当读到x1时,当前信息的最高级是S,也就是第一级,而这个时候没有历史,可以看做历史的辐射范围为0:
读到x2时,因为S还是那个S,所以当前新的信息的最高级只有2了,而历史信息的最低级此时也是2:
x3类似分析,我就不画图了(太费劲了)。
上面的例子比较简答,实际上也可能会有历史信息和当前信息存在重叠,或者根本不互相影响的情形。所以总的来说有两种情况:
如何让上面的过程变成一个式子:
这样,对于cell state,我们就分三段进行不同的更新,公式如下:
对比LSTM,ON-LSTM的改动就是cell state是怎么更新的,其他的部分都一样。
所以最后ON-LSTM的结构可以用这个图表示:
[ON-LSTM运算流程示意图,来源:苏剑林的博客:https://kexue.fm/archives/6621]
我们只需要只是历史信息的层级,就可以解析出句子的树状结构:
[用ON-LSTM来解析句子结构,来源:苏剑林的博客:https://kexue.fm/archives/6621]
这个图也来来自于苏剑林大神的文章,这里解释一下:
假设上面的图对应的句子是[x1,x2,x3,x4,x5], 最上面的黄色部分代表历史信息的范围,所以可以知道每一个词的历史层级:
词 | x1 | x2 | x3 | x4 | x5 |
---|---|---|---|---|---|
层级 | 4 | 2 | 3 | 1 | 3 |
可以看出,层级最高的是x4,这意味着x4包含的历史信息是最少的,因此推断这里应该是一个新的语言结构的开始,所以我们从x4给句子断开一次。
然后断开的两截,按照相同的方法再去断开成更细的结构,直至细化到每个词。
用可以用下面这个图来示意:
这样,一个句子的结构就解析出来了。
论文作者试验了一下用他们训练好的模型来解析出句子的树形结构,发现准确率很高,这也说明了ON-LSTM确实把句子的结构给编码进去了,表示能力确实比LSTM要大大增强。
模型的效果自然不必说,大家感兴趣可以自行看论文中的相关实验。
代码的话我这里推荐苏剑林的github:https://github.com/bojone/on-lstm
个人亲测很好用,基本可以直接替换之前的LSTM层,不用更改多少东西去适配。目前我在一个长文本相似度的任务上测试过ON-LSTM的效果,仅仅是将LSTM替换成ON-LSTM就将测试集准确率提高了约5个百分点,还是比较明显的。所以推荐大家去试试。
Yikang Shen, Shawn Tan, Alessandro Sordoni, Aaron Courville. Ordered Neurons: Integrating Tree Structures into Recurrent Neural Networks. arXiv preprint arXiv:1810.09536 [cs.CL]
Christopher Olah. (2015, August 27).《Understanding LSTM Networks》[Blog post].Retrieved from http://colah.github.io/posts/2015-08-Understanding-LSTMs/
苏剑林. (2019, May 28). 《ON-LSTM:用有序神经元表达层次结构 》[Blog post]. Retrieved from https://kexue.fm/archives/6621
推荐阅读
想学深度学习?这些笔记你一定喜欢:
一只蚊子告诉你,什么是正则化(Regularization)
一文上手TensorFlow,并搭建神经网络实现手写数字识别
想了解更多NLP有趣的知识?看看这些: Hello NLP(1)——词向量Why&How Hello NLP(2)——关于word2vec你想知道的一切 放弃幻想,全面拥抱Transformer:自然语言处理三大特征抽取器(CNN/RNN/TF)比较
全套笔记请至公众号菜单,戳【这有惊喜】