Bert模型详解和训练实例

article/2025/10/29 15:40:07

前面已经介绍了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.845588eval_loss = 0.505248global_step = 343loss = 0.505248

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


http://chatgpt.dhexx.cn/article/AuScNXrL.shtml

相关文章

无监督模型 训练过程_监督使用训练模型

无监督模型 训练过程 Machine Learning, Artificial Intelligence, and Deep Learning are some of the most complex, yet highly demanded fields of expertise today. There are innumerable resources and tools to work in these fields, and one such popular tool is Su…

Tensorflow V2 图像识别模型训练流程

Tensorflow V2.0 图像识别教程 代码: https://github.com/dwSun/classification-tutorial.git 教程参考官方专家高级教程: https://tensorflow.google.cn/tutorials/quickstart/advanced?hlen 这里以 TinyMind 《汉字书法识别》比赛数据为例&#xf…

(三)mmclassification图像分类——模型训练

(三)mmclassification图像分类——模型训练和测试 1.模型训练1.1使用预训练模型1.2使用自己的数据训练1.2.1制作数据集1.2.2修改模型参数(configs文件)(1)models(2)datasets(3)schedules(4)新建mobilenet_v2_b32x8_car.py 1.3训练…

tensorflow CNN模型训练+优化参数+实战

训练线性函数 import numpy as np import tensorflow.keras as keras # 构建模型 model keras.Sequential([keras.layers.Dense(units1,input_shape[1])]) # optimizer优化,loss损失 model.compile(optimizersgd, lossmean_squared_error) #准备训练数据 xsnp.ar…

nanodet训练手势识别模型

序言 前段时间nanodet爆火,以非常小的模型和运算量,取得了超过tiny-yolov4的精度,非常惊艳,因为时间问题一直没有尝试,最近有空决定尝试一下。先来看下作者给的模型效果 一、nanodet安装 首先安装nanodet的环境包…

Pytorch教程[10]完整模型训练套路

一般的模型构建都是按照下图这样的流程 下面分享一个自己手动搭建的网络 from model import * import torchvision import torch from torch.utils.tensorboard import SummaryWriter from torchvision import transforms from torch import nn from torch.utils.data import …

PaddleOCR学习(二)PaddleOCR检测模型训练

这一部分主要介绍,如何使用自己的数据库去训练PaddleOCR的文本检测模型。 官方教程https://github.com/PaddlePaddle/PaddleOCR/blob/develop/doc/doc_ch/detection.md 一、准备训练数据 首先你需要有自己的数据,如果没有自己的数据,推荐使…

迁移学习的模型训练

用深度学习解决目标检测有两个重要工作: 1、设计、实现、训练和验证模型 模型如果设计模型如何编程实现如何收集足够的数据来训练并验证模型是否符合预期 从头开始设计、实现、训练和验证模型是需要有众多深度学习算法人才做支撑,并且极其耗时耗力 2、…

TF2.0模型训练

TF2.0模型训练 概述数据集介绍1、通过fit方法训练模型准备数据创建模型编译模型训练模型 2、通过fit_generator方法训练模型构建生成器创建模型编译模型训练模型 3、自定义训练准备数据创建模型定义损失函数及优化器训练模型 下一篇TF2.0模型保存 概述 这是TF2.0入门笔记【TF2…

TensorFlow 2.0 —— 模型训练

目录 1、Keras版本模型训练1.1 构造模型(顺序模型、函数式模型、子类模型)1.2 模型训练:model.fit()1.3 模型验证:model.evaluate()1.4 模型预测:model.predict()1.5 使用样本加权和类别加权1.6 回调函数1.6.1 EarlySt…

如何在jupyter上运行Java代码(适用LINUX)

如何在jupyter上运行Java代码 1.下载必须软件 下载JDK且JDK版本必须 ≥ 9 ≥9 ≥9从github上下载ijava 附 : ijava下载链接.装有jupyter,我在LINUX上是直接装的anaconda 安装过程 将下载的ijava压缩包解压出来,并在此路径用该命令 : sudo…

Java单元测试介绍

文章目录 单元测试单元测试基本介绍单元测试快速入门单元测试常用注解 单元测试 单元测试基本介绍 单元测试: 单元测试就是针对最小的功能单元编写测试代码,Java程序最小的功能单元是方法,因此,单元测试就是针对Java方法的测试,…

Jupyter 配置 Java环境,写Java代码,测试成功

本次简单诉说下怎么通过jupyter安装iJava,写Java代码。 安装Java的不说了 我使用的是Java15 然后去:https://github.com/SpencerPark/IJava/releases 下载zip,不要下载其他的 得到就是一个py文件 下面就是一个 python install.py 我这里就…

java调用python执行脚本,附代码

最近有个功能需要java调用python脚本实现一些功能,前期需要做好的准备:配置好python环境,如下: 以下展示的为两种,一种为生成图片,另一种为生成字符串。 package com.msdw.tms.common.utils.py;import ja…

Selenium Java自动化测试环境搭建

IDE用的是Eclipse。 步骤1:因为是基于Java,所以首先要下载与安装JDK(Java Development Kit) 下载: 点击这里下载JDK 安装:按照默认安装一路点next就可以了。 验证:安装完成后,在命…

java单元测试(Junit)

相关代码下载链接: http://download.csdn.net/detail/stevenhu_223/4884357 在有些时候,我们需要对我们自己编写的代码进行单元测试(好处是,减少后期维护的精力和费用),这是一些最基本的模块测试。当然&…

Java单元测试工具:JUnit4(一)——概述及简单例子

(一)JUnit概述及一个简单例子 看了慕课网的JUnit视频教程: http://www.imooc.com/learn/356,总结笔记。 这篇笔记记录JUnit的概述,以及一个快速入门的例子。 1.概述 1.1 什么是JUnit ①JUnit是用于编写可复用测试集的…

Linux下执行Python脚本

1.Linux Python环境 Linux系统一般集成Python,如果没有安装,可以手动安装,联网状态下可直接安装。Fedora下使用yum install,Ubuntu下使用apt-get install,前提都是root权限。安装完毕,可将Python加入环境变…

python pytest脚本执行工具

pytest脚本执行工具 支持获取当前路径下所有.py脚本 添加多个脚本,一起执行 import tkinter as tk from tkinter import filedialog import subprocess import os from datetime import datetimedef select_script():script_path filedialog.askopenfilename(fil…

linux上运行python(简单版)

linux上运行python(简单版) 一、前提准备1.centOS72.挂载yum源[http://t.csdn.cn/Isf0i](http://t.csdn.cn/Isf0i) 二、安装python3三、运行程序 一、前提准备 1.centOS7 2.挂载yum源http://t.csdn.cn/Isf0i 在终端进行安装python3 二、安装python3 …