以前的博文已经介绍了CNN的基本原理,本文将大概总结一下最近CNN在NLP中的句子建模(或者句子表示)方面的应用状况,主要阅读了如下的文献:php
Kim Y. Convolutional neural networks for sentence classification[J]. arXiv preprint arXiv:1408.5882, 2014.html
Kalchbrenner N, Grefenstette E, Blunsom P. A convolutional neural network for modelling sentences[J]. arXiv preprint arXiv:1404.2188, 2014.git
Hu B, Lu Z, Li H, et al. Convolutional neural network architectures for matching natural language sentences[C]//Advances in Neural Information Processing Systems. 2014: 2042-2050.github
He H, Gimpel K, Lin J. Multi-perspective sentence similarity modeling with convolutional neural networks[C]//Proceedings of the 2015 Conference on Empirical Methods in Natural Language Processing. 2015: 1576-1586.算法
Wenpeng Yin, Hinrich Schütze. Convolutional Neural Network for Paraphrase Identification. The 2015 Conference of the North American Chapter of the Association for Computational Linguistics网络
Zhang Y, Wallace B. A Sensitivity Analysis of (and Practitioners’ Guide to) Convolutional Neural Networks for Sentence Classification[J]. arXiv preprint arXiv:1510.03820, 2015.架构
下面对文献中CNN的结构和细节进行梳理。app
模型的结构以下:框架
说明以下:ide
如图所示,输入层是句子中的词语对应的word vector依次(从上到下)排列的矩阵,假设句子有 n 个词,vector的维数为 k ,那么这个矩阵就是 n×k 的。
这个矩阵的类型能够是静态的(static),也能够是动态的(non static)。静态就是word vector是固定不变的,而动态则是在模型训练过程当中,word vector也当作是可优化的参数,一般把反向偏差传播致使word vector中值发生变化的这一过程称为Fine tune
。
对于未登陆词的vector,能够用0或者随机小的正数来填充。
输入层经过卷积操做获得若干个Feature Map
,卷积窗口的大小为 h×k ,其中 h 表示纵向词语的个数,而 k 表示word vector的维数。经过这样一个大型的卷积窗口,将获得若干个列数为1的Feature Map
。
接下来的池化层,文中用了一种称为Max-over-time Pooling
的方法。这种方法就是简单地从以前一维的Feature Map
中提出最大的值,文中解释最大值表明着最重要的信号。能够看出,这种Pooling方式能够解决可变长度的句子输入问题(由于无论Feature Map
中有多少个值,只须要提取其中的最大值)。
最终池化层的输出为各个Feature Map
的最大值们,即一个一维的向量。
池化层的一维向量的输出经过全链接的方式,链接一个Softmax层,Softmax层可根据任务的须要设置(一般反映着最终类别上的几率分布)。
最终实现时,咱们能够在倒数第二层的全链接部分上使用Dropout
技术,即对全链接层上的权值参数给予L2正则化
的限制。这样作的好处是防止隐藏层单元自适应(或者对称),从而减轻过拟合的程度。
1. 数据
实验用到的数据集以下(具体的名称和来源能够参考论文):
2. 模型训练和调参
这些参数的选择都是基于SST-2 dev数据集,经过网格搜索方法(Grid Search)获得的最优参数。另外,训练过程当中采用随机梯度降低方法,基于shuffled mini-batches之上的,使用了Adadelta update rule(Zeiler, 2012)。
3. 预训练的Word Vector
这里的word vector使用的是公开的数据,即连续词袋模型(COW)在Google News上的训练结果。未登陆次的vector值是随机初始化的。
4. 实验结果
实验结果以下图:
其中,前四个模型是上文中所提出的基本模型的各个变种:
Fine tuned
;博主本身下载了论文做者的实现程序(Github地址),最终在MR数据集上的运行结果以下:
和论文中的结果差很少。
5. 结论
CNN-static
较与CNN-rand
好,说明pre-training的word vector确实有较大的提高做用(这也难怪,由于pre-training的word vector显然利用了更大规模的文本数据信息);CNN-non-static
较于CNN-static
大部分要好,说明适当的Fine tune也是有利的,是由于使得vectors更加贴近于具体的任务;CNN-multichannel
较于CNN-single
在小规模的数据集上有更好的表现,实际上CNN-multichannel
体现了一种折中思想,即既不但愿Fine tuned的vector距离原始值太远,但同时保留其必定的变化空间。值得注意的是,static的vector和non-static的相比,有一些有意思的现象以下表格:
bad
对应的最相近词为good
,缘由是这两个词在句法上的使用是极其相似的(能够简单替换,不会出现语句毛病);而在non-static
的版本中,bad
对应的最相近词为terrible
,这是由于在Fune tune
的过程当中,vector的值发生改变从而更加贴切数据集(是一个情感分类的数据集),因此在情感表达的角度这两个词会更加接近;!
最接近一些表达形式较为激进的词汇,如lush
等;而,
则接近于一些链接词,这和咱们的主观感觉也是相符的。Kim Y的这个模型很简单,可是却有着很好的性能。后续Denny用TensorFlow实现了这个模型的简单版本,可参考这篇博文;以及Ye Zhang等人对这个模型进行了大量的实验,并给出了调参的建议,可参考这篇论文。
下面总结一下Ye Zhang等人基于Kim Y的模型作了大量的调参实验以后的结论:
Ye Zhang等人给予模型调参者的建议以下:
non-static
版本的word2vec
或者GloVe
要比单纯的one-hot representation
取得的效果好得多;1-10
之间,固然对于长句,使用更大的过滤器也是有必要的;Feature Map
的数量在100-600
之间;ReLU
和tanh
两种激活函数表现较佳;1-max pooling
就已经足够了,能够不必设置太复杂的pooling方式;Feature Map
的数量使得模型的性能降低时,能够考虑增大正则的力度,如调高dropout
的几率;论文附录中还附上了各类调参结果,感兴趣的能够前往阅读之。
Kal的这篇文章引用次数较高,他提出了一种名为DCNN(Dynamic Convolutional Neural Network)的网络模型,在上一篇(Kim’s Paper)中的实验结果部分也验证了这种模型的有效性。这个模型的精妙之处在于Pooling的方式,使用了一种称为动态Pooling
的方法。
下图是这个模型对句子语义建模的过程,能够看到底层经过组合邻近的词语信息,逐步向上传递,上层则又组合新的Phrase信息,从而使得句子中即便相离较远的词语也有交互行为(或者某种语义联系)。从直观上来看,这个模型可以经过词语的组合,提取出句子中重要的语义信息(经过Pooling),某种意义上来讲,层次结构的feature graph
的做用相似于一棵语法解析树。
DCNN可以处理可变长度的输入,网络中包含两种类型的层,分别是一维的卷积层和动态k-max的池化层(Dynamic k-max pooling)。其中,动态k-max池化是最大化池化更通常的形式。以前LeCun将CNN的池化操做定义为一种非线性的抽样方式,返回一堆数中的最大值,原话以下:
The max pooling operator is a non-linear subsampling function that returns the maximum of a set of values (LuCun et al., 1998).
而文中的k-max pooling方式的通常化体如今:
DCNN的网络结构以下图:
网络中的卷积层使用了一种称之为宽卷积(Wide Convolution)
的方式,紧接着是动态的k-max池化层。中间卷积层的输出即Feature Map
的大小会根据输入句子的长度而变化。下面讲解一下这些操做的具体细节:
1. 宽卷积
相比于传统的卷积操做,宽卷积的输出的Feature Map
的宽度(width)会更宽,缘由是卷积窗口并不须要覆盖全部的输入值,也能够是部分输入值(能够认为此时其他的输入值为0,即填充0)。以下图所示:
图中的右图即表示宽卷积的计算过程,当计算第一个节点即s1时,能够假使s1s1节点前面有四个输入值为0的节点参与卷积(卷积窗口为5)。明显看出,狭义上的卷积输出结果是宽卷积输出结果的一个子集。
2. k-max池化
给出数学形式化的表述是,给定一个k值,和一个序列p∈Rp(其中p≥k),k-max pooling
选择了序列p中的前k个最大值,这些最大值保留原来序列的次序(其实是原序列的一个子序列)。
k-max pooling
的好处在于,既提取除了句子中的较重要信息(不止一个),同时保留了它们的次序信息(相对位置)。同时,因为应用在最后的卷积层上只须要提取出k个值,因此这种方法容许不一样长度的输入(输入的长度应该要大于k)。然而,对于中间的卷积层而言,池化的参数k不是固定的,具体的选择方法见下面的介绍。
3. 动态k-max池化
动态k-max池化操做,其中的k是输入句子长度
和网络深度
两个参数的函数,具体以下:
其中ll表示当前卷积的层数(即第几个卷积层),L是网络中总共卷积层的层数;ktop为最顶层的卷积层pooling对应的k值,是一个固定的值。举个例子,例如网络中有三个卷积层,ktop=3ktop=3,输入的句子长度为18;那么,对于第一层卷积层下面的pooling参数k1=12,而第二层卷积层对于的为k2=6,而k3=ktop=3。
动态k-max池化的意义在于,从不一样长度的句子中提取出相应数量的语义特征信息,以保证后续的卷积层的统一性。
4. 非线性特征函数
pooling层与下一个卷积层之间,是经过与一些权值参数相乘后,加上某个偏置参数而来的,这与传统的CNN模型是同样的。
5. 多个Feature Map
和传统的CNN同样,会提出多个Feature Map以保证提取特征的多样性。
6. 折叠操做(Folding)
以前的宽卷积是在输入矩阵d×s中的每一行内进行计算操做,其中d是word vector的维数,s是输入句子的词语数量。而Folding
操做则是考虑相邻的两行之间的某种联系,方式也很简单,就是将两行的vector相加;该操做没有增长参数数量,可是提早(在最后的全链接层以前)考虑了特征矩阵中行与行之间的某种关联。
1. 模型训练及参数
2. 实验结果
在三个数据集上进行了实验,分别是(1)电影评论数据集上的情感识别,(2)TREC问题分类,以及(3)Twitter数据集上的情感识别。结果以下图:
能够看出,DCNN的性能很是好,几乎不逊色于传统的模型;并且,DCNN的好处在于不须要任何的先验信息输入,也不须要构造很是复杂的人工特征。
1. 基于CNN的句子建模
这篇论文主要针对的是句子匹配(Sentence Matching)的问题,可是基础问题仍然是句子建模。首先,文中提出了一种基于CNN的句子建模网络,以下图:
图中灰色的部分表示对于长度较短的句子,其后面不足的部分填充的全是0值(Zero Padding)。能够看出,模型解决不一样长度句子输入的方法是规定一个最大的可输入句子长度,而后长度不够的部分进行0值的填充;图中的卷积计算和传统的CNN卷积计算无异,而池化则是使用Max-Pooling。
下图示意性地说明了卷积结构的做用,做者认为卷积的做用是从句子中提取出局部的语义组合信息,而多张Feature Map
则是从多种角度进行提取,也就是保证提取的语义组合的多样性;而池化的做用是对多种语义组合进行选择,过滤掉一些置信度低的组合(可能这样的组合语义上并没有意义)。
2. 基于CNN的句子匹配模型
下面是基于以前的句子模型,创建的两种用于两个句子的匹配模型。
2.1 结构I
模型结构以下图:
简单来讲,首先分别单独地对两个句子进行建模(使用上文中的句子模型),从而获得两个相同且固定长度的向量,向量表示句子通过建模后抽象得来的特征信息;而后,将这两个向量做为一个多层感知机(MLP)的输入,最后计算匹配的分数。
这个模型比较简单,可是有一个较大的缺点:两个句子在建模过程当中是彻底独立的,没有任何交互行为,一直到最后生成抽象的向量表示后才有交互行为(一块儿做为下一个模型的输入),这样作使得句子在抽象建模的过程当中会丧失不少语义细节,同时过早地失去了句子间语义交互计算的机会。所以,推出了第二种模型结构。
2.2 结构II
模型结构以下图:
图中能够看出,这种结构提早了两个句子间的交互行为。
第一层中,首先取一个固定的卷积窗口k1,而后遍历 Sx 和 Sy 中全部组合的二维矩阵进行卷积,每个二维矩阵输出一个值(文中把这个称做为一维卷积,由于其实是把组合中全部词语的vector排成一行进行的卷积计算),构成Layer-2。下面给出数学形式化表述:
从而获得Layer-2,而后进行2×2的Max-pooling:
后续的卷积层均是传统的二维卷积操做,形式化表述以下:
与第一层卷积层后的简单Max-Pooling方式不一样,后续的卷积层的Pooling是一种动态Pooling方法,这种方法来源于参考文献[1]。
1. 模型训练及参数
2. 实验结果
一共作了三个实验,分别是(1)句子自动填充任务,(2)推文与评论的匹配,以及(3)同义句识别;结果以下面的图示:
其实结构I和结构II的结果相差不大,结构II稍好一些;而相比于其余的模型而言,结构I和结构II的优点仍是较大的。
第四篇论文即He的文章中所提出的模型,是全部基于NN的模型中,在Paraphrase identification任务标准数据集MSRP上效果最佳的。下面咱们来学习一下这个模型。
模型主要分为两个部分:
模型不须要借助WordNet, 句法解析树等资源;可是能够选择性地使用词性标注、word embedding等方法来加强模型的性能;与以前的模型区别在于,文中的模型使用了多种类型的卷积、池化方法,以及针对获得的句子表征的局部进行相应的类似度计算。(这样作的优势在于可以更加充分地挖掘出句子中的特征信息,从而提高性能,但同时使得模型变得复杂、耗时)
模型的总体框架以下:
下面具体看看这两个模型是如何实现的。
模型是基于CNN的,卷积层有两种卷积方式,池化层则有三种。
假设模型的输入为二维矩阵 Sent,Sent∈Rlen×Dim,其中 lenlen 表示句子切分为Token List后的长度(Token能够是词/字),Dim 表示Token的Embedding表示的维度。由此有 Senti表示矩阵的第 i 行,即输入中的第 i 个Token的Embedding表示;Senti:j 表示矩阵中的第 i到第 j 行的一个切片,也是一个子矩阵;Senti[k] 表示矩阵的第 i 行第 k 列的值,对应是Embedding的第 k 个值;而 Senti:j[k] 则是矩阵中第 i 行到第 j 行中的第 k 列的一个切片。
卷积层有两种卷积的方式:(1)粒度为word的卷积;(2)粒度为embedding 维度上的卷积。以下图:
其中,第一种卷积方式与以前的Kim Y提出模型中的相同,至关因而n-gram特征的抽取;而对于第二种卷积方式,论文做者给出的解释是,(1)这种方式有助于充分地提取出输入的特征信息;(2)因为粒度更小,因此在学习过程当中的参数调整上,每个维度可以获得不一样程度的参数调整。(第二种卷积方式从直观上没有太多的物理意义,而做者也是直说不可以给出符合人直观想法上的解释)。
模型除了使用传统的max-pooling
,还使用了min-pooling
和mean-pooling
方式。
假设 group(ws,pooling,sent) 表示卷积宽度为 ws,使用 pooling 池化函数,应用在输入的句子 sent 上。咱们使用了两种类型的building block
,分别是 blockA 和 blockB上,定义以下
这里 blockA 有三组卷积层,卷积窗口的宽度一致(都是 wsa ),每一组对应一种池化操做。这里池化操做和卷积层是一一对应的,也就是说并非一个卷积层上实施三种池化操做(虽然也能够这么作,做者没有这么作的缘由是因为激活函数的存在,对每一个卷积结果都进行max-pooling
和min-pooling
是没有必要的)。
而 blockB 的定义以下:
这里 blockB 有两组卷积层,卷积窗口的宽度为 wsb,两组分别对应max-pooling
和min-pooling
的操做。值得说明的是,groupB(∗) 中的卷积层对应有 Dim 个以embedding dimension
为粒度的卷积窗口,也就是对embedding
的每一维度作卷积运算。
这里只因此要组合这些多样的卷积和池化操做,缘由是但愿可以从多个方面来提取出输入中的特征信息,以供后续的决策任务。
与传统的n-gram模型类似,这里在building block
中使用了多种尺寸的卷积窗口。以下图所示:
其中 wsws 表示卷积时卷积的n-gram长度,而 ws=∞ws=∞ 表示卷积窗口为整个word embedding
矩阵。wsws 的值及Feature Map
的数量都是须要调参的。
下面介绍在获得句子的表征向量以后,如何计算它们的类似度。直观的想法是,咱们可使用传统的类似度计算方法如余弦类似度等来计算两个句子向量的类似度。可是,直接应用这种作法在两个句子向量上并非最优的,缘由在于最后生成的句子向量中的每个部分的意义各不相同,这样简单粗暴的计算势必会影响效果,因此作法是对句子向量中的各个部分进行相应的比较和计算(Structured Comparision)。为了使得句子向量中的局部间的比较和计算更加有效,咱们须要考虑以下方面:
(1) 是否来自相同的building block
;
(2) 是否来自相同卷积窗口大小下的卷积结果;
(3) 是否来自相同的pooling层
;
(4) 是否来自相同的Feature Map
;
最终比较句子中的相应部分时,须要至少知足以上两个条件。为了识别句子中的哪些对应部分须要参与到类似度计算,文中提供了两种算法。
2.1. 类似度计算单元(Unit)
两种类似度计算单元以下:
2.2. 基于句子局部的类似度计算
算法1和算法2为句子表征向量的两种计算方法,其中算法1仅用在 blockAblockA 上;而算法2则都用在 blockAblockA 和 blockBblockB 上,两种算法都是针对相同类型(pooling和block类型)的输出作局部比较。
给出以下的符号假设:
算法的伪代码以下:
下面的图示说明了在 blockA 上,两种算法的计算方式的区别,算法一表现了向量在水平方向上的比较;而算法二则是在垂直方向。
须要注意的是,在算法二中相同类型的pooling的输出groups中,向量是两两进行比较的(图中的红色虚线只是为了说明比较的方向,并非只针对group中相同大小的卷积窗口做比较);而算法一中的每一行都要做比较,不只仅是第一行。
基于句子局部的类似度计算以后,获得相应的类似度向量;而后这组向量以后链接一个全链接层,最后softmax对应输出。若是是计算类似度度量值,能够用softmax输出的类别几率值。
使用tanh
函数做为激活函数。
用于评测同义句检测 (Paraphrase Identification) 任务的经典数据集,数据集来源于新闻;包含5801对句子对,其中4076对用于模型训练,而1725对用于测试;每一对句子拥有一个标签,0或者1,0表示两个句子不是互为同义句,而1则表示两个句子互为同义句。所以这是一个二分类的任务。
数据来源于2014年SemEval比赛,数据集有9927对句子对,其中4500对用于模型训练,500对用于模型验证,而剩下的4927对用于模型测试。这些句子都是在图片和视频描述中抽取获得的,每一对句子对有一个相关分数,区间在[1, 5],分数越高表示句子越相关。
数据集来源于2012年的SemEval比赛,包含1500对短文本(用于描述视频信息)。其中通常用于模型训练,一半用于模型测试,每一对句子有一个相关性分数,区间在[0, 5],分数越高表示句子越相关。
针对MSRP和其余两个数据集,分别使用两种损失函数。对于MSRP数据集,损失函数(Hinge Loss)以下:
对于其他两个数据集,损失函数(KL-divergence Loss)以下:
GloVe word embedding
;对于MSRP数据集,还额外使用了200维的POS embedding
(Standford POS tagger)和25维的Paragram Vectors
(Wieting et al., 2015 PDF,数据下载地址)。所以对于MSRP任务而言,word embedding
的维数为525维 (200+300+25);而其他两个任务则对应是300维。Feature Map
的数量与输入的embedding
维数相同,即MSRP是525个,而SICK和MSRVID则是300个。能够看出,文中的模型是全部基于NN的方法中在MSRP数据集上性能最好的。
而模型在SICK和MSRVID数据集上的表现也很好。
下面的表格说明了在不使用某种技术下,模型性能在实验数据集上的变化状况。
从中能够得出如下结论:
POS Embedding
和Paragram Vector
效果显著;Horizontal
和Vertical
算法均有必定的提高效果,而Vertical
算法的提高程度更高;max-pooling
方式确实要比min-pooling
和mean-pooling
强太多。文中的模型包含两个部分:卷积-池化模型和类似度计算模型。实验部分已经验证了模型的有效性,在MSRP数据集上模型取得了仅次于state-of-art的结果,而且在基于NN的方法中是最好的。模型中的类似度计算层是有必要的,由于对卷积池化处理后的句子成分进行了针对性的比较,从直观上要比直接扔进全链接层更合理,而实验结果也代表了这一点。
然而,我的以为,文中的模型结构较为复杂,并且其中有不少trick的地方,好比为何要对word embedding中的每一维度作卷积,blockBblockB 中的pooling
方式为何只用了max和min,不用mean的方式等问题,而这些方式或许是做者本身作了大量实验后,从果到于是使用的。
Yin的这篇论文提出了一种叫Bi-CNN-MI
的架构,其中Bi-CNN
表示两个使用Siamese
框架的CNN模型;MI
表示多粒度的交互特征。Bi-CNN-MI
包含三个部分:
这部分模型主要使用了上述Kal在2014年提出的模型,针对句子自己提取出四种粒度的特征表示:词、短ngram、长ngram和句子粒度。多种粒度的特征表示是很是必要的,一方面提升模型的性能,另外一方面加强模型的鲁棒性。
这部分模型主要是基于2011年Socher提出的RAE模型,作了一些简化,即仅对同一种粒度下的提取特征作两两比较。
论文提出的模型主要是基于Kal的模型及Socher的RAE模型的结合体,以下图:
经过模型图能够看出模型的主要思想:一方面利用Kal的模型进行多种粒度上的特征提取,另外一方面采起RAE模型的思想,对提取出来的特征进行两两的类似度计算,计算完成的结果经过dynamic pooling
的方式进一步提取少许特征,而后各个层次的pooling
计算结果平摊为一组向量,经过全链接的方式与LR(或者softmax)层链接,从而适配同义句检测任务自己。
这个模型具体的计算细节再也不赘述了,感兴趣的读者能够直接去看论文。除了提出这种模型结构以外,论文还有一个亮点在于使用了一种相似于语言模型的CNN-LM
来对上述CNN部分的模型进行预训练,从而提早肯定模型的参数。CNN-LM
的网络结构以下图:
CNN-LM
模型的训练预料使用了最终的实验数据集,即MSRP;另外,因为MSRP的数据规模较小,因此做者又增长了100,000个英文句子语料。CNN-LM
模型最终可以获得word embedding, 模型权值等参数。须要注意的是,这些参数并非固定的,在以后的句子匹配任务中是会不断更新的。从后面的实验结果中能够看出,CNN-LM
的做用是显著的。
论文仅使用了一种数据集,即公认的PI (Paraphrase Identification)任务数据集,MSRP。实验结果以下:
能够看出,CNN-LM
的预训练效果显著,预训练后的模型性能很强(可是结果上比以前He提出的模型稍差一些)。
本文结束,感谢欣赏。
欢迎转载,请注明本文的连接地址:
http://www.jeyzhang.com/cnn-apply-on-modelling-sentence.html
参考文献
[1] R. Socher, E. H. Huang, and A. Y. Ng. Dynamic pooling and unfolding recursive autoencoders for paraphrase detection. In Advances in NIPS, 2011.
推荐资料
Implementing a CNN for Text Classification in TensorFlow
Kim Y’s Implement: Convolutional Neural Networks for Sentence Classification