实战:循环神经网络与文本内容情感分类

在传统的神经网络模型中,是从输入层到隐含层再到输出层,层与层之间是全连接的,每层之间的节点是无连接的。但是这种普通的神经网络对于很多问题却无能为力。例如,你要预测句子的下一个单词是什么,一般需要用到前面的单词,因为一个句子中前后单词并不是独立的,即一个序列当前的输出与前面的输出也有关。

具体的表现形式为网络会对前面的信息进行记忆并应用于当前输出的计算中,即隐藏层之间的节点不再是无连接的,而是有连接的,并且隐藏层的输入不仅包括输入层的输出,还包括上一时刻隐藏层的输出,这种传统的神经网络模型如图8-2所示。

8.2.1  基于循环神经网络的中文情感分类准备工作

在讲解循环神经网络的理论知识之前,最好的学习方式就是通过实例实现并运行对应的项目,本小节将带领读者完成一下循环神经网络的情感分类实战的准备工作。

1. 数据的准备

首先是数据集的准备工作。在本节中,我们需要完成的是中文数据集的情感分类,因此事先准备了一套已完成情感分类的数据集,读者可以参考本书配套代码中dataset目录下的chnSenticrop.txt文件确认一下。此时我们需要完成数据的读取和准备工作,其实现代码如下:

max_length = 80         #设置获取的文本长度为80
labels = []             #用以存放label
context = []            #用以存放汉字文本
vocab = set()           
with open("../dataset/cn/ChnSentiCorp.txt", mode="r", encoding="UTF-8") as emotion_file:for line in emotion_file.readlines():line = line.strip().split(",")# labels.append(int(line[0]))if int(line[0]) == 0:labels.append(0)    #由于在后面直接采用PyTorch自带的crossentroy函数,因此这里直接输入0,否则输入[1,0]else:labels.append(1)text = "".join(line[1:])context.append(text)for char in text: vocab.add(char)   #建立vocab和vocab编号voacb_list = list(sorted(vocab))
# print(len(voacb_list))
token_list = []
#下面是对context内容根据vocab进行token处理
for text in context:token = [voacb_list.index(char) for char in text]token = token[:max_length] + [0] * (max_length - len(token))token_list.append(token)

2. 模型的建立

接下来可以根据需求建立模型。在这里我们实现了一个带有单向GRU和一个双向GRU的循环神经网络,代码如下:

class RNNModel(torch.nn.Module):def __init__(self,vocab_size = 128):super().__init__()self.embedding_table = torch.nn.Embedding(vocab_size,embedding_dim=312)self.gru  =  torch.nn.GRU(312,256)  # 注意这里输出有两个:out与hidden,out是序列在模型运行后全部隐藏层的状态,而hidden是最后一个隐藏层的状态self.batch_norm = torch.nn.LayerNorm(256,256)self.gru2  =  torch.nn.GRU(256,128,bidirectional=True)  # 注意这里输出有两个:out与hidden,out是序列在模型运行后全部隐藏层的状态,而hidden是最后一个隐藏层的状态def forward(self,token):token_inputs = tokenembedding = self.embedding_table(token_inputs)gru_out,_ = self.gru(embedding)embedding = self.batch_norm(gru_out)out,hidden = self.gru2(embedding)return out

这里要注意的是,对于GRU进行神经网络训练,无论是单向还是双向GUR,其结果输出都是两个隐藏层状态,即out与hidden。这里的out是序列在模型运行后全部隐藏层的状态,而hidden是此序列最后一个隐藏层的状态。

在这里我们使用的是2层GRU,有读者会注意到,在我们对第二个GRU进行定义时,使用了一个额外的参数bidirectional,这个参数用来定义循环神经网络是单向计算还是双向计算的,其具体形式如图8-3所示。

从图8-3中可以很明显地看到,左右两个连续的模块并联构成了不同方向的循环神经网络单向计算层,而这两个方向同时作用后生成了最终的隐藏层。

8.2.2  基于循环神经网络的中文情感分类

上一小节完成了循环神经网络的数据准备以及模型的建立,下面我们可以对中文数据集进行情感分类,完整的代码如下:

import numpy as npmax_length = 80         #设置获取的文本长度为80
labels = []             #用以存放label
context = []            #用以存放汉字文本
vocab = set()           with open("../dataset/cn/ChnSentiCorp.txt", mode="r", encoding="UTF-8") as emotion_file:for line in emotion_file.readlines():line = line.strip().split(",")# labels.append(int(line[0]))if int(line[0]) == 0:labels.append(0)    #由于在后面直接采用PyTorch自带的crossentroy函数,因此这里直接输入0,否则输入[1,0]else:labels.append(1)text = "".join(line[1:])context.append(text)for char in text: vocab.add(char)   #建立vocab和vocab编号voacb_list = list(sorted(vocab))
# print(len(voacb_list))
token_list = []
#下面的内容是对context根据vocab进行token处理
for text in context:token = [voacb_list.index(char) for char in text]token = token[:max_length] + [0] * (max_length - len(token))token_list.append(token)seed = 17
np.random.seed(seed);np.random.shuffle(token_list)
np.random.seed(seed);np.random.shuffle(labels)dev_list = np.array(token_list[:170])
dev_labels = np.array(labels[:170])token_list = np.array(token_list[170:])
labels = np.array(labels[170:])import torch
class RNNModel(torch.nn.Module):def __init__(self,vocab_size = 128):super().__init__()self.embedding_table = torch.nn.Embedding(vocab_size,embedding_dim=312)self.gru  =  torch.nn.GRU(312,256)  # 注意这里输出有两个:out与hidden,out是序列在模型运行后全部隐藏层的状态,而hidden是最后一个隐藏层的状态self.batch_norm = torch.nn.LayerNorm(256,256)self.gru2  =  torch.nn.GRU(256,128,bidirectional=True)  # 注意这里输出有两个:out与hidden,out是序列在模型运行后全部隐藏层的状态,而hidden是最后一个隐藏层的状态def forward(self,token):token_inputs = tokenembedding = self.embedding_table(token_inputs)gru_out,_ = self.gru(embedding)embedding = self.batch_norm(gru_out)out,hidden = self.gru2(embedding)return out#这里使用顺序模型的方式建立了训练模型
def get_model(vocab_size = len(voacb_list),max_length = max_length):model = torch.nn.Sequential(RNNModel(vocab_size),torch.nn.Flatten(),torch.nn.Linear(2 * max_length * 128,2))return modeldevice = "cuda"
model = get_model().to(device)
model = torch.compile(model)
optimizer = torch.optim.Adam(model.parameters(), lr=2e-4)loss_func = torch.nn.CrossEntropyLoss()batch_size = 128
train_length = len(labels)
for epoch in (range(21)):train_num = train_length // batch_sizetrain_loss, train_correct = 0, 0for i in (range(train_num)):start = i * batch_sizeend = (i + 1) * batch_sizebatch_input_ids = torch.tensor(token_list[start:end]).to(device)batch_labels = torch.tensor(labels[start:end]).to(device)pred = model(batch_input_ids)loss = loss_func(pred, batch_labels.type(torch.uint8))optimizer.zero_grad()loss.backward()optimizer.step()train_loss += loss.item()train_correct += ((torch.argmax(pred, dim=-1) == (batch_labels)).type(torch.float).sum().item() / len(batch_labels))train_loss /= train_numtrain_correct /= train_numprint("train_loss:", train_loss, "train_correct:", train_correct)test_pred = model(torch.tensor(dev_list).to(device))correct = (torch.argmax(test_pred, dim=-1) == (torch.tensor(dev_labels).to(device))).type(torch.float).sum().item() / len(test_pred)print("test_acc:",correct)print("-------------------")

在上面代码中,我们顺序建立循环神经网络模型,在使用GUR对数据进行计算后,又使用Flatten对序列embedding进行平整化处理;而最后的Linear是分类器,作用是对结果进行分类。具体结果请读者自行测试查看。

本文节选自《PyTorch语音识别实战》,获出版社和作者授权发布。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/271238.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微服务基础

目录 一、单体架构 二、分布式架构 三、微服务 四、微服务结构 五、SpringCloud 六、服务拆分 七、远程调用 一、单体架构 单体架构就是将业务的所有功能都集中在一个项目中进行开发,并打成一个包进行部署。 他的优点很明显,就是架构简单&#xff…

在分布式环境中使用状态机支持数据的一致性

简介 在本文中,我们将介绍如何在分布式系统中使用transaction以及分布式系统中transaction的局限性。然后我们通过一个具体的例子,介绍了一种通过设计状态机来避免使用transaction的方法。 什么是数据库transaction Transaction是关系型数据普遍支持的…

【HarmonyOS】鸿蒙开发之Stage模型-UIAbility的启动模式——第4.4章

UIAbility的启动模式简介 一共有四种:singleton,standard,specified,multion。在项目目录的:src/main/module.json5。默认开启模式为singleton(单例模式)。如下图 singleton(单实例模式)启动模式 每个UIAbility只存在唯一实例。任务列表中只会存在一…

动态内存经典笔试题分析

题目1: void GetMemory(char *p) { *p (char *)malloc(100); } void Test(void) { char *str NULL; GetMemory(str); strcpy(str, "hello world"); 对NULL指针解引用操作符程序崩溃。 printf(str); } 请问运行Test函数会有什么样的后果? G…

温室气体排放控制中的DNDC模型建模技术及双碳应用

由于全球变暖、大气中温室气体浓度逐年增加等问题的出现,“双碳”行动特别是碳中和已经在世界范围形成广泛影响。国家领导人在多次重要会议上讲到,要把“双碳”纳入经济社会发展和生态文明建设整体布局。同时,提到要把减污降碳协同增效作为促…

【C++从练气到飞升】01---C++入门

🎈个人主页:库库的里昂 ✨收录专栏:C从练气到飞升 🎉鸟欲高飞先振翅,人求上进先读书。 目录 推荐 前言 什么是C C的发展史 📋命名空间 命名空间定义 命名空间使用 命名空间的嵌套 std命名空间的使用 &#…

离散数学例题——4.计数和集合论(特殊关系、计数基础和函数)

等价关系 等价关系的证明 等价类和商集 等价关系与划分一一对应 偏序关系 证明偏序关系 哈斯图 整除关系画哈斯图 特殊元素 最大最小元,极大极小元 上界上确界,下界下确界 其他关系 全序关系、良序关系 拟序关系、相容关系 计数基础 排列组合 函数定义…

Chromium内核浏览器编译记(四)Linux版本CEF编译

转载请注明出处:https://blog.csdn.net/kong_gu_you_lan/article/details/136508294 本文出自 容华谢后的博客 0.写在前面 本篇文章是用来记录编译Linux版本CEF的步骤和踩过的坑,以防止后续再用到的时候忘记,同时也希望能够帮助到遇到同样问…

离散数学例题——5.图论基础

基本的图 关联矩阵 子图和补图 度数和握手定理 注意!!!无向图的度数,要行/列和对角线值 根据度数序列判定是否为无向图 度和握手定理证明题 竞赛图 同构图 自补图 通路和回路数量 通路和回路数量 最短路径——dijkstra算法 连通…

[数据结构初阶]队列

鼠鼠我呀,今天写一个基于C语言关于队列的博客,如果有兴趣的读者老爷可以抽空看看,很希望的到各位老爷观点和点评捏! 在此今日,也祝各位小姐姐女生节快乐啊,愿笑容依旧灿烂如初阳,勇气与童真永不…

【HTML】HTML基础7.2(有序列表)

目录 标签 效果 注意 标签 <ol> <li>列表内容</li> <li>列表内容</li> <li>列表内容</li> <li>列表内容</li> 。。。。。。 </ol> 效果 代码 <ol><li>银河护卫队 10000000000</li><l…

RUST 每日一省:发布到crates.io

github是开源代码分享的地方&#xff0c;rust的开源项目除了github&#xff0c;我们还可以将其发布到 crates.io 上&#xff0c;然后其它用户就可以使用cargo进行安装使用了。其实步骤很简单&#xff0c;只有三条命令了&#xff0c;我们一次来看一下。 1、cargo package 首先&a…

Threejs着色器(GPU)编程——感温管网

管网,作为支撑现代城市运转的重要基础设施,是隐藏在地面之下的庞大工程网络。这些管网如同城市的血脉,负责输送各种必要的资源,如水源、热力、燃气等,同时排除废水和其他废弃物。然而,由于其位于地下,人们往往难以直接感知其存在和运行状态。为了保障这些地下管网的安全…

Go编程实战:高效利用encoding/binary进行数据编解码

Go编程实战&#xff1a;高效利用encoding/binary进行数据编解码 引言encoding/binary 包核心概念ByteOrder 接口Binary 数据类型的处理处理复杂数据结构 基础使用教程数据类型与二进制格式的映射基本读写操作写操作 - binary.Write读操作 - binary.Read 错误处理 高级功能与技巧…

手机备忘录可以设置密码吗 能锁屏加密的备忘录

在繁忙的生活中&#xff0c;手机备忘录成了我随身携带的“小秘书”。那些关于工作的灵感、生活的琐事&#xff0c;甚至深藏心底的小秘密&#xff0c;都被我一一记录在里面。然而&#xff0c;每次当手机离开我的视线&#xff0c;或者需要借给他人使用时&#xff0c;我总会心生担…

Vue+SpringBoot打造校园疫情防控管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 学生2.2 老师2.3 学校管理部门 三、系统展示四、核心代码4.1 新增健康情况上报4.2 查询健康咨询4.3 新增离返校申请4.4 查询防疫物资4.5 查询防控宣传数据 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBoot…

力扣刷题Days12第二题--100相同的树(js)

目录 1,题目 2&#xff0c;代码 2.1深度优先遍历 2.2广度优先遍历 3&#xff0c;学习与总结 1,题目 给你两棵二叉树的根节点 p 和 q &#xff0c;编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同&#xff0c;并且节点具有相同的值&#xff0c;则认为它们是…

数字孪生10个技术栈:数据处理的六步骤,以获得可靠数据。

一、什么是数据处理 在数字孪生中&#xff0c;数据处理是指对采集到的实时或历史数据进行整理、清洗、分析和转化的过程。数据处理是数字孪生的基础&#xff0c;它将原始数据转化为有意义的信息&#xff0c;用于模型构建、仿真和决策支持。 数据处理是为了提高数据质量、整合数…

ElasticSearch之通过search after和scroll解决深度分页问题

写在前面 通过from&#xff0c;size来进行分页查询时&#xff0c;如下&#xff1a; 当from比较大时会有深度分页问题&#xff0c;问题产生的核心是coordinate node需要从每个分片中获取fromsize条数据&#xff0c;当from比较大&#xff0c;整体需要获取的数据量也会比较大&am…

阿珊解析Vuex:实现状态管理的利器

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…