最近在学习BERT。
简单说几句。
BERT=Bidirectional Encoder Representation from Transformer
作者是谷歌的团队
主要亮点是使用transformer和pre-trainning+未标注的数据,训练出来一个通用的语言模型。
0:背景
视觉算法因为有ImageNet的存在,迁移学习或者微调都很方便,但是当时NLP一直没有。
在这个情况下BERT应运而生。
1:技术框架
a:Masked Language Model
在 BERT 中,Masked LM(Masked Language Model)构建了语言模型,简单来说,就是随机遮盖或替换一句话里面的任意字或词,然后让模型通过上下文预测那一个被遮盖或替换的部分,之后做 Loss 的时候也只计算被遮盖部分的 Loss,这其实是一个很容易理解的任务,实际操作如下:
-
随机把一句话中 15% 的 token(字或词)替换成以下内容:
- 这些 token 有 80% 的几率被替换成
[MASK]
,例如 my dog is hairy→my dog is [MASK] - 有 10% 的几率被替换成任意一个其它的 token,例如 my dog is hairy→my dog is apple
- 有 10% 的几率原封不动,例如 my dog is hairy→my dog is hairy
- 这些 token 有 80% 的几率被替换成
- 之后让模型预测和还原被遮盖掉或替换掉的部分,计算损失的时候,只计算在第 1 步里被随机遮盖或替换的部分,其余部分不做损失,其余部分无论输出什么东西,都无所谓
为什么要这样做?
主要是为了利用transformer提供全局语义信息,使得模型可以考虑上下文。从而增强各个特征之间的联系。
b:Next Sentence Prediction
我们首先拿到属于上下文的一对句子,也就是两个句子,之后我们要在这两个句子中加一些特殊的 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 中的不一样,不是三角函数,而是学习出来的
Multi-Task Learning
BERT 预训练阶段实际上是将上述两个任务结合起来,同时进行,然后将所有的 Loss 相加
2:训练
BERT 的 Fine-Tuning 共分为 4 个类型。
这里参考的主要是台大李宏毅老师。
分类任务的开头是cls,然后将该位置的 output,丢给 Linear Classifier,让其 predict 一个 class 即可。整个过程中 Linear Classifier 的参数是需要从头开始学习的,而 BERT 中的参数微调就可以了。
如果现在的任务是 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 .
3:代码实现
我是在A100的卡上跑的。
从结果上来看,只能说能用。