文本分类模型学习笔记

  • TextCNN
    • 模型结构
  • HAN
    • 模型结构
  • 实验
    • 数据集
    • 预处理
    • 模型内容
    • 模型训练
    • 模型测试

近年来,深度学习模型在计算机视觉和语音识别中取得了显著成果。在自然语言处理中,深度学习方法的许多工作都涉及通过神经语言模型来学习单词向量表示,并利用学习的词向量进行分类。CNN模型最初是为计算机视觉而发明的,后来被证明对NLP有效,并且在语义解析、查询检索、句子建模等方面均取得了优异的成绩。
    下面对TextCNN及HAN的模型进行介绍,并在此基础上进行实验。

TextCNN

模型结构


    上图为TextCNN的模型结构图,可以看出其由四层构成:输入层、卷积层、最大池化层、全连接层。
    1. 输入层:输入层是一个n*k的矩阵,n表示一个句子中的单词数, k表示每个词对应的词向量的维度。即输入层的每一行就是一个单词所对应的k维的词向量。为了使向量长度一致,对原句子进行了padding操作。

2. 卷积层:卷积核大小 = 卷积大小(n-gram) * 词向量维度(embed) ,一般卷积大小设2,3,4,5等。根据词向量的不同可以对卷积层进行微调,包括四种模型:
   (1)CNN-rand:随机初始化词向量,所有的word vector都是随机初始化的,在训练过程中更新
   (2)CNN-static:word2vec预训练词向量,在整个train process中所有的words保持不变,只学习其他参数
   (3)CNN-no-static:word2vec预训练词向量,训练过程中微调
   (4)CNN-multichannel:两套词向量构造出的句子矩阵作为两个通道,在误差反向传播时,只更新一组词向量,保持另外一组不变。

3. 池化层:图中所示的网络采用了最大池化,即从每个滑动窗口产生的特征向量中筛选出一个最大的特征,然后将这些特征拼接起来构成向量表示。也可以选用K-Max池化,即选出每个特征向量中最大的K个特征;或者平均池化,即将特征向量中的每一维取平均等,达到的效果都是将不同长度的句子通过池化得到一个定长的向量表示。

4. 全连接层:也叫输出层,使用图像领域中首先提出的的dropout,防止过拟合,再使用激活函数分类输出。

HAN

模型结构


    HAN的网络结构如上图所示,它的核心结构由两个部分组成,下面是一个单词编码器加基于单词编码的Attention层,上面是一个句子编码器加基于句子编码的Attention层。
    1. 单词编码器:单词编码器的输入是一个句子,给定一个由单词witw_{it}wit组成的句子,首先经过一个嵌入矩阵编码成一个特征向量,之后使用单层的双向GRU对其进行编码,并拼接得到双向GRU的输出hith_{it}hit

2. 单词Attention层:单词编码器之上是一个单词Attention层,首先将上一层得到的hith_{it}hit输入到多层感知机中得到它的非线性表示,接下来是Attention部分,首先用softmax函数计算每个特征的权值,在对得到的αit\alpha _ {it}αit进行加权得到最终值:
αit=exp(uitTuw)∑texp(uitTuw)\alpha _ {it}=\frac{exp(u_{it}^Tu_w)}{\sum\limits_{t}exp(u_{it}^Tu_w)} αit=texp(uitTuw)exp(uitTuw)
si=∑tαithits_i=\sum\limits_{t}\alpha_{it}h_{it} si=tαithit

3. 句子编码器:句子编码器使用的也是一个双向GRU,它的结构和单词编码器基本一致。

4. 句子Attention层:句子Attention层的输入是句子编码器得到的特征向量,输出的是整个文本的特征向量,计算方法与单词Attention层基本一致:
αi=exp(uiTus)∑iexp(uiTus)\alpha _ {i}=\frac{exp(u_{i}^Tu_s)}{\sum\limits_{i}exp(u_{i}^Tu_s)} αi=iexp(uiTus)exp(uiTus)
v=∑iαihiv=\sum\limits_{i}\alpha_{i}h_{i} v=iαihi
    最终通过一个softmax激活函数就可以得到文本中每个类别的预测概率p。
p=softmax(Wcv+bc)p=softmax(W_cv+b_c) p=softmax(Wcv+bc)

实验

利用TextCNN模型实现文本的多分类。

数据集

实验使用THUCNews的一个子集进行训练与测试,数据集下载地址:http://thuctc.thunlp.org。其中使用THUCNews数据集中10个类别,每个类别6500条数据。类别为:

股票, 财经, 体育, 时政, 游戏, 娱乐, 家居, 教育, 社会, 科技

数据集按照10:1:2的比例划分训练集、验证集、测试集。下图为训练集部分内容截图:

    生成训练集、验证集、测试集分词文件和以词为单位的词汇表文件。

def new_file(filename, save_file):contents, labels = [], []with open(filename, 'r') as f:for line in f:try:label, content = line.strip().split('\t')if content:contents.append([i for i in jieba.cut(content.strip()) if len(i) > 1 and not check_number(i)])labels.append(label)except:passsavefile = open(save_file, 'w')for i in range(len(contents)):savefile.write(labels[i] + '\t' + ",".join(contents[i]) + '\n')return contents, labels

预处理

将文件转换为id表示。

def file_trans(filename, word_to_id, cat_to_id, embedding_type, max_length=600):contents, labels = read_file(filename, embedding_type)data_id, label_id = [], []for i in range(len(contents)):data_id.append([word_to_id[x] for x in contents[i] if x in word_to_id])label_id.append(cat_to_id[labels[i]])# 将文本pad为固定长度x_pad = kr.preprocessing.sequence.pad_sequences(data_id, max_length)y_pad = kr.utils.to_categorical(label_id, num_classes=len(cat_to_id))return x_pad, y_pad

为神经网络的训练准备经过shuffle批次的数据。

def batch_iter(x, y, batch_size=64):data_len = len(x)num_batch = int((data_len - 1) / batch_size) + 1indices = np.random.permutation(np.arange(data_len))x_shuffle = x[indices]y_shuffle = y[indices]for i in range(num_batch):start_id = i * batch_sizeend_id = min((i + 1) * batch_size, data_len)yield x_shuffle[start_id:end_id], y_shuffle[start_id:end_id]

利用训练集生成词汇表,长度为5000。

def build_vocab(contents, _vocab_dir, vocab_size=5000):stop_words = load_stopwords('stopwords.txt')all_data = []count = 0for content in contents:if count % 100 == 0:print('finished: ', count)count += 1all_data.extend([i for i in content if i not in stop_words])counter = Counter(all_data)count_pairs = counter.most_common(vocab_size - 1)words, _ = list(zip(*count_pairs))# 将所有文本pad为同一长度words = ['<PAD>'] + list(words)open(_vocab_dir, mode='w').write('\n'.join(words) + '\n')

模型内容

模型配置:

embedding_dim = 64  #词向量维度
seq_length = 600  #序列长度
class_num = 10  #类别数
filters_num = 256  #卷积核数目
kernel_size = 5 #卷积核尺寸
vocab_size = 5000  #词汇表大小
hidden_dim = 256  #全连接层神经元
dropout_prob = 0.5  #dropout比例
lr_rate = 1e-3  #学习率
batch_size = 64  #训练大小
epoch_num = 10  #总迭代轮次
save_batch = 10  #保存模型的轮数

模型实现:

class TextCNN(object):def __init__(self, config):# 初始化self.config = configself.input_x = tf.placeholder(tf.int32, [None, self.config.seq_length], name='input_x')self.input_y = tf.placeholder(tf.float32, [None, self.config.num_classes], name='input_y')self.keep_prob = tf.placeholder(tf.float32, name='keep_prob')self.cnn()def cnn(self):# 词向量映射with tf.device('/cpu:0'):embedding = tf.get_variable('embedding', [self.config.vocab_size, self.config.embedding_dim])embedding_inputs = tf.nn.embedding_lookup(embedding, self.input_x)with tf.name_scope("cnn"):# CNN层conv = tf.layers.conv1d(embedding_inputs, self.config.filters_num, self.config.kernel_size, name='conv')# 最大池化层gmp = tf.reduce_max(conv, reduction_indices=[1], name='gmp')with tf.name_scope("score"):# 全连接层fc = tf.layers.dense(gmp, self.config.hidden_dim, name='fc1')fc = tf.contrib.layers.dropout(fc, self.keep_prob)fc = tf.nn.relu(fc)# 分类器self.logits = tf.layers.dense(fc, self.config.num_classes, name='fc2')self.y_pred_cls = tf.argmax(tf.nn.softmax(self.logits), 1)with tf.name_scope("optimize"):# 损失函数cross_entropy = tf.nn.softmax_cross_entropy_with_logits(logits=self.logits, labels=self.input_y)self.loss = tf.reduce_mean(cross_entropy)with tf.name_scope("accuracy"):# 准确率correct_pred = tf.equal(tf.argmax(self.input_y, 1), self.y_pred_cls)self.acc = tf.reduce_mean(tf.cast(correct_pred, tf.float32))

模型训练

训练过程代码为:

def train():for epoch in range(config.num_epochs):print('Epoch:', epoch + 1)batch_train = batch_iter(x_train, y_train, config.batch_size)for x_batch, y_batch in batch_train:feed_dict = feed_data(x_batch, y_batch, config.dropout_keep_prob)if total_batch % config.save_per_batch == 0:# 将训练结果写入tensorboard scalars = session.run(merged_summary, feed_dict=feed_dict)writer.add_summary(s, total_batch)if total_batch % config.print_per_batch == 0:# 输出在训练集和验证集上的性能feed_dict[model.keep_prob] = 1.0loss_train, acc_train = session.run([model.loss, model.acc], feed_dict=feed_dict)loss_val, acc_val = evaluate(session, x_val, y_val)  if acc_val > best_acc_val:# 保存最好结果best_acc_val = acc_vallast_improved = total_batchsaver.save(sess=session, save_path=save_path)improved_str = '*'else:improved_str = ''time_dif = get_time_dif(start_time)msg = 'Iter: {0:>6}, Train Loss: {1:>6.2}, Train Acc: {2:>7.2%},' \+ ' Val Loss: {3:>6.2}, Val Acc: {4:>7.2%}, Time: {5} {6}'print(msg.format(total_batch, loss_train, acc_train, loss_val, acc_val, time_dif, improved_str))session.run(model.optim, feed_dict=feed_dict)  total_batch += 1if total_batch - last_improved > require_improvement:# 验证集正确率长期不提升,提前结束训练flag = Truebreakif flag:break

下图为训练过程截图,在第四个epoch准确率趋于稳定,模型不再继续训练。

模型测试

模型测试的代码如下所示:

def test():# 读取保存的模型session = tf.Session()session.run(tf.global_variables_initializer())saver = tf.train.Saver()saver.restore(sess=session, save_path=save_path)  batch_size = 128data_len = len(x_test)num_batch = int((data_len - 1) / batch_size) + 1# 保存预测结果y_test_cls = np.argmax(y_test, 1)y_pred_cls = np.zeros(shape=len(x_test), dtype=np.int32)  for i in range(num_batch):  start_id = i * batch_sizeend_id = min((i + 1) * batch_size, data_len)feed_dict = {model.input_x: x_test[start_id:end_id],model.keep_prob: 1.0}y_pred_cls[start_id:end_id] = session.run(model.y_pred_cls, feed_dict=feed_dict)

测试结果为:

loss: 0.11
acc: 96.79%

文本分类模型学习笔记相关推荐

  1. 分类模型 · 学习笔记一

    文章目录 分类模型 分类算法一:逻辑回归 一.直接采用线性概率模型是否可行? 二.模型的构建 1. 两点分布(伯努利分布) 2. 那么连接函数 F ( x , β ) F(x,\beta) F(x,β ...

  2. R使用LSTM模型构建深度学习文本分类模型(Quora Insincere Questions Classification)

    R使用LSTM模型构建深度学习文本分类模型(Quora Insincere Questions Classification) Long Short Term 网络-- 一般就叫做 LSTM --是一 ...

  3. 文本分类模型_文本分类中的经典深度学习模型

    众所周知,文本分类是NLP领域中十分基础的任务,大部分文本分类模型稍加修改就可以应用到其他任务中.下面介绍几个经典的文本分类模型. 图中被引数来源google学术(2019/5/16) 1. text ...

  4. 独家 | 教你用Pytorch建立你的第一个文本分类模型!

    作者:Aravind Pai 翻译:王威力 校对:张一豪 本文约3400字,建议阅读10+分钟 本文介绍了利用Pytorch框架实现文本分类的关键知识点,包括使用如何处理Out of Vocabula ...

  5. 文本基线怎样去掉_ICML 2020 | 基于类别描述的文本分类模型

    论文标题: Description Based Text Classification with Reinforcement Learning 论文作者: Duo Chai, Wei Wu, Qing ...

  6. fastText、TextCNN、TextRNN……这里有一套NLP文本分类深度学习方法库供你选择 作者:机器人圈 / 微信号:ROBO_AI发表时间 :2017-07-28 图:pixabay

    fastText.TextCNN.TextRNN--这里有一套NLP文本分类深度学习方法库供你选择 「机器人圈」编译:嗯~阿童木呀.多啦A亮 这个库的目的是探索用深度学习进行NLP文本分类的方法. 它 ...

  7. ICML 2020 | 基于类别描述的文本分类模型

    论文标题: Description Based Text Classification with Reinforcement Learning 论文作者: Duo Chai, Wei Wu, Qing ...

  8. 文本分类模型_【文本分类】几个可作为Baseline的模型

    点击上方,选择星标或置顶,每天给你送干货! 阅读大概需要9分钟 跟随小博主,每天进步一丢丢 来自:AINLP 作者:老宋的茶书会 知乎专栏:NLP与深度学习 研究方向:自然语言处理 前言 最近,从Te ...

  9. 文本分类模型(一)——RCNN

    文本分类模型(一) RCNN 文章目录 文本分类模型(一) RCNN 一.概述 二.背景 三.RCNN原理 3.1 模型结构 3.2 前向传播 1)Word Representation Learni ...

最新文章

  1. JavaScript 变量
  2. python dict 字典 清空
  3. photoshop8.0 安装步骤及注意事项
  4. springboot 远程日志
  5. html5文件阅读器api,html 5 读取本地文件API
  6. fit、transform与fit_transform
  7. 神经网络模型模型转ONNX
  8. Composer fails to download http json files on update, not a network issue, https fine
  9. 当年叱咤风云的框架Struts2,你可知Struts2内功如何修炼
  10. iframe调用父页面js方法_JS高级技巧
  11. E-MapReduce 2.0.0 版本发布
  12. triz矛盾矩阵_怎样利用项目TRIZ矛盾定义法,突破产品“创
  13. python 谷歌翻译
  14. 安利几个优秀的开源电商系统
  15. react + better-scroll 横向滚动案例
  16. python如何移动图片_python 简单图像处理(3) 平移
  17. GNSS/INS组合导航(五):惯性导航参数建模
  18. idea光标移至行尾快捷键——End键不能移至行尾的解决办法
  19. Pinterest Copy to China——meterial collect
  20. win2003 iis 设置301转向

热门文章

  1. 浅谈RabbitMQ的基石—高级消息队列协议(AMQP)
  2. Python 爬取微博、百度实时热点
  3. 【NDN学习】NDN的定义,基础,解决什么问题
  4. 联想笔记本声音太小怎么办_笔记本声音太小,详细教您笔记本电脑声音太小解决方法...
  5. 统信桌面操作系统V20专业版(1020)正式发布
  6. 我的世界服务器不显示前缀,[管理|聊天]TRCStudioChatSystem —— 多功能聊天系统|聊天|脏话|匿名|前缀[1.7-1.15]...
  7. python黑魔法指南_Python黑魔法大全
  8. 腾讯云与智慧产业总裁汤道生:C2B是腾讯产业互联网的重要优势
  9. 这就涉及到ABAQUS历史输出中各能量变量的意义
  10. vscode让代码敲出火焰