用RNN构建人名分类器

在这里插入图片描述

项目综述

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

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

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;第三层中第三个元素为1
    for k,letter in enumerate(line):
        tensor[k][0][all_letters.find(letter)]=1
    return 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 #
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值