文:陈之炎
本文约4400字,建议阅读10+分钟本文对BERT模型预训练任务的源代码进行了详细解读,在Eclipse开发环境里,对BERT 源代码的各实现步骤分步解析。
BERT模型架构是一种基于多层双向变换器(Transformers)的编码器架构,在tensor2tensor库框架下发布。由于在实现过程当中采用了Transformers,BERT模型的实现几乎与Transformers一样。
BERT预训练模型没有采用传统的从左到右或从右到左的单向语言模型进行预训练,而是采用从左到右和从右到左的双向语言模型进行预训练,本文对BERT模型预训练任务的源代码进行了详细解读,在Eclipse开发环境里,对BERT 源代码的各实现步骤分步解析。
BERT 模型的代码量比较大,由于篇幅限制,不可能对每一行代码展开解释,在这里,解释一下其中每一个核心模块的功能。
1) 数据读取模块
图 1
模型训练的第一步,是读取数据,将数据从数据集中读取进来,然后按照BERT 模型要求的数据格式,对数据进行处理,写出具体数据处理的类以及实际要用到的数据集中数据处理的方法,如果任务中用到的数据集不是MRPC ,这部分的代码需要依据特定的任务重新写一下如何操作数据集的代码,对于不同的任务,需要构造一个新的读取数据的类,把数据一行一行地读进来。
2) 数据预处理模块
图 2
利用tensorflow 对数据进行预处理,由于用TF-Record 读数据的速度比较快,使用起来比较方便,在数据读取层面,需要将数据转换成TF-Record格式。首先,定义一个writer,利用writer函数将数据样本写入到TF-Record当中,这样一来,在实际训练过程中,不用每次都到原始数据中去读取数据,直接到TF-Record当中读取处理好的数据。
把每一个数据样本都转化成一个TF-Record格式的具体做法如下:首先,构建一个标签,接下来对数据做一个判断,判断数据中由几句话组成,拿到当前第一句话后,做一个分词操作。分词方法为wordpiece 方法。在英文文本中,由字母组成单词,词与词之间利用空格来切分单词,利用空格切分单词往往还不充分,需要对单词做进一步切分转换,在BERT 模型中,通过调用wordpiece 方法将输入的单词再进一步切分,利用wordpiece的贪心匹配方法,将输入单词进一步切分成词片,从而使得单词表达的含义更加丰富。在这里,利用wordpiece 方法将读入的单词进行再次切分,把输入的单词序列切分成更为基本的单元,从而更加便于模型学习。
在中文系统中,通常把句子切分成单个的字,切分完成之后,把输入用wordpiece转化成wordpiece结构之后,再做一个判断,看是否有第二句话输入,如果有第二句话输入,则用wordpiece对第二句话做相同的处理。做完wordpiece转换之后,再做一个判断,判断实际句子的长度是否超过max_seq_length 的值,如果输入句子的长度超过max_seq_length规定的数值,则需要进行截断操作。
3) tf-record 制作
对输入句对进行编码,遍历wordpiece结构的每一个单词以及每一个单词的type_id ,加入句子分隔符【CLS】、【SEP】&#x