NLP(9)--rnn实现中文分词

news/2024/5/12 1:25:39

前言

仅记录学习过程,有问题欢迎讨论

利用rnn实现分词效果(感觉十分依赖词数据)
使用jieba分词好的数据做样本
  • pip install jieba

代码

import jieba
import numpy as np
import torch
import torch.nn as nn
from torch.utils.data import DataLoader"""
基于pytorch的网络编写一个分词模型
我们使用jieba分词的结果作为训练数据
看看是否可以得到一个效果接近的神经网络模型中文分词缺点:
1.对词表极为依赖,如果没有词表,则无法进行;如果词表中缺少需要的词,结果也不会正确
2.切分过程中不会关注整个句子表达的意思,只会将句子看成一个个片段
3.如果文本中出现一定的错别字,会造成一连串影响
4.对于人名等的无法枚举实体词无法有效的处理"""class TorchModel(nn.Module):def __init__(self, vocab, input_dim, hidden_size, rnn_layer_size):super(TorchModel, self).__init__()self.emb = nn.Embedding(len(vocab) + 1, input_dim)# 多层rnn效果会比 单层好self.rnn = nn.RNN(input_size=input_dim,hidden_size=hidden_size,num_layers=rnn_layer_size,batch_first=True)# 不能使用pool# self.pool = nn.AvgPool1d(sentence_length)# 输出为0/1 2分类的self.classify = nn.Linear(hidden_size, 2)# -1 不参与计算self.loss = nn.CrossEntropyLoss(ignore_index=-1)def forward(self, x, y=None):x = self.emb(x)x, _ = self.rnn(x)# 用 polling 层# x= self.pool(x.transpose(1,2)).squeeze()y_pred = self.classify(x)if y is not None:# y_pred : n,class_num [[1,2,3][3,2,1]]# y : n                 [0     ,1     ]# 20*20*2===>view ===> 400 * 2   y===> 400 *1return self.loss(y_pred.view(-1, 2), y.view(-1))else:return y_pred# 使用jieba获取切分好的数据 来作为样本数据
# 我爱你们 === 1,1,0,1
def sequence_to_label(sentence):words = jieba.lcut(sentence)labels = [0] * len(sentence)pointer = 0for word in words:pointer += len(word)labels[pointer - 1] = 1return labels# 读取给定词表数据 构建字符集
def build_vocab(path):vocab = {}with open(path, encoding="utf8") as f:for index, line in enumerate(f):char = line.strip()vocab[char] = index + 1vocab['unk'] = len(vocab) + 1return vocabclass Dataset:def __init__(self, vocab, corpus_path, max_length):self.vocab = vocabself.corpus_path = corpus_pathself.max_length = max_lengthself.load()# 构建数据集def load(self):# data 的结构为 [x,y]self.data = []with open(self.corpus_path, encoding="utf8") as f:for line in f:vocab = self.vocab# 转化为 切分好的数据 yy = sequence_to_label(line)# 转化为数字x = [vocab.get(char, vocab['unk']) for char in line]# 都 标准化为最大长度x, y = self.padding(x, y)self.data.append([torch.LongTensor(x), torch.LongTensor(y)])# 使用部分数据做展示,使用全部数据训练时间会相应变长if len(self.data) > 10000:breakdef padding(self, x, y):# 长了就截取x = x[:self.max_length]# 短了就 补0x += [0] * (self.max_length - len(x))y = y[:self.max_length]# y 不能用 0y += [-1] * (self.max_length - len(y))return x, y# 为了给 data_load 使用 做小批量数据分割def __len__(self):return len(self.data)def __getitem__(self, item):return self.data[item]def build_dataset(vocab, corpus_path, max_length, batch_size):dataset = Dataset(vocab, corpus_path, max_length)# shuffle 随机打乱样本data_loader = DataLoader(dataset, shuffle=True, batch_size=batch_size)  # torchreturn data_loaderdef main():batch_size = 20lr = 1e-3epoch_size = 10vocab = build_vocab("D:\\NLP\\test\\week4\\chars.txt")hidden_size = 100# 每个字符的维度input_dim = 20rnn_layer_size = 2# 样本最大长度max_length = 20model = TorchModel(vocab, input_dim, hidden_size, rnn_layer_size)optim = torch.optim.Adam(model.parameters(), lr=lr)# 语料库(样本数据)路径corpus_path = "D:\\NLP\\test\\week4\\corpus.txt"dataiter = build_dataset(vocab, corpus_path, max_length, batch_size)for epoch in range(epoch_size):epoch_loss = []model.train()for x, y_true in dataiter:loss = model(x, y_true)loss.backward()optim.step()optim.zero_grad()epoch_loss.append(loss.item())print("第%d轮 loss = %f" % (epoch + 1, np.mean(epoch_loss)))# save modeltorch.save(model.state_dict(), "model.pth")return# 最终预测
def predict(model_path, vocab_path, input_strings):# 配置保持和训练时一致char_dim = 20  # 每个字的维度hidden_size = 100  # 隐含层维度num_rnn_layers = 2  # rnn层数vocab = build_vocab(vocab_path)  # 建立字表(字符集)model = TorchModel(vocab, char_dim, hidden_size, num_rnn_layers)  # 建立模型model.load_state_dict(torch.load(model_path))  # 加载训练好的模型权重model.eval()for input_string in input_strings:# 逐条预测x = [vocab.get(char, vocab['unk']) for char in input_string]with torch.no_grad():result = model.forward(torch.LongTensor([x]))[0]result = torch.argmax(result, dim=-1)  # 预测出的01序列# 在预测为1的地方切分,将切分后文本打印出来for index, p in enumerate(result):if p == 1:print(input_string[index], end=" ")else:print(input_string[index], end="")print()if __name__ == '__main__':main()# input_strings = ["同时国内有望出台新汽车刺激方案",#                  "沪胶后市有望延续强势",#                  "经过两个交易日的强势调整后",#                  "昨日上海天然橡胶期货价格再度大幅上扬"]# predict("model.pth", "D:\\NLP\\test\\week4\\chars.txt", input_strings)

http://www.mrgr.cn/p/32230218

相关文章

Python_AI库 Matplotlib的应用简例:绘制与保存折线图

本文默认读者已具备以下技能: 熟悉Python基础语法,以自行阅读python代码块熟悉Vscode或其它编辑工具的应用 在数据可视化领域,Matplotlib无疑是一个强大的工具。它允许我们创建各种静态、动态、交互式的可视化图形,帮助我们更好…

OpenHarmony实战开发-如何实现自定义绘制 (XComponent)

XComponent组件作为一种绘制组件,通常用于满足开发者较为复杂的自定义绘制需求,例如相机预览流的显示和游戏画面的绘制。 其可通过指定其type字段来实现不同的功能,主要有两个“surface”和“component”字段可供选择。 对于“surface”类型…

jvm中的引用类型

Java中的引用类型 1.强引用 一个对象A被局部变量、静态变量引用了就产生了强引用。因为局部变量、静态变量都是被GC Root对象关联上的,所以被引用的对象A,就在GC Root的引用链上了。只要这一层关系存在,对象A就不会被垃圾回收器回收。所以只要…

HarmonyOS 应用开发——入门

首先当然是华为的官方文档了,要认真学习: https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V2/start-overview-0000001478061421-V2 不想花时间看,可以看我下面总结的干货,哈哈 第一个问题:stage架构和fa架构的区…

Xcode 15构建问题

构建时出现的异常: 解决方式: 将ENABLE_USER_SCRIPT_SANDBOXING设为“no”即可!

Open3D(C++) 最小二乘拟合多项式曲线

目录 一、算法原理二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、算法原理 多项式曲线表示为: p ( x ) =

ROS1快速入门学习笔记 - 05发布者Publisher编程的实现

目录 一、话题模型(发布/订阅) 二、实现步骤 1. 创建一个功能包 2. C代码的实现 3. 配置发布者代码编译规则 4. 编译并运行发布者 5. Python代码的实现 一、话题模型(发布/订阅) 二、实现步骤 1. 创建一个功能包 $ cd~/ca…

IDEA实现Springboot项目自动热部署

每当我们在修改代码时,往往需要重新启动项目,这样不仅浪费时间而且很麻烦,我们可以通过IDEA的热部署来提高效率 1、首先点file >> settings >> Build Excution >> Compire,选择Build project auto matically 2.…

百度安全多篇议题入选Blackhat Asia以硬技术发现“芯”问题

Blackhat Asia 2024于4月中旬在新加坡隆重举行。此次大会聚集了业界最杰出的信息安全专业人士和研究者,为参会人员提供了安全领域最新的研究成果和发展趋势。在本次大会上,百度安全共有三篇技术议题被大会收录,主要围绕自动驾驶控制器安全、跨…

AG32 MCU在触摸屏的应用(AGM FPGA/MCU行业应用)

传统的屏驱MCU常见应用于洗衣机、空调、空调面板、仪器仪表等人机交互界面显示场景中,通常是以段码的形式显示设备运转的时间、温度、测量结果等简单运行数据,随着人机交互需求丰富化,智能家居设备、摩托车、电动车等产品也逐步增加了屏幕显示…

未来已来:解锁AGI的无限潜能与挑战

未来已来:解锁AGI的无限潜能与挑战 引言 假设你有一天醒来,发现你的智能手机不仅提醒你今天的日程,还把你昨晚做的那个奇怪的梦解释了一番,并建议你可能需要减少咖啡摄入量——这不是科幻电影的情节,而是人工通用智能…

c++补充

构造函数、析构函数 #include <iostream> using namespace std;// 构造函数、析构函数 // --- "构造函数"类比生活中的"出厂设置" --- // --- "析构函数"类比生活中的"销毁设置" --- // 如果我们不写这两种函数&#xff0c;编译…

云计算时代:SFP、SFP+、SFP28、QSFP+和QSFP28光纤模块详解

随着数据中心的快速发展和云计算的广泛应用&#xff0c;高速、高效率的光纤网络传输成为关键需求。在众多光纤模块中&#xff0c;SFP、SFP、SFP28、QSFP和QSFP28是最常见的几种类型。本文将为您详细解析这几种光纤模块之间的区别&#xff0c;帮助您更好地了解和选择适合自己需求…

安装crossover游戏提示容量不足怎么办 如何把游戏放到外置硬盘里 Mac电脑清理磁盘空间不足

CrossOver作为一款允许用户在非原生操作系统上运行游戏和应用程序的软件&#xff0c;为不同平台的用户提供了极大的便利。然而&#xff0c;随着游戏文件大小的不断增加&#xff0c;内置硬盘的容量往往无法满足安装需求。幸运的是&#xff0c;通过一些简单的步骤&#xff0c;我们…

【深度学习】神经网络中的激活函数:释放非线性的力量

神经网络中的激活函数&#xff1a;释放非线性的力量 一、激活函数的原理与作用二、激活函数的实例与代码实现三、激活函数的热点应用四、结语 在人工智能的浪潮中&#xff0c;人工神经网络&#xff08;ANN&#xff09;以其强大的学习和拟合能力&#xff0c;日益成为解决复杂问题…

pytest-xdist:远程多主机 - 分布式运行自动化测试

简介&#xff1a;pytest-xdist插件使用新的测试执行模式扩展了pytest&#xff0c;最常用的是在多个CPU之间分发测试以加快测试执行&#xff0c;即 pytest -n auto同时也是一个非常优秀的分布式测试插件&#xff0c;分别支持ssh和socket两种方式实现master和worker的远程通讯。…

Pytorch 之torch.nn初探 卷积--Convolution Layers

任务描述 本关任务&#xff1a; 本关提供了一个Variable 类型的变量input&#xff0c;按照要求创建一 Conv1d变量conv&#xff0c;对input应用卷积操作并赋值给变量 output&#xff0c;并输出output 的大小。 相关知识 卷积的本质就是用卷积核的参数来提取原始数据的特征&a…

ssm智能停车场管理系统

视频演示效果: SSMvue智能停车场 摘 要 本论文主要论述了如何使用JAVA语言开发一个智能停车场管理系统&#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论述智能停车…

Bert语言大模型基础

一、Bert整体模型架构 基础架构是transformer的encoder部分&#xff0c;bert使用多个encoder堆叠在一起。 主要分为三个部分&#xff1a;1、输入部分 2、注意力机制 3、前馈神经网络 bertbase使用12层encoder堆叠在一起&#xff0c;6个encoder堆叠在一起组成编码端&#xf…

在Linux系统内搭建DNS本地服务器

文章目录 Linux的本地DNS服务一、什么是DNS1.1、域名1.2、DNS服务器、DNS客户端和DNS中继1.3、DNS域名解析 二、搭建DNS服务2.1、正反向解析2.1.1.安装bind软件包2.1.2.修改主配置文件2.1.3.修改区域配置文件2.1.4.配置区域数据文件2.1.5.启动服务、关闭防火墙2.1.6.本地解析测…