1、pipline方式数据样例
微观营销环境的相关机构是什么啊? 相关机构 1
微观营销环境的相关机构是什么啊? 网络接口 0
微观营销环境的相关机构是什么啊? 指挥官 0
微观营销环境的相关机构是什么啊? 指标 0
微观营销环境的相关机构是什么啊? 公司简介 0
微观营销环境的相关机构是什么啊? 理论 0
我们会发现,通过实体召回所有属性,以上述方式构建的分类/相似匹配模型,文本间的差异仅仅是属性值的改变,却额外的训练了一个分类模型,总体损失计算变为: l o s s n e r + l o s s t e x t c l a s s i f i e r loss_{ner}+loss_{textclassifier} lossner+losstextclassifier。因此,端到端的联合模型显得就很有必要了。
2、 端到端的联合模型(NER+RE)
在span片段识别的ner模型时,模型的span是枚举query产生的,如:姚明的老婆是谁?
姚
姚明
姚明的
姚明的老
姚明的老婆
姚明的老婆是
姚明的老婆是谁
姚明的老婆是谁?
在成功识别出“姚明”这个实体后,我们可以通过实体链接从知识库中召回所有与“姚明”相关的候选属性集合,如下:
['体重', '亚洲运动会', '出生年月', '生肖', '出生地', '星座', '登录身高', '语言', '民族', '所属运动队', '中文名', '血型', '别名', '毕业院校', '身高', '籍贯', '1997-2002上海大鲨鱼(CBA)2002-2011休斯顿火箭(NBA)', '生涯最高分', '职业生涯', '女儿', '祖籍', '主要奖项', '生涯中国篮球职业联赛/NBA数据', '性别', '初中', '职业', '小学', '出生日期', '外文名', '金牌', '重要事件', '篮板', '代表作品', '专业特点', 'NBA明星队赛(2003-2009)NBA最佳阵容第二队(2007、2009)NBA最佳阵容第三队(2004、2006、2008)ESPN全球最有潜力运动员(2000)劳伦斯世界体育奖-年度最佳新人(2003)', '运动项目', '主要成就', '国籍', '盖帽', '姓名', '老婆', '自传', '英文名', '研究生', '中锋', '位置', '个人资料', '银牌', '鞋码', '登录体重']
此时,可以将所有的候选属性当作是训练RE网络的样本,训练仍然是分类问题:“1”或“0”,将所有候选输入经过“BCEWithLogitsLoss()”损失函数即可拿到所有候选属性的logits。在知识库中查询答案时返回top1的属性对应的答案即可。
这样的优势就是只需训练一个BERT模型即可,也能减少推理速度。
3、模型代码结构
from torch import nn
from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss
from transformers import BertPreTrainedModel, BertModel
class KBQA(BertPreTrainedModel):
def __init__(self, config):
super(KBQA, self).__init__(config)
self.bert = BertModel(config)
self.ner = nn.Linear(config.hidden_size, 2)
self.re = nn.Linear(config.hidden_size, 1)
self.apply(self.init_bert_weights)
def forward(self, batch_data, task, is_train):
if args.task == 'ner':
token_ids, token_types, head, tail = batch_data
attention_mask = token_ids.gt(0)
sequence_output, _ = self.bert(token_ids, token_types, attention_mask, output_all_encoded_layers=False)
head_logits, tail_logits = self.ner(sequence_output).split(1, dim=-1)
head_logits = head_logits.squeeze(dim=-1)
tail_logits = tail_logits.squeeze(dim=-1)
logits = (head_logits, tail_logits)
if args.do_train:
seq_lengths = attention_mask.sum(-1).float()
ignored_index = head_logits.size(1)
head.clamp_(0, ignored_index)
tail.clamp_(0, ignored_index)
loss_fct = CrossEntropyLoss(ignore_index=ignored_index)
head_loss = loss_fct(head_logits, head)
tail_loss = loss_fct(tail_logits, tail)
loss = (head_loss + tail_loss) / 2
if args.task=='re':
token_ids, token_types, label = batch_data
attention_mask = token_ids.gt(0)
_, pooled_output = self.bert(token_ids, token_types, attention_mask, output_all_encoded_layers=False)
logits = self.re(pooled_output).squeeze(-1)
if args.do_train:
loss_fct = BCEWithLogitsLoss()
loss = loss_fct(logits, label)
return loss if is_train else logits
公众号:自然语言处理及深度学习