原文地址:Understanding Convolutional Neural Networks for NLP
CNN在CV(computer vision)中非常重要。本文主要介绍了CNN,以及它在NLP中的应用。
a sliding window function applied to a matrix-在矩阵上的滑动窗口函数
这里的滑动窗口也被称为核(kernel),过滤器(filter)或者特征提取器(feature detector)。
Averaging each pixel with its neighboring values blurs an image
Taking the difference between a pixel and its neighbors detects edges
several layers of convolutions with nonlinear activation functions like ReLU or tanh applied to the results
CNN = 几层卷积+非线性激活函数(ReLU或者tanh)
在传统前馈神经网络中,一般会将输入和下一层输出直接连接起来,这被称为全链接层(fully connected layer)或仿射层(affine layer)。但是在CNN中是通过在输入上卷积以后得到输出,每层都可以使用不同的卷积,再将结果整合起来。这里还有一个池化层(pooling layer或者subsample layer)。训练时,CNN训练的就是这些卷积。
在CNN图像分类(image classification)中的一般步骤:
值得注意的是:
- 位置不变性Location Invariance只判断是否有,但是不判断在图片中的位置在哪里。
- 局部组合性Local Compositionality每个卷积都会将特征从低维映射到高维一次。
和图像像素不同的是,nlp的输入是矩阵化的句子或者文档。矩阵的每一行代表一个token,通常是一个词,也可以是一个字。因此每行向量表示了一个词。一般这些向量都使用了词嵌入(word embedding)的低维表示方法,如word2vec或GloVe,不过这些向量也可以是独热(one-hot)向量(词在单词表中的索引位置)。
如,一个有十个词的句子,使用100维的词嵌入,我们将得到一个10*100的矩阵,这就是我们的"image"输入。
在图像中,我们的过滤器会在一张图片的patch上滑动,但是在nlp中我们一般用过滤器在每行(word)滑动。所以nlp过滤器的宽度一般和输入矩阵的宽度相等,高度(region size)则一般为2-5个词。
综上,NLP中的CNN一般是这样的1:
CNN句子分类
如图所示:
那么CNN的优势在NLP中是如何体现的呢?
在image中起到关键作用的location invariance和local compositionality并没有在nlp有明显的效果。因为我们会去关注词在句子中出现的位置。邻近的像素可能在一定程度上有语义关联(可能是同一对象的一部分),但是在词上就不一定了。在很多语言中,一些短语间可能会穿插着其他的词,所以局部组合性也就不那么突出了。而且很明显的,词的组成,如形容词修饰一个名词,在高维表达中到底是怎么实现以及如何解释,并不像CV案例中的那么明确。
基于上述内容,CNN看起来并不适合NLP任务,RNN可能更加适用。RNN的结构和我们处理语言的逻辑更为相似:从左到右读取序列。不过这并不代表CNN不能用于nlp。所有模型都是错误的,但是有些是有用的(All models are wrong, but some are useful.)。实际上,CNN在nlp上的效果是非常不错的。词袋模型的假定是错误的并且过于简单了,但是却有很好的效果并成了nlp的标准方法。
CNN的一个很大的优势是速度快。卷积是CV的核心,并且在硬件级别的GPU上运行。和n-grams比起来,CNN在表示上也非常的高效。在一个大的词汇表上,计算任何大于3-grams的东西都会很吃力,即使是google也都没有超过5-grams。卷积过滤器可以自动学习好的表示,而不需要表示整个词表,所以它能使用大于5的过滤器。我认为第一层学习到的过滤器抓取到的特征和n-gram是非常相似的(但是并不局限),但是却能以更为压缩的方式进行表示。
在介绍CNN如何在NLP任务中使用之前,我们要先来看看构建cnn时你需要做的选择,希望这能帮助你更好的理解。
在之前介绍卷积时省略了过滤器的构建细节。在矩阵的中间应用3*3
的过滤器是没问题的,但是在边缘时该怎么处理呢?当你在处理矩阵的第一个元素时,它的上方和左边并没有相邻的元素,这时该如何处理?这里可以使用零填充zero-padding。所有在矩阵之外的元素都用0表示。通过这个方法就可以在输入矩阵的所有元素上应用过滤器,然后获得更大/相等的输出。添加零填充又被称为宽卷积,不添加的成为窄卷积。下图是一个一维的例子2:
narrow vs. wide convolution
如图所示。窄卷积的输出大小为(7-5)+1=3
,宽卷积的输出大小为(7+2*4-5)+1=11
。输出大小的公式为 n o u t = ( n i n + 2 ∗ n p a d d i n g − n f i l t e r ) + 1 n_{out} = (n_{in} + 2*n_{padding} - n_{filter})+1 nout=(nin+2∗npadding−nfilter)+1。
卷积的另一个超参数是卷积步长,即过滤器每一步移动的距离。在上面的例子中,步长都是1,过滤器在连续使用时会有重叠。步长越大,过滤器使用得越少,输出就会更小。下图展示了在一维输入上应用步长1和步长2的差异:
stride size
一般来说步长都是1,但是大一点的步长可以得到类似RNN的效果。
CNN的一个重要的部分就是池化层,一般在卷积层之后。池化层会对输入进行二次取样。比较常用的池化是对每个过滤器的结果应用max操作,而并不需要对整个矩阵进行池化,当然也可以对窗口进行池化。举个例子,下图展示了对2*2
窗口的max池化(在nlp中,一般输出进行池化,使得每个过滤器都得到一个数字):
max pooling
为什么要做池化呢?
最后需要理解的概念是通道。通道是输入数据的不同"view"。比如,在图像识别中一般有RGB通道。可以在不同的通道使用相同或者不同的卷积权重。在nlp中,也可以把输入看作多个通道:使用不同的词嵌入方法(如word2vec和GloVe)形成不同的通道,或者由不同语言/短语组成的通道。
假设卷积前的map宽度为N,卷积后输出的map宽度为M,则可以得到:
N + 2 × p a d d i n g = ( M − 1 ) × s t r i d e + k e r n e l _ s i z e N+2\times padding = (M - 1)\times stride + kernel\_size N+2×padding=(M−1)×stride+kernel_size
则:
M = N + 2 × p a d d i n g − k e r n e l _ s i z e s t r i d e + 1 M = \frac{N+2\times padding-kernel\_size}{stride} + 1 M=strideN+2×padding−kernel_size+1
如果需要卷积操作不改变矩阵宽度,即M=N,则padding宽度为:
p a d d i n g = ( N − 1 ) × s t r i d e − N + k e r n e l _ s i z e 2 padding = \frac{(N - 1)\times stride - N + kernel\_size}{2} padding=2(N−1)×stride−N+kernel_size
下面介绍CNN在nlp的应用实例。
CNN最常用在分类任务中,不如语义分析,垃圾邮件识别或者主题分类。卷积和池化操作会丢失词的顺序信息,所以序列标注如PoS标注或者实体抽取中很少使用纯CNN框架(但也不是不能使用,可以通过在输入中添加位置特征来进行优化)。
文献3中对一个CNN框架在多个分类数据集上的效果进行了评价,这些数据集来自情感分析和主题分类任务。该CNN框架在这些数据集上都有很不错的效果,在一些数据集上还刷新了记录。然而,这篇文章中的网络框架却非常简单,这也使它更为强大。模型的输入层是一个由连接的word2vec词嵌入组成的句子,接下来是一个多过滤器的卷积层,然后是一个max池化层,最后是softmax分类器。该文章同时也在通道上做了探索,包括静态和动态的词嵌入通道,其中动态词嵌入会在训练中会进行调整,而静态词嵌入不做调整。
文献2中则介绍了类似的但是更为复杂的架构。
文献4在此基础上又添加了一个层来进行"语义聚类"。
文献5从头训练了一个CNN模型,没有使用预训练词向量如word2vec或GloVe。它直接在独热向量上使用了卷积。作者还介绍了一种类似词袋的输入数据的空间高效表示方法,对网络需学习的参数数量进行了降维。
在文献6中,作者通过添加一层无监督的"区域嵌入"(通过CNN预测文本区域的上下文来学习)对模型进行了扩展。
这些文章的方法在长文本(电影评论)中可以取得一定的效果,但是在短文本(tweets)中的效果就不是很明显。不过这也是有一定道理的,在短文本中使用预训练词嵌入会比在长文本中yield larger gains。
构建一个CNN模型意味着需要选择非常多的超参数,如之前提到的:输入表示(word2vec, GloVe, one-hot),卷积过滤器的数量和大小,池化策略(max,average),以及激活函数(ReLU, tanh)。
文献1中对CNN架构中不同超参数的效果进行了实验,探究了这些超参数在多次运行后对模型效果的影响。如果你想用自己的CNN模型来进行文本分类,推荐看看这篇文章。文章中的一些比较有用的结论:max池化比average池化的效果好;过滤器的大小非常重要,但是比较依赖于任务;在NLP任务中归一化的效果没有想象中明显。不过要注意的是这篇文章使用的数据集的长度都是相似的,这些结论不一定适用于其他不同的数据集。
文献7介绍了CNN在关系抽取和关系分类任务上的应用。在词向量上,作者使用了目标实体词的相对位置来作为卷积层的输入。模型假设实体的位置已经给定了,并且每个输入都包含一个关系。
文献8和文献9也介绍了相似的模型。
文献10和文献11介绍了微软研究院另一个有意思的CNN-NLP应用。文章介绍了如何学习句子的有意义的语义表达,这个可以应用在信息检索上。文章中的例子包括,基于用户正在阅读的文档来给用户推荐他们可能感兴趣的文档。这里的句子表示是通过搜索引擎的日志数据来训练的。
大多数CNN框架都将学习词或者句子的嵌入(低维表示)作为训练过程的一部分。但是没有多少文章去探究学习嵌入这个过程的价值。文献12介绍了一个预测Facebook posts的标签的CNN框架,并同时生成了词或者句子的有意义的嵌入。这些学习到的嵌入被成功应用到另一个任务:通过对点击流数据的训练,来向用户推荐可能感兴趣的文档。
至此,上面列出的所有模型都是基于词的。此外还有很多研究将CNN直接用于字符的文章。
文献13学习了字符级别的嵌入,然后联合预训练词嵌入,利用CNN做词性标注(Part of Speech tagging)。
文献14和文献15探索了直接利用CNN从字符中学习,而不使用任何预训练嵌入的方法。值得注意的是,作者使用了一个9层的深度网络,然后用于情感分析和文本分类任务。结果显示,直接从字符级输入进行学习在大数据集(比如百万级别)上的效果很好,但是简单一点的模型在小数据集(比如百、千级别)上的效果不好。
文献16则探索了字符级卷积在语言建模上的应用,它在每个time step都使用了字符级CNN的输出作为LSTM的输入,并且在不同的语言使用了这个模型。
神奇的是,这些文章都是在近1-2年发表的。当然在这之前也有很多CNN在NLP上的出色工作,比如从头开始NLP,但是发表新结果以及优秀系统的速度正在不断加快。
[1] [ Zhang, Y., & Wallace, B. (2015). A Sensitivity Analysis of (and Practitioners’ Guide to) Convolutional Neural Networks for Sentence Classification](http://arxiv.org/abs/1510.03820) [2] [ Kalchbrenner, N., Grefenstette, E., & Blunsom, P. (2014). A Convolutional Neural Network for Modelling Sentences. Acl, 655–665.](http://arxiv.org/abs/1404.2188) [3] [ Kim, Y. (2014). Convolutional Neural Networks for Sentence Classification. Proceedings of the 2014 Conference on Empirical Methods in Natural Language Processing (EMNLP 2014), 1746–1751.](http://arxiv.org/abs/1408.5882) [4] [ Wang, P., Xu, J., Xu, B., Liu, C., Zhang, H., Wang, F., & Hao, H. (2015). Semantic Clustering and Convolutional Neural Network for Short Text Categorization. Proceedings ACL 2015, 352–357.](http://www.aclweb.org/anthology/P15-2058) [5] [ Johnson, R., & Zhang, T. (2015). Effective Use of Word Order for Text Categorization with Convolutional Neural Networks. To Appear: NAACL-2015, (2011).](http://arxiv.org/abs/1412.1058v1) [6] [ Johnson, R., & Zhang, T. (2015). Semi-supervised Convolutional Neural Networks for Text Categorization via Region Embedding.](http://arxiv.org/abs/1504.01255) [7] [ Nguyen, T. H., & Grishman, R. (2015). Relation Extraction: Perspective from Convolutional Neural Networks. Workshop on Vector Modeling for NLP, 39–48.](http://www.cs.nyu.edu/~thien/pubs/vector15.pdf) [8] [ Sun, Y., Lin, L., Tang, D., Yang, N., Ji, Z., & Wang, X. (2015). Modeling Mention , Context and Entity with Neural Networks for Entity Disambiguation, (Ijcai), 1333–1339.](http://ijcai.org/papers15/Papers/IJCAI15-192.pdf) [9] [ Zeng, D., Liu, K., Lai, S., Zhou, G., & Zhao, J. (2014). Relation Classification via Convolutional Deep Neural Network. Coling, (2011), 2335–2344. ](http://www.aclweb.org/anthology/C14-1220) [10] [ Gao, J., Pantel, P., Gamon, M., He, X., & Deng, L. (2014). Modeling Interestingness with Deep Neural Networks.](http://research.microsoft.com/pubs/226584/604_Paper.pdf) [11] [ Shen, Y., He, X., Gao, J., Deng, L., & Mesnil, G. (2014). A Latent Semantic Model with Convolutional-Pooling Structure for Information Retrieval. Proceedings of the 23rd ACM International Conference on Conference on Information and Knowledge Management – CIKM ’14, 101–110. ](http://research.microsoft.com/pubs/226585/cikm2014_cdssm_final.pdf) [12] [ Weston, J., & Adams, K. (2014). T AG S PACE : Semantic Embeddings from Hashtags, 1822–1827.](http://emnlp2014.org/papers/pdf/EMNLP2014194.pdf) [13] [ Santos, C., & Zadrozny, B. (2014). Learning Character-level Representations for Part-of-Speech Tagging. Proceedings of the 31st International Conference on Machine Learning, ICML-14(2011), 1818–1826.](http://jmlr.org/proceedings/papers/v32/santos14.pdf) [14] [ Zhang, X., Zhao, J., & LeCun, Y. (2015). Character-level Convolutional Networks for Text Classification, 1–9.](http://arxiv.org/abs/1509.01626) [15] [ Zhang, X., & LeCun, Y. (2015). Text Understanding from Scratch. arXiv E-Prints, 3, 011102.](http://arxiv.org/abs/1502.01710) [16] [ Kim, Y., Jernite, Y., Sontag, D., & Rush, A. M. (2015). Character-Aware Neural Language Models.](http://arxiv.org/abs/1508.06615)