From 7d675386103c1c12fd792eb1ab20b9d1a24dc4ec Mon Sep 17 00:00:00 2001 From: erenup Date: Sun, 29 Aug 2021 23:17:12 +0800 Subject: [PATCH] refactor --- .../篇章2-Transformer相关原理/2.3-图解BERT.md | 42 ++++++++++++++----- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/docs/篇章2-Transformer相关原理/2.3-图解BERT.md b/docs/篇章2-Transformer相关原理/2.3-图解BERT.md index 4cad550..4a442b1 100644 --- a/docs/篇章2-Transformer相关原理/2.3-图解BERT.md +++ b/docs/篇章2-Transformer相关原理/2.3-图解BERT.md @@ -1,4 +1,25 @@ # 图解BERT + +内容组织; +- 图解BERT + - BERT句子分类 + - 模型结构 + - 模型输入 + - 模型输出 + - 预训练任务:Masked Language Model + - 预训练任务:相邻句子判断 + - BERT的应用 + - BERT特征提取 + - 拓展阅读 + - 对比CNN + - 词嵌入(Embedding)进展 + - 回顾词嵌入 + - 语境问题 + - Transformer:超越LSTM + - OpenAI Transformer:预训练一个Transformer Decoder进行语言建模 + - BERT:Decoder到Encoder + - 致谢 + 在学习完2.2章节的Transformer之后,我们来学习一下将Transformer模型结构发扬光大的一个经典模型:BERT。 站在2021年来看,2018年是自然语言处理技术的一个转折点,运用深度学习技术处理文本的能力通过预训练模型被极大的发挥了出来。同时,伴随着NLP开源社区的贡献,很多强大的模型被封装成组件,让NLP初学者也有机会在各种NLP任务上取得非常好的效果。在众多NLP预训练模型里,最经典的基本就是BERT和GPT了,因此本文将开始对BERT(单篇文章的citation已经接近2万)的学习。 @@ -9,12 +30,11 @@ BERT在2018年被剔除,BERT模型一出现就打破了多个自然语言处 ![BERT训练和微调](./pictures/3-bert.webp)图:BERT训练和微调 -## BERT应用 +## BERT句子分类 要想很好的理解BERT,最好先理解一下BERT的使用场景,明确一下输入和输出,最后再详细学习BERT的内在模型结构和训练方法。因此,在介绍模型本身涉及的BERT相关概念之前,让我们先看看如何直接应用BERT。 - 下载在无监督语料上预训练好的BERT模型,一般来说对应了3个文件:BERT模型配置文件(用来确定Transformer的层数,隐藏层大小等),BERT模型参数,BERT词表(BERT所能处理的所有token)。 - 针对特定任务需要,在BERT模型上增加一个任务相关的神经网络,比如一个简单的分类器,然后在特定任务监督数据上进行微调训练。(微调的一种理解:学习率较小,训练epoch数量较少,对模型整体参数进行轻微调整) -### 句子分类 先来看一下如何使用BERT进行句子分类, 假设我们的句子分类任务是:判断一个邮件是“垃圾邮件”或者“非垃圾邮件”,如下图所示。当然除了垃圾邮件判断,也可以是其他NLP任务,比如: @@ -27,7 +47,7 @@ BERT在2018年被剔除,BERT模型一出现就打破了多个自然语言处 ![BERT句子分类](./pictures/3-bert-cls.png)图:BERT句子分类 -### 模型结构 +## 模型结构 通过上面的例子,了解了如何使用BERT,接下来让我们更深入地了解一下它的工作原理。BERT原始论文提出了BERT-base和BERT—large两个模型,base的参数量比large少一些,可以形象的表示为下图的样子。 @@ -38,13 +58,13 @@ BERT在2018年被剔除,BERT模型一出现就打破了多个自然语言处 ![BERT encoder](./pictures/3-bert-encoder.webp)图:BERT-base为12层的encoder -### 模型输入 +## 模型输入 接着看一下模型的输入和输出:BERT模型输入有一点特殊的地方是在一句话最开始拼接了一个[CLS] token,如下图所示。这个特殊的[CLS] token经过BERT得到的向量表示通常被用作当前的句子表示。除了这个特殊的[CLS] token,其余输入的单词类似篇章2.2的Transformer。BERT将一串单词作为输入,这些单词多层encoder中不断向上流动,每一层都会经过 Self-Attention和前馈神经网络。 ![模型输入](./pictures/3-bert-input.png)图:模型输入 -### 模型输出 +## 模型输出 BERT输入的所有token经过BERt编码后,会在每个位置输出一个大小为 hidden_size(在 BERT-base中是 768)的向量。 @@ -56,13 +76,13 @@ BERT输入的所有token经过BERt编码后,会在每个位置输出一个大 -### 预训练任务:Masked Language Model +## 预训练任务:Masked Language Model 知道了模型输入、输出、Transformer结构,那么BERT是如何无监督进行训练的呢?如何得到有效的词、句子表示信息呢?以往的NLP预训练通常是基于语言模型进行,比如给定语言模型的前3个词,让模型预测第4个词。但是,BERT是基于Masked language model进行预训练的:将输入文本序列的部分(15%)单词随机Mask掉,让BERT来预测这些被Mask的词语。如下图所示: ![BERT mask](./pictures/3-bert-mask.webp)图: BERT mask 这种训练方式最早可以追溯到Word2vec时代,典型的Word2vec算法便是:基于词C两边的A、B和D、E词来预测出词C。 -### 预训练任务:相邻句子判断 +## 预训练任务:相邻句子判断 除了masked language model,BERt在预训练时,还引入了一个新的任务:判断两个句子是否是相邻句子。如下图所示:输入是sentence A和sentence B,经过BERT编码之后,使用CLS token的向量表示来预测两个句子是否是相邻句子。 @@ -71,14 +91,14 @@ BERT输入的所有token经过BERt编码后,会在每个位置输出一个大 注意事项:为了本文的描述方便,在前面的叙述中,均省略了BERT tokenize的过程,但读者朋友需要注意BERT实际上使用的是WordPieces作为最小的处理单元(采用的是wordpiece算法分词):token,而不是使用单词本身。在 WordPiece中,有些词会被拆分成更小的部分。关于WordPiece分词,本文不过多展开,感兴趣的读者可以阅读和学习[subword tokenizer](https://towardsdatascience.com/a-comprehensive-guide-to-subword-tokenisers-4bbd3bad9a7c)。另外,判断两个句子是否相邻这个任务再后来的研究中逐渐被淡化了,比如roberta模型在被提出的时候就不再使用该任务进行预训练了。 -### BERT的应用 +## BERT的应用 BERT论文展示了BERT在多种任务上的应用,如下图所示。可以用来判断两个句子是否相似,判断单个句子的情感,用来做抽取式问答,用来做序列标注。 ![BERT应用](./pictures/3-bert-app.png)图: BERT应用 -### BERT特征提取 +## BERT特征提取 由于BERT模型可以得到输入序列所对应的所有token的向量表示,因此不仅可以使用最后一程BERT的输出连接上任务网络进行微调,还可以直接使用这些token的向量当作特征。比如,可以直接提取每一层encoder的token表示当作特征,输入现有的特定任务神经网络中进行训练。 @@ -153,7 +173,7 @@ ELMo 通过将LSTM模型的隐藏成表示向量(以及初始化的词嵌入 2017年,基于Transformer的Encoder-Decode展示了它在机器翻译上的威力。但怎么才能用它来做文本分类呢?你怎么才能使用它来预训练一个语言模型,并能够在其他任务上进行微调(下游任务是指那些能够利用预训练模型的监督学习任务)? -### OpenAI Transformer:预训练一个Transformer Decoder进行语言建模 +#### OpenAI Transformer:预训练一个Transformer Decoder进行语言建模 沿着LSTM语言模型预训练的路子,将LSTM替换成Transformer结构后(相当于),直接语言模型预训练的参数给予下游任务监督数据进行微调,与最开始用于翻译seq2seq的Transformer对比来看,相当于只使用了Decoder部分。有了Transformer结构和语言模型任务设计,直接使用大规模未标记的数据不断得预测下一个词:只需要把 7000 本书的文字依次扔给模型 ,然后让它不断学习生成下一个词即可。 @@ -169,7 +189,7 @@ ELMo 通过将LSTM模型的隐藏成表示向量(以及初始化的词嵌入 #### BERT:Decoder到Encoder -OpenAI Transformer为我们提供了一个基于Transformer的预训练网络。但是在把LSTM换成Transformer 的过程中,有些东西丢失了。比如之前的ELMo的语言模型是双向的,但 OpenAI Transformer 只训练了一个前向的语言模型。我们是否可以构建一个基于 Transformer 的语言模型,它既向前看,又向后看(用技术术语来说 - 融合上文和下文的信息)。那答案就是BERT啦。 +OpenAI Transformer为我们提供了一个基于Transformer的预训练网络。但是在把LSTM换成Transformer 的过程中,有些东西丢失了。比如之前的ELMo的语言模型是双向的,但 OpenAI Transformer 只训练了一个前向的语言模型。我们是否可以构建一个基于 Transformer 的语言模型,它既向前看,又向后看(用技术术语来说 - 融合上文和下文的信息)。那答案就是BERT:基于双向Transformer的encoder,在Masked language model上进行预训练,最终在多项NLP下游任务重取得了SOTA效果。 ## 致谢 主要由哈尔滨工业大学张贤同学翻译(经过原作者授权)撰写,由多多重新组织和整理。感谢Jacob Devlin、Matt Gardner、Kenton Lee、Mark Neumann 和 [Matthew Peters](https://twitter.com/mattthemathman) 为这篇文章的早期版本提供了反馈。