文本分类系列2-textCNN

paper reading

主要框架和使用CNN进行文本分类的意图参考paper: Convolutional Neural Networks for Sentence Classification 可参考cs224d中的课堂笔记,这堂课就是讲的这篇paper: cs224d-lecture13 卷积神经网络

TextCNN详细过程: - 第一层是图中最左边的7乘5的句子矩阵,每行是词向量,维度=5,这个可以类比为图像中的原始像素点了,然后在图像中图像的表示是[length, width, channel],这里将文本的表示[sequence_len, embed_size, 1]。可以看到下面代码中:

1
2
3
embeded_words = tf.nn.embedding_lookup(self.embedding, self.input_x) # [None, sentence_len, embed_size]
# three channels similar to the image. using the tf.nn.conv2d
self.sentence_embedding_expanded = tf.expand_dims(embeded_words, axis=-1) # [None, sentence_len, embed_size, 1]

  • 然后经过有 filter_size=(2,3,4) 的一维卷积层,每个filter_size 有两个输出 channel。上图中的filter有3个,分别为:
  • filter:[2, 5, 2] ==> feature map:[6,1,2]
  • filter:[3, 5, 2] ==> feature map:[5,1,2]
  • filter:[4, 5, 2] ==> feature map:[4,1,2]
  • 第三维表示channels,卷积后得到两个feature maps.

  • 第三层是一个1-max pooling层,这样不同长度句子经过pooling层之后都能变成scale,这里每个fiter_size的channel为2,所以输入的pooling.shape=[batch_size,1,1,2], 然后concat为一个flatten向量。

  • 最后接一层全连接的 softmax 层,输出每个类别的概率。

特征:这里的特征就是词向量,有静态(static)和非静态(non-static)方式。static方式采用比如word2vec预训练的词向量,训练过程不更新词向量,实质上属于迁移学习了,特别是数据量比较小的情况下,采用静态的词向量往往效果不错。non-static则是在训练过程中更新词向量。推荐的方式是 non-static 中的 fine-tunning方式,它是以预训练(pre-train)的word2vec向量初始化词向量,训练过程中调整词向量,能加速收敛,当然如果有充足的训练数据和资源,直接随机初始化词向量效果也是可以的。

通道(Channels):图像中可以利用 (R, G, B) 作为不同channel,而文本的输入的channel通常是不同方式的embedding方式(比如 word2vec或Glove),实践中也有利用静态词向量和fine-tunning词向量作为不同channel的做法。下面代码中的通道为1.

一维卷积(conv-1d):图像是二维数据,经过词向量表达的文本为一维数据,因此在TextCNN卷积用的是一维卷积。一维卷积带来的问题是需要设计通过不同 filter_size 的 filter 获取不同宽度的视野。

Pooling层:利用CNN解决文本分类问题的文章还是很多的,比如这篇 A Convolutional Neural Network for Modelling Sentences 最有意思的输入是在 pooling 改成 (dynamic) k-max pooling ,pooling阶段保留 k 个最大的信息,保留了全局的序列信息。比如在情感分析场景,举个例子:

        “ 我觉得这个地方景色还不错,但是人也实在太多了 ”

虽然前半部分体现情感是正向的,全局文本表达的是偏负面的情感,利用 k-max pooling能够很好捕捉这类信息。

代码实现

参数设置和模型具体实现参考paper: A Sensitivity Analysis of (and Practitioners' Guide to) Convolutional Neural Networks for Sentence Classification

设计一个模型需要考虑的:
- input word vector representations 输入的词向量表示
- filter region size(s); 卷积核的大小
- the number of feature maps; 特征图的通道数
- the activation function 激活函数
- the pooling strategy 池化的方式
- regularization terms (dropout/l2) 正则化项(dropout/l2)

需要注意的问题

一个单本对应单个标签和多个标签的区别?

关于多标签分类,应该看看周志华老师的这篇文章A Review on Multi-Label Learning Algorithms, 知乎上还有其他资料多标签(multi-label)数据的学习问题,常用的分类器或者分类策略有哪些?

本文代码中的方法:

  • 真实值labels的输入:单个标签的真实值是

    1
    2
    3
    4

    ```python
    self.input_y = tf.placeholder(dtype=tf.int32, shape=[None], name='input_y')
    self.input_y_multilabels = tf.placeholder(dtype=tf.float32, shape=[None, num_classes], name="input_y_multilabels")

  • 损失函数的选择:

  • 评价指标的区别: