共计 1676 个字符,预计需要花费 5 分钟才能阅读完成。
BERT 预训练的基本概念
BERT(Bidirectional Encoder Representations from Transformers)是一种基于 Transformer 架构的预训练语言模型。它的核心思想是通过大规模无监督文本数据预训练,学习通用的语言表示能力。BERT 预训练的目标是让模型理解语言的上下文关系,从而可以适配各种下游 NLP 任务。

BERT 的预训练过程主要包含两个任务:
- Masked Language Model (MLM):随机遮盖输入文本中的部分词汇,让模型预测被遮盖的词汇
- Next Sentence Prediction (NSP):判断两个句子是否是连续的上下文关系
BERT 的三种典型输出
1. [CLS]分类向量
[CLS]是 BERT 输入序列的第一个特殊 token,它的输出向量通常被用作整个输入序列的聚合表示。
- 特点:
- 维度为 768(BERT-base)或 1024(BERT-large)
- 经过整个 Transformer 层的上下文信息聚合
-
适用于序列级别的分类任务
-
适用场景:
- 文本分类(情感分析、主题分类等)
- 句子对任务(文本相似度、自然语言推理等)
2. 词级别输出
BERT 为输入序列中的每个 token(包括原始词和子词)都输出一个向量表示。
- 结构特点:
- 每个 token 对应一个 768 维向量
- 包含丰富的上下文信息
-
对同一个词在不同语境下会生成不同的向量
-
处理建议:
- 对于中文等不使用空格分隔的语言,需要注意子词对齐
- 可以取各词最后一层表示,或各层表示的加权组合
3. 注意力权重
BERT 的每一层都包含多头注意力机制,可以可视化注意力权重来理解模型关注的重点。
- 可视化示例:
- 可以观察到不同头关注不同方面的语言关系(语法、语义等)
- 有助于模型可解释性分析
代码示例:加载预训练 BERT 并提取特征
from transformers import BertTokenizer, BertModel
import torch
# 初始化 tokenizer 和模型
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
model = BertModel.from_pretrained('bert-base-uncased')
# 输入文本预处理
text = "This is a BERT tutorial."
inputs = tokenizer(text, return_tensors="pt")
# 前向传播,获取模型输出
with torch.no_grad():
outputs = model(**inputs)
# 提取不同输出
last_hidden_states = outputs.last_hidden_state # 词级别输出 [1, seq_len, 768]
pooler_output = outputs.pooler_output # [CLS]分类向量 [1, 768]
attentions = outputs.attentions # 各层的注意力权重
下游任务的特征选择策略
1. 文本分类
- 推荐使用 [CLS] 向量
- 可以在其基础上添加一个简单的分类层
2. 命名实体识别(NER)
- 使用词级别输出
- 对每个 token 进行分类预测
- 注意处理子词对齐问题
3. 问答系统(QA)
- 同时使用问题和上下文的词级别表示
- 计算问题与上下文各位置的相似度
避坑指南
处理长文本
BERT 的最大输入长度为 512 个 token。对于超长文本:
- 截断法:保留前 510 个 token(加 [CLS] 和[SEP])
- 分段法:将文本分成多个段落分别处理,再合并结果
特征维度匹配
- 确保下游任务输入维度与 BERT 输出维度一致
- 常见做法:添加适配层进行维度转换
微调 vs 特征提取
- 特征提取:冻结 BERT 参数,仅训练下游任务层
- 适合数据量小的场景
- 训练速度快
- 微调:同时训练 BERT 和任务特定层
- 适合数据量大的场景
- 通常效果更好但计算成本高
思考题
如何结合具体业务场景设计特征融合方案?例如:
- 对于多模态任务(文本 + 图像),如何有效融合 BERT 文本特征和 CNN 图像特征?
- 在推荐系统中,如何将用户行为特征与 BERT 文本表示结合?
这些问题的解决方案需要根据具体业务需求和数据特点进行针对性设计。
正文完
