卷积神经网络(CNN)最开始是用于计算机视觉中,然而现在也被广泛用于自然语言处理中,而且有着不亚于RNN(循环神经网络)的性能。
1、传统的自然语言处理模型
1)传统的词袋模型或者连续词袋模型(CBOW)都可以通过构建一个全连接的神经网络对句子进行情感标签的分类,但是这样存在一个问题,我们通过激活函数可以让某些结点激活(例如一个句子里”not”,”hate”这样的较强的特征词),但是由于在这样网络构建里,句子中词语的顺序被忽略,也许同样两个句子都出现了not和hate但是一个句子(I do not hate this movie)表示的是good的情感,另一个句子(I hate this movie and will not choose it)表示的是bad的情感。其实很重要的一点是在刚才上述模型中我们无法捕获像not hate这样由连续两个词所构成的关键特征的词的含义。
2)在语言模型里n-gram模型是可以用来解决上面的问题的,想法其实就是将连续的两个词作为一个整体纳入到模型中,这样确实能够解决我们刚才提出的问题,加入bi-gram,tri-gram可以让我们捕捉到例如“don’t love”,“not the best”。但是新的问题又来了,如果我们使用多元模型,实际训练时的参数是一个非常大的问题,因为假设你有20000个词,加入bi-gram实际上你就要有400000000个词,这样参数训练显然是爆炸的。另外一点,相似的词语在这样的模型中不能共享例如参数权重等,这样就会导致相似词无法获得交互信息。
2、自然语言处理中的卷积神经网络
在图像中卷积核通常是对图像的一小块区域进行计算,而在文本中,一句话所构成的词向量作为输入。每一行代表一个词的词向量,所以在处理文本时,卷积核通常覆盖上下几行的词,所以此时卷积核的宽度与输入的宽度相同,通过这样的方式,我们就能够捕捉到多个连续词之间的特征(只要通过设置卷积核的尺寸,卷积核的宽度一般和词向量的长度一致,长度可以去1,2,3这类的值,当取3时就会将3个连续词的特征表示出来),并且能够在同一类特征计算时中共享权重。如下图所示
如上图所示,不同长度的卷积核,会获得不同长度的输出值,但在之后的池化中又会得到相同的长度(比如上面的深红色的卷积核是4 × 5,对于输入值为7 × 5的输入值,卷积之后的输出值就是4 × 1,最大池化之后就是1 × 1;深绿色的卷积核是3 × 5,卷积之后的输出值是5 × 1,最大池化之后就是1 × 1),最后将所有池化后的值组合在一起,这样有一点好处,无论输入值的大小是否相同(输入值行一般不相等,对于输入值列是词向量的长度,一般都是相等,但是行是和文本中词的数量相关的),要用相同数量的卷积核进行卷积,之后再池化就会获得相同长度的向量(向量的长度和卷积核的数量相等),这样再之后就可以用全连接层了(全连接层的输入值的向量大小必须是一致的)。
3、卷积层的最大池化问题
MaxPooling Over Time是NLP中CNN模型中最常见的一种下采样操作。意思是对于某个Filter抽取到若干特征值,只取其中得分最大的那个值作为Pooling层保留值,其它特征值全部抛弃,值最大代表只保留这些特征中最强的,而抛弃其它弱的此类特征(正如上图所示的那样)。
CNN中采用Max Pooling操作有几个好处:
1)这个操作可以保证特征的位置与旋转不变性,因为不论这个强特征在哪个位置出现,都会不考虑其出现位置而能把它提出来。对于图像处理来说这种位置与旋转不变性是很好的特性,但是对于NLP来说,这个特性其实并不一定是好事,因为在很多NLP的应用场合,特征的出现位置信息是很重要的,比如主语出现位置一般在句子头,宾语一般出现在句子尾等等,这些位置信息其实有时候对于分类任务来说还是很重要的,但是Max Pooling 基本把这些信息抛掉了。
2)MaxPooling能减少模型参数数量,有利于减少模型过拟合问题。因为经过Pooling操作后,往往把2D(图像中)或者1D(自然语言中)的数组转换为单一数值,这样对于后续的Convolution层或者全联接隐层来说无疑单个Filter的参数或者隐层神经元个数就减少了。
3)对于NLP任务来说,Max Pooling有个额外的好处;在此处,可以把变长的输入X整理成固定长度的输入。因为CNN最后往往会接全联接层,而其神经元个数是需要事先定好的,如果输入是不定长的那么很难设计网络结构。
但是,CNN模型采取MaxPooling Over Time也有一些值得注意的缺点:首先就如上所述,特征的位置信息在这一步骤完全丢失。在卷积层其实是保留了特征的位置信息的,但是通过取唯一的最大值,现在在Pooling层只知道这个最大值是多少,但是其出现位置信息并没有保留;另外一个明显的缺点是:有时候有些强特征会出现多次,比如我们常见的TF.IDF公式,TF就是指某个特征出现的次数,出现次数越多说明这个特征越强,但是因为Max Pooling只保留一个最大值,所以即使某个特征出现多次,现在也只能看到一次,就是说同一特征的强度信息丢失了。这是Max Pooling Over Time典型的两个缺点。
针对上面提出的两个缺点,通常的解决办法是下面两种池化方法
K-Max Pooling
K-MaxPooling的核心思想是:原先的Max Pooling Over Time从Convolution层一系列特征值中只取最强的那个值,K-Max Pooling可以取所有特征值中得分在Top –K的值,并保留这些特征值原始的先后顺序,就是说通过多保留一些特征信息供后续阶段使用。如下图所示
很明显,K-Max Pooling可以表达同一类特征出现多次的情形,即可以表达某类特征的强度;另外,因为这些Top K特征值的相对顺序得以保留,所以应该说其保留了部分位置信息,但是这种位置信息只是特征间的相对顺序,而非绝对位置信息。
Chunk-Max Pooling
Chunk-MaxPooling的核心思想是:把某个Filter对应的Convolution层的所有特征向量进行分段,切割成若干段后,在每个分段里面各自取得一个最大特征值,比如将某个Filter的特征向量切成3个Chunk,那么就在每个Chunk里面取一个最大值,于是获得3个特征值。如下图所示,不同颜色代表不同段
Chunk-Max Pooling思路类似于K-Max Pooling,因为它也是从Convolution层取出了K个特征值,但是两者的主要区别是:K-Max Pooling是一种全局取Top K特征的操作方式,而Chunk-Max Pooling则是先分段,在分段内包含特征数据里面取最大值,所以其实是一种局部Top K的特征抽取方式。
至于这个Chunk怎么划分,可以有不同的做法,比如可以事先设定好段落个数,这是一种静态划分Chunk的思路;也可以根据输入的不同动态地划分Chunk间的边界位置,可以称之为动态Chunk-Max方法。事实上对于K-Max Pooling也有动态的去获取K的值的方法,表达式如下
s代表的是句子长度,L代表总的卷积层的个数,l代表的是当前是在几个卷积层,所以可以看出这里的k是随着句子的长度和网络深度而改变。
Chunk-Max Pooling很明显也是保留了多个局部Max特征值的相对顺序信息,尽管并没有保留绝对位置信息,但是因为是先划分Chunk再分别取Max值的,所以保留了比较粗粒度的模糊的位置信息;当然,如果多次出现强特征,则也可以捕获特征强度。
如果分类所需要的关键特征的位置信息很重要,那么类似Chunk-Max Pooling这种能够粗粒度保留位置信息的机制应该能够对分类性能有一定程度的提升作用;但是对于很多分类问题,估计Max-Pooling over time就足够了。
4、卷积神经网络在自然语言处理中的应用
最适合CNNs的莫过于分类任务,如语义分析、垃圾邮件检测和话题分类。卷积运算和池化会丢失局部区域某些单词的顺序信息,因此纯CNN的结构框架不太适用于PoS Tagging和Entity Extraction等顺序标签任务。
参考文献:
https://blog.csdn.net/malefactor/article/details/51078135
https://blog.csdn.net/qq_40027052/article/details/78331816
https://blog.csdn.net/qq_21460525/article/details/62216395
https://blog.csdn.net/zdy0_2004/article/details/49824319