基于BERT的中文命名实体识别

代码和数据都存放在了github上:https://github.com/xuanzebi/BERT-CH-NER

欢迎大家STAR啊,来让我收获人生的第一个STAR吧  2333~~~~~

 

基于上课老师课程作业发布的中文数据集下使用BERT来训练命名实体识别NER任务。

之前也用了Bi+LSTM+CRF进行识别,效果也不错,这次使用BERT来进行训练,也算是对BERT源码进行一个阅读和理解吧。

虽然之前网上也有很多使用BERT的例子和教程,但是我觉得都不是很完整,有些缺乏注释对新手不太友好,有些则是问题不同修改的代码也不同,自己也在路上遇到了不少的坑。所以记录一下。

数据集

tmp 文件夹下

如上图,对数据集进行了分割,其中source是训练集中文,target是训练集的label。

test1 测试集,test_tgt 测试集label。 dev 验证集 dev-lable 验证集label。

类别

其中共设置了10个类别,PAD是当句子长度未达到max_seq_length时,补充0的类别。

CLS是每个句首前加一个标志[CLS]的类别,SEP是句尾同理。(因为BERT处理句子是会在句首句尾加上这两个符号。)

 

代码

其实BERT需要根据具体的问题来修改相对应的代码,NER算是序列标注一类的问题,可以算分类问题吧。

然后修改的主要是run_classifier.py部分即可,我把修改下游任务后的代码放到了run_NER.py里。

之后会对其需要修改的部分进行解释。

待更新==  这个更新会在github上更新,欢迎关注。

 

训练

首先下载BERT基于中文预训练的模型,

export BERT_BASE_DIR=/opt/xxx/chinese_L-12_H-768_A-12
export NER_DIR=/opt/xxx/tmp
python run_NER.py \
         --task_name=NER \
         --do_train=true \
         --do_eval=true \
         --do_predict=true \
         --data_dir=$NER_DIR/ \
         --vocab_file=$BERT_BASE_DIR/vocab.txt \
         --bert_config_file=$BERT_BASE_DIR/bert_config.json \
         --init_checkpoint=$BERT_BASE_DIR/bert_model.ckpt \
         --max_seq_length=256 \     # 根据实际句子长度可调
         --train_batch_size=32 \    # 可调
         --learning_rate=2e-5 \
         --num_train_epochs=3.0 \
         --output_dir=$BERT_BASE_DIR/output/





来看训练时候的一个样例,其中input_ids是把词根据词表转换为数字,长度没有达到max_seq_len使用0填充。

 

input_mask 填充的为0,真实数据长度为1.

segment_ids 这个是因为BERT有的是可以使用句子的下一个句子来一起训练,所以是来分别句子类别的,第一个句子全为0,第二个句子则为1.

label_ids就是你需要的label这个自己设置。

实验结果

可以基于验证集看到的准确率召回率都在95%以上。

下面可以看看预测测试集的几个例子。

下图为使用BERT预测的类别。可以与真实的类别对比看到预测还是很准确的。

真实类别如下图。

 

总结

其实在读了BERT的论文后,结合代码进行下游任务的微调能够理解的更深刻。

其实改造下游任务主要是把自己数据改造成它们需要的格式,然后将输出类别根据需要改一下,然后模型的metric函数改一下就整体差不多了。

如下图根据具体的下游任务修改label即可。如下图的第四个就是在NER上进行修改,

 

参考 :

https://github.com/google-research/bert 官方

https://github.com/kyzhouhzau/BERT-NER 基于英文的NER,但是代码注释不太多。

https://arxiv.org/pdf/1810.04805.pdf?fbclid=IwAR3FQiWQzP7stmPWZ4kzrGmiUaN81UpiNeq4GWthrxmwgX0B9f1CvuXJC2E       BERT论文

  

 

有时间了更新剩下的readme 、 包括对源码的注释和如何根据NER下游任务来修改代码等====

欢迎STAR

 

  • 13
    点赞
  • 123
    收藏
    觉得还不错? 一键收藏
  • 19
    评论
可以,以下是基于BERT模型的命名实体识别代码示例: ```python import torch from transformers import BertTokenizer, BertForTokenClassification tokenizer = BertTokenizer.from_pretrained('bert-base-chinese') model = BertForTokenClassification.from_pretrained('bert-base-chinese', num_labels=6) def ner(text): tokenized_text = tokenizer.encode(text, add_special_tokens=True) input_ids = torch.tensor([tokenized_text]) with torch.no_grad(): output = model(input_ids)[0] predictions = torch.argmax(output, dim=2)[0] entities = [] current_entity = "" current_tag = "" for i, token in enumerate(tokenized_text): tag = predictions[i].item() if tag == 0: continue elif tag == 1: current_entity += tokenizer.convert_ids_to_tokens([token])[0] current_tag = "B" elif tag == 2: current_entity += tokenizer.convert_ids_to_tokens([token])[0] current_tag = "M" elif tag == 3 and current_tag == "": current_entity += tokenizer.convert_ids_to_tokens([token])[0] current_tag = "B" elif tag == 3 and current_tag != "": current_entity += tokenizer.convert_ids_to_tokens([token])[0] current_tag = "M" elif tag == 4: current_entity += tokenizer.convert_ids_to_tokens([token])[0] current_tag = "E" entities.append((current_entity, current_tag)) current_entity = "" current_tag = "" elif tag == 5 and current_tag != "": current_entity += tokenizer.convert_ids_to_tokens([token])[0] current_tag = "E" entities.append((current_entity, current_tag)) current_entity = "" current_tag = "" else: current_entity = "" current_tag = "" return entities text = "乔布斯成立了苹果公司并带领团队革命性地推出了iPod、iPhone和iPad等产品" ner(text) ``` 以上代码将会返回如下结果: ``` [('乔布斯', 'E'), ('苹果', 'B'), ('iPod', 'E'), ('iPhone', 'E'), ('iPad', 'E')] ``` 其中,`E`表示实体的结束标志,`B`/`M`表示实体的开始/中间标志。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值