0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

跨语言命名实体识别:无监督多任务多教师蒸馏模型

深度学习自然语言处理 来源:深度学习自然语言处理 作者:深度学习自然语言 2022-07-21 11:12 次阅读

前言 这是一篇来自于 ACL 2022 的关于跨语言的 NER 蒸馏模型。主要的过程还是两大块:1)Teacher Model 的训练;2)从 Teacher Model 蒸馏到 Student Model。采用了类似传统的 Soft 蒸馏方式,其中利用了多任务的方式对 Teacher Model 进行训练,一个任务是 NER 训练的任务,另一个是计算句对的相似性任务。整体思路还是采用了序列标注的方法,也是一个不错的 IDEA。

bbd5155e-0818-11ed-ba43-dac502259ad0.png

论文标题:

An Unsupervised Multiple-Task and Multiple-Teacher Model for Cross-lingual Named Entity Recognition

论文链接:

https://aclanthology.org/2022.acl-long.14.pdf

模型架构

2.1 Teacher Model

bc228672-0818-11ed-ba43-dac502259ad0.png

图1.Teacher Model训练架构 从上图可以明显的看出,Teacher Model 在进行训练时,采用了两种不同的 Labeled Data,一种是传统的单文本序列标注数据;另一种是句对类型的序列标注数据,然后通过三个独立的 Encoder 编码器进行特征抽取,一个任务就是我们常用的 NER 训练任务,也就是将 Encoder 编码器的输出经过一个线性层映射为标签数的特征矩阵,对映射的特征矩阵进行 softmax 归一化(这里笔者理解就是 NER 任务中的 BERT+Softmax 模型),利用归一化后的特征矩阵与输入的 labels 进行 loss 计算,这里采用的是 CrossEntropyLoss。需要明确具体的是作者采用了 Multilingual BERT(也就是 mBert)作为编码器,计算公式如下:

bc4ad780-0818-11ed-ba43-dac502259ad0.png

首先利用 mBERT 提取输入文本序列的特征 ,这里的 表示的是:

bc5d9802-0818-11ed-ba43-dac502259ad0.png

将计算得到的文本序列隐藏向量经过一个线性变换后进行 softmax 归一化,计算如下:

bc79c93c-0818-11ed-ba43-dac502259ad0.png

以上就是 Teacher Model 的第一个任务,直接对标注序列进行 NER,并且采用交叉熵损失函数作为 loss_function,计算如下:

bc86e306-0818-11ed-ba43-dac502259ad0.png

另外一个任务输入的为序列标注的句对数据,分别采用两个独立的Encoder编码器进行编码,得到的对应的 last_hidden_state,然后计算这两个输出的 cosine_similar,并且将其使用 进行激活,得到两个序列的相似度向量,计算如下:

bc983bf6-0818-11ed-ba43-dac502259ad0.png

bca8edac-0818-11ed-ba43-dac502259ad0.png

这里也就是一个类似于 senetnce_similar 的操作,不同点在于这里计算的是序列中每个 Token 的相似度。通过对比句对序列标签得到一个 ,这里 时表示 (预测正确),反正的话,。到了计算相似度时,损失函数的设计就是基于 的,计算公式如下:

bcb888b6-0818-11ed-ba43-dac502259ad0.png

这里的 是 BinaryCrossEntropy。这里的 是句对序列所对应的标签通过比对得到的对比标签序列,也就是对于两个句子序列标签

bcc89224-0818-11ed-ba43-dac502259ad0.png

来说,其生成的 ,通过这样的损失设计就可以很直观的理解 sim_loss 的计算了。 Tips:对于式(6)这里采用二元交叉熵(BCE)来计算 loss,笔者的理解是对输入句对中的每个 Token 的相似度进行一个二分类,其最终目标是使得具有相同标签的句对更加的靠近,也就是相似度更高。BCE 是用来评判一个二分类模型预测结果 的好坏程度的,通俗的讲,即对于标签 y 为 1 的情况,如果预测值 p(y) 趋近于 1,那么损失函数的值应当趋近于 0。反之,如果此时预测值 p(y) 趋近于 0,那么损失函数的值应当非常大,这非常符合 log 函数的性质。 Teacher Model 的设计总体上就是这样的,通过两个任务来增加 Teacher Model 的准确性和泛化性,对于实体识别来说,使用句对相似度的思想来拉近具有相同标签的 Token,并且结合传统的 NER 模型(mBERT+softmax)可以使得模型的学习更加有指向性,不单单靠一个序列标签来指导模型学习,笔者任务这是一个不错的思路。

2.2 Student Model Distilled

bce14f62-0818-11ed-ba43-dac502259ad0.png

图2.Teacher Model--Student Model Distilled 上面笔者分析了 Teacher Model 的训练,但这不是重点,笔者认为本篇文章在于作者在进行蒸馏时的想法是有亮点的。从蒸馏流程图可以看出来,作者使用的 Student Model 也是一个双塔 mBERT 模型作为编码器,输入的就是 Unlabeled Pairwise Data,其操作就是把 Teacher Model 的多任务直接进行统一,模型架构变化不大。蒸馏过程也是通用的蒸馏模式,Teacher Model 预测,Student Model 学习。 2.2.1 Teacher Model Inference Teacher Model 预测这一部分没啥可说的,就是把无标签的数据输入到模型中,得到输出的 ner_logits 和 similar_logits。这也是蒸馏模型的常规操作了,这里需要注意的是在使用 Teacher Model 进行预测时,输入的数据是有讲究的,笔者对于这里的理解有两个:一个是是模型输入的是句对数据,只不过从这个句对数据中抽取一条输入到 Recognizer_teacher 中进行识别;另一个是作者采用了 BERT 模型的句对输入方式,输入的就是一个句对,只不过使用了 [SEP] 标签进行分隔,具体是哪一种笔者也不知道,理解了的读者可以告诉笔者一下。而且在 Teacher Model 训练时,笔者也不知道采用哪种数据输入方式。 2.2.2 Student Model Learning Student Model 这一部分输入的就是 target 文本序列对,Student Model 的编码器也是一个双塔的 mBert 模型,分别对输入的 target 序列进行进行编码,这里也是进行一个 BERT+Softmax 的基本操作,在此期间也使用了序列 Token 相似度计算的操作,具体的计算如下所示:

bd015afa-0818-11ed-ba43-dac502259ad0.png

bd12941e-0818-11ed-ba43-dac502259ad0.png

获得两个序列的hidden_state后进行一个线性计算,然后利用softmax进行归一化,得到每个Token预测的标签,计算如下:

bd219aae-0818-11ed-ba43-dac502259ad0.png

bd336f22-0818-11ed-ba43-dac502259ad0.png

这里也类似 Teacher Model 的计算方式,计算 target 序列间的Token相似度,计算如下所示:

bd461eb0-0818-11ed-ba43-dac502259ad0.png

当然,这里做的是蒸馏模型,所以对于输入到 Student Model 的序列对,也是Teacher Model Inference 预测模型的输入,通过 Teacher Model 的预测计算得到一个 teacher_ner_logits 和 teacher_similar_logits,将 teacher_ner_logits 分别与 通过 CrossEntropyLoss 来计算 TS_ _Loss 和 TS_ _Loss,teacher_similar_logits 与 通过 计算 Similar_Loss,最终将几个 loss 进行相加作为 DistilldeLoss。

这里作者还对每个 TS_ _Loss,TS_ _Loss 分别赋予了权重 ,对 Similar_Loss 赋予了权重 ,对最终的 DistilldeLoss 赋予权重 ,这样的权重赋予能够使得 Student Model 从 Teacher Model 学习到的噪声减少。最终的 Loss 计算如下所示:

bd6865ec-0818-11ed-ba43-dac502259ad0.png

bd79f62c-0818-11ed-ba43-dac502259ad0.png

bd8fac4c-0818-11ed-ba43-dac502259ad0.png

bda48b62-0818-11ed-ba43-dac502259ad0.png

这里的权重 笔者认为是用来控制 Student Model 学习倾向的参数,首先对于 来说,由于 Student Model 输入的是 Unlabeled 数据,所以在进行蒸馏学习时,需要尽可能使得 Student Model 的输出的 student_ner_logits 来对齐 Teacher Model 预测输出的 teacher_ner_logits,由于不知道输入的无标签数据的数据分布,所以设置一个权重参数来对整个 Teacher Model 的预测标签进行加权,将各个无标签的输入序列看作一个数据量较少的类别。这里可以参考 在进行数据标签不平衡时使用权重系数对各个标签进行加权的操作。而且作者也分析了, 参数是一个随着 Teacher Model 输出而递增的一个参数。如下图所示:

bdbd9706-0818-11ed-ba43-dac502259ad0.png

图3.α参数与Weight和F1 作者在文章中也给出了参数 的计算方式,具体而言就是跟 Student Model 的序列编码有关,计算如下所示:

bdd398c6-0818-11ed-ba43-dac502259ad0.png

对于 参数而言,其加权的对象是 Similar_Loss,也就是对 Teacher Model 的相似度矩阵和Student Model 的相似度矩阵的交叉熵损失进行加权,参数的设置思路大致是当 Teacher Model 的 Similar_logits 接近 0 或 1 时, 参数就较大,接近 0.5 时就较小,其目的也是让 Student Model 学习更有用的信息,而不是一些似是而非的东西。其计算方式如下所示:

bde85e6e-0818-11ed-ba43-dac502259ad0.png

最后对于参数 来说,其作用是用来调整 NER 任务和 Similarity 任务一致性的参数,对于两个输入的 Token,希望 Student Model 从 Teacher Model 的两个任务中学习 Teacher Model 的 NER 任务的高预测准确率和 Similarity 任务远离 0.5 相似度的 Token 信息,反之亦然。其计算方式如下 所示:

bdfe1646-0818-11ed-ba43-dac502259ad0.png

实验结果

作者分别在 CoNLL 和 WiKiAnn 数据集上进行了实验,数据使用量如下图所示:

be1de02a-0818-11ed-ba43-dac502259ad0.png

图4.CoNLL and WiKiAnn数据 作者还与现有的一些 SOTA 模型进行了对比,实验对比结果如下所示:

be68ca86-0818-11ed-ba43-dac502259ad0.png

图5.实验对比结果 从实验对比结果图可以看出,MTMT 模型在各方面都有不错的表现,对于中文上的表现稍微不如 BERT-f 模型,其他部分语言上有着大幅度的领先。

简单代码实现

#!/usr/bin/envpython
#-*-coding:utf-8-*-
#@Time:2022/5/3013:59
#@Author:SinGaln

"""
AnUnsupervisedMultiple-TaskandMultiple-TeacherModelforCross-lingualNamedEntityRecognition
"""

importtorch
importtorch.nnasnn
importtorch.nn.functionalasF
fromtransformersimportBertModel,BertPreTrainedModel,logging

logging.set_verbosity_error()


classTeacherNER(BertPreTrainedModel):
def__init__(self,config,num_labels):
"""
teacher模型是在标签数据上训练得到的,
主要分为三个encoder.
:paramconfig:
:paramnum_labels:
"""
super(TeacherNER,self).__init__(config)
self.config=config
self.num_labels=num_labels
self.mbert=BertModel(config=config)
self.fc=nn.Linear(config.hidden_size,num_labels)

defforward(self,batch_token_input_ids,batch_attention_mask,batch_token_type_ids,batch_labels,training=True,
batch_pair_input_ids=None,batch_pair_attention_mask=None,batch_pair_token_type_ids=None,
batch_t=None):
"""
:parambatch_token_input_ids:单句子token序列
:parambatch_attention_mask:单句子attention_mask
:parambatch_token_type_ids:单句子token_type_ids
:parambatch_pair_input_ids:句对token序列
:parambatch_pair_attention_mask:句对attention_mask
:parambatch_pair_token_type_ids:句对token_type_ids

"""
#RecognizerTeacher
single_output=self.mbert(input_ids=batch_token_input_ids,attention_mask=batch_attention_mask,
token_type_ids=batch_token_type_ids).last_hidden_state
single_output=F.softmax(self.fc(single_output),dim=-1)
#EvaluatorTeacher(类似双塔模型)
pair_output1=self.mbert(input_ids=batch_pair_input_ids[0],attention_mask=batch_pair_attention_mask[0],
token_type_ids=batch_pair_token_type_ids[0]).last_hidden_state
pair_output2=self.mbert(input_ids=batch_pair_input_ids[1],attention_mask=batch_pair_attention_mask[1],
token_type_ids=batch_pair_token_type_ids[1]).last_hidden_state
pair_output=torch.sigmoid(torch.cosine_similarity(pair_output1,pair_output2,dim=-1))#计算两个输出的cosine相似度
iftraining:
#计算loss,训练时采用平均loss作为模型最终的loss
loss1=F.cross_entropy(single_output.view(-1,self.num_labels),batch_labels.view(-1))
loss2=F.binary_cross_entropy(pair_output,batch_t.type(torch.float))
loss=loss1+loss2
returnsingle_output,loss
else:
returnsingle_output,pair_output


classStudentNER(BertPreTrainedModel):
def__init__(self,config,num_labels):
"""
student模型采用的也是一个双塔结构
:paramconfig:mBert的配置文件
:paramnum_labels:标签数量
"""
super(StudentNER,self).__init__(config)
self.config=config
self.num_labels=num_labels
self.mbert=BertModel(config=config)
self.fc1=nn.Linear(config.hidden_size,num_labels)
self.fc2=nn.Linear(config.hidden_size,num_labels)

defforward(self,batch_pair_input_ids,batch_pair_attention_mask,batch_pair_token_type_ids,batch_pair_labels,
teacher_logits,teacher_similar):
"""
:parambatch_pair_input_ids:句对token序列
:parambatch_pair_attention_mask:句对attention_mask
:parambatch_pair_token_type_ids:句对token_type_ids

"""
output1=self.mbert(input_ids=batch_pair_input_ids[0],attention_mask=batch_pair_attention_mask[0],
token_type_ids=batch_pair_token_type_ids[0]).last_hidden_state
output2=self.mbert(input_ids=batch_pair_input_ids[1],attention_mask=batch_pair_attention_mask[1],
token_type_ids=batch_pair_token_type_ids[1]).last_hidden_state
soft_output1,soft_output2=self.fc1(output1),self.fc2(output2)
soft_logits1,soft_logits2=F.softmax(soft_output1,dim=-1),F.softmax(soft_output2,dim=-1)
alpha1,alpha2=torch.square(torch.max(input=soft_logits1,dim=-1)[0]).mean(),torch.square(
torch.max(soft_logits2,dim=-1)[0]).mean()
output_similar=torch.sigmoid(torch.cosine_similarity(soft_output1,soft_output2,dim=-1))
soft_similar=torch.sigmoid(torch.cosine_similarity(soft_logits1,soft_logits2,dim=-1))
beta=torch.square(2*output_similar-1).mean()
gamma=1-torch.abs(soft_similar-output_similar).mean()
#计算蒸馏的loss
#teacherlogits与studentlogits1的loss
loss1=alpha1*(F.cross_entropy(soft_logits1,teacher_logits))
#teachersimilar与studentsimilar的loss
loss2=beta*(F.binary_cross_entropy(soft_similar,teacher_similar))
#teacherlogits与studentlogits2的loss
loss3=alpha2*(F.cross_entropy(soft_logits2,teacher_logits))
#finalloss
loss=gamma*(loss1+loss2+loss3).mean()
returnloss


if__name__=="__main__":
fromtransformersimportBertConfig

pretarin_path="./pytorch_mbert_model"

batch_pair1_input_ids=torch.randint(1,100,(2,128))
batch_pair1_attention_mask=torch.ones_like(batch_pair1_input_ids)
batch_pair1_token_type_ids=torch.zeros_like(batch_pair1_input_ids)
batch_labels1=torch.randint(1,10,(2,128))
batch_labels2=torch.randint(1,10,(2,128))
#t(对比两个序列标签,相同为1,不同为0)
batch_t=torch.as_tensor(batch_labels1.numpy()==batch_labels2.numpy()).float()

batch_pair2_input_ids=torch.randint(1,100,(2,128))
batch_pair2_attention_mask=torch.ones_like(batch_pair2_input_ids)
batch_pair2_token_type_ids=torch.zeros_like(batch_pair2_input_ids)

batch_all_input_ids,batch_all_attention_mask,batch_all_token_type_ids,batch_all_labels=[],[],[],[]
batch_all_labels.append(batch_labels1)
batch_all_labels.append(batch_labels2)
batch_all_input_ids.append(batch_pair1_input_ids)
batch_all_input_ids.append(batch_pair2_input_ids)
batch_all_attention_mask.append(batch_pair1_attention_mask)
batch_all_attention_mask.append(batch_pair2_attention_mask)
batch_all_token_type_ids.append(batch_pair1_token_type_ids)
batch_all_token_type_ids.append(batch_pair2_token_type_ids)

config=BertConfig.from_pretrained(pretarin_path)
#teacher模型训练
teacher_model=TeacherNER.from_pretrained(pretarin_path,config=config,num_labels=10)
outputs,loss=teacher_model(batch_token_input_ids=batch_pair1_input_ids,
batch_attention_mask=batch_pair1_attention_mask,
batch_token_type_ids=batch_pair1_token_type_ids,batch_labels=batch_labels1,
batch_pair_input_ids=batch_all_input_ids,
batch_pair_attention_mask=batch_all_attention_mask,
batch_pair_token_type_ids=batch_all_token_type_ids,
training=True,batch_t=batch_t)
#student模型蒸馏
teacher_logits,teacher_similar=teacher_model(batch_token_input_ids=batch_pair1_input_ids,
batch_attention_mask=batch_pair1_attention_mask,
batch_token_type_ids=batch_pair1_token_type_ids,
batch_labels=batch_labels1,
batch_pair_input_ids=batch_all_input_ids,
batch_pair_attention_mask=batch_all_attention_mask,
batch_pair_token_type_ids=batch_all_token_type_ids,
training=False)

student_model=StudentNER.from_pretrained(pretarin_path,config=config,num_labels=10)
loss_all=student_model(batch_pair_input_ids=batch_all_input_ids,
batch_pair_attention_mask=batch_all_attention_mask,
batch_pair_token_type_ids=batch_all_token_type_ids,
batch_pair_labels=batch_all_labels,teacher_logits=teacher_logits,
teacher_similar=teacher_similar)
print(loss_all)

笔者自己实现的一部分代码,可能不是原论文作者想表达的意思,读者有疑问的话可以一起讨论一下^~^。


审核编辑 :李倩


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 编码器
    +关注

    关注

    41

    文章

    3364

    浏览量

    131576
  • 模型
    +关注

    关注

    1

    文章

    2707

    浏览量

    47707
  • 标签
    +关注

    关注

    0

    文章

    129

    浏览量

    17789

原文标题:ACL2022 | 跨语言命名实体识别:无监督多任务多教师蒸馏模型

文章出处:【微信号:zenRRan,微信公众号:深度学习自然语言处理】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    自然语言基础技术之命名实体识别相对全面的介绍

    早期的命名实体识别方法基本都是基于规则的。之后由于基于大规模的语料库的统计方法在自然语言处理各个方面取得不错的效果之后,一大批机器学习的方法也出现在命名实体
    的头像 发表于 04-17 10:12 4741次阅读
    自然<b class='flag-5'>语言</b>基础技术之<b class='flag-5'>命名实体</b><b class='flag-5'>识别</b>相对全面的介绍

    HanLP分词命名实体提取详解

    可能词) 5.极速词典分词(速度快,精度一般) 6.用户自定义词典 7.标准分词(HMM-Viterbi) 命名实体识别 1.实体机构名识别(层叠HMM-Viterbi) 2.中国人名
    发表于 01-11 14:32

    基于结构化感知机的词性标注与命名实体识别框架

    `上周就关于《结构化感知机标注框架的内容》已经分享了一篇《分词工具Hanlp基于感知机的中文分词框架》,本篇接上一篇内容,继续分享词性标注与命名实体识别框架的内容。词性标注训练词性标注是分词后紧接着
    发表于 04-08 14:57

    HanLP-命名实体识别总结

    的中国人名自动识别研究》,大家可以百度一下看看 地名识别 理论指导文章为:《基于层叠隐马尔可夫模型的中文命名实体识别》 机构名
    发表于 07-31 13:11

    基于神经网络结构在命名实体识别中应用的分析与总结

    近年来,基于神经网络的深度学习方法在自然语言处理领域已经取得了不少进展。作为NLP领域的基础任务命名实体识别(Named Entity Recognition,NER)也不例外,神经
    的头像 发表于 01-18 09:24 4451次阅读
    基于神经网络结构在<b class='flag-5'>命名实体</b><b class='flag-5'>识别</b>中应用的分析与总结

    思必驰中文命名实体识别任务助力AI落地应用

    验阶段走向实用化。近期,思必驰语言与知识团队对中文细粒度命名实体识别任务进行探索,并取得阶段性进展:在CLUE数据集Fine-Grain NER评测
    的头像 发表于 02-22 18:27 1669次阅读

    新型中文旅游文本命名实体识别设计方案

    传统基于词向量表示的命名实体识别方法通常忽略了字符语义信息、字符间的位置信息,以及字符和单词的关联关系。提出一种基于单词字符引导注意力网络( WCGAN)的中文旅游命名实体识别方法,利
    发表于 03-11 11:26 24次下载
    新型中文旅游文本<b class='flag-5'>命名实体</b><b class='flag-5'>识别</b>设计方案

    知识图谱与训练模型相结合和命名实体识别的研究工作

    本次将分享ICLR2021中的三篇投递文章,涉及知识图谱与训练模型相结合和命名实体识别(NER)的研究工作。 文章概览 知识图谱和语言理解的联合预训练(JAKET: Joint
    的头像 发表于 03-29 17:06 3870次阅读
    知识图谱与训练<b class='flag-5'>模型</b>相结合和<b class='flag-5'>命名实体</b><b class='flag-5'>识别</b>的研究工作

    命名实体识别的迁移学习相关研究分析

    命名实体识别(NER)是自然语言处理的核心应用任务之一。传统和深度命名实体识别方法严重依赖于大量
    发表于 04-02 15:15 8次下载
    <b class='flag-5'>命名实体</b><b class='flag-5'>识别</b>的迁移学习相关研究分析

    基于字语言模型的中文命名实体识别系统

    而造成的数据稀缺问题,以及传统字向量不能解决的一字多义问題,文中使用在大规模无监督数据上预训练的基于上下文相关的字向量,即利用语言模型生成上下文相关字向量以改进中文NER模型的性能。同
    发表于 04-08 14:36 14次下载
    基于字<b class='flag-5'>语言</b><b class='flag-5'>模型</b>的中文<b class='flag-5'>命名实体</b><b class='flag-5'>识别</b>系统

    基于神经网络的中文命名实体识别方法

    在基于神经网络的中文命名实体识别过程中,字的向量化表示是重要步骤,而传统的词向量表示方法只是将字映射为单一向量,无法表征字的多义性。针对该问题,通过嵌入BERT预训练语言模型,构建BE
    发表于 06-03 11:30 3次下载

    关于边界检测增强的中文命名实体识别

    引言 命名实体识别(Named Entity Recognition,NER)是自然语言处理领域的一个基础任务,是信息抽取等许多任务的子
    的头像 发表于 09-22 16:05 2738次阅读

    基于序列标注的实体识别所存在的问题

    实体识别通常被当作序列标注任务来做,序列标注模型需要对实体边界和实体类别进行预测,从而
    的头像 发表于 07-28 11:08 1404次阅读

    如何统一各种信息抽取任务的输入和输出

    信息抽取任务包括命名实体识别(NER)、关系抽取(RE)、事件抽取(EE)等各种各样的任务
    的头像 发表于 09-20 15:25 908次阅读

    什么是嵌套实体识别

    嵌套命名实体识别命名实体识别中的一个颇具挑战的子问题。我们在《实体识别LEAR论文阅读笔记》与
    的头像 发表于 09-30 15:19 1435次阅读