在文章NLP(三十四)使用keras-bert实现序列标注任务 中,我们已经用keras-bert模块实现了中文序列标注任务,其中对BERT进行微调。当前,我们也可以顺便实现下英语序列标注任务。
本文将介绍如何使用keras-bert实现英语序列标注任务。
一个小测试
使用keras-bert实现英语序列标注任务的代码,大体上与文章NLP(三十四)使用keras-bert实现序列标注任务 中的相似,但英语序列标注有其特殊之处。其特殊之处在于,BERT会将复杂的英语单词拆分成多个简单英语单词,进行tokenize.
下面给出一个例子。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 from keras_bert import Tokenizer dict_path = './uncased_L-12_H-768_A-12/vocab.txt' token_dict = {}with open (dict_path, 'r' , encoding='utf-8' ) as reader: for line in reader: token = line.strip() token_dict[token] = len (token_dict) id_token_dict = {v: k for k, v in token_dict.items()} tokenizer = Tokenizer(token_dict=token_dict) code = tokenizer.encode("A man waits in the arrivals hall at Heathrow Airport in London." )print ("ids: " , code[0 ])print ("type_ids: " , code[1 ]) encode_text = [id_token_dict[_] for _ in code[0 ]]print ("encode_text: " , encode_text)
输出结果为:
1 2 3 ids: [101 , 1037 , 2158 , 18074 , 1999 , 1996 , 25470 , 2534 , 2012 , 9895 , 10524 , 3199 , 1999 , 2414 , 1012 , 102 ] type_ids: [0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] encode_text: ['[CLS]' , 'a' , 'man' , 'waits' , 'in' , 'the' , 'arrivals' , 'hall' , 'at' , 'heath' , '##row' , 'airport' , 'in' , 'london' , '.' , '[SEP]' ]
可以看到,在句子中单词Heathrow
被拆分成了两个tokenheath
和##row
,这是BERT英语预训练模型在tokenize时的特殊之处。
基于上述原因,我们原来的标注序列:
1 2 ['a ', 'man ', 'waits ', 'in ', 'the ', 'arrivals ', 'hall ', 'at ', 'heathrow ', 'airport ', 'in ', 'london ', '. '] ['O ', 'O ', 'O ', 'O ', 'O ', 'O ', 'O ', 'O ', 'B-LOC ', 'I-LOC ', 'O ', 'B-LOC ', 'O ']
在进入英语序列标注时,应当变成如下序列:
1 2 ['[CLS ]', 'a ', 'man ', 'waits ', 'in ', 'the ', 'arrivals ', 'hall ', 'at ', 'heath ', '##row', 'airport ', 'in ', 'london ', '. ', '[SEP ]'] ['O ', 'O ', 'O ', 'O ', 'O ', 'O ', 'O ', 'O ', 'O ', 'B-LOC ', 'B-LOC ', 'I-LOC ', 'O ', 'B-LOC ', 'O ', 'O ']
也就是说,拆分后的多个简单英语单词的序列标注标签将会跟随原先复杂单词的标签。
数据集
本文将会在两个英语命名实体识别的数据集上进行测试。
Conll2003
conll2003.train 14987条数据和conll2003.test
3466条数据,共4种标签:
wnut17
wnut17.train 3394条数据和wnut17.test 1009条数据,共6种标签:
模型评估
英语序列标注使用keras-bert进行模型训练、评估和预测的代码与文章NLP(三十四)使用keras-bert实现序列标注任务 中的相似,本文不再详细给出,感兴趣的读者可以参考Github的实现代码:https://github.com/percent4/keras_bert_english_sequence_labeling
。 我们利用上述模型,在两个数据集上的评估结果如下:
模型参数:uncased_L-12_H-768_A-12, MAX_SEQ_LEN=128, BATCH_SIZE=32,
EPOCH=10
运行model_evaluate.py,模型评估结果如下:
1 2 3 4 5 6 7 8 9 precision recall f1-score support PER 0 .9650 0 .9577 0 .9613 1842 ORG 0 .8889 0 .8770 0 .8829 1341 MISC 0 .8156 0 .8395 0 .8274 922 LOC 0 .9286 0 .9271 0 .9278 1837 micro avg 0 .9129 0 .9116 0 .9123 5942 macro avg 0 .9134 0 .9116 0 .9125 5942
最新SOTA结果的F1值为94.3%.
模型参数:uncased_L-12_H-768_A-12, MAX_SEQ_LEN=128, BATCH_SIZE=20,
EPOCH=10
运行model_evaluate.py,模型评估结果如下:
1 2 3 4 5 6 7 8 9 10 11 precision recall f1-score support work 0 .2069 0 .0571 0 .0896 105 person 0 .6599 0 .4830 0 .5577 470 product 0 .3333 0 .0965 0 .1497 114 location 0 .5070 0 .4865 0 .4966 74 group 0 .1500 0 .1538 0 .1519 39 corporation 0 .1935 0 .1765 0 .1846 34 micro avg 0 .5328 0 .3489 0 .4217 837 macro avg 0 .5016 0 .3489 0 .4033 837
BERT模型效果对比
Google对BERT进行优化,又开放了几个小版本的BERT英语预训练模型,如下:
BERT英语各版本模型
我们在Conll2003数据集上,模型参数为MAX_SEQ_LEN=128, BATCH_SIZE=32,
EPOCH=10,对比结果如下:
BERT-Small
0.8744
0.8859
0.8801
BERT-Medium
0.9052
0.9031
0.9041
BERT-Base
0.9129
0.9116
0.9123
总结
本文采用keras-bert实现了英语序列标注任务,其中对BERT进行微调。本项目已经上传至Github,网址为:https://github.com/percent4/keras_bert_english_sequence_labeling
。
后续将介绍如何使用keras-bert加载ALBERT模型,并实现文本多分类、文本多标签任务和序列标注任务,欢迎关注~
欢迎关注我的公众号
NLP奇幻之旅 ,原创技术文章第一时间推送。
欢迎关注我的知识星球“自然语言处理奇幻之旅 ”,笔者正在努力构建自己的技术社区。