Bert 模型学习

article/2025/9/15 14:26:31

一、Bert 模型

BERT 模型的全称是 BidirectionalEncoder Representations from Transformer,基于 Transformer 的双向编码器表示,是一个预训练的语言表征模型,它强调了不再像以往一样采用传统的单向语言模型或者把两个单向语言模型进行浅层拼接的方法进行预训练,而是采用新的 masked language model(MLM),以致能生成深度的双向语言表征。BERT 模型的目标是利用大规模无标注语料训练、获得文本的包含丰富语义信息的 Representation,即:文本的语义表示,然后将文本的语义表示在特定NLP任务中作微调,最终应用于该NLP任务。煮个栗子,BERT模型训练文本语义表示的过程就好比我们在高中阶段学习语数英、物化生等各门基础学科,夯实基础知识;而模型在特定NLP任务中的参数微调就相当于我们在大学期间基于已有基础知识、针对所选专业作进一步强化,从而获得能够应用于实际场景的专业技能。

BERT是一个预训练的模型,那么什么是预训练呢?

假设已有 A 训练集,先用 A 对网络进行预训练,在 A 任务上学会网络参数,然后保存以备后用,当来一个新的任务 B,采取相同的网络结构,网络参数初始化的时候可以加载 A 学习好的参数,其他的高层参数随机初始化,之后用 B 任务的训练数据来训练网络,当加载的参数保持不变时,称为 “frozen”,当加载的参数随着 B 任务的训练进行不断的改变,称为 “fine-tuning”,即更好地把参数进行调整使得更适合当前的 B 任务。

优点:当任务 B 的训练数据较少时,很难很好的训练网络,但是获得了 A 训练的参数,会比仅仅使用 B 训练的参数更优。

Bert 模型优点:

1)采用 MLM 对双向的 Transformers 进行预训练,以生成深层的双向语言表征。

2)预训练后,只需要添加一个额外的输出层进行 fine-tune,就可以在各种各样的下游任务中取得 state-of-the-art 的表现。在这过程中并不需要对 BERT 进行任务特定的结构修改。

二、Bert 模型的预训练任务

实际上预训练的概念在 CV(Computer Vision,计算机视觉)中已经是很成熟了,应用十分广泛。CV 中所采用的预训练任务一般是 ImageNet 图像分类任务,完成图像分类任务的前提是必须能抽取出良好的图像特征,同时 ImageNet 数据集有规模大、质量高的优点,因此常常能够获得很好的效果。

虽然 NLP 领域没有像 ImageNet 这样质量高的人工标注数据,但是可以利用大规模文本数据的自监督性质来构建预训练任务。因此 BERT 构建了两个预训练任务,分别是 Masked Language Model 和 Next Sentence Prediction。

1、Task #1: Masked LM

为了训练双向特征,这里采用了 Masked Language Model 的预训练方法,随机 mask 句子中的部分 token,然后训练模型来预测被去掉的 token。

具体操作是:

随机 mask 语料中 15% 的 token,然后将 masked token 位置输出的 final hidden vectors 送入 softmax,来预测 masked token。

这里也有一个小 trick,如果都用标记 [MASK] 代替 token 会影响模型,所以在随机 mask 的时候采用以下策略:

1)80% 的单词用 [MASK]token 来代替

my dog is hairy → my dog is [MASK]

2)10% 单词用任意的词来进行代替

my dog is hairy → my dog is apple

3)10% 单词不变

my dog is hairy → my dog is hairy

2、Task 2#: Next Sentence Prediction

为了让模型捕捉两个句子的联系,使模型具备理解长序列上下文的联系的能力,这里增加了 Next Sentence Prediction 的预训练方法,即给出两个句子 A 和 B,B 有一半的可能性是 A 的下一句话,训练模型来预测 B 是不是 A 的下一句话。

一些如问答、自然语言推断等任务需要理解两个句子之间的关系,而 MLM 任务倾向于抽取 token 层次的表征,因此不能直接获取句子层次的表征。为了使模型能够有能力理解句子间的关系,BERT 使用了 NSP 任务来预训练,简单来说就是预测两个句子是否连在一起。具体的做法是:对于每一个训练样例,我们在语料库中挑选出句子 A 和句子 B 来组成,50% 的时候句子 B 就是句子 A 的下一句(标注为 IsNext),剩下 50% 的时候句子 B 是语料库中的随机句子(标注为 NotNext)。接下来把训练样例输入到 BERT 模型中,用 [CLS] 对应的 C 信息去进行二分类的预测。

预训练任务总结

最后训练样例长这样:

Input1=[CLS] the man went to [MASK] store [SEP] he bought a gallon [MASK] milk [SEP]Label1=IsNextInput2=[CLS] the man [MASK] to the store [SEP] penguin [MASK] are flight ##less birds [SEP]Label2=NotNext

把每一个训练样例输入到 BERT 中可以相应获得两个任务对应的 loss,再把这两个 loss 加在一起就是整体的预训练 loss。(也就是两个任务同时进行训练)

可以明显地看出,这两个任务所需的数据其实都可以从无标签的文本数据中构建(自监督性质),比 CV 中需要人工标注的 ImageNet 数据集可简单多了。

三、Bert 的结构

BERT 模型是基于 Transformer 的 Encoder(编码器),主要模型结构就是 Transformer 的堆叠。
当我们组建好 Bert 模型之后,只要把对应的 token 喂给 BERT,每一层 Transformer 层吐出相应数量的 hidden vector,一层层传递下去,直到最后输出。模型就这么简单,专治花里胡哨,这大概就是谷歌的暴力美学。
在这里插入图片描述
2 种不同大小规模的 BERT 模型都有大量的 Encoder 层(论文里把这些层称为 Transformer Blocks):BASE 版本有 12 层 Encoder,Large 版本有 20 层 Encoder。同时,这些 BERT 模型也有更大的前馈神经网络(分别有 768 个和 1024 个隐藏层单元)和更多的 attention heads(分别有 12 个和 16 个),超过了原始 Transformer 论文中的默认配置参数(原论文中有 6 个 Encoder 层, 512 个隐藏层单元和 8 个 attention heads)。
Transformer 是组成 BERT 的核心模块,而 Attention 机制又是 Transformer 中最关键的部分

(1)Attention

Attention 机制的中文名叫“注意力机制”,顾名思义,它的主要作用是让神经网络把“注意力”放在一部分输入上,即:区分输入的不同部分对输出的影响。这里,我们从增强字/词的语义表示这一角度来理解一下 Attention 机制。
我们知道,一个字/词在一篇文本中表达的意思通常与它的上下文有关。比如:光看“鹄”字,我们可能会觉得很陌生(甚至连读音是什么都不记得吧),而看到它的上下文“鸿鹄之志”后,就对它立马熟悉了起来。因此,字/词的上下文信息有助于增强其语义表示。同时,上下文中的不同字/词对增强语义表示所起的作用往往不同。比如在上面这个例子中,“鸿”字对理解“鹄”字的作用最大,而“之”字的作用则相对较小。为了有区分地利用上下文字信息增强目标字的语义表示,就可以用到 Attention 机制
Attention 机制主要涉及到三个概念:Query、Key 和 Value。在上面增强字的语义表示这个应用场景中,目标字及其上下文的字都有各自的原始 Value,Attention 机制将目标字作为 Query、其上下文的各个字作为 Key,并将 Query 与各个 Key 的相似性作为权重,把上下文各个字的 Value 融入目标字的原始 Value 中。如下图所示,Attention 机制将目标字和上下文各个字的语义向量表示作为输入,首先通过线性变换获得目标字的 Query 向量表示、上下文各个字的 Key 向量表示以及目标字与上下文各个字的原始 Value 表示,然后计算 Query 向量与各个 Key 向量的相似度作为权重,加权融合目标字的 Value 向量和各个上下文字的 Value 向量,作为 Attention 的输出,即:目标字的增强语义向量表示
在这里插入图片描述

1)Self-Attention:

对于输入文本,我们需要对其中的每个字分别增强语义向量表示,因此,我们分别将每个字作为 Query,加权融合文本中所有字的语义信息,得到各个字的增强语义向量,如下图所示。在这种情况下,Query、Key 和 Value 的向量表示均来自于同一输入文本,因此,该 Attention 机制也叫 Self-Attention。
在这里插入图片描述

2)Multi-head Self-Attention

为了增强 Attention 的多样性,文章作者进一步利用不同的 Self-Attention 模块获得文本中每个字在不同语义空间下的增强语义向量,并将每个字的多个增强语义向量进行线性组合,从而获得一个最终的与原始字向量长度相同的增强语义向量,如下图所示。
在这里插入图片描述

(2)Transformer Encoder

在 Multi-headSelf-Attention 的基础上再添加一些“佐料”,就构成了大名鼎鼎的 Transformer Encoder。实际上,Transformer 模型还包含一个 Decoder 模块用于生成文本,但由于 BERT 模型中并未使用到 Decoder 模块,因此这里对其不作详述。下图展示了 Transformer Encoder 的内部结构,可以看到,Transformer Encoder 在 Multi-head Self-Attention 之上又添加了三种关键操作:1)残差连接(ResidualConnection):将模块的输入与输出直接相加,作为最后的输出。这种操作背后的一个基本考虑是修改输入比重构整个输出更容易(“锦上添花”比“雪中送炭”容易多了!)。这样一来,可以使网络更容易训练。2)Layer Normalization:对某一层神经网络节点作0均值1方差的标准化。3)线性转换:对每个字的增强语义向量再做两次线性变换,以增强整个模型的表达能力。这里,变换后的向量与原向量保持长度相同。
在这里插入图片描述

可以看到,Transformer Encoder 的输入和输出在形式上还是完全相同,因此,Transformer Encoder 同样可以表示为将输入文本中各个字的语义向量转换为相同长度的增强语义向量的一个黑盒

组装好 TransformerEncoder 之后,再把多个 Transformer Encoder 一层一层地堆叠起来,BERT 模型就大功告成了!

四、输入输出

在基于深度神经网络的NLP方法中,文本中的字/词通常都用一维向量来表示(一般称之为“词向量”);在此基础上,神经网络会将文本中各个字或词的一维词向量作为输入,经过一系列复杂的转换后,输出一个一维词向量作为文本的语义表示。特别地,我们通常希望语义相近的字/词在特征向量空间上的距离也比较接近,如此一来,由字/词向量转换而来的文本向量也能够包含更为准确的语义信息。因此,BERT模型的主要输入是文本中各个字/词的原始词向量,该向量既可以随机初始化,也可以利用Word2Vector等算法进行预训练以作为初始值;输出是文本中各个字/词融合了全文语义信息后的向量表示,如下图所示(为方便描述且与BERT模型的当前中文版本保持一致,本文统一以字向量作为输入):
在这里插入图片描述
从上图中可以看出,BERT 模型通过查询字向量表将文本中的每个字转换为一维向量,作为模型输入;模型输出则是输入各字对应的融合全文语义信息后的向量表示。此外,模型输入除了字向量,还包含另外两个部分:1)文本向量,该向量的取值在模型训练过程中自动学习,用于刻画文本的全局语义信息,并与单字/词的语义信息相融合;2)位置向量,由于出现在文本不同位置的字/词所携带的语义信息存在差异(比如:“我爱你”和“你爱我”),因此,BERT模型对不同位置的字/词分别附加一个不同的向量以作区分。最后,BERT模型将字向量、文本向量和位置向量的加和作为模型输入。

1、输入

bert 的输入部分是个线性序列,两个句子通过分隔符分割,最前面和最后增加两个标识符号。每个单词有三个embedding:位置信息 embedding,这是因为 NLP 中单词顺序是很重要的特征,需要在这里对位置信息进行编码;单词 embedding,这个就是我们之前一直提到的单词 embedding;第三个是句子 embedding,因为前面提到训练数据都是由两个句子构成的,那么每个句子有个句子整体的 embedding 项对应给每个单词。把单词对应的三个 embedding 叠加,就形成了 Bert 的输入。

在这里插入图片描述
在 BERT 中,输入的向量是由三种不同的 embedding 求和而成,分别是:

1)token embedding:单词本身的向量表示。token 是指将单词划分成一组有限的公共子词单元,能在单词的有效性和字符的灵活性之间取得一个折中的平衡。
2)position embedding:将单词的位置信息编码成特征向量。因为我们的网络结构没有RNN 或者LSTM,因此我们无法得到序列的位置信息,所以需要构建一个position embedding。构建position embedding有两种方法:BERT是初始化一个position embedding,然后通过训练将其学出来;而Transformer是通过制定规则来构建一个position embedding
3)segment embedding:用于区分两个句子的向量表示。这个在问答等非对称句子中是用区别的。

2、输出

Bert 的输出是由四部分组成:

(1)last_hidden_state:shape 是(batch_size, sequence_length, hidden_size),hidden_size=768,它是模型最后一层输出的隐藏状态(通常用于命名实体识别)。
(2)pooler_output:shape是(batch_size, hidden_size),这是序列的第一个token(classification token)的最后一层的隐藏状态,它是由线性层和 Tanh 激活函数进一步处理的(通常用于句子分类,至于是使用这个表示,还是使用整个输入序列的隐藏状态序列的平均化或池化,视情况而定)。
(3)hidden_states:这是输出的一个可选项,如果输出,需要指定 config.output_hidden_states=True,它也是一个元组,它的第一个元素是 embedding,其余元素是各层的输出,每个元素的形状是(batch_size, sequence_length, hidden_size)。
(4)attentions:这也是输出的一个可选项,如果输出,需要指定 config.output_attentions=True,它也是一个元组,它的元素是每一层的注意力权重,用于计算 self-attention heads 的加权平均值。


http://chatgpt.dhexx.cn/article/72L5SlsG.shtml

相关文章

【理论篇】是时候彻底弄懂BERT模型了(收藏)

引言 本文对BERT模型的理论进行了一个非常详尽的解释,相信看完本篇文章后,你对BERT模型的理解会上升🚀一个层次。 本文是理论篇,下篇是实战篇。 BERT的基本思想 BERT如此成功的一个原因之一是它是基于上下文(context-based)的嵌…

Hive !!!

文章目录 Hive数据处理方法论step1 了解产品/运营的需求step2 数据收集(数据准备)step3 数据处理(数据调研)step4 数据分析 Hive背景Hive简介引入原因安装hive注意事项一些代码Hive SQL VS SQL Hive的数据类型数据类型Hive架构 Hi…

Shark简介

简介 Shark是一个新的数据分析系统,在集群上进行查询处理和复杂分析。Shark使用一种新的分布式内存抽象,为SQL查询和复杂分析函数提供了统一的运行引擎,并能够有效的容错。这种新的分布式内存抽象使得shark执行SQL查询的速度比Hive快100倍&a…

Vue3中shallowReactive 与 shallowRef 的用法

shallowReactive 与 shallowRef shallowReactive:只处理对象最外层属性的响应式(浅响应式)。 shallowRef:只处理基本数据类型的响应式, 不进行对象的响应式处理。 什么时候使用? 如果有一个对象数据,结构比较深, 但…

2018华为软挑--模拟退火+FF解决装箱问题【C++代码】

算法简介: 装箱问题是一个NP完全问题,求解全局最优解有很多种方法:遗传算法、禁忌搜索算法、蚁群算法、模拟退火算法等等,本次使用模拟退火,它的优点是在参数合适的情况下基本上可以100%得到全局最优解,缺点…

2020华为软挑热身赛代码开源-思路大起底(华为软件精英挑战赛编程闯关)

本文首发于个人公众号【两猿社】,后台回复【华为】,获取完整开源代码链接。 昵称:lou_shang_shi_bian_tai 成绩:0.032 社长没有针对硬件做任何优化,热身赛成绩也一般。但有些比赛的trick我想与大家一起分享,希望对继续…

2021华为软挑-成渝复赛复盘

成渝赛区 团队名:newWorld 初赛 rank 22,复赛 rank 22。 github源码:https://github.com/Yin-Freedom/codecraft_2021 赛题介绍 赛题网址:https://competition.huaweicloud.com/advance/1000041380/circumstance 本次赛题来源…

2020华为软挑热身赛

基于高斯贝叶斯分类的C优化器 摘要:2020华为软件挑战赛如期举行,本次挑战赛分为热身赛、初赛、复赛、总决赛4个部分,其中热身赛结合当前机器学习中分类问题以及鲲鹏服务器性能相关来出题。为了解决该问题,达到算法准确率和程序时…

华为软挑赛2023-初赛笔记

前言 比赛介绍 官方链接: 2023华为软件精英挑战赛——普朗克计划 (huaweicloud.com) 赛题介绍 场景介绍 官方赛题介绍: 2023华为软件精英挑战赛初赛赛题及相关材料发布_2023华为软件精英挑战赛_华为云论坛 (huaweicloud.com) 比赛场景如图所示 简单来说,在一…

【C++】2018华为软挑:模拟退火+贪心FF解决装箱问题

本文的主要工作是补充这篇博客的缺失代码,使之能够运行。 2018华为软挑--模拟退火FF解决装箱问题【C代码】_小马哥MAX的博客-CSDN博客算法简介: 装箱问题是一个NP完全问题,求解全局最优解有很多种方法:遗传算法、禁忌搜索…

2020华为软挑热身赛-这些坑我帮你踩过了(华为软件精英挑战赛编程闯关)

本文始发于个人公众号【两猿社】。 声明,为保证比赛公平,本文不会提供比赛源码,仅提供思路与踩坑经验。 他来了,他来了,他带着面试绿卡走来了。 他来了,他来了,他带着20w大奖走来了。 一年一度…

2018华为软挑参赛体验

第一次接触到这个比赛应该是研究生刚入学的时候,在教研室看到了师姐的一份简历,上面就有华为软挑的参赛经历。研一利用空余时间加强C和STL的学习,看完了《C primer》《Effective STL》,自己也写了一些demo,感觉这个比赛…

2022华为软挑编程问题报错总结

for i in number_feature: TypeError: ‘int’ object is not iterable的错误 错误原因:是因为在python里,整型(int)数据是不能直接用于迭代的,而是应该用range()函数 改为如下图:

2021华为软挑部分答疑——哪些你有错却总是找不到的地方,我来带你找啦(含标准输入代码)

前期工作: 2021华为软挑初探——代码实现 2021华为软挑再探——代码实现 1 关于打包 在windows系统下,先把你写的程序写在src里面的CodeCraft-2021里面 然后在这个页面,将这三个文件压缩就可以上传啦: 2 关于标准输入 标准输…

华为软挑2019

参加软挑的一些感悟 写在前边的话 我本科一直在做嵌入式相关的项目,这是第一次参加软件类的竞赛,不得不说过程确实很刺激,最后止步杭厦赛区50强也很是遗憾,明明很接近,最后输在了代码效率上,本地成绩很好的 python代码 ,上传测评运行时间超限(官测环境比本地性能好&…

2021华为软挑初探——代码实现

其他工作: 2021华为软挑部分答疑——哪些你有错却总是找不到的地方,我来带你找啦(含标准输入代码) 2021华为软挑再探——代码实现 这几天华为软挑好多人也是做的热火朝天,作为一个渣渣小孙也来探探,不探…

2020华为软挑总结

文章目录 一、热身赛编程闯关:评价标准:问题分析 二、初赛问题描述评价标准:问题分析思路一:思路二:思路三:针对思路三的提速: 最终结果: 三、code记录初赛两篇不错的总结三、复活赛…

2022华为软挑比赛(初赛笔记)

文章目录 2022华为软挑(初赛笔记)1. 赛题要求2. 解决方案2.1 挑选适合的边缘节点2.2 第一轮:最大分配2.3 第二轮:均值分配 总结 本文仓库地址: Github-CodeCraft-2022 2022华为软挑(初赛笔记) …

2023华为软件精英挑战赛笔记心得(Python实现)

第一次参加华为软挑,问了周围一圈人没人组队,看了眼题目,感觉挺有意思的,就打算自己写来跑一下,不求分数,主要是想学点东西,顺便记录一下。(最后跑了195w,自己的能力也就…

2021华为软件精英挑战总结

2021华为软挑32强总结 今年的软挑最终止步于粤港澳赛区第16名,总成本为16亿3979万6349,赛区第一名总成本为15亿3903万4817。 虽然没进入决赛,但是拿到了华为面试直通卡,也喜提广州一日游,算不虚此行了。决赛虽然还在继…