热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

BERT系列BERT模型的初步认识

1.BERT模型的初步认识BERT(Pre-trainingofDeepBidirectionalTransformers,原文链接:B
1.BERT模型的初步认识

BERT(Pre-training of Deep Bidirectional Transformers,原文链接:BERT)是近年来NLP圈中最火爆的模型,让我们来看一些数据。

自从2018年BERT模型发布以来,BERT模型仅用 2019 年一年的时间,便以势如破竹的姿态成为了 NLP 领域首屈一指的红人,BERT 相关的论文也如涌潮般发表出来。2019 年,可谓是 NLP 发展历程中具有里程碑意义的一年,而其背后的最大功臣当属 BERT !在NLP领域,如果把2019年称为“BERT年”也不为过。
据统计,2019以BERT为主要内容的论文发表数量近200篇,具体数据可以看看下面图片的github链接呦。

不过话说回来,第一个使用Transformer的预训练模型不是bert,而是GPT。想要进一步了解GPT模型的同学,可以阅读补充资料(OpenAI GPT: Generative Pre-Training for Language Understanding),如果你不了解Transformer结构,我建议你先不要阅读,等阅读完系列文章后,再来品味一下GPT与BERT的不同。

提前透露一下GPT和BERT的最大的不同,GPT里的基本结构是由单向的Transformer-Decoder结构组成,而BERT是由双向的Transformer-Encoder结构组成。

不管是ELMo、GPT还是BERT,他们改变解决NLP的重要思路是预训练+微调的模式。如图所示,预训练+微调的模式是一种迁移学习的思想,预训练阶段可以使用大规模的数据(比如wiki),使得一个强大的模型学习到大量的知识,而且这些知识的学习方式是无监督的。通过预训练的学习之后,模型就已经具备大量的先验知识,在微调阶段继续使用预训练好的模型参数,采用业务自身标注数据在此基础上完成最后一步的监督学习。

了解到这,大家对于BERT应该有了一个初步的认识,那顺便思考一下。

BERT采用了迁移学习的思想,如果在相同的NLP任务上达到传统模型(如RNN等)一样的性能指标,比如准确度都是90%,在准备数据成本上有优势么,什么样的优势?

3.带你读BERT原论文

该部分会精读一下BERT的原文,我也已经将重要的信息做了标注和解释。

把标注的地方全部弄清楚,就可以进行下面的学习了,一个新的算法,理论啃完,在把源码吃透,才算真的掌握,希望大家多注意细节。

完整解读版,可以自行下载,链接: https://pan.baidu.com/s/1Q0DcoIR1boHd4qi7vkwoTg 密码: ee20


4.跑通BERT代码

BERT当年发表时就在SQuAD v1.1上,获得了93.2%的 F1 分数,超过了之前最高水准的分数91.6%,同时超过了人类的分数91.2%。

BERT 还在极具挑战性的 GLUE 基准测试中将准确性的标准提高了7.6%。这个基准测试包含 9 种不同的自然语言理解(NLU)任务。在这些任务中,具有人类标签的训练数据跨度从 2,500 个样本到 400,000 个样本不等。BERT 在所有任务中都大大提高了准确性。

上述的微调任务介绍如下表

  • MNLI:给定一个前提 (Premise) ,根据这个前提去推断假设 (Hypothesis) 与前提的关系。该任务的关系分为三种,蕴含关系 (Entailment)、矛盾关系 (Contradiction) 以及中立关系 (Neutral)。所以这个问题本质上是一个分类问题,我们需要做的是去发掘前提和假设这两个句子对之间的交互信息。
  • QQP:基于Quora,判断 Quora 上的两个问题句是否表示的是一样的意思。
  • QNLI:用于判断文本是否包含问题的答案,类似于我们做阅读理解定位问题所在的段落。
  • STS-B:预测两个句子的相似性,包括5个级别。
  • MRPC:也是判断两个句子是否是等价的。
  • RTE:类似于MNLI,但是只是对蕴含关系的二分类判断,而且数据集更小。
  • SWAG:从四个句子中选择为可能为前句下文的那个。
  • SST-2:电影评价的情感分析。
  • CoLA:句子语义判断,是否是可接受的(Acceptable)。

初步了解了BERT以后,我们就简单跑一个BERT的例子吧,让大家有一个整体的认识。

# 正式开始实验之前首先通过如下命令安装最新版本的 paddlenlp
!python -m pip install --upgrade paddlenlp -i https://pypi.org/simple

# 导入所需要的包
from functools import partial
import argparse
import os
import random
import timeimport numpy as np
import paddle
import paddle.nn.functional as Fimport paddlenlp as ppnlp
from paddlenlp.data import Stack, Tuple, Pad
from paddlenlp.datasets import load_dataset
from paddlenlp.transformers import LinearDecayWithWarmup

# 下载paddlenlp预置数据
train_ds, dev_ds, test_ds = load_dataset("chnsenticorp", splits=["train", "dev", "test"])

# 输出训练集的前 10 条样本
for idx, example in enumerate(train_ds):if idx <&#61; 10:print(example)

# 超参数
EPOCHS &#61; 10 # 训练的轮数
BATCH_SIZE &#61; 8 # 批大小
MAX_LEN &#61; 300 # 文本最大长度
LR &#61; 1e-5 # 学习率
WARMUP_STEPS &#61; 100 # 热身步骤
T_TOTAL &#61; 1000 # 总步骤

# 调用bert模型用的tokenizer
tokenizer &#61; ppnlp.transformers.BertTokenizer.from_pretrained(&#39;bert-base-chinese&#39;)

# 将文本内容转化成模型所需要的token id
def convert_example(example, tokenizer, max_seq_length&#61;512, is_test&#61;False):"""Builds model inputs from a sequence or a pair of sequence for sequence classification tasksby concatenating and adding special tokens. And creates a mask from the two sequences passed to be used in a sequence-pair classification task."""encoded_inputs &#61; tokenizer(text&#61;example["text"], max_seq_len&#61;max_seq_length)input_ids &#61; encoded_inputs["input_ids"]token_type_ids &#61; encoded_inputs["token_type_ids"]if not is_test:label &#61; np.array([example["label"]], dtype&#61;"int64")return input_ids, token_type_ids, labelelse:return input_ids, token_type_ids

# 创建dataloader
def create_dataloader(dataset,mode&#61;&#39;train&#39;,batch_size&#61;1,batchify_fn&#61;None,trans_fn&#61;None):if trans_fn:dataset &#61; dataset.map(trans_fn)shuffle &#61; True if mode &#61;&#61; &#39;train&#39; else Falseif mode &#61;&#61; &#39;train&#39;:batch_sampler &#61; paddle.io.DistributedBatchSampler(dataset, batch_size&#61;batch_size, shuffle&#61;shuffle)else:batch_sampler &#61; paddle.io.BatchSampler(dataset, batch_size&#61;batch_size, shuffle&#61;shuffle)return paddle.io.DataLoader(dataset&#61;dataset,batch_sampler&#61;batch_sampler,collate_fn&#61;batchify_fn,return_list&#61;True)

# 样本转换函数
trans_func &#61; partial(convert_example,tokenizer&#61;tokenizer,max_seq_length&#61;MAX_LEN)
batchify_fn &#61; lambda samples, fn&#61;Tuple(Pad(axis&#61;0, pad_val&#61;tokenizer.pad_token_id), # inputPad(axis&#61;0, pad_val&#61;tokenizer.pad_token_type_id), # segmentStack(dtype&#61;"int64") # label): [data for data in fn(samples)]
train_data_loader &#61; create_dataloader(train_ds,mode&#61;&#39;train&#39;,batch_size&#61;BATCH_SIZE,batchify_fn&#61;batchify_fn,trans_fn&#61;trans_func)
dev_data_loader &#61; create_dataloader(dev_ds,mode&#61;&#39;dev&#39;,batch_size&#61;BATCH_SIZE,batchify_fn&#61;batchify_fn,trans_fn&#61;trans_func)
test_data_loader &#61; create_dataloader(test_ds,mode&#61;&#39;test&#39;,batch_size&#61;BATCH_SIZE,batchify_fn&#61;batchify_fn,trans_fn&#61;trans_func)

# 调用bert的预训练模型
model &#61; ppnlp.transformers.BertForSequenceClassification.from_pretrained(&#39;bert-base-chinese&#39;, num_classes&#61;len(train_ds.label_list))

# 完成训练设置
num_training_steps &#61; len(train_data_loader) * EPOCHSlr_scheduler &#61; LinearDecayWithWarmup(LR, num_training_steps, WARMUP_STEPS)# Generate parameter names needed to perform weight decay.
# All bias and LayerNorm parameters are excluded.
decay_params &#61; [p.name for n, p in model.named_parameters()if not any(nd in n for nd in ["bias", "norm"])
]
optimizer &#61; paddle.optimizer.AdamW(learning_rate&#61;lr_scheduler,parameters&#61;model.parameters(),weight_decay&#61;0.0,apply_decay_param_fun&#61;lambda x: x in decay_params)criterion &#61; paddle.nn.loss.CrossEntropyLoss()
metric &#61; paddle.metric.Accuracy()

# 开始训练
global_step &#61; 0
tic_train &#61; time.time()
for epoch in range(1, EPOCHS &#43; 1):for step, batch in enumerate(train_data_loader, start&#61;1):input_ids, token_type_ids, labels &#61; batchlogits &#61; model(input_ids, token_type_ids)loss &#61; criterion(logits, labels)probs &#61; F.softmax(logits, axis&#61;1)correct &#61; metric.compute(probs, labels)metric.update(correct)acc &#61; metric.accumulate()global_step &#43;&#61; 1if global_step % 10 &#61;&#61; 0:print("global step %d, epoch: %d, batch: %d, loss: %.5f, accu: %.5f, speed: %.2f step/s"% (global_step, epoch, step, loss, acc,10 / (time.time() - tic_train)))tic_train &#61; time.time()loss.backward()optimizer.step()lr_scheduler.step()optimizer.clear_grad()if global_step % 100 &#61;&#61; 0:breakbreakprint(&#39;bert训练Demo完成了...&#39;)

ok&#xff0c;终于可以完成一个BERT的训练demo了。

5.后续计划

本节课内容就这些&#xff0c;喜欢的同学可以关注后续内容。

计划&#xff1a;

《BERT模型的核心架构》

《BERT如何完成预训练》

《BERT微调细节详解》

《使用BERT完成任务》

《。。。》


推荐阅读
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 深度学习中的Vision Transformer (ViT)详解
    本文详细介绍了深度学习中的Vision Transformer (ViT)方法。首先介绍了相关工作和ViT的基本原理,包括图像块嵌入、可学习的嵌入、位置嵌入和Transformer编码器等。接着讨论了ViT的张量维度变化、归纳偏置与混合架构、微调及更高分辨率等方面。最后给出了实验结果和相关代码的链接。本文的研究表明,对于CV任务,直接应用纯Transformer架构于图像块序列是可行的,无需依赖于卷积网络。 ... [详细]
  • EzPP 0.2发布,新增YAML布局渲染功能
    EzPP发布了0.2.1版本,新增了YAML布局渲染功能,可以将YAML文件渲染为图片,并且可以复用YAML作为模版,通过传递不同参数生成不同的图片。这个功能可以用于绘制Logo、封面或其他图片,让用户不需要安装或卸载Photoshop。文章还提供了一个入门例子,介绍了使用ezpp的基本渲染方法,以及如何使用canvas、text类元素、自定义字体等。 ... [详细]
  • GPT-3发布,动动手指就能自动生成代码的神器来了!
    近日,OpenAI发布了最新的NLP模型GPT-3,该模型在GitHub趋势榜上名列前茅。GPT-3使用的数据集容量达到45TB,参数个数高达1750亿,训练好的模型需要700G的硬盘空间来存储。一位开发者根据GPT-3模型上线了一个名为debuid的网站,用户只需用英语描述需求,前端代码就能自动生成。这个神奇的功能让许多程序员感到惊讶。去年,OpenAI在与世界冠军OG战队的表演赛中展示了他们的强化学习模型,在限定条件下以2:0完胜人类冠军。 ... [详细]
  • 【OCR学习笔记】What Is Wrong With Scene Text Recognition Model Comparisons Dataset and Model Analysis
    文章目录摘要细节开源代码摘要提出了一个统一的四阶段STR框架。Transformation:TPS,归一化字符区域到预定义的矩形,校正图像。Featureextraction ... [详细]
  • 老电影和图片变清晰的秘密!分辨率提升400%的AI算法
    老电影和图片变清晰的秘密!分辨率提升400%的AI算法-如上图,从100x133pix→400x532pix,除了肉眼可见的清晰,拥有可以将分辨率提升400%的技术到底意味着什么 ... [详细]
  • 抠图前vsPython自动抠图后在日常的工作和生活中,我们经常会遇到需要抠图的场景,即便是只有一张图片需要抠,也会抠得我们不耐烦ÿ ... [详细]
  • 读手语图像识别论文笔记2
    文章目录一、前言二、笔记1.名词解释2.流程分析上一篇快速门:读手语图像识别论文笔记1(手语识别背景和方法)一、前言一句:“做完了&#x ... [详细]
  • 自己手动写一个RPC框架
    一,简单一点的过程解说图(不太清晰,凑合看吧)Gitee仓库源码:https:gitee.comfanjiangfengwrite-rpc-framworkcommon模块创建商品 ... [详细]
  • 早晨七点半。北京初秋的凉风叫醒了住在望京西的你,睁开眼睛,一想到又要为人类的信息化事业贡献满满的正能量,你不禁哼唱起那句“早晨起来 ... [详细]
  • Jupyter 使用Anaconda 虚拟环境内核
    Anaconda虚拟环境中使用JupyterNotebook安装好Anaconda之后,进入AnacondaPrompt,创建虚拟环境, ... [详细]
  • 世界人工智能大赛OCR赛题方案!
     Datawhale干货 作者:阿水,北京航空航天大学,Datawhale成员本文以世界人工智能创新大赛(AIWIN)手写体OCR识别竞赛为实践背景,给出了OCR实践的常见思路和流 ... [详细]
  • 华为200万年薪招聘AI应届生——有多少本事,给多少钱
    据新浪科技报道,阿里AIlabs年薪百万美元引进两位科学家。除AI顶尖科学家外,华为也是为多位AI应届博士开出了200万的高价年薪。19年9月,各大互联招聘企业陆续发布2019年人 ... [详细]
  • 百度AI的2020
    百度AI的2020-世界的2020,是充满不确定性的变局之年;中国的2020,是团结一心、共克时艰、于变局中开新局的希望之年;百度AI的2020,是坚定信念,拥抱变化,践行“科技为 ... [详细]
author-avatar
谁会心如刀割_590
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有