「Python」利用PyTorch进行NLP任务,一文将其解决 自然语言处理(NLP)是当今计算机科学领域的新热点,在这个领域中,PyTorch 是一种非常流行的机器学习框架,Pytorch 的强大功能可以帮助我们处理各种不同的 NLP 任务,本文将介绍如何利用 PyTorch 解决 NLP 任务。 1. 准备数据 在NLP任务中,数据准备是非常重要的一步,我们需要对原始数据进行清洗、标记、分词等操作,并将其转换为可以被模型处理的格式,这个过程可以用 Python 和 PyTorch 实现。在这里我们将使用一个叫做 TorchText 的 PyTorch 库,它可以帮助我们更加方便地进行数据处理。 ```python from torchtext.datasets import text_classification import torch from torch.utils.data import DataLoader NGRAMS = 2 import os if not os.path.isdir('./.data'): os.mkdir('./.data') train_dataset, test_dataset = text_classification.DATASETS['AG_NEWS']( root='./.data', ngrams=NGRAMS, vocab=None) BATCH_SIZE = 16 device = torch.device("cuda" if torch.cuda.is_available() else "cpu") train_loader = DataLoader(train_dataset, batch_size=BATCH_SIZE, shuffle=True, collate_fn=lambda x: x) test_loader = DataLoader(test_dataset, batch_size=BATCH_SIZE, shuffle=False, collate_fn=lambda x: x) ``` 上面的代码中,我们首先导入了 text_classification、torch 和 DataLoader 这三个模块,然后设置了 NGRAMS 的值为 2,代表我们会考虑词组的长度为 2 的情况,接着设置了一个新的文件夹 './.data', 以存放我们处理好的数据。然后我们从 TorchText 库里面导入了 AG_NEWS 数据集,并利用 DataLoader 进行数据加载和预处理。 2. 构建模型 PyTorch 的神经网络模型比较容易构建,我们只需要继承 nn.Module 类并重写 forward 函数即可。在本文中,我们将使用一个叫做 TextSentiment 的模型,它采用了带有卷积神经网络的双向 LSTM,我们可以通过以下代码进行定义。 ```python import torch.nn as nn import torch.nn.functional as F 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) ``` 在这个代码中,我们首先导入了 nn 和 F 两个模块,并定义了一个叫做 TextSentiment 的模型类,它的基类是 nn.Module。在模型的构造函数中,我们定义了一个 EmbeddingBag 层和一个线性分类器,其中 EmbeddingBag 层可以将词向量作为输入,并对其进行平均池化处理,返回一个特征向量,而线性分类器可以将特征向量转化为分类结果。在模型的 forward 函数中,我们首先将词向量传入到 EmbeddingBag 层中进行处理,然后再将其传入到线性分类器中进行分类。 3. 训练模型 模型定义好以后,我们需要进行训练,这个过程可以使用 PyTorch 的优化器类来实现,我们可以选择 Adam 优化器,同时使用交叉熵作为损失函数。以下是 PyTorch 训练模型的主要代码。 ```python from torch.utils.data.dataset import random_split import time N_EPOCHS = 10 min_valid_loss = float('inf') def train(model, iterator, optimizer, criterion, device): model.train() for batch in iterator: text, offsets = batch[0], batch[1] labels = batch[2] optimizer.zero_grad() predictions = model(text, offsets).squeeze(1) loss = criterion(predictions, labels) loss.backward() optimizer.step() def evaluate(model, iterator, criterion, device): model.eval() epoch_loss = 0 epoch_acc = 0 with torch.no_grad(): for batch in iterator: text, offsets = batch[0], batch[1] labels = batch[2] predictions = model(text, offsets).squeeze(1) loss = criterion(predictions, labels) acc = binary_accuracy(predictions, labels) epoch_loss += loss.item() epoch_acc += acc.item() return epoch_loss / len(iterator), epoch_acc / len(iterator) optimizer = torch.optim.Adam(model.parameters()) criterion = nn.CrossEntropyLoss().to(device) for epoch in range(N_EPOCHS): start_time = time.time() train(model, train_loader, optimizer, criterion, device) valid_loss, valid_acc = evaluate(model, test_loader, criterion, device) end_time = time.time() epoch_mins, epoch_secs = epoch_time(start_time, end_time) if valid_loss < min_valid_loss: min_valid_loss = valid_loss torch.save(model.state_dict(), 'tut1-model.pt') print(f'Epoch: {epoch+1:02} | Epoch Time: {epoch_mins}m {epoch_secs}s') print(f'\tVal. Loss: {valid_loss:.3f} | Val. Acc: {valid_acc*100:.2f}%') ``` 在上述代码中,我们首先定义了一个训练函数 train 和一个评估函数 evaluate。两个函数的参数都包括了我们需要训练的模型、数据迭代器、优化器和损失函数等。在训练函数中,我们首先对模型进行清空,并将其设置为训练状态,然后对每一个 Mini-Batch 执行的操作包括:获取输入数据、将数据传入模型中、计算模型输出、计算损失值、计算梯度,最后更新模型参数。 在评估函数中,我们也需要首先对模型进行清空,并将其设置为评估状态,然后对每一个 Mini-Batch 执行的操作包括:获取输入数据、将数据传入模型中、计算模型输出、计算损失值、计算准确率。在每一个 epoch 结束的时候,我们需要检查当前的验证损失是否比之前的最小验证损失要小,如果是,则保存当前模型,否则不进行任何操作。最后输出当前 epoch 的验证损失和验证准确率。 4. 总结 本文介绍了如何利用 PyTorch 处理自然语言处理任务,主要包括数据准备、模型构建和模型训练三个步骤。在这个过程中,我们使用了 PyTorch 提供的一些基本模块和数据集,并且编写了自己的模型,同时还使用了 PyTorch 的优化器和损失函数来训练模型。希望这篇文章能对那些想要学习 PyTorch NLP 方面的同学提供一些帮助和启示。