首页 > 其他分享 >一张图看懂BERT

一张图看懂BERT

时间:2024-04-17 11:45:02浏览次数:21  
标签:BERT 768 Embeddings 模型 一张 ids 图看 向量

https://zhuanlan.zhihu.com/p/500807675

 

 

 

一张图看懂BERT

  1 前言

关于 BERT 模型的原理讲解实在太多了,学习路径主要是理解两篇论文:

1)理解 Transformer 模型,BERT 模型的主要结构就是 Transformer 模型的 Encoder 部分。论文传送门:Attention is all you need

2)理解 BERT 模型,论文传送门:BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding

本文主要讲解 BERT 模型的计算过程,并结合代码让读者有一个清晰的认识。

本文使用的 BERT 模型是来自哈工大的中文 ROBERTA 预训练模型,ROBERTA 是 BERT 的改进版本,模型下载地址:chinese_roberta_wwm_ext_L-12_H-768_A-12。尽管 ROBERTA 与 BERT 有一些差异(比如 ROBERTA 取消了 NSP 任务),但本文依然按照 BERT 的计算过程进行讲解。

 

2 BERT 计算过程

如下图所示,整个计算过程从下往上:

1、第一步输入语句,这里的 Sentence: “刮风这天,我试过握着你手。”

2、第二步数据转换,一般通过 BertTokenizer(分词器)进行转换,这个 BertTokenizer 的主要任务就是对原始语句进行处理,以满足 BertModel 的输入要求。BertTokenizer 主要执行以下处理过程:

1)生成词表,这个词表包含了训练语料库中所有的词,词表存储在 ./chinese_roberta_wwm_ext_L-12_H-768_A-12/vocab.txt 中。打开 vocab.txt,一共有 21128 个词,中文分词其实就是按照汉字进行拆分的。每个词都有对应的索引(索引从 0 开始),比如 [PAD]:0、 [CLS]:101、 [SEP]:102、[MASK]:103,[unused1]~[unused99] 表示未定义的词,是预留给用户自定义的。

2)BertTokenizer 的输入 Sentence:“刮风这天,我试过握着你手。”,定义 BertModel 的输入语句长度为 18,将 Sentence 转换为 BertModel 定义的格式 Assemble:“[CLS]”、 “刮“、 “风”、 “这”、 “天”、 “,”、 “[SEP]”、 “我”、 “试”、 “过”、 “握”、 “着”、 “你”、 “手”、 “。”、 “[SEP]”、 “[PAD]” 、 “[PAD]” 。图中可以看到设定 Mask 的词为 “我”、 “握”、 “着”。

3)BertTokenizer 的输出: Input_ids、Token_Type_ids、Attention_Mask(图中绿色标记)。Input_ids 表示按照词表将每个词映射为索引,比如 “[CLS]” 映射为 101、“刮” 映射为 1167;Token_Type_ids 表示两个语句的上下文关系,第一个语句的每个词都标注 0,第二个语句的每个词都标注 1;Attention_Mask 记录 Mask 的位置信息,在 Mask 位置标注 0,其它位置标注 1。对于 [PAD] 位置统一标注 0。

3、第三步 BertModel 计算,主要执行以下处理过程:

1)生成词表向量库,对应的 size 为 [21128, 768],即一共 21128 个词,每个词向量的维度是 768。将词索引Input_ids 转化为词向量 Word_Embeddings。

2)生成 NSP 向量库,对应的 size 为 [2, 768],即只表示 0、1 两种标注,每个词向量的维度是 768。将上下文关系索引 Token_Type_ids 转化为上下文关系向量 Token_Type_Embeddings。

3)按顺序生成位置索引 Position_ids,索引为 0~17。生成 Position 向量库,对应的 size 为 [18, 768],即长度为 18,每个词向量的维度是 768。将位置索引 Position_ids 转化为位置向量 Position_Embeddings。

4)神经网络的输入就是将 Word_Embeddings、Token_Type_Embeddings、Position_Embeddings 直接相加,即输入 Embeddings = Word_Embeddings + Token_Type_Embeddings + Position_Embeddings。

5)输入 Embeddings 经过 12 层 Encoder 计算模型输出。图中给出了一层 Encoder 结构,其中 Multi-Head Self-Attention 采用 12 个注意力头,输入与输出的词向量维度都是 768;Feed Forward 第一层输出词向量维度 3072(采用 GELU 激活函数),第二层输出词向量维度 768 (作为线性层)。整个 Encoder 的输入到输出词向量的维度都是 768,一直到第 12 层 Encoder 的输出 HiddenState(size = [18, 768]),作为整个模型的输出。

6)通常 BertModel 还有一个输出 PoolOut,它是把 HiddenState 第 0 个位置,即 [CLS] 对应的输出,经过一层全连接层(输出词向量维度 768,采用 Tanh 作为激活函数),得到 PoolOut 的输出结果。通常我们在BertModel 的输出里会看到 HiddenState、PoolOut 两个结果。

7)BertModel 的损失函数分为 NSP Loss 与 MASK Loss。NSP Loss 评价输入的两个句子是否为上下文关系,因此直接把 HiddenState 第 0 个位置的输出接一个二分类器;MASK Loss 预测被 MASK 的词,所以这里需要用到 Attention_Mask 序列来告诉模型哪些位置被 MASK 了,只选取被 MASK 位置的输出参与损失函数计算,这里选取序号 7、10、11 位置的输出,先经过一层全连接层(输出词向量维度 768,采用 GELU 作为激活函数),再经过一层全连接层映射到 21128 维度的向量(词表的大小)。总的损失函数 Loss = NSP Loss + MASK Loss。

注:1)Word_Embeddings 、Token_Type_Embeddings、Position_Embeddings 都参与了训练过程,参数是动态调节的,这一点与 Transformer 有所不同(Transformer 中的 Position_Embeddings 是固定的正余弦函数)。 2)[PAD] 位置是不参与训练的,代码中自动屏蔽了 [PAD] 位置的梯度。

以上就是 BERT 的计算过程,模型训练需要大量的语料,一般都是直接使用训练好的 BERT 模型。加载预训练的 BERT 模型,只需要传入 Input_ids、Token_Type_Ids、Attention_Mask,模型自动完成 Embedding,输出可以取 HiddenState、PoolOut。

3 BERT 计算样例

这里我们做一个简单的例子查看模型的输入、输出。我们不考虑上下文,只输入一句话,所以 token_type_ids 全部为 0;没有 MASK 词,所以 attention_mask 只有在 [PAD] 位置为 0 ,其它全部为 1。

from transformers import BertModel, BertTokenizer

# 加载分词工具
tokenizer = BertTokenizer.from_pretrained("hfl/chinese-roberta-wwm-ext")

# 数据加载
data = tokenizer.encode_plus(text='刮风这天,我试过握着你手。',
                             truncation=True,
                             padding='max_length',
                             max_length=18,
                             return_tensors='pt',
                             return_length=True,
                             return_attention_mask=True
                             )

input_ids = data['input_ids']
attention_mask = data['attention_mask']
token_type_ids = data['token_type_ids']

# 加载预训练模型
model = BertModel.from_pretrained("hfl/chinese-roberta-wwm-ext")

# 不训练模型
for param in model.parameters():
    param.requires_grad_(False)

out = model(input_ids=input_ids,
            attention_mask=attention_mask,
            token_type_ids=token_type_ids)

print('input_ids', input_ids.shape, input_ids)
print('attention_mask', attention_mask.shape, attention_mask)
print('token_type_ids', token_type_ids.shape, token_type_ids)
print('last_hidden_state', out['last_hidden_state'].shape, out['last_hidden_state'])
print('pooler_output', out['pooler_output'].shape, out['pooler_output'])

打印结果:

input_ids:1) torch.Size([1, 18]) 
           2)tensor([[ 101, 1167, 7599, 6821, 1921, 8024, 2769, 6407, 
              6814, 2995, 4708,  872,   2797,  511,  102,    0,    0,    0]])

attention_mask:1) torch.Size([1, 18]) 
                2)tensor([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0]])

token_type_ids:1)torch.Size([1, 18]) 
                2)tensor([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])    

last_hidden_state: 1)torch.Size([1, 18, 768]) 
                    2)tensor([[[ 0.0448,  0.2122,  0.3339,  ..., -0.7975, -0.3528, -0.2340],
                                                             ...,
                             [ 0.3545, -0.1148,  0.0680,  ..., -0.2061, -0.3512, -0.6292]]])

pooler_output:1)torch.Size([1, 768])
               2)tensor([[ 0.9767,  0.8776,  0.9743,  0.6167, -0.6348,  0.0866, -0.8775, -0.0658,
                                                           ...,
                         -0.5344,  0.9941,  0.9434, -0.6481, -0.8505, -0.8339, -0.4736, -0.0645]])

 

BERT

简介:BERT的全称是Bidirectional Encoder Representation from Transformers,即双向Transformer的Encoder,因为decoder是不能获要预测的信息的。模型的主要创新点都在pre-train方法上,即…

卷积层发表于BERT相...

关于BERT中的那些为什么

1、为什么BERT在第一句前会加一个[CLS]标志? BERT在第一句前会加一个[CLS]标志,最后一层该位对应向量可以作为整句话的语义表示,从而用于下游的分类任务等。 为什么选它呢,因为与文本中已…

sliderSun      

标签:BERT,768,Embeddings,模型,一张,ids,图看,向量
From: https://www.cnblogs.com/zhangbojiangfeng/p/18140234

相关文章

  • 如何评估一个回答的好坏——BERTScore 基于预训练模型的相似度度量方式
    基于预训练模型的相似度度量方式BERTScoreBERTScore是一种基于BERT(双向编码器表示器转换器)语言模型的相似度度量。它将问题和回答编码为BERT向量,然后计算两个向量的余弦相似度。与传统的基于重叠词语的相似度度量不同,BERTScore能够捕获语义相似性,即使两个句子不包含相同的......
  • 周杰伦第一张专辑《JAY》十首歌附吉他谱分享
    周杰伦第一张专辑《JAY》,整张专辑的曲风以R&B及NewHip-Hop为主,古典巴洛克式弦乐伴奏及Band的加入,形成了一种英国式的复古风格,更特别的是,西班牙式风格的弦乐演奏在专辑歌曲中表现出的意境极度逼近电影配乐。专辑《JAY》封面  1.《可爱女人》:随着一声wu~,这首歌打开了......
  • 默认显示三张,第一张和第三张只显示一半,中间全部显示,点击可左右切换默认显示一二张
     项目地址:https://github.com/holiday0912/SwiperPreView   varswiper=newSwiper(".swiper-container",{autoplay:false,loop:true,initialSlide:2,spaceBetween:20,centeredSlides:true,slidesPerView:1.9,p......
  • BERT详解
    一、从RNN开始NLP里最常用、最传统的深度学习模型就是循环神经网络RNN(RecurrentNeuralNetwork)。这个模型的命名已经说明了数据处理方法,是按顺序按步骤读取的。与人类理解文字的道理差不多,看书都是一个字一个字,一句话一句话去理解的。RNN有多种结构,如下所示:1.one-to-on......
  • 一张表通用系统
    一张表通用系统为实现数据共享和信息互通,有效解决基层填报表单繁多、条线分割、多头录入、重复填报等问题。以基层表单填报为切入点,通过智能填报功能,基层社工可以一次性填写相关信息,避免了多次重复填报的繁琐过程,实现数据共享和信息互通,有效解决了基层填报表单繁多、条线分割、......
  • 打造自然资源“一张图”管理平台,推动生态文明建设新篇章
    在信息化时代的浪潮下,自然资源管理正面临着前所未有的挑战与机遇。传统的资源管理模式已经难以满足当前生态环境保护与经济发展的双重需求,我们需要一个全新的平台,一个集信息集成、智能分析、决策支持于一体的自然资源“一张图”管理平台。一、平台建设的必要性随着人口增长和......
  • 打造自然资源“一张图”管理平台,推动生态文明建设新篇章
    在信息化时代的浪潮下,自然资源管理正面临着前所未有的挑战与机遇。传统的资源管理模式已经难以满足当前生态环境保护与经济发展的双重需求,我们需要一个全新的平台,一个集信息集成、智能分析、决策支持于一体的自然资源“一张图”管理平台。一、平台建设的必要性随着人口增长和城......
  • 神经网络算法:一文搞懂BERT(基于Transformer的双向编码器)
    本文将从BERT的本质、BERT的原理、BERT的应用三个方面,带您一文搞懂BidirectionalEncoderRepresentationsfromTransformers|BERT。GoogleBERT一、BERT的本质BERT架构:一种基于多层Transformer编码器的预训练语言模型,通过结合Tokenization、多种Embeddings和特定任......
  • MySQL UPDATE JOIN 根据一张表或多表来更新另一张表的数据
    当使用MySQL时,经常需要根据一张表或多张表的数据来更新另一张表的数据。这种情况下,我们可以使用UPDATE语句结合JOIN操作来实现这一需求。本文将介绍MySQL中使用UPDATEJOIN的技术。什么是UPDATEJOINUPDATEJOIN是MySQL中一种结合UPDATE语句和JOIN操作的技术,用于根据一张表或多......
  • 9n-triton部署bert模型实战经验
    一、背景对于算法工程师来说,通常采用python语言来作为工作语言,但是直接用python部署线上服务性能很差。这个问题困扰了我很久,为了缓解深度学习模型工程落地性能问题,探索了Nvidia提供的triton部署框架,并在九数中台上完成线上部署,发现性能提升近337%!!(原服务单次访问模型推理时间175m......