当前位置:   article > 正文

BERT原理详细介绍

bert

目录

1. 前言

1.1 Word2Vec和BERT对比

1.1.1 word2vec缺点:

1.1.2 bert

1.2 BERT简介

2. ELMO介绍

2.1 为什么要说到ELMO呢?

2.2 ELMO的损失函数:

2.3 ELMO的核心就是深层,双向的语言模型。

3. 对BERT的理解

4.Bert

4.1 bert的结构

4.2 bert输入表示

4.3 如何训练BERT

4.3.1 Masked LM

4.3.2 预测两个句子是否连接在一起

4.4 bert常见应用

4.5 bert的其他应用

4.6 BERT代码安装部署

4.6.1 预训练的模型(Pre-trained models)

4.6.2 Fine-tuning with BERT

4.7 Bert设置说明

4.7.1 Masking


1. 前言

bert 的本质是学习单词的词向量表达。那我们先来回顾 word2vec,和 bert 预训练产生词向量的不同吧!

1.1 Word2Vec和BERT对比

1.1.1 word2vec缺点:

  • 学习到的是静态词向量,与上下文无关,如 “ I like to eat Apple" 和 ”Apple is a high-tech company in the United States“, 很显然这两个apple的意思不一样,但在Word2vec看来,它们是一样的词向量。
  • 对于训练的句子,只利用了句子的单向信息:如:今天 天气 真好,要预测 ”真好“ 概率时,根据语言模型概率公式: p(真好)= p(天气 | 今天,天气),预测 p(天气) = p(天气| 今天), 就是说预测”天气“时不能利用”真好“这个信息,因为这个词在”天气“后面。

1.1.2 bert

完美的解决了这上述两个缺点,可以学习动态的基于上下文的词向量;利用句子的双向信息。

1.2 BERT简介

BERT能够同时利用前后两个方向的信息,而ELMo和GPT只能使用单个方向的。

BERT使用的是Transformer模型,使用的是transformer的encoder部分。那它是怎么解决语言模型只能利用一个方向的信息的问题呢?答案是它的pretraining训练的不是普通的语言模型,而是Mask语言模型。

BERT模型具有以下两个特点:

第一,是这个模型非常的深,12层,并不宽(wide),中间层只有1024,而之前的Transformer模型中间层有2048。这似乎又印证了计算机图像处理的一个观点——深而窄 比 浅而宽 的模型更好。

第二,MLM(Masked Language Model)同时利用左侧和右侧的词语,这个在ELMo上已经出现了,绝对不是原创。但是解决双向问题(上下文信息)。

BERT目前已经刷新的11项自然语言处理任务的最新记录包括:将GLUE基准推至80.4%(绝对改进7.6%),MultiNLI准确度达到86.7% (绝对改进率5.6%),将SQuAD v1.1问答测试F1得分纪录刷新为93.2分(绝对提升1.5分),超过人类表现2.0分。

2. ELMO介绍

2.1 为什么要说到ELMO呢?

因为它首先尝试解决word2vec的缺点。

总结起来:
在这里插入图片描述
即:

1. 深度双向lstm,特点:deep,为什么要做深层??类似于图像识别一样,网络层越深,越能提取到图片中物体的具体信息。放到文本特征提取上,网络层越深,那么能提取的特征也依次具体化: 词特征 --> 语法特征 --> 语义特征。

                    在这里插入图片描述

2. 保留每一层lstm的隐层状态,包括正向和反向 [ →hi | hi←]

3. 最终某个单词的词向量是 该单词位置上所有隐层状态的加权和

举个栗子:

在这里插入图片描述

2.2 ELMO的损失函数:

在这里插入图片描述

2.3 ELMO的核心就是深层双向的语言模型。

这个模型有些致命的缺点:

  • 不完全双向:elmo虽然是双向,但是这个双向不是真正意义上的双向,它是先训练一个前向的RNN,再训练一个后向的RNN,这两个RNN本质上是独立的。对于一个序列,前向遍历一遍获得左边的LSTM隐层输出,后向遍历一遍获得右边的LSTM隐层输出,最后得到的隐层向量直接拼接(前向的hidden state + 后向的hidden state = 总的hidden state,+是concat),并且在最后的Loss function中也是前向和后向的loss function直接相加,并非完全同时的双向计算。
  • 自己看见自己:“深层”,“双向” 就容易自己看见自己。以传统RNN 为例,假如输入 A,B,C,D,我们要预测 C,则 经典语言模型公式: P(C)= P(C | A,B),可以看到 C 是用不到D 信息的。但在EMLO中,情况就不一样了,如图:

在这里插入图片描述

  • 从下往上看
  • 第一层:词向量层
  • 第二层,预测 C 时,前向用到了 A,B信息,后向用到了D信息,所以第二层只有 A,B|D信息,这时 没有出现自己看见自己情况,即C没有参考C的信息
  • 第三层,预测 C 时,前向用到了 BCD, A|CD 信息,后向用到了 ABC 的信息,所以综合一下 第三层用到了 ABCD的信息,那么 预测C 时,就会参考到 C 的信息。

3. 对BERT的理解

BERT 的五个关键词 Pre-training、Deep、Bidirectional、Transformer、Language Understanding 分别是什么意思?

《A Neural Probabilistic Language Model》这篇论文讲的 Language Model,严格讲是语言生成模型(Language Generative Model),预测语句中下一个将会出现的词汇。语言生成模型能不能直接移用到其它 NLP 问题上去?

譬如,淘宝上有很多用户评论,能否把每一条用户转换成评分?-2、-1、0、1、2,其中 -2 是极差,+2 是极好。假如有这样一条用户评语,“买了一件鹿晗同款衬衫,没想到,穿在自己身上,不像小鲜肉,倒像是厨师”,请问这条评语,等同于 -2,还是其它?

语言生成模型,能不能很好地解决上述问题?进一步问,有没有 “通用的” 语言模型,能够理解语言的语义,适用于各种 NLP 问题?BERT 这篇论文的题目很直白,《BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding》,一眼看去,就能猜得到这篇文章会讲哪些内容。

这个题目有五个关键词,分别是 Pre-training、Deep、Bidirectional、Transformers、和 Language Understanding。其中 pre-training 的意思是,作者认为,确实存在通用的语言模型,先用文章预训练通用模型,然后再根据具体应用,用 supervised 训练数据,精加工(fine tuning)模型,使之适用于具体应用。为了区别于针对语言生成的 Language Model,作者给通用的语言模型,取了一个名字,叫语言表征模型 Language Representation Model。

能实现语言表征目标的模型,可能会有很多种,具体用哪一种呢?作者提议,用 Deep Bidirectional Transformers 模型。假如给一个句子 “能实现语言表征[mask]的模型”,遮盖住其中“目标”一词。从前往后预测[mask],也就是用“能/实现/语言/表征”,来预测[mask];或者,从后往前预测[mask],也就是用“模型/的”,来预测[mask],称之为单向预测 unidirectional。单向预测,不能完整地理解整个语句的语义。于是研究者们尝试双向预测。把从前往后,与从后往前的两个预测,拼接在一起 [mask1/mask2],这就是双向预测 bi-directional。细节参阅《Neural Machine Translation by Jointly Learning to Align and Translate》。

BERT 的作者认为,bi-directional 仍然不能完整地理解整个语句的语义,更好的办法是用上下文全向来预测[mask],也就是用 “能/实现/语言/表征/../的/模型”,来预测[mask]。BERT 作者把上下文全向的预测方法,称之为 deep bi-directional。如何来实现上下文全向预测呢?BERT 的作者建议使用 Transformer 模型。这个模型由《Attention Is All You Need》一文发明。

4.Bert

现在才开始介绍我们的主角:bert

4.1 bert的结构

这里需要用到transformer的知识,大家可以看transformer
Transformer的网络架构如图所示,Transformer是一个encoder-decoder的结构,由编码器和解码器构成。图中的左侧部分为编码器,由若干个(论文中6个)encoder堆叠而成,
右侧部分为解码器,由若干个(论文中6个)decoder堆叠而成。

在这里插入图片描述

Bert只用到了Transformer的编码器部分,它的结构图如下:
其中Trm表示一个Transformer的编码器部分

在这里插入图片描述

真实应用中Trm 不止图中的 2 个,通常有两种结构
在这里插入图片描述
L表示网络的层数(即Transformer 编码器的数量),A表示Multi-Head Attention中self-Attention的头数,H是隐层单元的维度。

4.2 bert输入表示

BERT的输入表示如下图所示。比如输入的是两个句子”my dog is cute”,”he likes playing”。后面会解释为什么需要两个句子。这里采用类似GPT的两个句子的表示方法,首先会在第一个句子的开头增加一个特殊的Token [CLS],在cute的后面增加一个[SEP]表示第一个句子结束,在##ing后面也会增加一个[SEP]。注意这里的分词会把”playing”分成”play”和”##ing”两个Token,这种把词分成更细粒度的Word Piece(Wu et al., 2016)的方法是一种解决未登录词的常见办法,后面的代码部分也会简单介绍。接着对每个Token进行3个Embedding:词的Embedding;位置的Embedding和Segment的Embedding。词的Embedding大家都很熟悉了,而位置的Embedding和词类似,把一个位置(比如2)映射成一个低维稠密的向量。而Segment只有两个,要么是属于第一个句子(segment)要么属于第二个句子,不管哪个句子,它都对应一个Embedding向量。同一个句子的Segment Embedding是共享的,这样它能够学习到属于不同Segment的信息。对于情感分类这样的任务,只有一个句子,因此Segment id总是0;而对于Entailment任务,输入是两个句子,因此Segment是0或者1。

BERT模型要求有一个固定的Sequence的长度,比如128。如果不够就在后面padding,否则就截取掉多余的Token,从而保证输入是一个固定长度的Token序列,后面的代码会详细的介绍。第一个Token总是特殊的[CLS],它本身没有任何语义,因此它会(必须)编码整个句子(其它词)的语义。

在这里插入图片描述

bert将输入句子转化为词向量,是经过了3 个Embedding 的加和, 即
input_embed = Token_embed + Sentence_embed + Position_embed.
源码是:

在这里插入图片描述

在这里插入图片描述

maxLen:批训练时,最大句子长度。d_model:词嵌入的维度,n_segments:表示输入多少句话,一般最大取2。

具体如下:

  • 使用WordPiece嵌入(Wu et al., 2016)和30,000个token的词汇表。用##表示分词。
  • 使用学习的positional embeddings,支持的序列长度最多为512个token。
  • 每个序列的第一个token始终是特殊分类嵌入([CLS])。对应于该token的最终隐藏状态(即,Transformer的输出)被用作分类任务的聚合序列表示。对于非分类任务,将忽略此向量。
  • 句子对被打包成一个序列。以两种方式区分句子。首先,用特殊标记([SEP])将它们分开。其次,添加一个learned sentence A嵌入到第一个句子的每个token中,一个sentence B嵌入到第二个句子的每个token中。
  • 对于单个句子输入,只使用 sentence A嵌入。
     

用pytorch调用模型的话,我们只需要输入:

  1. input_ids:一个形状为[batch_size, sequence_length]的 torch.LongTensor,在词汇表中包含单词的token索引, 注意 在句子首尾分别加了 [cls] 和 [sep] 的 索引
  2. segment_ids :形状[batch_size, sequence_length]的可选 torch.LongTensor,在0, 1中选择token类型索引。类型0对应于句子A,类型1对应于句子B。如 [0,0,0,0,0,1,1,1,1,1], 0代表第一个句子A, 1代表第二个句子B,默认全为0
  3. input_mask:一个可选的 torch.LongTensor,形状为[batch_size, sequence_length],索引在0, 1中选择。0 是 padding 的位置,1是没有padding的字

4.3 如何训练BERT

与Peters et al. (2018) 和 Radford et al. (2018)不同,论文不使用传统的从左到右或从右到左的语言模型来预训练BERT。相反,使用两个新的无监督预测任务对BERT进行预训练。

这个模型的核心是聚焦机制,对于一个语句,可以同时启用多个聚焦点,而不必局限于从前往后的,或者从后往前的,序列串行处理。不仅要正确地选择模型的结构,而且还要正确地训练模型的参数,这样才能保障模型能够准确地理解语句的语义。BERT 用了两个步骤,试图去正确地训练模型的参数。第一个步骤是把一篇文章中,15% 的词汇遮盖,让模型根据上下文全向地预测被遮盖的词。假如有 1 万篇文章,每篇文章平均有 100 个词汇,随机遮盖 15% 的词汇,模型的任务是正确地预测这 15 万个被遮盖的词汇。通过全向预测被遮盖住的词汇,来初步训练 Transformer 模型的参数。然后,用第二个步骤继续训练模型的参数。譬如从上述 1 万篇文章中,挑选 20 万对语句,总共 40 万条语句。挑选语句对的时候,其中 2*10 万对语句,是连续的两条上下文语句,另外 2*10 万对语句,不是连续的语句。然后让 Transformer 模型来识别这 20 万对语句,哪些是连续的,哪些不连续。

这两步训练合在一起,称为预训练 pre-training。训练结束后的 Transformer 模型,包括它的参数,是作者期待的通用的语言表征模型。

4.3.1 Masked LM

从直觉上看,研究团队有理由相信,深度双向模型比left-to-right 模型或left-to-right and right-to-left模型的浅层连接更强大。遗憾的是,标准条件语言模型只能从左到右或从右到左进行训练,因为双向条件作用将允许每个单词在多层上下文中间接地“see itself”。

为了训练一个深度双向表示(deep bidirectional representation),研究团队采用了一种简单的方法,即随机屏蔽(masking)部分输入token,然后只预测那些被屏蔽的token。论文将这个过程称为“masked LM”(MLM),尽管在文献中它经常被称为Cloze任务(Taylor, 1953)。

在这个例子中,与masked token对应的最终隐藏向量被输入到词汇表上的输出softmax中,就像在标准LM中一样。在团队所有实验中,随机地屏蔽了每个序列中15%的WordPiece token。与去噪的自动编码器(Vincent et al., 2008)相反,只预测masked words而不是重建整个输入
掩码语言模型的提出就是为了防止:自己看见自己。
Masked Language Model(MLM)是指在训练的时候随机从输入语料上mask掉一些单词,然后通过它的上下文预测该单词,该任务非常像我们在中学时期经常做的完形填空。这一点是非常不同于RNN语言模型的。比如输入 A, B,C

  1. RNN模型
    p(ABC) = P(A)*p(B|A)*p(C|AB)
  2. Bert
    假如把B给 mask掉,则 P(ABC) = P(B| AC)

为了使模型更加稳定,作者不单单是随机mask掉 15%的单词,然后让BERT来预测这些Mask的词,通过调整模型的参数使得模型预测正确的概率尽可能大,这等价于交叉熵的损失函数。这样的Transformer在编码一个词的时候会(必须)参考上下文的信息。

虽然这确实能让团队获得双向预训练模型,但这种方法有两个缺点首先,预训练和finetuning之间不匹配,因为在finetuning期间从未看到[MASK]token。为了解决这个问题,团队并不总是用实际的[MASK]token替换被“masked”的词汇。相反,训练数据生成器随机选择15%的token。随机mask语料中15%的token,对于[Mask]这个符号,由于在测试集中不存在,为了减轻训练和预测之间的不匹配,作者按一定的比例在需要预测的token上动了手脚,如:my dog is hairy,则:在15%的单词当中

  • 有80%的概率用“[mask]”标记来替换——my dog is [MASK]
  • 有10%的概率用随机采样的一个单词来替换——my dog is apple
  • 有10%的概率不做替换——my dog is hairy

Transformer encoder不知道它将被要求预测哪些单词或哪些单词已被随机单词替换,因此它被迫保持每个输入token的分布式上下文表示。此外,因为随机替换只发生在所有token的1.5%(即15%的10%),这似乎不会损害模型的语言理解能力。

使用MLM的第二个缺点是每个batch只预测了15%的token,这表明模型可能需要更多的预训练步骤才能收敛。团队证明MLM的收敛速度略慢于 left-to-right的模型(预测每个token),但MLM模型在实验上获得的提升远远超过增加的训练成本。

这样做的好处是,BERT并不知道[MASK]替换的是哪一个词,而且任何一个词都有可能是被替换掉的,比如它看到的apple可能是被替换的词。这样强迫模型在编码当前时刻的时候不能太依赖于当前的词,而要考虑它的上下文,甚至更加依赖上下文进行”纠错”。比如上面的例子模型在编码apple是根据上下文my dog is应该把apple(部分)编码成hairy的语义而不是apple的语义。

4.3.2 预测两个句子是否连接在一起

“下一句预测”(next sentence prediction)任务。

许多重要的下游任务,如问答(QA)和自然语言推理(NLI)都是基于理解两个句子之间的关系,这并没有通过语言建模直接获得。

在为了训练一个理解句子的模型关系,预先训练一个二进制化的下一句预测任务,这一任务可以从任何单语语料库中生成。具体地说,当选择句子A和B作为预训练样本时,B有50%的可能是A的下一个句子,也有50%的可能是来自语料库的随机句子。例如:

Input = [CLS] the man went to [MASK] store [SEP]

he bought a gallon [MASK] milk [SEP]

Label = IsNext

Input = [CLS] the man [MASK] to the store [SEP]

penguin [MASK] are flight ##less birds [SEP]

Label = NotNext

团队完全随机地选择了NotNext语句,最终的预训练模型在此任务上实现了97%-98%的准确率。

特殊字符也需要编码。如下图左边的句子是应该连在一起的情况,但是右边的两个句子是不应该连在一起的情况。[cls]在进行编码的时候会考虑右边的所有结果,在编码时会判断是否应该连在一起。在对[cls]进行编码的时候也需要做一个分类任务,就是一个二分类任务,输出结果是判断两个句子是否应该连在一起。

BERT在第一句前会加一个[CLS]标志,最后一层该位对应向量可以作为整句话的语义表示,从而用于下游的分类任务等。

为什么选它呢,因为与文本中已有的其它词相比,这个无明显语义信息的符号会更“公平”地融合文本中各个词的语义信息,从而更好的表示整句话的语义。

4.3.2.1 bert句子级别任务

(1) 假如我们要做一个分类任务

  • 利用RNN的话,我们只需要最后一个隐层状态,再它的基础上搭一个线性分类器就行,因为最后一个隐层状态h,就代表了整句话的意思,如图

在这里插入图片描述

  • 而 transformer encoder 不一样,如图:y1, y2, y3,y4只能分别代表 单词 w1,w2,w3,w4在上下文中的意思,而不能代表整句话的意思,因此我们无从搭分类器。

在这里插入图片描述

  • bert 是如何解决这个问题的呢??, 它在输入句子的前面加了一个 [CLS] 符号,我们可以把这个符号看做是整个输入句子的象征, 那么它对应的输出C就可以代表整句话的意思了,如图:

在这里插入图片描述

(2) 假如我们要做一个问答系统,也就是输入有两句话,那么bert又做了什么呢??

–为什么要提出这个预训练任务呢,主要也是很多譬如问答、推理之类的任务,更多的是要学习句子之间的关系,这是语言模型无法做到的,因为语言模型根据token预测token,是在句子内部进行学习的

bert在训练时会判断这两个输入句子是否是连续的,相关的,也就是它会做一个二分类任务,若两个句子是挨在一起的,那么预测为1,否则为0。每个句子的结尾以 [SEP] 作为分隔符。

在这里插入图片描述

那么句子如何选取呢??训练的时候,输入到模型的第二个句子会以50%的可能从全部文本中随机选取,剩下50%的可能从紧挨着第一个句子的文本中选取

这样看来,模型就有两个损失函数了,一个是做完形填空时产生的,一个是做二分类时产生的,两个损失函数之就是bert总的损失函数了。源码片段:

在这里插入图片描述

4.4 bert常见应用

  • 情感分析: 提取 [CLS] 的输出 C,在其上搭分类器,如逻辑回归,SVM等,做fine-tuning
  • 特征提取:提取 每个单词的词向量,再运用到其他任务中。
    对于测试集中的一句话如:Help prince Meyuko ?, 我们把它放到已经训练完的Bert上面,那么我们就可以得到这句话每层的输出了, 也就是每层每个单词的上下文表达,图中每一列由黄到红就是每个单词不同层面的上下文表达。

在这里插入图片描述

至于哪一层效果最好,我们有这个实验

在这里插入图片描述

效果最好的是:最后四层的拼接。

4.5 bert的其他应用

在这里插入图片描述

图中:我们的面向特定任务的模型是将BERT与一个额外的输出层结合而形成的,因此需要从头开始学习最小数量的参数。在这些任务中,(a)和(b)是序列级任务,而(c)和(d)是token级任务。在图中,E表示输入嵌入,Ti表示tokeni的上下文表示,[CLS]是用于分类输出的特殊符号,[SEP]是用于分隔非连续token序列的特殊符号。

MNLI(Multi-Genre Natural Language Inference):给定一对句子,目标是预测第二句子和第一个句子是相关的、无关的还是矛盾的。
QQP(Quora Question Pairs):判断两个问句是否是同一个意思。
QNLI(Question Natural Language Inference):样本是(question,sentence)在一段文本中sentence是否是question的答案。
STS-B(Semantic Textual Similarity Benchmark):给出一对句子, 使用1~5的评分评价两者在语义上的相似程度。
MRPC (Microsoft Research Paraphrase Corpus):句子对来源于对同一条新闻的评论. 判断这一对句子在语义上是否相同。
RTE(Recognizing Textual Entailment):是一个二分类问题, 类似于MNLI, 但是数据量少很多。

SST-2(The Stanford Sentiment Treebank):单句的二分类问题, 句子来源于人们对一部电影的评价, 判断这个句子的情感。
CoLA (The Corpus of Linguistic Acceptability):单句的二分类问题, 判断一个英文句子在语法上是不是可接受的。

SQuAD(Standford Question Answering Dataset):给定一个问题和一个来自包含答案的Wikipedia段落,任务是预测答案在段落中所在的位置。
CoNLL-2003 NER命名实体识别任务,应该是大家最熟悉的了,预测每个字的标签是什么。

总体来说对于(a)(b)中的任务,我们取得的是最终CLS位置的输出C。对于(c)中的任务主要是预测start和end标记所在的最大值,且是start的id值小于end的id值,其中start是答案所在段落中的起始位置,end是结束位置。对于(d)NER任务,自然是取得每一个单词的输出的表达,后面再接一个CRF。

4.6 BERT代码安装部署

Google提供的BERT代码在https://github.com/google-research/bert,我们可以直接git clone下来。注意运行它需要Tensorflow 1.11及其以上的版本,低版本的Tensorflow不能运行。

4.6.1 预训练的模型(Pre-trained models)

由于从头开始(from scratch)训练需要巨大的计算资源,因此Google提供了预训练的模型(的checkpoint),目前包括英语、汉语和多语言3类模型,而英语又包括4个版本:

BERT-Base, Uncased 12层,768个隐单元,12个Attention head,需要训练的模型参数总数是 12 * 768 * 12 = 110M参数
BERT-Large, Uncased 24层,1024个隐单元,16个head,340M参数
BERT-Base, Cased 12层,768个隐单元,12个Attention head,110M参数
BERT-Large, Uncased 24层,1024个隐单元,16个head,340M参数。
Uncased的意思是保留大小写,而cased是在预处理的时候都变成了小写。

对于汉语只有一个版本:BERT-Base, Chinese: 包括简体和繁体汉字,共12层,768个隐单元,12个Attention head,110M参数。另外一个多语言的版本是BERT-Base, Multilingual Cased (New, recommended),它包括104种不同语言,12层,768个隐单元,12个Attention head,110M参数。它是用所有这104中语言的维基百科文章混在一起训练出来的模型。所有这些模型的下载地址都在https://github.com/google-research/bert#pre-trained-models。

常用的中文汉字有 3500 个,这些字组合成词汇,中文词汇数量高达 50 万个。假如词向量的维度是 512,那么语言模型的参数数量,至少是 512 * 50万 = 256M。模型参数数量这么大,必然需要海量的训练语料。从哪里收集这些海量的训练语料?《A Neural Probabilistic Language Model》这篇论文说,每一篇文章,天生是训练语料。难道不需要人工标注吗?回答,不需要。

这么多版本我们应该选择哪一个呢?如果我们处理的问题只包含英文,那么我们应该选择英语的版本(模型大效果好但是参数多训练慢而且需要更多内存/显存)。如果我们只处理中文,那么应该使用中文的版本。如果是其他语言就使用多语言的版本。

在压缩包里面有三类文件:

  • A TensorFlow checkpoint (bert_model.ckpt) 总共三个文件,包含的是一些预训练参数
  • A vocab file (vocab.txt) 保存的是当前模型用到的所有的词
  • A config file (bert_config.json) 包含BERT的配置,模型用到的参数

4.6.2 Fine-tuning with BERT

用bert来做一个fine-tuning。由于MRPC中数据集没有那么多,方面进行学习和测试,这里我们已GLUE的MRPC为例子,我们首先需要下载预训练的模型然后解压。下载GLUE数据好像需要代理,这里提供一个国内我已经下载好的数据,https://download.csdn.net/download/one_super_dreamer/12264680

需要下载的有三个,第一个是bert训练好的模型,第二个是bert-master,第三个是fine-tuning用的数据MRPC,我的目录结构如下所示:,我是用的是pycharm环境。

接下来就可以运行如下命令来进行Fine-Tuning了:

  1. python run_classifier.py \
  2. --task_name=MRPC \
  3. --do_train=true \
  4. --do_eval=true \
  5. --data_dir=$GLUE_DIR/MRPC \
  6. --vocab_file=$BERT_BASE_DIR/vocab.txt \
  7. --bert_config_file=$BERT_BASE_DIR/bert_config.json \
  8. --init_checkpoint=$BERT_BASE_DIR/bert_model.ckpt \
  9. --max_seq_length=128 \
  10. --train_batch_size=8 \
  11. --learning_rate=2e-5 \
  12. --num_train_epochs=3.0 \
  13. --output_dir=/tmp/mrpc_output/

这里简单的解释一下参数的含义,在后面的代码阅读里读者可以更加详细的了解其意义。

  • task_name 任务的名字,这里我们Fine-Tuning MRPC任务
  • do_train 是否训练,这里为True
  • do_eval 是否在训练结束后验证,这里为True
  • data_dir 训练数据目录,配置了环境变量后不需要修改,否则填入绝对路径
  • vocab_file BERT模型的词典
  • bert_config_file BERT模型的配置文件
  • init_checkpoint Fine-Tuning的初始化参数
  • max_seq_length Token序列的最大长度,这里是128
  • train_batch_size batch大小,对于普通8GB的GPU,最大batch大小只能是8,再大就会OOM
  • learning_rate
  • num_train_epochs 训练的epoch次数,根据任务进行调整
  • output_dir 训练得到的模型的存放目录

这里最常见的问题就是内存不够,通常我们的GPU只有8G作用的显存,因此对于小的模型(bert-base),我们最多使用batchsize=8,而如果要使用bert-large,那么batchsize只能设置成1。运行结束后可能得到类似如下的结果:

  1. ***** Eval results *****
  2.   eval_accuracy = 0.845588
  3.   eval_loss = 0.505248
  4.   global_step = 343
  5.   loss = 0.505248

大家可以对不同的任务进行训练测试,对于中文模型会在后面的文章里面讲解。
 

4.7 Bert设置说明

4.7.1 Masking

有两种masking方法:

(1)WordPiece token masking

例如:Input Text: the man jumped up , put his basket on phil ##am ##mon ' s head Original       

    Masked Input: [MASK] man [MASK] up , put his [MASK] on phil [MASK] ##mon ' s head

(2)Whole word masking

例如:Whole Word Masked Input: the man [MASK] up , put his basket on [MASK] [MASK] [MASK] ' s head

 

在Bert中,是可以设置使用哪一种的。

 

 

推荐相关文章链接:

https://blog.csdn.net/one_super_dreamer/article/details/105181690?spm=1001.2014.3001.5502

http://fancyerii.github.io/2019/03/09/bert-theory/

https://blog.csdn.net/qq_39521554/article/details/83062188

https://blog.csdn.net/one_super_dreamer/article/details/105206692

https://blog.csdn.net/one_super_dreamer/article/details/105206692

https://www.pianshen.com/article/31881994004/

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/352705
推荐阅读
相关标签
  

闽ICP备14008679号