Bert模型详解和训练实例

前面已经介绍了transformer,理解了transformer,那么理解bert就简单多了。对transformer不是很了解的可以跳转到https://blog.csdn.net/one_super_dreamer/article/details/105181690

bert的核心代码解读在https://blog.csdn.net/one_super_dreamer/article/details/105344649,本文主要介绍训练实例。

Bert简介

BERT来自Google的论文Pre-training of Deep Bidirectional Transformers for Language Understanding,BERT是”Bidirectional Encoder Representations from Transformers”的首字母缩写。如下图所示,BERT能够同时利用前后两个方向的信息,而ELMo和GPT只能使用单个方向的。

BERT使用的是Transformer模型,使用的是transformer的encoder部分。那它是怎么解决语言模型只能利用一个方向的信息的问题呢?答案是它的pretraining训练的不是普通的语言模型,而是Mask语言模型。在介绍Mask语言模型之前我们先介绍BERT的输入表示。

输入表示

BERT的输入表示如图下图所示。比如输入的是两个句子”my dog is cute”,”he likes playing”。后面会解释为什么需要两个句子。这里采用类似GPT的两个句子的表示方法,首先会在第一个句子的开头增加一个特殊的Token [CLS],在cute的后面增加一个[SEP]表示第一个句子结束,在##ing后面也会增加一个[SEP]。注意这里的分词会把”playing”分成”play”和”##ing”两个Token,这种把词分成更细粒度的Word Piece的方法在前面的机器翻译部分介绍过了,这是一种解决未登录词的常见办法,后面的代码部分也会简单介绍。接着对每个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

以下两种训练是同时进行的。

第一种方法:随机mask掉部分词汇,让机器去学习

为了解决只能利用单向信息的问题,BERT使用的是Mask语言模型而不是普通的语言模型。Mask语言模型有点类似与完形填空——给定一个句子,把其中某个词遮挡起来,让人猜测可能的词。这里会随机的Mask掉15%的词,然后让BERT来预测这些Mask的词,通过调整模型的参数使得模型预测正确的概率尽可能大,这等价于交叉熵的损失函数。这样的Transformer在编码一个词的时候会(必须)参考上下文的信息。

但是这有一个问题:在Pretraining Mask LM时会出现特殊的Token [MASK],但是在后面的fine-tuning时却不会出现,这会出现Mismatch的问题。因此BERT中,如果某个Token在被选中的15%个Token里,则按照下面的方式随机的执行:

  • 80%的概率替换成[MASK],比如my dog is hairy → my dog is [MASK]
  • 10%的概率替换成随机的一个词,比如my dog is hairy → my dog is apple
  • 10%的概率替换成它本身,比如my dog is hairy → my dog is hairy

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

第二种方法:预测两个句子是否连接在一起

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

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

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

安装部署

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

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

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

  • BERT-Base, Uncased 12层,768个隐单元,12个Attention head,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

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

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

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

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了:

python run_classifier.py \
	--task_name=MRPC \
	--do_train=true \
	--do_eval=true \
	--data_dir=$GLUE_DIR/MRPC \
	--vocab_file=$BERT_BASE_DIR/vocab.txt \
	--bert_config_file=$BERT_BASE_DIR/bert_config.json \
	--init_checkpoint=$BERT_BASE_DIR/bert_model.ckpt \
	--max_seq_length=128 \
	--train_batch_size=8 \
	--learning_rate=2e-5 \
	--num_train_epochs=3.0 \
	--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 训练得到的模型的存放目录

如果有读者使用的是pycharm,可以在run里面配置参数,下面是具体示意图。

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

***** Eval results *****
  eval_accuracy = 0.845588
  eval_loss = 0.505248
  global_step = 343
  loss = 0.505248

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

  • 20
    点赞
  • 262
    收藏
    觉得还不错? 一键收藏
  • 24
    评论
训练自己的BERT模型需要以下几个步骤: 1. 数据准备:首先,你需要准备一个大规模的文本语料库作为训练数据。这个语料库应该包含足够多的文本样本,以便训练出具有良好语言理解能力的模型。 2. 模型架构:接下来,你需要定义自己的BERT模型的架构。BERT模型使用了Transformer的encoder部分,并采用了Mask语言模型训练方式。你可以参考BERT的论文和代码来设计自己的模型架构。 3. 数据预处理:在训练之前,你需要对准备好的文本数据进行预处理。这包括将文本转换为模型可以理解的输入表示形式,如tokenization和padding等。 4. 模型训练:使用准备好的数据和定义好的模型架构,你可以开始进行模型训练训练过程中,你可以使用预训练BERT模型作为初始参数,然后通过反向传播和优化算法来更新模型的参数。 5. 调参和验证:在训练过程中,你可以根据需要进行超参数的调整,并使用验证集来评估模型的性能。通过不断地调整和验证,你可以找到最佳的模型配置。 6. 模型保存和应用:训练完成后,你可以将训练好的模型保存下来,以便后续的应用和推理任务中使用。 需要注意的是,训练BERT模型需要大量的计算资源和时间。如果你没有足够的资源和时间,可以考虑使用已经预训练好的BERT模型,并在此基础上进行微调来适应自己的任务。这样可以节省训练时间和资源,并且通常能够取得不错的效果。 #### 引用[.reference_title] - *1* [BERT模型—2.BERT模型训练与微调](https://blog.csdn.net/weixin_46649052/article/details/118936381)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Bert模型详解训练实例](https://blog.csdn.net/one_super_dreamer/article/details/105206692)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值