人工智能之语言领域 自然语言处理 第十五章 BERT系列模型

人工智能之语言领域

第十五章 BERT系列模型


文章目录

  • 人工智能之语言领域
  • 前言BERT系列模型
    • [15.1 BERT基础模型详解](#15.1 BERT基础模型详解)
      • [15.1.1 BERT的模型结构与版本(Base/Large)](#15.1.1 BERT的模型结构与版本(Base/Large))
      • [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的中文文本分类与调优)
      • 任务目标
      • [完整代码实现(PyTorch + Hugging Face)](#完整代码实现(PyTorch + Hugging Face))
      • 关键调优技巧
        • [Layer-wise LR Decay 示例](#Layer-wise LR Decay 示例)
    • [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% 保持不变
  • 目标:预测被遮盖的原始词

🌰 示例:

输入:"我 [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》

相关推荐
小程故事多_802 小时前
规范驱动开发,OpenSpec 联动 Claude Code 全流程实战
人工智能·aigc·ai编程
WLJT1231231232 小时前
科技赋能消防 守护平安底线
人工智能·科技
BullSmall2 小时前
如何借助AI高效实现自动化测试
人工智能·自动化·集成测试
nap-joker2 小时前
【临床笔记+生理信号+医学影像】多模态风险预测,结合生理信号、医学影像和临床笔记
人工智能·机器学习·临床笔记+医学影像·早期融合·中期融合·晚期融合
upward3372 小时前
OpenClaw 阿里云/本地部署多Agent步骤
人工智能·阿里云·云计算
智算菩萨2 小时前
基于ChatGPT 5.4的Windows 11智能命令行维护系统:理论架构与实践应用
人工智能·python·ai·chatgpt·ai编程
大傻^2 小时前
LangChain4j 企业知识库实战:PDF 解析、OCR 与文档加载器生态
人工智能·pdf·ocr·langchain4j
视频砖家2 小时前
AI Sider: ChatGPT + DeepSeek + Gemini
人工智能·chatgpt
Peter·Pan爱编程2 小时前
第8节:多维网格——如何处理二维三维数据
人工智能·深度学习·计算机视觉