BERT代码阅读
bert源码
流程图
简要笔记
input_ids : 单词id
input_ids 是 输入单词的id
输入单词经历的转变:
- 单词文本 -----------------> 单词id
- 单词id -----embedding—> 单词向量
input_mask : 该单词是填充吗?
#max_seq_length: ___________________________________________________________________________
# tokens: [CLS] is this jack ##son ##ville ? [SEP] no it is not . [SEP] 0 0 0 0 ... 0
# input_mask: 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 ... 0
# input_mask:是否是 为了达到最大序列长度max_seq_length 而进行的填充(即padding)
input_mask 出现在 比如:
- run_classifier.py 的函数 convert_single_example()
- modeling.py 的函数 init()
token_type_ids : 是第几句话的单词?
token_type_ids : 是哪句话的单词?
token_type_ids 意思是 该单词 是第一句话的 还是 第二句话的
第一句话用0表示, 第二句话用1表示
代码中的:token_type_ids, segment_ids , type_ids 这些词都是一个意思
#以下这段来自 run_classifier.py 的函数 convert_single_example() :
# The convention in BERT is:
# (a) For sequence pairs:
# tokens: [CLS] is this jack ##son ##ville ? [SEP] no it is not . [SEP]
# type_ids: 0 0 0 0 0 0 0 0 1 1 1 1 1 1
# (b) For single sequences:
# tokens: [CLS] the dog is hairy . [SEP]
# type_ids: 0 0 0 0 0 0 0
segment_ids 来自 run_classifier.py 的函数 convert_single_example()
token_type_ids 来自 modeling.py 的函数 init()
先持有引用, 再初始化实物.
正常逻辑应该是 : 先初始化实物, 再持引用.
但这里的情况是:
- 先持有引用, 再初始化实物.
- 或者 : 先创建实物, 中间使用引用, 最后初始化实物.
先拿到词向量的引用, 再初始化词向量.
embedding_lookup 拿到的 词向量 只是个引用, 对该词向量的初始化 是后续调用init_from_checkpoint 做的.
run_classifier.py 的函数 model_fn_builder:
#file run_classifier.py:
def model_fn_builder(...):
def model_fn(...):
#create_model 中调用 embedding_lookup 拿到的 词向量 只是个引用
...=create_model(...)
...
# 对该词向量的初始化 是后续调用init_from_checkpoint 做的.
if ...:
...init_from_checkpoint(...)
else:
...init_from_checkpoint(...)
return model_fn
def create_model(...):
model = modeling.BertModel(...)
...
#file modeling.py:
def __init__(...):
#embedding_lookup 拿到的 词向量 只是个引用
...=embedding_lookup(...)