使用 PyTorch 进行自然语言处理

发布日期:2026-07-08 08:43:04   来源 : 杭州电子商务研究院    浏览量 :7
杭州电子商务研究院 发布日期:2026-07-08 08:43:04  
7

介绍

自然语言处理是数据科学和人工智能的一个大领域。它包括多种应用,例如情绪分析、机器翻译、语音识别、聊天机器人创建、市场情报和文本分类。PyTorch是一个流行且功能强大的深度学习库,具有执行自然语言处理任务的丰富功能。在本指南中,您将探索和学习使用PyTorch进行文本分类的自然语言处理技术

数据和所需库

首先,加载所需的库。您要导入的第一个包是torch库,它用于定义张量并执行数学运算。要导入的第二个库是torchtext库,它是 PyTorch 中的 NLP 库,其中包含数据处理实用程序。

      import torch
import torchtext
    

下一步是加载数据集。torchtext库包含模块torchtext.data ,该模块有多个数据集可用于执行自然语言处理任务。在本指南中,您将使用内置的SogouNews数据集进行文本分类。这是一个监督学习新闻数据集,有五个标签:0代表体育,1代表金融,2代表娱乐,3代表汽车,4代表科技。

下面的代码行加载数据集。设置NGRAMS = 2将确保数据集中的文本将是单个单词加二元词串的列表。

      from torchtext.datasets import text_classification
NGRAMS = 2
import os
if not os.path.isdir('./.data'):
    os.mkdir('./.data')
train_dataset, test_dataset = text_classification.DATASETS['SogouNews'](
    root='./.data', ngrams=NGRAMS, vocab=None)
BATCH_SIZE = 16
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    

输出:

      sogou_news_csv.tar.gz: 384MB [00:04, 94.7MB/s] 
450000lines [08:18, 902.49lines/s] 
450000lines [17:33, 427.10lines/s] 
60000lines [02:19, 428.77lines/s]
    

您已经加载了数据,下一步是设置模型架构。

模型架构

该模型架构由一个嵌入层和一个线性层组成。nn.EmbeddingBag函数计算一袋嵌入的平均值(无填充),因为文本长度保存在偏移量中

下面的前两行代码导入了所需的模块。下一步是在nn.Module中实现TextSentiment()模型类,这是通过第三行代码完成的。

然后,使用__init__()方法设置架构。__ init__()方法下的self参数表示对象本身的实例。参数vocab_size表示词汇表的大小,默认值为 20,000。参数embed_dim表示词嵌入的维度。num_class参数表示目标变量中的类数。

您已经定义了层,但您还需要定义它们如何相互作用。这是通过def forward()函数完成的。简而言之,这意味着您以正向方式从输入到输出。

      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)
    

模型架构已设置好,下一步是定义上面讨论的将在模型构建中使用的重要参数。这可以通过以下代码完成。

      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)
    

批次生成

数据集中的文本长度各不相同,因此需要编写一个生成数据批次的函数。此任务由以下代码中的generate_batch()函数执行。

      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_)来执行此操作。

torch.utils.data实用程序导入DataLoader模块,以便于并行加载数据。主要参数包括:

  1. batch_size:每个批次要加载的样本数量。默认值为 1。

  2. collat​​e_fn:合并张量列表以形成张量的小批量。之前创建的generate_batch函数将成为此参数的输入。

3:shuffle:设置为True表示每次迭代都会重新排列数据。默认选项为False

您还将创建辅助函数来评估训练和测试数据集。

      from torch.utils.data import DataLoader
def train_func(sub_train_):
    # Train the model
    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()

    # Adjust the learning rate
    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_)
    

模型建立

在构建模型之前,您必须拆分数据,这可以通过torch.utils.data.dataset实用函数中的random_split模块完成。使用随机梯度下降优化器来优化网络,考虑到这是一个分类问题,使用交叉熵作为损失函数。lr 参数指定优化器函数的学习率。最后,打印出epochs性能和所用时间。

      import time
from torch.utils.data.dataset import random_split
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)')
    

输出:

      Epoch: 1  | time in 18 minutes, 17 seconds
	Loss: 0.0128(train)	|	Acc: 93.8%(train)
	Loss: 0.0000(valid)	|	Acc: 95.0%(valid)
Epoch: 2  | time in 17 minutes, 59 seconds
	Loss: 0.0080(train)	|	Acc: 96.1%(train)
	Loss: 0.0000(valid)	|	Acc: 95.9%(valid)
Epoch: 3  | time in 18 minutes, 9 seconds
	Loss: 0.0065(train)	|	Acc: 96.8%(train)
	Loss: 0.0000(valid)	|	Acc: 96.3%(valid)
Epoch: 4  | time in 18 minutes, 19 seconds
	Loss: 0.0056(train)	|	Acc: 97.2%(train)
	Loss: 0.0000(valid)	|	Acc: 95.9%(valid)
Epoch: 5  | time in 18 minutes, 17 seconds
	Loss: 0.0048(train)	|	Acc: 97.6%(train)
	Loss: 0.0000(valid)	|	Acc: 96.4%(valid)
    

从上面的输出可以看出,该模型在第五个时期的准确率达到了 97.6%。接下来,在测试数据上评估模型性能。

模型评估

下面的代码行检查测试数据并显示结果。

      print('Model result on test data...')
test_loss, test_acc = test(test_dataset)
print(f'\tLoss: {test_loss:.4f}(test)\t|\tAcc: {test_acc * 100:.1f}%(test)')
    

输出:

      Model result on test data...
	Loss: 0.0000(test)	|	Acc: 96.2%(test)
    

在测试数据上模型准确率为96.2%,与在训练数据上模型表现一致,说明模型取得了良好的效果。

结论

在本指南中,您学习了如何使用高性能深度学习库 PyTorch 构建文本分类模型。您学习了使用PyTorch 的torchtorchtext包构建文本分类算法的架构和关键组件。

要了解有关使用 Python 进行数据科学的更多信息,请参阅以下指南。

  1. Scikit 机器学习

  2. 使用 scikit-learn 进行线性、套索和岭回归

  3. 使用 scikit-learn 实现非线性回归树

  4. 使用 scikit-learn 进行神经网络机器学习

  5. 使用 scikit-learn 验证机器学习模型

  6. 使用 scikit-learn 进行集成建模

  7. 使用 scikit-learn 准备建模数据

  8. 数据科学初学者

  9. 使用 Python 的描述性统计数据解释数据

  10. 使用 Python 导入数据

以上内容来自杭州电子商务研究院推送
关注
关于我们
热门推荐
合作伙伴
免责声明:本站部分资讯来源于网络,如有侵权请及时联系客服,我们将尽快处理
Copyright © 2025-2027 ToB产业网址导航 公安备案 浙公网安备33010602013138号 浙ICP备16025413号-9
支持 反馈 关注 数据