• 字符级RNN教程


    CLASSIFYING NAMES WITH A CHARACTER-LEVEL RNN

    教程链接

    从这个教程学到的主要内容

    • 如何读取一个文件夹下的全部文件;
    • 如何把Unicode字符转成纯ascii字符;
    • pytorch的训练流程
      • 创建输入和目标;
      • 前向传播;
      • 计算损失;
      • 后向更新;
      • 返回损失;

    整体代码如下:

    import matplotlib.pyplot as plt
    import torch
    import unicodedata
    import string
    from __future__ import unicode_literals,print_function,division
    from io import open
    import os
    
    all_files = "/home/dataset/data/names/*.txt"
    
    all_letters = string.ascii_letters + ".,;'"
    
    def unicodeToAscii(s):
        return ''.join(
            c for c in unicodedata.normalize("NFD",s)
            if unicodedata.category(c) != "Mn"
            and c in all_letters
        )
    # 在Unicode中,某些字符能够用多个合法的编码表示。
    
    # 在需要比较字符串的程序中使用字符的多种表示会产生问题。 为了修正这个问题,你可以使用unicodedata模块先将文本标准化:
    
    # normalize() 第一个参数指定字符串标准化的方式。 NFC表示字符应该是整体组成(比如可能的话就使用单一编码),而NFD表示字符应该分解为多个组合字符表示。
    
    category_lines = {}
    all_categories = []
    
    import glob
    def findFiles(filepath):
        return glob.glob(filepath)
    
    def readlines(filename):
        lines = open(filename,encoding="utf-8").read().strip().split("
    ")
        return [unicodeToAscii(line) for line in lines]
    

    网络结构的定义如下:

    import torch.nn as nn
    class RNN(nn.Module):
        def __init__(self,input_size,hidden_size,output_size):
            super(RNN,self).__init__()
            self.hidden_size = hidden_size
            self.i2h = nn.Linear(input_size + hidden_size,hidden_size)
            self.i2o = nn.Linear(input_size + hidden_size,output_size)
            self.softmax = nn.LogSoftmax(dim=1)
        
        def forward(self,input,hidden):
            combined = torch.cat((input,hidden),1)
            output = self.i2o(combined)
            hidden = self.i2h(combined)
            output = self.softmax(output)
            return output,hidden
            
        def initHidden(self):
            return torch.zeros(1,self.hidden_size)
    

    具体的计算损失和梯度回传的过程,有两种写法

    • 前向传播;
      • prediction = net(x)
    • 计算损失;
      • loss = loss_func(prediction, y)
    • 清空上一步的残余更新参数值
      • optimizer.zero_grad()
    • 误差反向传播, 计算参数更新值
      • loss.backward()
    • 将参数更新值施加到 net 的 parameters 上
      • optimizer.step()
    learning_rate = 0.006
    optimizer = torch.optim.SGD(rnn.parameters(),lr =learning_rate)
    def train(category_tensor,line_tensor):
        hidden = rnn.initHidden()
        rnn.zero_grad()
        for i in range(line_tensor.size()[0]):
            output, hidden = rnn(line_tensor[i], hidden)
        loss = criterion(output,category_tensor)
        loss.backward()
        
        for p in rnn.parameters():
            p.data.add_(-learning_rate, p.grad.data)
    
        return output,loss.item()
    

    第一种方法手动更新参数,即使用SGD算法;

    learning_rate = 0.006
    optimizer = torch.optim.SGD(rnn.parameters(),lr =learning_rate)
    def train(category_tensor,line_tensor):
        hidden = rnn.initHidden()
        optimizer.zero_grad()
        for i in range(line_tensor.size()[0]):
            output, hidden = rnn(line_tensor[i], hidden)
        loss = criterion(output,category_tensor)
        loss.backward()
        
        optimizer.step()
    
        return output,loss.item()
    

    第二种方式使用自带的优化器,需要注意梯度清空

  • 相关阅读:
    MongoDB安装 & 用户创建增删改查
    MongoDB介绍
    JAVA日报
    JAVA日报
    JAVA日报
    JAVA日报
    JAVA日报
    JAVA日报
    JAVA日报
    JAVA日报
  • 原文地址:https://www.cnblogs.com/curtisxiao/p/11144085.html
Copyright © 2020-2023  润新知