【python 走进NLP】从零开始搭建textCNN卷积神经网络模型

本文主要是介绍【python 走进NLP】从零开始搭建textCNN卷积神经网络模型,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

无意中发现了一个巨牛的人工智能教程,忍不住分享一下给大家。教程不仅是零基础,通俗易懂,而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家。点这里可以跳转到教程。人工智能教程

1、众所周知,tensorflow 是一个开源的机器学习框架,它的出现大大降低了机器学习的门槛,即使你没有太多的数学知识,它也可以允许你用“搭积木”的方式快速实现一个神经网络,即使没有调节太多的参数,模型的表现一般还不错。目前,tensorflow 的安装已经变得非常简单,一个简单的 pip install tensorflow 即可,然后 import tensorflow as tf 就能愉快玩耍了。

2、卷积神经网络,即CNN,它的核心思想是捕捉数据的局部特征。不仅仅在图像领域大放异彩,CNN在文本分类领域也有很强的表现。在Yoon Kim的这篇 论文 中,比较清楚地解释了CNN用于文本分类的原理,关键在于如何将文本向量化,如下图,即把每个词都表示为一个 1×k的向量,对长度为N的文本则表示为N×K的矩阵,经过这一步处理,那么我们就可以把图像上的分类经验应用到文本上来了。

def _read_file(txt_file):"""读取txt文件"""return open(txt_file, 'rb').read().decode("gbk", 'ignore')

3、那么又如何将文本转换为向量呢。有两种方法,第一种,采用预训练模型训练好的词向量。第二种呢,就是从原始文本中建立词汇表,然后把文本中的每个字符都对应编码。比如,“我爱北京天安门。”,我们就会把这段文本全部打散成为“我”、“爱”、“北”、“京”、“天”、“安”、“门”、“。”,甚至标点符号、特殊字符都会有对应的编码,不过从模型的表现来看,效果很好。

4、构建词汇表。筛选出的训练集语料中出现频次较高的5000个字符作为词汇表,我比较好奇的是我并没有对原始语料做任何的清洗、去噪,却丝毫不影响分类器的表现。添加一个 来将所有文本pad为同一长度

build_vocab(): 构建词汇表,使用字符级的表示,这一函数会将词汇表存储下来,避免每一次重复处理;

def build_vocab(train_path, vocab_path, vocab_size=5000):"""构建词汇表"""data_train, _ = read_file(train_path)all_data = []for content in data_train:all_data.extend(content)counter = Counter(all_data)counter_pairs = counter.most_common(vocab_size-1)words, _ = list(zip(*counter_pairs))words = ['<PAD>'] + list(words)open_file(vocab_path, mode='w').write('\n'.join(words) + '\n')

5、词汇表建立好了,txt文件并不适合查询,所以这里用字符在文件的顺序作为其标识的id,存储到字典 word_to_id 中,这样以来就方便查找了。
read_vocab(): 读取上一步存储的词汇表,转换为{词:id}表示;

def read_vocab(vocab_path):with open(vocab_path) as f:words = [_.strip() for _ in f.readlines()]word_to_id = dict(zip(words, range(len(words))))return words, word_to_id

6、因变量编码
read_category(): 将分类目录固定,转换为{类别: id}表示;

def read_category():categories = ['mil.news', 'cul', 'health', 'travel', 'auto', 'learning', 'it', 'yule', 'sports', 'business', 'news']cat_to_id = dict(zip(categories, range(len(categories))))return categories, cat_to_id

7、处理数据。做完构建词汇表、类别转换为one-hot编码的准备工作,终于要进入正题了,数据进入模型训练、验证、测试前的准备工作还没有做。下面, process_file() 函数首先读取数据文件,将正文和标签分别对应存储在 contents 和 labels 两个列表中,然后再处理 contents 中的每一段文本,把文本中每一个字符在词汇表中找到其对应的id,完成文本数值化操作。类别转换为one-hot表示: y_pad = kr.utils.to_categorical(label_id, num_classes=len(cat_to_id)) 。

process_file(): 将数据集从文字转换为固定长度的id序列表示;

def process_file(file_name, word_to_id, cat_to_id, max_length=600):contents, labels = read_file(file_name)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]])# 使用keras提供的pad_sequences来将文本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))  # 将标签转换为one-hot表示return x_pad, y_pad

batch_iter(): 为神经网络的训练准备经过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]

8、CNN配置

class TCNNConfig(object):"""CNN配置参数"""embedding_dim = 64  # 词向量宽度seq_length = 1000  # 输入矩阵的宽度num_classes = 11  # 类别数num_filters = 256  # 卷积核数目kernel_size = 5  # 卷积核尺寸,即卷积核覆盖的词汇数量vocab_size = 6000  # 词汇表大小hidden_dim = 128  # 全连接层神经元dropout_keep_prob = 0.5  # dropout保留比例learning_rate = 1e-3  # 学习率batch_size = 64  # 每批训练大小num_epochs = 10  # 总迭代轮次print_per_batch = 100  # 每多少轮输出一次结果save_per_batch = 10  # 每多少轮存入tensorboard

9、CNN模型

class TextCNN(object):"""文本分类,CNN模型"""def __init__(self, config):self.config = config# 三个待输入的数据,腾出占位符# input_x 为 n * seq_length 的矩阵,n 大小不固定# input_y 同self.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):"""CNN模型"""# 词向量映射with tf.device('/cpu:0'): # 强制使用CPUembedding = 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 layerconv = tf.layers.conv1d(embedding_inputs, self.config.num_filters, self.config.kernel_size, name='conv')# global max pooling layergmp = tf.reduce_max(conv, reduction_indices=[1], name='gmp')with tf.name_scope("score"):# 全连接层,后面接dropout以及relu激活# 激活函数后得到第二个全连接层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_v2(logits=self.logits, labels=self.input_y)self.loss = tf.reduce_mean(cross_entropy)# 优化器self.optim = tf.train.AdamOptimizer(learning_rate=self.config.learning_rate).minimize(self.loss)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))

10、train训练

def train():print("Configuring TensorBoard and Saver...")# 配置 Tensorboard,重新训练时,请将tensorboard文件夹删除,不然图会覆盖tensorboard_dir = 'tensorboard/textcnn'if not os.path.exists(tensorboard_dir):os.makedirs(tensorboard_dir)tf.summary.scalar("loss", model.loss)tf.summary.scalar("accuracy", model.acc)merged_summary = tf.summary.merge_all()writer = tf.summary.FileWriter(tensorboard_dir)# 配置 Saversaver = tf.train.Saver()if not os.path.exists(save_dir):os.makedirs(save_dir)print("Loading training and validation data...")# 载入训练集与验证集start_time = time.time()x_train, y_train = process_file(train_dir, word_to_id, cat_to_id, config.seq_length)x_val, y_val = process_file(val_dir, word_to_id, cat_to_id, config.seq_length)time_dif = get_time_dif(start_time)print("Time usage:", time_dif)# 创建sessionsession = tf.Session()session.run(tf.global_variables_initializer())writer.add_graph(session.graph)print('Training and evaluating...')start_time = time.time()total_batch = 0  # 总批次best_acc_val = 0.0  # 最佳验证集准确率last_improved = 0  # 记录上一次提升批次require_improvement = 1000  # 如果超过1000轮未提升,提前结束训练flag = Falsefor 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)  # todoif 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:# 验证集正确率长期不提升,提前结束训练print("No optimization for a long time, auto-stopping...")flag = Truebreak  # 跳出循环if flag:  # 同上break

11、测试test函数

def test():print("Loading test data...")start_time = time.time()x_test, y_test = process_file(test_dir, word_to_id, cat_to_id, config.seq_length)session = tf.Session()session.run(tf.global_variables_initializer())saver = tf.train.Saver()saver.restore(sess=session, save_path=save_path)  # 读取保存的模型print('Testing...')loss_test, acc_test = evaluate(session, x_test, y_test)msg = 'Test Loss: {0:>6.2}, Test Acc: {1:>7.2%}'print(msg.format(loss_test, acc_test))batch_size = 128data_len = len(x_test)num_batch = int((data_len - 1) / batch_size) + 1y_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)# 评估print("Precision, Recall and F1-Score...")print(metrics.classification_report(y_test_cls, y_pred_cls, target_names=categories))# 混淆矩阵print("Confusion Matrix...")cm = metrics.confusion_matrix(y_test_cls, y_pred_cls)print(cm)time_dif = get_time_dif(start_time)print("Time usage:", time_dif)

12、模型结构

在这里插入图片描述

demo:github项目学习地址:
https://github.com/gaussic/text-classification-cnn-rnn

这篇关于【python 走进NLP】从零开始搭建textCNN卷积神经网络模型的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1144271

相关文章

python panda库从基础到高级操作分析

《pythonpanda库从基础到高级操作分析》本文介绍了Pandas库的核心功能,包括处理结构化数据的Series和DataFrame数据结构,数据读取、清洗、分组聚合、合并、时间序列分析及大数据... 目录1. Pandas 概述2. 基本操作:数据读取与查看3. 索引操作:精准定位数据4. Group

Python pandas库自学超详细教程

《Pythonpandas库自学超详细教程》文章介绍了Pandas库的基本功能、安装方法及核心操作,涵盖数据导入(CSV/Excel等)、数据结构(Series、DataFrame)、数据清洗、转换... 目录一、什么是Pandas库(1)、Pandas 应用(2)、Pandas 功能(3)、数据结构二、安

Python使用Tenacity一行代码实现自动重试详解

《Python使用Tenacity一行代码实现自动重试详解》tenacity是一个专为Python设计的通用重试库,它的核心理念就是用简单、清晰的方式,为任何可能失败的操作添加重试能力,下面我们就来看... 目录一切始于一个简单的 API 调用Tenacity 入门:一行代码实现优雅重试精细控制:让重试按我

Python安装Pandas库的两种方法

《Python安装Pandas库的两种方法》本文介绍了三种安装PythonPandas库的方法,通过cmd命令行安装并解决版本冲突,手动下载whl文件安装,更换国内镜像源加速下载,最后建议用pipli... 目录方法一:cmd命令行执行pip install pandas方法二:找到pandas下载库,然后

Python实现网格交易策略的过程

《Python实现网格交易策略的过程》本文讲解Python网格交易策略,利用ccxt获取加密货币数据及backtrader回测,通过设定网格节点,低买高卖获利,适合震荡行情,下面跟我一起看看我们的第一... 网格交易是一种经典的量化交易策略,其核心思想是在价格上下预设多个“网格”,当价格触发特定网格时执行买

Python标准库之数据压缩和存档的应用详解

《Python标准库之数据压缩和存档的应用详解》在数据处理与存储领域,压缩和存档是提升效率的关键技术,Python标准库提供了一套完整的工具链,下面小编就来和大家简单介绍一下吧... 目录一、核心模块架构与设计哲学二、关键模块深度解析1.tarfile:专业级归档工具2.zipfile:跨平台归档首选3.

使用Python构建智能BAT文件生成器的完美解决方案

《使用Python构建智能BAT文件生成器的完美解决方案》这篇文章主要为大家详细介绍了如何使用wxPython构建一个智能的BAT文件生成器,它不仅能够为Python脚本生成启动脚本,还提供了完整的文... 目录引言运行效果图项目背景与需求分析核心需求技术选型核心功能实现1. 数据库设计2. 界面布局设计3

Python进行JSON和Excel文件转换处理指南

《Python进行JSON和Excel文件转换处理指南》在数据交换与系统集成中,JSON与Excel是两种极为常见的数据格式,本文将介绍如何使用Python实现将JSON转换为格式化的Excel文件,... 目录将 jsON 导入为格式化 Excel将 Excel 导出为结构化 JSON处理嵌套 JSON:

Python操作PDF文档的主流库使用指南

《Python操作PDF文档的主流库使用指南》PDF因其跨平台、格式固定的特性成为文档交换的标准,然而,由于其复杂的内部结构,程序化操作PDF一直是个挑战,本文主要为大家整理了Python操作PD... 目录一、 基础操作1.PyPDF2 (及其继任者 pypdf)2.PyMuPDF / fitz3.Fre

python设置环境变量路径实现过程

《python设置环境变量路径实现过程》本文介绍设置Python路径的多种方法:临时设置(Windows用`set`,Linux/macOS用`export`)、永久设置(系统属性或shell配置文件... 目录设置python路径的方法临时设置环境变量(适用于当前会话)永久设置环境变量(Windows系统