UNILM全名Unified Language Model Pre-training for Natural Language Understanding and Generation。NU直接用BERT做,NLG直接把BERT的 S1 [SEP] S2 当成 encoder-decoder,虽然没有那个结构,但是心中有那个思想。
seq-to-seq LM中的mask矩阵代码实现
这里的0标记的是上图的
s
1
s_{1}
s1部分的位置,1标记的是上图的
s
2
s_{2}
s2部分的位置。
import keras.backend as K
import tensorflow as tf
s=[[0,0,0,1,1],[0,0,1,1,1]]
idxs = K.cumsum(s, axis=1)
mask =idxs[:, None, :] <= idxs[:, :, None]
mask = K.cast(mask, K.floatx())
with tf.Session() as sess:
a=sess.run(mask)
print(a)
运行结果:
mask =
[[[1. 1. 1. 0. 0.]
[1. 1. 1. 0. 0.]
[1. 1. 1. 0. 0.]
[1. 1. 1. 1. 0.]
[1. 1. 1. 1. 1.]]
[[1. 1. 0. 0. 0.]
[1. 1. 0. 0. 0.]
[1. 1. 1. 0. 0.]
[1. 1. 1. 1. 0.]
[1. 1. 1. 1. 1.]]]
解析过程:
首先进行
idxs = K.cumsum(s,axis=1)
得到对应的idxs
[[0 0 0 1 2]
[0 0 1 2 3]]
接着进行调用
mask = idxs[:,None,:] <= idxs[:,:None]
这里的
idxs[:,None,:] =
[[[0 0 0 1 2]]
[[0 0 1 2 3]]]
idxs[:,:,None] =
[[[0]
[0]
[0]
[1]
[2]]
[[0]
[0]
[1]
[2]
[3]]]
以
[[[0 0 0 1 2]]]
与
[[[0]
[0]
[0]
[1]
[2]]]
进行对比,
(1)前三列都是用
[0]
与
[0]
[0]
[0]
[1]
[2]
进行对比,小于等于完全成立,所以前三列为全1矩阵
(2)将
[1]
与
[0]
[0]
[0]
[1]
[2]
判断小于等于,得到矩阵
[0]
[0]
[0]
[1]
[1]
可以看出,当前位置之后的向量全部置1,而当前位置之前的向量全部置0。
left-to-right LM中的mask矩阵代码实现
import keras.backend as K
import tensorflow as tf
s=[[0,0,0,1,1]]
seq_len = K.shape(s)[1]
idxs = K.arange(0, seq_len)
mask = idxs[None, :] <= idxs[:, None]
mask = K.cast(mask, K.floatx())
with tf.Session() as sess:
a=sess.run(mask)
print(a)
运行结果:
[[1. 0. 0. 0. 0.]
[1. 1. 0. 0. 0.]
[1. 1. 1. 0. 0.]
[1. 1. 1. 1. 0.]
[1. 1. 1. 1. 1.]]
这里的left-to-right mask不再需要考虑本身s的值了,而是只需要用到s矩阵的形状即可。
Unilm中softmax的对应公式
Unilm中softmax的对应公式为
A
l
=
s
o
f
t
m
a
x
(
Q
K
T
d
k
+
M
)
V
l
A_{l} = softmax(\frac{QK^{T}}{\sqrt{d_{k}}}+M)V_{l}
Al=softmax(dkQKT+M)Vl
假设最大长度为128,批次为5,
则Q = (5,128,12,64),K = (5,128,12,64),翻转之后的内容为
Q = (5,12,128,64),K = (5,12,64,128),
Q
∗
K
T
=
(
5
,
12
,
128
,
64
)
∗
(
5
,
12
,
64
,
128
)
=
(
5
,
12
,
128
,
128
)
Q*K^{T} = (5,12,128,64)*(5,12,64,128) = (5,12,128,128)
Q∗KT=(5,12,128,64)∗(5,12,64,128)=(5,12,128,128),此时将每一个句子长度暴露在最后构成三角矩阵之后,就可以加上mask矩阵得到最终的结果。
这里解析一下为什么(5,12,128,128)一个四维度的矩阵,只需要加上(5,128,128)一个mask的掩码即可
因为这里的12本质上是由768维度获得的,也就是说12是由128中的数值生成的,所以加上同样维度的掩码即可。