(READY) bert 详解
动机、参考资料、涉及内容
动机
- Google 原版 bert 代码学习
参考资料
- Google 原版 bert 代码:https://github.com/google-research/bert, commit-id: eedf5716ce1268e56f0a50264a88cafad334ac61
涉及内容
- 尽量用自然语言描述代码,只附上相应的源码链接
模型结构
Bert 也做了 emdedding 和输出层预测 token 做了 tie-weight
预训练
数据处理
原始文本的格式如下,具体例子可参考源代码库样例文件
总体处理逻辑为:
- 句子 -> 预处理 -> 转化为 token
- 文章 -> 每个句子都 token 化 -> 训练样本
tokenize的过程中, 经过各种预处理后, 最终每个句子变成 word 序列
# unicode 字符:U+0B90: ஐ, name 为 TAMIL LETTER AI
["apples", "dஐapp", "er"]
# 假设词表为[apple, ##es, er, ##s, er, d, ##app, app]
# 转换为的 token 序列为: 每个词用贪心算法查找词典: 先看apples在不在词表里, 再看apple在不在词表里
# 特殊情况1: 对于dஐapp, 在编码了d后, 一直查找词典都没找到, 则把整个ஐapp当作<unk>
# 特殊情况2: 如果某个词的长度超过了200, 则把整个词当作<unk>
=> [apple, ##s, d, <unk>, er]
每个example都有两段话, 部分被mask掉了, 需要同时预测mask掉的部分以及两段话是否出自同一篇文章
一个具体的example例子为(这里是对源码的准确理解, 对于完全复现, 具有参考意义):
# 假设设定模型的序列长度为16, 最多的mask数量为6个
paragraph_a, paragraph_b = "AB CD EF", "G HI J K"
# 原始实现里: 85%为"O"操作, 剩下的15%为替换操作, 其中: "M" 为 80%, "R" 为 10%, "RO" 为 10%
# ops表示对原始数据的操作: "O" 表示不操作, "M" 表示替换为 [MASK], "R" 表示替换为另一个, "RO" 表示替换为本身, 等同于"O"
ops = ["O" , "O", "M" , "O", "O" , "M" , "R" , "O" , "O", "O", "M" , "RO", "O", "O" ] + ["O", "O"]
range_helper=[0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 ] + [14, 15]
ori_tokens = ["[CLS]", "A", "##B", "C", "##D", "E" , "##F", "[SEP]", "G", "H", "##I", "J" , "K", "SEP"] + [0, 0]
# 以下为实际存储的数据(为了直观, token_id用token表示了)
input_ids = ["[CLS]", "A", "[M]", "C", "##D", "[M]", "A", "[SEP]", "G", "H", "[M]", "J" , "K", "SEP"] + [0, 0]
input_mask = [1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ] + [0, 0]
segment_ids= [0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 1 , 1 ] + [0, 0]
masked_lm_positions = [2 , 5 , 6 , 10 , 11] + [0] # 发生修改的位置, 补齐到 6
masked_lm_ids = ["##B", "E", "##F", "##I", "J"] + [0] # 发生修改位置的真实标签, 及ori_tokens中相应位置的值
masked_lm_weights = [1.0 , 1.0, 1.0 , 1.0 , 1.0] + [0.0]
next_sentence_labels = 1 # 如果前后两端话是相连的, 取值为1, 否则取值为 0.
说明:
- 第 2、10 个位置的操作不是 WWM(Whole Word Mask),而第 5、6个位置的操作是 WWM,并且对于 WWM,每个 wordpiece 的具体操作可以不一样:这个例子中第 5 个位置的操作是替换为 MASK,第 6 个位置是替换为其他字符
fine-tune 训练
原始代码仓库中的 fine-tune 采用的是不冻结参数
其他资料
BERT 官方仓库中并未提供 BERT 预训练所使用的 BooksCorpus (800M words) 和 English Wikipedia (2500M words) 这两个数据集的下载方式。
🤗 Transfomers 官方文档 推荐了这篇博客“复现” BERT的训练过程。其中提到了以上两个数据集已在 🤗 Datasets 维护:BooksCorpus 和 English Wikipedia。
备注:BERT原始论文中的 English Wikipedia 与 🤗 Datasets 上维护的版本有差异