本章旨在使用TensorFlow API实现卷积神经网络文本分类。
代码地址:Github
转载请注明出处:Gaussic - 写干净的代码
基于CNN的文本分类问题已经有了一定的研究成果,CNN做句子分类的论文可以参看: Convolutional Neural Networks for Sentence Classification。
以及字符级CNN的论文:Character-level Convolutional Networks for Text Classification。
在网上也有了一些开源的实现,例如比较著名的dennybritz大牛的博客Implementing a CNN for Text Classification in TensorFlow基于早期TensorFlow的一个实现版本。
如今,TensorFlow大版本已经升级到了1.3,对很多的网络层实现了更高层次的封装和实现,甚至还整合了如Keras这样优秀的一些高层次框架,使得其易用性大大提升。相比早起的底层代码,如今的实现更加简洁和优雅。
本章的目的是基于TensorFlow的API来重新实现一个在中文文本上的分类器。如果你觉得对你有些许帮助或者疑惑,欢迎star和交流。
数据集
本文采用了清华NLP组提供的THUCNews新闻文本分类数据集的一个子集(原始的数据集大约74万篇文档,训练起来需要花较长的时间)。数据集请自行到THUCTC:一个高效的中文文本分类工具包下载,请遵循数据提供方的开源协议。
本次训练使用了其中的10个分类,每个分类6500条,总共65000条新闻数据。
类别如下:
体育, 财经, 房产, 家居, 教育, 科技, 时尚, 时政, 游戏, 娱乐
数据集划分如下:
- 训练集: 5000*10
- 验证集: 500*10
- 测试集: 1000*10
从原数据集生成子集的过程请参看helper
下的两个脚本。其中,copy_data.sh
用于从每个分类拷贝6500个文件,cnews_group.py
用于将多个文件整合到一个文件中。执行该文件后,得到三个数据文件:
- cnews.train.txt: 训练集(50000条)
- cnews.val.txt: 验证集(5000条)
- cnews.test.txt: 测试集(10000条)
预处理
data/cnews_loader.py
为数据的预处理文件。
read_file()
: 读取文件数据;build_vocab()
: 构建词汇表,使用字符级的表示,这一函数会将词汇表存储下来,避免每一次重复处理;read_vocab()
: 读取上一步存储的词汇表,转换为{词:id}
表示;read_category()
: 将分类目录固定,转换为{类别: id}
表示;to_words()
: 将一条由id表示的数据重新转换为文字;preocess_file()
: 将数据集从文字转换为固定长度的id序列表示;batch_iter()
: 为神经网络的训练准备经过shuffle的批次的数据。
经过数据预处理,数据的格式如下:
Data | Shape | Data | Shape |
---|---|---|---|
x_train | [50000, 600] | y_train | [50000, 10] |
x_val | [5000, 600] | y_val | [5000, 10] |
x_test | [10000, 600] | y_test | [10000, 10] |
CNN卷积神经网络
配置项
CNN可配置的参数如下所示,在cnn_model.py
中。
class TCNNConfig(object):
"""CNN配置参数"""
embedding_dim = 64 # 词向量维度
seq_length = 600 # 序列长度
num_classes = 10 # 类别数
num_filters = 128 # 卷积核数目
kernel_size = 5 # 卷积核尺寸
vocab_size = 5000