在这里插入图片描述

本节课你将学到

  • BERT模型的核心原理与优势
  • HuggingFace Transformers库的BERT接口使用
  • 情感分析任务的完整实现流程
  • 模型微调(Fine-tuning)技巧

开始之前

环境要求

  • Python 3.8+
  • 需要安装的包:
    pip install torch transformers datasets pandas tqdm
    
  • GPU推荐(可加速训练)

前置知识

  • 第28讲Transformer基础
  • 基本PyTorch使用经验

核心概念

什么是BERT?

BERT就像一位读过全互联网的"语言专家":

  • 双向理解:同时考虑上下文(传统模型只能单向理解)
  • 预训练+微调:先海量自学,再快速适应新任务
  • 通用性强:适合各种NLP任务(分类/问答/生成等)

为什么BERT适合情感分析?

  1. 理解情感词与修饰词的关系
    (如"not good"与"very good"的差别)
  2. 捕捉长距离依赖
    (如"虽然开头很无聊,但结尾令人震撼")
  3. 已有丰富的语义知识
    (预训练阶段已学习过大量情感表达)

代码实战

1. 加载数据集

from datasets import load_dataset

# 加载SST-2情感分析数据集(斯坦福情感树库)
dataset = load_dataset('glue', 'sst2')
print(dataset['train'][0])  # 查看示例

# 输出示例:
# {'sentence': 'a stirring portrait of suffering', 'label': 1, 'idx': 0}
# label=1是正面,0是负面

2. 初始化BERT模型

from transformers import BertTokenizer, BertForSequenceClassification

# 加载BERT的分词器
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')

# 加载BERT分类模型(2分类)
model = BertForSequenceClassification.from_pretrained(
    'bert-base-uncased',
    num_labels=2,
    output_attentions=False  # 不需要注意力权重时可关闭以节省内存
)

# ⚠️ 注意:首次运行会自动下载约400MB的预训练模型

3. 数据预处理

def tokenize_function(examples):
    # 对文本进行BERT特有的分词处理
    return tokenizer(
        examples['sentence'],
        padding='max_length',
        truncation=True,
        max_length=128,
        return_tensors="pt"
    )

# 应用分词器
tokenized_datasets = dataset.map(tokenize_function, batched=True)

# 重命名标签列
tokenized_datasets = tokenized_datasets.rename_column("label", "labels")

# 设置PyTorch格式
tokenized_datasets.set_format("torch", 
    columns=["input_ids", "attention_mask", "labels"])

4. 训练准备

from transformers import TrainingArguments, Trainer
import numpy as np
from sklearn.metrics import accuracy_score

# 定义评估指标
def compute_metrics(pred):
    labels = pred.label_ids
    preds = pred.predictions.argmax(-1)
    return {'accuracy': accuracy_score(labels, preds)}

# 训练参数配置
training_args = TrainingArguments(
    output_dir='./bert_results',  # 输出目录
    evaluation_strategy="epoch",  # 每轮评估
    learning_rate=2e-5,          # 小学习率(微调关键!)
    per_device_train_batch_size=16,
    per_device_eval_batch_size=32,
    num_train_epochs=3,          # 训练轮数
    weight_decay=0.01,           # 权重衰减
    logging_dir='./logs',        # 日志目录
)

5. 开始训练

# 创建Trainer
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_datasets["train"],
    eval_dataset=tokenized_datasets["validation"],
    compute_metrics=compute_metrics,
)

# 启动训练
trainer.train()

# 保存模型
trainer.save_model("my_bert_sentiment")

完整项目

项目结构:

bert_sentiment_analysis/
├── train.py              # 训练脚本
├── predict.py            # 预测脚本
├── requirements.txt
└── README.md

requirements.txt内容:

torch>=2.0.0
transformers>=4.30.0
datasets>=2.12.0
tqdm>=4.0.0

运行效果

训练输出示例

Epoch  Training Loss  Validation Accuracy
1      0.324          0.894
2      0.198          0.906
3      0.142          0.912

预测新文本

from transformers import pipeline

# 创建情感分析管道
classifier = pipeline(
    "text-classification",
    model="my_bert_sentiment",
    tokenizer=tokenizer
)

# 测试样例
result = classifier("The movie was a waste of time")
print(result)  # [{'label': 'NEGATIVE', 'score': 0.98}]

result = classifier("This is the best film I've ever seen")
print(result)  # [{'label': 'POSITIVE', 'score': 0.96}]

常见问题

Q1: 训练速度太慢怎么办?

优化方案:

  • 使用bert-base-uncased代替更大模型
  • 开启混合精度训练(fp16=True
  • 减小max_length(如改为64)

Q2: 如何提高准确率?

调优建议:

  • 尝试更大的max_length(如256)
  • 增加训练轮数(num_train_epochs=5
  • 使用领域相关数据继续预训练

Q3: 模型文件太大如何部署?

解决方案:

  • 使用bert-base-uncased的蒸馏版(如DistilBERT)
  • 进行模型量化(torch.quantization)
  • 转换为ONNX格式

课后练习

  • 尝试在不同领域数据(如商品评论)上微调
  • 修改为多分类任务(如积极/中立/消极)
  • 比较BERT与LSTM模型的性能差异

扩展阅读

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐