自然语言处理(NLP):08-02 CNN文本分类论文讲解及TextCNN原理

TextCNN 短文本分类案例分享,学习更多工业界案例:数据分析可视化技术、TextCNN论文原理、词向量技术、tensorboardx效果可视化工具、TextCNN 短文本分类案例分享总结,让大家彻底掌握TextCNN 在文本分类领域应用,有任何问题请留言或者加入交流群:NLP技术交流群 ,让我们一起学习NLP。

自然语言处理(NLP):08 TextCNN在短文本分类应用介绍
自然语言处理(NLP):08-01 数据分析和文本分类效果对比
自然语言处理(NLP):08-02 CNN文本分类论文讲解及TextCNN原理
自然语言处理(NLP):08-03 词向量word2vec
自然语言处理(NLP):08-04 tensorboardx 可视化
自然语言处理(NLP):08-05 TextCNN短文本分类案例分享

CNN论文笔记

Convolutional Neural Networks for Sentence Classification

卷积神经网络的核心思想是捕捉局部特征,对于文本来说,局部特征就是由若干单词组成的滑动窗口,类似于N-gram。卷积神经网络的优势在于能够自动地对N-gram特征进行组合和筛选,获得不同抽象层次的语义信息


模型推导

  • 一个句子是由多个词拼接而成的,如果一个句子有nn个词,且第i个词表示为xix_i,词xix_i通过embedding后表示为k维的向量,即xikx_i\in\Re^k,则一个句子x1:nx_{1:n}nkn*k的矩阵,可以形式化如下:
    X1:n=x1x2xnX_{1:n}=x_1\oplus x_2\oplus \dots \oplus x_n
  • 一个包含hh个的词的词窗口表示为:Xi:i+h1hkX_{i:i+h-1}\in\Re^{hk}
  • 一个filter是大小为hkh*k的矩阵,表示为:WhkW\in\Re^{hk}
  • 通过一个filter作用一个词窗口提取可以提取一个特征cic_i,如下:
    ci=f(WXi:i+h1+b)c_i=f(W \cdot X_{i:i+h-1}+b)其中,bb\in\Re是bias值,ff为**函数如Relu等。
  • 卷积操作:通过一个filter在整个句子上从句首到句尾扫描一遍,提取每个词窗口的特征,可以得到一个特征图(feature map) cnh+1c\in\Re^{n-h+1},表示如下(这里默认不对句子进行padding):
    c=[c1,c2,,cnh+1]c= [c_1, c_2, \dots , c_{n-h+1}]
  • 池化操作:对一个filter提取到的feature map进行max pooling,得到c^\hat{c}\in\Re即:
    c^=max(c)\hat{c}=max(c)
  • 若有mm个filter,则通过一层卷积、一层池化后可以得到一个长度为mm的向量zmz\in\Re^m:
    z=[c^1,c^2,,c^m]z = [\hat{c}_1, \hat{c}_2, \dots, \hat{c}_m]
  • 最后,将向量zz输入到全连接层,得到最终的特征提取向量yy (这里的WW为全连接层的权重,注意与filter进行区分):
    y=Wz+by=W \cdot z+b

优化

词向量

  • 随机初始化 (CNN-rand)

作为一个基础模型,Embedding layer所有words被随机初始化,然后模型整体进行训练。

  • 预训练词向量进行初始化,在训练过程中固定 (CNN-static)

模型使用预训练的word2vec初始化Embedding layer,对于那些在预训练的word2vec没有的单词,随机初始化。然后固定Embedding layer,fine-tune整个网络。

  • 预训练词向量进行初始化,在训练过程中进行微调 (CNN-non-static)

同(2),只是训练的时候,Embedding layer跟随整个网络一起训练

  • 多通道(CNN-multichannel):将固定的预训练词向量和微调的词向量分别当作一个通道(channel),卷积操作同时在这两个通道上进行,可以类比于图像RGB三通道。

Embedding layer有两个channel,一个channel为static,一个为non-static。然后整个网络fine-tune时只有一个channel更新参数。两个channel都是使用预训练的word2vec初始化的。
自然语言处理(NLP):08-02 CNN文本分类论文讲解及TextCNN原理

论文中用于文本分类的卷积神经网络模型架构

http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.703.6858&rep=rep1&type=pdf

正则化

  • Dropout: 对全连接层的输入zz向量进行dropout
    y=W(zr)+by=W \cdot (z \circ r)+b其中rmr\in\Re^mmasking向量(每个维度值非0即1,可以通过伯努利分布随机生成),和向量zz进行元素与元素对应相乘,让rr向量值为0的位置对应的zz向量中的元素值失效(梯度无法更新)。
  • L2-norms: 对L2正则化项增加限制:当正则项W2>s\lVert W \rVert_2 > s时, 令W2=s\lVert W \rVert_2 = s,其中ss为超参数。

实验及讨论

实验设置

  • Activation function(ff): rectified linear units (ReLu)
  • Filter windows(hh): 3,4,5 with 100 feature maps each
  • Dropout rate(pp): 0.5
  • L2 constraint(ss): 3
  • Mini-batch size: 50
  • Dev set: randomly select 10% of the train data (for datasets without a standard dev set)
  • Optimizer: stochastic gradient descent(SGD) over shuffled mini-batches with the Adadelta update rule
  • Pre-trained words : word2vec vectors from Google News

实验结果

自然语言处理(NLP):08-02 CNN文本分类论文讲解及TextCNN原理

  • SST-1: Paragraph-Vec (Le and Mikolov, 2014), 48.7
  • Subj : MNB (Wang and Manning, 2012) F-Dropout (Wang and Manning, 2013), 93.6
  • TREC: SVMS (Silva et al., 2011) 95.6

讨论

  • Multichannel vs. Single Channel Models: 虽然作者一开始认为多通道可以预防过拟合,从而应该表现更高,尤其是在小规模数据集上。但事实是,单通道在一些语料上比多通道更好;
  • Static vs. Non-static Representations: 在大部分的语料上,CNN-non-static都优于CNN-static,一个解释:预训练词向量可能认为‘good’和‘bad’类似(可能它们有许多类似的上下文),但是对于情感分析任务,good和bad应该要有明显的区分,如果使用CNN-static就无法做调整了;
  • Dropout可以提高2%–4%性能(performance);
  • 对于不在预训练的word2vec中的词,使用均匀分布U[a,a]U[-a,a]随机初始化,并且调整aa使得随机初始化的词向量和预训练的词向量保持相近的方差,可以有微弱提升;
  • 可以尝试其他的词向量预训练语料,如Wikipedia[Collobert et al. (2011)]
  • Adadelta(Zeiler, 2012)和Adagrad(Duchi et al., 2011)可以得到相近的结果,但是所需epoch更少。

进一步思考

TextCNN整体架构

TextCNN架构的论文

《A Sensitivity Analysis of (and Practitioners’ Guide to) Convolutional Neural Networks for Sentence Classification》

https://arxiv.org/pdf/1510.03820.pdf

用于文本分类任务的TextCNN结构描述 这里详细解释TextCNN架构及词向量矩阵是如何做卷积的
自然语言处理(NLP):08-02 CNN文本分类论文讲解及TextCNN原理

如果TextCNN卷积核宽度为2、3、4,每种卷积核的个数为2的话,那么它长这个样:

可以参考: https://pytorch.org/docs/stable/nn.html#conv1d

TextCNN工作机制

卷积窗口沿着长度为n的文本一个个滑动,类似于n-gram机制对文本切词,然后和文本中的每个词进行相似度计算,因为后面接了个Max-pooling,因此只会保留和卷积核最相近的词。这就是TextCNN抓取关键词的机制。

若CNN前面加一层LSTM,效果相对不错。

TextCNN 工作过程

https://zhuanlan.zhihu.com/p/77634533

  • 第一层为输入层。

输入层是一个 [公式] 的矩阵,其中 [公式] 为一个句子中的单词数, [公式] 是每个词对应的词向量的维度。也就是说,输入层的每一行就是一个单词所对应的 [公式] 维的词向量。另外,这里为了使向量长度一致对原句子进行了padding操作。我们这里使用 [公式] 表示句子中第 [公式] 个单词的 [公式] 维词嵌入。

每个词向量可以是预先在其他语料库中训练好的,也可以作为未知的参数由网络训练得到。这两种方法各有优势,预先训练的词嵌入可以利用其他语料库得到更多的先验知识,而由当前网络训练的词向量能够更好地抓住与当前任务相关联的特征。因此,图中的输入层实际采用了双通道的形式,即有两个 [公式] 的输入矩阵,其中一个用预训练好的词嵌入表达,并且在训练过程中不再发生变化;另外一个也由同样的方式初始化,但是会作为参数,随着网络的训练过程发生改变。

  • 第二层为卷积层,第三层为池化层。

首先,我们要注意到卷积操作在计算机视觉(CV)和NLP中的不同之处。在CV中,卷积核往往都是正方形的,比如 [公式] 的卷积核,然后卷积核在整张image上沿高和宽按步长移动进行卷积操作。与CV中不同的是,在NLP中输入层的"image"是一个由词向量拼成的词矩阵,且卷积核的宽和该词矩阵的宽相同,该宽度即为词向量大小,且卷积核只会在高度方向移动。因此,每次卷积核滑动过的位置都是完整的单词,不会将几个单词的一部分"vector"进行卷积,词矩阵的行表示离散的符号(也就是单词)[2],这就保证了word作为语言中最小粒度的合理性(当然,如果研究的粒度是character-level而不是word-level,需要另外的方式处理)。

然后,我们详述这个卷积、池化过程。由于卷积核和word embedding的宽度一致,一个卷积核对于一个sentence,卷积后得到的结果是一个vector,其shape=(sentence_len - filter_window_size + 1, 1),那么,在经过max-pooling操作后得到的就是一个Scalar。我们会使用多个filter_window_size(原因是,这样不同的kernel可以获取不同范围内词的关系,获得的是纵向的差异信息,即类似于n-gram,也就是在一个句子中不同范围的词出现会带来什么信息。比如可以使用3,4,5个词数分别作为卷积核的大小),每个filter_window_size又有num_filters个卷积核(原因是卷积神经网络学习的是卷积核中的参数,每个filter都有自己的关注点,这样多个卷积核就能学习到多个不同的信息。[2]中也提到使用多个相同size的filter是为了从同一个窗口学习相互之间互补的特征。比如可以设置size为3的filter有64个卷积核)。一个卷积核经过卷积操作只能得到一个scalar,将相同filter_window_size卷积出来的num_filter个scalar组合在一起,组成这个filter_window_size下的feature_vector。最后再将所有filter_window_size下的feature_vector也组合成一个single vector,作为最后一层softmax的输入

TextCNN 代码过程

整个过程在后续的项目实战实战内容都会讲解。

数据处理:所有句子padding成一个长度:seq_len

1.模型输入:
[batch_size, seq_len]

2.经过embedding层:加载预训练词向量或者随机初始化, 词向量维度为embed_size:
[batch_size, seq_len, embed_size]

3.卷积层:NLP中卷积核宽度与embed-size相同,相当于一维卷积。

3个尺寸的卷积核:(2, 3, 4),每个尺寸的卷积核有256个。卷积后得到三个特征图:

seq_len - filter_size + 1 ,其中 filter_size 每个数值分别为2,3,4

[batch_size, 256, seq_len - 2 + 1]

[batch_size, 256, seq_len - 3 + 1]

[batch_size, 256, seq_len - 4 + 1]

4.池化层:对三个特征图做最大池化

其中256 = kernal_size(卷积核个数 )
[batch_size, 256]

[batch_size, 256]

[batch_size, 256]

5.拼接:
[batch_size, 256*3]

6.全连接:num_class是预测的类别数
[batch_size, num_class]

7.预测:softmax归一化,将num_class个数中最大的数对应的类作为最终预测
[batch_size, 1]

分析:
卷积操作相当于提取了句中的2-gram,3-gram,4-gram信息,多个卷积是为了提取多种特征,最大池化将提取到最重要的信息保留。

总结

(1)使用预训练的word2vec 、 GloVe初始化效果会更好。一般不直接使用One-hot。

(2)卷积核的大小影响较大,一般取1~10,对于句子较长的文本,则应选择大一些。

(3)卷积核的数量也有较大的影响,一般取100~600 ,同时一般使用Dropout(0~0.5)。

(4)**函数一般选用ReLU 和 tanh。

(5)池化使用1-max pooling。

(6)随着feature map数量增加,性能减少时,试着尝试大于0.5的Dropout。

(7)评估模型性能时,记得使用交叉验证。

摘自:https://github.com/llhthinker/NLP-Papers/blob/master/text%20classification/2017-10/Convolutional%20Neural%20Networks%20for%20Sentence%20Classification/note.md