Автор|Д-Р ВАЙБХАВ КУМАР Компилировать|ВКонтакте Источник|Аналитика в Диамаге
Классификация текста является одним из важных приложений обработки естественного языка. Существуют различные способы классификации текста в машинном обучении. Но большинство из этих методов классификации требуют большой предварительной обработки и больших вычислительных ресурсов. В этом посте мы используем PyTorch для многоклассовой классификации текста, потому что он имеет следующие преимущества:
- PyTorch предоставляет мощный способ реализации сложных архитектур моделей и алгоритмов с относительно небольшой предварительной обработкой и меньшим потреблением вычислительных ресурсов (включая время выполнения).
- Фундаментальной единицей PyTorch является тензор, преимущество которого заключается в изменении архитектуры во время выполнения и распределении обучения между графическими процессорами.
- PyTorch предоставляет мощную библиотеку под названием TorchText, которая содержит сценарии для предварительной обработки текста и исходный код для некоторых популярных наборов данных NLP.
В этой статье мы продемонстрируем многоклассовую классификацию текста с использованием TorchText, мощной библиотеки обработки естественного языка в PyTorch.
Для этой классификации будет использоваться модель, состоящая из слоя EmbeddingBag и линейного слоя. EmbeddingBag обрабатывает текстовые записи переменной длины, вычисляя среднее значение вложений.
Эта модель будет обучаться на наборе данных DBpedia, где текст принадлежит 14 классам. После успешного обучения модель будет предсказывать метку класса входного текста.
Набор данных DBpedia
DBpedia — популярный эталонный набор данных в области обработки естественного языка. Он содержит тексты в 14 категориях, таких как компании, учебные заведения, художники, фильмы и т. д.
На самом деле это структурированный набор контента, извлеченного из информации, созданной проектом Википедия. Набор данных DBpedia, предоставленный TorchText, содержит 63 000 текстовых экземпляров, принадлежащих 14 классам. Он включает 5600 учебных экземпляров и 70000 тестовых экземпляров.
Классификация текста с помощью TorchText
Во-первых, нам нужно установить последнюю версию TorchText.
!pip install torchtext==0.4
После этого мы импортируем все необходимые библиотеки.
import torch
import torchtext
from torchtext.datasets import text_classification
import os
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.data import DataLoader
import time
from torch.utils.data.dataset import random_split
import re
from torchtext.data.utils import ngrams_iterator
from torchtext.data.utils import get_tokenizer
На следующем шаге мы определим ngrams и размер пакета. Функция ngrams используется для сбора важной информации о локальном порядке слов.
Мы используем биграммы, пример текста в наборе данных будет представлять собой список отдельных слов плюс строки биграмм.
NGRAMS = 2
BATCH_SIZE = 16
Теперь мы прочитаем набор данных DBpedia, предоставленный TorchText.
if not os.path.isdir('./.data'):
os.mkdir('./.data')
train_dataset, test_dataset = text_classification.DATASETS['DBpedia'](
root='./.data', ngrams=NGRAMS, vocab=None)
После загрузки набора данных мы проверим длину и количество меток загруженного набора данных.
print(len(train_dataset))
print(len(test_dataset))
print(len(train_dataset.get_labels()))
print(len(test_dataset.get_labels()))
Мы будем использовать архитектуру CUDA для ускорения запуска и выполнения.
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
device
На следующем шаге мы определим модель для классификации.
class TextSentiment(nn.Module):
def __init__(self, vocab_size, embed_dim, num_class):
super().__init__()
self.embedding = nn.EmbeddingBag(vocab_size, embed_dim, sparse=True)
self.fc = nn.Linear(embed_dim, num_class)
self.init_weights()
def init_weights(self):
initrange = 0.5
self.embedding.weight.data.uniform_(-initrange, initrange)
self.fc.weight.data.uniform_(-initrange, initrange)
self.fc.bias.data.zero_()
def forward(self, text, offsets):
embedded = self.embedding(text, offsets)
return self.fc(embedded)
print(model)
Теперь мы инициализируем гиперпараметры и определим функции для создания обучающих пакетов.
VOCAB_SIZE = len(train_dataset.get_vocab())
EMBED_DIM = 32
NUN_CLASS = len(train_dataset.get_labels())
model = TextSentiment(VOCAB_SIZE, EMBED_DIM, NUN_CLASS).to(device)
def generate_batch(batch):
label = torch.tensor([entry[0] for entry in batch])
text = [entry[1] for entry in batch]
offsets = [0] + [len(entry) for entry in text]
offsets = torch.tensor(offsets[:-1]).cumsum(dim=0)
text = torch.cat(text)
return text, offsets, label
На следующем шаге мы определим функции для обучения и тестирования модели.
def train_func(sub_train_):
# 训练模型
train_loss = 0
train_acc = 0
data = DataLoader(sub_train_, batch_size=BATCH_SIZE, shuffle=True,
collate_fn=generate_batch)
for i, (text, offsets, cls) in enumerate(data):
optimizer.zero_grad()
text, offsets, cls = text.to(device), offsets.to(device), cls.to(device)
output = model(text, offsets)
loss = criterion(output, cls)
train_loss += loss.item()
loss.backward()
optimizer.step()
train_acc += (output.argmax(1) == cls).sum().item()
# 调整学习率
scheduler.step()
return train_loss / len(sub_train_), train_acc / len(sub_train_)
def test(data_):
loss = 0
acc = 0
data = DataLoader(data_, batch_size=BATCH_SIZE, collate_fn=generate_batch)
for text, offsets, cls in data:
text, offsets, cls = text.to(device), offsets.to(device), cls.to(device)
with torch.no_grad():
output = model(text, offsets)
loss = criterion(output, cls)
loss += loss.item()
acc += (output.argmax(1) == cls).sum().item()
return loss / len(data_), acc / len(data_)
Мы будем обучать модель с 5 эпохами.
N_EPOCHS = 5
min_valid_loss = float('inf')
criterion = torch.nn.CrossEntropyLoss().to(device)
optimizer = torch.optim.SGD(model.parameters(), lr=4.0)
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, 1, gamma=0.9)
train_len = int(len(train_dataset) * 0.95)
sub_train_, sub_valid_ = \
random_split(train_dataset, [train_len, len(train_dataset) - train_len])
for epoch in range(N_EPOCHS):
start_time = time.time()
train_loss, train_acc = train_func(sub_train_)
valid_loss, valid_acc = test(sub_valid_)
secs = int(time.time() - start_time)
mins = secs / 60
secs = secs % 60
print('Epoch: %d' %(epoch + 1), " | time in %d minutes, %d seconds" %(mins, secs))
print(f'\tLoss: {train_loss:.4f}(train)\t|\tAcc: {train_acc * 100:.1f}%(train)')
print(f'\tLoss: {valid_loss:.4f}(valid)\t|\tAcc: {valid_acc * 100:.1f}%(valid)')
Далее мы проверим нашу модель на тестовом наборе данных и проверим точность модели.
print('Checking the results of test dataset...')
test_loss, test_acc = test(test_dataset)
print(f'\tLoss: {test_loss:.4f}(test)\t|\tAcc: {test_acc * 100:.1f}%(test)')
Теперь мы проверим нашу модель на одной текстовой строке новостей и предскажем метку класса для данного текста новостей.
DBpedia_label = {0: 'Company',
1: 'EducationalInstitution',
2: 'Artist',
3: 'Athlete',
4: 'OfficeHolder',
5: 'MeanOfTransportation',
6: 'Building',
7: 'NaturalPlace',
8: 'Village',
9: 'Animal',
10: 'Plant',
11: 'Album',
12: 'Film',
13: 'WrittenWork'}
def predict(text, model, vocab, ngrams):
tokenizer = get_tokenizer("basic_english")
with torch.no_grad():
text = torch.tensor([vocab[token]
for token in ngrams_iterator(tokenizer(text), ngrams)])
output = model(text, torch.tensor([0]))
return output.argmax(1).item() + 1
vocab = train_dataset.get_vocab()
model = model.to("cpu")
Теперь мы случайным образом выберем текст из тестовых данных и проверим предсказанные метки классов.
Первый прогноз:
ex_text_str = "Brekke Church (Norwegian: Brekke kyrkje) is a parish church in Gulen Municipality in Sogn og Fjordane county, Norway. It is located in the village of Brekke. The church is part of the Brekke parish in the Nordhordland deanery in the Diocese of Bjørgvin. The white, wooden church, which has 390 seats, was consecrated on 19 November 1862 by the local Dean Thomas Erichsen. The architect Christian Henrik Grosch made the designs for the church, which is the third church on the site."
print("This is a %s news" %DBpedia_label[predict(ex_text_str, model, vocab, 2)])
Второй прогноз:
ex_text_str2 = "Cerithiella superba is a species of very small sea snail, a marine gastropod mollusk in the family Newtoniellidae. This species is known from European waters. It was described by Thiele, 1912."
print("This text belongs to %s class" %DBpedia_label[predict(ex_text_str2, model, vocab, 2)])
Третье предсказание:
ex_text_str3 = " Nithari is a village in the western part of the state of Uttar Pradesh India bordering on New Delhi. Nithari forms part of the New Okhla Industrial Development Authority's planned industrial city Noida falling in Sector 31. Nithari made international news headlines in December 2006 when the skeletons of a number of apparently murdered women and children were unearthed in the village."
print("This text belongs to %s class" %DBpedia_label[predict(ex_text_str3, model, vocab, 2)])
Таким образом, мы достигаем многоклассовой классификации текста с помощью TorchText.
Это простой и легкий способ классификации текста с очень небольшой предварительной обработкой с использованием этой библиотеки PyTorch. Обучение модели на 5600 экземплярах заняло менее 5 минут.
Повторно запустите эти коды, изменив ngram с 2 на 3, и посмотрите, улучшатся ли результаты. Та же реализация может быть реализована и для других наборов данных, предоставляемых TorchText.
использованная литература:
- «Текстовая классификация с помощью TorchText», учебник по PyTorch
- Аллен Ни, «Учебник по TorchText»
Оригинальная ссылка:аналитика Индия mag.com/multi-class…
Добро пожаловать на сайт блога Panchuang AI:panchuang.net/
sklearn машинное обучение китайские официальные документы:sklearn123.com/
Добро пожаловать на станцию сводки ресурсов блога Panchuang:docs.panchuang.net/