一、什么是BERT?

没错下图中的小黄人就是文本的主角Bert ,而红色的小红人你应该也听过,他就是ELMo。2018年发布的BERT 是一个 NLP 任务的里程碑式模型,它的发布势必会带来一个 NLP 的新时代。BERT 是一个算法模型,它的出现打破了大量的自然语言处理任务的记录。在 BERT 的论文发布不久后,Google 的研发团队还开放了该模型的代码,并提供了一些在大量数据集上预训练好的算法模型下载方式。Goole 开源这个模型,并提供预训练好的模型,这使得所有人都可以通过它来构建一个涉及NLP 的算法模型,节约了大量训练语言模型所需的时间,精力,知识和资源。BERT模型的全称是:BERT(Bidirectional Encoder Representations from Transformers)。从名字中可以看出,BERT模型的目标是利用大规模无标注语料训练、获得文本的包含丰富语义信息的Representation。

二、Bert模型原理

BERT模型简介

BERT BASE: 与OpenAI Transformer 的尺寸相当,以便比较性能。

BERT LARGE: 一个非常庞大的模型,是原文介绍的最先进的结果。

BERT的基础集成单元是Transformer的Encoder。关于Transformer的介绍可以阅读Paper--Attention is All You Need。

2 个 BERT 的模型都有一个很大的编码器层数,(论文里面将此称为 Transformer Blocks) - 基础版本就有 12 层,进阶版本有 24 层。同时它也有很大的前馈神经网络 ( 768 和 1024 个Hidden units),还有很多 Attention heads(12和16 个)。这超过了 Transformer 论文中的参考配置参数(6 个编码器层,512 个隐藏层单元,和 8 个注意头)。在我们平时实际使用bert的过程中一般只会使用Bert-base,因为Bert模型的太大了,庞大的参数一般人的电脑配置难以驾驭,当然有TPU的土豪除外...

模型的输入和输出

BERT模型的主要输入是文本中各个词的原始词向量,该向量既可以随机初始化,也可以利用Word2Vector等算法进行预训练以作为初始值;输出是文本中各个词融合了全文语义信息后的向量表示。

从上图中可以看出,BERT模型的输入具体分为三种信息:

l Token Embeddings:是每个词的词向量,第一个单词是[CLS] Token,其取值在模型训练过程中自动学习,用于刻画文本的全局语义信息,可以用于之后的分类任务。[SEP] Token是用来分割输入的两条句子。

l Segment Embeddings:用来区别两种句子(是否是正常顺序的两个句子),因为Bert预训练不光做MLM还要做以两个句子为输入的分类任务。

l Position Embeddings:由于出现在文本不同位置的词所携带的语义信息存在差异(比如:“我爱你”和“你爱我”),因此,BERT模型对不同位置的词分别附加一个不同的向量以作区分。

特别地,在目前的BERT模型中,文章作者还将英文词汇作进一步切割,划分为更细粒度的语义单位(WordPiece),例如:将playing分割为play和ing;此外,对于中文,目前作者尚未对输入文本进行分词,而是直接将单个字作为构成文本的基本单位。输出是文本中各个词融合了全文语义信息后的向量表示。

模型的预训练任务

1) Task 1#: Masked Language Model

为了达到真正的bidirectional的LM的效果,作者创新性的提出了Masked LM,如下图所示,简单来说就是将句子中的一部分词mask掉,然后让模型去预测被mask掉的词(可以理解为我们大家初中都做过的完形填空)。这样有个缺点是在预训练的过程中把一些词mask起来,但是未来的fine tuning过程中的输入是没有mask的,这样模型有可能没见过这些词。这个量积累下来还是很大的。在训练过程中作者随机mask 15%的token,而不是把像CBOW一样把每个词都预测一遍。最终的损失函数只计算被mask掉那个token(其实这样也会导致一个问题就是训练的效率会比较低,因为每次反向传播只能计算15%的词)。Mask具体如何做也是有技巧的,前面说过如果全部用标记[MASK]代替会影响模型的fine tuning,所以作者mask的时候10%的单词会被随机替代成其他单词,还有10%的单词保持不变,剩下80%才被替换为[MASK] token。要注意的是Masked LM预训练阶段模型是不知道真正被mask的是哪个词,所以模型每个词都要关注。因为序列长度太大(512)会影响训练速度,所以90%的steps都用seq_len=128训练,余下的10%步数训练512长度的输入。

2) Task 2#: Next Sentence Prediction

Next Sentence Prediction的任务可以解释为:给定一篇文章中的两句话,判断第二句话在文本中是否紧跟在第一句话之后,目的是让模型理解两个句子之间的联系,如下图所示。将一篇文章的各段打乱,让我们通过重新排序把原文还原出来,这其实需要我们对全文大意有充分、准确的理解。Next Sentence Prediction任务实际上就是段落重排序的简化版:只考虑两句话,判断是否是一篇文章中的前后句。在实际预训练过程中,作者从文本语料库中随机选择50%正确语句对和50%错误语句对进行训练,与Masked LM任务相结合,让模型能够结合上下文预料更准确地表示每个词和句子的语义信息。

 

模型Fine tuning

Bert的fine-tuning之前对模型的修改非常简单,如果做Sentence pair classification 任务,那么就两句话一起输入例如:[CLS]我喜欢吃苹果[SEP]你喜欢吃梨子,最后取第一个token [CLS]的输出表示,喂给一个softmax层得到分类结果输出。Single sentence classification 就更简单,也是输入一句话,然后取第一个token [CLS]的输出来进行分类。对于Q&A问题着同时输入[CLS]Question[SEP]Answer,然后取输出的Answer中Start和End之间即为答案。对于Single sentence tagging tasks(NER),取所有token的最后层transformer输出,喂给softmax层做分类。总之不同类型的任务需要对模型做不同的修改,但是修改都是非常简单的,最多加一层神经网络即可。如下图所示:

四、总结

Bert的优点:BERT是截至2018年10月的最新state of the art模型,通过预训练和精调横扫了11项NLP任务,这首先就是最大的优点了。而且它还用的是Transformer,也就是相对基于RNN的模型Bert更加高效、能捕捉更长距离的依赖。对比起之前的预训练模型,它捕捉到的是真正意义上的bidirectional context信息。

Bert的缺点:主要就是MLM预训练时的mask问题,[MASK]标记在实际预测中不会出现,训练时用过多[MASK]会影响模型在fine tuning的下游任务上帝的表现;每个batch只有15%的token被预测,所以BERT收敛得比left-to-right模型要慢(它们会预测每个token)。全文读下来你会发现其实Bert也没有我们想象中的那么神奇,但是实际中Bert却是如此的强大,其中重要的原因也是Google拥有庞大的语料库(钱)来进行训练,当然TPU(钱)也是必不可少的。

论文地址:https://arxiv.org/pdf/1810.04805

代码地址(TensorFlow和Pytorch两个版本):

https://github.com/google-research/bert

https://github.com/huggingface/pytorch-pretrained-BERT

 

一文彻底搞懂BERT的更多相关文章

  1. 一文彻底搞懂Java中的环境变量

    一文搞懂Java环境变量 记得刚接触Java,第一件事就是配环境变量,作为一个初学者,只知道环境变量怎样配,在加上各种IDE使我们能方便的开发,而忽略了其本质的东西,只知其然不知其所以然,随着不断的深 ...

  2. 一文彻底搞懂MySQL分区

    一个执着于技术的公众号 一.InnoDB逻辑存储结构 首先要先介绍一下InnoDB逻辑存储结构和区的概念,它的所有数据都被逻辑地存放在表空间,表空间又由段,区,页组成. 段 段就是上图的segment ...

  3. 【NLP】彻底搞懂BERT

    # 好久没更新博客了,有时候随手在本上写写,或者Evernote上记记,零零散散的笔记带来零零散散的记忆o(╥﹏╥)o..还是整理到博客上比较有整体性,也方便查阅~ 自google在2018年10月底 ...

  4. 一文彻底搞懂Cookie、Session、Token到底是什么

    > 笔者文笔功力尚浅,如有不妥,请慷慨指出,必定感激不尽 Cookie 洛:大爷,楼上322住的是马冬梅家吧? 大爷:马都什么? 夏洛:马冬梅. 大爷:什么都没啊? 夏洛:马冬梅啊. 大爷:马什 ...

  5. 一文彻底搞懂BP算法:原理推导+数据演示+项目实战(上篇)

    欢迎大家关注我们的网站和系列教程:http://www.tensorflownews.com/,学习更多的机器学习.深度学习的知识! 反向传播算法(Backpropagation Algorithm, ...

  6. 【原创】一文彻底搞懂安卓WebView白名单校验

    前言 近两年公司端侧发现的漏洞很大一部分都出在WebView白名单上,针对这类漏洞安全编码团队也组织过多次培训,但是这种漏洞还是屡见不鲜.下面本人就结合产品中容易出现问题的地方,用实例的方式来总结一下 ...

  7. 一文轻松搞懂redis集群原理及搭建与使用

    今天早上由于zookeeper和redis集群不在同一虚拟机导致出了点很小错误(人为),所以这里总结一下redis集群的搭建以便日后所需同时也希望能对你有所帮助. 笔主这里使用的是Centos7.如果 ...

  8. 一文快速搞懂MySQL InnoDB事务ACID实现原理(转)

    这一篇主要讲一下 InnoDB 中的事务到底是如何实现 ACID 的: 原子性(atomicity) 一致性(consistency) 隔离性(isolation) 持久性(durability) 隔 ...

  9. 一文轻松搞懂Vuex

    概念: Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式(官网地址:https://vuex.vuejs.org/zh/).它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状 ...

随机推荐

  1. C语言程序报告五

    C程序设计实验报告 姓 名:赖瑾 实验地点:家 实验时间: 2020年4月21日 实验项目:6.3.1练习1 编写由三角形三边求面积的函数 6.3.1练习2 编写求N阶乘的函数 6.3.1练习3 求两 ...

  2. 2019-2020Nowcoder Girl初赛 题解

    题目都不是很难,就是最后一题有点毒瘤 第一题:牛妹爱整除 这个你把一个进制数进行拆分,拆分成若干位,然后在取模,这样会发现如果是x进制的数,那么对x+1这个进制转化即满足条件. 举个例子:一个x进制数 ...

  3. 微软原文翻译:适用于.Net Core的WPF数据绑定概述

    原文链接,大部分是机器翻译,仅做了小部分修改.英.中文对照,看不懂的看英文. Data binding overview in WPF 2019/09/19 Data binding in Windo ...

  4. Mysql常用sql语句(14)- 多表查询

    测试必备的Mysql常用sql语句,每天敲一篇,每次敲三遍,每月一循环,全都可记住!! https://www.cnblogs.com/poloyy/category/1683347.html 前言 ...

  5. [hdu4888]最大流,判断最大流唯一性

    题意:给一个n*m的矩形,往每个格子填0-k的数字,使得对第i行和为row[i],第i列和为col[i],问是否存在方案,方案是否唯一,如果方案唯一则输出具体方案. 思路:首先根据问题提取对象,行.列 ...

  6. USACO 3.1 Contact

    http://www.nocow.cn/index.php/Translate:USACO/contact 题目大意:给一个只含0和1的序列,统计每个子序列的重复次数,并按次数递减来输出 考虑子序列时 ...

  7. [hdu4598]二分图判定,差分约束

    题意: 给一个图,问能否给每个点分配一个实数值,使得存在一个数实数T,所有点满足:|value(i)| < T 且 u,v之间有边<=> |value(u)-value(v)| &g ...

  8. 【题解】[SCOI2015]小凸玩矩阵

    题目链接 思路:题目要求变相解答一下,求出是否有n-k个数,不大于当前求的第k个数 而每一行每一列只能有一个数,就可以得到一个二分图的思路,边上的权值就是第i行第j列这个数的值 对于答案就是第k大的数 ...

  9. 在终端输入npm run serve时出现npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! test_vue_0613@1.0.0 dev: 错误的解决方法

    在vscode终端使用命令 npm run serve 的时候报错 错误原因在于由于文件 node_modules 太大,在项目上传时有些人会删掉 导致我们下载的项目中缺少这个文件 在尝试把自己项目的 ...

  10. 【Python代码】TSNE高维数据降维可视化工具 + python实现

    目录 1.概述 1.1 什么是TSNE 1.2 TSNE原理 1.2.1入门的原理介绍 1.2.2进阶的原理介绍 1.2.2.1 高维距离表示 1.2.2.2 低维相似度表示 1.2.2.3 惩罚函数 ...