Автор|Д-Р ВАЙБХАВ КУМАР Компилировать|ВКонтакте Источник|Аналитика в Диамаге
Обработка естественного языка (NLP) имеет много интересных приложений, и генерация текста — одно из них.
Когда модель машинного обучения работает с моделями последовательностей, такими как рекуррентные нейронные сети, LSTM-RNN, GRU и т. д., они могут генерировать следующую последовательность входного текста.
PyTorch предоставляет мощный набор инструментов и библиотек для выполнения этих задач на основе НЛП. Это не только требует меньше предварительной обработки, но и ускоряет процесс обучения.
В этой статье мы обучим рекуррентную нейронную сеть (RNN) для нескольких языков в PyTorch. После успешного обучения модель RNN будет предсказывать имена, принадлежащие языкам, начиная с введенных букв.
Реализация PyTorch
Эта реализация выполняется в Google Colab, где набор данных извлекается с Google Диска. Итак, сначала мы смонтируем Google Диск с помощью Colab Notebook.
from google.colab import drive
drive.mount('/content/gdrive')
Теперь мы импортируем все необходимые библиотеки.
from __future__ import unicode_literals, print_function, division
from io import open
import glob
import os
import unicodedata
import string
import torch
import torch.nn as nn
import random
import time
import math
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
Фрагмент кода ниже будет читать набор данных.
all_let = string.ascii_letters + " .,;'-"
n_let = len(all_let) + 1
def getFiles(path):
return glob.glob(path)
# Unicode字符串到ASCII
def unicodeToAscii(s):
return ''.join(
c for c in unicodedata.normalize('NFD', s)
if unicodedata.category(c) != 'Mn'
and c in all_let
)
# 读一个文件并分成几行
def getLines(filename):
lines = open(filename, encoding='utf-8').read().strip().split('\n')
return [unicodeToAscii(line) for line in lines]
# 建立cat_lin字典,存储每个类别的行列表
cat_lin = {}
all_ctg = []
for filename in getFiles('gdrive/My Drive/Dataset/data/data/names/*.txt'):
categ = os.path.splitext(os.path.basename(filename))[0]
all_ctg.append(category)
lines = getLines(filename)
cat_lin[categ] = lines
n_ctg = len(all_ctg)
На следующем шаге мы определим класс модуля для генерации имени. Этот модуль будет рекуррентной нейронной сетью.
class NameGeneratorModule(nn.Module):
def __init__(self, inp_size, hid_size, op_size):
super(NameGeneratorModule, self).__init__()
self.hid_size = hid_size
self.i2h = nn.Linear(n_ctg + inp_size + hid_size, hid_size)
self.i2o = nn.Linear(n_ctg + inp_size + hid_size, op_size)
self.o2o = nn.Linear(hid_size + op_size, op_size)
self.dropout = nn.Dropout(0.1)
self.softmax = nn.LogSoftmax(dim=1)
def forward(self, category, input, hidden):
inp_comb = torch.cat((category, input, hidden), 1)
hidden = self.i2h(inp_comb)
output = self.i2o(inp_comb)
op_comb = torch.cat((hidden, output), 1)
output = self.o2o(op_comb)
output = self.dropout(output)
output = self.softmax(output)
return output, hidden
def initHidden(self):
return torch.zeros(1, self.hid_size)
Следующие функции будут использоваться для выбора случайных элементов из списка и случайных строк из категорий.
def randChoice(l):
return l[random.randint(0, len(l) - 1)]
def randTrainPair():
category = randChoice(all_ctg)
line = randChoice(cat_lin[category])
return category, line
Следующие функции преобразуют данные в формат, совместимый с модулем RNN.
def categ_Tensor(categ):
li = all_ctg.index(categ)
tensor = torch.zeros(1, n_ctg)
tensor[0][li] = 1
return tensor
def inp_Tensor(line):
tensor = torch.zeros(len(line), 1, n_let)
for li in range(len(line)):
letter = line[li]
tensor[li][0][all_let.find(letter)] = 1
return tensor
def tgt_Tensor(line):
letter_indexes = [all_let.find(line[li]) for li in range(1, len(line))]
letter_id.append(n_let - 1) # EOS
return torch.LongTensor(letter_id)
Следующая функция создаст случайные обучающие примеры, включая тензоры классов, входных и целевых значений.
#损失
criterion = nn.NLLLoss()
#学习率
lr_rate = 0.0005
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=-lr_rate)
return output, loss.item() / input_line_tensor.size(0)
Чтобы отображать время во время тренировки, определите следующую функцию.
def time_taken(since):
now = time.time()
s = now - since
m = math.floor(s / 60)
s -= m * 60
return '%dm %ds' % (m, s)
На следующем шаге мы определим модель RNN.
model = NameGenratorModule(n_let, 128, n_let)
Мы увидим, что параметры модели RNN определены.
print(model)
Далее модель будет обучаться на 10 000 эпох.
epochs = 100000
print_every = 5000
plot_every = 500
all_losses = []
total_loss = 0 # 每次迭代时重置
start = time.time()
for iter in range(1, epochs + 1):
output, loss = train(*rand_train_exp())
total_loss += loss
if iter % print_every == 0:
print('Time: %s, Epoch: (%d - Total Iterations: %d%%), Loss: %.4f' % (time_taken(start), iter, iter / epochs * 100, loss))
if iter % plot_every == 0:
all_losses.append(total_loss / plot_every)
total_loss = 0
Визуализируем потерю во время тренировки.
plt.figure(figsize=(7,7))
plt.title("Loss")
plt.plot(all_losses)
plt.xlabel("Epochs")
plt.ylabel("Loss")
plt.show()
Наконец, мы проверим нашу модель для генерации имен, принадлежащих языку, если задана начальная буква алфавита.
max_length = 20
# 类别和起始字母中的示例
def sample_model(category, start_letter='A'):
with torch.no_grad(): # no need to track history in sampling
category_tensor = categ_Tensor(category)
input = inp_Tensor(start_letter)
hidden = NameGenratorModule.initHidden()
output_name = start_letter
for i in range(max_length):
output, hidden = NameGenratorModule(category_tensor, input[0], hidden)
topv, topi = output.topk(1)
topi = topi[0][0]
if topi == n_let - 1:
break
else:
letter = all_let[topi]
output_name += letter
input = inp_Tensor(letter)
return output_name
# 从一个类别和多个起始字母中获取多个样本
def sample_names(category, start_letters='XYZ'):
for start_letter in start_letters:
print(sample_model(category, start_letter))
Теперь мы рассмотрим пример модели, которая генерирует имя с учетом языка и начальной буквы.
print("Italian:-")
sample_names('Italian', 'BPRT')
print("\nKorean:-")
sample_names('Korean', 'CMRS')
print("\nRussian:-")
sample_names('Russian', 'AJLN')
print("\nVietnamese:-")
sample_names('Vietnamese', 'LMT')
Итак, как мы видим выше, наша модель сгенерировала имена, принадлежащие языковым категориям, начиная с входных букв.
использованная литература:
- Трунг Тран, «Генерация текста с помощью Pytorch».
- «НЛП с нуля: Генерация имен с помощью RNN уровня символов», Учебное пособие по PyTorch.
- Франческа Паулин, «LSTM на уровне персонажа в PyTorch», Kaggle.
Оригинальная ссылка:аналитика Индия mag.com/recurrent - вы...
Добро пожаловать на сайт блога Panchuang AI:panchuang.net/
sklearn машинное обучение китайские официальные документы:sklearn123.com/
Добро пожаловать на станцию сводки ресурсов блога Panchuang:docs.panchuang.net/