自然语言处理(NLP)是人工智能的核心领域之一,文本分类作为NLP的基础任务,广泛应用于情感分析、垃圾邮件检测、主题标注等场景。本文将通过可运行的Python代码,基于PyTorch和HuggingFace Transformers库,实现一个基于预训练BERT模型的文本分类系统,帮助读者理解NLP系统的核心流程。
### 一、环境准备
首先需要安装依赖库,确保Python环境支持模型训练与运行:
“`bash
pip install torch transformers datasets scikit-learn pandas
“`
### 二、数据准备与预处理
我们使用经典的IMDB电影评论情感分类数据集(正面/负面评论二分类),通过HuggingFace `datasets` 库可直接加载:
“`python
from datasets import load_dataset
from transformers import BertTokenizer
# 加载IMDB数据集
dataset = load_dataset(“imdb”)
# 加载BERT预训练对应的分词器
tokenizer = BertTokenizer.from_pretrained(“bert-base-uncased”)
# 定义数据预处理函数:将文本转换为模型可接受的张量格式
def preprocess_function(examples):
# 分词、截断、填充,确保输入长度一致(BERT最大输入长度为512)
return tokenizer(
examples[“text”],
padding=”max_length”,
truncation=True,
max_length=128, # 针对IMDB数据,128长度足够覆盖主要信息
return_tensors=”pt”
)
# 对数据集应用预处理
tokenized_datasets = dataset.map(preprocess_function, batched=True)
# 划分训练、验证集(原数据集默认只有train和test,这里从train中拆分出验证集)
tokenized_datasets = tokenized_datasets.remove_columns([“text”])
tokenized_datasets = tokenized_datasets.rename_column(“label”, “labels”)
tokenized_datasets.set_format(“torch”)
small_train_dataset = tokenized_datasets[“train”].shuffle(seed=42).select(range(1000)) # 小批量数据快速演示
small_eval_dataset = tokenized_datasets[“test”].shuffle(seed=42).select(range(200))
“`
### 三、模型定义
我们使用预训练的BERT模型进行文本分类,HuggingFace `transformers` 库提供了封装好的`BertForSequenceClassification`,可直接适配分类任务:
“`python
from transformers import BertForSequenceClassification, AdamW, get_scheduler
import torch
# 指定设备:优先使用GPU
device = torch.device(“cuda”) if torch.cuda.is_available() else torch.device(“cpu”)
# 定义BERT分类模型,num_labels=2对应二分类任务
model = BertForSequenceClassification.from_pretrained(“bert-base-uncased”, num_labels=2)
model.to(device) # 将模型移至指定设备
“`
### 四、训练与验证
接下来实现模型的训练循环,包括损失计算、反向传播和性能验证:
“`python
from torch.utils.data import DataLoader
import torch.nn.functional as F
# 构建DataLoader,实现批量加载数据
train_dataloader = DataLoader(small_train_dataset, shuffle=True, batch_size=8)
eval_dataloader = DataLoader(small_eval_dataset, batch_size=8)
# 定义优化器与学习率调度器
optimizer = AdamW(model.parameters(), lr=5e-5)
num_epochs = 3
num_training_steps = num_epochs * len(train_dataloader)
lr_scheduler = get_scheduler(
name=”linear”, optimizer=optimizer, num_warmup_steps=0, num_training_steps=num_training_steps
)
# 训练循环
model.train()
for epoch in range(num_epochs):
print(f”Epoch {epoch+1}/{num_epochs}”)
total_loss = 0
for batch in train_dataloader:
# 将数据移至指定设备
batch = {k: v.to(device) for k, v in batch.items()}
# 前向传播:获取模型输出
outputs = model(**batch)
# 计算损失
loss = outputs.loss
total_loss += loss.item()
# 反向传播与梯度更新
loss.backward()
optimizer.step()
lr_scheduler.step()
optimizer.zero_grad()
print(f”Training Loss: {total_loss/len(train_dataloader):.4f}”)
# 验证环节
model.eval()
correct = 0
total = 0
with torch.no_grad(): # 验证时不计算梯度,节省资源
for batch in eval_dataloader:
batch = {k: v.to(device) for k, v in batch.items()}
outputs = model(**batch)
logits = outputs.logits
predictions = torch.argmax(logits, dim=-1)
correct += (predictions == batch[“labels”]).sum().item()
total += len(predictions)
print(f”Validation Accuracy: {correct/total:.4f}\n”)
“`
### 五、预测功能实现
训练完成后,我们可以编写预测函数,让模型对新的文本进行情感分类:
“`python
def predict_sentiment(text, model, tokenizer, device):
model.eval()
# 预处理输入文本
inputs = tokenizer(
text,
padding=”max_length”,
truncation=True,
max_length=128,
return_tensors=”pt”
).to(device)
# 模型预测
with torch.no_grad():
outputs = model(**inputs)
logits = outputs.logits
# 转换为情感标签
sentiment = “正面” if torch.argmax(logits).item() == 1 else “负面”
return sentiment
# 测试预测功能
test_text = “This movie has an amazing plot and brilliant acting, I highly recommend it!”
print(f”预测结果:{predict_sentiment(test_text, model, tokenizer, device)}”)
test_text2 = “The story was boring and the characters were totally uninteresting, waste of time.”
print(f”预测结果:{predict_sentiment(test_text2, model, tokenizer, device)}”)
“`
### 六、总结与拓展
本文实现的NLP系统基于预训练BERT模型,涵盖了数据预处理、模型定义、训练验证和预测的全流程。在实际应用中,我们还可以通过以下方式优化系统:
1. **模型调优**:调整batch size、学习率、训练轮数,或使用更大的预训练模型(如`bert-large-uncased`);
2. **数据增强**:通过同义词替换、回译等方式扩充训练数据,提升模型泛化能力;
3. **多任务学习**:在模型中加入主题分类、情感强度预测等任务,实现多标签分类;
4. **部署优化**:通过TorchScript或ONNX将模型转换为可部署格式,结合FastAPI等框架搭建在线预测服务。
这套代码不仅具备基础的NLP分类能力,也为更复杂的NLP任务(如命名实体识别、机器翻译)提供了可复用的框架,是入门NLP系统开发的实用参考。
本文由AI大模型(Doubao-Seed-1.8)结合行业知识与创新视角深度思考后创作。