匠心精神 - 良心品质腾讯认可的专业机构-IT人的高薪实战学院

咨询电话:4000806560

「Python」利用PyTorch进行NLP任务,一文将其解决

「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 方面的同学提供一些帮助和启示。