✨陈千语✨都懂的自注意力机制

1 阅读8分钟

你的名字-001

大家好,我是半夏之沫 😁😁 一名金融科技领域的JAVA系统研发😊😊
我希望将自己工作和学习中的经验以最朴实最严谨的方式分享给大家,共同进步👉💓👈
👉👉👉👉👉👉👉👉💓写作不易,期待大家的关注和点赞💓👈👈👈👈👈👈👈👈


1. 注意力机制Attention

帝江号最近新招募了一位干员,名字叫汤汤

干员能力的高低,用能力值来表示,能力值的评定暂时基于干员的力量属性,下面是帝江号上已经招募的干员的力量属性和其能力值的对应关系。

PYrRu9L5lBwjs9qLB9idAlDyJz-9cuLAlZMXhPK0MZQ.jpg

现在已知汤汤的力量是207,那么汤汤能力值该如何计算。

塔卫二的守护者,巴别塔恶灵意志的传承者-管理员自然有一套计算方式。

hQmWAaWLpYaYIRuSGOgqQFMntJtqq2OyPMWrNTsPsWs.png

既然汤汤的力量是207,管理员觉得根据汤汤的力量去与已有干员的力量进行相关度系数计算,然后再分别将已有干员的能力值与相关度系数做加权求和,就可以得到汤汤的能力值,如下所示。

dAJx6z8FgT7T_PTdRUA3qcsECjZQ958ytTqQVm2x6pY.jpg

但是干员不仅仅有力量属性,还会有智力属性,如果靠力量评估干员的能力值,评判结果难以让干员信服,所以管理员基于力量智力,重新给已有干员做了能力值评估,如下所示。

Jpr376MbTnzR8yqQxX_Orwrhd4v5_k88aB5wCUziQ4U.jpg

已知汤汤的力量是207,智力是289,重新计算相关度系数,然后加权求和,得到汤汤的能力值如下所示。

H0UwYubGEShNsqg04QdsdL9h8NlJSilQdhp8YH9Qn4w.jpg

随着游戏版本来到3.0,干员属性的个数扩充到了12288,此时干员能力值的计算就变成下面这样。

TalpHiKXltV_J4uoBza1U-_NKyNsRpL35KVzcs5Npt4.jpg

在该情景下,要评判汤汤的能力值,需要参考已有干员的能力值情况,如果有一个干员的属性和汤汤的相似度,那么在评估汤汤的能力值时就应该更多的参考这个干员的能力值情况,即需要将更多注意力放在和汤汤属性相似度更高的干员身上,这就是注意力机制

2. 自注意力机制Self-Attention

现在管理员手下有一批干员,干员数量为50个,每个干员的属性个数有12288个。

50个干员的属性可以表示如下。

Z3AQ4QqcZxr1JeiJ5Mxa896PeDjzvRJrcefWQK03sEE.jpg

现在管理员觉得既然大家作为一个Team,彼此之间需要多交流切磋。

对于每个干员而言,都需要从自己的角度出发,判断自己对每个干员的注意力高低,自己注意的干员,就应该从这个干员身上学习一些属性。

陈千语此时犯了迷糊,问管理员怎么才能判断自己对每个干员的注意力高低呢,管理员说需要将更多的注意力给到和自己属性更加相似的干员。

当每个干员都根据各自对其他干员的注意力高低完成了属性学习后,每个干员的属性就会因为受到其他干员的影响而发生一点变化,下图展示了汤汤的属性变化过程。

x5zF2pPPGLN0z-Z0EW9SHFJ19_9H3BI8OuiDtBmc-jU.jpg

根据上面的变化过程,可以依次得到50个干员变化后的属性。

但这个时候管理员觉得还有问题,因为终末地里有很多副本,干员的属性在不同的副本里其实是需要调整的,所以干员间的注意力需要和干员在不同副本里的属性的相似度有关,此时管理员通过神经网络学习得到了三个矩阵。

  1. 其中一个矩阵是WqW_{q},将干员的12288维属性通过WqW_{q}做一次线性变换就能得到干员在影拓丰碑副本里面的12288维属性,称这组属性是qq属性;
  2. 其中一个矩阵是WkW_{k},将干员的12288维属性通过WkW_{k}做一次线性变换就能得到干员在协议空间副本里面的12288维属性,称这组属性是kk属性;
  3. 其中一个矩阵是WvW_{v},将干员的12288维属性通过WvW_{v}做一次线性变换就能得到干员在‌密境行者副本里面的12288维属性,称这组属性是vv属性。

现在重新展示汤汤的属性变化过程。

BJlhobDnNQvuE-lpJUy-WDTaZWxJzvu859mFt633oiU.jpg

根据上面的变化过程,可以依次得到50个干员变化后的属性。

50个干员的qq属性(查询向量Query)全部组合在一起就能得到一个50×1228850\times 12288QQ矩阵。

50个干员的kk属性(键向量Key)全部组合在一起就能得到一个50×1228850\times 12288KK矩阵。

50个干员的kk属性(值向量Key)全部组合在一起就能得到一个50×1228850\times 12288VV矩阵。

自注意力机制就是组内的每个干员都用自己在不同副本里的属性来和组内干员在不同副本里的属性计算相关度系数,相关度系数越高则表明对这个干员的注意力就需要越高,从而就应该学习这个干员更多的属性。

3. 多头自注意力机制Multi-head Self Attention

终末地更新了多个版本之后,管理员觉得之前的WqW_{q}WkW_{k}WvW_{v}不是那么好了,因为每个版本都有不同的副本,干员的属性在每个版本的不同副本里都应该得到调整,聪明的管理员立马想到了解决办法,那就是准备多组WqW_{q}WkW_{k}WvW_{v},因为现在已经更新了96个版本,所以管理员通过神经网络学习了96WqW_{q}WkW_{k}WvW_{v},并且聪明的管理员还将WW矩阵的维度从12288×1228812288\times 12288维降低到了12288×12812288\times 128,这样可以在计算相关度系数时极大的降低计算量。

引入了9612288×12812288\times 128维度的WqW_{q}WkW_{k}WvW_{v}后,再来看看汤汤的属性变化过程。

n9YD2O1IV3nZK2o4v2-NudU-_66MLkkSk89wLyfDki0.jpg

因为WqW_{q}WkW_{k}WvW_{v}的维度变成了12288×12812288\times 128,所以每个版本得到的属性向量只有128维,但一共有96个版本,所以把96个版本得到的属性向量全部拼接起来就可以还原回12288维的属性向量,最后通过一个12288×1228812288\times 12288维的WoW_{o}进行线性变换后,就可以得到汤汤的变换后的12288维属性向量。

这就是多头自注意力机制,在自注意力机制上将一组WqW_{q}WkW_{k}WvW_{v}扩展成了多组WqW_{q}WkW_{k}WvW_{v},让干员的属性能在不同版本的不同副本里进行相关度计算,最终干员的变换后的属性就包含其他干员在不同版本不同副本里的属性信息。

4. 公式补充

自注意力机制多用于计算一段文字中一个词对另一个词的依赖关系,从而让每个词都能聚合上下文信息。

将一段文字进行TokenizationEmbeddingPositional Encoding后,这段文字的每一个Token都可以表示成一个向量xx,这段文字的所有Token的向量可以表示成{xiRd}i=1t\left \{ x_{i}\in \mathbb{R}^{d} \right \}^{t}_{i=1},这里tt表示Token个数,dd表示每Token的向量维度。

自注意力机制中有三个元素,分别是查询qiq_{i}kik_{i}viv_{i},这三个元素是通过输入向量xx经过WqW_{q}WkW_{k}WvW_{v}线性变换依次得到的,表示如下。

xiWq=qix_{i} W_{q}=q_{i}

xiWk=kix_{i} W_{k}=k_{i}

xiWv=vix_{i} W_{v}=v_{i}

其中WqRd×dqW_{q} \in \mathbb{R}^{d\times d_{q}}WkRd×dkW_{k} \in \mathbb{R}^{d\times d_{k}}WvRd×dvW_{v} \in \mathbb{R}^{d\times d_{v}}{qiRdq}i=1t\left \{q_{i} \in \mathbb{R}^{d_{q}} \right \}^{t}_{i=1}{kiRdk}i=1t\left \{k_{i} \in \mathbb{R}^{d_{k}}\right \}^{t}_{i=1}{viRdv}i=1t\left \{v_{i} \in \mathbb{R}^{d_{v}}\right \}^{t}_{i=1}

如果要计算ii位置的Token需要聚合的上下文信息,首先需要将qiq_{i}分别与kk点积运算得到匹配分数,如下所示。

qik1q_{i}\cdot k_{1}

qik2q_{i}\cdot k_{2}

......

qiktq_{i}\cdot k_{t}

然后需要对所有匹配分数进行缩放,如下所示。

qik1d\frac{q_{i}\cdot k_{1}}{\sqrt{d} }

qik2d\frac{q_{i}\cdot k_{2}}{\sqrt{d} }

......

qiktd\frac{q_{i}\cdot k_{t}}{\sqrt{d} }

再然后SoftmaxSoftmax就得到了相关系数,如下所示。

eqik1dj=1teqikjd\frac{e^{\frac{q_{i}\cdot k_{1}}{\sqrt{d} }} }{\sum\limits_{j=1}^{t} e^{\frac{q_{i}\cdot k_{j}}{\sqrt{d} }}}

eqik2dj=1teqikjd\frac{e^{\frac{q_{i}\cdot k_{2}}{\sqrt{d} }} }{\sum\limits_{j=1}^{t} e^{\frac{q_{i}\cdot k_{j}}{\sqrt{d} }}}

......

eqiktdj=1teqikjd\frac{e^{\frac{q_{i}\cdot k_{t}}{\sqrt{d} }} }{\sum\limits_{j=1}^{t} e^{\frac{q_{i}\cdot k_{j}}{\sqrt{d} }}}

最后将相关度系数与{viRdv}i=1t\left \{v_{i} \in \mathbb{R}^{d_{v}}\right \}^{t}_{i=1}进行加权求和就可以得到ii位置的Token聚合完上下文信息后的向量ziz_{i}

zi=eqik1dj=1teqikjdv1+eqik2dj=1teqikjdv2+...+eqiktdj=1teqikjdvtz_{i}=\frac{e^{\frac{q_{i}\cdot k_{1}}{\sqrt{d} }} }{\sum\limits_{j=1}^{t} e^{\frac{q_{i}\cdot k_{j}}{\sqrt{d} }}}v_{1}+\frac{e^{\frac{q_{i}\cdot k_{2}}{\sqrt{d} }} }{\sum\limits_{j=1}^{t} e^{\frac{q_{i}\cdot k_{j}}{\sqrt{d} }}}v_{2} + ... + \frac{e^{\frac{q_{i}\cdot k_{t}}{\sqrt{d} }} }{\sum\limits_{j=1}^{t} e^{\frac{q_{i}\cdot k_{j}}{\sqrt{d} }}}v_{t}

上述计算过程就是下面公式的展开

Z=Attention(Q,K,V)=Softmax(QKTd)VZ=Attention(Q, K, V)=Softmax(\frac{QK^{T}}{\sqrt{d} } )V

在引入多头自注意力机制后,ii位置的Token的向量xix_{i}需要通过NNWqW_{q}WkW_{k}WvW_{v}线性变换到NN个不同表示子空间中,然后通过上述计算得到NNZ={ziRdv}i=1tZ=\left \{ z_{i}\in \mathbb{R}^{d_{v}} \right \}^{t}_{i=1}NNZZ首尾拼到一起可以得到{ziRNdv}i=1t\left \{ z_{i}\in \mathbb{R}^{Nd_{v}} \right \}^{t}_{i=1},最后将拼接得到的ZZ再通过一个WoRNdv×dW_{o} \in \mathbb{R}^{Nd_{v}\times d}做线性变换得到最终的输出,最终的输出中ii位置的Token就聚合了不同表示子空间中上下文的信息。


大家好,我是半夏之沫 😁😁 一名金融科技领域的JAVA系统研发😊😊
我希望将自己工作和学习中的经验以最朴实最严谨的方式分享给大家,共同进步👉💓👈
👉👉👉👉👉👉👉👉💓写作不易,期待大家的关注和点赞💓👈👈👈👈👈👈👈👈

你的名字-002