NLP中的语言模型预训练相关总结
前言
语言模型的预处理主要是在各种NLP任务(翻译任务, QA, 实体识别等等)中作为上游任务出现的,用来获取语句的embedding向量, 从而作为下游模型的输入. 本文对最近看的一些博文中有关LM预处理的模型进行总结及阐述
one-hot 模型
最简单的表示一个词的向量就是one-hot, 如果语料库中有3个词(I love you), one-hot进行如下编码
I: (001) love(010) you(100)
word2vec模型
我们首先了解一下LM, LM等价于一串词对应的一连串概率分布
{… P(w5|w4,w3), P(w6|w5,w4), P(w7|w6,w5)…}-------(1)
我们可以离散的计算(1) 但是会遇到数据稀疏的问题:
P
(
w
5
∣
w
4
,
w
3
)
=
c
o
u
n
t
(
w
3
,
w
4
,
w
5
)
c
o
u
n
t
(
w
3
,
w
4
,
a
n
y
t
h
i
n
g
P(w5|w4,w3)=\frac{count(w3,w4,w5)}{count(w3,w4,anything}
P(w5∣w4,w3)=count(w3,w4,anythingcount(w3,w4,w5)
进一步我们可以利用三层前馈神经网络来进行建模 从而训练 计算概率分布
(其实其他获取更好的embedding目标的方法都是基于能建立一个能比较好描述LM的模型, 也就是尽可能通过模型的获得准确的概率分布(1) 在寻找模型的过程中也就获得了word embedding 的表示 这也就是 语言模型指导的预训练 的意思)
(标准的语言模型目标函数,即通过前k个词预测当前词)
主要有两种网络: CBOW(上下文=>缺省词) and skip-gram(缺省词=>上下文)
此时我们有趣的发现利用network的第一层参数可以很好的表示词向量, 不仅低维紧密,而且能够蕴涵语义, 于是导出了新的embedding方法=> word2vec
优缺点: 比one-hot方法获得的维度低很多 并且能包含语义 但是是上下文无关的静态embedding 理想的动态embedding 应该对不同语义的apple有不同的embedding
ELMO模型
Embedding from Language Model
ELMo本质上是用一个多层双向的LSTM网络训练语言模型,最后的representation是每层LSTM状态的线性组合。(并不是像w2v取静态的权重作为token的唯一表示)
我们首先来看LSTM结构(long-short term memory RNN)–用来解决一般的RNN训练过程中因为序列过长产生的梯度消失以及梯度爆炸(梯度:下降最快的方向 和偏导有关 梯度具有传递性)
c
t
:
c
e
l
l
s
t
a
t
e
表
示
长
时
间
状
态
∣
∣
h
t
:
h
i
d
d
e
n
s
t
a
t
e
表
示
短
时
状
态
∣
∣
y
t
:
输
出
由
h
i
d
d
e
n
s
t
a
t
e
产
生
c^t:cell state表示长时间状态||h^t:hidden state 表示短时状态 \\||y^t:输出 由hidden state产生
ct:cellstate表示长时间状态∣∣ht:hiddenstate表示短时状态∣∣yt:输出由hiddenstate产生
我们再来看ELMO 可以清楚的看到由一个前向和一个后向语言模型构成,目标函数就是取这两个方向语言模型的最大似然
对于kth token我们可以有L+1个向量来表示:
R
k
=
{
X
k
L
M
,
h
k
,
j
L
M
}
:
X
k
L
M
=
>
k
t
h
t
o
k
e
n
的
初
始
e
m
b
e
d
d
i
n
g
h
k
,
j
L
M
=
>
k
t
h
t
o
k
e
n
+
j
t
h
l
a
y
e
r
o
u
t
p
u
t
(
左
右
拼
接
以
后
)
=
>
R
k
=
{
h
k
,
j
L
M
∣
j
=
0...
L
}
R_k=\{X_k^{LM},h_{k,j}^{LM}\}:\\X_k^{LM}=>kth\, token的初始embedding \\h_{k,j}^{LM}=>kth\,token+jth\,layer\,output(左右拼接以后) \\=>R_k=\{h_{k,j}^{LM}|j=0...L\}
Rk={XkLM,hk,jLM}:XkLM=>kthtoken的初始embeddinghk,jLM=>kthtoken+jthlayeroutput(左右拼接以后)=>Rk={hk,jLM∣j=0...L}
对Rk进行加权合并即可获得kth token的embedding
对于下游监督学习的NLP任务,对于给定的的Bi-LM模型,我们首先freeze双向语言模型参数,学习ELMo中的softmax后的线性权重参数 s j t a s k s_j^{task} sjtask和scaling系数 γ t a s k γ^{task} γtask,计算得到ELMo的输出作为具体下游任务的输入,并且同时下游任务的具体参数也同时进行学习
动态原因:对词义消歧有需求的任务就更容易通过训练给第二隐层一个很大的权重,而对词性、句法有明显需求的任务则可能对第一隐层的参数学习到比较大的值
优点:1. 一次多义问题 2. 双向LSTM语言模型,比word2vec一个固定窗口,得到句子更长的依赖关系
缺点:1 lstm对LM建模不如attention model 2. 双向模型只是在最高层拼接 特征融合能力弱
Open AT GPT
Improving Language Understanding by Generative Pre-Training
- 利用了Transformer网络代替了LSTM作为语言模型来更好的捕获长距离语言结构
首先我们来看一看Transformer网络=>最开始是《Attention is all your need》被提出来 用来处理翻译任务的模型 总体上包含encoder和decoder两部分:
1.1. encoder
1.1.1. 编码器接收原语种的句子作为输入 进行embedding
1.1.2. 经过position encoding(embedding+position encoding=embedding with time signal)
1.1.3. 开始multi-head attention:
attention实质上就是对(查询Q, 键K, 键值 V)对每个查询计算每个键对应的键值(重要的大一点 体现attention)
self-attention: (Q,K,V)基于同一个X (输入embedding)=>Q和K相关,同一个句子
Q
1
=
X
∗
W
1
Q
K
1
=
X
∗
W
1
K
V
1
=
X
∗
W
1
V
Q1=X*W^Q_1\\K1=X*W^K_1\\V1=X*W^V_1
Q1=X∗W1QK1=X∗W1KV1=X∗W1V
Z 1 = s o f t m a x ( Q 1 ∗ K 1 T d k ) ∗ V 1 ( d k : k e y 向 量 的 维 度 是 64 维 , 其 平 方 根 = 8 , 这 样 可 以 使 得 训 练 过 程 中 具 有 更 稳 定 的 梯 度 ) Z1=softmax(\frac{Q1*K1^T}{\sqrt{d_k}})*V1\\(d_k:key向量的维度是64维,其平方根=8,\\这样可以使得训练过程中具有更稳定的梯度) Z1=softmax(dkQ1∗K1T)∗V1(dk:key向量的维度是64维,其平方根=8,这样可以使得训练过程中具有更稳定的梯度)
通过multi-headed attention,我们为每个“header”都独立维护一套Q/K/V的权值矩阵=>得到Zi结果矩阵, 加权后得到Z矩阵
1.1.4. add&normal
我们首先了解一下residuals 和layer normalization:
residuals:残差连接(skip connect) 将输出表述为输入和输入的一个非线性变换的线性叠加(解决梯度消散 d h d x = d ( f + x ) d x = 1 + d f d x \frac{dh}{dx}=\frac{d(f+x)}{dx}=1+\frac{df}{dx} dxdh=dxd(f+x)=1+dxdf)
layer normalization: 在同一句话中对不同的token的embedding同时进行normalization(不同于BN)
因此当前操作即为
L
a
y
e
r
N
o
r
m
a
l
(
X
+
Z
)
LayerNormal(X+Z)
LayerNormal(X+Z)
1.1.5 feed forward
Self-attention的输出会被传入一个全连接的前馈神经网络,每个encoder的前馈神经网络参数个数都是相同的,但是他们的作用是独立的。
1.2. decoder:
特别的通过一层encoder-decoder attention连接encoder和decoder, 不同于self-attention 这里的(K,V) 基于encoder输出的原句的embedding, 同时我们需要previous outputs通过一层self-attention&&add with normal得到Q=>利用上述的(Q,K,V)进行attention+AN+feed forward+AN 获得新的embedding, 这样就是一个基本的decoder;
最后, 将decoder级联后的输出通过linear+softmax层预测下一个token
(线性层是一个简单的全连接神经网络,它是由Decoder堆栈产生的向量投影到一个更大,更大的向量中,称为对数向量=>在线性层之后是一个softmax层,softmax将这些分数转换为概率。选取概率最高的索引,然后通过这个索引找到对应的单词作为输出)
以上就是关于transformer 的介绍, 其实使用的时候可以只使用encoder或decoder 但要注意encoder是整个句子互连的(self-attention:编码当前token时要考虑到句子中其他的左右的tokens) 而decoder是从左到右受限的transformer(encoder-decoder attention)
- 具体到GPT 使用了decoder 因此只是单向的
-
Pretrain without supervision:利用标准的LM目标函数进行训练;
Supervised fine-tuning: 与ELMO把输出当作特征不同 GPT直接在原模型上增加Linear&&softmax作为任务输出层 并且可能使用LM作为辅助任务提高泛化能力并加速收敛:
L
3
(
C
)
=
L
2
(
C
)
+
λ
∗
L
1
(
C
)
=
>
两
种
任
务
目
标
L_3(C)=L_2(C)+\lambda*L_1(C)=>两种任务目标
L3(C)=L2(C)+λ∗L1(C)=>两种任务目标
Bert
BERT : Pre-training of Deep Bidirectional Transformers for Language Understanding
(老大哥终于来了aha)
整体框架和GPT类似,是进一步的发展。具体的,他们BERT是使用Transformer的编码器来作为语言模型,在语言模型预训练的时候,提出了两个新的目标任务(即遮挡语言模型MLM和预测下一个句子的任务)替代了原来的LM目标
ELMo使用的是双向LSTM,虽然是双向的,但是也只是在两个单向的LSTM的最高层进行简单的拼接, 只有BERT是真正在模型所有层中是双向的。
输入细节:(加入了位置向量和句子切分向量 以及[CLS] [SEP]占位符)
MLM可以从任何方向去预测这些挡上的词,而不仅仅是单向的。但是这样做会带来两个缺点:1)预训练用[MASK]提出挡住的词后,在微调阶段是没有[MASK]这个词的,所以会出现不匹配;(可以部分[mask] 减少mask比例) 2)预测15%的词而不是预测整个句子,使得预训练的收敛更慢。但是对于第二点,作者们觉得虽然是慢了,但是效果提升比较明显可以弥补。
第二个目标任务就是预测下一个句子。其实就是一个二元分类问题,50%的时间,输入一个句子和下一个句子的拼接,分类标签是正例,而另50%是输入一个句子和非下一个随机句子的拼接,标签为负例。
总结
总的来说, 在解决语言模型目标函数的过程的 我们由最开始的one-hot, word2vec 逐步扩展到后来的ELMO GPT 以及bert结构 通过这些结构的预训练 我们能获取到包含更多上下文信息更丰满的word embedding 从而为下游任务提供更好的input. 当然到后期我们解决LM目标函数object 也变成了更有效的MLM object(双向性)与predict-next-sentence object(句间关系).
到这里本文就大概梳理完了有关NLP预训练的一些的方法 当然还有一些其它的新的变体啦 就不过分深究了aha
参考资料
https://zhuanlan.zhihu.com/p/103361361
https://www.cnblogs.com/robert-dlut/p/9824346.html
https://blog.csdn.net/qq_42890800/article/details/111501057
https://zhuanlan.zhihu.com/p/42833949