这周主要复习了一个开源项目,在cnew数据集上做文本分类,简单的记录一下,方便以后查看。
1.首先是数据集的介绍:
cnew是一个中文的新闻数据集,标签主要有[‘体育’,‘’]10个分类,分为训练集,验证集和测试集。
数据预处理部分就是一般的自然语言处理的标准过程(没有使用到分词工具,是按照字符级进行训练的),包括生成字典,把words和labels转换成对应的id, 生成批数据。
2.模型部分
模型主要使用了cnn和lstm,框架使用的是tensorflow。
模型分三个部分:
embedding层,使用tensorflow自带的函数embedding_lookup()将输入的句子的维度转换成[batch_size, max_length, word_embedding_dim]
特征提取层,这里使用两种不同的特征提取器。
cnn作为特征提取器时,一般是conv-dropout-activate,卷积核的大小是kernel_size,使用的卷积核的数目是filter_nums,经过卷积操作处理后的sequence的大小是[batch_size,max_length-kernel_size+1,filter_nums],如果使用池化操作,可以选择max_pooling, average_pooling等,大小是[batch_size, filter_nums]
lstm作为特征提取器,隐藏层的节点个是hidden_dim,本文使用的两层lstm(注意这里使用的两层lstm是同方向的,和双向lstm是不同的),在层之间可以使用dropout,同样有两种方式,可以指定是int_keep_prob还是out_keep_prob,同一层前后的lstm单元是不能进行dropout操作的。tf.rnn.dynamic_rnn()的输出会有两个,第一个输出out_puts是最后一层每个step的输出,shape=[batch_size,max_length,hidden_dim];第二个输出是最后一个step的输出,last_out.c存放的是cell的参数,last_out.h是最后一个step的输出,shape=[batch_size, hidden_dim]。(这个地方需要注意的是,我认为使用last_out.h会比使用out_puts[:,-1,:]好,因为如果句子长度<max_length,会使用keras提供的方法对句子进行padding,那么此时句子的out_puts[:,-1,:]很有可能是全零向量,具体是不是我不太清楚,但是看lstm的一些实例,发现out_puts[:,-1,:]输出的是全零向量,而last_out.h是我们想要的东西)。
全连接分类层,对于特征提取层输出的向量,进入两个全连接层,第一层可以被称为是隐藏层,节点数是hidden_nums; 第二层是分类层,节点数等于分类数,输出是[classes_num]的向量。在分类时使用softmax()函数,得出分类的概率。如果是一个单分类问题使用argmax()函数取出分类概率最大的那个类,就是分类结果。
3.在训练的过程中,每间隔一定的batch后,使用验证集进行验证,这时需要注意的是在验证和测试的时候是没有进行dropout 的,也就是说keep_prob=1.0,训练时设置keep_prob的值是一个小于1的数。
网友评论