自然语言处理之BERT模型
一、BERT模型原理
-
BERT模型(Bidirectional Encoder Representations from Transformers):双向transformer编码表达。
1)Bidirectional:BERT 的模型结构和 ELMo 类似,均为双向的。
2)Encoder:BERT 只是用到了 Transformer 的 Encoder 编码器部分。
3)Representation:做词 / 句子的语义表征。
4)Transformer:Transformer Encoder 是 BERT 模型的核心组成部分。 -
BERT 模型的目标是利用自监督学习方法在大规模无标注语料上进行预训练,从而捕捉文本中的丰富语义信息。在后续特定的 NLP 任务中,我们可以根据任务类型对 BERT 预训练模型参数进行微调,以取得更好的任务效果。BERT 论文链接:https://arxiv.org/abs/1810.04805 ,github 地址:https://github.com/google-research/bert
-
BERT网络架构:
-
BERT 提供了基础和复杂两个模型,对应的超参数分别如下:
1) B E R T B A S E BERT_{BASE} BERTBASE:L=12,H=768,A=12,参数总量110M
2) B E R T L A R G E BERT_{LARGE} BERTLARGE:L=24,H=1024,A=16,参数总量340M
其中 L 表示网络的层数(即 Transformer blocks 的数量),A 表示 Multi-Head Attention 中 self-Attention 的数量,H 是输出向量的维度。谷歌提供了中文 BERT 基础预训练模型 bert-base-chinese,TensorFlow 版模型链接:https://storage.googleapis.com/bert_models/2018_11_03/chinese_L-12_H-768_A-12.zip ,Pytorch 版模型权重链接:https://huggingface.co/bert-base-chinese/tree/main -
BERT 论文中还对比了 GPT[3] 和 ELMo[4],它们两个的结构如下图所示:其中 BERT 使用的是双向 Transformer 编码器,GPT 使用的是单向 Transformer 解码器,ELMo 使用两个独立训练的 LSTM 结构,只有BERT表征会基于所有层中的左右两侧语境。除了结构上的不同,BERT 和 GPT 是基于微调的方式,而 ELMo 是基于特征的方法。
-
在BERT中主要以两种预训练的方式建立语言模型:MASKED LM和Next Sentence Prediction。
1.1 MASKED LM(Masked language Model)
- 在BERT中,MASKED LM(Masked language Model)构建了语言模型,简单来说随机遮盖或替换一句话里面任意字或词,然后让模型通过上下文的理解预测被遮盖或替换的部分,之后计算Loss时只计算被遮盖部分的Loss,具体如下操作:
- 随机把一句话中15%的token替换成以下内容:
1)这些token有80%的几率被替换成[mask],eg:my dog is hairy → \to → my dog is [MASK];
2)有10%的几率被替换成任意一个其他的token,这样会使得句子不通顺,eg:my dog is hairy → \to → my dog is apple;
3)有10%的几率不动,eg:my dog is hairy → \to → my dog is hairy;
1.2 Next Sentence Prediction
- 首先拿到属于上下文的两个句子,我们在两个连续的句子里加一些特殊的token:
[cls]上一句话,[sep]下一句话.[sep]
也就是在句子开头加一个[cls],在两句话之中和句末加一个[sep],具体如下图所示,Token Embedding是字向量的Embedding矩阵;Segment Embedding是上下句分界;Position Embedding是位置嵌入,将三个Embedding元素对位相加即可:
- 我们看到上图中的两句话是[cls]my dog is cute[sep]he likes playing[sep],即[cls]我的狗很可爱[sep]他喜欢玩耍[sep],除此之外,我们还要准备同样格式的两句话,但他们不属于上下文关系的情况;
[cls]我的狗很可爱[sep]企鹅不擅长飞行[sep],可见这属于上下句不属于上下文关系的情况;在实际训练中,我们让上面的两种情况出现的比例为1:1,也就是一半的时间输出的文本属于上下文关系,一半不是; - 我们讲完上述步骤后,还要随机化一个可训练的segment embedding,如上图所示,作用就是用embedding的信息让模型分开上下句,我们一般会给上句全0的token,下句全1的token,让模型得意判断上下句的起止位置,例如:
- 注意力机制中,每一个字对应的Embedding向量里的一行数据,都融入了整句话所有的信息,因此我们期望这个句子里面所有的信息都会往[cls]的token对应的一条向量里汇总。在transformer block中输出的结果
X
h
i
d
d
e
n
X_{hidden}
Xhidden的维度是
[
b
a
t
c
h
_
s
i
z
e
,
s
e
q
u
e
n
c
e
_
l
e
n
g
t
h
,
e
m
b
e
d
d
i
n
g
_
d
i
m
]
[batch\_size, sequence\_length, embedding\_dim]
[batch_size,sequence_length,embedding_dim],我们取出[cls]的token对应的一条向量,[cls]对应
s
e
q
l
e
n
seq_len
seqlen维度的第0条:
c l s _ v e c t o r = X _ h i d d e n [ : , 0 , : ] , c l s _ v e c t o r ∈ R b a t c h _ s i z e , e m b e d d i n g _ d i m cls\_vector=X\_{hidden}[:,0,:],cls\_vector\in R^{batch\_size,embedding\_dim} cls_vector=X_hidden[:,0,:],cls_vector∈Rbatch_size,embedding_dim
之后我们采用二分类进行上下文预测(即属于上下文关系isNext和不属于上下文关系notNext)。我们用 y ^ \hat y y^表示模型输出二分类预测。
y ^ = s i g m o i d ( L i n e a r ( c l s _ v e c t o r ) ) , y ^ ∈ ( 0 , 1 ) \hat y=sigmoid(Linear(cls\_vector)), \hat y\in(0, 1) y^=sigmoid(Linear(cls_vector)),y^∈(0,1)
1.3 BERT模型预训练
- BERT 模型使用两个新的无监督预测任务进行预训练,分别是 Masked LM(MLM)和 Next Sentence Prediction(NSP)。
- 参考网址:1. https://mp.weixin.qq.com/s/MH9ncxmbAcOi4-IIYjaTiA