bert-large-ner模型在实际使用时发现对org实体的提取不够准确,所以增加新的训练集尝试优化
(其实凑合用着原本的也不是不行,只是想要更高的准确率和泛化能力)
使用wikier数据集对hugging face的bert-large-ner模型进行微调,这里数据集使用了IOB标注,需要进行BIO格式的标签统一,微调代码如下:
查看模型训练时的label编码,微调时要使用相同的编码:
1.处理数据
- 首先将训练集读入成元组格式 lines=[('O O B-LOC', 'I love Beijing'), ('O O O B-LOC', 'He is from Shanghai')]
读入方法见笔记:《读取BIO数据 / 读取IOB数据并转化BIO》
- train_text= [doc[1] for doc in data_train] 把train_text和train_label整理成list
- train_label = [doc[0] for doc in data_train]
- train_inputs = tokenizer(train_text, max_length=MAX_INPUT_LENGTH, truncation=True, return_offsets_mapping=True)
参数return_offsets_mapping=True返回每个token在原始输入文本中的起始和结束位置的映射,用 .offset_mapping 获得
这里注意不要加多余的参数如is_split_into_ords=True之类的
在使用BERT的tokenizer时,默认情况下,输入文本会被分割成单词或子词,并进行相应的编码。并且tokenizer会自动添加“special tokens”(如果相关模型依赖于它们),这些标记是模型有时使用的特殊ID。
我们可以直接将多个输入文本作为一个列表传递给tokenizer,它将返回一个包含编码结果的字典。
- label2id = model.config.label2id # 获取模型训练时标签的序号与具体标签之间的映射
- id2label = model.config.id2label # {0: 'O', 1: 'B-MISC', 2: 'I-MISC', 3: 'B-PER', 4: 'I-PER', 5: 'B-ORG', 6: 'I-ORG', 7: 'B-LOC', 8: 'I-LOC'}
- 把wordoiece获得的token跟标注的label对应。
tokenizer返回的id比我们的数据集所包含的标签列表要长,因为wordpiece算法使得单词被再次拆分, 同时tokenizer还添加了特殊的标记比如CLS和SEP来检测开始结束的位置。所以需要重新处理标签
最后记得padding到MAX_INPUT_LENGTH。