使用了苏神的bert4keras框架
分别借鉴了并改动了
- keras_roberta的转换方法 (由fairseq版的RoBERETa pytorch转为原版BERT Tensorflow)
- RobertaTokenizer的分词方法
得益于bert4keras的可扩展性,完全不需要修改bert4keras的框架,仅需要调用BERT类和更改tokenizer即可实现在bert4keras框架使用英文原版RoBERTa
- 使用英文RoBERTa、GPT2、BART等模型的bpe分词
- 传入custom position id, 将position id设置为
[2, max_length]
- 抛弃segment embeddings, 将segment_vocab_size=0
- 将fairseq的pytorch RoBERTa转为google原版的BERT
简单写了一个文本分类的代码,可以直接运行cls_classification_roberta.py,也可以使用run_cls_roberta.sh(可能需要修改相对路径)
- 将fairseq原版的pytorch RoBERTa转为tensorflow格式
- 从fairseq/RoBERTa下载,base或large版的RoBERTa,保存至RoBERTa4Keras/models下.
- 使用convert_fairseq_roberta_to_tf.py将其转换为tensorflow格式,同样保存在RoBERTa4Keras/models下
- 此时,
models/roberta_large_fairseq_tf
下有四类文件,分别是bert_config.json
merges.txt
vocab.json
和roberta_large.ckpt.data|index|meta
三个文件
- 基于[CLS]位置的fine-tuning关键步骤
-
加载bpe分词器
merges_file = r'./models/roberta_large_fairseq_tf/merges.txt' vocab_file = r'./models/roberta_large_fairseq_tf/vocab.json' tokenizer = RobertaTokenizer(vocab_file=vocab_file, merges_file=merges_file)
-
使用bert4keras的框架中的BERT模型加载RoBERTa模型 这里需要设置两个关键参数,
custom_position_ids=True
传入自定义position_ids,segment_vocab_size=0
将segment embeddings维度设置为0
bert = build_transformer_model( config_path, checkpoint_path, model=model, with_pool=False, return_keras_model=False, custom_position_ids=True, segment_vocab_size=0 # RoBERTa don't have the segment embeddings (token type embeddings). )
-
分词和token编码 这里会调用
bpe_tokenization.py
中的分词模型,将会把输入的文本编码为<s> X </s>
这种形式token_ids, _ = tokenizer.encode(text, maxlen=maxlen)
-
位置编码 这里需要把位置编码设置为
[2,max_len]
,具体原因需要到fairseq的仓库下查issues,padding使用的是1
这个position id(可能也没有影响)custom_position_ids = [2 + i for i in range(len(token_ids))] batch_custom_position_ids = sequence_padding(batch_custom_position_ids, value=1)
其他地方与中文BERT基本一致,只需要改一些inputs就可以了,不再赘述