卷积神经网络CNN 在自然语言处理中的应用

序言

CNN在文本分类中取得了不俗的结果,而运用在这里的卷积可以分为1d、2d甚至是3d的。

我们知道,CNN一般用来做图像。图像是可以通过预处理,将每幅照片都处理成一样的size的(也就是height和width具有一样的像素值)。然后用一个filter在图像上去滑动做卷积。但是文本不一样,文本语料中每句话的长度是不固定的,你怎么把它处理成类似于图像的这种二维矩阵结构呢?

这个问题,是理解CNN for nlp的关键。

1.文本的二维矩阵表示

把文本表示成和图像一样的二维矩阵形式的方法很简单:

一方面,填充每个句子到的最大句子长度。我们添加特殊的tokens到其他句子中使得它们包含max_length个words。填充句子到同样的长度是有用的,因为批处理的每个样本都必须有相同的长度,所以这样可以高效地把数据划分成批。

填充句子长度,其实就是一个padding的问题。

另一方面,使用word embedding。可以直接在神经网络中从头开始训练词向量(train from scratch)。也可以采用迁移学习的思想,先通过word2vec、glovec或者Fasttext等方式训练词向量,然后把词向量直接导入神经网络中的embedding层作为权重,进行fine-tuning。

以上说的是“英文”等不需要分词的文本的方式。对于汉语文本,需要先做分词,再做上两个步骤。

2 文本分类的CNN网络结构

2.1 经典结构

《卷积神经网络CNN 在自然语言处理中的应用》

yoon kim的《Convolutional Neural Networks for Sentence Classification》。(2014 Emnlp会议)

他用的结构比较简单,就是使用长度不同的filter 对文本矩阵进行卷积,filter的宽度等于词向量的长度,然后使用max-pooling 对每一filter提取的向量进行操作,最后每一个filter对应一个数字,把这些filter拼接起来,就得到了一个表征该句子的向量。最后的预测都是基于该句子的。该模型作为一个经典的模型,作为很多其他改领域论文里实验参照。论文下载:http://www.aclweb.org/anthology/D14-1181

2.2  其他结构

《A Convolutional Neural Network for Modelling Sentences》(2014 ACL会议)

《卷积神经网络CNN 在自然语言处理中的应用》

这个模型看起来就相对复杂一些,不过其基础也是基于卷积的。每一层的卷积操作之后同样会跟上一个max pooling操作。整个模型操作相对于上面的那个模型比较繁琐,同时我有以下几个比较质疑的地方:

1倒数第二到倒数第三层使用了k-max的pooling操作,也就是说第三层中相邻的词语对应于原来的句子可能不再是相邻的,而且它们只有相对的先后关系保存了下来。倒数第三层中不同卷积平面对应的词语在原句子中可能处于不同的位置,甚至是不同的词语,因此倒数第三道倒数第四之间的卷积是没有意义的。

2关于这里的folding操作。把同一个词语向量的不用维度之间进行加法操作,这样原文里是这样解释的“With a folding layer, a feature detector of the i-th order depends now on two rows of feature values in the lower maps of order i -1.”。但是这样的操作有意义吗??从来没有见人提到用过,也许我们未来可以探索一下这样是否能够提高卷积器的性能。

《A C-LSTM Neural Network for Text Classification》(arXiv preprint arXiv)

《卷积神经网络CNN 在自然语言处理中的应用》

其实这篇论文里只是用cnn对原文的词向量以某一长度的filter进行卷积抽象,这样原来的纯粹词向量序列就变成了经过卷积的抽象含义序列。最后对原句子的encoder还是使用lstm,由于使用了抽象的含义向量,因此其分类效果将优于传统的lstm,这里的cnn可以理解为起到了特征提取的作用。

《Recurrent Convolutional Neural Networks for Text Classification》(2015 AAAi会议)

《卷积神经网络CNN 在自然语言处理中的应用》

正如标题所说的,把lstm和cnn结合起来了,不过这个结合的方式和上面的不一样。举例来说对于词序列: A B C D E F来说,在形成C词的向量化表示的时候,使用的不再仅仅是C的word embedding,而是C左边的内容构成的向量和C以及C右边内容构成的向量的拼接形式。由于使用到了左右两边的内容故使用的是双向的Lstm。然后如图中所示使用1-d convolution的方式得到一系列的y,最后经过max-pooling的方式得到整个句子的向量化表示,最后的预测也是基于该句子的。

《Learning text representation using recurrent convolutional neural network with highway layers》(arXiv preprint arXiv)

《卷积神经网络CNN 在自然语言处理中的应用》

这个模型几乎就是稍微的更改了一下上面的模型,只不过在C向量拼接完毕将要进行卷积操作之前经过了一个highway而已。

3 CNN在文本分类中的应用

3.1 文本分类的网络结构

3.2 迁移学习在文本分类中的应用

3.3 文本分类的Tensorflow实现(含代码)

4 实战:基于CNN的query意图分类模型

训练数据:分析某行业query对应的意图;一共有十几类意图,通过人工标注几万条。

训练10个epoch,基于这10个epoch来评价三种方案的效果:

方案1:不使用pre-trained词向量

Dev集92.3%测试集92.8%

说明:数据分为“训练集 交叉验证 测试集”三种,Dev集就是交叉验证的数据集

方案2:使用预训练的词向量,但embedding层通过fine-tuning进行调整。

我们使用pre-trained词向量(50维),但是pre-trained词向量只赋初值,embedding层的权重在训练过程中可以变化。

这里我使用的是自己通过医疗行业几千万bidword训练出的词向量,不过有时候如果要偷懒,也可以使用网上公开的词向量(效果会略微差点):

https://github.com/facebookresearch/fastText/blob/master/pretrained-vectors.md

训练效果(准确率)

Dev集94.4%测试集93.4%

方案3:使用预训练的词向量,且embedding层不许在训练时改变。

embedding层不接受训练时训练效果(准确率):

Dev集:93.6%测试集:94.3%

由于我们最终希望的是结果能够有比较好的泛化,因此,pre-trained的词向量在赋给embedding层以后不许再修改,似乎是一种最好的方式。

通过预训练的词向量,我们的准确率提升了1.5%。效果还是很明显的。

版权声明:

本文首发于:人工智能A7论坛

转载请注明出处

    原文作者:_木豆_
    原文地址: https://www.jianshu.com/p/8bba86b03691
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞