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

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

3天内不再提示

采用双塔BERT模型对文本字符和label进行编码

深度学习自然语言处理 来源:PaperWeekly 作者:SinGaln 2022-07-08 10:38 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

这是一篇来自于 ACL 2022 的文章,总体思想就是在 meta-learning 的基础上,采用双塔 BERT 模型分别来对文本字符和对应的label进行编码,并且将二者进行 Dot Product(点乘)得到的输出做一个分类的事情。文章总体也不复杂,涉及到的公式也很少,比较容易理解作者的思路。对于采用序列标注的方式做 NER 是个不错的思路。

1、模型

1.1 架构

▲图1.模型整体构架

从上图中可以清楚的看到,作者采用了双塔 BERT 来分别对文本的 Token 和每个 Token 对应的 label 进行编码。这里作者采用这种方法的思路也很简单,因为是 Few-shot 任务,没有足够的数据量,所以作者认为每个 Token 的 label 可以为 Token 提供额外的语义信息。 作者的 Meta-Learning 采用的是 metric-based 方法,直观一点理解就是首先计算每个样本 Token 的向量表征,然后与计算得到的 label 表征计算相似度,这里从图上的 Dot Product 可以直观的体现出来。然后对得到的相似度矩阵 ([batch_size,sequence_length,embed_dim]) 进行 softmax 归一化,通过 argmax 函数取最后一维中值最大的 index,并且对应相应的标签列表,得到当前 Token 对应的标签。

1.2 Detail

此外,作者在对标签进行表征时,也对每个标签进行了相应的处理,总体分为以下三步: 1. 将词语的简写标签转为自然语言形式,例如 PER--》person,ORG--》organization,LOC--》local 等等; 2. 将标注标签起始、中间的标记转为自然语言形式,例如以 BIO 形式进行标记的就可以转为 begin、inside、other 等等,其他标注形式的类似。 3. 按前两步的方法转换后进行组合,例如 B-PER--》begin person,I-PER--》inside person。 由于进行的是 Few-shot NER 任务,所以作者在多个 source datasets 上面训练模型,然后他们在多个 unseen few shot target datasets 上面验证经过 fine-tuning 和不经过 fine-tuning 的模型的效果。 在进行 Token 编码时,对应每个 通过 BERT 模型可以得到其对应的向量 ,如下所示:

这里需要注意的是 BERT 模型的输出取 last_hidden_state 作为对应 Token 的向量。 对标签进行编码时,对标签集合中的所有标签进行对应编码,每个完整的 label 得到的编码取 部分作为其编码向量,并且将所有的 label 编码组成一个向量集合 ,最后计算每个 与 的点积,形式如下:

由于这里使用了 label 编码表征的方式,相比于其他的 NER 方法,在模型遇到新的数据和 label 时,不需要再初始一个新的顶层分类器,以此达到 Few-shot 的目的。

1.3 Label Transfer

在文章中作者还罗列了实验数据集的标签转换表,部分如下所示:

▲图2. 实验数据集Label Transfer

1.4 Support Set Sampling Algorithm

采样伪代码如下所示:

▲图3. 采样伪代码

2、实验结果

▲图4. 部分实验结果

从实验结果上看,可以明显的感受到这种方法在 Few-shot 时还是有不错的效果的,在 1-50 shot 时模型的效果都优于其他模型,表明了 label 语义的有效性;但在全量数据下,这种方法就打了一些折扣了,表明了数据量越大,模型对于 label 语义的依赖越小。这里笔者还有一点想法就是在全量数据下,这种方式的标签语义引入可能会对原本的文本语义发生微小偏移,当然,这种说法在 Few-shot 下也是成立的,只不过 Few-shot 下的偏移是一个正向的偏移,能够增强模型的泛化能力,全量数据下的偏移就有点溢出来的感觉。 双塔 BERT 代码实现(没有采用 metric-based 方法):

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

importtorch
importtorch.nnasnn
fromtransformersimportBertModel,BertPreTrainedModel


classSinusoidalPositionEmbedding(nn.Module):
"""定义Sin-Cos位置Embedding
"""

def__init__(
self,output_dim,merge_mode='add'):
super(SinusoidalPositionEmbedding,self).__init__()
self.output_dim=output_dim
self.merge_mode=merge_mode

defforward(self,inputs):
input_shape=inputs.shape
batch_size,seq_len=input_shape[0],input_shape[1]
position_ids=torch.arange(seq_len,dtype=torch.float)[None]
indices=torch.arange(self.output_dim//2,dtype=torch.float)
indices=torch.pow(10000.0,-2*indices/self.output_dim)
embeddings=torch.einsum('bn,d->bnd',position_ids,indices)
embeddings=torch.stack([torch.sin(embeddings),torch.cos(embeddings)],dim=-1)
embeddings=embeddings.repeat((batch_size,*([1]*len(embeddings.shape))))
embeddings=torch.reshape(embeddings,(batch_size,seq_len,self.output_dim))
ifself.merge_mode=='add':
returninputs+embeddings.to(inputs.device)
elifself.merge_mode=='mul':
returninputs*(embeddings+1.0).to(inputs.device)
elifself.merge_mode=='zero':
returnembeddings.to(inputs.device)


classDoubleTownNER(BertPreTrainedModel):
def__init__(self,config,num_labels,position=False):
super(DoubleTownNER,self).__init__(config)
self.position=position
self.num_labels=num_labels
self.bert=BertModel(config=config)
self.fc=nn.Linear(config.hidden_size,self.num_labels)

ifself.position:
self.sinposembed=SinusoidalPositionEmbedding(config.hidden_size,"add")

defforward(self,sequence_input_ids,sequence_attention_mask,sequence_token_type_ids,label_input_ids,
label_attention_mask,label_token_type_ids):
#获取文本和标签的encode
#[batch_size,sequence_length,embed_dim]
sequence_outputs=self.bert(input_ids=sequence_input_ids,attention_mask=sequence_attention_mask,
token_type_ids=sequence_token_type_ids).last_hidden_state
#[batch_size,embed_dim]
label_outputs=self.bert(input_ids=label_input_ids,attention_mask=label_attention_mask,
token_type_ids=label_token_type_ids).pooler_output
label_outputs=label_outputs.unsqueeze(1)

#位置向量
ifself.position:
sequence_outputs=self.sinposembed(sequence_outputs)
#Dot交互
interactive_output=sequence_outputs*label_outputs
#full-connection
outputs=self.fc(interactive_output)
returnoutputs

if__name__=="__main__":
pretrain_path="../bert_model"
fromtransformersimportBertConfig

token_input_ids=torch.randint(1,100,(32,128))
token_attention_mask=torch.ones_like(token_input_ids)
token_token_type_ids=torch.zeros_like(token_input_ids)

label_input_ids=torch.randint(1,10,(1,10))
label_attention_mask=torch.ones_like(label_input_ids)
label_token_type_ids=torch.zeros_like(label_input_ids)
config=BertConfig.from_pretrained(pretrain_path)
model=DoubleTownNER.from_pretrained(pretrain_path,config=config,num_labels=10,position=True)

outs=model(sequence_input_ids=token_input_ids,sequence_attention_mask=token_attention_mask,sequence_token_type_ids=token_token_type_ids,label_input_ids=label_input_ids,
label_attention_mask=label_attention_mask,label_token_type_ids=label_token_type_ids)
print(outs,outs.size())

审核编辑:郭婷

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

    关注

    30

    文章

    4941

    浏览量

    73144
  • 数据集
    +关注

    关注

    4

    文章

    1230

    浏览量

    26046

原文标题:ACL2022 | 序列标注的小样本NER:融合标签语义的双塔BERT模型

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

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    百度文心大模型5.0-Preview文本能力国内第一

    11月8日凌晨,LMArena大模型竞技场最新排名显示,文心全新模型ERNIE-5.0-Preview-1022登上文本排行榜全球并列第二、中国第一该模型在创意写作、复杂长问题理解、指
    的头像 发表于 11-11 17:15 1095次阅读

    浅析多模态标注对大模型应用落地的重要性与标注实例

    ”的关键工序——多模态标注重要性日益凸显。 一、什么是多模态标注? 多模态标注是指对文本、图像、语音、视频、点云等异构数据进行跨模态语义关联的标注过程,通过建立数据间的时空一致性和语义对齐,为大模型提供结构化的训练素
    的头像 发表于 09-05 13:49 757次阅读

    linux系统awk特殊字符命令详解

    在Linux系统中,awk 是一种非常强大的文本处理工具,能够对文本数据进行分析、格式化和筛选。利用其内置的特殊字符和操作符,用户可以实现复杂的数据处理任务。以下对一些常见的awk特殊
    的头像 发表于 07-28 16:38 417次阅读

    从FA模型切换到Stage模型时:module的切换说明

    的能力,采用字符串数组的格式表示。/Stage模型不支持。 metaData该标签标识ability的元信息。metadata具体差异见表2。 type标识Ability的类型。/Stage模型不支持
    发表于 06-05 08:16

    在KaihongOS中,可以使用文件管理对文进行基础的操作

    文件操作 在KaihongOS中,可以使用@ohos.file.fs (文件管理)对文进行基础的操作。下面简单介绍一下关于本地文件的查询、拷贝、删除、修改的操作。 导入模块 import fs
    发表于 05-08 06:39

    ​VLM(视觉语言模型)​详细解析

    的详细解析: 1. 核心组成与工作原理 视觉编码器 :提取图像特征,常用CNN(如ResNet)或视觉Transformer(ViT)。 语言模型 :处理文本输入/输出,如GPT、BERT
    的头像 发表于 03-17 15:32 7571次阅读
    ​VLM(视觉语言<b class='flag-5'>模型</b>)​详细解析

    使用OpenVINO™训练扩展对水平文本检测模型进行微调,收到错误信息是怎么回事?

    已针对水平文本检测模型运行OpenVINO™训练扩展中的 微调 步骤,并收到错误消息: RuntimeError: Failed to find annotation files
    发表于 03-05 06:48

    阿里云通义开源长文本模型Qwen2.5-1M

    近日,阿里云通义宣布了一项重大开源举措,推出了支持100万Tokens上下文的Qwen2.5-1M模型。这一新模型在处理长文本任务中展现出了卓越的性能,稳定超越了GPT-4o-mini
    的头像 发表于 02-05 14:01 779次阅读

    【「基于大模型的RAG应用开发与优化」阅读体验】+Embedding技术解读

    引入外部知识库来增强生成模型的能力。而Embedding在 Embedding模型将用户的问题和文档库中的文本转换为向量表示,这是RAG系统进行信息检索和
    发表于 01-17 19:53

    【「基于大模型的RAG应用开发与优化」阅读体验】+大模型微调技术解读

    。对于文本数据,可以采用同义词替换、句法变换、上下文扩展等技术。微调策略和方法全参数微调:对模型的所有参数进行再训练。虽然需要大量的计算资源,但它可以充分适应特定任务。轻量级微调方法:
    发表于 01-14 16:51

    字符串在数据库中的存储方式

    固定长度的空间,适合存储长度变化不大的字符串。 可变长度字符串 :如VARCHAR类型,它根据字符串的实际长度动态分配空间,适合存储长度变化较大的字符串。
    的头像 发表于 01-07 15:41 1251次阅读

    字符串在编程中的应用实例

    字符串在编程中有着广泛的应用,它们被用于表示文本数据、处理用户输入、构建动态内容等。以下是一些字符串在编程中的应用实例: 1. 用户输入与输出 用户输入 :程序通常需要从用户那里获取输入,这些输入通
    的头像 发表于 01-07 15:33 1129次阅读

    字符串与字符数组的区别

    在编程语言中,字符串和字符数组是两种基本的数据结构,它们都用于存储和处理文本数据。尽管它们在功能上有一定的重叠,但在内部表示、操作方式和使用场景上存在显著差异。 1. 内部表示 字符
    的头像 发表于 01-07 15:29 1676次阅读

    【「大模型启示录」阅读体验】如何在客服领域应用大模型

    训练模型BERT、GPT等。这些模型在理解自然语言、生成文本、处理对话等方面具有不同的能力。因此,在选择模型时,需要了解每个
    发表于 12-17 16:53

    Linux三剑客之Sed:文本处理神器

    关于linux三剑客 grep,过滤关键字信息数据。主要是用于查文本内的数据 sed ,对文本数据进行编辑,修改原文件内容 awk,对文件数据过滤,提取,并且能实现,格式化输出 awk
    的头像 发表于 12-16 15:58 1122次阅读
    Linux三剑客之Sed:<b class='flag-5'>文本</b>处理神器