吾本轻狂|PyTorch文本:02.使用字符级RNN生成名字( 二 )


在组合隐藏状态和输出之后我们增加了第二个linear层o2o , 使模型的性能更好 。 当然还有一个dropout层 , 参考这篇论文随机将输入部分替换为0 给出的参数(dropout=0.1)来模糊处理输入防止过拟合 。我们将它添加到网络的末端 , 故意添加一些混乱使采样特征增加 。
import torchimport torch.nn as nnclass RNN(nn.Module):def __init__(self, input_size, hidden_size, output_size):super(RNN, self).__init__()self.hidden_size = hidden_sizeself.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_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, hiddendef initHidden(self):return torch.zeros(1, self.hidden_size)3.训练3.1 训练准备首先 , 构造一个可以随机获取成对训练数据(category, line)的函数 。
import random# 列表中的随机项def randomChoice(l):return l[random.randint(0, len(l) - 1)]# 从该类别中获取随机类别和随机行def randomTrainingPair():category = randomChoice(all_categories)line = randomChoice(category_lines[category])return category, line对于每个时间步长(即 , 对于要训练单词中的每个字母) , 网络的输入将是“(类别 , 当前字母 , 隐藏状态)” , 输出将是“(下一个字母 ,下一个隐藏状态)” 。 因此 , 对于每个训练集 , 我们将需要类别、一组输入字母和一组输出/目标字母 。
在每一个时间序列 , 我们使用当前字母预测下一个字母 , 所以训练用的字母对来自于一个单词 。 例如 对于 “ABCD“ , 我们将创建 (“A” , “B”) , (“B” , “C”) , (“C” , “D”) , (“D” , “EOS”)) 。
类别张量是一个<1 x n_categories>尺寸的one-hot张量 。 训练时 , 我们在每一个时间序 列都将其提供给神经网络 。 这是一种选择策略 , 也可选择将其作为初始隐藏状态的一部分 , 或者其他什么结构 。
# 类别的One-hot张量def categoryTensor(category):li = all_categories.index(category)tensor = torch.zeros(1, n_categories)tensor[0][li] = 1return tensor# 用于输入的从头到尾字母(不包括EOS)的one-hot矩阵def inputTensor(line):tensor = torch.zeros(len(line), 1, n_letters)for li in range(len(line)):letter = line[li]tensor[li][0][all_letters.find(letter)] = 1return tensor# 用于目标的第二个结束字母(EOS)的LongTensordef targetTensor(line):letter_indexes = [all_letters.find(line[li]) for li in range(1, len(line))]letter_indexes.append(n_letters - 1) # EOSreturn torch.LongTensor(letter_indexes)为了方便训练 , 我们将创建一个randomTrainingExample函数 , 该函数随机获取(类别 , 行)的对并将它们转换为所需要的(类别 , 输入 ,目标)格式张量 。
# 从随机(类别 , 行)对中创建类别 , 输入和目标张量def randomTrainingExample():category, line = randomTrainingPair()category_tensor = categoryTensor(category)input_line_tensor = inputTensor(line)target_line_tensor = targetTensor(line)return category_tensor, input_line_tensor, target_line_tensor


推荐阅读