【零基础学AI】第28讲:Transformer模型实战 - 文本分类

发布于:2025-07-08 ⋅ 阅读:(18) ⋅ 点赞:(0)

在这里插入图片描述

本节课你将学到

  • Transformer模型的核心原理
  • 如何使用HuggingFace库加载预训练Transformer模型
  • 实现一个文本分类任务的完整流程
  • 模型训练与评估方法

开始之前

环境要求

  • Python 3.8+
  • 需要安装的包:
    pip install torch transformers datasets pandas sklearn
    
  • 硬件:CPU即可运行(GPU加速更好)

前置知识

  • 第27讲注意力机制基础
  • 基本Python编程能力

核心概念

什么是Transformer?

Transformer就像一群专业分工的翻译团队:

  1. 编码器(Encoder):负责理解输入文本

    • 像团队中的"语言专家",分析句子的结构和含义
  2. 解码器(Decoder):负责生成输出

    • 像"翻译员",根据理解的内容生成目标语言
  3. 自注意力机制(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)的效果
  • 添加混淆矩阵评估指标

网站公告

今日签到

点亮在社区的每一天
去签到