RNN、LSTM、GRU神经网络构建人名分类器(二)+https://developer.aliyun.com/article/1544721?spm=a2c6h.13148508.setting.17.2a1e4f0eMtMqGK
7 构建时间计算函数
def timeSince(since): "获得每次打印的训练耗时, since是训练开始时间" now = time.time() s = now - since m = math.floor(s / 60) s -= m * 60 return '%dm %ds' % (m, s)
8 构建训练过程的日志打印函数
n_iters = 1000 print_every = 50 plot_every = 10 def train(train_type_fn): """训练过程的日志打印函数, 参数train_type_fn代表选择哪种模型训练函数, 如trainRNN""" all_losses = [] start = time.time() current_loss = 0 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) correct = '✓' if guess == category else '✗ (%s)' % category print('%d %d%% (%s) %.4f %s / %s %s' % (iter, iter / n_iters * 100, timeSince(start), loss, line, guess, correct)) if iter % plot_every == 0: all_losses.append(current_loss / plot_every) current_loss = 0 return all_losses, int(time.time() - start)
9 开始训练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)
10 日志输出
模型训练的耗时长短代表模型的计算复杂度, 由图可知, 也正如我们之前的理论分析, 传统RNN复杂度最低, 耗时几乎只是后两者的一半, 然后是GRU, 最后是复杂度最高的LSTM
训练次数还是有点少,如果多的话效果更加明显
模型训练的损失降低快慢代表模型收敛程度。由图可知, 传统RNN的模型收敛情况最好, 然后是GRU, 最后是LSTM, 这是因为: 我们当前处理的文本数据是人名, 他们的长度有限, 且长距离字母间基本无特定关联, 因此无法发挥改进模型LSTM和GRU的长距离捕捉语义关联的优势. 所以在以后的模型选用时, 要通过对任务的分析以及实验对比, 选择最适合的模型。
构建评估函数并进行预测
1 构建RNN评估函数
def evaluateRNN(line_tensor): """评估函数, 和训练函数逻辑相同, 参数是line_tensor代表名字的张量表示""" hidden = rnn.initHidden() for i in range(line_tensor.size()[0]): output, hidden = rnn(line_tensor[i], hidden) return output.squeeze(0)
2 构建LSTM评估函数
def evaluateLSTM(line_tensor): hidden, c = lstm.initHiddenAndC() for i in range(line_tensor.size()[0]): output, hidden, c = lstm(line_tensor[i], hidden, c) return output.squeeze(0)
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)
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)) topv, topi = output.topk(n_predictions, 1, True) predictions = [] for i in range(n_predictions): value = topv[0][i].item() category_index = topi[0][i].item() print('(%.2f) %s' % (value, all_categories[category_index])) predictions.append([value, all_categories[category_index]])
小结
学习了关于人名分类问题: 以一个人名为输入, 使用模型帮助我们判断它最有可能是来自哪一个国家的人名, 这在某些国际化公司的业务中具有重要意义, 在用户注册过程中, 会根据用户填写的名字直接给他分配可能的国家或地区选项, 以及该国家或地区的国旗, 限制手机号码位数等等。
- 人名分类器的实现可分为以下五个步骤:
第一步: 导入必备的工具包.
第二步: 对data文件中的数据进行处理,满足训练要求.
第三步: 构建RNN模型(包括传统RNN, LSTM以及GRU).
第四步: 构建训练函数并进行训练.
第五步: 构建评估函数并进行预测.
- 第一步: 导入必备的工具包
python版本使用3.6.x, pytorch版本使用1.3.1
- 第二步: 对data文件中的数据进行处理,满足训练要求
定义数据集路径并获取常用的字符数量.
字符规范化之unicode转Ascii函数unicodeToAscii.
构建一个从持久化文件中读取内容到内存的函数readLines.
构建人名类别(所属的语言)列表与人名对应关系字典
将人名转化为对应onehot张量表示函数lineToTensor
- 第三步: 构建RNN模型
构建传统的RNN模型的类class RNN.
构建LSTM模型的类class LSTM.
构建GRU模型的类class GRU.
- 第四步: 构建训练函数并进行训练
从输出结果中获得指定类别函数categoryFromOutput.
随机生成训练数据函数randomTrainingExample.
构建传统RNN训练函数trainRNN.
构建LSTM训练函数trainLSTM.
构建GRU训练函数trainGRU.
构建时间计算函数timeSince.
以及该国家或地区的国旗, 限制手机号码位数等等。
- 人名分类器的实现可分为以下五个步骤:
第一步: 导入必备的工具包.
第二步: 对data文件中的数据进行处理,满足训练要求.
第三步: 构建RNN模型(包括传统RNN, LSTM以及GRU).
第四步: 构建训练函数并进行训练.
第五步: 构建评估函数并进行预测.
- 第一步: 导入必备的工具包
python版本使用3.6.x, pytorch版本使用1.3.1
- 第二步: 对data文件中的数据进行处理,满足训练要求
定义数据集路径并获取常用的字符数量.
字符规范化之unicode转Ascii函数unicodeToAscii.
构建一个从持久化文件中读取内容到内存的函数readLines.
构建人名类别(所属的语言)列表与人名对应关系字典
将人名转化为对应onehot张量表示函数lineToTensor
- 第三步: 构建RNN模型
构建传统的RNN模型的类class RNN.
构建LSTM模型的类class LSTM.
构建GRU模型的类class GRU.
- 第四步: 构建训练函数并进行训练
从输出结果中获得指定类别函数categoryFromOutput.
随机生成训练数据函数randomTrainingExample.
构建传统RNN训练函数trainRNN.
构建LSTM训练函数trainLSTM.
构建GRU训练函数trainGRU.
构建时间计算函数timeSince.
构建训练过程的日志打印函数train.得到损失对比曲线和训练耗时对比图