因为项目和毕设的缘故,做了挺多关于Bert分类的实际操作的,本文主要记录下transformers库中使用较多的类。
在本文中,你将看到

  • huggingface(hf)中Bert模型的简单介绍
  • BertConfig,BertTokenizer,BertModel的简单使用

博客地址:https://ilingen.top/

Bert(Bidirectional Transformer for Language Understanding)通过MLM和NSP预训练任务,在Wikipedia和Toronto Book Corpus上进行自监督的学习。

所谓的自监督:我理解的就是从无标签的数据中学习监督任务。比如MLM任务中,将随机mask掉一些token,然后predict出对应masked掉的token。

Bert的预训练任务以及其encoder结构决定了其适合于NLU中的预测型的任务,不适合于text generation生成式任务,在工程实际使用中也需要注意这一点。

Hugging face库中关于Bert的模型有很多,但是实际上需要掌握的用的最多的只有三个:BertConfig、BertTokenizer、BertModel。其他的封装好的下游任务API比如BertForSequenceClassification其实就是在原生的BertModel上外接Linear层实现的。

BertConfig配置

# 定义
class transformers.BertConfig(vocab_size = 30522, hidden_size = 768, num_hidden_layers = 12, num_attention_heads = 12,intermediate_size = 3072, hidden_act = 'gelu',hidden_dropout_prob = 0.1,attention_probs_dropout_prob = 0.1,max_position_embeddings = 512, type_vocab_size = 2,initializer_range = 0.02, layer_norm_eps = 1e-12,pad_token_id = 0,position_embedding_type = 'absolute',use_cache = True, classifier_dropout = None, **kwargs)

transformers中的一个类,用来记录BertModel的基本配置,继承自PretrainedConfig,用来初始化BERT模型,实例化bert-base-uncased模型。

from transformers import BertModel, BertConfig
# 默认使用bert-based-uncased初始化
configuration=BertConfig()
# 初始化BertModel
model=BertModel(configuration)
# 获取模型的配置
configuration=model.config

BertConfig继承自父类PretrainedConfig,因此可以调用父类的from_pretrained方法来直接加载模型配置。

# 加载bert-based-chinese
configuration=BertConfig.from_pretrained("bert-based-chinese")

BertTokenizer分词器

# 定义
class transformers.BertTokenizer(vocab_file, do_lower_case=True,do_basic_tokenize=True, never_split=None,unk_token='[UNK]', sep_token='[SEP]',pad_token='[PAD]',cls_token='[CLS]',mask_token='[MASK]',tokenize_chinese_chars=True,strip_accents=None,**kwargs)

构建基于WordPiece分词方式的BERT分词器,并进行编码。继承自PretrainedTokenizer,PretrainedTokenizer具有很多功能,可以查看源代码。

BertTokenizer进行编码有三种方式,直接使用tokenizer()、tokenizer.encode()以及tokenizer.encode_plus()
三个函数调用时的参数基本一致,主要有以下几个

  • text, text_pair 代表输入的两个句子 str
  • truncation 是否进行截断操作 bool
  • padding 是否进行padding处理 bool
  • return_tensors 'pt’表示pytorch的tensor;'tf’表示tensorflow版本tensor;None表示返回list

通过tokenizer.vocab查看BertTokenizer的词典,主要注意几个词对应的是’[PAD]‘对应的id为0,’[UNK]‘对应id为100,’[CLS]‘对应id为101,’[SEP]‘对应id为102,’[MASK]'对应id为103。
其中tokenizer()和tokenizer.encode_plus()返回结果一致,都返回所有的编码结果,而tokenizer.encode()则是简单的返回词对应的id序列,对于编码器输出的三个编码结果,对应的含义如下。

  • input_ids 是Tokenizer对两个句子的token进行idx映射编码,将对应的句子映射为idx。比如在BERT这里输入的形式是 CLS sen1 SEP sen2 SEP

  • token_type_idx 是为了区分第一句话和第二句话的编码。0表示第一句话,1表示第二句话

  • attention_mask 是为了区分有多少token是有用的,因为Bert输入为固定长度512,所以不足512的需要进行补全操作。补全的部分对应的attention_mask为0

from transformers import BertTokenizer
tokenizer=BertTokenizer.from_pretrained("bert-base-chinese")
# 编码的两个句子
sens1="银行贷款允许未成年人吗"
sens2='未成年人可以办理银行卡吗'
# 第一种编码
tokenizer(text=sens1,text_pair=sens2)
# 输出
{'input_ids': [101, 7213, 6121, 6587, 3621, 1038, 6387, 3313, 2768, 2399, 782, 1408, 102, 3313, 2768, 2399, 782, 1377, 809, 1215, 4415, 7213, 6121, 1305, 1408, 102], 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}# 第二种tokenizer.encode_plus()
tokenizer.encode_plut(text=sens1, text_pair=sens2)
# 输出
{'input_ids': [101, 7213, 6121, 6587, 3621, 1038, 6387, 3313, 2768, 2399, 782, 1408, 102, 3313, 2768, 2399, 782, 1377, 809, 1215, 4415, 7213, 6121, 1305, 1408, 102], 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}
# 第三种tokenizer.encode()
tokenizer.encode(text=sens1, text_pair=sens2)
# 输出
[101, 7213, 6121, 6587, 3621, 1038, 6387, 3313, 2768, 2399, 782, 1408, 102, 3313, 2768, 2399, 782, 1377, 809, 1215, 4415, 7213, 6121, 1305, 1408, 102]

BertModel

# 原始定义
BertModel(config, add_pooling_layer=True)

这里需要讨论一下BertModel的两个加载方式

  • BertConfig加载,用来加载配置,但不加载模型权重,相当于加载一个空的Bert模型,用作预训练任务。
  • .from_pretrained()方法加载。.from_pretrained()方法是来自于父类PreTrainedModel,用来加载模型权重,相当于加载一个与训练好的Bert模型,用作下游微调。

Bert的输入

BertModel也是nn.Module的子类,forward函数定义如下

# BertModel.forwarddef forward(self,input_ids: Optional[torch.Tensor] = None,attention_mask: Optional[torch.Tensor] = None,token_type_ids: Optional[torch.Tensor] = None,position_ids: Optional[torch.Tensor] = None,head_mask: Optional[torch.Tensor] = None,inputs_embeds: Optional[torch.Tensor] = None,encoder_hidden_states: Optional[torch.Tensor] = None,encoder_attention_mask: Optional[torch.Tensor] = None,past_key_values: Optional[List[torch.FloatTensor]] = None,use_cache: Optional[bool] = None,output_attentions: Optional[bool] = None,output_hidden_states: Optional[bool] = None,return_dict: Optional[bool] = None,) -> Union[Tuple[torch.Tensor], BaseModelOutputWithPoolingAndCrossAttentions]:

其中,重点介绍一些输入的参数

  • input_ids (batch_size,sequence_length) 输入序列根据字典中的token转化id
  • attention_mask (batch_size, sequence_legnth) optional,避免对padding的id进行attention操作。1表示没有经过padding,0表示经过padding操作。
  • token_type_ids (batch_size,sequence_length) optional,表示两个输入的句子。0表示第一个句子,1表示第二个句子
  • position_ids (batch_size,sequence_length) optional,对输入的token进行位置的表示,如果没有输入,则会是Bert中的绝对位置编码
  • head_mask (num_heads,)或者(num_layers, num_heads) optional 对选定的attention head进行mask操作。
  • return_dict bool optional 是否返回ModelOutput形式的dict或者只是一个元组的形式。

根据forward函数,Bert模型的简单使用如下所示。

from transformers import BertModel
model=BertModel.from_pretrained("bert-base-chinese")from transformers import BertTokenizer
tokenizer=BertTokenizer.from_pretrained("bert-base-chinese")sens1="银行贷款允许未成年人吗"
sens2="未成年人可以办理银行卡吗"
inputs=tokenizer(sens1, sens2, return_tensors='pt')
outputs=model(**inputs)

Bert的输出

对于outputs,在未定义其他输出的情况下,有两个tensor输出,用作简单输出。

  • last_hidden_state Bert给每个输入的token的表示,shape为[batch_size, seq_len, hidden_size]

  • pooler_output last_hidden_state的第一个[CLS]向量经过线性层之后的输出,用作分类输出,shape为[batch_size,hidden_size]

在定义其他输出结果时,Bert模型返回结果为transformers中
modeling_outputs.BaseModelOutputWithPoolingAndCrossAttention类的实例形式。

  • last_hidden_state (batch_size, sequence_length, hidden_size)最后一层的输出

  • pooler_output (batch_size, hidden_size) 对最后一层第一个token对应的CLS输出进行线性层和Tanh激活函数后的输出结果,通常用于句子分类。

  • hidden_states (Tuple),当BERT的输入的output_hidden_states为True时,输出一个元组:长度为13,第一个为embedding,后面十二个都为对应层的输出结果,形状都为(batch_size, sequence_length, hidden_size)每层输出的模型隐藏状态加上可选的初始嵌入输出。

  • attentions (Tuple),当输入的output_attentions=True时,对每层attention矩阵的输出,形状是(batch_size,num_heads,sequence_length,sequence_length)。经过softmax得到的注意力权重,用于计算加权权重。

  • cross_attentions(Tuple) 当输入的output_attentions=True时,输出解码器的attention矩阵输出,形状同样是(batch_size,num_heads,sequence_length,sequence_length)。

  • past_key_value(Tuple(Tuple)) 暂时没搞懂这个是啥。当use_cache=True时,返回元组的的元组。每个元组有两个张量(batch_size,num_heads,sequence_length,embed_size_per_head)包含预先计算的隐藏状态(自注意力块中的键和值,以及交叉注意力块中的可选 config.is_encoder_decoder=True),可用于加速顺序解码(参见 past_key_values 输入)。

总结

本文主要总结了transformers库中有关Bert模型的一些简单操作,也算是趁着暑期项目和学业没有特别赶的时候填的坑吧,有一些不太清楚或者有问题的可以随时反馈,希望大家在讨论中一起学习进步。

参考

transformer的BERT官方文档

huggingface中Bert模型的简单使用相关推荐

  1. bert模型简介、transformers中bert模型源码阅读、分类任务实战和难点总结

    bert模型简介.transformers中bert模型源码阅读.分类任务实战和难点总结:https://blog.csdn.net/HUSTHY/article/details/105882989 ...

  2. NLP中BERT模型详解

    标题NLP中BERT模型详解 谷歌发表的论文为: Attention Is ALL You Need 论文地址:[添加链接描述](https://arxiv.org/pdf/1706.03762.pd ...

  3. 在osgEarth中添加模型的简单示例

    一个在osgEarth中加载模型的小示例,方便在此基础上进行其它场景编辑,资源为osgEarth自带Data. #include "common.h" #include <W ...

  4. datawhale 8月学习——NLP之Transformers:编写BERT模型

    前情回顾 1.attention和transformers 2.BERT和GPT 结论速递 跟着教程,阅读了HuggingFace的BERT模型,分为tokenizer和model两大部分,而mode ...

  5. 使用huggingface的Transformers预训练自己的bert模型+FineTuning

    ① 将"softmax+交叉熵"推广到多标签分类问题 多分类问题引申到多标签分类问题(softmax+交叉熵) 作者苏剑林论述了将多分类任务下常用的softmax+CE的方式,推广 ...

  6. 从Word Embedding到Bert模型---NLP中预训练发展史

    本文转自张俊林老师,希望加深记忆及理解. 本文的主题是自然语言处理中的预训练过程,会大致说下NLP中的预训练技术是一步一步如何发展到Bert模型的,从中可以很自然地看到Bert的思路是如何逐渐形成的, ...

  7. bert模型中的[CLS]、[UNK]、[SEP]

    一般我们就用训练集出一个模型,然后可以在其他的代码里读取这个模型来使用.其他的代码就是所谓的下游任务(比如·什么分类.NER什么的).BERT只是出一个词向量,这个向量不接任务你也看不出什么东西.这种 ...

  8. excelexportentity中设置null不显示的方法_如何在 Creator3D 中切换模型贴图,超级简单!...

    效果预览 前两天有伙伴在 QQ 上询问,如何在 Creator 3D 中切换模型贴图.Shawn 之前也没尝试过,不过根据之前 Cocos Creator 的经验以及这几天对 Creator 3D 的 ...

  9. 20. [Python GUI] PyQt5中的模型与视图框架-实现一个简单的文件浏览器的例子

    PyQt5中的模型与视图框架-实现一个简单的文件浏览器的例子 一.使用模型/视图实现一个简单的文件浏览器 二.小手一抖,点个赞再走哦~ 一.使用模型/视图实现一个简单的文件浏览器 这个例子里不涉及数据 ...

最新文章

  1. DeepMind丢掉了归一化,让图像识别训练速度提升了8.7倍 | 已开源
  2. 热榜第四:GitHub开源代码数据集界ImageNet,推出代码搜索挑战赛
  3. linux-windows主动推送文件同步目录数据 linux-windows数据目录同步
  4. [原创 - 尚学堂科技 - 马士兵老师]
  5. linux下安装win xp 进pe出错,PE安装原版XP系统(含高版本PE安装选项灰色处理办法)...
  6. 阅读总结:如何在生产中成功运用Docker
  7. Boltzmann Machine 入门(1)
  8. 笔记本电脑关机后指示灯还亮_汽车仪表常见指示符号之清洗液指示灯,灯亮了怎么办?...
  9. 阿里云天池 Python训练营Task4: Python数据分析:从0完成一个数据分析实战 学习笔记
  10. windows c++ 服务 当前用户提权_windows xp 提权
  11. cisco ios cookbook
  12. 6LoWPAN Header compression
  13. Cadence系列之SIPI仿真笔记:Cadence多种版本的安装、卸载重装(一)
  14. DELL服务器运行硬件检测
  15. mac 清理微信缓存文件
  16. Eviction Kill POD选择分析
  17. 计算机无法进去系统,开机进入bios无法进入系统怎么办_电脑开机就进入bios的解决方法...
  18. 从ADS到RealView MDK
  19. oracle 表添加一列
  20. Sketch教程|Sketch图层如何使用?如何使用Sketch画板?

热门文章

  1. win7旗舰恢复出厂设置_教你把电脑恢复出厂设置。
  2. linux安装酷狗软件下载,Ubuntu 9.04安装kugou(酷狗)音乐
  3. SAP FICO全解析之-公司代码
  4. jmeter的Body Data怎样使用?
  5. matlab 中的del2函数
  6. 2022年T电梯修理操作证考试题模拟考试平台操作
  7. 通信原理(5)—— 数字带通传输系统(ASK/FSK/PSK/DPSK)
  8. ubuntu16.04输入密码登录无法进入工作桌面的解决方法
  9. Ta来了,Ta来了,Spark基础能力测试题Ta来了!
  10. 联想拯救者系列嗡嗡声,风扇狂转解决办法,亲测有效