赞
踩
Bert:Pre-training of Deep Bidirectional Transformers for Language Understanding。可以看出,Bert=Encoder of Transformer。
论文中提到,标准的语言模型应该是无方向的,像OPENAIGPT使用了从左往右的结构,使得self-attention只能attention到前面的内容。此外,论文中Bert使用了两种训练方式:1. MLM(Masked Language Model);2. next sentence prediction
主要贡献:在sentence-level(自然语言推理)和token-level(QA,NER)的任务上sota表现
有两种将预先训练的language representations应用于下游任务的现有策略:
Bert可以分为两个步骤:1.pre-training(在无标签数据上预训练);2.fine-tuining(使用预训练好的初始化参数,结合下游任务微调)
在 BERT 中,Masked LM(Masked Language Model)构建了语言模型,简单来说,就是随机遮盖或替换一句话里面的任意字或词,然后让模型通过上下文预测那一个被遮盖或替换的部分,之后做 Loss 的时候也只计算被遮盖部分的 Loss,这其实是一个很容易理解的任务,实际操作如下:
[MASK]
,例如 my dog is hairy→my dog is [MASK]这样做的好处是,BERT 并不知道 [MASK] 替换的是哪一个词,而且任何一个词都有可能是被替换掉的,比如它看到的 apple 可能是被替换的词。这样强迫模型在编码当前时刻词的时候不能太依赖当前的词,而要考虑它的上下文,甚至根据上下文进行 “纠错”。比如上面的例子中,模型在编码 apple 时,根据上下文 my dog is,应该把 apple 编码成 hairy 的语义而不是 apple 的语义
我们首先拿到属于上下文的一对句子,也就是两个句子,之后我们要在这两个句子中加一些特殊的 token:[CLS]
上一句话[SEP]
下一句话[SEP]
。也就是在句子开头加一个[CLS]
,在两句话之间和句末加[SEP]
,具体地如下图所示
可以看到,上图中的两句话明显是连续的。如果现在有这么一句话 [CLS]我的狗很可爱[SEP]企鹅不擅长飞行[SEP]
,可见这两句话就不是连续的。在实际训练中,我们会让这两种情况出现的数量为 1:1
Token Embedding
就是正常的词向量,即 PyTorch 中的 nn.Embedding()
Segment Embedding
的作用是用 embedding 的信息让模型分开上下句,我们给上句的 token 全 0,下句的 token 全 1,让模型得以判断上下句的起止位置,例如
[CLS]我的狗很可爱[SEP]企鹅不擅长飞行[SEP]
0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
Position Embedding
和 Transformer 中的不一样,不是三角函数,而是学习出来的
BERT 预训练阶段实际上是将上述两个任务结合起来,同时进行,然后将所有的 Loss 相加,例如
Input:
[CLS] calculus is a branch of math [SEP] panda is native to [MASK] central china [SEP]
Targets: False, south
----------------------------------
Input:
[CLS] calculus is a [MASK] of math [SEP] it [MASK] developed by newton and leibniz [SEP]
Targets: True, branch, was
BERT 的 Fine-Tuning 共分为 4 中类型,以下内容、图片均来自台大李宏毅老师 Machine Learning 课程(以下内容 图在上,解释在下)
如果现在的任务是 classification,首先在输入句子的开头加一个代表分类的符号[CLS]
,然后将该位置的 output,丢给 Linear Classifier,让其 predict 一个 class 即可。整个过程中 Linear Classifier 的参数是需要从头开始学习的,而 BERT 中的参数微调就可以了
这里李宏毅老师有一点没讲到,就是为什么要用第一个位置,即 [CLS] 位置的 output。这里我看了网上的一些博客,结合自己的理解解释一下。因为 BERT 内部是 Transformer,而 Transformer 内部又是 Self-Attention,所以 [CLS] 的 output 里面肯定含有整句话的完整信息,这是毋庸置疑的。但是 Self-Attention 向量中,自己和自己的值其实是占大头的,现在假设使用 wi的 output 做分类,那么这个 output 中实际上会更加看重 ,而wi 又是一个有实际意义的字或词,这样难免会影响到最终的结果。但是 [CLS] 是没有任何实际意义的,只是一个占位符而已,所以就算 [CLS] 的 output 中自己的值占大头也无所谓。当然你也可以将所有词的 output 进行 concat,作为最终的 output
如果现在的任务是 Slot Filling,将句子中各个字对应位置的 output 分别送入不同的 Linear,预测出该字的标签。其实这本质上还是个分类问题,只不过是对每个字都要预测一个类别
如果现在的任务是 NLI(自然语言推理)。即给定一个前提,然后给出一个假设,模型要判断出这个假设是 正确、错误还是不知道。这本质上是一个三分类的问题,和 Case 1 差不多,对[CLS]
的 output 进行预测即可
如果现在的任务是 QA(问答),举例来说,如上图,将一篇文章,和一个问题(这里的例子比较简单,答案一定会出现在文章中)送入模型中,模型会输出两个数 s,e,这两个数表示,这个问题的答案,落在文章的第 s 个词到第 e 个词。具体流程我们可以看下面这幅图
首先将问题和文章通过 [SEP] 分隔,送入 BERT 之后,得到上图中黄色的输出。此时我们还要训练两个 vector,即上图中橙色和黄色的向量。首先将橙色和所有的黄色向量进行 dot product,然后通过 softmax,看哪一个输出的值最大,例如上图中 d2 对应的输出概率最大,那我们就认为 s=2
同样地,我们用蓝色的向量和所有黄色向量进行 dot product,最终预测得 d3 的概率最大,因此 e=3。最终,答案就是 s=2,e=3
你可能会觉得这里面有个问题,假设最终的输出 s>e 怎么办,那不就矛盾了吗?其实在某些训练集里,有的问题就是没有答案的,因此此时的预测搞不好是对的,就是没有答案
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。