一、BERT 核心概念
BERT(Bidirectional Encoder Representations from Transformers)的核心是:用双向自注意力机制,基于 "掩码语言模型(MLM)" 和 "下一句预测(NSP)" 预训练,让模型理解文本的上下文语义。关键概念拆解:
- 双向性:区别于传统单向语言模型,只看前后文,BERT 能同时看一个词的左边和右边上下文。
- 掩码语言模型(MLM):随机掩盖输入文本中 15% 的词,让模型预测被掩盖的词。
- 下一句预测(NSP):让模型判断两个句子是否是连续的上下文。
- Token Embedding + Segment Embedding + Position Embedding:BERT 的输入是这三种嵌入的叠加,分别表示 "词本身"、"属于哪个句子"、"词的位置"。
二、核心数学公式
1. 自注意力
BERT 的核心是多头自注意力,先看单头自注意力:
- 第一步:将输入嵌入 X映射为 Query、Key、Value 矩阵:
;
其中是可学习的权重矩阵。
- 第二步:计算注意力分数(缩放点积):
;
是缩放因子,避免点积结果过大导致 Softmax 梯度消失;
- Softmax 把注意力分数归一化为 0-1 的概率,代表对每个词的关注程度。
2. 多头注意力
将单头注意力重复 h 次(BERT-base 中 h=12),拼接结果后再线性变换:
其中为输出矩阵。
3. 掩码语言模型(MLM)损失
对被掩码的 token,计算预测概率与真实 token 的交叉熵损失:
其中是被掩码 token 的真实值,
是除该 token 外的上下文。
三、BERT 核心代码
模块一:导入核心库
import torch:导入 PyTorch 框架 ------BERT 是基于深度学习的模型,PyTorch 是运行和计算模型的核心工具,所有张量(数据)、模型运算都依赖它。from transformers import ...:导入 HuggingFace 的transformers库中两个核心组件:-
BertTokenizer:BERT 的分词器 ------ 负责把人类能看懂的自然语言(比如 "今天天气好")转换成模型能看懂的数字,是 "语言" 和 "模型" 之间的翻译官。 -
BertForMaskedLM:带 "掩码语言模型(MLM)" 任务头的 BERT 模型 ------ 专门用来做掩码词预测的 BERT,比基础版 BERT 多了一层 "预测词表" 的输出层。import torch
from transformers import BertTokenizer, BertForMaskedLM
-
模块二:加载模型和分词器
tokenizer:加载预训练的中文 BERT 分词器:from_pretrained('bert-base-chinese'):表示直接下载并使用官方训练好的中文 BERT 分词器,包含中文词表、分词规则,不用自己从零构建。- 如果是处理英文,换成
bert-base-uncased即可。
model:加载预训练的中文 BERT 模型,带 MLM 任务:- 预训练模型已经在海量中文文本,比如新闻、书籍,上学过语义,直接用就能预测,不用自己花几个月训练。
python
tokenizer = BertTokenizer.from_pretrained('bert-base-chinese')
model = BertForMaskedLM.from_pretrained('bert-base-chinese')
模块三:设置模型为评估模式
python
model.eval()
模块四:定义输入文本
定义要测试的文本,其中[MASK]是 BERT 的专用掩码标记------ 代表需要模型预测的位置,这是 MLM 任务的核心标识,模型会自动识别这个标记并预测它对应的词。
python
text = "今天的天气很[MASK],适合出门散步。"
模块五:文本编码
python
inputs = tokenizer(
text, # 输入文本
return_tensors='pt', # 返回PyTorch张量
padding=True, # 补全到相同长度(单句时无效果)
truncation=True # 截断过长文本(单句时无效果)
)
模块六:找到 MASK 的位置
python
mask_token_index = torch.where(inputs["input_ids"] == tokenizer.mask_token_id)[1]
模块七:模型前向传播
outputs = model(**inputs):把编码后的输入传给模型,执行前向计算:**inputs:解包字典,相当于把input_ids=inputs["input_ids"], attention_mask=inputs["attention_mask"]传给模型,不用手动写每个参数。outputs:模型的输出对象,包含logits原始预测分数、loss损失值,训练时用等。
logits = outputs.logits:提取原始预测分数:- 维度说明:
[1, 序列长度, 词表大小]------1 表示 1 个样本,序列长度是 16,词表大小是 21128,中文 BERT 的词表总数。 - 含义:每个位置的每个词都有一个分数,分数越高,模型认为这个词越可能出现在该位置。
- 维度说明:
python
with torch.no_grad():
outputs = model(**inputs) # **inputs 解包字典,传入input_ids/attention_mask等
logits = outputs.logits # 模型输出的原始分数(维度:[1, 序列长度, 词表大小])
模块八:提取 MASK 的预测结果
python
mask_token_logits = logits[0, mask_token_index, :] # 取[MASK]位置的所有词的分数
top_5_tokens = torch.topk(mask_token_logits, 5, dim=1).indices[0].tolist()
模块九:输出预测结果
python
print(f"原始文本:{text}")
print("预测的[MASK]候选词:")
for token in top_5_tokens:
# 将token id转换为文字
print(f"- {tokenizer.decode([token])}")
运行结果:
原始文本:今天的天气很[MASK],适合出门散步。
预测的[MASK]候选词:
-
好
-
晴
-
热
-
棒
-
冷
四、总结
- 核心概念:BERT 的核心是双向自注意力 + MLM 预训练,能理解上下文语义,输入是 "词嵌入 + 句子嵌入 + 位置嵌入" 的叠加。
- 核心公式:多头自注意力是 BERT 的基础,MLM 损失是预训练的核心目标,本质是交叉熵损失。
- 代码关键:HuggingFace 封装了 BERT 的复杂细节,核心步骤是 "分词编码→找掩码位置→模型预测→解析结果",新手只需关注输入输出的转换逻辑。
感谢大家的观看,如果有不足之处,请大家批评指正!