为什么Attention中除以
d
\sqrt{d}
d这么重要? 对于两个d维向量q,k,假设它们都采样自“均值为0、方差为1”的分布,那么它们的内积的二阶矩是:
E
[
(
q
,
k
)
]
2
=
d
E[(q,k)]^{2}=d
E[(q,k)]2=d。由于均值也为0,所以这也意味着方差也是d。
Attention是内积后softmax,主要设计的运算是
e
q
⋅
k
e^{q⋅k}
eq⋅k,我们可以大致认为内积之后、softmax之前的数值在
−
3
d
-3\sqrt{d}
−3d到
3
d
3\sqrt{d}
3d这个范围内,由于d通常都至少是64,所以
e
3
d
e^{3\sqrt{d}}
e3d比较大而
e
−
3
d
e^{-3\sqrt{d}}
e−3d比较小,因此经过softmax之后,Attention的分布非常接近一个one hot分布了,这带来严重的梯度消失问题,导致训练效果差。
相应地,解决方法就有两个:
像NTK参数化那样,在内积之后除以
d
\sqrt{d}
d,使q⋅k的方差变为1,对应
e
3
e^3
e3,
e
−
3
e^{−3}
e−3都不至于过大过小,这样softmax之后也不至于变成one hot而梯度消失了,这也是常规的Transformer如BERT里边的Self Attention的做法
另外就是不除以
d
\sqrt{d}
d,但是初始化q,k的全连接层的时候,其初始化方差要多除以一个d,这同样能使得使q⋅k的初始方差变为1,T5采用了这样的做法。
对于复杂模型来说,参数的初始化显得尤为重要。糟糕的初始化,很多时候已经不单是模型效果变差的问题了,还更有可能是模型根本训练不动或者不收敛。在深度学习中常见的自适应初始化策略是Xavier初始化。 深度学习模型本身上就是一个个全连接层的嵌套,所以为了使模型最后的输出不至于在初始化阶段就过于“膨胀”或者“退化”,一个想法就是让模型在初始化时能保持模长不变。 正交矩阵是指满足
W
⊤
W
=
I
W^⊤W=I
W⊤W=I的矩阵,也就是说它的逆等于转置。正交矩阵的重要意义在于它在变换过程中保持了向量的模长不变.用数学公式来表达,就是设
W
∈
R
n
×
n
W\in \mathbb{R}^{n\times n}
W∈Rn×n是一个正交矩阵,而
x
∈
R
n
x\in \mathbb{R}^{n}
x∈Rn是任意向量,则x的模长等于
W
x
W_{x}
Wx的模长:
∥
W
x
∥
2
=
x
T
W
T
W
x
=
x
T
x
=
x
\left \| W_{x} \right \|^{2}=x^{T}W^{T}Wx=x^{T}x=x
∥Wx∥2=xTWTWx=xTx=x 这个想法形成的一个自然的初始化策略就是“以全零初始化b,以随机正交矩阵初始化W”
上面说的是输入和输出维度都是n的情况,如果输入是n维,输出是m维呢?这时候
W
∈
R
m
×
n
W\in \mathbb{R}^{m\times n}
W∈Rm×n,保持Wx模长不变的条件依然是
W
⊤
W
=
I
W^⊤W=I
W⊤W=I。
m<n时,这是不可能的;
推论四:当m≥n时,从任意的均值为0、方差为1/m的分布p(x)中独立重复采样出来的m×n矩阵,近似满足
W
⊤
W
=
I
W^⊤W=I
W⊤W=I(只需要把采样分布的方差改为1/m就好)。
sigmoid函数:W服从
U
[
−
96
n
i
+
n
i
+
1
,
96
n
i
+
n
i
+
1
]
U[-\sqrt{\frac{96}{n_{i}+n_{i+1}}},\sqrt{\frac{96}{n_{i}+n_{i+1}}}]
U[−ni+ni+196,ni+ni+196]
Relu函数:W服从
U
[
−
12
n
i
+
n
i
+
1
,
12
n
i
+
n
i
+
1
]
U[-\sqrt{\frac{12}{n_{i}+n_{i+1}}},\sqrt{\frac{12}{n_{i}+n_{i+1}}}]
U[−ni+ni+112,ni+ni+112]
这其中的奥妙主要在Attention矩阵之上。Attention实际上相当于将输入两两地算相似度,这构成了一个
n
2
n^2
n2大小的相似度矩阵(即Attention矩阵,n是句子长度,本节的Attention均指Self Attention),这意味着它的空间占用量是O(
n
2
n^2
n2)量级,相比之下,RNN模型、CNN模型只不过是O(n),所以实际上Attention通常更耗显存。 然而,有弊也有利,更大的空间占用也意味着拥有了更多的可能性,我们可以通过往这个O(
n
2
n^2
n2)级别的Attention矩阵加入各种先验约束,使得它可以做更灵活的任务。说白了,也就只有纯Attention的模型,才有那么大的“容量”去承载那么多的“花样”。
而加入先验约束的方式,就是对Attention矩阵进行不同形式的Mask,这便是本文要关注的焦点。
4.3 乱序语言模型
乱序语言模型是XLNet提出来的概念,它主要用于XLNet的预训练上。 乱序语言模型跟语言模型一样,都是做条件概率分解,但是乱序语言模型的分解顺序是随机的:
p
(
x
1
,
x
2
,
x
3
,
…
,
x
n
)
=
p
(
x
1
)
p
(
x
2
∣
x
1
)
p
(
x
3
∣
x
1
,
x
2
)
…
p
(
x
n
∣
x
1
,
x
2
,
…
,
x
n
−
1
)
=
p
(
x
3
)
p
(
x
1
∣
x
3
)
p
(
x
2
∣
x
3
,
x
1
)
…
p
(
x
n
∣
x
3
,
x
1
,
…
,
x
n
−
1
)
=
…
=
p
(
x
n
−
1
)
p
(
x
1
∣
x
n
−
1
)
p
(
x
n
∣
x
n
−
1
,
x
1
)
…
p
(
x
2
∣
x
n
−
1
,
x
1
,
…
,
x
3
)
p(x1,x2,x3,…,xn) =p(x1)p(x2|x1)p(x3|x1,x2)…p(xn|x1,x2,…,xn−1) =p(x3)p(x1|x3)p(x2|x3,x1)…p(xn|x3,x1,…,xn−1) =… =p(xn−1)p(x1|xn−1)p(xn|xn−1,x1)…p(x2|xn−1,x1,…,x3)
p(x1,x2,x3,…,xn)=p(x1)p(x2∣x1)p(x3∣x1,x2)…p(xn∣x1,x2,…,xn−1)=p(x3)p(x1∣x3)p(x2∣x3,x1)…p(xn∣x3,x1,…,xn−1)=…=p(xn−1)p(x1∣xn−1)p(xn∣xn−1,x1)…p(x2∣xn−1,x1,…,x3) 总之,x1,x2,…,xn任意一种“出场顺序”都有可能。原则上来说,每一种顺序都对应着一个模型,所以原则上就有n!个语言模型。而基于Transformer的模型,则可以将这所有顺序都做到一个模型中去! 实现某种特定顺序的语言模型,就将原来的下三角形式的Mask以某种方式打乱。正因为Attention提供了这样的一个n×n的Attention矩阵,我们才有足够多的自由度去以不同的方式去Mask这个矩阵,从而实现多样化的效果。
UNILM单个Bert模型完成Seq2Seq任务的思路: 添加上述形状的Mask,输入部分的Attention是双向的,输出部分的Attention是单向,满足Seq2Seq的要求,而且没有额外约束。这样做不需要修改模型架构,并且还可以直接沿用Bert的Masked Language Model预训练权重,收敛更快。这符合“一Bert在手,天下我有”的万用模型的初衷,个人认为这是非常优雅的方案。
《Attention is All You Need》浅读(简介+代码) RNN要逐步递归才能获得全局信息,因此一般要双向RNN才比较好;CNN事实上只能获取局部信息,是通过层叠来增大感受野;Attention的思路最为粗暴,它一步到位获取了全局信息:纯Attention!单靠注意力就可以。yt=f(xt,A,B) Attention层的好处是能够一步到位捕捉到全局的联系,因为它直接把序列两两比较(代价是计算量变为
O
(
n
2
)
O(n^2)
O(n2),当然由于是纯矩阵运算,这个计算量相当也不是很严重);相比之下,RNN需要一步步递推才能捕捉到,而CNN则需要通过层叠来扩大感受野,这是Attention层的明显优势。