IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> GENERATING NAMES WITH A CHARACTER-LEVEL RNN教程解析 -> 正文阅读

[人工智能]GENERATING NAMES WITH A CHARACTER-LEVEL RNN教程解析

RNN生成名字教程NLP FROM SCRATCH: GENERATING NAMES WITH A CHARACTER-LEVEL RNN是一篇不错的RNN入门教程,为了方便理解,这里将里面容易困惑的地方记录下。
这个教程会教你如何从头训练一个RNN模型,这个模型能够根据输入的国家名称和名字首字母来生成对应国家的名字。

python sample.py Russian G
# 输出以G开头的德国名字Gerren
python sample.py Chinese C
# 输出以C开头的中文名字Chan
python sample.py Chinese H
#输出以H开头的中文名字Hang

网络结构:
在这里插入图片描述

数据集结构

训练数据结构如下:

Archive:  data.zip
  inflating: data/eng-fra.txt        
  inflating: data/names/Arabic.txt   
  inflating: data/names/Chinese.txt  
  inflating: data/names/Czech.txt    
  inflating: data/names/Dutch.txt    
  inflating: data/names/English.txt  
  inflating: data/names/French.txt   
  inflating: data/names/German.txt   
  inflating: data/names/Greek.txt    
  inflating: data/names/Irish.txt    
  inflating: data/names/Italian.txt  
  inflating: data/names/Japanese.txt  
  inflating: data/names/Korean.txt   
  inflating: data/names/Polish.txt   
  inflating: data/names/Portuguese.txt  
  inflating: data/names/Russian.txt  
  inflating: data/names/Scottish.txt  
  inflating: data/names/Spanish.txt  
  inflating: data/names/Vietnamese.txt  

每个.txt文件中存储的都是对应国家的人名,总计有18个国家的类别名字,来看下Chinese.txt存了些啥

! cat data/names/Chinese.txt
Chin
Chong
Chou
Chu
Cui
Dai
Deng
Ding
Dong
Dou
Duan
Eng
Fan
Fei
...

在加载了这些字符后,需要将每个ascii字符转换为一个one-hot编码的向量。

import torch
import torch.nn as nn

# 定义一个rnn
class RNN(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        # input_size: n_letters(59), all_letters:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ .,;'-
        super(RNN, self).__init__()
        self.hidden_size = hidden_size

        self.i2h = nn.Linear(n_categories + input_size + hidden_size, hidden_size)
        self.i2o = nn.Linear(n_categories + input_size + hidden_size, output_size)
        self.o2o = nn.Linear(hidden_size + output_size, output_size)
        self.dropout = nn.Dropout(0.1)
        self.softmax = nn.LogSoftmax(dim=1)

    def forward(self, category, input, hidden):
        # input: start letter, one hot encoding vector
        input_combined = torch.cat((category, input, hidden), 1)
        hidden = self.i2h(input_combined)
        output = self.i2o(input_combined)
        output_combined = torch.cat((hidden, output), 1)
        output = self.o2o(output_combined)
        output = self.dropout(output)
        output = self.softmax(output)
        return output, hidden

    def initHidden(self):
        return torch.zeros(1, self.hidden_size)
        
all_letters = string.ascii_letters + " .,;'-" #总计58个字符
n_letters = len(all_letters) + 1 # Plus EOS marker,n_letters=59

推理

先看下推理是怎么做的,rnn的输入是类别category和首字母,category要转换成18个国家类别的one-hot vector, 首字母start_letter要转换为59个字母表对应的onehot,每次rnn预测出来的一个字符会成为下个迭代中rnn的输入。
需要注意的是,正常我们做模型推理的时候会加上model.eval来避免dropout/bn的随机性,但是下面的sample示例并没有加,原因就是想通过模型中的dropout增加一些随机,同一个起始字符能够输出不同的名字。

def sample(category, start_letter='A'):
    # 将category对18个国家类别做onehot
    category_tensor = categoryTensor(category)
    # 将输入名字对59个字符类别做onehot,
    input = inputTensor(start_letter) # input.shape:[1,1,59], [seq_len, batch_size, n_letters], one hot encoding vector
    hidden = rnn.initHidden()

    output_name = start_letter

    for i in range(max_length):
    # category_tensor, input 都是one-hot
        output, hidden = rnn(category_tensor, input[0], hidden)
        topv, topi = output.topk(1)
        topi = topi[0][0]
        # 如果是EOS则停止预测
        if topi == n_letters - 1:
            break
        else:
            letter = all_letters[topi]
            output_name += letter
        # 将预测出来的字符复制给input参与下个字符的预测。
        input = inputTensor(letter)

    return output_name
sample('Chinese', 'L')
# 打印 Lin, 第一次预测i,第二次预测n
sample('Chinese', 'LW')
#打印 Li和 Wang。

训练

训练与推理不同的是训练要加入额外gt标签target_line_tensor。
以名字yang为例,input_line_tensor为yang的onehot,比如:
[[[0,0,...1,0,0...],[0,0,...1...],...]],shape:(4,1,59)shape 满足(seq_len, batch_size, n_letters),
target_line_tensor为input每个字符的下一个字符,也就是ang<eos>的id列表,注意这里没有对其做onehot,因为这里用的loss是NLLoss,他需要的是类别的index,不需要onehot,target_line_tensor打印可能是下面的结果:[8, 19, 4, 58], shape:(4,)
简化的训练代码:

criterion = nn.NLLLoss()
learning_rate = 0.0005
# train(*randomTrainingExample())
def train(category_tensor, input_line_tensor, target_line_tensor):
    target_line_tensor.unsqueeze_(-1)
    hidden = rnn.initHidden()

    rnn.zero_grad()

    loss = 0

    for i in range(input_line_tensor.size(0)):
        output, hidden = rnn(category_tensor, input_line_tensor[i], hidden)
        l = criterion(output, target_line_tensor[i])
        loss += l

    loss.backward()

    for p in rnn.parameters():
        p.data.add_(p.grad.data, alpha=-learning_rate)

    return output, loss.item() / input_line_tensor.size(0)
  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2022-03-30 18:23:58  更:2022-03-30 18:27:31 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/9 1:22:49-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码