用RNN构建人名分类器

目录

  • 项目综述
  • 1.导入必备的工具包
  • 2.处理数据,满足训练要求
    • 2.1 统计常用的字符
    • 2.2 进行规范化处理,去除重音符号
    • 2.3 将文件读取到内存中
    • 2.4 构建人名国家和具体人名的对应关系
    • 2.5 one-hot编码
  • 3.构建RNN模型
    • 3.1 构建传统RNN模型
    • 3.2 构建传统LSTM模型
    • 3.3 构建传统GRU模型
    • 3.4 测试输出
  • 4.构建训练函数并进行训练
    • 4.1辅助函数
      • 4.1.1 返回指定的类别函数
      • 4.1.2 随机产生训练数据函数
      • 4.1.3 耗时计算函数
    • 4.2构建传统RNN训练函数
    • 4.3LSTM训练函数
    • 4.4GRU训练函数
    • 4.5 训练过程的日志打印函数
  • 5.构建评估函数并进行验证
    • 5.1 传统RNN评估函数
    • 5.2 LSTM评估函数
    • 5.3 GRU评估函数
    • 5.4 预测函数

在这里插入图片描述

项目综述

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

  • 该任务并没有分训练集和验证集,数据集为随机产生的,这样的优点是即使所给名字不在数据集里也可将其转化成模型可接受的张量;
  • 分训练集和验证集要考虑两者数据的平衡,对于不在数据集里无法将其转化成模型可接受的张量。

1.导入必备的工具包

#从io中导入文件打开方式
from io import open
#帮助使用正则化表达式进行子目录的查询
import glob
import os
#用于获得常见字母及字符规范化
import string
import unicodedata
#导入随机工具
import random
#导入时间和数学工具包
import time
import math
#导入torch工具,构建模型
import torch
import torch.nn as nn
#引入制图工具包
import matplotlib.pyplot as plt

导入工具包:
Win+R输入cmd进入到CMD窗口下;
执行:pip install xxx -i https://pypi.tuna.tsinghua.edu.cn/simple
其中xxx为所要安装的工具包

2.处理数据,满足训练要求

下载数据集:数据集地址
注意:
数据集要将最后一个空白去除,即
在这里插入图片描述
不然会将其当作一个数据(之后被选中时会报错)

2.1 统计常用的字符

#获取所有常用字符(字母和标点)
#string.ascii_letters表示26个小写字母和26个小大写
all_letters=string.ascii_letters+" .,;'"
#表示52个字母(先小写后大写)再加上空格、句号、逗号、分号、单引号n_letters=len(all_letters) #57

2.2 进行规范化处理,去除重音符号

def unicodeToAscii(s):return ''.join(c for c in unicodedata.normalize('NFD',s)#以下是判断是否去除成功且在all_letters中if unicodedata.category(c)!='Mn' #'Mn'表示有标记字符and c in all_letters)

在这里插入图片描述

2.3 将文件读取到内存中

data_path="./data/names/"
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+"Portuguese.txt"
results=readLines(filename)
print(results[:20])

在这里插入图片描述

2.4 构建人名国家和具体人名的对应关系

#构建一个人名类别与具体人名对应的字典
category_lines={} #即形如{“English”:["Lily",...],"Chinese":["Zhang",...],...}
#构建所有类别的列表
all_categories=[] #所有国家名#遍历所有文件,使用glob.glob中可以利用正则表达式的便利
for filename in glob.glob(data_path+"*.txt"):#获取每个文件的文件名:os.path.basename(filename)获取:国家.txt,如Chinese.txt#os.path.splitext()将其分为Chinese和.txt两部分#[0]表示去Chinese(第一个)category=os.path.splitext(os.path.basename(filename))[0]#将获取的每个国家名放入所有类别的列表中all_categories.append(category)#读取每个文件的内容,形成名字的列表lines=readLines(filename)#按照对应类别,将名字列表写入category_lines字典中#最终形成键值:国家名,value值:名字列表category_lines[category]=lines#测试:
n_categories=len(all_categories)#表示有18个国家的人
print(n_categories)
print(category_lines['Italian'][:10])#打印出Italian中的前10个人名

在这里插入图片描述

2.5 one-hot编码

什么是one-hot编码
枚举enumerate函数

#使得每一个人名都有对应的张量,该张量维度为x*1*y
#x层:人名所含字母个数;即每一个字母都用1*y的张量表示
# 1行;
# y列:所有可能用到的字符个数
def lineToTensor(line):#初始化一个全零张量,维度为(len(line),1,n_letters)tensor=torch.zeros(len(line),1,n_letters)#遍历每个人名中的每一个字符,搜索其对应的索引值,将该索引值所对应的全零张量中某一位赋值为1#比如:abc:第一层中第一个为1,其余全为0;第二层中第二个元素为1;第三层中第三个元素为1for k,letter in enumerate(line):tensor[k][0][all_letters.find(letter)]=1return tensor#测试:
line="abc"
tensor=lineToTensor(line)
print(tensor)

在这里插入图片描述

3.构建RNN模型

压缩只能在维度为1是才可压缩,若所在维度不为1则不可压缩。(扩充同上)
torch.unsqueeze函数
squeeze、unsqueeze函数

x=torch.tensor([0,1,2,3])  #一维
y1=torch.unsqueeze(x,0)  #形状1*4
y2=torch.unsqueeze(x,1)  #形状4*1
print(y1)
print(y1.shape)
print(y2)
print(y2.shape)

在这里插入图片描述

3.1 构建传统RNN模型

#构建传统RNN模型
class RNN(nn.Module):def __init__(self,input_size,hidden_size,output_size,num_layers=1):#input_size:输入张量维度、hidden_size:隐藏层维度、output_size:输出维度super(RNN,self).__init__() # 调用父类(nn.Module)的__init__self.input_size=input_size #代表RNN输入的最后一个维度self.hidden_size=hidden_size #代表RNN隐藏层的最后一个维度self.output_size=output_size #代表RNN网络最后线性层的输出维度self.num_layers=num_layers #代表RNN网络层数#实例化nn.RNNself.rnn=nn.RNN(input_size,hidden_size,num_layers)#nn.Linear和nn.LogSoftmax用于将RNN输出经线性化和softmax(激活函数),真正输出(即forward函数的返回)#实例化nn.Linear(全连接层),用于将nn.RNN的输出维度转化成指定输出维度self.linear=nn.Linear(hidden_size,output_size)#实例化Softmax层,用于从输出层获得类别结果self.softmax=nn.LogSoftmax(dim=-1)#dim=-1表示在最后一个维度进行(例如1*1*32即在32处进行)#传统RNN计算逻辑#forward正向传播def forward(self,input,hidden):#input:输入张量(形状1*n_letters),# hidden:隐层张量(self.num_layers*1*self.hidden_size)-由initHidden函数生成#nn.RNN要求输入为三维,input扩展一个维度input=input.unsqueeze(0)#形状:1*1*n_letters#传入RNN,若num_layers=1,则rr(输出)恒等于hn(隐层)rr,hn=self.rnn(input,hidden)#返回通过线性变换和softmax的结果,同时返回隐藏层输出(作为后续RNN输入)return self.softmax(self.linear(rr)),hn #实现真正输出#初始化一个全零隐层(即h0,三维)def initHidden(self):#self.num_layers:层数(*方向),1:批次,self.hidden_size:隐藏层维度return torch.zeros(self.num_layers,1,self.hidden_size)

Softmax层与LogSoftmax层的对比1
Softmax层与LogSoftmax层的对比2

3.2 构建传统LSTM模型

#构建LSTM模型
class LSTM(nn.Module):def __init__(self,input_size,hidden_size,output_size,num_layers=1):#input_size:输入张量维度、hidden_size:隐藏层维度、output_size:输出维度super(LSTM,self).__init__()self.input_size=input_size #代表LSTM输入的最后一个维度self.hidden_size=hidden_size #代表LSTM隐藏层的最后一个维度self.output_size=output_size #代表LSTM网络最后线性层的输出维度self.num_layers=num_layers #代表LSTM网络层数#实例化nn.LSTMself.lstm=nn.LSTM(input_size,hidden_size,num_layers)#nn.Linear和nn.LogSoftmax用于将RNN输出经线性化和softmax(激活函数)#实例化nn.Linear,用于将nn.RNN的输出维度转化成指定输出维度self.linear=nn.Linear(hidden_size,output_size)#实例化Softmax层,用于从输出层获得类别结果self.softmax=nn.LogSoftmax(dim=-1)#dim=-1表示在最后一个维度进行(例如1*1*32即在32处进行)#LSTM计算逻辑def forward(self,input,hidden,cell):#cell:细胞状态张量#input:输入张量(形状1*n_letters),hidden:隐层张量(self.num_layers*1*self.hidden)input=input.unsqueeze(0)#形状:1*1*n_letters#传入RNN,若num_layers=1,则rr(输出)恒等于hn(隐层)rr,(hn,cn)=self.lstm(input,(hidden,cell))#返回通过线性变换和softmax的结果,同时返回隐藏层输出(作为后续RNN输入)return self.softmax(self.linear(rr)),hn,cn #实现真正输出#初始化一个全零隐层和细胞状态(即h0和c0,三维)def initHiddenAndCell(self):#self.num_layers:层数(*方向),1:批次,self.hidden_size:隐藏层维度h0=c0=torch.zeros(self.num_layers, 1, self.hidden_size)return h0,c0

3.3 构建传统GRU模型

class GRU(nn.Module):def __init__(self,input_size,hidden_size,output_size,num_layers=1):#input_size:输入张量维度、hidden_size:隐藏层维度、output_size:输出维度super(GRU,self).__init__()self.input_size=input_size #代表GRU输入的最后一个维度self.hidden_size=hidden_size #代表GRU隐藏层的最后一个维度self.output_size=output_size #代表GRU网络最后线性层的输出维度self.num_layers=num_layers #代表GRU网络层数self.gru=nn.GRU(input_size,hidden_size,num_layers)#nn.Linear和nn.LogSoftmax用于将GRU输出经线性化和softmax(激活函数),真正输出(即forward函数的返回)#实例化nn.Linear(全连接层),用于将nn.RNN的输出维度转化成指定输出维度self.linear=nn.Linear(hidden_size,output_size)#实例化Softmax层,用于从输出层获得类别结果self.softmax=nn.LogSoftmax(dim=-1)#dim=-1表示在最后一个维度进行(例如1*1*32即在32处进行)#传统GRU计算逻辑def forward(self,input,hidden):#input:输入张量(形状1*n_letters),hidden:隐层张量(self.num_layers*1*self.hidden)#nn.RNN要求输入为三维,input扩展一个维度input=input.unsqueeze(0)#形状:1*1*n_letters#传入RNN,若num_layers=1,则rr(输出)恒等于hn(隐层)rr,hn=self.gru(input,hidden)#返回通过线性变换和softmax的结果,同时返回隐藏层输出(作为后续RNN输入)return self.softmax(self.linear(rr)),hn #实现真正输出#初始化一个全零隐层(即h0,三维)def initHidden(self):#self.num_layers:层数(*方向),1:批次,self.hidden_size:隐藏层维度return torch.zeros(self.num_layers,1,self.hidden_size)

3.4 测试输出

#输入张量为每个人名对应的张量,其最后一维都是n_letters(57)
input_size=n_letters
#定义隐层最后一维尺寸大小(神经元个数)
hidden_size=128
#输出尺寸为国家类别种数(18)
output_size=n_categories
#num_layers= #默认为1,可需改#假设以一个字母B作为输入
#lineToTensor('B')输出为三维张量;squeeze(0)降低一个维度(该维度需为1,才可降低)(定义的三类模型输入为二维,每一个类内都会进行扩充维度)
input1=lineToTensor('B').squeeze(0)
#初始化一个三维隐藏层和一个细胞状态张量
hidden=cell=torch.zeros(1,1,hidden_size)##调用三类模型
rnn=RNN(input_size,hidden_size,output_size)
lstm=LSTM(input_size,hidden_size,output_size)
gru=GRU(input_size,hidden_size,output_size)rnn_output,next_hidden=rnn(input1,hidden)
print("rnn:",rnn_output)
print("rnn_shape:",rnn_output.shape)
print('*******************')lstm_output,next_hidden1,cell=lstm(input1,hidden,cell)
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)

在这里插入图片描述

这里只是对一个字母进行测试,如果是n个字母,则需要修改参数

4.构建训练函数并进行训练

torch.topkh函数

x=torch.arange(1,6)#x为1-5的列表
res=torch.topk(x,3)#输出x中最大的三个数及其对应索引
print(x)
print(res)#索引从0开始

在这里插入图片描述

torch.add()函数

x=torch.randn(4)#随机生成符合正态分布的4个数
y=torch.randn(3,1)#随机生成符合正态分布的3*1的向量
print(x)
print(y)
a=torch.add(x,y)
b=torch.add(x,y,alpha=10)
print(a)
print(b)

在这里插入图片描述

torch.add(x,y):即x和y张量相加,x的每一个值与y的每一个值相加(a的第一行为x的每一个值分别于y的第一个值相加…)
torch.add(x,y,alpha=10):y先乘10再进行torch.add(x,y),即相当于torch.add(x,10y)

4.1辅助函数

4.1.1 返回指定的类别函数

#从输出结果中得到所指定的类别
def categoryFromOutput(output):top_n,top_i=output.topk(1)#获取output中的值和所对应的索引category_i=top_i[0].item()#从top_i获取索引值#返回索引值对应国家,和索引值return all_categories[category_i],category_i

测试:

category,category_i=categoryFromOutput(gru_output)#取GRU模型输出
print('category:',category)
print('category_i:',category_i)

在这里插入图片描述

即,对于GRU模型输出结果,取最大值后,判断‘B’(输入)为国家类别中第13个国家Portuguese中的名字(准确率低)

4.1.2 随机产生训练数据函数

def randomTrainingExample():#在所有国家类别中随机选择一个国家,并在该国家里随机选择一个名字category=random.choice(all_categories)line=random.choice(category_lines[category])#将选择的类别和人名封装成张量#all_categories.index(category)返回category在all_categories列表中的索引值#torch.long长整型张量category_tensor=torch.tensor([all_categories.index(category)],dtype=torch.long)line_tensor=lineToTensor(line)#人名转化成onehot张量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)

在这里插入图片描述

即随机生成10个国家、10个国家里的名字,并将其转换成张量(对于国家名张量category_tensor,其为一维,方括号内为其在国家名列表中的位置;人名张量见one-hot编码部分)

4.1.3 耗时计算函数

#计算模型所耗时间
def timeSince(since):#since为开始时间,返回为耗费时间now=time.time()#获取当前时间s=now-since#获取耗费时间(单位:秒)m=math.floor(s/60)#获取分钟数s=s-m*60#获取剩余秒数#输出:*m *sreturn '%dm %ds' % (m,s)#测试
since=time.time()-10*60
period=timeSince(since)
print(period)

在这里插入图片描述

4.2构建传统RNN训练函数

详解torch.NLLLoss

#构建传统RNN训练函数
#定义损失函数:nn.NLLLoss()函数,因为其和最后使用的nn.LogSoftmax()函数内部计算逻辑匹配
criterion=nn.NLLLoss()#学习率(经验值)
learning_rate=0.005
#训练函数
def trainRNN(category_tensor,line_tensor):#category_tensor:代表训练数据的标签#line_tensor:代表训练数据的特征hidden=rnn.initHidden()#初始化RNN隐藏层张量#将模型结构中的梯度归零(关键的一步)rnn.zero_grad()#遍历训练数据line_tensor中的每一个字符,传入RNN中,并迭代更新hiddenfor i in range(line_tensor.size()[0]):#line_tensor.size():line_tensor的尺寸(名字字母个数*1*57);#line_tensor.size()[0]:取出名字字母个数#line_tensor[i]表示名字中第i个字母对应的张量#hidden迭代更新;output输出最后一个时间步的输出(即最后一层的输出)output,hidden=rnn(line_tensor[i],hidden)#RNN输出output是三维张量,为满足category_tensor,需要进行降维操作# #output.squeeze(0)即为了将output变为1*18(即1*n的形式),对应标签category_tensor的一维(详情见详解torch.NLLLoss)loss=criterion(output.squeeze(0),category_tensor)#进行反向传播loss.backward()#计算出每一步的梯度值#显示更新模型中的所有参数(手动更新)for p in rnn.parameters():#将参数的张量标识与参数的梯度进行乘法运算#p.data表示p的数值;p.data.add_()表示用计算出的结果覆盖p的值#(-learning_rate,p.grad.data)即p=p-learning_rate*梯度#p.data.add_(-learning_rate,p.grad.data)#该种形式系统格式报错p.data.add_(p.grad.data, alpha=-learning_rate)#返回RNN最终的输出结果output,和模型损失lossreturn output,loss.item()

4.3LSTM训练函数

#构建LSTM训练函数(多了细胞状态)
def trainLSTM(category_tensor,line_tensor):#category_tensor:代表训练数据的标签#line_tensor:代表训练数据的特征hidden,cell=lstm.initHiddenAndCell()#将模型结构中的梯度归零(关键的一步)lstm.zero_grad()#遍历训练数据line_tensor中的每一个字符,传入并迭代更新hidden与cellfor i in range(line_tensor.size()[0]):#line_tensor.size():line_tensor的尺寸(名字字母个数*1*57);#line_tensor.size()[0]:取出名字字母个数#line_tensor[i]表示名字中第i个字母对应的张量#hidden迭代更新;output输出最后一个时间步的输出(即最后一层的输出)output,hidden,cell=lstm(line_tensor[i],(hidden,cell))#RNN输出output是三维张量,为满足category_tensor,需要进行降维操作#output.squeeze(0)即为了将output变为1*18(即1*n的形式),对应标签category_tensor的一维loss=criterion(output.squeeze(0),category_tensor)#进行反向传播loss.backward()#计算出每一步的梯度值#显示更新模型中的所有参数for p in lstm.parameters():#将参数的张量标识与参数的梯度进行乘法运算#p.data表示p的数值;p.data.add_()表示用计算出的结果覆盖p的值#(-learning_rate,p.grad.data)即p-learning_rate*梯度#p.data.add_(-learning_rate,p.grad.data)p.data.add_(p.grad.data, alpha=-learning_rate)#返回RNN最终的输出结果output,和模型损失lossreturn output,loss.item()

4.4GRU训练函数

#构建GRU训练函数
def trainGRU(category_tensor,line_tensor):#category_tensor:代表训练数据的标签#line_tensor:代表训练数据的特征hidden=gru.initHidden()#将模型结构中的梯度归零(关键的一步)gru.zero_grad()#遍历训练数据line_tensor中的每一个字符,传入并迭代更新hiddenfor i in range(line_tensor.size()[0]):#line_tensor.size():line_tensor的尺寸(名字字母个数*1*57);#line_tensor.size()[0]:取出名字字母个数#line_tensor[i]表示名字中第i个字母对应的张量#hidden迭代更新;output输出最后一个时间步的输出(即最后一层的输出)output,hidden=gru(line_tensor[i],hidden)#RNN输出output是三维张量,为满足category_tensor,需要进行降维操作#output.squeeze(0)即为了将output变为1*18(即1*n的形式),对应标签category_tensor的一维loss=criterion(output.squeeze(0),category_tensor)#进行反向传播loss.backward()#计算出每一步的梯度值#显示更新模型中的所有参数for p in gru.parameters():#将参数的张量标识与参数的梯度进行乘法运算#p.data表示p的数值;p.data.add_()表示用计算出的结果覆盖p的值#(-learning_rate,p.grad.data)即p-learning_rate*梯度#p.data.add_(-learning_rate,p.grad.data)p.data.add_(p.grad.data, alpha=-learning_rate)#返回最终的输出结果output,和模型损失lossreturn output,loss.item()

4.5 训练过程的日志打印函数

#构建训练过程的日志打印函数
n_iters=10000#训练的迭代次数
print_every=50#结果打印间隔(防止将代码卡死当作训练中)
plot_every=10#绘制损失曲线的制图间隔def train(train_type_fn):# train_type_fn代表三种训练模型(即trainRNN、trainLSTM、trainGRU)all_losses=[]#初始化存储每个制图间隔损失的列表start=time.time()#获取开始时间戳current_loss=0#设置初始间隔的损失值为0# 迭代训练n_iters次for iter in range(1,n_iters+1):#随机产生一组训练数据和标签category, line, category_tensor, line_tensor=randomTrainingExample()#开始训练output,loss=train_type_fn(category_tensor, line_tensor)#累加损失值current_loss+=loss#若达到打印间隔if iter % print_every==0:#从该迭代步输出获取类别和索引值guess,guess_i=categoryFromOutput(output)#判断:与真实类别标签比较;若相同则为True,否则为False并打印出类别correct='True' if guess==category else 'False (%s)'% category#打印信息:iter(当前迭代次数),iter/n_iters*100(当前迭代次数百分比,%d%%表示*%,后两个%一个为转义字符,表示%),timeSince(start)(当前训练所耗费时间),# loss(每一个打印间隔的损失值),line(真实类别),guess(猜测类别),correct(正确与否)print('%d %d%% (%s) %.4f %s / %s %s' % (iter,iter/n_iters*100,timeSince(start),loss,line,guess,correct))#print(iter)#若达到制图间隔if iter % plot_every==0:#将过去plot_every次迭代的平均损失添加到all_lossesall_losses.append(current_loss/plot_every)#间隔损失重置为0(使得all_losses均为每plot_every轮的平均值)current_loss=0#返回总损失列表和训练耗时return all_losses,int(time.time()-start)

测试:

#调用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.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.show()

如果报错见数据集处理

一些输出:

在这里插入图片描述

以下是训练次数10万的图结果:

在这里插入图片描述

  • 损失函数对比曲线分析:
    模型训练的损失降低快慢代表模型收敛程度,由图可知,传统RNN的模型收敛情况量好,然后是GRU,最后是LSTM。这是因为:我们当前处理的文本数据是人名,他们的长度有限,且长距离字母间基本无特定关联,因此无法发挥改进模型LSTM和GRU的长距离捕捉语义关联的优势。所以在以后的模型选用时,要通过对任务的分析以及实验对比,选择最合适的模型。

在这里插入图片描述

  • 训练耗时对比图分析:
    模型训练的耗时长短代表模型的计算复杂度,由图可知,也正如我们之前的理论分析,传统RNN复杂度最低,耗时几乎只是后两者的一半,然后是GRU,最后是复杂度最高的LSTM。

结论: 模型选用一般应通过实验对比,并非越复杂或越先进的模型表现越好,而是需要结合自己的特定任务,从对数据的分析和实验结果中获得最佳答案.

5.构建评估函数并进行验证

5.1 传统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)#降维(二维)

5.2 LSTM评估函数

def evaluateLSTM(line_tensor):hidden,cell=lstm.initHiddenAndCell()for i in range(line_tensor.size()[0]):output,hidden,cell=lstm(line_tensor[i],hidden,cell)return output.squeeze(0)

5.3 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)

5.4 预测函数

#构建预测函数
def predict(input_line,evaluate,n_predictions=3):#input_line表示输入的人名;n_predictions表示取出前top个#打印输入名print('\n> %s' % input_line)#表示以下操作相关张量不进行梯度更新(梯度更新在训练阶段进行)with torch.no_grad():#人名转换张量并预测output=evaluate(lineToTensor(input_line))#获取前top个的值和索引topv,topi=output.topk(n_predictions,1,True)#用于存储预测结果predictions=[]for i in range(n_predictions):#将第i个的值取出value=topv[0][i].item()#将第i个的索引值取出category_index=topi[0][i].item()print('(%.2f) %s' % (value,all_categories[category_index]))#将结果存放到predications中predictions.append([value,all_categories[category_index]])

测试:

for evaluate_fn in [evaluateRNN,evaluateLSTM,evaluateGRU]:print('*'*10)predict('Lipengyang',evaluate_fn)

在这里插入图片描述

参考资料

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

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

相关文章

永久免费设备日志采集工具

免费试用下载: Gitee下载 最新版本 优势: A. 开箱即用. 解压直接运行.不需额外安装. B. 批管理设备. 设备配置均在后台管理. C. 无人值守 客户端自启动,自更新. D. 稳定安全. 架构简单,内存占用小,通过授权访问.

openeuler一个服务异常占用cpu的排查过程

1 环境 硬件环境:LS1046A arm64 系统环境:openEuler release 22.03 (LTS-SP1) Linux kernel 4.19.26 2 问题说明 我的硬件平台需要适配一下 openEuler release 22.03 (LTS-SP1) 但是目前只能使用原来硬件平台的内核,在适配的过程中…

LLM大语言模型应用方案之RAG检索增强生成的实现步骤。

0.我理解的RAG 什么是RAG? RAG的全称是“检索增强生成模型”(Retrieval-Augmented Generation)。这是一种特别聪明的大语言模型。 RAG是怎么工作的呢? 1.检索:当你问RAG一个问题时,它会先去“图书…

aardio - 【库】lock 跨进程读写锁

import win.ui; /*DSG{{*/ var winform win.form(text"aardio form";right272;bottom203;topmost1) winform.add( button{cls"button";text"无锁演示";left27;top132;right120;bottom184;z2}; button2{cls"button";text"有锁演示…

Redis的实战常用一、验证码登录(解决session共享问题)(思路、意识)

一、基于session实现登录功能 第一步:发送验证码: 用户在提交手机号后,会校验手机号是否合法: 如果不合法,则要求用户重新输入手机号如果手机号合法,后台此时生成对应的验证码,同时将验证码进行…

前端路线指导(4):前端春招秋招经验分享

春招/秋招经验分享(前端) 哈喽大家好,我是小粉,双一流本科,自学前端一年,收获腾讯,字节等多家大厂offer,一半以上ssp~ 今天给大家分享一下我的春招(暑期实习)、秋招经历,…

【Gradio】如何设置 Gradio 数据框的样式

简介 数据可视化是数据分析和机器学习的关键方面。Gradio DataFrame 组件是一种流行的方式,在网络应用程序中显示表格数据(特别是以 pandas DataFrame 对象的形式)。 本文将探讨 Gradio 的最新增强功能,这些功能允许用户整合 pand…

Spring的启动扩展点机制详解

在Java的世界中,我们知道Spring是当下最主流的开发框架,没有之一。而在使用Dubbo、Mybatis等开源框架时,我们发现可以采用和Spring完全一样的使用方式来使用它们。 可能你在平时的使用过程中并没有意识到这一点,但仔细想一想&…

解决js打开新页面百度网盘显示不存在方法:啊哦,你所访问的页面不存在了。

用js打开新页面open或window.location.href打开百度网盘后都显示:啊哦,你所访问的页面不存在了。 window.open(baidu_url); window.location.href baidu_url;在浏览器上,回车后网盘资源是可以打开的,刷新也是打开的。这是很奇怪…

深入分析并可视化城市轨道数据

介绍 中国城市化进程加速中,城市轨道交通的迅速扩张成为提升城市运行效率和居民生活品质的关键。这一网络从少数大城市延伸至众多大中型城市,映射了经济飞跃和城市管理现代化。深入分析并可视化城市轨道数据,对于揭示网络特性、评估效率、理…

进程、线程的区别

进程、线程的关系 开工厂生产手机,制作一条生产线,这个生产线上有很多的器件以及材料。一条生产线就是一个进程。 只有生产线是不够的,使用找五个工人来进行生产,这个工人能够利用这些材料最终一步步的将手机做出来,这…

Ansible 自动化运维实践

随着 IT 基础设施的复杂性不断增加,手动运维已无法满足现代企业对高效、可靠的 IT 运维需求。Ansible 作为一款开源的自动化运维工具,通过简洁易用的 YAML 语法和无代理(agentless)架构,极大简化了系统配置管理、应用部…

LuxTrust、契约锁联合启动中欧两地跨境电子签服务

6月18日,欧洲领先的数字身份和电子签名厂商-LuxTrust、全球领先的数字化技术和服务的提供商-浩鲸科技一行莅临契约锁上海总部,并于当日下午联合举行“跨境签战略合作”现场签约仪式。 三方将以此次合作为契机,发挥各自领域专业优势&#xff…

DS知识点总结--线性表定义及顺序表示

数据结构知识点汇总(考研C版) 文章目录 数据结构知识点汇总(考研C版)二、线性表2.1 线性表的定义和操作2.1.1 线性表的定义2.1.2 线性表的基本操作 2.2 线性表的顺序表示2.2.1 顺序表的定义2.2.2 顺序表上的基本操作的实现 二、线性表 2.1 线性表的定义和操作 2.1.1 线性表的…

区块链会议投稿资讯CCF A--WINE 2024 截止7.15 附录用率 附录用的区块链文章

Conference:The Conference on Web and Internet Economics (WINE) CCF level:CCF A Categories:Cross-cutting/comprehensive/emerging Year:2024 Conference time: December 2-5, 2024 录用率: sele…

MSPM0G3507——PWM

在sysconfig中,左侧可以选择MCU的外设,我们找到并点击TIMER-PWM选项卡,在TIMER-PWM中点击ADD,就可以添加定时器下的PWM外设。 这里设置通道0为100Hz的频率,0%占空比的PWM,周期计数值为1000,比较…

我理解的文本表示模型

词袋模型与N-grams模型 1 词袋模型 (Bag of Words)1.1 one-hot 取值 (Binary)1.2 Term Frequency 取值 (TF)普通频数 r a w t f raw_{tf} rawtf​频率范数归一化对数频数 1.3 Inverse document frequency (IDF)1.4 TF-IDF scores 取值 N-Gram 最简单的文本建模场景&#xff1a…

聚类算法(2)--- ISODATA算法

本篇文章是博主在人工智能等领域学习时,用于个人学习、研究或者欣赏使用,并基于博主对人工智能等领域的一些理解而记录的学习摘录和笔记,若有不当和侵权之处,指出后将会立即改正,还望谅解。文章分类在AI学习笔记&#…

Vue02-第一个Vue程序

第一个Vue程序 1、什么是MVVM MVVM(Model-View-ViewModel)是一种软件设计模式,由微软WPF(用于替代WinForm,以前就是用这个技术开发桌面应用程序的)和Silverlight(类似于Java Applet&#xff0…

新手(初学者)学R语言第一课,从学正确导入数据开始

初看题目好像我在教你怎么导入数据,不不不,我是在教你正确的导入数据,不是说数据导入R就叫正确导入数据了。本章为新手教程,老手可以跳过。 这个内容早就想写了,今天有点空和大家聊一下。为什么R语言对于新手而言不太友…