RNN经典案例——构建人名分类器

RNN经典案例——人名分类器

  • 一、数据处理
    • 1.1 去掉语言中的重音标记
    • 1.2 读取数据
    • 1.3 构建人名类别与人名对应关系字典
    • 1.4 将人名转换为对应的onehot张量
  • 二、构建RNN模型
    • 2.1 构建传统RNN模型
    • 2.2 构建LSTM模型
    • 2.3 构建GRU模型
  • 三、构建训练函数并进行训练
    • 3.1 从输出结果中获得指定类别函数
    • 3.2 随机生成训练数据
    • 3.3 构建传统的RNN训练函数
    • 3.4 构建LSTM训练函数
    • 3.5 构建GRU训练函数
    • 3.6 构建时间计算函数
    • 3.7 构建训练过程的日志打印函数
    • 3.8 调用train函数, 进行模型的训练
  • 四、构建评估模型并预测
    • 4.1 构建传统RNN评估函数
    • 4.2 构建LSTM评估函数
    • 4.3 构建GRU评估函数
    • 4.4 构建预测函数

一、数据处理

from io import open
import glob
import os
import string 
import unicodedata
import random
import time
import math
import torch
import torch.nn as nn
import matplotlib.pyplot as plt

1.1 去掉语言中的重音标记

# 获取常用字符数量和常用标点
all_letters = string.ascii_letters + " .,;'"
n_letters = len(all_letters)
print("all_letters:",all_letters)
print("n_letters:",n_letters)

在这里插入图片描述

# 去掉一些语言中的重音标记
# 如: Ślusàrski ---> Slusarski
def unicodeToAscii(s):ascii = ''.join(# NFD会将每个字符分解为其基本字符和组合标记,Ś会拆分为音掉和S#'Mn'这类字符通常用于表示重音符号、音调符号等c for c in unicodedata.normalize('NFD',s) if unicodedata.category(c) != 'Mn' and c in all_letters)return ascii

1.2 读取数据

# 读取数据
data_path = "./data/names/"def readLines(filename):lines = open(filename,encoding='utf-8').read().strip().split('\n')return [unicodeToAscii(line) for line in lines]
# 调试
filename = data_path + "Chinese.txt"
lines = readLines(filename)
print(lines)

在这里插入图片描述

1.3 构建人名类别与人名对应关系字典

# 类别名字列表
category_lines = {}
# 类别名称
all_category = []for filename in glob.glob(data_path + '*.txt'):category = os.path.splitext(os.path.basename(filename))[0]all_category.append(category)lines = readLines(filename)category_lines[category] = lines# 查看类别总数
n_categories = len(all_category)
print("n_categories:",n_categories)

在这里插入图片描述

1.4 将人名转换为对应的onehot张量

def lineToTensor(line):tensor = torch.zeros(len(line),1,n_letters)for i,letter in enumerate(line):tensor[i][0][all_letters.find(letter)] = 1return tensor  
# 调试
line = 'cui'
line_tensor = lineToTensor(line)
line_tensor

在这里插入图片描述

二、构建RNN模型

2.1 构建传统RNN模型

class RNN(nn.Module):def __init__(self,input_size,hidden_size,output_size,num_layers=1):super(RNN,self).__init__()self.hidden_size = hidden_sizeself.num_layers = num_layers# 实例化RNNself.rnn = nn.RNN(input_size,hidden_size,num_layers)# RNN 层的输出转换为最终的输出特征self.linear = nn.Linear(hidden_size,output_size)# 将全连接层的输出特征转换为概率分布self.softmax = nn.LogSoftmax(dim=-1)def forward(self,input,hidden):# input 形状为1*n_letters需要变换为三维张量input = input.unsqueeze(0)rr,hn = self.rnn(input,hidden)return self.softmax(self.linear(rr)),hn# 定义初始化隐藏状态def initHidden(self):return torch.zeros(self.num_layers,1,self.hidden_size)

2.2 构建LSTM模型

class LSTM(nn.Module):def __init__(self,input_size,hidden_size,output_size,num_layers=1):super(LSTM,self).__init__()self.hidden_size = hidden_sizeself.num_layers = num_layersself.lstm = nn.LSTM(input_size,hidden_size,num_layers)self.linear = nn.Linear(hidden_size,output_size)self.softmax = nn.LogSoftmax(dim=-1)def forward(self,input,hidden,c):input = input.unsqueeze(0)rr,(hn,c) = self.lstm(input,(hidden,c))return self.softmax(self.linear(rr)),hn,cdef initHidden(self):hidden = c = torch.zeros(self.num_layers,1,self.hidden_size)return hidden,c

2.3 构建GRU模型

class GRU(nn.Module):def __init__(self,input_size,hidden_size,output_size,num_layers=1):super(GRU,self).__init__()self.hidden_size = hidden_sizeself.num_layers = num_layersself.gru = nn.GRU(input_size,hidden_size,num_layers)self.linear = nn.Linear(hidden_size,output_size)self.softmax = nn.LogSoftmax(dim=-1)def forward(self,input,hidden):input = input.unsqueeze(0)rr,hn = self.gru(input,hidden)return self.softmax(self.linear(rr)),hndef initHidden(self):return torch.zeros(self.num_layers,1,self.hidden_size)
# 调用
# 实例化参数
input_size = n_letters
n_hidden = 128
output_size = n_categoriesinput = lineToTensor('B').squeeze(0)
hidden = c = torch.zeros(1,1,n_hidden)rnn = RNN(n_letters,n_hidden,n_categories)
lstm = LSTM(n_letters,n_hidden,n_categories)
gru = GRU(n_letters,n_hidden,n_categories)rnn_output, next_hidden = rnn(input, hidden)
print("rnn:", rnn_output)
lstm_output, next_hidden, c = lstm(input, hidden, c)
print("lstm:", lstm_output)
gru_output, next_hidden = gru(input, hidden)
print("gru:", gru_output) 

在这里插入图片描述

三、构建训练函数并进行训练

3.1 从输出结果中获得指定类别函数

def categoryFromOutput(output):# 从输出张量中返回最大的值和索引top_n,top_i = output.topk(1)category_i = top_i[0].item()# 获取对应语言类别, 返回语⾔类别和索引值return all_category[category_i],category_i
# 调试
category, category_i = categoryFromOutput(gru_output)
print("category:", category)
print("category_i:", category_i)

在这里插入图片描述

3.2 随机生成训练数据

def randomTrainingExample():# 随机获取一个类别category = random.choice(all_category)# 随机获取该类别中的名字line = random.choice(category_lines[category])# 将类别索引转换为tensor张量category_tensor = torch.tensor([all_category.index(category)],dtype=torch.long)# 对名字进行onehot编码line_tensor = lineToTensor(line)return category,line,category_tensor,line_tensor
# 调试
for i in range(10):category,line,category_tensor,line_tensor = randomTrainingExample()print('category =',category,'/ line =',line,'/ category_tensor =',category_tensor,'/ line_tensor =',line_tensor)

在这里插入图片描述

3.3 构建传统的RNN训练函数

# 定义损失函数
criterion = nn.NLLLoss()
# 设置学习率为0.005
learning_rate = 0.005
import torch.optim as optim
def trainRNN(category_tensor,line_tensor):# 实例化对象rnn初始化隐层张量hidden = rnn.initHidden()# 梯度清零optimizer = optim.SGD(rnn.parameters(),lr=0.01,momentum=0.9)optimizer.zero_grad()# 前向传播for i in range(line_tensor.size()[0]):# output 是 RNN 在每个时间步的输出。每个时间步的输出是一个隐藏状态,这些隐藏状态可以用于后续的处理,例如分类、回归等任务。# hidden是 RNN 在最后一个时间步的隐藏状态。这些隐藏状态可以用于捕获整个序列的信息,通常用于后续的处理,例如作为下一个层的输入。output,hidden = rnn(line_tensor[i],hidden)# 计算损失loss = criterion(output.squeeze(0),category_tensor)# 反向传播loss.backward()optimizer.step()# 更新模型中的参数#for p in rnn.parameters():#p.data.add_(-learning_rate,p.grad.data)return output,loss.item()

3.4 构建LSTM训练函数

def trainLSTM(category_tensor,line_tensor):hidden,c = lstm.initHidden()lstm.zero_grad()for i in range(line_tensor.size()[0]):output,hidden,c = lstm(line_tensor[i],hidden,c)loss = criterion(output.squeeze(0),category_tensor)loss.backward()for p in lstm.parameters():p.data.add_(-learning_rate,p.grad.data)return output,loss.item()

3.5 构建GRU训练函数

def trainGRU(category_tensor,line_tensor):hidden = gru.initHidden()gru.zero_grad()for i in range(line_tensor.size()[0]):output,hidden = gru(line_tensor[i],hidden)loss = criterion(output.squeeze(0),category_tensor)loss.backward()for p in gru.parameters():p.data.add_(-learning_rate,p.grad.data)return output,loss.item()

3.6 构建时间计算函数

# 获取每次打印的训练耗时
def timeSince(since):# 获得当前时间now = time.time()# 获取时间差s = now - since# 将秒转换为分m = s // 60# 计算不够1分钟的秒数s -= m * 60return '%dm %ds' % (m,s)

3.7 构建训练过程的日志打印函数

# 设置训练迭代次数
n_iters= 1000
# 设置结果的打印间隔
print_every = 50
# 设置绘制损失曲线上的打印间隔
plot_every = 10
def train(train_typr_fn):# 保存每个间隔的损失函数all_losses = []# 获得训练开始的时间戳start = time.time()# 设置当前间隔损失为0current_loss = 0# 循环训练for iter in range(1,n_iters+1):category,line,category_tensor,line_tensor = randomTrainingExample()output,loss = train_typr_fn(category_tensor,line_tensor)# 计算打印间隔的总损失current_loss += lossif iter % print_every == 0:# 获得预测的类别和索引guess,guess_i = categoryFromOutput(output)if guess == category:correct = '✓'else:correct = '✗(%s)' % categoryprint('%d %d%% (%s) %.4f %s / %s %s' % (iter, iter / n_iters *100, timeSince(start), loss, line, guess, correct))if iter % plot_every == 0:all_losses.append(current_loss / plot_every)current_loss = 0 return all_losses,int(time.time()-start)       

3.8 调用train函数, 进行模型的训练

# 调⽤train函数, 分别进⾏RNN, LSTM, GRU模型的训练
all_losses1, period1 = train(trainRNN)
all_losses2, period2 = train(trainLSTM)
all_losses3, period3 = train(trainGRU)

在这里插入图片描述

# 创建画布0
plt.figure(0)
# 绘制损失对⽐曲线
plt.plot(all_losses1, label="RNN")
plt.plot(all_losses2, color="red", label="LSTM")
plt.plot(all_losses3, color="orange", label="GRU")
plt.legend(loc='upper left')# 创建画布1
plt.figure(1)
x_data=["RNN", "LSTM", "GRU"]
y_data = [period1, period2, period3]
# 绘制训练耗时对⽐柱状图
plt.bar(range(len(x_data)), y_data, tick_label=x_data)

在这里插入图片描述
在这里插入图片描述

四、构建评估模型并预测

4.1 构建传统RNN评估函数

# 构建传统RNN评估函数
def evaluateRNN(line_tensor):hidden = rnn.initHidden()for i in range(line_tensor.size()[0]):output,hidden = rnn(line_tensor[i],hidden)return output.squeeze(0)

4.2 构建LSTM评估函数

# 构建LSTM评估函数
def evaluateLSTM(line_tensor):hidden,c = lstm.initHidden()for i in range(line_tensor.size()[0]):output,hidden,c = lstm(line_tensor[i],hidden,c)return output.squeeze(0)

4.3 构建GRU评估函数

# 构建GRU评估函数
def evaluateGRU(line_tensor):hidden = gru.initHidden()for i in range(line_tensor.size()[0]):output,hidden = gru(line_tensor[i],hidden)return output.squeeze(0)
# 调试
line = "Bai"
line_tensor = lineToTensor(line)rnn_output = evaluateRNN(line_tensor)
lstm_output = evaluateLSTM(line_tensor)
gru_output = evaluateGRU(line_tensor)
print("rnn_output:", rnn_output)
print("gru_output:", lstm_output)
print("gru_output:", gru_output)

在这里插入图片描述

4.4 构建预测函数

def predict(input_line,evaluate,n_predictions=3):print('\n> %s' % input_line)with torch.no_grad():output = evaluate(lineToTensor(input_line))topv,topi = output.topk(n_predictions,1,True)predictions = []for i in range(n_predictions):# 从topv中取出的output值value = topv[0][i].item()# 取出索引并找到对应的类别category_index = topi[0][i].item()# 打印ouput的值, 和对应的类别print('(%.2f) %s' % (value, all_category[category_index]))# 将结果装进predictions中predictions.append([value, all_category[category_index]])
for evaluate_fn in [evaluateRNN, evaluateLSTM, evaluateGRU]:print("-"*18)predict('Dovesky', evaluate_fn)predict('Jackson', evaluate_fn)predict('Satoshi', evaluate_fn)

在这里插入图片描述

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

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

相关文章

【可答疑】基于51单片机的智能台灯(含仿真、代码、报告、演示视频等)

✨哈喽大家好,这里是每天一杯冰美式oh,985电子本硕,大厂嵌入式在职0.3年,业余时间做做单片机小项目,有需要也可以提供就业指导(免费)~ 🐱‍🐉这是51单片机毕业设计100篇…

2025秋招LLM大模型多模态面试题(九)-- LoRA 面试问题大全:从理论到实践

随着深度学习模型的不断发展,微调大模型的需求也逐渐增多。然而,传统的全参数微调需要消耗大量的计算资源和显存,对于普通用户和中小企业来说负担较大。为了应对这些问题,LoRA(Low-Rank Adaptation)应运而生。LoRA 是一种高效微调技术,通过低秩分解的方式显著减少训练参…

单目三d重建学习笔记2024

从单目视频生成动态多物体场景 已经开源: https://github.com/dreamscene4d/dreamscene4d 2021年: 浙大团队研发NeuralRecon,首个基于学习的实时单目三维重建系统 https://github.com/zju3dv/NeuralRecon https://github.com/zju3dv/Neura…

数据分析-28-交互式数据分析EDA工具和低代码数据科学工具

文章目录 1 数据分析的七步指南1.1 第一步:问题定义和数据采集1.2 第二步:数据清洗和预处理1.3 第三步:数据探索和分析1.4 第四步:模型建立和分析1.5 第五步:数据可视化1.6 第六步:结果解释和报告1.7 第七步:部署和维护1.8 基础的数据分析库1.9 低代码数据科学工具2 EDA…

Flutter InAppWebView 路由导航处理

flutter InAppWebView路由导航处理,有以下两种处理方案: H5层控制路由,H5拥有自己的路由,当返回到跟路由root时,此时点击跟节点,通过jsbridge调用flutter提供的方法来关闭当前widget,flutter关…

改变数组页面重新渲染的操作/那些操作不会重新渲染页面以及解决方法

在前端开发中,当数组数据发生变化时,是否会导致页面重新渲染,以及如何进行相关操作,这取决于使用的具体框架或库(如React、Vue等)及其内部机制。以下是对这一问题的详细解答: 一、会导致页面重…

STM32 通用定时器

一、概述 STM32内部集成了多个定时/计数器,根据型号不同,STM32系列芯片最多包含8个定时/计数器。其中,TIM6、TIM7为基本定时器,TIM2~TIM5为通用定时器,TIM1、TIM8为高级控制定时器。 1.定时器的类型 基本定时器通用定…

实战案例:结合大模型与爬虫技术实现12306智能查票系统

大语言模型,例如 GPT-4,拥有强大的知识储备和语言理解能力,能够进行流畅的对话、创作精彩的故事,甚至编写代码。然而,它们也面临着一些难以克服的困境,就像一个空有知识却无法行动的巨人 信息滞后&#xf…

Linux 之 安装软件、GCC编译器、Linux 操作系统基础

安装软件、GCC编译器、Linux 操作系统基础 学习任务: 安装 Vmware虚拟机、掌握Ubuntu 系统的使用认识 Ubuntu 操作系统的终端和 Shell掌握软件安装、文件系统、掌握磁盘管理与解压缩掌握 VIM 编辑器、Makefile 基本语法熟悉 Linux 常见指令操作 安装好开发软件&…

148.排序链表

文章目录 方法1:自顶向下的归并排序方法2 自底向上的归并排序 方法1:自顶向下的归并排序 使用归并排序算法。归并排序是一种分治算法,它将链表分成两半,然后对每一半进行排序,最后将两个有序的链表合并。由于链表不支…

[Go语言快速上手]初识Go语言

目录 一、什么是Go语言 二、第一段Go程序 1、Go语言结构 注意 2、Go基础语法 关键字 运算符优先级 三、Go语言数据类型 示例 小结 一、什么是Go语言 Go语言,通常被称为Golang,是一种静态类型、编译型的计算机编程语言。它由Google的Robert Gr…

用HTML5+CSS+JavaScript庆祝国庆

用HTML5CSSJavaScript庆祝国庆 中华人民共和国的国庆日是每年的10月1日。 1949年10月1日,中华人民共和国中央人民政府成立,在首都北京天安门广场举行了开国大典,中央人民政府主席毛泽东庄严宣告中华人民共和国成立,并亲手升起了…

Vue3 中Ref的最佳实践

在vue3中如果我们需要获取一个响应式的变量,可以使用ref来定义一个变量。 const name ref( "" );name.value "test" 定义好后,就可以实现修改状态,更新UI的效果了。 在这个基础上,本文主要讨论跨组件时如何…

Discord:报错:A fatal Javascript error occured(解决办法)

按 Windows 键 R 并输入 %appdata% 选择 discord 文件夹并将其删除。 再次按 Windows 键 R 并输入 %LocalAppData% 选择 discord 文件夹并再次将其删除。 附加: 如果还不行,就通过官网下载吧,这个问题通过epic下载可能会有

Python并发编程挑战与解决方案

Python并发编程挑战与解决方案 并发编程是现代软件开发中的一项核心能力,它允许多个任务同时运行,提高程序的性能和响应速度。Python因其易用性和灵活性而广受欢迎,但其全局解释器锁(GIL)以及其他特性给并发编程带来了…

Docker面试-24年

1、Docker 是什么? Docker一个开源的应用容器引擎,是实现容器技术的一种工具,让开发者可以打包他们的应用以及环境到一个镜像中,可以快速的发布到任何流行的操作系统上。 2、Docker的三大核心是什么? 镜像:Docker的…

FANUC机器人—PCDK

前言 FANUC提供了一种使用其 PC 开发人员套件 (PCDK) 从 PC 命令和配置机器人的简单方法。该套件允许 PC 访问机器人上的变量、寄存器、IO、程序、位置和警报;接下来,我将如何开始使用 C#。 连接到机器人 将以下突出显示的行添加…

网络威胁情报技术的进步

网络威胁形势不断演变,必然导致防御者和攻击者之间持续展开军备竞赛。幸运的是,网络威胁情报 (CTI) 技术的进步为安全专业人员提供了强大的工具,使他们能够保持领先地位。 本指南深入探讨了 CTI 的最新进展,让您了解这些技术如何…

【AI知识点】假设检验(Hypothesis Testing)

假设检验(Hypothesis Testing) 是统计推断中用来判断一个关于总体参数的假设是否成立的标准方法。它通过样本数据来做出推断,从而确定是否可以拒绝原先设定的假设。假设检验广泛应用于科学实验、社会调查、质量控制等领域,用于验证…

【学习笔记】手写一个简单的 Spring MVC

目录 一、什么是Spring MVC ? Spring 和 Spring MVC 的区别? Spring MVC 的运行流程? 二、实现步骤 1. DispatcherServlet 1. 创建一个中央分发器 拦截所有请求 测试 2. 接管 IOC 容器 1. 创建配置文件 2. 修改 web.xml 配置文件 …