这是阅读《自然语言处理-基于预训练模型的方法》的学习笔记,记录学习过程,详细的内容请大家购买书籍查阅。
同时参考沐神的两个视频:
GPT,GPT-2,GPT-3 论文精读【论文精读】
BERT 论文逐段精读【论文精读】
概述
自然语言处理的核心在于如何更好地建模语言。广义上的预训练语言模型可以泛指提前经过大规模数据训练的语言模型,包括早期的Word2vec、GloVe为代表的静态词向量模型,以及基于上下文建模的CoVe、ELMo等动态词向量模型。在2018年,以GPT和BERT为代表的基于深层Transformer的表示模型出现后,预训练语言模型这个词才真正被大家广泛熟知。
大数据
获取足够多的大规模文本是数据是训练一个好的预训练语言模型的开始。因此,预训练数据需要讲究“保质”和“保量”。
- “保质”是希望预训练语料的质量要尽可能高,避免混入过多的低质量语料。
- “保量”是希望预训练语料的规模要尽可能大,从而获取更丰富的上下文信息。
在实际情况中,训练数据往往来源不同。精细化地预处理所有不同来源地数据是非常困难的。因此,在预训练数据地准备过程中,通常不会进行非常精细化地处理,仅会处理预训练语料的共性问题。同时,通过增大语料规模进一步稀释低质量语料的比重,从而降低质量较差的语料对预训练过程带来的负面影响。这需要在数据处理投入和数据质量之间做出权衡。
大模型
在有了大数据之后,就需要有一个足以容纳这些数据的模型。数据规模和模型规模在一定程度上是正相关的。需要一个容量足够大的模型来学习和存放大数据中的各种特征。在机器学习中,“容量大”通常指的是模型的“参数量大”。如何设计一个参数量较大的模型主要考虑两个方面:
- 模型需要具有较高的并行程度,以弥补大模型带来的训练速度下降的问题;
- 模型能够捕获上下文信息,以充分挖掘大数据文本中丰富的语义信息。
综合以上两点。基于Transformer的神经网络模型成为目前构建预训练语言模型的最佳选择。首先Transformer模型具有较高的并行度。Transformer核心部分的多头自注意力机制(Multi-head Self-attention
)不依赖于顺序建模,因此可以快速地并行处理。与此相反,传统的神经网络语言模型通常基于循环神经网络(RNN
),而RNN需要按照序列顺序处理,并行化程度较低。其次,Transformer中的多头自注意力机制能够有效地捕获不同词之间的关联程度,并且能够通过多头机制从不同维度刻画这种关联程度,使得模型能够得到更加精准的计算结果。因此主流的预训练语言模型无一例外都使用了Transformer作为模型的主体结构。
大算力
训练预训练语言模型,主要使用图形处理单元(Graphics Processing Unit, GPU
),还有张量处理单元(Tensor Processing Unit, TPU
)。
GPT
#GPT是transformer的解码器#
#四个月之后bert出现,bert-base的模型与gpt模型大小差不多#
#GPT3“暴力出奇迹”#
OpenAI公司在2018年提出了一种生成式预训练(Generative Pre-Training, GPT
)模型用来提升自然语言理解任务的效果,正式将自然语言处理带入“预训练”时代。“预训练”时代意味着利用更大规模的文本数据以及更深层的神经网络模型来学习更丰富的文本语义表示。同时,GPT的出现打破了自然语言处理中各个任务之间的壁垒,使得搭建一个面向特定任务的自然语言处理模型不再需要了解非常多的任务背景,只需要根据任务的输入输出形式应用这些预训练语言模型,就能达到一个不错的效果。因此,GPT提出了“生成式预训练 + 判别式任务精调”的自然语言处理新范式,使得自然语言处理模型的搭建变得不再复杂。
#GPT:使用通用的预训练来提升语言的理解能力#
#GPT选了个更难优化的问题,同时天花板更高#
无监督预训练
GPT的整体结构是一个基于Transformer的单向语言模型(Transformer解码器),即从左到右对输入文本建模。
GPT利用常规语言建模的方法优化给定文本序列
x
=
x
1
.
.
.
x
n
x=x_1...x_n
x=x1...xn的最大似然估计
L
P
T
L^{PT}
LPT。
L
P
T
=
∑
i
l
o
g
P
(
x
i
∣
x
i
−
k
.
.
.
x
i
−
1
;
θ
)
L^{PT}=\sum_{i}^{} logP(x_i|x_{i-k}...x_{i-1};\theta )
LPT=i∑logP(xi∣xi−k...xi−1;θ)
k
k
k表示语言模型的窗口大小,即基于k个历史词预测当前时刻的词
x
i
x_i
xi;
θ
\theta
θ表示神经网络的参数,可使用随机梯度下降优化该似然函数。
具体的,GPT使用了多层transformer作为模型的基本结构,对于长度为k的窗口词序列 x ′ = x − k . . . x − 1 x'=x_{-k}...x_{-1} x′=x−k...x−1,通过以下方式计算建模概率P。 h [ 0 ] = e x ′ W e + W p h^{[0]} = e_{x'}W^e+W^p h[0]=ex′We+Wp h [ l ] = T r a n s f o r m e r − B l o c k ( h l − 1 ) ∀ l ∈ 1 , 2... , L h^{[l]}=Transformer-Block(h^{l-1})\forall l \in {1,2...,L} h[l]=Transformer−Block(hl−1)∀l∈1,2...,L P ( x ) = S o f t m a x ( h L W e ⊤ ) P(x)=Softmax(h^{L}{W^{e}}^\top ) P(x)=Softmax(hLWe⊤) e x ′ e_{x'} ex′是 x ′ x' x′的独热向量表示; W e {W^e} We表示词向量矩阵; W p W^p Wp表示位置向量矩阵(此处只截取窗口 x ′ x' x′对应的位置向量); L L L是 T r a n s f o m e r Transfomer Transfomer的总层数。
有监督下游任务精调
在预训练阶段,
G
P
T
GPT
GPT利用大规模数据训练出基于深层
T
r
a
n
s
f
o
r
m
e
r
Transformer
Transformer的语言模型,已经掌握了文本的通用语义表示。精调(Fine-tuning
)的目的是在通用语义表示的基础上,根据下游任务(Downstream task
)的特性进行领域匹配,使之与下游任务的形式更加契合,以获得更好的下游任务应用效果。
下游任务精调通常是由有标注数据进行训练和优化的。假设下游任务的标注数据是 C C C,其中每个样例的输入是 x = x 1 . . . x n x=x_1...x_n x=x1...xn构成的长度为 n n n的文本序列,与之对应的标签是 y y y。首先将文本序列输出预训练的GPT中,获取最后一层的最后一个词对应的隐含层输出 h n [ L ] h_n^{[L]} hn[L],紧接着,将该隐藏层输出通过一层全连接层变换,预测最终的标签。
另外,为了进一步提升精调后模型的通用性以及收敛速度,可以在下游任务精调时加入一定权重的预训练损失。这样做是为了缓解在下游任务精调过程中出现灾难性遗忘(Catastrophic Forgetting
)问题。在下游任务精调的过程中,GPT的训练目标是优化下游任务数据集上的效果,更强调特殊性。因此,势必会对预训练阶段学习的通用知识产生部分的覆盖或擦除,丢失一定的通用性。通过结合下游任务精调损失和预训练任务损失,可以有效地缓解灾难性遗忘问题。
适配不同的下游任务
不同任务之间的输入形式各不相同,应当根据不同任务适配GPT的输入形式。
下面是4中典型任务在GPT中的输入输出形式,其中包括:单句文本分类、文本蕴含、相似度计算和选择型阅读理解。
(1)单句文本分类
假设输入为
x
=
x
1
.
.
.
x
n
x=x_1...x_n
x=x1...xn,单句文本分类的样例将通过如下形式输入到GPT中:
<
s
>
x
1
x
2
.
.
.
x
n
<
e
>
<s> x_1 x_2 ... x_n <e>
<s>x1x2...xn<e>(2)文本蕴含
文本蕴含的输入由两段文本构成,输出由分类标签构成,用于判断两段文本之间的蕴含关系。需要注意的是,文本蕴含中的前提(Premise
)和假设(Hypothesis
)是有序的,两者的顺序必须固定。
<
s
>
x
1
(
1
)
,
x
2
(
1
)
.
.
.
x
n
(
1
)
$
x
1
(
2
)
,
x
2
(
2
)
.
.
.
x
m
(
2
)
<
e
>
<s> x_1^{(1)},x_2^{(1)}... x_n^{(1)}\$x_1^{(2)},x_2^{(2)}... x_m^{(2)}<e>
<s>x1(1),x2(1)...xn(1)$x1(2),x2(2)...xm(2)<e>(3)相似度计算
相似度计算也是由两段文本构成,但与文本蕴含任务不同的是,参与相似度计算的两段文本之间不存在顺序关系。经两段序列输入GPT中,得到两个相应的隐含层表示,最终将两个隐含层相加,并通过一个全连接层预测相似度。
<
s
>
x
1
(
1
)
,
x
2
(
1
)
.
.
.
x
n
(
1
)
$
x
1
(
2
)
,
x
2
(
2
)
.
.
.
x
m
(
2
)
<
e
>
<s> x_1^{(1)},x_2^{(1)}... x_n^{(1)}\$x_1^{(2)},x_2^{(2)}... x_m^{(2)}<e>
<s>x1(1),x2(1)...xn(1)$x1(2),x2(2)...xm(2)<e>
<
s
>
x
1
(
2
)
,
x
2
(
2
)
.
.
.
x
m
(
2
)
$
x
1
(
1
)
,
x
2
(
1
)
.
.
.
x
n
(
1
)
<
e
>
<s> x_1^{(2)},x_2^{(2)}... x_m^{(2)}\$x_1^{(1)},x_2^{(1)}... x_n^{(1)}<e>
<s>x1(2),x2(2)...xm(2)$x1(1),x2(1)...xn(1)<e>(4)选择型阅读理解
选择型阅读理解是让机器阅读一篇文章,并且需要从多个选项中选择出问题对应的正确选项,即需要将(篇章、问题、选项)作为输入,以正确选项编号作为标签。假设篇章为
p
=
p
1
p
2
.
.
.
p
n
p=p_1 p_2...p_n
p=p1p2...pn,问题为
q
1
q
2
.
.
.
q
m
q_1q_2...q_m
q1q2...qm,第i个选项为
c
i
=
c
1
i
c
2
i
.
.
.
c
k
i
c^{i}=c_1^{i} c_2^{i}...c_k^{i}
ci=c1ic2i...cki,并假设选项个数为N:
<
s
>
p
1
p
2
.
.
.
p
n
$
q
1
q
2
.
.
.
q
m
$
c
1
1
c
2
1
.
.
.
c
k
1
<
e
>
<s>p_1p_2...p_n\$q_1q_2...q_m\$c_1^{1} c_2^{1}...c_k^{1}<e>
<s>p1p2...pn$q1q2...qm$c11c21...ck1<e>
<
s
>
p
1
p
2
.
.
.
p
n
$
q
1
q
2
.
.
.
q
m
$
c
1
2
c
2
2
.
.
.
c
k
2
<
e
>
<s>p_1p_2...p_n\$q_1q_2...q_m\$c_1^{2} c_2^{2}...c_k^{2}<e>
<s>p1p2...pn$q1q2...qm$c12c22...ck2<e>
.
.
.
...
...
<
s
>
p
1
p
2
.
.
.
p
n
$
q
1
q
2
.
.
.
q
m
$
c
1
3
c
2
3
.
.
.
c
k
3
<
e
<s>p_1p_2...p_n\$q_1q_2...q_m\$c_1^{3} c_2^{3}...c_k^{3}<e
<s>p1p2...pn$q1q2...qm$c13c23...ck3<e将(篇章,问题,选项)作为输入,通过
G
P
T
GPT
GPT建模得到对应的隐含层表示,并通过全连接层得到每个选项的得分。最终,将
N
N
N个选项的得分拼接,通过
S
o
f
t
m
a
x
Softmax
Softmax函数得到归一化的概率(单选题),并通过交叉熵损失函数学习。
GPT2:语言模型是无监督的多任务学习器。
将不同形式的自然语言处理任务重定义为文本生成实现模型的通用化。
亮点:zero-shot,在下游任务中不做训练。
Prompt提示做什么任务,以自然语言描述或者指令作为前缀表征目标任务。
GPT3:语言模型是少样本学习者
GPT3是一篇技术报告。
GPT3不做任何梯度更新和微调,就能够在只有少量目标任务标注样本的情况下进行很好的泛化。
GPT3主要展示的是超大规模语言模型的小样本学习(Few-shot learning
)能力。
自回归模型为什么会有小样本学习的能力呢?其关键在于数据本身的有序性,使得连续出现的序列数据往往会蕴含着同一任务的输入输出模式。
“上下文学习”:
语言模型的学习过程实际上可以看做从很多不同的任务中进行元学习的过程。
语言模型在一个序列上的训练为一次内循环(Inner loop
),也称为In-Context Learning
。模型在不同的序列上的训练则对应元学习的外循环(Outer loop
),起到了在不同任务之间泛化的作用,以避免模型过拟合至某一个特定任务。数据的规模和质量对于GPT-3的小样本学习能力起到了关键的作用。
由于需要以少量标注样本作为条件,因此,GPT-3模型的输入序列可能较长。GPT-3使用了大小为2048的输入,相较于其他模型,其对于内存、计算量的要求都要更高。
损失随着计算量的指数增加而线性下降。
总结,语言模型可以暴力出奇迹。
BERT
BERT(Bidirectional Encoder Representation from Transformers
)是由Google在2018年提出的基于深层Transformer的预训练语言模型。BERT不仅充分利用了大规模无标注文本来挖掘其中丰富的语义信息,同时还进一步加深了自然语言处理模型的深度。
BERT的基本模型结构由多层Transformer构成,包含两个预训练任务:掩码语言模型(Masked Language Model, MLM
)和下一个句子预测(Next Sentencce Prediction, NSP
)。
模型的输入由两段文本 x 1 x^{1} x1和 x 2 x^{2} x2拼接组成,然后通过BERT建模上下文的语义表示,最终学习掩码语言模型和下一个句子预测。需要注意的是,掩码语言模型对输入形式并没有特别要求,可以是一段文本也可以是两段文本。而下一个句子预测要求模型的输入是两段文本。因此,BERT在预训练阶段的输入形式统一为两段文本拼接的形式。
在BERT训练中主要改变了transformer层数、隐藏层维度和多头个数,模型主要分为BERT-large和BERT-base。
BERT模型可学习参数的计算,字典大小30k,q、k、v的投影矩阵在每个头之间合并之后是一个HH的参数,拿到输出之后会再投影到HH,得到 4 ∗ H 2 4*H^2 4∗H2,紧接着两个MLP的大小是 H 2 H^2 H2*8,紧接着乘以层数 L L L,可以大概算出BERT-base和BERT-large的参数量。
使用 W o r d P i e c e WordPiece WordPiece的原因是可以使用一个相对小的词典,因为词典过大会让大部分学习的参数都集中在词嵌入层。
BERT的输入表示(Input Representation
)由词向量(Token Embeddings
)、块向量(Segment Embeddings
)和位置向量(Position Embeddings
)之和组成:
为了计算方便,这三种向量的维度相同均为
e
e
e,输入序列对应的输入表示
v
v
v为:
v
=
v
t
+
v
s
+
v
p
v = v^{t} + v^{s} + v^{p}
v=vt+vs+vp(1)词向量
与传统神经网络模型类似,BERT中的词向量同样通过词向量矩阵将输入文本转换为实值向量表示,假设输入序列
x
x
x对应的独热向量表示为
e
t
e^t
et,其对应的词向量表示
v
t
v^{t}
vt为:
v
t
=
e
t
W
t
v^{t}=e^tW^t
vt=etWt(2)块向量
块向量用来编码当前词属于哪一个块(Segment
)。输入序列中每个词对应的块编码(Segment Encoding
)为当前词所在的块的序号(从0开始计数)。
- 当输入序列是单个块的时候(如单句文本分类),所有词的块编号均为0;
- 当输入序列是两个块时(如句对文本分类),第一个句子中每个词对应的块编码为0,另一个为1。