前言
Google又出新作Bert:Pre-training of Deep Bidirectional Transformers,在11项测试中取得了牛逼的效果。主要是将之前的Transform加上更为泛化的预训练,得到了很好的语言表达模型。
预训练方法
1) input data

预训练分为两块,一个是随机遮挡词的预测;一个是下句话的预测。
2) Masked Language Model
遮挡15%的词并替换为[mask]/origin_token/random_token,只预测遮挡发生的位置词。在预测某个词时,所有被遮挡的词们是无法被模型看到的,只能看到[mask]标记。其中遮挡也是分情况的,如下:
a) 80%的概率,遮挡词被替换为[mask]。
⟶
\longrightarrow
⟶别人看不到我。
b) 10%的概率,遮挡词被替换为随机词。
⟶
\longrightarrow
⟶别人看走眼我。
c) 10%的概率,遮挡词被替换为原来词。
⟶
\longrightarrow
⟶别人能看到我。
为什么要这样替换呢?有什么道理么~降低了可视域的难度。
从左到右,实际上也是有遮挡的,相当于遮挡了一侧。而这里的遮挡则仅有12%的遮挡,1.5%的误导,1.5%的无碍。Transformer全局的可视,又增加了信息的获取,但是不让模型获取全量信息。
注意:有参数dupe_factor决定数据duplicate的次数
其中,create_instance_from_document函数,是构造了一个sentence-pair的样本。对每一句,先生成[CLS]+A+[SEP]+B+[SEP],有长(0.9)有短(0.1),再加上mask,然后做成样本类object。
注意:create_masked_lm_predictions函数返回的tokens是已经被遮挡词替换之后的tokens了,masked_lm_labels则是遮挡词对应位置真实的label。
3) Next Sentence Prediction
根据真实文本,构造如下样本,并做预测。
个人感觉,Bert就是在各种倒腾训练预料,先是用Mask来提高视野范围的信息获取量,又觉得对其他非mask词不公平,增加duplicate再随机Mask,这样跟RNN类方法依次训练预测没什么区别了除了mask不同位置外;全局视野极大地降低了学习的难度,再想办法提高下难度,于是用A+B/C来作为样本,这样每条样本都有50%的概率看到一半左右的噪声;但是直接学习Mask A+B/C是没法学习的,因为不知道哪些是噪声,所以又加上next_sentence预测任务,与MLM同时进行训练,这样用next来辅助模型对噪声/非噪声的辨识,用MLM来完成语义的大部分的学习。上个手绘图来解释下。

3) Bert, GTP, ELMo方法比较

所谓从左到右,是指在训练预测时仅依赖左侧信息;从右向左则反之。而Bert则时从遮挡词预测时,可以充分利用左右两侧信息,而不必仅关注一侧信息。【GPT是借助Transformer结构,其中的解码有个mask动作,强制保证只使用一侧信息;而Bert是省掉了Transformer中的Decoder,只用Encoder部分,所以收取信息时左右开弓。】
补充1:Transformer
这个模型,来自17年的"attention is all you need",非常吸睛的取名方式。Position Embedding是关键,也是舍弃RNN结构之后为弥补位置信息而做的改动。

P
E
(
p
o
s
,
2
i
)
=
s
i
n
(
p
o
s
/
1000
0
2
i
/
d
m
o
d
e
l
)
PE(pos, 2i)=sin(pos/10000^{2i/d_{model}})
PE(pos,2i)=sin(pos/100002i/dmodel)
P
E
(
p
o
s
,
2
i
+
1
)
=
c
o
s
(
p
o
s
/
1000
0
2
i
/
d
m
o
d
e
l
)
PE(pos, 2i+1)=cos(pos/10000^{2i/d_{model}})
PE(pos,2i+1)=cos(pos/100002i/dmodel)
其中
i
i
i是映射的维度,
d
m
o
d
e
l
d_{model}
dmodel是输入的维度,
p
o
s
pos
pos是待计算的位置。
注意:其中每个子层都有Normalized和skip-connect。

上面右侧是左侧的h倍复制,其中Scaled是为避免点乘过大使得进入函数饱和区域,而用
1
d
k
\frac{1}{\sqrt{d_k}}
dk1作加权。多头则是对输入做多次平行变换,然后加上attention层,输出concate到一起。
解码时,mask的含义是:“This masking, combined with fact that the output embeddings are offset by one position, ensures that the predictions for position i can depend only on the known outputs at positions less than i.”预测输出时,是依次预测的。第一层解码器的attention相当于self-attention,后续解码器的attention是编码器的key+value +上层解码输出作query构成的。
Transformer的预测动态图如下

补充2:GPT
OpenAI 的GPT:Generative Pre-Traininig通过预训练来提升语义理解,并指出预训练是文本语言理解中尤其重要。并期望预训练学习到的通用表示,能够被尽量小地修改就可以适配到新的不同学习任务中。

无监督预训练
仍然是窗口内的词出现概率的最大似然估计,不过是基于Transfor结构的word2vec的学习。
L
1
(
{
u
}
)
=
∑
i
l
o
g
P
(
u
i
∣
u
i
−
k
,
.
.
.
,
u
i
−
1
;
θ
)
L_1(\{u\}) = \sum_i log P(u_i|u_{i-k}, ..., u_{i-1}; \theta)
L1({u})=i∑logP(ui∣ui−k,...,ui−1;θ)
使用多层 Mult-headed Self-Attention Transformer作为语言模型,如下:
{
h
0
=
U
W
e
+
W
p
h
l
=
t
r
a
n
s
f
o
r
m
e
r
_
b
l
o
c
k
(
h
l
−
1
)
∀
i
∈
[
1
,
n
]
P
(
u
)
=
s
o
f
t
m
a
x
(
h
n
W
e
T
)
\left\{\begin{matrix} h_0 &= UW_e+W_p \\ h_l &= transformer\_block(h_{l-1}) \forall i \in [1,n] \\ P(u) &= softmax(h_n W_e^T) \end{matrix}\right.
⎩⎨⎧h0hlP(u)=UWe+Wp=transformer_block(hl−1)∀i∈[1,n]=softmax(hnWeT)
W
e
W_e
We是词向量矩阵,
W
p
W_p
Wp是位置向量矩阵,
t
a
n
s
f
o
r
m
e
r
_
b
l
o
c
a
k
tansformer\_blocak
tansformer_blocak是单层的多头自注意Transformer。
有监督的微调
主要在具体任务时作很小调整,将预训练的最后一层
h
l
m
h_l^m
hlm + 全连接层 接入具体任务,并加入了无监督学习时的loss作辅助。
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)
L
2
(
C
)
=
∑
(
x
,
y
)
l
o
g
P
(
y
∣
x
1
,
x
2
,
.
.
.
,
x
m
)
⟶
P
(
y
∣
{
x
}
)
=
s
o
f
t
m
a
x
(
h
l
m
W
y
)
L_2(C) = \sum_{(x,y)}log P(y|x^1, x^2, ..., x^m) \longrightarrow P(y|\{x\})=softmax(h_l^m W_y)
L2(C)=∑(x,y)logP(y∣x1,x2,...,xm)⟶P(y∣{x})=softmax(hlmWy)
{
x
}
=
{
x
1
,
.
.
.
,
x
m
}
\{x\}=\{x^1, ..., x^m\}
{x}={x1,...,xm}是输入词序列。在文中指出,只需3个epoch即可达到非常好的学习效果。加上语言模型的学习目标对调优来说,有助于增强有监督模型的泛化能力,并能加速收敛。
注意:在微调时,还需要学习调整
L
1
L_1
L1中的参数么?目测也随着任务做调整学习。
注意:其词特征不用单独抽取,而直接将最后层跟指定任务合并到一起。
补充3:ELMo
ELMo:Embeddings from Language Models同样在预训练上做了重要的工作,充分利用了DeepLSTM来学习词向量,听名字就知道是怎么表示词向量的。
∑
k
=
1
N
[
l
o
g
P
(
t
k
∣
t
1
,
.
.
.
,
t
k
−
1
;
θ
t
o
k
e
n
2
e
m
b
,
θ
→
L
S
T
M
,
θ
s
o
f
t
m
a
x
)
+
l
o
g
P
(
t
t
∣
t
k
+
1
,
.
.
.
,
t
N
;
θ
t
o
k
e
n
2
e
m
b
,
θ
←
L
S
T
M
,
θ
s
o
f
t
m
a
x
)
]
\sum_{k=1}^N [log P(t_k| t_1, ..., t_{k-1}; \theta_{token2emb}, \overrightarrow{\theta}_{LSTM}, \theta_{softmax}) +log P(t_t|t_{k+1}, ..., t_N; \theta_{token2emb}, \overleftarrow{\theta}_{LSTM}, \theta_{softmax})]
k=1∑N[logP(tk∣t1,...,tk−1;θtoken2emb,θLSTM,θsoftmax)+logP(tt∣tk+1,...,tN;θtoken2emb,θLSTM,θsoftmax)]
对每个词而言,
L
−
l
a
y
e
r
L-layer
L−layer层的双向LM,计算了一组隐状态集
R
k
=
{
x
k
,
h
→
k
,
j
,
h
←
k
,
j
∣
j
=
1
,
.
.
.
,
L
}
=
{
h
k
,
j
∣
j
=
0
,
1
,
.
.
.
,
L
}
R_k=\{x_k, \overrightarrow{h}_{k,j}, \overleftarrow{h}_{k,j}| j=1, ..., L \}=\{ h_{k,j}|j=0,1,...,L\}
Rk={xk,hk,j,hk,j∣j=1,...,L}={hk,j∣j=0,1,...,L}
其中
h
k
,
0
h_{k,0}
hk,0表示token2emb层,则通用的token权重计算如下
E
L
M
o
k
=
E
(
R
k
)
=
γ
∑
j
=
0
L
s
j
h
k
,
j
ELMo_k = E(R_k)=\gamma \sum_{j=0}^L s_j h_{k,j}
ELMok=E(Rk)=γj=0∑Lsjhk,j
其中
s
j
s_j
sj是sotmax的正则权重,在预训练之后使用时,则可以将
E
L
M
o
k
ELMo_k
ELMok与输入concate成新的输入;也可以将
E
L
M
o
k
ELMo_k
ELMok与倒数第二层合并,共同给输出层使用。
有个问题:若是 θ L S T M \theta_{LSTM} θLSTM参数也是共享的了,会怎样?
参考
- 2018 - 《Bert:Pre-training of Deep Bidirectional Transformers for
Language Understanding》 - 2018 - 《GPT:Improving Language Understanding by Generative Pre-Training》
- 2018 -《ELMo:Deep Contextualized Word Representation》
- 2017 - 《Transformer:Attention is all you need》
- https://kexue.fm/archives/4765
- https://github.com/google-research/bert
- https://github.com/jxyyjm/bert-as-service