Fork me on GitHub

pytorch实现自己的textCNN

对于初学深度学习的人来说,直接上手NLP的梯度较大。

首先,理解词向量就有一定的困难。关于词向量的的详细描述,可以参考《word2vec Parameter Learning Explained》的解释。一个100列的词向量可以简单理解为有100个特征(feature)的向量,如同一个人有100个特征一样,这100个特征“完备”的描述了这个人的所有性质。

简单理解了词向量之后,作为初学者,肯定想自己训练一个自己的词向量,以加深理解。作为一个工程师,如何验证自己的正确性是在开始编码之前就需要考虑的。于是,我们把眼光瞄向了已经实现word2vec的第三方库中...

 python的gensim库了解一下...作为搞NLP的人这个库必须知道,我们这里用它来生成词向量。然后,接下来我们要处理中文,不可避免的需要进行中文分词,这里我们选择了jieba分词(不是jiba)。然后是我们实验需要使用的数据集,要做文本分类,这里我们找到的一个还不错的数据集:thucnews, 大家可以在网上自行搜索;为了方便大家测试使用,这里给出我使用的下载链接:  提取码: aqkg

这个数据集有14个类别,每个类别是一个文件夹,每个文件夹中包含了许多txt文件,每个txt文件是一段对应类别的新闻描述。接下来要做的,是利用数据集生成我们自己的第一份词向量。其次,利用词向量和数据集进行textCNN的训练,在这个过程中,我们将会不断的犯错,在错误中学习。

源码参考:https://github.com/webbery/NLPToolset

1. 生成词向量

wv_thucnews.py代码的主要功能是遍历所有文件,对所有的文本创建对应的标签列表,以及文本列表,这两个列表是一一对应的;此外,在遍历的同时还对所有文本进行了分词操作。

gensim库提供了LineSentence类,这个类支持从文本中读取所有的句子。它对文本的格式要求是这样的,它把每一行当成一个句子,并把所有的句子做成list返回。因此,如果要使用LineSentence,我们就需要按照这个格式来制作它的输入文件。

zh.seg.txt存储的格式如下图所示,该文件即作为LineSentence的输入。在设置好数据集的路径之后,运行to_vector.py,第一个参数是已经分词完毕的输入数据,这里即zh.seg.txt,第二个参数是要保存的词向量模型文件名。在代码中,设置的词向量的维度是100个feature。曾经试过800feature的,内存需要提供16G才能训练完orz。因此如果只是学习使用,100个feature已经足够了。

 

2. 数据预处理

在wv_thucnews.py阶段已经产生了所有数据以及这些数据对应的标签,因此这一阶段的主要目标是对原始数据做一次shuffle,使样本之间尽可能的无关。因此在载入数据之后,调用了train_test_split。

trainX, testX, trainY, testY = train_test_split(content,targets)

trainX是待训练的数据,trainY是每个训练数据对应的标签。注意,到目前为止这里的数据还是字符串格式的,因此接下来要把训练数据转成词向量格式,标签数据转成数字形式。

to_categorical函数的主要任务就是将标签字符串转为数字形式,因为数据集的类型总共有14类,因此标签的值从0~13。
然后在代码中使用yield语法返回batch_size个数据,提供训练。
PS:这里建议预先查看下数据集中一个句子的长度,这样训练时可以设置句子平均的合适长度, 长度不足的部分补0。

3. textCNN

我们使用pytorch编写模型。按照《深度学习》圣经的说法,“卷积网络中一个典型层包含三级”,第一级计算多个卷积,第二级通过一个非线性的激活函数,第三级将通过池化函数调整输出。因此我们经常看到这样的写法:

 

1 self.conv1 = nn.Sequential(
2             nn.Conv1d(vec_dim,64,kernel_size,padding=2),
3             nn.ReLU(),
4             nn.MaxPool1d(3,stride=1,padding=1)
5         )

 

Convolutional Neural Networks for Sentence Classification》的textCNN中使用了三个卷积网络。如果需要验证论文的同学,可以严格按照文章的网络和参数进行设置。在我的textCNN.py实现中,使用了三个网络,但跟论文的参数并不相同,因为自行训练得到的词向量维度和数据的batch大小不同。

 

4. 如何调试

对于所有的程序来说,调试是必不可少的。观察loss和accuracy是最基本的方法。理论上来说loss曲线应该是逐渐下降且逼近于一个值,accuracy应该是逐渐上升且逼近一个值。如果中间有较大的跳跃,可能是算法编写的地方有问题,一般说来,可能是数据集没有suffle,每个数据之间关联性较大;也有可能是产生了过拟合,等等。例如下面两个曲线是我没有对label标签去重导致的...

 

而正确的accuracy图应该类似于下方这张:

 

 

posted @ 2019-04-03 22:51  webberg  阅读(6551)  评论(1编辑  收藏  举报