神经网络在文本分类中的应用

在自然语言的文本分类中,主要使用两类模型,一类是使用传统的机器学习模型,如朴素贝叶斯,最大熵,支持向量机等,第二类就是使用神经网络模型,包括CNN和RNN。传统的机器模型在分类前首先要做特征工程,例如把文本转换成词袋,并转化为TF-IDF矩阵,然后再做分类。而使用神经网络模型可以使它自己提取特征并进行文本分类,并能获得优于传统机器学习模型的能力。

CNN模型的文本分类

CNN原来是用于对图像分类,后来按照其形式用到了对自然语言处理上,处理原理相同,首先是对句子的每一个词生成一个实值的词向量,然后按照句子合并成一个词向量矩阵,这个词向量矩阵就相当于一个图像的像素,剩下的就如同图像处理一样,使用卷积核进行卷积以及进行池化等。 
Kim使用了CNN对句子进行分类。具体模型形式如下: 
这里写图片描述

让xi∈Rkxi∈Rk为一个句子中第ii个单词的词向量,向量维度为kk,句子的长度为nn,则整个句子的向量为: 

x1:n=x1⊕x2⊕⋯⊕xn(1)(1)x1:n=x1⊕x2⊕⋯⊕xn


其中,⊕⊕为连接算子,则x1:nx1:n的维度为nknk。 
让xi:i+jxi:i+j为词向量xi,xi+1,⋯,xi+jxi,xi+1,⋯,xi+j的连接,卷积核为w∈Rhkw∈Rhk,其中,hh为卷积的窗口大小,则从窗口中的词向量产生的特征cici为: 

ci=f(w⋅xi:i+h+b)(2)(2)ci=f(w⋅xi:i+h+b)


其中,b∈Rb∈R为偏置,ff为非线性函数,例如tanhtanh等。然后,卷积核应用于句子的每个可能的窗口{x1:h,x2:h+1,⋯,xn−h+1:n}{x1:h,x2:h+1,⋯,xn−h+1:n},产生一个特征图: 

c=[c1,c2,⋯,cn−h+1](3)(3)c=[c1,c2,⋯,cn−h+1]


其中,c∈Rn−h+1c∈Rn−h+1。然后对特征图进行最大池化操作来获取最重要的特征c^=max{c}c^=max{c} 
为了获取多个特征可以使用多个卷积核。Kim使用了2个通道,每个通道用2个卷积核,这样共生成4个特征图。这两个通道中,一个是在训练中保持不变,即词向量是不变的,另一个通道在训练中通过后向传播对词向量进行修正。 
Kim对最大池化层进行了dropout正则化,假设得到的最大池化层为z=[c^1,⋯,c^m]z=[c^1,⋯,c^m],则前向传播中,dropout使用: 

y=w⋅(z∘r)+b(4)(4)y=w⋅(z∘r)+b


其中,∘∘为按元素乘积,r∈Rmr∈Rm为以概率pp为1的Bernnoulli随机变量,此向量又被称为“遮盖向量”,也就是在梯度后向传播中不经过这些遮盖住的单元。在测试的时候,学习权重变为w^=pww^=pw,这个w^w^用于预测新的句子 。Kim又对ww做了约束为||w||2=s||w||2=s,即在梯度下降中,当||w||2>s||w||2>s时把||w||2||w||2设置为ss。 
一些技巧:

  • 使用多个卷积核以获取多个特征
  • 使用dropout
  • 使用word2vec初始化词向量(也可以使用GloVe)
  • 梯度下降使用Adadelta或Adagrad(两个相差不大)

另一个具有相似的CNN模型是Zhang提出的。仍然是先把句子转化成单词向量组成的句子矩阵,每一行为一个词向量,可由word2vec或GloVe训练出,维度为dd,则句子矩阵的维度为s×ds×d 
与Kim不太一样的是,Zhang并没有把句子转化为一个向量,而是仍然按照句子矩阵的形式排列,这样就相当于一个图像,由于每一行代表一个离散的特征,所以在选卷积核的时候,对应核的长度就是这个词向量的维度dd,而核的高度(region size)可由自己确定。假设卷积核ww的高度为hh,则ww的维度为h×dh×d。句子矩阵为A∈Rs×dA∈Rs×d,用A[i:j]A[i:j]表示行ii至行jj,则经过卷积之后的输出为: 

oi=Σ(w⊕A[i:i+h−1])(5)(5)oi=Σ(w⊕A[i:i+h−1])


即矩阵对应元素乘积再求和。而整个卷积后输出序列为o=[o1,⋯,os−h+1]o=[o1,⋯,os−h+1]。 
然后做了个变换,即: 

ci=f(oi+b)(6)(6)ci=f(oi+b)


得到特征图c=[c1,⋯,cs−h+1]c=[c1,⋯,cs−h+1],然后再进行最大池化操作,具体可看下图: 
这里写图片描述 
Zhang使用了3个卷积宽度(region size),分别是(2,3,4),每个region size使用了2个不同的卷积核,总共6个卷积核,然后用这些卷积核对句子矩阵做卷积得到6个特征图,然后对每个region size中的2个特征图分别取最大值,即做最大池化操作,再然后把每个region size中最大池化操作后的值拼接起来,再然后把不同的region size中拼接后的值再拼接起来,最后使用softmax函数进行分类。这样的CNN可以处理不同句子长度以及不同region size的情况。 
经验技巧:

  • 词向量初始化很重要(word2vec或GloVe初始化)
  • 卷积核高度对结果有影响
  • 卷积核的个数对模型有较大影响,应多试几个
  • 最大池化操作比其他池化操作要好
  • 考虑不同的激活函数(这个是在卷积层后的那一步非线性转换)
  • 考虑正则化(如dropout)
  • 考虑方差(可以使用cross validation)

Kalchbrenner提出了另一种动态卷积神经网络(DCNN),主要的变化是在最大池化层,最大池化层使用的是Dynamic k-max-pooling,另外又加了一个folding层,这样能捕获相邻行的特征,具体可看A Convolutional Neural Network for Modelling Sentences

RNN模型的文本分类

Lai使用了一种RNN模型进行文本分类,这个模型结构比较奇葩,一共分为三层,首先使用的是类似双向RNN的结构当做卷积层,第二层为最大池化层,最后一层是输出层,具体如下。 
使用cl(wi)cl(wi)表示单词wiwi的左边的上下文,使用cr(wi)cr(wi)表示wiwi的右边的上下文,当然cl(wi)cl(wi)和cr(wi)cr(wi)都是实值向量,维度为|c||c|。单词wiwi左边和右边的上下文向量分别有下式计算: 

cl(wi)=f(W(l)cl(wi−1)+W(sl)e(wi−1))(1)(1)cl(wi)=f(W(l)cl(wi−1)+W(sl)e(wi−1))

cr(wi)=f(W(l)cr(wi+1)+W(sr)e(wi+1))(2)(2)cr(wi)=f(W(l)cr(wi+1)+W(sr)e(wi+1))


其中,e(wi)e(wi)表示第ii个词的词向量,W(l)W(l)为从一个隐藏层(上下文)到下一个隐藏层的参数矩阵,W^{(sl)}为当前词与左边上下文的参数矩阵,ff诶非线性激活函数,对于cr(wi)cr(wi)类似。第一个单词的左边上下文默认为cl(w1)cl(w1),对于最后一个单词的右边上下文默认为cr(wn)cr(wn)。 
那么,现在wiwi的词向量可以表示为左右上下文和原来词向量的连接,即xi=[cl(wi);e(wi);cr(wi)]xi=[cl(wi);e(wi);cr(wi)]而不是e(wi)e(wi)了。然后再进行一个非线性转换: 

y(2)i=tanh(W(2)xi+b(2))(3)(3)yi(2)=tanh(W(2)xi+b(2))


这个y(2)iyi(2)称为潜在语义向量。 
那么这整个的就算做第一层了,可以见下图: 
这里写图片描述

接着第二层,使用了一个最大池化层: 

y(3)=maxni=1y(2)i(4)(4)y(3)=maxi=1nyi(2)


即y(3)y(3)的第kk个元素为y(2)iyi(2)的第kk个元素的最大值。 
最后,输出层为: 

y(4)=W(4)y(3)+b(4)(5)(5)y(4)=W(4)y(3)+b(4)


把输出转化为概率: 

pi=exp(y(4)i)Σnk=1exp(y(4)k)(6)(6)pi=exp(yi(4))Σk=1nexp(yk(4))

添加注意力向量

另一种文本分类中,是使用注意力机制来捕获相关特征。我在神经网络机器翻译总结中详细说明了注意力机制的内容。Yang等人就是使用了双向GRU+注意力机制来进行文本分类的。这个模型主要分两大块:一是单词编码,在句子水平上获得词注意力向量;二是句子编码,在文档水平上获得句子注意力向量。最后解码输出,图示如下: 
这里写图片描述

首先来看单词编码。假设一个文档中第ii个句子中的单词为wit,t∈[0,T]wit,t∈[0,T],它的词向量为xijxij。然后把它输入到双向GRU: 

h→it=GRU−→−−(xit),t∈[1,T],h←it=GRU←−−−(xit),t∈[T,1]h→it=GRU→(xit),t∈[1,T],h←it=GRU←(xit),t∈[T,1]


然后把得到的h→it,h←ith→it,h←it拼接起来就得到单词witwit的annotationhit=[h→it,h←it]hit=[h→it,h←it],这样就能得到整个句子的信息。 
在加入attention的时候与Bahdanau一样: 

uit=tanh(Wwhit+bw)αit=exp(u′ituw)Σtexp(u′ituw)si=Σtαithit(6)(6)uit=tanh(Wwhit+bw)αit=exp(uit′uw)Σtexp(uit′uw)si=Σtαithit

上面三个式子中,首先对hithit进行非线性变换得到它的隐藏表达uituit,然后计算uituit与上下文向量uwuw(随机初始化的,后期要训练)的相似性并标准化得到annotation的权重αitαit,最后计算句子向量sisi。至此,句子的解析就结束了,下一部分是句子的编码。 
仍然是相同的操作,使用双向GRU编码句子,只是这里的输入为sisi: 

h→i=GRU−→−−(si),i∈[1,L],h←i=GRU←−−−(si),t∈[L,1]h→i=GRU→(si),i∈[1,L],h←i=GRU←(si),t∈[L,1]


其中,LL为某个文档中句子的个数。然后拼接起来作为第ii个句子的annotationhi=[h→i,h←i]hi=[h→i,h←i],那么hihi就综合了该句子上下文句子的信息。 
然后加入句子的attention: 

ui=tanh(Wshi+bs)αi=u′ius)Σiexp(u′ius)v=Σiαihi(7)(7)ui=tanh(Wshi+bs)αi=ui′us)Σiexp(ui′us)v=Σiαihi


意义与解析单词编码的一样。这个vv就表示了该文档的文档向量。 
最后一步就是对文档进行分类: 

p=softmax(Wcv+bc)(8)(8)p=softmax(Wcv+bc)


用对数似然函数作为损失函数: 

L=−ΣdlogpdjL=−Σdlogpdj


其中,dd为文档个数,jj为文档dd的标签。

使用多任务学习分类

Liu使用了多任务学习方法进行文本分类,文章中共使用三种模型结构。 
这里写图片描述 
第一种是单层的结构,以两个任务为例,使用了共享向量x(s)ixi(s),把各个任务的输入向量与共享向量拼接在一起,通过共同的RNN隐藏层来达到学习不同分类的目的。 
这里写图片描述 
第二种是双层结构,它没有使用一个共享向量x(s)ixi(s),而是每个任务有各自隐藏层,但是他们的隐藏层之间有交叉,即你可以用我的,我也可以用你的,最后得到不同的分类。 
 
第三种是共享层结构,这个结构是在第二种结构上又加了一个双向RNN,这个双向RNN的输入是两个不同任务的输入向量,而双向RNN的输出是两个不同任务的输入,从而达到信息共享的效果。具体内容可以参考Liu的论文。 
参考文献 
【Yoon Kim】Convolutional Neural Networks for Sentence Classification 
【Ye Zhang, Byron C. Wallace】A Sensitivity Analysis of (and Practitioners’ Guide to) Convolutional Neural Networks for Sentence Classification 
【Nal Kalchbrenner, Edward Grefenstette, Phil Blunsom】A Convolutional Neural Network for Modelling Sentences 
【Siwei Lai, Liheng Xu, Kang Liu, Jun Zhao】Recurrent Convolutional Neural Networks for Text Classification 
【Zichao Yang, Diyi Yang, Chris Dyer et al】Hierarchical Attention Networks for Document Classification 
【Dzmitry Bahdanau, KyungHyun Cho, Yoshua Bengio】NEURAL MACHINE TRANSLATION BY JOINTLY LEARNING TO ALIGN AND TRANSLATE 
【Pengfei Liu, Xipeng Qiu, Xuanjing Huang】Recurrent Neural Network for Text Classification with Multi-Task Learning

猜你喜欢

转载自blog.csdn.net/qq_30263737/article/details/81407528