一些废话
好久没有更新了,简书上公式编辑实在是让我不舒服~
发现,不写下来自己的金鱼脑袋太容易忘记。
ok,继续记录。
由于最近看了几篇cnn在nlp中应用的论文,作此总结,主要按照看论文的顺序。
1.Single Layer NLP
参考论文:Kim Y. Convolutional neural networks for sentence classification[J]. arXiv preprint arXiv:1408.5882, 2014.(EMNLP 2014).
与图像处理不同,对于自然语言处理任务来说,输入一般是用矩阵表示的句子或文档。对于句子矩阵,每一行表示一个单词,每个词可以用向量表示(word2vec or GloVe, but they could also be one-hot vectors)。下面介绍一种简单的cnn结构,一层convolution+一层pooling。
1.1 说明如下:
输入层
如图所示,输入层是句子中的词语对应的word vector依次(从上到下)排列的矩阵,假设句子有 n 个词,vector的维数为 k ,那么这个矩阵就是 n×k 的。
这里,模型根据词向量的不同分为四种:
- CNN-rand,所有的词向量都随机初始化,并且作为模型参数进行训练。
- CNN-static,即用word2vec预训练好的向量(Google News),在训练过程中不更新词向量,句中若有单词不在预训练好的词典中,则用随机数来代替。
- CNN-non-static,根据不同的分类任务,进行相应的词向量预训练。这里的动态是在模型训练过程中,word vector也当做是可优化的参数,通常把反向误差传播导致word vector中值发生变化的这一过程称为Fine tune。
- CNN-multichannel,CNN-static和CNN-non-static的混合版。两套词向量构造出的句子矩阵作为两个通道,在误差反向传播时,只更新一组词向量,保持另外一组不变。
对于未登录词的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层,Softmax层可根据任务的需要设置(通常反映着最终类别上的概率分布)。
最终实现时,我们可以在倒数第二层的全连接部分上使用Dropout技术,即对全连接层上的权值参数给予L2正则化的限制。这样做的好处是防止隐藏层单元自适应(或者对称),从而减轻过拟合的程度。
1.2 实验部分
数据
实验用到的数据集如下(具体的名称和来源可以参考论文):
模型训练和调参
- 修正线性单元(Rectified linear units)
- 滤波器的h大小:3,4,5;对应的Feature Map的数量为100;
- Dropout率为0.5,L2正则化限制权值大小不超过3;
- mini-batch的大小为50;
这些参数的选择都是基于SST-2 dev数据集,通过网格搜索方法(Grid Search)得到的最优参数。另外,训练过程中采用随机梯度下降方法,基于shuffled mini-batches之上的,使用了Adadelta update rule(Zeiler, 2012)。
预训练的Word Vector
这里的word vector使用的是公开的数据,即连续词袋模型(COW)在Google News上的训练结果。未登录次的vector值是随机初始化的。
1.3 实验结果
实验结果如下图:
实验结果.png
1.4 实验代码
开源地址:https://github.com/yoonkim/CNN_sentence
1.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距离原始值太远,但同时保留其一定的变化空间。
在七组数据集上进行了对比实验,证明了单层的CNN在文本分类任务中的有效性,同时也说明了用无监督学习来的词向量对于很多nlp任务都非常有意义。
这里需要注意的是,(1)static模型中word2vec预训练出的词向量会把good和bad当做相似的词,在sentiment classification任务中将会导致错误的结果,而non-static模型因为用了当前task dataset作为训练数据,不会存在这样的问题。(2)句子中的!最接近一些表达形式较为激进的词汇,如lush等;而,则接近于一些连接词,这和我们的主观感受也是相符的。
具体可参看下图:
Kim Y的这个模型很简单,但是却有着很好的性能。后续Denny用TensorFlow实现了这个模型的简单版本,可参考这篇博文;以及Ye Zhang等人对这个模型进行了大量的实验,并给出了调参的建议,可参考这篇论文。
下面总结一下Ye Zhang等人基于Kim Y的模型做了大量的调参实验之后的结论:
- 由于模型训练过程中的随机性因素,如随机初始化的权重参数,mini-batch,随机梯度下降优化算法等,造成模型在数据集上的结果有一定的浮动,如准确率(accuracy)能达到1.5%的浮动,而AUC则有3.4%的浮动;
- 词向量是使用word2vec还是GloVe,对实验结果有一定的影响,具体哪个更好依赖于任务本身;
- Filter的大小对模型性能有较大的影响,并且Filter的参数应该是可以更新的;
- Feature Map的数量也有一定影响,但是需要兼顾模型的训练效率;
- 1-max pooling的方式已经足够好了,相比于其他的pooling方式而言;
- 正则化的作用微乎其微。
Ye Zhang等人给予模型调参者的建议如下:
- 使用
non-static
版本的word2vec
或者GloVe
要比单纯的one-hot representation
取得的效果好得多; - 为了找到最优的过滤器(Filter)大小,可以使用线性搜索的方法。通常过滤器的大小范围在
1-10
之间,当然对于长句,使用更大的过滤器也是有必要的; -
Feature Map
的数量在100-600
之间; - 可以尽量多尝试激活函数,实验发现
ReLU
和tanh
两种激活函数表现较佳; - 使用简单的
1-max pooling
就已经足够了,可以没必要设置太复杂的pooling方式; - 当发现增加
Feature Map
的数量使得模型的性能下降时,可以考虑增大正则的力度,如调高dropout
的概率; - 为了检验模型的性能水平,多次反复的交叉验证是必要的,这可以确保模型的高性能并不是偶然。
论文附录中还附上了各种调参结果,感兴趣的可以前往阅读之。
2. Multi-Layer CNN
参考论文:A Convolutional Neural Network for Modelling Sentences
该网络使用动态k-Max池,一个通过线性序列的全局池操作。该网络处理不同长度的输入句子,并在句子中归纳出一个特征图,可以明确地捕捉短和长期的关系。该网络不依赖于解析树,并且很容易适用于任何语言。我们在四个实验中对DCNN进行了测试:小尺度二进制和多类情绪预测,六道问题分类和远程监控的推特情绪预测。该网络在前三项任务中取得了出色的性能,并且在最后一项任务中,在最强大的Baseline上减少了25%的错误。
模型架构如下:
模型架构.png
2.1 说明如下
-
Wide Convolution宽卷积
一维卷积是一个权重向量m∈Rm和一个被视为序列的输入向量
[图片上传失败...(image-58e53f-1525754004284)]之间的运算。向量m是卷积的滤波器。具体地说,我们认为s是输入语句,
[图片上传失败...(image-da8bc4-1525754004284)]是与句子中第i个单词相关的单一特征值。一维卷积背后的思想是在句子中求每个m-gram与向量m的点积,从而获得另一个序列c:
[图片上传失败...(image-44a089-1525754004285)]
根据 j 的取值范围,公式1给出了两种类型的卷积。窄卷积要求s≥m,序列[图片上传失败...(image-67aeb9-1525754004285)]的j的范围是m到s。宽卷积对s或m没有大小要求,序列c的索引j的范围是1到s+m−1。超出范围(i<1或者i>s)的输入值si会被设为零,狭义卷积的结果是广义卷积结果的子序列。两种一维卷积在图2中得到了说明。
与Narrow相对而言,wide convolution指用filter m 对句子中的所有可能组合进行卷积,句子左右可以补零,从而得到比原句子长度更长的feature map,能够获得句子中词语尽可能多的不同组合。例如下图:
图中的右图即表示宽卷积的计算过程。
过滤器m中训练的权重相当于一个语言特征检测器,它学习对一个特定的n-gram进行编码,这些n-grams为大小n≤m,m是滤波器的宽度。在一个宽的卷积中应用权重m比在一个窄的卷积中应用它们有一些优势。一个宽卷积可以确保过滤器中的所有权重达到整个句子,包括边缘的单词。当m被设置为相对较大的值(比如8或10)时,这是非常重要的。此外,宽卷积保证了滤波器m对输入语句的应用总是产生一个有效的非空结果c,独立于宽度m和句子长度s。
k-Max Pooling池化
接下来我们描述的是一个池化操作,它是在Max-TDNN语言模型中的关于时间维度的最大池化操作的一般化,不同于用于目标检测的卷积网络中使用的局部最大池化操作 (LeCun et al., 1998)。
给出数学形式化的表述是,给定一个k值,和一个序列图片上传失败...(image-49fb6a-1525754004285),k-max pooling选择了序列p中的前k个最大值,这些最大值保留原来序列的次序(实际上是原序列的一个子序列)。
k-max pooling的好处在于,既提取除了句子中的较重要信息(不止一个),同时保留了它们的次序信息(相对位置)。同时,由于应用在最后的卷积层上只需要提取出k个值,所以这种方法允许不同长度的输入(输入的长度应该要大于k)。然而,对于中间的卷积层而言,池化的参数k不是固定的,具体的选择方法见下面的介绍。
k-max池操作使得选出在p中的k个最活跃特征成为可能,它们位于一些不同的位置。它保留了特征的顺序,但对它们的特定位置不敏感。它还可以更精细地分辨出在p中,特征被高度激活的次数,以及在p上的特征变化的被高度激活的状况。将k-max池运算符应用于最顶层卷积层后的网络中。这保证了全连接层的输入独立于输入句子的长度。但是,正如我们接下来看到的,在中间卷积层中,池参数k不是固定的,而是动态选择的,以便能够平滑地提取更高阶和更长的特性。
动态k-max池化
动态k-max池化操作,其中的k是输入句子长度和网络深度两个参数的函数,具体如下:
一个动态k-max池操作是一个k-max池操作,我们让k成为句子长度和网络深度的函数。虽然可能有很多函数,但我们只是简单地将池参数建模如下:
[图片上传失败...(image-520de5-1525754004285)])
其中 l 表示当前卷积的层数(即第几个卷积层),L是网络中总共卷积层的层数;[图片上传失败...(image-87ff90-1525754004285)]为最顶层的卷积层pooling对应的k值,是一个固定的值。举个例子,例如网络中有三个卷积层,ktop=3,输入的句子长度s=18;那么,对于第一层卷积层下面的pooling参数k1=12,而第二层卷积层的pooling参数k2=6,第三层有固定的池化参数k3=ktop=3。方程4是描述第l部分的序列的相关部分在长度为s的句子上的相关部分所需要的数值数量的模型。对于情绪预测中的一个例子,根据方程,在长度s的句子中,一阶特征,例如一个正数,大多数出现[图片上传失败...(image-4e63d0-1525754004285)]次,而另一个二阶特征,如否定句或子句,最多出现[图片上传失败...(image-98d273-1525754004285)]次。
动态k-max池化的意义在于,从不同长度的句子中提取出相应数量的语义特征信息,以保证后续的卷积层的统一性。
非线性特征函数
在动态池化应用于卷积的结果之后,一个偏置项[图片上传失败...(image-de6789-1525754004285)]和一个非线性函数g被应用于被池化的矩阵的每一个元素。每个集合矩阵的每一行都有一个单偏差值。如果我们暂时忽略池化层,我们可以说明在卷积层和非线性层后如何计算矩阵a中的d维的列a。定义M为对角矩阵。
其中m为宽卷积的d维滤波器的权值。然后,在第一对卷积和一个非线性层之后,矩阵a中的每一列a得到如下所示,对于一些索引j:
pooling层与下一个卷积层之间,是通过与一些权值参数相乘后,加上某个偏置参数而来的,这与传统的CNN模型是一样的。
多个Feature Map
和传统的CNN一样,会提出多个Feature Map以保证提取特征的多样性。
折叠操作(Folding)
到目前为止,在网络的形成过程中,应用于句子矩阵的单个行的特征检测器可以有多种顺序,并在多个特征映射的同一行中创建复杂的依赖关系。然而,不同行的特征检测器相互独立,直到顶部的全连接层。可以通过在Eq. 5中使M变成满矩阵来实现完全依赖于不同的行,而不是一个稀疏矩阵的对角线。在这里,我们探索一种更简单的方法,称为折叠,它不引入任何其他参数。在一个卷积层之后,动态k-Max池化之前,将一个feature map组件中的每两行相加。对于d行的映射,折叠返回d/2行的映射,从而使表示的大小减半。使用折叠层之后,第i层的特征探测器现在依赖于更低的第i−1层的两行特征值。这样我们结束了对DCNN的描述。
Folding操作则是考虑相邻的两行之间的某种联系,方式也很简单,就是将两行的vector相加;该操作没有增加参数数量,但是提前(在最后的全连接层之前)考虑了特征矩阵中行与行之间的某种关联。
模型的特点
- 保留了句子中词序信息和词语之间的相对位置;
- 宽卷积的结果是传统卷积的一个扩展,某种意义上,也是n-gram的一个扩展;
- 模型不需要任何的先验知识,例如句法依存树等,并且模型考虑了句子中相隔较远的词语之间的语义信息;
2.2 实验部分
模型训练及参数
- 输出层是一个类别概率分布(即softmax),与倒数第二层全连接;
- 代价函数为交叉熵,训练目标是最小化代价函数;
- L2正则化;
- 优化方法:mini-batch + gradient-based (使用Adagrad update rule, Duchi et al., 2011)
实验结果
在三个数据集上进行了实验,分别是(1)电影评论数据集上的情感识别,(2)TREC问题分类,以及(3)Twitter数据集上的情感识别。结果如下图:
2.3 实验结论
可以看出,DCNN的性能非常好,几乎不逊色于传统的模型;而且,DCNN的好处在于不需要任何的先验信息输入,也不需要构造非常复杂的人工特征。
参考
卷积神经网络(CNN)在句子建模上的应用
自然语言处理系列(9):A Convolutional Neural Network for Modelling Sentences—DCNN
从CNN视角看nlp应用
网友评论