NLP(三十七)使用keras-bert实现英语序列标注任务

在文章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
# -*- coding: utf-8 -*-
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)

# tokenize
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']

也就是说,拆分后的多个简单英语单词的序列标注标签将会跟随原先复杂单词的标签。

数据集

本文将会在两个英语命名实体识别的数据集上进行测试。

  1. Conll2003

    conll2003.train 14987条数据和conll2003.test 3466条数据,共4种标签:

  2. wnut17

    wnut17.train 3394条数据和wnut17.test 1009条数据,共6种标签:

模型评估

英语序列标注使用keras-bert进行模型训练、评估和预测的代码与文章NLP(三十四)使用keras-bert实现序列标注任务中的相似,本文不再详细给出,感兴趣的读者可以参考Github的实现代码:https://github.com/percent4/keras_bert_english_sequence_labeling 。 我们利用上述模型,在两个数据集上的评估结果如下:

  • Conll2003

模型参数: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%.

  • wnut17

模型参数: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,对比结果如下:

模型名称 P R F1
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奇幻之旅,原创技术文章第一时间推送。

欢迎关注我的知识星球“自然语言处理奇幻之旅”,笔者正在努力构建自己的技术社区。


NLP(三十七)使用keras-bert实现英语序列标注任务
https://percent4.github.io/NLP(三十七)使用keras-bert实现英语序列标注任务/
作者
Jclian91
发布于
2023年7月10日
许可协议