关于bert+lstm+crf实体识别训练数据的构建(一)

一.在实体识别中,bert+lstm+crf也是近来常用的方法。这里的bert可以充当固定的embedding层,也可以用来和其它模型一起训练fine-tune。大家知道输入到bert中的数据需要一定的格式,如在单个句子的前后需要加入"[CLS]"和“[SEP]”,需要mask等。下面构造训练集并利用albert抽取句子的embedding。

  1 import torch
  2 from configs.base import config
  3 from model.modeling_albert import BertConfig, BertModel
  4 from model.tokenization_bert import BertTokenizer
  5 from keras.preprocessing.sequence import pad_sequences
  6 from torch.utils.data import TensorDataset, DataLoader, RandomSampler
  7
  8 import os
  9
 10 device = torch.device(‘cuda‘ if torch.cuda.is_available()  else "cpu")
 11 MAX_LEN = 10
 12 if __name__ == ‘__main__‘:
 13     bert_config = BertConfig.from_pretrained(str(config[‘albert_config_path‘]), share_type=‘all‘)
 14     base_path = os.getcwd()
 15     VOCAB = base_path + ‘/configs/vocab.txt‘  # your path for model and vocab
 16     tokenizer = BertTokenizer.from_pretrained(VOCAB)
 17
 18     # encoder text
 19     tag2idx={‘[SOS]‘:101, ‘[EOS]‘:102, ‘[PAD]‘:0, ‘B_LOC‘:1, ‘I_LOC‘:2, ‘O‘:3}
 20     sentences = [‘我是中华人民共和国国民‘, ‘我爱祖国‘]
 21     tags = [‘O O B_LOC I_LOC I_LOC I_LOC I_LOC I_LOC O O‘, ‘O O O O‘]
 22
 23     tokenized_text = [tokenizer.tokenize(sent) for sent in sentences]
 24     #利用pad_sequence对序列长度进行截断和padding
 25     input_ids = pad_sequences([tokenizer.convert_tokens_to_ids(txt) for txt in tokenized_text], #没法一条一条处理,只能2-d的数据,即多于一条样本,但是如果全部加载到内存是不是会爆
 26                               maxlen=MAX_LEN-2,
 27                               truncating=‘post‘,
 28                               padding=‘post‘,
 29                               value=0)
 30
 31     tag_ids = pad_sequences([[tag2idx.get(tok) for tok in tag.split()] for tag in tags],
 32                             maxlen=MAX_LEN-2,
 33                             padding="post",
 34                             truncating="post",
 35                             value=0)
 36
 37     #bert中的句子前后需要加入[CLS]:101和[SEP]:102
 38     input_ids_cls_sep = []
 39     for input_id in input_ids:
 40         linelist = []
 41         linelist.append(101)
 42         flag = True
 43         for tag in input_id:
 44             if tag > 0:
 45                 linelist.append(tag)
 46             elif tag == 0 and flag:
 47                 linelist.append(102)
 48                 linelist.append(tag)
 49                 flag = False
 50             else:
 51                 linelist.append(tag)
 52         if tag > 0:
 53             linelist.append(102)
 54         input_ids_cls_sep.append(linelist)
 55
 56     tag_ids_cls_sep = []
 57     for tag_id in tag_ids:
 58         linelist = []
 59         linelist.append(101)
 60         flag = True
 61         for tag in tag_id:
 62             if tag > 0:
 63                 linelist.append(tag)
 64             elif tag == 0 and flag:
 65                 linelist.append(102)
 66                 linelist.append(tag)
 67                 flag = False
 68             else:
 69                 linelist.append(tag)
 70         if tag > 0:
 71             linelist.append(102)
 72         tag_ids_cls_sep.append(linelist)
 73
 74     attention_masks = [[int(tok > 0) for tok in line] for line in input_ids_cls_sep]
 75
 76     print(‘---------------------------‘)
 77     print(‘input_ids:{}‘.format(input_ids_cls_sep))
 78     print(‘tag_ids:{}‘.format(tag_ids_cls_sep))
 79     print(‘attention_masks:{}‘.format(attention_masks))
 80
 81
 82     # input_ids = torch.tensor([tokenizer.encode(‘我 是 中 华 人 民 共 和 国 国 民‘, add_special_tokens=True)]) #为True则句子首尾添加[CLS]和[SEP]
 83     # print(‘input_ids:{}, size:{}‘.format(input_ids, len(input_ids)))
 84     # print(‘attention_masks:{}, size:{}‘.format(attention_masks, len(attention_masks)))
 85
 86     inputs_tensor = torch.tensor(input_ids_cls_sep)
 87     tags_tensor = torch.tensor(tag_ids_cls_sep)
 88     masks_tensor = torch.tensor(attention_masks)
 89
 90     train_data = TensorDataset(inputs_tensor, tags_tensor, masks_tensor)
 91     train_sampler = RandomSampler(train_data)
 92     train_dataloader = DataLoader(train_data, sampler=train_sampler, batch_size=2)
 93
 94     model = BertModel.from_pretrained(config[‘bert_dir‘],config=bert_config)
 95     model.to(device)
 96     model.eval()
 97     with torch.no_grad():
 98         ‘‘‘
 99         note:
100         一.
101         如果设置:"output_hidden_states":"True"和"output_attentions":"True"
102         输出的是: 所有层的 sequence_output, pooled_output, (hidden_states), (attentions)
103         则 all_hidden_states, all_attentions = model(input_ids)[-2:]
104
105         二.
106         如果没有设置:output_hidden_states和output_attentions
107         输出的是:最后一层  --> (output_hidden_states, output_attentions)
108        ‘‘‘
109         for index, batch in enumerate(train_dataloader):
110             batch = tuple(t.to(device) for t in batch)
111             b_input_ids, b_input_mask, b_labels = batch
112             last_hidden_state = model(input_ids = b_input_ids,attention_mask = b_input_mask)
113             print(len(last_hidden_state))
114             all_hidden_states, all_attentions = last_hidden_state[-2:] #这里获取所有层的hidden_satates以及attentions
115             print(all_hidden_states[-2].shape)#倒数第二层hidden_states的shape         print(all_hidden_states[-2])

二.打印结果

input_ids:[[101, 2769, 3221, 704, 1290, 782, 3696, 1066, 1469, 102], [101, 2769, 4263, 4862, 1744, 102, 0, 0, 0, 0]]
tag_ids:[[101, 3, 3, 1, 2, 2, 2, 2, 2, 102], [101, 3, 3, 3, 3, 102, 0, 0, 0, 0]]
attention_masks:[[1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 0, 0, 0, 0]]
4
torch.Size([2, 10, 768])
tensor([[[-1.1074, -0.0047,  0.4608,  ..., -0.1816, -0.6379,  0.2295],
         [-0.1930, -0.4629,  0.4127,  ..., -0.5227, -0.2401, -0.1014],
         [ 0.2682, -0.6617,  0.2744,  ..., -0.6689, -0.4464,  0.1460],
         ...,
         [-0.1723, -0.7065,  0.4111,  ..., -0.6570, -0.3490, -0.5541],
         [-0.2028, -0.7025,  0.3954,  ..., -0.6566, -0.3653, -0.5655],
         [-0.2026, -0.6831,  0.3778,  ..., -0.6461, -0.3654, -0.5523]],

[[-1.3166, -0.0052,  0.6554,  ..., -0.2217, -0.5685,  0.4270],
         [-0.2755, -0.3229,  0.4831,  ..., -0.5839, -0.1757, -0.1054],
         [-1.4941, -0.1436,  0.8720,  ..., -0.8316, -0.5213, -0.3893],
         ...,
         [-0.7022, -0.4104,  0.5598,  ..., -0.6664, -0.1627, -0.6270],
         [-0.7389, -0.2896,  0.6083,  ..., -0.7895, -0.2251, -0.4088],
         [-0.0351, -0.9981,  0.0660,  ..., -0.4606,  0.4439, -0.6745]]])

原文地址:https://www.cnblogs.com/little-horse/p/11731552.html

时间: 2024-11-15 06:20:34

关于bert+lstm+crf实体识别训练数据的构建(一)的相关文章

用深度学习做命名实体识别(四)——模型训练

通过本文你将了解如何训练一个人名.地址.组织.公司.产品.时间,共6个实体的命名实体识别模型. 准备训练样本 下面的链接中提供了已经用brat标注好的数据文件以及brat的配置文件,因为标注内容较多放到brat里加载会比较慢,所以拆分成了10份,每份包括3000多条样本数据,将这10份文件和相应的配置文件放到brat目录/data/project路径下,然后就可以从浏览器访问文件内容以及相应的标注情况了. 链接:https://pan.baidu.com/s/1-wjQnvCSrbhor9x3G

用IDCNN和CRF做端到端的中文实体识别

实体识别和关系抽取是例如构建知识图谱等上层自然语言处理应用的基础.实体识别可以简单理解为一个序列标注问题:给定一个句子,为句子序列中的每一个字做标注.因为同是序列标注问题,除去实体识别之外,相同的技术也可以去解决诸如分词.词性标注等不同的自然语言处理问题. 说到序列标注直觉是会想到RNN的结构.现在大部分表现最好的实体识别或者词性标注算法基本都是biLSTM的套路.就像Ruder在他的博客 Deep Learning for NLP Best Practices 里面说的,There has b

用CRF做命名实体识别

摘要 本文主要讲述了关于人民日报标注语料的预处理,利用CRF++工具包对模型进行训练以及测试 目录 明确我们的标注任务 语料和工具 数据预处理 1.数据说明 2.数据预处理 模型训练及测试 1.流程 2.标注集 3.特征模板 4.CRF++包的使用说明 总结与展望 正文 1.明确我们的标注任务 这篇文章主要是介绍用CRF模型去提取人民日报语料的时间.人物.地点及组织机构名,也就是提取TIME.PERSON.LOCATION.ORGANIZATION四种实体.训练我们直接使用CRF++工具包. 2

NLP入门(八)使用CRF++实现命名实体识别(NER)

CRF与NER简介 ??CRF,英文全称为conditional random field, 中文名为条件随机场,是给定一组输入随机变量条件下另一组输出随机变量的条件概率分布模型,其特点是假设输出随机变量构成马尔可夫(Markov)随机场. ??较为简单的条件随机场是定义在线性链上的条件随机场,称为线性链条件随机场(linear chain conditional random field). 线性链条件随机场可以用于序列标注等问题,而本文需要解决的命名实体识别(NER)任务正好可通过序列标注方

用深度学习做命名实体识别(七)-CRF介绍

还记得之前介绍过的命名实体识别系列文章吗,可以从句子中提取出人名.地址.公司等实体字段,当时只是简单提到了BERT+CRF模型,BERT已经在上一篇文章中介绍过了,本文将对CRF做一个基本的介绍.本文尽可能不涉及复杂晦涩的数学公式,目的只是快速了解CRF的基本概念以及其在命名实体识别等自然语言处理领域的作用. 什么是CRF? CRF,全称 Conditional Random Fields,中文名:条件随机场.是给定一组输入序列的条件下,另一组输出序列的条件概率分布模型. 什么时候可以用CRF?

CRF++地名实体识别(特征为词性和词)

http://x-algo.cn/index.php/2016/02/29/crf-name-entity-recognition/ 类似使用CRF实现分词和词性标注,地域识别也是需要生成相应的tag进行标注.这里使用的语料库是1998年1月人民日报语料集.最终学习出来的模型,对复杂的地名识别准确率(F值)非常低,推测是预料中对地名的标注多处是前后矛盾.例如  [华南/ns 地区/n]ns  标为地名实体,但是 东北/f 地区/n 确分开标注,类似错误还有很多.将来有时间可以考虑使用微软的词库 

用深度学习做命名实体识别(六)-BERT介绍

什么是BERT? BERT,全称是Bidirectional Encoder Representations from Transformers.可以理解为一种以Transformers为主要框架的双向编码表征模型.所以要想理解BERT的原理,还需要先理解什么是Transformers. Transformers简单来说是一个将一组序列转换成另一组序列的黑盒子,这个黑盒子内部由编码器和解码器组成,编码器负责编码输入序列,然后解码器负责将编码器的输出转换为另一组序列.具体可以参考这篇文章<想研究B

Tensorflow进行POS词性标注NER实体识别 - 构建LSTM网络进行序列化标注

http://blog.csdn.net/rockingdingo/article/details/55653279  Github下载完整代码 https://github.com/rockingdingo/deepnlp/tree/master/deepnlp/pos 简介 这篇文章中我们将基于Tensorflow的LSTM模型来实现序列化标注的任务,以NLP中的POS词性标注为例实现一个深度学习的POS Tagger.文中具体介绍如何基于Tensorflow的LSTM cell单元来构建多

神经网络结构在命名实体识别(NER)中的应用

近年来,基于神经网络的深度学习方法在自然语言处理领域已经取得了不少进展.作为NLP领域的基础任务-命名实体识别(Named Entity Recognition,NER)也不例外,神经网络结构在NER中也取得了不错的效果.最近,我也阅读学习了一系列使用神经网络结构进行NER的相关论文,在此进行一下总结,和大家一起分享学习. 1 引言 命名实体识别(Named Entity Recognition,NER)就是从一段自然语言文本中找出相关实体,并标注出其位置以及类型,如下图.它是NLP领域中一些复