本节课你将学到
- Transformer模型的核心原理
- 如何使用HuggingFace库加载预训练Transformer模型
- 实现一个文本分类任务的完整流程
- 模型训练与评估方法
开始之前
环境要求
- Python 3.8+
- 需要安装的包:
pip install torch transformers datasets pandas sklearn
- 硬件:CPU即可运行(GPU加速更好)
前置知识
- 第27讲注意力机制基础
- 基本Python编程能力
核心概念
什么是Transformer?
Transformer就像一群专业分工的翻译团队:
编码器(Encoder):负责理解输入文本
- 像团队中的"语言专家",分析句子的结构和含义
解码器(Decoder):负责生成输出
- 像"翻译员",根据理解的内容生成目标语言
自注意力机制(Self-Attention):
- 让模型知道句子中哪些词更重要
- 比如"猫吃鱼"中,"吃"是关键词
为什么Transformer适合文本分类?
- 能理解上下文关系(比传统方法更懂语义)
- 预训练模型(如BERT)已经学会了很多语言知识
- 微调(Fine-tuning)后可以快速适应新任务
代码实战
1. 准备数据
from datasets import load_dataset
# 加载IMDB电影评论数据集
# 这是一个二分类任务(正面/负面评价)
dataset = load_dataset('imdb')
print(dataset['train'][0]) # 查看第一条数据
# 输出示例:
# {'text': 'This movie was terrible...', 'label': 0}
# label=0是负面评价,1是正面
2. 加载预训练模型
from transformers import AutoTokenizer, AutoModelForSequenceClassification
# 使用DistilBERT模型(轻量版BERT)
model_name = "distilbert-base-uncased"
# 加载分词器
tokenizer = AutoTokenizer.from_pretrained(model_name)
# 加载模型(指定分类标签数为2)
model = AutoModelForSequenceClassification.from_pretrained(model_name, num_labels=2)
# ⚠️ 常见错误:忘记设置num_labels会导致维度不匹配
3. 数据预处理
def preprocess_function(examples):
# 对文本进行分词和填充
return tokenizer(examples['text'], truncation=True, padding='max_length', max_length=128)
# 应用预处理
tokenized_datasets = dataset.map(preprocess_function, batched=True)
# 重命名标签列(适配transformers要求)
tokenized_datasets = tokenized_datasets.rename_column("label", "labels")
# 设置数据格式为PyTorch张量
tokenized_datasets.set_format("torch", columns=["input_ids", "attention_mask", "labels"])
4. 训练模型
from transformers import Trainer, TrainingArguments
# 训练参数设置
training_args = TrainingArguments(
output_dir="./results", # 输出目录
evaluation_strategy="epoch", # 每轮评估
learning_rate=2e-5, # 学习率
per_device_train_batch_size=8, # 批大小
num_train_epochs=3, # 训练轮数
)
# 定义评估指标
from sklearn.metrics import accuracy_score
def compute_metrics(eval_pred):
predictions, labels = eval_pred
predictions = predictions.argmax(axis=-1)
return {"accuracy": accuracy_score(labels, predictions)}
# 创建Trainer
trainer = Trainer(
model=model,
args=training_args,
train_dataset=tokenized_datasets["train"].select(range(1000)), # 为演示取部分数据
eval_dataset=tokenized_datasets["test"].select(range(200)),
compute_metrics=compute_metrics,
)
# 开始训练!
trainer.train()
完整项目
项目结构:
transformer_text_classification/
├── main.py # 主程序
├── requirements.txt # 依赖包
└── README.md # 说明文档
requirements.txt
内容:
torch>=2.0.0
transformers>=4.30.0
datasets>=2.12.0
sklearn
运行效果
训练过程输出
Epoch Training Loss Validation Accuracy
1 0.345 0.852
2 0.198 0.876
3 0.112 0.891
预测示例
# 使用训练好的模型预测新文本
text = "This movie is fantastic! I love it."
inputs = tokenizer(text, return_tensors="pt")
outputs = model(**inputs)
predicted_class = outputs.logits.argmax().item()
print("正面评价" if predicted_class == 1 else "负面评价") # 输出:正面评价
常见问题
Q1: 出现CUDA内存不足错误
解决方法:
- 减小
per_device_train_batch_size
- 使用
gradient_accumulation_steps
Q2: 预测结果不理想
解决方法:
- 尝试更大的模型(如bert-base-uncased)
- 增加训练数据量
- 调整学习率
Q3: 如何保存和加载模型?
# 保存
trainer.save_model("./my_model")
# 加载
model = AutoModelForSequenceClassification.from_pretrained("./my_model")
课后练习
- 尝试在其他数据集(如新闻分类)上运行
- 比较不同模型(BERT vs RoBERTa)的效果
- 添加混淆矩阵评估指标