RNN人名分类器算法

1.优化处理

1.使用teacherforcing算法优化。

2.超参数调节,学习率调节,numepoch=80000,1000000。

3.rnn,lstm,gru算法对比

2.rnn,lstm,gru算法对比可视化

numepoch=80000

numepoch=1000000

3.代码段

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 pltall_letters = string.ascii_letters + " .,;'"
n_letters = len(all_letters)
# print("n_letters:", n_letters)# 函数的作用是去掉一些语言中的重音标记
def unicodeToAscii(s):return ''.join(c for c in unicodedata.normalize('NFD', s)if unicodedata.category(c) != 'Mn' and c in all_letters)s = "Ślusàrski"
a = unicodeToAscii(s)
# print(a)data_path = "./data/"def readLines(filename):# 打开指定的文件并读取所有的内容, 使用strip()去除掉两侧的空白符, 然后以'\n'为换行符进行切分lines = open(filename, encoding='utf-8').read().strip().split('\n')return [unicodeToAscii(line) for line in lines]filename = data_path + "Chinese.txt"
result = readLines(filename)
# print(result[:20])# 构建一个人名类别与具体人名对应关系的字典
category_lines = {}# 构建所有类别的列表
all_categories = []# 遍历所有的文件, 使用glob.glob中可以利用正则表达式的便利
for filename in glob.glob(data_path + "*.txt"):# 获取每个文件的文件名, 起始就是得到名字的类别category = os.path.splitext(os.path.basename(filename))[0]# 逐一将其装入所有类别的列表中all_categories.append(category)# 然后读取每个文件的内容, 形成名字的列表lines = readLines(filename)# 按照对应的类别, 将名字列表写入到category_lines字典中category_lines[category] = linesn_categories = len(all_categories)
# print("n_categories:", n_categories)# print(category_lines['Italian'][:10])def lineToTensor(line):# 首先初始化一个全0的张量, 这个张量的形状是(len(line), 1, n_letters)# 代表人名中的每一个字母都用一个(1 * n_letters)张量来表示tensor = torch.zeros(len(line), 1, n_letters)# 遍历每个人名中的每个字符, 并搜索其对应的索引, 将该索引位置置1for li, letter in enumerate(line):tensor[li][0][all_letters.find(letter)] = 1return tensorline = "Bai"
line_tensor = lineToTensor(line)
# print("line_tensor:", line_tensor)class RNN(nn.Module):def __init__(self, input_size, hidden_size, output_size, num_layers=1):# input_size: 代表RNN输入的最后一个维度# hidden_size: 代表RNN隐藏层的最后一个维度# output_size: 代表RNN网络最后线性层的输出维度# num_layers: 代表RNN网络的层数super(RNN, self).__init__()self.input_size = input_sizeself.hidden_size = hidden_sizeself.output_size = output_sizeself.num_layers = num_layers# 实例化预定义的RNN,三个参数分别是input_size, hidden_size, num_layersself.rnn = nn.RNN(input_size, hidden_size, num_layers)# 实例化全连接线性层, 作用是将RNN的输出维度转换成指定的输出维度self.linear = nn.Linear(hidden_size, output_size)# 实例化nn中预定义的Softmax层, 用于从输出层中获得类别的结果self.softmax = nn.LogSoftmax(dim=-1)def forward(self, input1, hidden):# input1: 代表人名分类器中的输入张量, 形状是1 * n_letters# hidden: 代表RNN的隐藏层张量, 形状是 self.num_layers * 1 * self.hidden_size# 注意一点: 输入到RNN中的张量要求是三维张量, 所以需要用unsqueeze()函数扩充维度input1 = input1.unsqueeze(0)# 将input1和hidden输入到RNN的实例化对象中, 如果num_layers=1, rr恒等于hnrr, hn = self.rnn(input1, hidden)# 将从RNN中获得的结果通过线性层的变换和softmax层的处理, 最终返回return self.softmax(self.linear(rr)), hndef initHidden(self):# 本函数的作用是用来初始化一个全零的隐藏层张量, 维度是3return torch.zeros(self.num_layers, 1, self.hidden_size)class LSTM(nn.Module):def __init__(self, input_size, hidden_size, output_size, num_layers=1):# input_size: 代表输入张量x中最后一个维度# hidden_size: 代表隐藏层张量的最后一个维度# output_size: 代表线性层最后的输出维度# num_layers: 代表LSTM网络的层数super(LSTM, self).__init__()self.input_size = input_sizeself.hidden_size = hidden_sizeself.output_size = output_sizeself.num_layers = num_layers# 实例化LSTM对象self.lstm = nn.LSTM(input_size, hidden_size, num_layers)# 实例化线性层, 作用是将LSTM网络的输出维度转换成指定的输出维度self.linear = nn.Linear(hidden_size, output_size)# 实例化nn中预定义的Softmax层, 作用从输出层的张量中得到类别结果self.softmax = nn.LogSoftmax(dim=-1)def forward(self, input1, hidden, c):# 注意: LSTM网络的输入有3个张量,尤其不要忘记细胞状态cinput1 = input1.unsqueeze(0)# 将3个参数输入到LSTM对象中rr, (hn, cn) = self.lstm(input1, (hidden, c))# 最后将3个张量结果全部返回, 同时rr要经过线性层和softmax的处理return self.softmax(self.linear(rr)), hn, cndef initHiddenAndC(self):# 注意: 对于LSTM来说, 初始化的时候要同时初始化hidden和细胞状态c# hidden和c的形状保持一致c = hidden = torch.zeros(self.num_layers, 1, self.hidden_size)return hidden, c# 参数
input_size = n_lettersn_hidden = 128output_size = n_categoriesinput1 = lineToTensor('B').squeeze(0)hidden = c = torch.zeros(1, 1, n_hidden)rnn = RNN(input_size, n_hidden, output_size)
lstm = LSTM(input_size, n_hidden, output_size)
gru = GRU(input_size, n_hidden, output_size)rnn_output, next_hidden = rnn(input1, hidden)
# print('rnn:', rnn_output)
# print('rnn_shape:', rnn_output.shape)
# print('***********')lstm_output, next_hidden1, c = lstm(input1, hidden, c)
# print('lstm:', lstm_output)
# print('lstm_shape:', lstm_output.shape)
# print('***********')gru_output, next_hidden2 = gru(input1, hidden)
# print('gru:', gru_output)
# print('gru_shape:', gru_output.shape)def categoryFromOutput(output):# output: 从输出结果中得到指定的类别# 需要调用topk()函数, 得到最大的值和索引, 作为我们的类别信息top_n, top_i = output.topk(1)# 从top_i中取出索引的值category_i = top_i[0].item()# 从前面已经构造号的all_categories中得到对应语言的类别,返回类别和索引return all_categories[category_i], category_i# x = torch.arange(1, 6)
# print(x)
# res = torch.topk(x, 3)
# print(res)# category, category_i = categoryFromOutput(gru_output)
# print('category:', category)
# print('category_i:', category_i)def randomTrainingExample():# 该函数的作用用于随机产生训练数据# 第一步使用random.choice()方法从all_categories中随机选择一个类别category = random.choice(all_categories)# 第二步通过category_lines字典取出category类别对应的名字列表line = random.choice(category_lines[category])# 第三步将类别封装成tensorcategory_tensor = torch.tensor([all_categories.index(category)], dtype=torch.long)# 将随机取到的名字通过函数lineToTensor()转换成onehot张量line_tensor = lineToTensor(line)return category, line, category_tensor, line_tensor# 定义损失函数, nn.NLLLoss()函数, 因为和RNN最后一层的nn.LogSoftmax()逻辑匹配
criterion = nn.NLLLoss()# 设置学习率为0.005
learning_rate = 0.005def trainRNN(category_tensor, line_tensor):# category_tensor: 代表训练数据的标签# line_tensor: 代表训练数据的特征# 第一步要初始化一个RNN隐藏层的张量hidden = rnn.initHidden()# 关键的一步: 将模型结构中的梯度归零rnn.zero_grad()# 循环遍历训练数据line_tensor中的每一个字符, 传入RNN中, 并且迭代更新hiddenfor i in range(line_tensor.size()[0]):output, hidden = rnn(line_tensor[i], hidden)# 因为RNN的输出是三维张量, 为了满足category_tensor, 需要进行降维操作loss = criterion(output.squeeze(0), category_tensor)# 进行反向传播loss.backward()# 显示的更新模型中所有的参数for p in rnn.parameters():# 将参数的张量标识与参数的梯度进行乘法运算并乘以学习率, 结果加到参数上, 并进行覆盖更新p.data.add_(-learning_rate, p.grad.data)# 返回RNN最终的输出结果output, 和模型的损失lossreturn output, loss.item()def trainLSTM(category_tensor, line_tensor):# 初始化隐藏层张量, 以及初始化细胞状态hidden, c = lstm.initHiddenAndC()# 先要将LSTM网络的梯度归零lstm.zero_grad()# 遍历所有的输入时间步的xifor i in range(line_tensor.size()[0]):# 注意LSTM每次输入包含3个张量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()def timeSince(since):# 本函数的作用是打印每次训练的耗时, since是训练开始的时间# 第一步获取当前的时间now = time.time()# 第二步得到时间差s = now - since# 第三步计算得到分钟数m = math.floor(s / 60)# 第四步得到秒数s -= m * 60# 返回指定格式的耗时return '%dm %ds' % (m, s)# 设置训练的迭代次数
n_iters = 400000
# 设置结果的打印间隔
print_every = 100
# 设置绘制损失曲线上的制图间隔
plot_every = 4000def train(train_type_fn):# train_type_fn代表选择哪种模型来训练函数, 比如选择trainRNN# 初始化存储每个制图间隔损失的列表all_losses = []# 获取训练开始的时间start = time.time()# 设置初始间隔的损失值等于0current_loss = 0# 迭代训练for iter in range(1, n_iters + 1):# 通过randomTrainingExample()函数随机获取一组训练数据和标签category, line, category_tensor, line_tensor = randomTrainingExample()# 将训练特征和标签张量传入训练函数中, 进行模型的训练output, loss = train_type_fn(category_tensor, line_tensor)# 累加损失值current_loss += loss# 如果到了迭代次数的打印间隔if iter % print_every == 0:# 取该迭代步的output通过函数categoryFromOutput()获取对应的类别和索引guess, guess_i = categoryFromOutput(output)# 判断和真实的类别标签进行比较, 如果相同则为True,如果不同则为Falsecorrect = 'True' if guess == category else 'False (%s)' % category# 打印若干信息print('%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列表中all_losses.append(current_loss / plot_every)# 将间隔损失值重置为0current_loss = 0# 返回对应的总损失列表, 并返回训练的耗时return all_losses, int(time.time() - start)print('okokok==============================================')
# 调用train函数, 分别传入RNN, LSTM, GRU的训练函数
# 返回的损失列表, 以及训练时间
all_losses1, period1 = train(trainRNN)
all_losses2, period2 = train(trainLSTM)
all_losses3, period3 = train(trainGRU)#绘制损失对比曲线
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")
plt.savefig('./00-11.jpg')
# 绘制训练耗时的柱状图
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)
plt.savefig('./00-21.jpg')

q我找代码

RNN-人名分类器算法相关推荐

  1. RNN模型构建人名分类器

    2.1 使用RNN模型构建人名分类器 学习目标: 了解有关人名分类问题和有关数据. 掌握使用RNN构建人名分类器实现过程. 关于人名分类问题: 以一个人名为输入, 使用模型帮助我们判断它最有可能是来自 ...

  2. 使用RNN模型构建人名分类器

    查看全文 http://www.taodudu.cc/news/show-2891405.html 相关文章: RNN模型构建人名分类器 Jenkins服务器迁移 阿里云服务器迁移注意事项等问题 从腾 ...

  3. Pytorch:RNN、LSTM、GRU 构建人名分类器(one-hot版本、Embedding嵌入层版本)

    日萌社 人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新) 2. RNN经典案例 2.1 使用RNN模型构建人名分类器 学 ...

  4. 基于RNN系列的人名分类器【数据处理-训练-预测-评估-调优】

    基于RNN系列的人名分类器 第一步:导入必备工具包 第二步:数据处理 文本信息规范化 编码 第三步:构建RNN系列网络 RNN网络 LSTM网络 GRU网络 第四步:构建模型训练 RNN训练函数 LS ...

  5. 自然语言处理入门——使用RNN模型构建人名分类器

    自然语言处理入门 使用RNN模型构建人名分类器 以一个人名为输入,使用模型帮助判断最有可能是来自哪一个国家的人名,在某些国际化公司的业务中具有重要意义,例如在用户注册过程中,会根据用户填写的名字直接分 ...

  6. Machine Learning | (8) Scikit-learn的分类器算法-随机森林(Random Forest)

    Machine Learning | 机器学习简介 Machine Learning | (1) Scikit-learn与特征工程 Machine Learning | (2) sklearn数据集 ...

  7. Machine Learning | (7) Scikit-learn的分类器算法-决策树(Decision Tree)

    Machine Learning | 机器学习简介 Machine Learning | (1) Scikit-learn与特征工程 Machine Learning | (2) sklearn数据集 ...

  8. Machine Learning | (6) Scikit-learn的分类器算法-性能评估

    Machine Learning | 机器学习简介 Machine Learning | (1) Scikit-learn与特征工程 Machine Learning | (2) sklearn数据集 ...

  9. Machine Learning | (5) Scikit-learn的分类器算法-朴素贝叶斯

    Machine Learning | 机器学习简介 Machine Learning | (1) Scikit-learn与特征工程 Machine Learning | (2) sklearn数据集 ...

最新文章

  1. 不错的jquery插件
  2. VirtualBox uuid冲突问题
  3. MFC载入JPG图片
  4. jsf标签p:ajax_JSF AJAX请求的会话超时处理
  5. caffe boost cuda __float128 undefined
  6. 【译】在设计表单的时候应该注意的八点
  7. java数据流无法输出验证码
  8. Win11如何提高游戏性能?Win11提升游戏性能的方法
  9. Javascript第三章循环最后一种方法for..in与for区别第二课
  10. unix学习笔记1 read () write()
  11. SMO算法是干什么的?有什么作用?
  12. windows下jenkins批处理执行git pull失败的原因
  13. 优麒麟 22.04 LTS 版本正式发布 | UKUI 3.1开启全新体验
  14. 前端基础 HTML 第九章 使用框架结构 ----暑假学习第五天
  15. Hbase安装~Hbase安装过程中常见的问题
  16. HTML期末学生大作业 响应式动漫网页作业 html+css+javascript
  17. input输入字符限制
  18. 中科院自动化研究所彭思龙:科学家创业的“七宗罪”
  19. 什么是AES对称加密算法
  20. GOF23种设计模式精解

热门文章

  1. sql知识——数据库设计
  2. 最近我都干了些什么——反思!!
  3. springboot项目开发实战
  4. 原生js遍历 json数组对象
  5. 命悬一线丨33岁程序员垂死经历为所有人敲响警钟!
  6. js鼠标移动到某个元素上改变鼠标样式,如悬浮小手、禁用鼠标、等待...
  7. python修改列表元素_python 3 基础之列表和列表添加元素、修改元素、查找元素、删除元素、排序、嵌套、取最值...
  8. 高防CDN如何防御网络攻击
  9. 第十次作业 - 项目测评(团队)
  10. Oracle选择填空题中英文,oracle中英文分开排序