BERT
结构
每组数据的两个句子 \(A,B\) 被拼接在一起, 中间用 \([SEP]\) 分隔
整个 input 由 word embeddings, position embeddings, segment embeddings 组成
segment embeddings 用于区分单词属于哪个句子
整体结构如下图:
将两个句子的 token 序列拼在一起输入 BERT, 图中 \(E_i\) 表示输入的 embeddings, \(T_i\) 表示隐藏层的输出向量, \(C\) 特指 \([CLS]\) 的输出
注意传入的输入是 tokenizer 处理后的结果, 传入 BERT 后还要经过 transformer 的 embedding 转换成矩阵
预训练
Masked LM
由于多层的结构可以让目标单词在其他层间接的看到自己, 不能完全学习到上下文推理
所以把一些单词 token 随机成 \([MASK]\), 训练时去预测这些词
但是不能完全把单词替换成 \([MASK]\), 因为微调时这些 \([MASK]\) 标记不会出现
所以我们已 \(80%\) 概率替换成 \([MASK]\), \(10%\) 概率替换成一个随机单词, \(10%\) 概率不变
NSP
为了让模型理解两个句子间的关系, 每次以 \(50\) 概率在句子 \(A\) 后加上真实的下一句 \(B\); \(50%\) 概率加上随机句子
最后输出 \(C\) 为 \(0/1\), 判断 \(B\) 是否适合作为 \(A\) 的下一句
微调
可以使用几种数据进行微调:
- 判断两句话是否语义相同
- 判断两句话是否可以从一句话推导到另一句话, 即从前提推导到假设
- 问答
- \(A\) 为一句话, \(B\) 为空, 用于分类 / 标注任务
对比早期 GPT
GPT 是单向的 transformer, 更适用于翻译, 回答问题等连续生成的任务
BERT 是双向的 encoder 层, 更适合标注, 分类任务