人工智能之语言领域
第十五章 BERT系列模型
文章目录
- 人工智能之语言领域
- 前言BERT系列模型
- [15.1 BERT基础模型详解](#15.1 BERT基础模型详解)
- [15.1.1 BERT的模型结构与版本(Base/Large)](#15.1.1 BERT的模型结构与版本(Base/Large))
- 核心结构
- [BERT 版本对比](#BERT 版本对比)
- [15.1.2 BERT的预训练任务与训练过程](#15.1.2 BERT的预训练任务与训练过程)
- [(1)掩码语言建模(Masked Language Model, MLM)](#(1)掩码语言建模(Masked Language Model, MLM))
- [(2)下一句预测(Next Sentence Prediction, NSP)](#(2)下一句预测(Next Sentence Prediction, NSP))
- 训练细节
- [15.2 BERT的变体模型](#15.2 BERT的变体模型)
- [15.2.1 中文特化模型](#15.2.1 中文特化模型)
- [15.2.2 轻量化变体](#15.2.2 轻量化变体)
- [15.2.3 领域特化模型](#15.2.3 领域特化模型)
- [15.3 BERT模型的下游任务适配](#15.3 BERT模型的下游任务适配)
- [15.3.1 分类任务适配:[CLS]向量与全连接层](#15.3.1 分类任务适配:[CLS]向量与全连接层)
- [15.3.2 序列标注任务适配:token向量与CRF](#15.3.2 序列标注任务适配:token向量与CRF)
- [15.3.3 关系抽取任务适配](#15.3.3 关系抽取任务适配)
- [15.4 实战:基于BERT的中文文本分类与调优](#15.4 实战:基于BERT的中文文本分类与调优)
- [BERT 系列模型演进图谱](#BERT 系列模型演进图谱)
- 小结
- 资料
前言BERT系列模型
BERT(Bidirectional Encoder Representations from Transformers)是自然语言处理(NLP)领域具有里程碑意义的预训练语言模型,由 Google 于 2018 年提出。它首次大规模成功应用双向 Transformer 编码器,在 11 项 NLP 任务上刷新纪录,开启了"预训练 + 微调"范式的黄金时代。本章将深入解析 BERT 的核心结构、预训练机制、主流变体、下游任务适配方法,并通过中文文本分类实战完整演示其工程落地过程。
15.1 BERT基础模型详解
15.1.1 BERT的模型结构与版本(Base/Large)
BERT 完全基于 Transformer 编码器堆叠 ,无解码器,仅用于语言理解任务。
核心结构
- 输入:词嵌入(Word Embedding) + 段落嵌入(Segment Embedding) + 位置嵌入(Position Embedding)
- 主干:多层 Transformer 编码器(每层含 Multi-Head Self-Attention + FFN)
- 输出:每个 token 的上下文表示
Input
Token: [CLS] 我 爱 NLP [SEP]
Segment: A A A A A
Position: 0 1 2 3 4
Embedding
Sum
Transformer
Encoder × N
输出向量:
h_CLS, h_我, h_爱, h_NLP, h_SEP
BERT 版本对比
| 模型 | 层数(L) | 隐藏层维度(H) | 注意力头数(A) | 参数量 |
|---|---|---|---|---|
| BERT-Base | 12 | 768 | 12 | ~110M |
| BERT-Large | 24 | 1024 | 16 | ~340M |
✅ 选择建议:
- 资源有限/快速原型 → BERT-Base
- 追求 SOTA 性能 → BERT-Large(需强大 GPU)
15.1.2 BERT的预训练任务与训练过程
BERT 采用两个自监督任务进行预训练:
(1)掩码语言建模(Masked Language Model, MLM)
- 随机遮盖输入中 15% 的 token
- 其中:
- 80% 替换为
[MASK] - 10% 替换为随机词
- 10% 保持不变
- 80% 替换为
- 目标:预测被遮盖的原始词
🌰 示例:
输入:"我 [MASK] 自然语言处理。"
目标:预测 "爱"
(2)下一句预测(Next Sentence Prediction, NSP)
- 构造句子对:(A, B)
- 50%:B 是 A 的真实下一句(标签=IsNext)
- 50%:B 是随机句子(标签=NotNext)
- 目标:判断两句话是否连续
⚠️ 后续研究发现:NSP 对多数任务帮助有限,RoBERTa 等模型已弃用
训练细节
- 语料:BooksCorpus(8亿词) + 英文维基百科(25亿词)
- Batch Size:256(Base) / 512(Large)
- 训练步数:1M steps
- 优化器:Adam(β₁=0.9, β₂=0.999),学习率=1e-4
15.2 BERT的变体模型
15.2.1 中文特化模型
标准 BERT 使用 WordPiece 分词,对中文不友好(按字切分,丢失词义)。中文社区推出优化版本:
| 模型 | 改进点 | Hugging Face ID |
|---|---|---|
| BERT-Chinese | 基于中文维基训练,按字分词 | bert-base-chinese |
| RoBERTa-Chinese | 移除 NSP,更大 batch,动态掩码 | hfl/chinese-roberta-wwm-ext |
| MacBERT | 用相似词替代 [MASK],缓解预训练-微调不一致 |
hfl/chinese-macbert-base |
💡 全词掩码(Whole Word Masking, WWM) :
掩盖整个词而非单字。
例:"自然语言处理" → 全部掩盖,而非只盖"语"。
15.2.2 轻量化变体
| 模型 | 核心思想 | 压缩率 | 性能损失 |
|---|---|---|---|
| DistilBERT | 知识蒸馏(6层 vs 12层) | 40% 参数 | ↓2-3% |
| ALBERT | 参数共享 + 因式分解嵌入 | 89% 参数(xxlarge) | ↑或持平 |
| TinyBERT | 深度+宽度蒸馏 | 14% 参数 | ↓3-5% |
✅ 适用场景:移动端、API 服务、边缘计算
15.2.3 领域特化模型
在通用 BERT 基础上,用领域语料继续预训练(Domain-Adaptive Pretraining):
| 领域 | 代表模型 | 训练语料 |
|---|---|---|
| 医疗 | BioBERT , ClinicalBERT | PubMed, 电子病历 |
| 金融 | FinBERT | 财报、新闻、研报 |
| 法律 | Legal-BERT | 判决书、法律条文 |
| 中文电商 | E-Commerce BERT | 商品描述、评论 |
🔧 构建方法:
python# 在领域语料上继续 MLM 训练 model = BertForMaskedLM.from_pretrained("bert-base-chinese") trainer.train(dataset=domain_corpus)
15.3 BERT模型的下游任务适配
BERT 输出每个 token 的上下文向量 h_i \\in \\mathbb{R}\^{768} ,不同任务使用不同向量:
15.3.1 分类任务适配:[CLS]向量与全连接层
- 使用
[CLS]token 的输出向量 h_{\\text{\[CLS\]}} 作为整句表示 - 接一个全连接层 + Softmax 进行分类
输入句子
BERT
h_[CLS]
全连接层
(768 → num_classes)
类别概率
python
from transformers import BertModel, BertTokenizer
import torch.nn as nn
class BertClassifier(nn.Module):
def __init__(self, num_classes, model_name='bert-base-chinese'):
super().__init__()
self.bert = BertModel.from_pretrained(model_name)
self.dropout = nn.Dropout(0.1)
self.classifier = nn.Linear(768, num_classes) # Base版隐藏层=768
def forward(self, input_ids, attention_mask):
outputs = self.bert(input_ids=input_ids, attention_mask=attention_mask)
cls_output = outputs.last_hidden_state[:, 0] # [CLS] 向量
cls_output = self.dropout(cls_output)
logits = self.classifier(cls_output)
return logits
15.3.2 序列标注任务适配:token向量与CRF
- 使用每个 token 的输出向量 h_i
- 接全连接层预测标签
- 可加 CRF 层 建模标签转移约束(如 B-PER 后不能直接接 I-LOC)
词序列
BERT
h₁
h₂
hₙ
FC
FC
FC
CRF
标签序列
📌 注意:中文需按字分词,标签与字对齐
15.3.3 关系抽取任务适配
关系抽取 = 实体识别 + 关系分类。常用方法:
方法1:基于实体对
- 提取两个实体的
[CLS]+ 实体起始 token 向量 - 拼接后分类关系类型
方法2:序列标注(联合抽取)
- 使用特殊标记标注实体和关系(如 SPO 结构)
🧩 高级方案:Span-based BERT、TPLinker 等
15.4 实战:基于BERT的中文文本分类与调优
任务目标
使用 BERT 对中文新闻标题进行分类(如体育、财经、科技等)。
完整代码实现(PyTorch + Hugging Face)
python
# Step 1: 安装依赖
# pip install transformers datasets accelerate scikit-learn
from transformers import (
BertTokenizer, BertForSequenceClassification,
TrainingArguments, Trainer
)
from datasets import load_dataset
import numpy as np
# Step 2: 加载数据集(以 THUCNews 为例)
dataset = load_dataset("thucnews") # 或自定义 CSV
train_dataset = dataset["train"].shuffle(seed=42).select(range(10000)) # 小样本
test_dataset = dataset["test"].shuffle(seed=42).select(range(2000))
# Step 3: 加载中文 BERT 分词器
model_name = "hfl/chinese-roberta-wwm-ext" # 推荐使用 RoBERTa-WWM
tokenizer = BertTokenizer.from_pretrained(model_name)
def tokenize_function(examples):
return tokenizer(
examples["text"],
truncation=True,
padding="max_length",
max_length=128
)
# Tokenize 数据集
train_tokenized = train_dataset.map(tokenize_function, batched=True)
test_tokenized = test_dataset.map(tokenize_function, batched=True)
# Step 4: 加载模型(自动适配分类头)
num_labels = len(set(train_dataset["label"]))
model = BertForSequenceClassification.from_pretrained(
model_name,
num_labels=num_labels
)
# Step 5: 设置训练参数
training_args = TrainingArguments(
output_dir="./results",
evaluation_strategy="epoch",
save_strategy="epoch",
learning_rate=2e-5,
per_device_train_batch_size=16,
per_device_eval_batch_size=16,
num_train_epochs=3,
weight_decay=0.01,
load_best_model_at_end=True,
metric_for_best_model="accuracy"
)
# Step 6: 定义评估指标
def compute_metrics(eval_pred):
predictions, labels = eval_pred
predictions = np.argmax(predictions, axis=1)
return {"accuracy": (predictions == labels).mean()}
# Step 7: 创建 Trainer 并训练
trainer = Trainer(
model=model,
args=training_args,
train_dataset=train_tokenized,
eval_dataset=test_tokenized,
compute_metrics=compute_metrics
)
trainer.train()
# Step 8: 模型推理
def predict(text):
inputs = tokenizer(text, return_tensors="pt", truncation=True, max_length=128)
with torch.no_grad():
logits = model(**inputs).logits
predicted_class_id = logits.argmax().item()
return model.config.id2label[predicted_class_id]
# 测试
print(predict("梅西在世界杯决赛中打入关键进球")) # 输出: "体育"
关键调优技巧
| 技巧 | 说明 |
|---|---|
| 学习率 | BERT 微调敏感,通常 2e-5 ~ 5e-5 |
| Batch Size | 越大越好(受显存限制),可梯度累积 |
| Early Stopping | 防止过拟合(配合 load_best_model_at_end) |
| Layer-wise LR Decay | 底层 LR 小,顶层 LR 大(如 0.95 衰减率) |
| 对抗训练 | 如 FreeLB,提升鲁棒性 |
Layer-wise LR Decay 示例
python
from transformers import AdamW
def get_optimizer_grouped_parameters(model, base_lr=2e-5, decay_rate=0.95):
no_decay = ["bias", "LayerNorm.weight"]
optimizer_grouped_parameters = []
# 获取所有编码器层
layers = [getattr(model.bert.encoder, f'layer.{i}') for i in range(12)]
layers.reverse() # 从顶层到底层
lr = base_lr
for layer in layers:
lr *= decay_rate
optimizer_grouped_parameters += [
{"params": [p for n, p in layer.named_parameters() if not any(nd in n for nd in no_decay)], "lr": lr},
{"params": [p for n, p in layer.named_parameters() if any(nd in n for nd in no_decay)], "weight_decay": 0.0}
]
# 嵌入层和分类头
optimizer_grouped_parameters += [
{"params": [p for n, p in model.bert.embeddings.named_parameters() if not any(nd in n for nd in no_decay)], "lr": lr * decay_rate},
{"params": model.classifier.parameters(), "lr": base_lr}
]
return optimizer_grouped_parameters
optimizer = AdamW(get_optimizer_grouped_parameters(model))
BERT 系列模型演进图谱
BERT
RoBERTa
(移除NSP, 动态掩码)
DistilBERT
(知识蒸馏)
ALBERT
(参数共享)
MacBERT
(替换[MASK])
Chinese-RoBERTa-WWM
(中文全词掩码)
领域特化模型
(医疗/金融/法律)
小结
BERT 通过双向 Transformer 编码器 和掩码语言建模 ,实现了强大的上下文感知能力。其变体(如 RoBERTa、MacBERT)进一步优化了训练策略,而轻量化(DistilBERT)和领域特化(BioBERT)则拓展了应用场景。在下游任务中,通过合理使用 [CLS] 向量或 token 向量,BERT 可高效适配分类、序列标注、关系抽取等任务。掌握 BERT 系列模型,是构建高性能 NLP 系统的关键一步。
资料
咚咚王
《Python 编程:从入门到实践》
《利用 Python 进行数据分析》
《算法导论中文第三版》
《概率论与数理统计(第四版) (盛骤) 》
《程序员的数学》
《线性代数应该这样学第 3 版》
《微积分和数学分析引论》
《(西瓜书)周志华-机器学习》
《TensorFlow 机器学习实战指南》
《Sklearn 与 TensorFlow 机器学习实用指南》
《模式识别(第四版)》
《深度学习 deep learning》伊恩·古德费洛著 花书
《Python 深度学习第二版(中文版)【纯文本】 (登封大数据 (Francois Choliet)) (Z-Library)》
《深入浅出神经网络与深度学习 +(迈克尔·尼尔森(Michael+Nielsen)》
《自然语言处理综论 第 2 版》
《Natural-Language-Processing-with-PyTorch》
《计算机视觉-算法与应用(中文版)》
《Learning OpenCV 4》
《AIGC:智能创作时代》杜雨 +&+ 张孜铭
《AIGC 原理与实践:零基础学大语言模型、扩散模型和多模态模型》
《从零构建大语言模型(中文版)》
《实战 AI 大模型》
《AI 3.0》