精华内容
下载资源
问答
  • CNN关系抽取模型.zip

    2021-03-19 08:58:43
    利用pytorch搭建了一个简单的关系抽取模型,数据集使用的SemEval2010_task8
  • 基于注意力与神经图灵机的语义关系抽取模型
  • 针对远程监督的基本假设过强容易引入噪声数据的问题,提出了一种可以对远程监督自动生成的训练数据去噪的人物实体关系抽取模型。在训练数据生成阶段,通过多示例学习的思想和基于 TF-IDF 的关系指示词发现的方法对...
  • 基于注意力的卷积神经网络关系抽取模型Attention CNNS 模型源自:论文Relation Classification via Multi-Level Attention CNNs 要点 本模型的精髓在于使用了两次注意力机制与输入数据特征组合。对于输入数据而言...

    基于注意力的卷积神经网络关系抽取模型Attention CNNS

    模型源自:论文Relation Classification via Multi-Level Attention CNNs

    要点

    本模型的精髓在于使用了两次注意力机制与输入数据特征组合。对于输入数据而言考虑了与语义相关的词向量,与实体位置相关的位置向量,这两种向量进行拼接构成了最初始的向量。使用滑动窗口的方式进行获取目标词与周围词组合在一起的综合向量。第一次的注意力机制应用在实体与序列中每个词的相关性。将相关性矩阵与输入的综合词向量矩阵相乘构成了一个二维矩阵,该矩阵使用卷积提取特征后对卷积结果使用第二次注意力机制进行捕获视窗与关系的相关性。再将卷积结果与相关性矩阵相乘获取出最后的输出结果。

    前置条件

    首先默认为序列中的实体已经被标记出来了。关系的种类是确定的,每一种关系都会有这个关系对应的向量进行表达,可以是通过trans系列的算法获取的向量,也可以是其他算法,反正这个向量已经是拿到了的。词向量已经训练完毕,已经生成了词向量库。

    模型结构

    在这里插入图片描述
    这里假设的是输入语句为:Fizzy drinks and meat cause heart disease and diabetes。实体分别为drinks和diabetes,这两个实体之间呈现的是因果关系。

    损失函数

    论文提出的距离

    在这里插入图片描述
    这里首先定义误差值,Wo表示的网络的输出,这个输出输出的是关系向量,Wo/|Wo|实际上表示归一化的意思,后面的WyL认为是正确的关系向量,向量之差求二范式。如果预测值与标准关系向量向量距离很小,则表明这种距离很小。基于这种距离提出损失函数
    在这里插入图片描述
    损失函数中β后面的是L2正则,前面有两项,第一项就是预测值与正确关系向量的距离,第二个中的y值表示的是非正确关系向量的距离,这里就会存在关系有很多个,只有一个关系向量是正确的,其他都作为错误关系向量,而这里选取的是其中距离最大的。
    在这里插入图片描述
    由此可见实际上在损失函数中的第二项实际计算的时候是计算了除正确关系向量外其他所有向量与预测向量的距离,取出的是最大的作为损失函数中的第二项。
    回过头看整个损失函数,不难发现这个函数的思路,首先是预测值与正确关系向量的距离,如果预测的很准,这个距离很小,那么该预测值与不正确关系向量的距离就会很大,损失函数中正好是1减的关系。两项之和越小,说明预测的越准,后面的L2正则只是为了防止过拟合。

    输入数据

    word embedding 词向量
    这个很好理解,就是提前训练好的词向量,在模型图中是Wid
    position embedding 位置向量
    表明词处于语句中的位置的向量,这种位置信息是当前词距离两个关系实体分别的词序距离,比如第一个实体处于语句中第三位置,第二个实体处于语句中第八个位置,那么第一个词的位置向量输入就是(2,7),这里的2与7两个数值分别就是对应的当前词到实体1的距离和实体2的距离。在模型图中是Wi1p和Wi2p。
    trigram信息
    这个是上下文信息的向量,所谓上下文信息是指定义一个滑动窗口,假设滑动窗口的长度是2k,以目标词为中心,截取目标词左右各k个长度的上下文词作为上下文信息,将这些词的词向量与位置向量拼接起来构成上下文向量。这个向量的在模型图中没有给出,他实际的输入位置还是在计算过注意力之后。

    模型计算过程

    首先构建需要输入的词向量(word embedding )与位置向量(position embedding )的拼接向量,该向量可以表示成
    在这里插入图片描述
    上面WiM是为了后续构建trigram信息用的,所以这里只要定义好窗口宽度,那么trigram信息就能表示成
    在这里插入图片描述
    Zi这里已经准备完毕,但是这不是直接输入模型的数据。模型图中的左下方window operation就是表达了计算Zi的过程。
    模型的思路是要把输入的词向量序列与实体做相关性计算,也就是第一层的attention机制,原文中提到的使用对角矩阵初始化attention机制的初始矩阵。为什么这么做我没懂,我估计是因为在计算过程中,顺序的向后计算每一个词的相关性,对角矩阵对角线上的值实际就是当前词本身。
    在这里插入图片描述
    这个过程表示词向量Wi与实体向量ej进行相关性计算,这种相关性计算用的是向量内积的形式。计算出来的Aiij表示的就是当前词Wi与实体向量ej的相关性也就是attention值。因为有两个实体,所以实际上该词会去计算两次attention值。
    将所语句中所有词逐个对j实体进行计算attention值之后获得序列词与实体的相关矩阵
    在这里插入图片描述
    因为有两个实体,实际上会计算出两个αij,这个过程对应了模型图中左下角和右下角的input att matrix Aj的过程。
    这个时候将得到的两个注意力矩阵αij与trigram信息Zi进行组合计算,因此实际上准备的输入信息Zi在这个时候才送入模型。
    然而论文中给出了三种计算方式,三种计算都将会生成一个二维的大矩阵,这个矩阵就是将来用作卷积的矩阵。
    三种方式分别是
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    每一个ri实际就是一个Zi与他的注意力计算值综合计算出来的,可以看到两个α值,分别代表的是与两个实体的注意力值。将所有的ri整合起来构成R矩阵,该矩阵就是模型图中中间红色网格部分。这个二维矩阵作为后面的卷积输入。
    在这里插入图片描述
    上式表达的是卷积过程,卷积的激活函数采用的是tanh,Bf为偏置,Wf为卷积核的参数。获得的R其实也是也是卷积后的二维矩阵,依然可以看做是一个图用来继续卷积,这里只做了一次卷积,该动作对应的是模型图中的中间红色网格状二维矩阵卷积到中间左边的矩阵过程。
    通常卷积之后是池化层,常规的池化常采用max或者avg,但是这个模型并没有使用常规池化,而是自定义了注意力偏置池化attention based pooling层进行替代常规池化。
    R矩阵通过卷积后获得的R
    矩阵实际上就是以卷积核大小的视窗提取出来的词与词周围的词综合的信息,而这些信息对于分类而言可能是具有不同程度的重要性,可以想象成R矩阵中的每个元素对分类的相关性是不同的,也就是每一个卷积的视窗对分类的相关性不同。未来表现这种不同的相关性,引入了G矩阵,用来表达相关性。
    在这里插入图片描述
    WL矩阵只的是所有的关系向量构成的二维矩阵,我各人理解是R
    矩阵是经过了卷积之后的二维矩阵,在矩阵shape上已经发生了改变,而WL是一个固定shape的矩阵,两个矩阵shape可能会不一致,这里就通过一个中间矩阵U进行连接,使得两个矩阵完成了相关性的计算获得了G矩阵。G矩阵就表示了卷积的视窗与每一个关系的相关性。
    对G矩阵进行softmax操作,将相关性的值转变为概率,这样就表示每一个视窗分别对应每一种关系的概率。
    在这里插入图片描述

    这个公式看起来很牛逼,好像很复杂,实际上就是指softmax操作,不要被公式忽悠住了。
    从构建G矩阵,到对G矩阵进行softmax操作,最后获得的是Ap矩阵。这个过程对应了模型图中第二层从黑色矩阵向右,获得了G矩阵,再斜向左上进行softmax操作,获得Ap的过程。
    这里获得了最后的视窗与关系的注意力值Ap,以及视窗本身(也就是卷积结果)R*。现在直接将两个矩阵相乘计算出最后的矩阵并取出最大值,以及最大值对应的索引。
    在这里插入图片描述
    上式完成的就是这个过程。对应了模型图中左上角最后的计算。

    展开全文
  • 1.服务器上,文件名最好用英文,不然可能报文件不存在的错误 2.输入格式注意,输入最好一个batch,一个batch,保证模型的泛化性 3.

    关系抽取预知识和发展介绍

    事实知识:
    三元组表示实体间关系

    关系抽取:
    文本中蕴藏含着大量事实知识
    一个完整关系抽取系统通常包含以下模块:
    NER
    Entity Linking(避免重复添加到知识图谱、消歧)
    Relation Classification

    构成知识图谱:
    知识图谱下游:搜索引擎、问答系统。。。

    关系抽取模型的发展
    Pattern Mining
    Feature-Based Methods
    Kernel-Based Methods(SVM等)
    Graphical Models
    Neural Models

    神经网络关系抽取
    RecursiveNN
    CNN
    RNN(word embbeding,position embedding)
    Graph Neural Networks(信息传递,推理)
    Transformers

    经典关系抽取:大量、人工训练数据,单句内,限定关系集的关系分类

    实际应用挑战和解决方案
    数据获取昂贵-----远程监督(引入噪声)
    远程监督降噪:
    在这里插入图片描述
    关系长尾现象严重(数据不平衡)------少次学习,N-Way K-Shot(易受到噪声的干扰)
    在这里插入图片描述
    给句子不同权重,给特征不同维度权重
    在这里插入图片描述
    设定简单
    在这里插入图片描述

    度量:
    Prototypical Ner
    在这里插入图片描述

    许多事实知识隐藏再更复杂的上下文中-----文档关系抽取

    关系的不断增长—开放的关系抽取
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    参照:实体抽取的现状和未来

    实体抽取简介

    NER又称作专名识别,是自然语言处理中的一项基础任务,应用范围非常广泛。命名实体一般指的是文本中具有特定意义或者指代性强的实体,通常包括人名、地名、组织机构名、日期时间、专有名词等。NER系统就是从非结构化的输入文本中抽取出上述实体,并且可以按照业务需求识别出更多类别的实体,比如产品名称、型号、价格等。因此实体这个概念可以很广,只要是业务需要的特殊文本片段都可以称为实体。

    NER是NLP中一项基础性关键任务。从自然语言处理的流程来看,NER可以看作词法分析中未登录词识别的一种,是未登录词中数量最多、识别难度最大、对分词效果影响最大问题。同时NER也是关系抽取、事件抽取、知识图谱、机器翻译、问答系统等诸多NLP任务的基础。

    BIO标注:将每个元素标注为“B-X”、“I-X”或者“O”。其中,“B-X”表示此元素所在的片段属于X类型并且此元素在此片段的开头,“I-X”表示此元素所在的片段属于X类型并且此元素在此片段的中间位置,“O”表示不属于任何类型。

    参考:https://blog.csdn.net/qq_27586341/article/details/103062651

    关系抽取简介

    实体抽取后,抽取实体间的关系。是知识图谱的基础

    对于有监督的关系抽取任务,通常也将其分为两大类
    Pipline:将实体抽取与关系抽取分为两个独立的过程,关系抽取依赖实体抽取的结果,容易造成误差累积
    Joint Model:实体抽取与关系抽取同时进行,通常用模型参数共享的方法来实现
    参考:https://www.cnblogs.com/sandwichnlp/p/12020066.html

    BERT 模型的使用主要有两种用途:
    一、当作文本特征提取的工具,类似Word2vec模型一样
    二、作为一个可训练的层,后面可接入客制化的网络,做迁移学习
    本次模型使用第一次用途。

    实践

    对有标签和实体信息的数据做关系抽取模型训练。

    思路:

    关系抽取模型,基于管道模型的思路,先进行实体抽取,依据实体抽取的结果根据先验知识组合判断,训练数据是已经标记了的数据。也有实体抽取模型可以预测得到数据。

    模型输入的数据

    模型输入的数据是文本,已经明确实体类型和位置的数据,根据实体类型可以直接排除掉一些关系类型(先验知识)。两两组合判断就将关系抽取转换为二分类,输入关系类型和实体信息,判断是否存在这种关系。正例样本就是两两组合正确的样本,负例样本就是组合不正确的样本(即实体A[1,2,3],实体B[‘a’,‘b’],若果1和a存在关系,则组合为正样本,而1和b组合就是负样本)。

    模型输入格式:4部分
    直接送入bert模型的序列数据,仿照token功能进行构造
    实体位置信息数据,头实体,尾实体embedding
    以实体为中心,进行实体周边位置的联合embedding
    类别one-hot编码信息

    实现

    函数主要包括:模型、评价函数、loss作图函数、训练验证模型函数,加载转换数据、预测数据的函数。数据来源于现病史,个人史,主诉,现病史数据较长,如果超过bert510字符限制,需要再单独处理。

    做的时候感到的难点:

    1.模型构成
    2.转换数据(创建负样本,转换中间数据格式确定)
    3.记录每种关系类型的accuracy,precision,recall,f1,数量等信息
    4.预测:根据实体抽取模型/标记数据的到的实体类型和位置信息,再根据先验知识(某两个实体只存在某些关系或者不存在关系),设置最大间距长度,如果两个实体间距超过多少则默认不再判断关系

    建议:

    1.服务器上,文件名最好用英文,不然可能报文件不存在的错误(乱码)
    程序后台运行等代码的命令

    nohup python -u main.py > log.txt 2>&1 &
    ps -ef|grep python
    kill - 9 PID号
    

    source home/env/pytorch_1.6/bin/activate激活多个环境中的一个

    2.输入格式注意,输入最好一个batch,各个类别正负样本均衡,保证模型的泛化性,并且每条数据格式一致,且需要打乱顺序

    3.如果在多核gpu跑,可能报错,caught runtimeError in replica 0 on device 0.这是因为第一个gpu有数据计算,第二个没有,比如数据共有100,batch是40,有2个gpu,第一轮后只剩下20条数据,分给第一个gpu后,第二个gpu上就没有数据了。解决办法,把最后一个epoch,不足一个batch数据丢掉,或者调整batch;loss也要mean(),否则会报错

    4.模型编写时,判断一下device,并且模型输入和标签和loss函数 都要to.device(),

    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu'
    model.to(device)
    if torch.cuda.device_count()>0
    	model = torch.nn.DataParallel(model)
    
    if torch.cuda.device_count()>0:
    	loss = loss.mean()
    

    5.模型保存,再多核GPU上训练的模型,直接到cpu上加载会报错,因此model=model.module,再保存

    6.过程数据,包括每种关系的f1,accuracy,…,全部关系,最好记录,否则没有衡量的法则

    7.如果batch太大,测试集跑完后,第二轮保存了第一轮的参数后,就没有多余的内存跑了,报错cuda out of memory,需要减少batch,
    并释放内存torch.cuda.empty_cache()删除一些不需要的变量,或者

    8.用utf-8读取excel可能报错,utf-8 codec can’t decode byte …,就换一个编码,gbk,或者gb18030,扩大编码范围,pd.read_csv(file_path,encoding=’’)

    9.弄清楚自己写的代码意思,不然跑了很久才报错,调试成本太大。并且做的时候校验下,适当输出一些肉眼能判断是否数据正确的信息。

    10.保存与加载模型,模型是在多上GPU跑的,但调试是在cpu上的电脑做的

    model_to_save = model.module if hasattr(model,"module") else model
    torch.save({
    'model_state_dict':model_to_save.state_dict()
    },save_path,__use__new_zipfile_serialzation=Fale)
    

    11.比较loss,在区间中比较,前n个loss最小的与当前loss相减,如果小于***,则跳出

    加载

    model = Model()
    checkpoint = torch.load(save_path,map_location='cpu')
    model.load_state_dict(checkpoint ['model_state_dict'],False)
    #如果不加False会报错,有个key,bert_model.embeddings.position_ids或找不到
    

    代码优化方向:
    深度学习:需要了解更多,方才能更好调参和定位问题
    函数方面:解耦(做着做着可能发现数据类型需要修改)
    多用高阶函数,map替代多个for循环

    预知识:
    输入模型的数据格式。
    输入数据包括四部分,直接送入bert模型的序列数据,第二部分是实体位置信息数据,第三部分是以实体为中心,进行实体周边位置联合embedding,第四部分是onehot编码信息
    在这里插入图片描述
    实体模型输入一个文本,输出:实体类型,索引,文本,这些信息预测关系类型将会用到,格式类似如下
    在这里插入图片描述

    关系模型(使用transformer的bertModel得到词向量,并冻结前几层,避免重新训练模型)

    结果:经过9个epoch,2次测试,
    发现优化器选择Adam较SGDloss收敛需要的次数更少,以后用Adam当默认优化器。对于window=10,优化器为SGD,epoch=9总体来说f1(第四列)不错,大部分超过75%,注意,测试了2次,其中另一个测试B,其中一类经过7个epoch精准度还是30%,但是当前有两个类f1只有60%多,测试B的f1除了一个类,其余类f1都超过了75%。说明还没有拟合足够,需要继续迭代计算,把训练集loss_flag设置小点,比如0.001,可能至少要迭代10轮,训练集loss几乎不变才说明不能继续迭代了,或者计算验证集的loss,当current loss比之前最小的loss小,则保存模型
    在这里插入图片描述
    epoch=2,优化器选择Adam,可以看到效果很好在这里插入图片描述
    模型预测输出结果(包括实体预测),线上返回格式应为json格式的文件:
    key:content,text_id,entity,relation,大概如下
    在这里插入图片描述
    真实使用中,由于负样本太多,就算模型f1达到80%多,结果还是很差,可以借助规则方面的tip改善

    补充:后来发现负样本生成有错误地方,修改后,在打乱标签的数据验证,平均f1达到96%,数据处理非常中央

    关键函数

    (用手机照的)

    关系模型:
    在这里插入图片描述

    在这里插入图片描述
    数据加载转换函数:
    先得到每个数据对应负样本,如果该文本同种类型只存在一个,则该类型无法创建负样本,先判断该类型在该句子是否存在多个
    把每个类的数据分别放在一个篮子里,然后用过抽样的方式,让每种类别数量相等,正负样本数量也相等,然后从每个篮子依次抽取batch_size/类别数量/2 条数据,形成一个batch,加载的到的数据就有多个batch.
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    data_balance函数:
    首先把数据分成训练集和测试集,训练集采用过抽样,保证每种类别的数量均衡
    在这里插入图片描述

    评价函数,训练的时候也打印出结果,在服务器excel不方便查看
    在这里插入图片描述

    模型训练代码:此时的数据,一个list有n个listA,每个listA有42条数据,每种类别分别2个正,2个负例子,在模型训练中list可以suffle,(不用在数据加载函数suffle,不然每次从头开始训练的时候训练集的数据可能都不同)
    在这里插入图片描述

    在这里插入图片描述

    主函数:有7种关系,batch_size必须是14的倍数

    在这里插入图片描述

    预测函数
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    展开全文
  • 信息抽取(Information Extraction, IE)是从自然语言文本中抽取实体、属性、关系及事件等事实类信息的文本处理技术,是信息检索、智能问答、智能对话等人工智能应用的重要基础,一直受到业界的广泛关注。信息抽取任务...

    关注微信公众号:NLP分享汇。【喜欢的扫波关注,每天都在更新自己之前的积累】

    文章链接:https://mp.weixin.qq.com/s/OebxnvwjQiVbBZZFL2Un3A


    前言

    信息抽取(Information Extraction, IE)是从自然语言文本中抽取实体、属性、关系及事件等事实类信息的文本处理技术,是信息检索、智能问答、智能对话等人工智能应用的重要基础,一直受到业界的广泛关注。信息抽取任务涉及命名实体识别、指代消解、关系分类等复杂技术,极具挑战性。而本文旨在介绍如何利用Bert预训练模型进行关系抽取任务。

     

    相关链接

    GitHub:https://github.com/yuanxiaosc/Entity-Relation-Extraction

    竞赛官网:http://lic2019.ccf.org.cn/

    理解难度:★★★★

    解决思路

    1、先使用bert搭建的关系分类模型,简单来看就是一个多标签分类任务,类别就是下述的那几种关系;

    2、接着用预测出来的关系和文本,使用bert搭建一个实体抽取的模型,其简单来看也是一个分类模型,类别是:

    ["[Padding]", "[category]", "[##WordPiece]", "[CLS]", "[SEP]", "B-SUB", "I-SUB", "B-OBJ", "I-OBJ", "O"]

    【 SUB对应的就是subject,B-SUB就是第一个实体开始的位置,后续的是I-SUB,OBJ就是第二个实体 】

    关系类型如下:

    ['丈夫', '上映时间', '专业代码', '主持人', '主演', '主角', '人口数量', '作曲', '作者', '作词', '修业年限', '出品公司', '出版社', '出生地', '出生日期', '创始人', '制片人', '占地面积', '号', '嘉宾', '国籍', '妻子', '字', '官方语言', '导演', '总部地点', '成立日期', '所在城市', '所属专辑', '改编自', '朝代', '歌手', '母亲', '毕业院校', '民族', '气候', '注册资本', '海拔', '父亲', '目', '祖籍', '简称', '编剧', '董事长', '身高', '连载网站', '邮政编码', '面积', '首都']

     

    思路分析

    • 所以第二个模型就是预测每一个tokens的标示,最后根据标示可提取出实体对。

    • 第二个模型是一个多分类任务,我们知道一句话中有可能有多个三元组,为此在进行第二个模型的时候,是先依据第一个模型预测出来的关系类如当前句子预测出3个关系,那么就重复该句话分成3个样本,那么3个样本就对应的是3个多分类单标签任务,为了使实体对和关系对应,所以第二个模型在计算loss的时候是综合考虑了关系和tokens标示的预测的。

    • 说到这里可能会有这样的疑惑?两个模型(所谓的管道),似乎没有交集,都是先处理准备好各自数据,然后各自训练各自的,而且第二个模型同时进行了关系和实体标示预测,那么第一个模型只预测了关系,那么第一个模型存在的意义是什么?直接用第二模型不就可以啦?

      • 逻辑是这样的:

        训练确实没有交集,各自训练各自的,因为训练样本都是精确的,无可厚非,但是在预测的时候我们只有一句话,要预测出这句话中的所有三元组,如果只采用第二个模型的话,它一句话根据当前的关系只能预测出一种三元组,所以需要第一个模型打前阵,先将句子中有多少种关系预测出来,然后再将句子依照关系分成一句话一个三元组,训练的时候我们是知道每一个句子有多少种关系,但是预测的时候我们并不知道,这就是第一个模型存在的意义,那么我就要用第二个模型同时解决一句话预测所有三元组呢?其实很难,因为首先tokens标记就是问题,怎么将标示和关系对应呢?是吧,所以这里所谓管道,其实是在预测过程体现的,下面就可以看到另外按照上面的思路,该模型bert的输入端一个样本的特征应该是当前句子和关系,而不仅仅是一个句子,不然的话将一句话拆分成多个样本还有什么意义?大家不就都一样啦,正是由于还有关系,才能实现同一句子抽取出不同的实体对(对应当前关系)。

    • 那么输入端是怎么将将关系整合进去的呢?

      • 解决办法是这样的:

        将关系作为当前句子的下句,还记得text_b吗?第一个模型设为了None,这里将类别平铺成和text_a一样长度,当成一句话作为text_a(当前句子)的下文,该部分具体看convert_single_example:

     

    核心代码部分

    模型一:bert搭建的关系分类模型

    def create_model(bert_config, is_training, input_ids, input_mask, segment_ids,                 labels, num_labels, use_one_hot_embeddings):    """Creates a classification model."""    model = modeling.BertModel(        config=bert_config,        is_training=is_training,        input_ids=input_ids,        input_mask=input_mask,        token_type_ids=segment_ids,        use_one_hot_embeddings=use_one_hot_embeddings)    # In the demo, we are doing a simple classification task on the entire    # segment.    #    # If you want to use the token-level output, use model.get_sequence_output()    # instead.    output_layer = model.get_pooled_output()    hidden_size = output_layer.shape[-1].value    output_weights = tf.get_variable(        "output_weights", [num_labels, hidden_size],        initializer=tf.truncated_normal_initializer(stddev=0.02))    output_bias = tf.get_variable(        "output_bias", [num_labels], initializer=tf.zeros_initializer())    with tf.variable_scope("loss"):        if is_training:            # I.e., 0.1 dropout            output_layer = tf.nn.dropout(output_layer, keep_prob=0.9)        logits_wx = tf.matmul(output_layer, output_weights, transpose_b=True)        logits = tf.nn.bias_add(logits_wx, output_bias)        probabilities = tf.sigmoid(logits)        label_ids = tf.cast(labels, tf.float32)        per_example_loss = tf.reduce_sum(            tf.nn.sigmoid_cross_entropy_with_logits(logits=logits, labels=label_ids), axis=-1)        loss = tf.reduce_mean(per_example_loss)        return loss, per_example_loss, logits, probabilities

     

    模型二:bert搭建一个实体抽取模型

    1、关系预测部分

        predicate_output_layer = model.get_pooled_output()    intent_hidden_size = predicate_output_layer.shape[-1].value    predicate_output_weights = tf.get_variable(        "predicate_output_weights", [num_predicate_labels, intent_hidden_size],        initializer=tf.truncated_normal_initializer(stddev=0.02))    predicate_output_bias = tf.get_variable(        "predicate_output_bias", [num_predicate_labels], initializer=tf.zeros_initializer())    with tf.variable_scope("predicate_loss"):        if is_training:            # I.e., 0.1 dropout            predicate_output_layer = tf.nn.dropout(predicate_output_layer, keep_prob=0.9)        predicate_logits = tf.matmul(predicate_output_layer, predicate_output_weights, transpose_b=True)        predicate_logits = tf.nn.bias_add(predicate_logits, predicate_output_bias)        predicate_probabilities = tf.nn.softmax(predicate_logits, axis=-1)        predicate_prediction = tf.argmax(predicate_probabilities, axis=-1, output_type=tf.int32)        predicate_labels = tf.one_hot(predicate_label_id, depth=num_predicate_labels, dtype=tf.float32)        predicate_per_example_loss = tf.reduce_sum(tf.nn.sigmoid_cross_entropy_with_logits(logits=predicate_logits, labels=predicate_labels), -1)        predicate_loss = tf.reduce_mean(predicate_per_example_loss)

    2、序列标注部分

        token_label_output_layer = model.get_sequence_output()    token_label_hidden_size = token_label_output_layer.shape[-1].value    token_label_output_weight = tf.get_variable(        "token_label_output_weights", [num_token_labels, token_label_hidden_size],        initializer=tf.truncated_normal_initializer(stddev=0.02)    )    token_label_output_bias = tf.get_variable(        "token_label_output_bias", [num_token_labels], initializer=tf.zeros_initializer()    )    with tf.variable_scope("token_label_loss"):        if is_training:            token_label_output_layer = tf.nn.dropout(token_label_output_layer, keep_prob=0.9)        token_label_output_layer = tf.reshape(token_label_output_layer, [-1, token_label_hidden_size])        token_label_logits = tf.matmul(token_label_output_layer, token_label_output_weight, transpose_b=True)        token_label_logits = tf.nn.bias_add(token_label_logits, token_label_output_bias)        token_label_logits = tf.reshape(token_label_logits, [-1, FLAGS.max_seq_length, num_token_labels])        token_label_log_probs = tf.nn.log_softmax(token_label_logits, axis=-1)        token_label_one_hot_labels = tf.one_hot(token_label_ids, depth=num_token_labels, dtype=tf.float32)        token_label_per_example_loss = -tf.reduce_sum(token_label_one_hot_labels * token_label_log_probs, axis=-1)        token_label_loss = tf.reduce_sum(token_label_per_example_loss)        token_label_probabilities = tf.nn.softmax(token_label_logits, axis=-1)        token_label_predictions = tf.argmax(token_label_probabilities, axis=-1)        # return (token_label_loss, token_label_per_example_loss, token_label_logits, token_label_predict)    loss = 0.5 * predicate_loss + token_label_loss
    展开全文
  • 远程监督的关系抽取 传统关系抽取 关系抽取是知识图谱构建的关键模块之一,同时它也是许多自然语言处理应用的重要组成部分,诸如情感分析、问答系统和自动摘要等。其核心任务是预测句子中实体间的关系。 关系抽取...
    • 传统关系抽取
      • 背景

        • 关系抽取是知识图谱构建的关键模块之一,作为实体识别基础上的一个知识抽取任务,该任务的核心是核心是判断句子中包含的实体对之间的关系。同时它也是许多自然语言处理应用的重要组成部分,诸如情感分析、问答系统和自动摘要等。其核心任务是预测句子中实体间的关系。
        • 通常将关系抽取任务转化为分类任务,即通过训练关系分类器,对句子的实体对进行关系分类。
      • 基本定义

        • 关系抽取:从一个句子中判断两个entity是否有关系,一般是一个二分类问题,指定某种关系
        • 关系分类:一般是判断一个句子中 两个entity是哪种关系,属于多分类问题。
      • 传统的方法

        • Supervised relation extraction
          • 对句子中的关系进行人工标注,然后抽取词法、句法、语义特征,训练有监督的分类器,对测试集中的实体关系进行预测;
        • Unsupervised information extraction
          • 从大量文本中,对实体进行标注,通过聚类等方法抽取实体之间的关系字符串。这种方法可以抽取非常大量的关系对,但是抽取结果很难映射到知识库中。
        • bootstrap learning
          • 利用少量的种子实例或模板,进行bootstrap的学习。将已有的实例应用在大规模语料中,抽取出新的模板;然后用新的模板抽取出更多的实例,如此迭代。但抽取结果准确率较低,还可能发生语义转移。
      • 挑战

        • 关系抽取算法最为突出的特点之一是对标注实例存在着数量上的巨大需求,需要语言学或领域专家对语料做大规模的标注,所以这是代价较高的方法。这一任务对于手工标注几乎是不可能完成的。
    • 远程监督的关系抽取
      • 目前关系抽取比较常见的一种做法,由Mintz于ACL 2009年首次提出,这种方法不属于传统的监督或无监督的抽取方法,而是使用知识库(KB或KG等)对齐朴素文本并标注,然后完成抽取的方法。
      • 假设
        • 两个实体如果在知识库中存在某种关系,则包含该两个实体的非结构化句子均能表示出这种关系。简单的说如果一个句子中含有一个关系涉及的实体对,那这个句子就是描述的这个关系。例如,"Steve Jobs"和"Apple"在 Freebase 中存在 founder 的关系,则包含这两个实体的非结构文本如:“Steve Jobs was the co-founderand CEO of Apple and formerly Pixar.”都可以作为一个训练正例来训练模型。
      • 抽取过程
        https://blog.csdn.net/m0_38031488/article/details/79852238
        • 从知识库中抽取存在关系的实体对
        • 从非结构化文本中抽取含有实体对的句子作为训练样例
        • 训练构造关系多分类器
      • 优点
        • 通过将知识库与非结构化文本对齐来自动构建大量训练数据,减少模型对人工标注数据的依赖,增强模型跨领域适应能力。
      • 缺点
        • 无法选择有效的句子是指模型无法判断关系实例对应的句子集(bag)中哪个句子是与关系相关的,在建模时能会将不是表达某种关系的句子当做表达这种关系的句子,或者将表达某种关系的句子当做不表达这种关系的句子,从而引入噪声数据。例如:乔布斯吃了一个苹果
          • 这里我们把整整含有指定关系的句子叫做real instance ,也就是True positive。那么也就有False positive表示实际不含此种关系的句子。这里我们把噪声问题称为wrong label问题。
          • 这个问题也是远程监督的方法最需要解决的问题
        • 缺少实体知识,例如“[Nevada] then sanctioned the sport , and the U.F.C. held its first show in [Las Vegas] in September 2001. ”如果不知道 Nevada 和 Las Vegas 是两座城市,则很难判断他们知识是地理位置上的包含关系
      • 优化方法
        https://blog.csdn.net/m0_37565948/article/details/84999919
        • dynamic-transition matrix(动态转移矩阵),它能很好的拟合由 distant supervision 所带来的噪声。通过该矩阵,我们能够大大提高 relation extraction 的效果。
        • rule learning(规则学习),通过定义规则,定义否定模式(negative pattern)过滤掉一些噪音数据,可以很大程度提高性能。缺点是规则依赖人工定义,通用性差,但是方法本身简单有效。
        • 清华刘知远团队的NER,利用了包含实体对的所有的句子信息,提出了attention机制,去解决远程监督的wrong label的问题。
        • 对于错误传播放大的问题有“joint learning”方法的提出,将命名实体识别和关系抽取两部并为一步走。
      • Code
        http://www.sohu.com/a/131451458_500659
    • 基于深度强化学习的远程监督关系抽取
      • ACL 2018

        • 作者基本思想
          • 为了解决wrong label(样本噪声)问题,人们尝试利用注意力机制对含有噪声的句子集合赋予权重以选择出有效的训练样本。但是,作者认为这种只选择出一个最佳样本的思路并不是最优的策略(因为作者认为假正例应该完全被放入负例集中,而不是分配一个较低的权重)。为了提高模型的鲁棒性,对于假正例不应只是简单的移除,而是应把它们放在正确的位置——负例集合中。
        • 成果
          • 论文尝试使用一种深度强化学习框架来生成一个假正例指示器,该框架在没有任何监督信息的情况下自动识别每个关系类型实例集中的假正例(False Positive)实例。
      • 论文的创新点

        • 作者设计了一个新的深度强化学习框架来提高远程监督关系抽取的鲁棒性
        • 该算法独立于关系抽取模型的,是一种即插即用的技术,可应用于任何一个现有的远程监督关系抽取模型;
        • 文章通过实验证明了该方法可以提升目前最新提出的关系抽取模型的性能。
      • 论文介绍

        • 框架图
          在这里插入图片描述
          • 根据作者的描述,他们提出的深度增强学习框架总能够动态识别假正例数据,但是并不是简单的移除,而是将其移动到负例集中,然后对重新分配的训练集进行学习,并使用测试集进行测试,根据测试结果对之前的划分行为进行奖励或惩罚,最终使模型能够自动识别假正例实例。
          • 也就是说模型要根据关系分类器性能的变化,决定是保留还是移除当前的实例(即一个句子)。然后,框架进一步使基于深度强化学习策略的 agent 学会如何重建一个纯净的远程监督训练数据集。
          • 作者描述为性能驱动、基于决策的增强学习、启发式的识别
        • RL组件
          • 必备组成:外部环境、RL agent。通过二者的动态交互训练得到
          • 外部环境(状态)
            • RL中的状态依赖于马尔科夫决策过程的条件,但传统的关系抽取中输入的实例(句子)相互独立,不能够仅仅通过他们建立状态转移,因此模型的状态s中包含了早期状态移除的句子信息和当前句子的信息。
            • 句子的语义和句法信息由一个连续实值向量表示,向量特征包括word embedding 和 position embedding (concatenation)
            • 早前状态被表示为移除实例的平均向量
            • 当前状态被给予较大的权重,放大当前决策的影响力
          • 策略网络(Policy Network)
            • 对于每个输入的句子,策略网络负责判断该句子是否表述了目标关系类型,然后对于与目标关系类型无关的句子启动移除操作。这样,多元分类器就转换为了二元分类器。文章使用一个窗口大小为kernel size 为的 CNN 来对策略网络π(s;θ)\pi(s;θ) 建模。
          • 行为
            • 在每一步中,agent 都会去判定实例对于目标关系类型是否为假阳性。每一个关系类型都拥有一个 agent,每个 agent 都有两个行为:对于当前实例,作出删除或是保留的决定。
            • 由于初始的远程监督数据集中包含有被错误标注的实例,期望 agent 能利用策略网络过滤掉这些噪声实例,由此得到的纯净数据集,以使远程监督获得更好的性能。
          • 奖励(Rewards)
            • 当错误标注数据被过滤掉后,关系分类器便能获得更好的性能。因此,文章中的模型采用结果驱动策略,以性能变化为依据,对 agent 的一系列行为决策进行奖励。奖励通过相邻 epochs 的差值来表示Ri=α(F1iF1i1)R_i=\alpha(F_1^i-F_1^{i-1})
              在第 i 步时,F1 增加,则 agent 将收到一个正奖励;反之,则 agent 将收到一个负奖励。通过这样的设置,奖励值将与 F1 的差值成比例,α 的作用是将 F1 的差值转换到有理数的范围内。为了消除 F1 的随机性,文章使用最近 5 个 epochs 的 F1 值的平均值来计算奖励。
        • **决策网络**的预训练
          • 目的
            • 在该论文中,作者提出的方法并不是真正意义上的关系抽取,仅仅判断一个被标记的实例在其对应的关系类型中是否是假正例,而并不对实体间的关系进行预测。而在训练集中,一种关系类型会包含成千上万的实例,如果随机初始化决策网络的参数,在训练和错误中学习参数,则会耗费很多时间,并且很难收敛。因此作者采用了一种有监督的决策网络预训练的方法。
          • 预训练策略
            • 受AlphaGo 的启发,为了加快agent的训练,首先使用一小部分标注数据训练决策网络,然后进行增强学习
            • 正例和负例的构建
              • 作者认为,在语料库与朴素文本对齐良好的情况下,和假正例相比,训练集中的真正例有明显的数量优势。
              • 因此作者直接把远程监督真正例集作为正例集,随机从远程监督的负例集中抽取一部分作为负例集。
              • 同时为了更好地考虑初始信息,负例集的数量是正例集的10倍,因为在学习大量的负例集时,agent更有可能朝好的方向学习。
          • 代价函数和训练
            • 交叉熵:J(θ)=iyilog[π(α=yisi;θ)]+(1yi)log[1π(α=yisi;θ)]J(\theta)=\sum_i{y_ilog[\pi(\alpha=y_i|s_i;\theta)]+(1-y_i)log[1-\pi(\alpha=y_i|s_i;\theta)]}
            • 因为远程标记的噪音特性,作者为了防止模型在噪音数据上过度拟合(预测概率极度接近0或1),在训练阶段早停(准确率为85%-90%)时。
        • 基于奖励的再训练
          • 目的
            • 为了在没有任何督信息的情况下发现wrong labeled 实例,作者提出了基于RL策略的方法,该方法用于发现在正例集中的噪音实例。
          • 训练过程
            • 基本符号:PtoriP_t^{ori}PvoriP_v^{ori}NtoriN_t^{ori}NvoriN_v^{ori} 。分别表示训练集合测试集的正例、反例。
            • 在每一轮,通过随机策略π(s;θ)\pi(s;θ)移除噪声实例集合Ψi\Psi_i,从而获取新的正例集Pt=PtoriΨiP_t=P_t^{ori}-\Psi_i,负例集合Nt=Ntori+ΨiN_t=N_t^{ori}+\Psi_i,然后利用新的训练集训练关系分类器。
            • 模型的目的是期望RL agent有通过重新标记wrong labeled的假阳性实例来提升关系分类器性能的能力,通过{PvoriP_v^{ori}NvoriN_v^{ori} }进行测试得到F1,然后根据迭代过程中F1值的变化作为奖励的依据Ri=α(F1iF1i1)R_i=\alpha(F_1^i-F_1^{i-1})
            • 需要注意的是,为了避免 agent 将正例集合中的真正例误删,在每一个 epoch 中,对 RL agent 移除句子的数目设置一个阈值,即一个 epoch 中移除的句子数目不能超过该值。这样,如果 agent 决定移除当前实例,则其他实例被移除的概率将变小。
          • 代价函数
            • RL agent的模型性能受被从正例集中移除的假正例的质量的影响,模型具备区分明显的假正例的能力,但是对于一些难以区分的wrong labeled实例仍然使很模糊的,但是这一部分往往是模型性能提升的关键影响因素。因此在不同的epochs中带来F1改变的被移除的不同的部分应该受到更多关注,所以提出做种的代价函数如下:
            • J(θ)=RΩilog[π(αs;θ)]+(R)Ωi1log[π(αs;θ)]J(\theta)=R\sum_{\Omega_i}log[\pi(\alpha|s;\theta)]+(-R)\sum_{\Omega_{i-1}}log[\pi(\alpha|s;\theta)]
              • 其中,Ωi=Ψi(ΨiΨi1)\Omega_i=\Psi_i-(\Psi_i \cap \Psi_{i-1}) , Ωi1=Ψi1(ΨiΨi1)\Omega_{i-1}=\Psi_{i-1}-(\Psi_i \cap \Psi_{i-1})
              • 也就是说在计算的过程中,去除前后两次相同的移除子集,使其不对迭代的结果产生影响
          • 模型结构图
            • 在这里插入图片描述
        • 通过以上过程,最终得到的agent能够具备识别wrong labeled实例的能力,利用这个agent作为分类器去识别假正例,对于一个实体对,如果所有的实例都被分类为假正例,则该实体对被分配为负例。
        • 模型总结
          • 模型输入
            • PtoriP_t^{ori}PvoriP_v^{ori}NtoriN_t^{ori}NvoriN_v^{ori},移除最大数γt,γv\gamma_t,\gamma_v,语料库中实例的句子向量sjs_j
            • 加载预训练决策网络参数θ\theta
            • 初始化向量SS^*(早前状态)为sjs_j同维度的零向量
          • 迭代过程:每轮迭代都遍历每个sjs_j
            • 构造状态sj~\tilde{s_j}
            • 随机选取实例:αj=π(αsj~;θ)\alpha_j = \pi(\alpha|\tilde{s_j};\theta),计算其为假正例的概率pj=π(α=0sj~;θ)p_j=\pi(\alpha=0|\tilde{s_j};\theta)
            • 如果aja_j被选中,将tj=(sj~,pj)t_j=(\tilde{s_j},p_j)存入T中,并且重新计算SS^*
            • 将T中pjp_jγt\gamma_t个s赋值给Ψi\Psi_i
            • 重新正例和负例集:正例集Pti=PtoriΨiP_t^i=P_t^{ori}-\Psi_i,负例集合Nti=Ntori+ΨiN_t^i=N_t^{ori}+\Psi_i
            • 基于测试集{PviP_v^{i}NviN_v^{i} },计算F1i,ΨiF_1^i,\Psi_i
            • 计算Ri=α(F1iF1i1)R_i=\alpha(F_1^i-F_1^{i-1})
            • 更新梯度:
              • update θ:gθΩilog[π(αs;θ)]R+θΩi1log[π(αs;θ)](R)\theta:g \propto \bigtriangledown_{\theta}\sum_{\Omega_i}log[\pi(\alpha|s;\theta)]R+\bigtriangledown_{\theta}\sum_{\Omega_{i-1}}log[\pi(\alpha|s;\theta)](-R)
                Ωi=Ψi(ΨiΨi1)\Omega_i=\Psi_i-(\Psi_i \cap \Psi_{i-1}) , Ωi1=Ψi1(ΨiΨi1)\Omega_{i-1}=\Psi_{i-1}-(\Psi_i \cap \Psi_{i-1})
      • 实验

        • 实验一
        • 抽样方法:留出法
        • 测试数据集**(/riedel/ecml)**,数据库:Free-base
        • 作者使用基于RL算法的模型和未采用的模型比较F1得分在这里插入图片描述
          - 实验二
          • 基于在original riedel dataset上对关系抽取模型(CNN)的表现做比较
            在这里插入图片描述
            在这里插入图片描述
    • 参考文献
    展开全文
  • 1.下载BERT预训练模型    更多bert模型参考github地址    本文用的是BERT-Base, Cased(12-layer, 768-hidden, 12-heads , 110M parameters)下载地址。其中Cased表示保留真实的大小写...
  • 以下是我根据作者的提示,找到的版本(花费了很多时间才明白如何找对应的不同版本) 模型地址https://github.com/facebookresearch/SpanBERT 点击下方链接NVIDIA/apex@4a8c4ac 点击右上方的Browse files,就可以...
  • 大多数现有的关系抽取模型可以分为两类:基于序列的关系抽取模型和基于依赖关系的关系抽取模型。基于序列的模型仅仅针对单词序列,而基于依赖关系的模型针对整个依赖关系树。因此基于依赖关系的模型更能捕获有用信息...
  • 知识库(Knowledge Base)包含大量真实世界的结构化信息,被广泛用于各种自然...尽管关系抽取与知识库嵌入关系密切,但很少有尝试系统地统一这两个模型,本文建立一个框架,统一这两个模型的学习过程,并在关系抽取...
  • 目前为止,有很多方法专注于关系抽取或关系分类任务,该任务是识别两个预先给出的实体之间的关系。这类方法假设实体已经给定,忽略了实体的抽取。早期的实体关系抽取方法是pipeline的,即先进行NER,然后再进行RE。...
  • 这篇文章提出了一种基于实体图的神经关系抽取模型,该模型用图的方式来表达一句话中多个实体间存在的多种关系。 句子中的实体被表示为图中的节点,实体间的关系则构成图的定向边,模型用一个实体及其上下文来初始化...
  • 这是EMNLP2020一篇文档级关系抽取的论文,代码链接 https://github.com/DreamInvoker/GAIN,其性能相较ACL2020中的文档级关系抽取模型LSR有一定的提升,其能够有提升的主要原因在于两点:1)构建了异质图并使用了R-...
  • 信息抽取(二)花了一个星期走了无数条弯路终于用TF复现了苏神的《Bert三元关系抽取模型,我到底悟到了什么?前言数据格式与任务目标模型整体思路复现代码数据处理数据读取训练数据处理模型搭建模型参数图...
  • 方 法2.1实体关系表(Figure-2)2.2 The Table Filling Multi-Task RNN Model2.3 Context-aware TF-MTRNN model2.4 Piggybacking for Entity-Relation Label Dependencies2.5 Ranking Bi-directi...
  • 6.关系抽取(核方法) 6.1global context kernel 6.2 local context kernel 6.3 shallow linguistic kernel 7实验 Giuliano, C., et al. “Relation extraction and the influence of automatic named-entity ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 951
精华内容 380
关键字:

关系抽取模型