Bert模型
一、定义
Bert 模型是 2018 年 10 月由 Google AI 研究院提出的一种预训练模型,采用 Transformer 的编码器(Encoder)结构,堆叠多层,目的是:训练出一个懂文本语言的通用特征提取器
二、BERT 机制
1. 双向注意力机制(Bidirectional Attention)= 自注意力机制
1.定义
普通 RNN/LSTM 只能从左到右看一句,BERT 可以同时看一句话的左右两边
双向 = 左边所有词 + 右边所有词(一句话内)= 上下文 full context
例如:
句子:“我喜欢吃苹果,因为它很甜。”
BERT 看 “苹果” 时:
- 左边:我喜欢吃
- 右边:因为它很甜
-
同时理解,真正双向注意力
2.自注意力公式(也即双向注意力公式)

- Q:查询(当前词)
- K:键(所有词)
- V:值(所有词)


2.多头注意力机制(Multi-Head Attention)
BERT 自注意力是多头并行:把 Query、Key、Value 向量分头投影成多组,并行执行多头自注意力,最后再拼接融合。
过程如下:
设输入词向量维度 d,头数 h
1.线性投影分头
输入词向量后分别得到 Q,K,V 矩阵,将 Q,K,V 矩阵分别通过学习权重矩阵投影,切分为 h 个小头:

每一头维度:d / h
2.每一头独立执行自注意力

3.多头结果拼接
把 h 个头的输出在维度上拼接:

三、BERT 预训练任务
任务:模型的任务 = 看【最终输出 + 损失函数】怎么定义,同一个模型结构,只要改最后输出层和损失函数,任务完全变掉。
1. MLM(Masked Language Model)掩码语言
在句子中随机遮盖一部分单词,让模型去猜
例子:“我喜欢吃 [MASK],因为它很甜。”模型要猜:是苹果?香蕉?还是橘子?
目的:让模型更好地根据全文理解单词的意思
2. NSP(Next Sentence Prediction)下句预测
给模型两句话,判断是不是同一段文章的连续两句,输出:是 / 不是(二分类)。
目的:让模型能够更好地理解句子间的关系
四、BERT 结构

上图是 BERT 的结构图,左侧的图表示了预训练的过程,右边的图是对于具体任务的微调过程。
1.BERT 的输入
BERT 得到要输入的句子后,要将句子的单词转成 Embedding:
编辑
- Token Embedding:词向量
- Segment Embedding:句子编号向量,用于区分每一个单词属于句子 A 还是句子 B
- Positional Encoding:位置向量
BERT 的输入向量,是由 三种 Embedding 直接相加 得到的:

[CLS] 和 [SEP] 作用?
[CLS]:分类专用 token.
最后一层 [CLS] 代表整个句子的语义向量
[SEP]:句子分隔符 + 注意力边界
句间隔离,不让两句词互相看见
2.Bert 预训练
BERT 输入句子得到 Input Embedding 之后,通过预训练方式训练模型,预训练有两个任务:
- MLM
- NSP
BERT 预训练的过程可以用下图来表示:

3.Bert 微调
预训练得到的 BERT 模型可以在后续用于具体 NLP 任务的时候进行微调 ,BERT 模型可以适用于多种不同的 NLP 任务,如下图所示
五、例子
1.分词
将 “商将务大床房” 拆成单个汉字 "商 务 大 床 房"。这是 BERT 的中文分词方式:按单个字 / 词切分(也可以是词粒度,但中文 BERT 通常用字粒度)。
注意:
- 实际 BERT 分词器还会加上特殊符号:
商 务 大 床 房→商 务 大 床 房 - 最终序列是:
[CLS] 商 务 大 床 房 [SEP]
2.生成标准输入向量
1. input_ids:词表索引
(101, 2112, 555, 2315, 13145, 32141, 102)
- 每个数字代表该 token 在词表中的索引
101是[CLS]的 ID,102是[SEP]的 ID- 后续模型会通过这些 ID,在嵌入层查表得到词向量
2. mask:注意力掩码
(1,1,1,1,1,1,1, 0,0,0,0,0,0,0,0,......)
1代表真实 token,模型需要处理0代表 padding(填充的无效 token),模型会忽略- 作用:让所有输入序列长度一致,不影响注意力计算
3. seq_ids(segment_ids):句子标记
(0,0,0,0,0,0,0,0 ........................)
- 标记每个 token 属于哪个句子(
0代表第一句,1代表第二句) - 这张图是单句输入,所以全是
0 - 如果是句子对任务(如问答),第一句标
0,第二句标1
3.Embedding 嵌入
根据标准输入向量得到3种Embedding:
Token Embedding(词嵌入)———— input_ids
Segment Embedding(句子嵌入)———— seq_ids
Position Embedding(位置嵌入)————pos_ids
BERT 把这三种向量直接相加,得到每个 token 的最终输入向量:

嵌入的实际操作:
input_ids,seq_ids,pos_ids 各自通过一次全连接,输出维度为768的向量
4.多头自注意力(Multi-Head Attention)
1.输入向量 Embeedding 经过3个分别的全连接线性变换,得到 Query(Q)、Key(K)、Value(V)
2.计算多头注意力:
- 把 Q/K/V 分成多个头
- 每个头独立计算注意力,再拼接起来
3.输出的向量维度和输入保持一致,还是 768
5.Add & Norm(残差连接与层归一化,第1次)
1.Add(残差连接):把「多头注意力的输出」和「原始输入向量」直接相加
2.Norm(层归一化):对相加后的结果做层归一化,稳定分布
结果:输出的向量维度和输入保持一致,还是 768,作为下一层(前馈网络)的输入
6.前馈神经网络(Feed Forward)
这是一个两层的全连接网络 Linear,BERT 里的标准结构是:
- 第一层:
Linear(768 → 3072),然后加激活函数(GELU) - 第二层:
Linear(3072 → 768),恢复维度
作用:对每个位置的向量做非线性变换,提取更复杂的语义特征
7.Add & Norm(残差连接与层归一化,第2次)
- Add:把「前馈网络的输出」和「前馈网络的输入」直接相加
- Norm:对相加后的结果做层归一化,稳定分布
- 输出的向量维度和输入保持一致,还是 768,传给 BERT 的下一层(或者传给Pooler output层)
8.Pooler output
1.取最后一层 [CLS] token 的 hidden state
也就是从 BERT 输出的最终向量里,只拿出每句话的 第 0 个位置 = [CLS]。即每句话开头的 [CLS] 768维向量 【以BERT-base 的 768 为例】
为什么要拿[CLS] 768 维向量 ?
因为 [CLS] 经过了全部 12 层双向注意力它融合了整句话所有词的信息所以可以当作 句子的总代表向量
2.拿到 [CLS] 768 维向量后通过一个全连接层(Linear)+ Tanh 激活
公式:pooler_output=tanh(W⋅CLS_hidden+b)
- 输入维度:
hidden_size(BERT-base 是 768) - 输出维度:和输入一样,也是 768
- 作用:把
[CLS]的向量,映射成一个 “句子级的向量表示”
9.输出给解码器
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐




所有评论(0)