这个文篇包含了两类mask,一类是 padding mask ,另一类则是 future mask ,第一类是用来减小padding的反向梯度的避免网络主要训练padding符号,第二类是用来遮挡后面的符号,前面的符号只能和之前的做线性或者非线性运算,不能和以后的符号有关系。

要提到transformer的attention的mask,就需要先来看看train的过程,mask主要是用来缩小某些符号在训练的时梯度,像padding符号,可能很多很多,网络绝大多数时间都用来训练pad符号去了的,梯度主要往pad下降去了的,导致网络训练很难收敛,甚至不能收敛的,此时就需要使用mask来避免pad符号对train的影响。

RNN或者LSTM内避免pad符号的影响可以参考这个:

numpy实现RNN和LSTM循环神经网络产生古诗 - 知乎 (zhihu.com)

transformer在train模型的时候,输入的数据是(batchsize, sequence_length, embed_dim),这是已经做了embedding以后的结果,没有做embedding之前,是(batchsize, sequence_length)的样子,sequence_length是定长的但句子是不定长的,通常在train的时候,传入的数据,是文本段或者句子,但是每个句子或者文本段的长度都是不相同的,输入的时候要批量train,就需要padding句子或者段到等长,也就是sequence_length的长度。

Example:两个句子做输入

输入的数据
但是每个句子或者文本段

分词以及映射

首先需要做映射,字符或者词映射到数字,这边首先分词,【“输入的数据”】分词到【“输入 数据”】,【“但是每个句子或者文本段”】分词到【”但是 每个 句子 或者 文本 ”】,然后映射到数字即可,【“输入 数据 】映射到 [0, 1, 2,],【”但是 每个 句子 或者 文本 ”】映射到 [3, 4, 5, 6, 7, 10],拿到的数组是[[0, 1, 2],[3, 4, 5, 6, 7, 10]],这样的数组是不能送入网络train的,主要是大小不相同。需要做padding才可以,这里两个句子映射到不同的数字,主要是两个句子没有相同的词,所以数字都不相同。若是有相同的词,就需要映射到相同的数字才可以。

输入 的 数据  =====>   [0, 1, 2]
但是每个句子或者文本段 ======> [3, 4, 5, 6, 7, 10]

padding

首个句子需要做padding,少了三个数字,就需要padding三个pad符号,通常这个符号是记作"",也就是分词,然后padding,然后映射到数字就可以,padding符号映射到数字 666。padding以后就得到[[0, 1, 2, 666, 666, 666], [3, 4, 5, 6, 7, 10]],数组的大小是 2行6列,可以送到网络train

输入 的 数据 <PAD> <PAD> <PAD> =====>   [0, 1, 2, 666, 666, 666]
但是每个句子或者文本段 ======> [3, 4, 5, 6, 7, 10]

Embedding+Position_embedding

下面需要做的就是Embedding,Embedding层映射数字到向量,向量一般都是小数,最后还需要和position_embedding相加,拿到最后的输入,假设已经拿到了最后的输入向量,也就是经过了Embedding和position_embedding相加的向量,而且简便起见的话,这里假设只有一个输入句子,也就是batch=1,既然batch=1,那么就不需要进行pad了,可以直接送入到网络进行train,不妨假设输入的句子是:

输入 的 数据 =====>   [0, 1, 2]

embed_dim=2,也就是一个数字映射到2dim的向量,经过Embedding和position_embedding相加以后拿到的向量是,也就是【输入】对应到token【 a 1 , a 2 a_1,a_2 a1,a2 】,【的】对应到token【 d 1 , d 2 d_1,d_2 d1,d2】,【数据】对应到token【 c 1 , c 2 c_1,c_2 c1,c2 】。大小是1个batch3行2列即 [1, 3, 2],每一行对应一个token

[ 输入 的 数据 ] = [ 0 1 2 ] = [ a 1 a 2 d 1 d 2 c 1 c 2 ] \left[\begin{matrix}输入\\ 的\\数据\end{matrix}\right]=\left[\begin{matrix}0\\ 1\\2\end{matrix}\right]=\left[\begin{matrix}a_1&a_2\\ d_1&d_2\\c_1&c_2\end{matrix}\right] 输入数据 = 012 = a1d1c1a2d2c2

在attention计算以前的话,还需要在最后一个dim做layer_norm,也就是对每个token做layer_norm操作,但是要简便起见,这边省略掉这个步骤,其实对每个token做layer_norm操作,不同的token之间是没有影响的,也就是a还是a,d还是d。像 [ a 1 , a 2 ] [a_1,a_2] [a1,a2] 做layer_norm,也就是归一化操作,其他的token并不会影响到a。也就是,仍然是每一行对应一个token,(1, 3, 2)

KaTeX parse error: Expected 'EOF', got '_' at position 12: \text{layer_̲norm}\left(\lef…

Attention

这边开始做attention运算, attention ( Q , K , V ) = Softmax ( Q ⋅ K T d i ) ⋅ V \text{attention}(Q,K,V)=\text{Softmax}\left(\frac{Q\cdot K^T}{\sqrt{d_i}}\right)\cdot V attention(Q,K,V)=Softmax(di QKT)V

上面已经提到了,可以忽略掉layer_norm操作,不会影响对token的理解,所以这里假设对应的输入向量,还是

I N = [ 输入 的 数据 ] = [ a 1 a 2 d 1 d 2 c 1 c 2 ] IN=\left[\begin{matrix}输入\\ 的\\数据\end{matrix}\right]=\left[\begin{matrix}a_1&a_2\\ d_1&d_2\\c_1&c_2\end{matrix}\right] IN= 输入数据 = a1d1c1a2d2c2 ,不妨假设这里的输入向量是:IN

attention ( Q , K , V ) \text{attention}(Q,K,V) attention(Q,K,V) Q , K , V Q,K,V QKV 都是使用了full connect拿到的,也就是

Q = f c 1 ( ( [ a 1 a 2 d 1 d 2 c 1 c 2 ] ) Q=\large{fc_1}(\left(\left[\begin{matrix}a_1&a_2\\ d_1&d_2\\c_1&c_2\end{matrix}\right]\right) Q=fc1( a1d1c1a2d2c2 K = f c 2 ( ( [ a 1 a 2 d 1 d 2 c 1 c 2 ] ) K=\large{fc_2}(\left(\left[\begin{matrix}a_1&a_2\\ d_1&d_2\\c_1&c_2\end{matrix}\right]\right) K=fc2( a1d1c1a2d2c2 V = f c 3 ( ( [ a 1 a 2 d 1 d 2 c 1 c 2 ] ) V=\large{fc_3}(\left(\left[\begin{matrix}a_1&a_2\\ d_1&d_2\\c_1&c_2\end{matrix}\right]\right) V=fc3( a1d1c1a2d2c2

这边用Q来做example,这里不妨假设full connect的dim是2行2列,也就是[2, 2],输出是[1, 3, 2]

Q = [ a 1 a 2 d 1 d 2 c 1 c 2 ] ⋅ [ Q 0 Q 1 Q 2 Q 3 ] = [ a 1 Q 0 + a 2 Q 2 a 1 Q 1 + a 2 Q 3 d 1 Q 0 + d 2 Q 2 d 1 Q 1 + d 2 Q 3 c 1 Q 0 + c 2 Q 2 c 1 Q 1 + c 2 Q 3 ] Q=\left[\begin{matrix}a_1&a_2\\ d_1&d_2\\c_1&c_2\end{matrix}\right] \cdot \left[\begin{matrix}Q_0&Q_1\\ Q_2&Q_3\end{matrix}\right]=\left[\begin{matrix}a_1Q_0+a_2Q_2&a_1Q_1+a_2Q_3\\ d_1Q_0+d_2Q_2&d_1Q_1+d_2Q_3\\c_1Q_0+c_2Q_2&c_1Q_1+c_2Q_3\end{matrix}\right] Q= a1d1c1a2d2c2 [Q0Q2Q1Q3]= a1Q0+a2Q2d1Q0+d2Q2c1Q0+c2Q2a1Q1+a2Q3d1Q1+d2Q3c1Q1+c2Q3

可见,仍然是每一行对应一个token,而且每行的token只是自身的线性组合,不同的token之间并没有发生交互,也就是 Q 、 K 、 V Q、K、V QKV 的计算过程并不涉及到不同的token,而是每个token自身的线性组合

像第一行的token,还是a之间的组合并不涉及到d和c

上面还可以对 Q 、 K 、 V Q、K、V QKV 做简化版的表示,也就是向量化表示,看起来更加的直观,而且 表达了参加运算的向量或者权重矩阵 ,输出是[1, 3, 2]

Q = [ a 1 a 2 d 1 d 2 c 1 c 2 ] ⋅ [ Q 0 Q 1 Q 2 Q 3 ] = [ a 1 Q 0 + a 2 Q 2 a 1 Q 1 + a 2 Q 3 d 1 Q 0 + d 2 Q 2 d 1 Q 1 + d 2 Q 3 c 1 Q 0 + c 2 Q 2 c 1 Q 1 + c 2 Q 3 ] = [ a Q 1 a Q 2 d Q 1 d Q 2 c Q 1 c Q 2 ] Q=\left[\begin{matrix}a_1&a_2\\ d_1&d_2\\c_1&c_2\end{matrix}\right] \cdot \left[\begin{matrix}Q_0&Q_1\\ Q_2&Q_3\end{matrix}\right]=\left[\begin{matrix}a_1Q_0+a_2Q_2&a_1Q_1+a_2Q_3\\ d_1Q_0+d_2Q_2&d_1Q_1+d_2Q_3\\c_1Q_0+c_2Q_2&c_1Q_1+c_2Q_3\end{matrix}\right]=\left[\begin{matrix}aQ^1&aQ^2\\ dQ^1&dQ^2\\cQ^1&cQ^2\end{matrix}\right] Q= a1d1c1a2d2c2 [Q0Q2Q1Q3]= a1Q0+a2Q2d1Q0+d2Q2c1Q0+c2Q2a1Q1+a2Q3d1Q1+d2Q3c1Q1+c2Q3 = aQ1dQ1cQ1aQ2dQ2cQ2

K = [ a 1 a 2 d 1 d 2 c 1 c 2 ] ⋅ [ K 0 K 1 K 2 K 3 ] = [ a 1 K 0 + a 2 K 2 a 1 K 1 + a 2 K 3 d 1 K 0 + d 2 K 2 d 1 K 1 + d 2 K 3 c 1 K 0 + c 2 K 2 c 1 K 1 + c 2 K 3 ] = [ a K 1 a K 2 d K 1 d K 2 c K 1 c K 2 ] K=\left[\begin{matrix}a_1&a_2\\ d_1&d_2\\c_1&c_2\end{matrix}\right] \cdot \left[\begin{matrix}K_0&K_1\\ K_2&K_3\end{matrix}\right]=\left[\begin{matrix}a_1K_0+a_2K_2&a_1K_1+a_2K_3\\ d_1K_0+d_2K_2&d_1K_1+d_2K_3\\c_1K_0+c_2K_2&c_1K_1+c_2K_3\end{matrix}\right]=\left[\begin{matrix}aK^1&aK^2\\ dK^1&dK^2\\cK^1&cK^2\end{matrix}\right] K= a1d1c1a2d2c2 [K0K2K1K3]= a1K0+a2K2d1K0+d2K2c1K0+c2K2a1K1+a2K3d1K1+d2K3c1K1+c2K3 = aK1dK1cK1aK2dK2cK2

V = [ a 1 a 2 d 1 d 2 c 1 c 2 ] ⋅ [ V 0 V 1 V 2 V 3 ] = [ a 1 V 0 + a 2 V 2 a 1 V 1 + a 2 V 3 d 1 V 0 + d 2 V 2 d 1 V 1 + d 2 V 3 c 1 V 0 + c 2 V 2 c 1 V 1 + c 2 V 3 ] = [ a V 1 a V 2 d V 1 d V 2 c V 1 c V 2 ] V=\left[\begin{matrix}a_1&a_2\\ d_1&d_2\\c_1&c_2\end{matrix}\right] \cdot \left[\begin{matrix}V_0&V_1\\ V_2&V_3\end{matrix}\right]=\left[\begin{matrix}a_1V_0+a_2V_2&a_1V_1+a_2V_3\\ d_1V_0+d_2V_2&d_1V_1+d_2V_3\\c_1V_0+c_2V_2&c_1V_1+c_2V_3\end{matrix}\right]=\left[\begin{matrix}aV^1&aV^2\\ dV^1&dV^2\\cV^1&cV^2\end{matrix}\right] V= a1d1c1a2d2c2 [V0V2V1V3]= a1V0+a2V2d1V0+d2V2c1V0+c2V2a1V1+a2V3d1V1+d2V3c1V1+c2V3 = aV1dV1cV1aV2dV2cV2

拿到了 Q 、 K 、 V Q、K、V QKV 以后,就可以开始attention的运算了的 attention ( Q , K , V ) = Softmax ( Q ⋅ K T d i ) ⋅ V \text{attention}(Q,K,V)=\text{Softmax}\left(\frac{Q\cdot K^T}{\sqrt{d_i}}\right)\cdot V attention(Q,K,V)=Softmax(di QKT)V ,首先来算出 Q ⋅ K T Q\cdot K^T QKT ,输出是[1, 3, 3]

Q ⋅ K T = Q\cdot K^T= QKT= [ a Q 1 a Q 2 d Q 1 d Q 2 c Q 1 c Q 2 ] ⋅ [ a K 1 d K 1 c K 1 a K 2 d K 2 c K 2 ] \left[\begin{matrix}aQ^1&aQ^2\\ dQ^1&dQ^2\\cQ^1&cQ^2\end{matrix}\right]\cdot \left[\begin{matrix}aK^1&dK^1&cK^1\\ aK^2&dK^2&cK^2\end{matrix}\right] aQ1dQ1cQ1aQ2dQ2cQ2 [aK1aK2dK1dK2cK1cK2]

= [ a Q 1 a K 1 + a Q 2 a K 2 a Q 1 d K 1 + a Q 2 d K 2 a Q 1 c K 1 + a Q 2 c K 2 d Q 1 a K 1 + d Q 2 a K 2 d Q 1 d K 1 + d Q 2 d K 2 d Q 1 c K 1 + d Q 2 c K 2 c Q 1 a K 1 + c Q 2 a K 2 c Q 1 d K 1 + c Q 2 d K 2 c Q 1 c K 1 + c Q 2 c K 2 ] =\left[\begin{matrix}aQ^1aK^1+aQ^2aK^2&aQ^1dK^1+aQ^2dK^2&aQ^1cK^1+aQ^2cK^2 \\ dQ^1aK^1+dQ^2aK^2&dQ^1dK^1+dQ^2dK^2&dQ^1cK^1+ dQ^2cK^2\\ cQ^1aK^1+cQ^2aK^2&cQ^1dK^1+cQ^2dK^2&cQ^1cK^1+cQ^2cK^2\end{matrix}\right] = aQ1aK1+aQ2aK2dQ1aK1+dQ2aK2cQ1aK1+cQ2aK2aQ1dK1+aQ2dK2dQ1dK1+dQ2dK2cQ1dK1+cQ2dK2aQ1cK1+aQ2cK2dQ1cK1+dQ2cK2cQ1cK1+cQ2cK2

可见此时得到的就是不同的token之间的交互运算的结果, Q ⋅ K T Q\cdot K^T QKT 内的每个计算结果,除去对角线的数字是同一个token内的运算,其他的数字都是不同的token之间运算得到的,像1行3列,就是token【a,c】之间的运算

上述式子看起来有些臃肿,不太方便观察,继续来做向量化的简化操作,表达了参加运算的向量或者权重矩阵,输出是[1, 3, 3]

Q ⋅ K T = Q\cdot K^T= QKT= [ a Q a K a Q d K a Q c K d Q a K d Q d K d Q c K c Q a K c Q d K c Q c K ] \left[\begin{matrix}aQaK&aQdK&aQcK \\ dQaK&dQdK&dQcK \\ cQaK&cQdK&cQcK\end{matrix}\right] aQaKdQaKcQaKaQdKdQdKcQdKaQcKdQcKcQcK

attention ( Q , K , V ) = Softmax ( Q ⋅ K T d i ) ⋅ V \text{attention}(Q,K,V)=\text{Softmax}\left(\frac{Q\cdot K^T}{\sqrt{d_i}}\right)\cdot V attention(Q,K,V)=Softmax(di QKT)V ,除以 d i \sqrt{d_i} di 是防止数值过大exp指数过大的,矩阵运算是相乘相加,累加会导致数值变大很多,所以需要除以一个常数,防止数值过大,导致exp指数运算结果越界的。

所以这里可以忽略掉除,不妨假设此时的运算公式变到了

attention ( Q , K , V ) ′ = Softmax ( Q ⋅ K T ) ⋅ V \text{attention}(Q,K,V)'=\text{Softmax}\left(Q\cdot K^T\right)\cdot V attention(Q,K,V)=Softmax(QKT)V

Softmax ( Q ⋅ K T ) \text{Softmax}\left(Q\cdot K^T\right) Softmax(QKT) 是在最后一个dim运算的,也就是token层次来运算的,也就归一化的方向是最后一个dim,此时每一行都被归一化了,输出是[1, 3, 3]

Softmax ( Q ⋅ K T ) = [ S o f t m a x ( a Q 1 a K 1 + a Q 2 a K 2 a Q 1 d K 1 + a Q 2 d K 2 a Q 1 c K 1 + a Q 2 c K 2 ) S o f t m a x ( d Q 1 a K 1 + d Q 2 a K 2 d Q 1 d K 1 + d Q 2 d K 2 d Q 1 c K 1 + d Q 2 c K 2 ) S o f t m a x ( c Q 1 a K 1 + c Q 2 a K 2 c Q 1 d K 1 + c Q 2 d K 2 c Q 1 c K 1 + c Q 2 c K 2 ) ] \text{Softmax}\left(Q\cdot K^T\right)=\left[\begin{matrix}Softmax(aQ^1aK^1+aQ^2aK^2&aQ^1dK^1+aQ^2dK^2&aQ^1cK^1+aQ^2cK^2) \\ Softmax(dQ^1aK^1+dQ^2aK^2&dQ^1dK^1+dQ^2dK^2&dQ^1cK^1+dQ^2cK^2) \\ Softmax(cQ^1aK^1+cQ^2aK^2&cQ^1dK^1+cQ^2dK^2&cQ^1cK^1+cQ^2cK^2) \end{matrix}\right] Softmax(QKT)= Softmax(aQ1aK1+aQ2aK2Softmax(dQ1aK1+dQ2aK2Softmax(cQ1aK1+cQ2aK2aQ1dK1+aQ2dK2dQ1dK1+dQ2dK2cQ1dK1+cQ2dK2aQ1cK1+aQ2cK2)dQ1cK1+dQ2cK2)cQ1cK1+cQ2cK2)

= [ ( a Q 1 a K 1 + a Q 2 a K 2 ) s ( a Q 1 d K 1 + a Q 2 d K 2 ) s ( a Q 1 c K 1 + a Q 2 c K 2 ) s ( d Q 1 a K 1 + d Q 2 a K 2 ) s ( d Q 1 d K 1 + d Q 2 d K 2 ) s ( d Q 1 c K 1 + d Q 2 c K 2 ) s ( c Q 1 a K 1 + c Q 2 a K 2 ) s ( c Q 1 d K 1 + c Q 2 d K 2 ) s ( c Q 1 c K 1 + c Q 2 c K 2 ) s ] =\left[\begin{matrix}(aQ^1aK^1+aQ^2aK^2)_s&(aQ^1dK^1+aQ^2dK^2)_s&(aQ^1cK^1+aQ^2cK^2)_s \\ (dQ^1aK^1+dQ^2aK^2)_s&(dQ^1dK^1+dQ^2dK^2)_s&(dQ^1cK^1+dQ^2cK^2)_s \\ (cQ^1aK^1+cQ^2aK^2)_s&(cQ^1dK^1+cQ^2dK^2)_s&(cQ^1cK^1+cQ^2cK^2)_s \end{matrix}\right] = (aQ1aK1+aQ2aK2)s(dQ1aK1+dQ2aK2)s(cQ1aK1+cQ2aK2)s(aQ1dK1+aQ2dK2)s(dQ1dK1+dQ2dK2)s(cQ1dK1+cQ2dK2)s(aQ1cK1+aQ2cK2)s(dQ1cK1+dQ2cK2)s(cQ1cK1+cQ2cK2)s

= [ ( a Q a K ) s ( a Q d K ) s ( a Q c K ) s ( d Q a K ) s ( d Q d K ) s ( d Q c K ) s ( c Q a K ) s ( c Q d K ) s ( c Q c K ) s ] =\left[\begin{matrix}(aQaK)_s&(aQdK)_s&(aQcK)_s \\ (dQaK)_s&(dQdK)_s&(dQcK)_s \\ (cQaK)_s&(cQdK)_s&(cQcK)_s\end{matrix}\right] = (aQaK)s(dQaK)s(cQaK)s(aQdK)s(dQdK)s(cQdK)s(aQcK)s(dQcK)s(cQcK)s

最后来运算得到 attention ( Q , K , V ) ′ = Softmax ( Q ⋅ K T ) ⋅ V \text{attention}(Q,K,V)'=\text{Softmax}\left(Q\cdot K^T\right)\cdot V attention(Q,K,V)=Softmax(QKT)V ,输出是[1, 3, 2]

= [ ( a Q a K ) s ( a Q d K ) s ( a Q c K ) s ( d Q a K ) s ( d Q d K ) s ( d Q c K ) s ( c Q a K ) s ( c Q d K ) s ( c Q c K ) s ] ⋅ [ a V 1 a V 2 d V 1 d V 2 c V 1 c V 2 ] =\left[\begin{matrix}(aQaK)_s&(aQdK)_s&(aQcK)_s \\ (dQaK)_s&(dQdK)_s&(dQcK)_s \\ (cQaK)_s&(cQdK)_s&(cQcK)_s\end{matrix}\right] \cdot \left[\begin{matrix}aV^1&aV^2\\ dV^1&dV^2\\cV^1&cV^2\end{matrix}\right] = (aQaK)s(dQaK)s(cQaK)s(aQdK)s(dQdK)s(cQdK)s(aQcK)s(dQcK)s(cQcK)s aV1dV1cV1aV2dV2cV2

= [ ( a Q a K ) s a V 1 + ( a Q d K ) s d V 1 + ( a Q c K ) s c V 1 ( a Q a K ) s a V 2 + ( a Q d K ) s d V 2 + ( a Q c K ) s c V 2 ( d Q a K ) s a V 1 + ( d Q d K ) s d V 1 + ( d Q c K ) s c V 1 ( d Q a K ) s a V 2 + ( d Q d K ) s d V 2 + ( d Q c K ) s c V 2 ( c Q a K ) s a V 1 + ( c Q d K ) s d V 1 + ( c Q c K ) s c V 1 ( c Q a K ) s a V 2 + ( c Q d K ) s d V 2 + ( c Q c K ) s c V 2 ] =\left[\begin{matrix}(aQaK)_saV^1+(aQdK)_sdV^1+(aQcK)_scV^1 & (aQaK)_saV^2+(aQdK)_sdV^2+(aQcK)_scV^2 \\ (dQaK)_saV^1+(dQdK)_sdV^1+(dQcK)_scV^1 & (dQaK)_saV^2+(dQdK)_sdV^2+(dQcK)_scV^2 \\(cQaK)_saV^1+(cQdK)_sdV^1+(cQcK)_scV^1 & (cQaK)_saV^2+(cQdK)_sdV^2+(cQcK)_scV^2 \\\end{matrix}\right] = (aQaK)saV1+(aQdK)sdV1+(aQcK)scV1(dQaK)saV1+(dQdK)sdV1+(dQcK)scV1(cQaK)saV1+(cQdK)sdV1+(cQcK)scV1(aQaK)saV2+(aQdK)sdV2+(aQcK)scV2(dQaK)saV2+(dQdK)sdV2+(dQcK)scV2(cQaK)saV2+(cQdK)sdV2+(cQcK)scV2

从上述式子可见,最后的结果的每个数字,都是每个token之间,每个权重矩阵之间运算得到的结果

上面的运算没有用到mask的,实际mask作用的地方是在softmax前一步:

attention ( Q , K , V ) = Softmax ( Q ⋅ K T d i + mask ) ⋅ V \text{attention}(Q,K,V)=\text{Softmax}\left(\frac{Q\cdot K^T}{\sqrt{d_i}}+\text{mask}\right)\cdot V attention(Q,K,V)=Softmax(di QKT+mask)V

现在回到最开始的输入, [ 输入 的 数据 ] = [ 0 1 2 ] = [ a 1 a 2 d 1 d 2 c 1 c 2 ] \left[\begin{matrix}输入\\ 的\\数据\end{matrix}\right]=\left[\begin{matrix}0\\ 1\\2\end{matrix}\right]=\left[\begin{matrix}a_1&a_2\\ d_1&d_2\\c_1&c_2\end{matrix}\right] 输入数据 = 012 = a1d1c1a2d2c2 ,输入是三个token[3, 2],输出也是三个token[3, 2]

上面提到了mask是用来防止pad对梯度的影响,不同的句子之间长度不同,需要Pad的内容非常多,导致了pad很多,从而每个batch的pad的token数量很多的,总体pad占比很大的,pad的梯度累加以后很大,会导致train不收敛,很难train的,所以要防止pad对梯度的影响,需要mask掉部分pad的梯度,也就是阻止某些Pad参加运算的,从而达到缩小pad梯度的目的。

若是从bert的source codes来看实践的操作,bert对pad这个token的mask操作方式是构造方阵的

具体的实现方式见下面,假设现在输入的是

输入 的 <PAD> ====== [0, 1, 666]

[ 输入 的 <PAD> ] = [ 0 1 666 ] = [ a 1 a 2 d 1 d 2 c 1 c 2 ] \left[\begin{matrix}输入\\ 的\\\text{<PAD>}\end{matrix}\right]=\left[\begin{matrix}0\\ 1\\666\end{matrix}\right]=\left[\begin{matrix}a_1&a_2\\ d_1&d_2\\c_1&c_2\end{matrix}\right] 输入<PAD> = 01666 = a1d1c1a2d2c2

现在来按照bert的方式来构造mask

第一步: 输入mask,也就是pad的地方置0,其他地方置1,大小是[batchsize, sequence_length],这里的batchsize=1,sequence_length=3,所以输入的 input_mask = [[1, 1, 0]],这里的0就是

第二步: 得到attention累加时的mask,根据上面推导的过程,可以得知累加的大小是[sequence_length, sequence_length],也就是sequence_length大小的方阵,

若input是[1, 3],输入embedding是[1, 3, 2], Q K T QK^T QKT 是[1, 3, 3],则input_mask大小是[1, 3],累加mask是[1, 3, 3]

若input是[2, 3],输入embedding是[2, 3, 2], Q K T QK^T QKT 是[2, 3, 3],则input_mask大小是[2, 3],累加mask是[2, 3, 3]

KaTeX parse error: Expected 'EOF', got '_' at position 14: 若 \text{input_̲mask}=[[1, 1, 0…

KaTeX parse error: Expected 'EOF', got '_' at position 14: 若 \text{input_̲mask} = [[1, 1,…

codes是

bert/modeling.py at master · google-research/bert (github.com)

def create_masks(input_mask):
    input_mask = np.array(input_mask)
    n, sequence_length = input_mask.shape
    k1 = input_mask[:, None, :]
    k2 = np.ones_like(input_mask)[:, :, None]
    k3 = k1 * k2
    k = (1.0 - k3) * (-1e6)
    return k

现在拿到了mask的,input_mask = [[1, 1, 0]]

mask = [ 0 0 − 1 e 6 0 0 − 1 e 6 0 0 − 1 e 6 ] \text{mask}=\left[\begin{matrix}0&0&-1e6\\ 0&0&-1e6\\ 0&0&-1e6\end{matrix}\right] mask= 0000001e61e61e6 ,输入是: [ 输入 的 <PAD> ] = [ 0 1 666 ] = [ a 1 a 2 d 1 d 2 c 1 c 2 ] \left[\begin{matrix}输入\\ 的\\\text{<PAD>}\end{matrix}\right]=\left[\begin{matrix}0\\ 1\\666\end{matrix}\right]=\left[\begin{matrix}a_1&a_2\\ d_1&d_2\\c_1&c_2\end{matrix}\right] 输入<PAD> = 01666 = a1d1c1a2d2c2

仍然是三个token,但是最后一个变到了pad,根据上面的运算输出可知:输出是[1, 3, 3]

Q ⋅ K T = Q\cdot K^T= QKT= [ a Q 1 a Q 2 d Q 1 d Q 2 c Q 1 c Q 2 ] ⋅ [ a K 1 d K 1 c K 1 a K 2 d K 2 c K 2 ] \left[\begin{matrix}aQ^1&aQ^2\\ dQ^1&dQ^2\\cQ^1&cQ^2\end{matrix}\right]\cdot \left[\begin{matrix}aK^1&dK^1&cK^1\\ aK^2&dK^2&cK^2\end{matrix}\right] aQ1dQ1cQ1aQ2dQ2cQ2 [aK1aK2dK1dK2cK1cK2]

= [ a Q 1 a K 1 + a Q 2 a K 2 a Q 1 d K 1 + a Q 2 d K 2 a Q 1 c K 1 + a Q 2 c K 2 d Q 1 a K 1 + d Q 2 a K 2 d Q 1 d K 1 + d Q 2 d K 2 d Q 1 c K 1 + d Q 2 c K 2 c Q 1 a K 1 + c Q 2 a K 2 c Q 1 d K 1 + c Q 2 d K 2 c Q 1 c K 1 + c Q 2 c K 2 ] =\left[\begin{matrix}aQ^1aK^1+aQ^2aK^2&aQ^1dK^1+aQ^2dK^2&aQ^1cK^1+aQ^2cK^2 \\ dQ^1aK^1+dQ^2aK^2&dQ^1dK^1+dQ^2dK^2&dQ^1cK^1+ dQ^2cK^2\\ cQ^1aK^1+cQ^2aK^2&cQ^1dK^1+cQ^2dK^2&cQ^1cK^1+cQ^2cK^2\end{matrix}\right] = aQ1aK1+aQ2aK2dQ1aK1+dQ2aK2cQ1aK1+cQ2aK2aQ1dK1+aQ2dK2dQ1dK1+dQ2dK2cQ1dK1+cQ2dK2aQ1cK1+aQ2cK2dQ1cK1+dQ2cK2cQ1cK1+cQ2cK2

Q ⋅ K T = [ a Q a K a Q d K a Q c K d Q a K d Q d K d Q c K c Q a K c Q d K c Q c K ] Q\cdot K^T=\left[\begin{matrix}aQaK&aQdK&aQcK \\ dQaK&dQdK&dQcK \\ cQaK&cQdK&cQcK\end{matrix}\right] QKT= aQaKdQaKcQaKaQdKdQdKcQdKaQcKdQcKcQcK

然后加上得到的mask就是 Q ⋅ K T + mask Q\cdot K^T+\text{mask} QKT+mask ,相加得到了-1e6,忽略掉aQcK,dQcK,cQcK的reason是相对-1e6来说,它们很小的所以可以忽略掉, $aQcK-1e6\approx-1e6$

[ a Q a K a Q d K a Q c K d Q a K d Q d K d Q c K c Q a K c Q d K c Q c K ] + [ 0 0 − 1 e 6 0 0 − 1 e 6 0 0 − 1 e 6 ] \left[\begin{matrix}aQaK&aQdK&aQcK \\ dQaK&dQdK&dQcK \\ cQaK&cQdK&cQcK\end{matrix}\right]+\left[\begin{matrix}0&0&-1e6\\ 0&0&-1e6\\ 0&0&-1e6\end{matrix}\right] aQaKdQaKcQaKaQdKdQdKcQdKaQcKdQcKcQcK + 0000001e61e61e6 = [ a Q a K a Q d K − 1 e 6 d Q a K d Q d K − 1 e 6 c Q a K c Q d K − 1 e 6 ] =\left[\begin{matrix}aQaK&aQdK&-1e6 \\ dQaK&dQdK&-1e6\\ cQaK&cQdK&-1e6\end{matrix}\right] = aQaKdQaKcQaKaQdKdQdKcQdK1e61e61e6

然后对每个token做softmax操作归一化,也就是对每行做softmax,axis = -1,softmax以后-1e6会被归一化到0

softmax ( Q ⋅ K T + mask ,   − 1 ) = [ Softmax( a Q a K a Q d K − 1 e 6 ) Softmax( d Q a K d Q d K − 1 e 6 ) Softmax( c Q a K c Q d K − 1 e 6 ) ] \text{softmax}\left(Q\cdot K^T+\text{mask},~ -1\right) =\left[\begin{matrix}\text{Softmax(}aQaK&aQdK&-1e6) \\ \text{Softmax(}dQaK&dQdK&-1e6)\\ \text{Softmax(}cQaK&cQdK&-1e6)\end{matrix}\right] softmax(QKT+mask, 1)= Softmax(aQaKSoftmax(dQaKSoftmax(cQaKaQdKdQdKcQdK1e6)1e6)1e6)

= [ ( a Q a K ) s ( a Q d K ) s 0 ( d Q a K ) s ( d Q d K ) s 0 ( c Q a K ) s ( c Q d K ) s 0 ] =\left[\begin{matrix}(aQaK)_s&(aQdK)_s&0 \\ (dQaK)_s&(dQdK)_s&0\\ (cQaK)_s&(cQdK)_s&0\end{matrix}\right] = (aQaK)s(dQaK)s(cQaK)s(aQdK)s(dQdK)s(cQdK)s000

最后就是算 attention ( Q , K , V ) = Softmax ( Q ⋅ K T + mask ) ⋅ V \text{attention}(Q,K,V)=\text{Softmax}\left({Q\cdot K^T}+\text{mask}\right)\cdot V attention(Q,K,V)=Softmax(QKT+mask)V ,上面已算过了代入得

= [ ( a Q a K ) s ( a Q d K ) s 0 ( d Q a K ) s ( d Q d K ) s 0 ( c Q a K ) s ( c Q d K ) s 0 ] ⋅ [ a V 1 a V 2 d V 1 d V 2 c V 1 c V 2 ] =\left[\begin{matrix}(aQaK)_s&(aQdK)_s&0 \\ (dQaK)_s&(dQdK)_s&0\\ (cQaK)_s&(cQdK)_s&0\end{matrix}\right] \cdot \left[\begin{matrix}aV^1&aV^2\\ dV^1&dV^2\\cV^1&cV^2\end{matrix}\right] = (aQaK)s(dQaK)s(cQaK)s(aQdK)s(dQdK)s(cQdK)s000 aV1dV1cV1aV2dV2cV2

= [ ( a Q a K ) s a V 1 + ( a Q d K ) s d V 1 + 0 ( a Q a K ) s a V 2 + ( a Q d K ) s d V 2 + 0 ( d Q a K ) s a V 1 + ( d Q d K ) s d V 1 + 0 ( d Q a K ) s a V 2 + ( d Q d K ) s d V 2 + 0 ( c Q a K ) s a V 1 + ( c Q d K ) s d V 1 + 0 ( c Q a K ) s a V 2 + ( c Q d K ) s d V 2 + 0 ] =\left[\begin{matrix}(aQaK)_saV^1+(aQdK)_sdV^1+0 & (aQaK)_saV^2+(aQdK)_sdV^2+0 \\ (dQaK)_saV^1+(dQdK)_sdV^1+0 & (dQaK)_saV^2+(dQdK)_sdV^2+0 \\(cQaK)_saV^1+(cQdK)_sdV^1+0 & (cQaK)_saV^2+(cQdK)_sdV^2+0 \\\end{matrix}\right] = (aQaK)saV1+(aQdK)sdV1+0(dQaK)saV1+(dQdK)sdV1+0(cQaK)saV1+(cQdK)sdV1+0(aQaK)saV2+(aQdK)sdV2+0(dQaK)saV2+(dQdK)sdV2+0(cQaK)saV2+(cQdK)sdV2+0

和之前运算得到的结果相比较,可以发现的,少了很多和c也就是相关的内容,此时c的梯度就变少了,累加的梯度变小了,网络在train的时候会少关注,不会因过多,网络train的时候往的梯度方向下降,这样就可以正常训练网络,这里要特别注意的是, 含c的项是减少了,并不是全部删除了 ,所以网络在train的时候c还是有梯度的,但是变小很多了,下面的式子内有10个含c的项,上面加上了mask以后,含c的项可以发现只有2+2个了,10变到了2+2,可见变少了很多,所以c的累加梯度也变小了很多的,mask只能减小梯度,并不能完全删除的。

= [ ( a Q a K ) s a V 1 + ( a Q d K ) s d V 1 + ( a Q c K ) s c V 1 ( a Q a K ) s a V 2 + ( a Q d K ) s d V 2 + ( a Q c K ) s c V 2 ( d Q a K ) s a V 1 + ( d Q d K ) s d V 1 + ( d Q c K ) s c V 1 ( d Q a K ) s a V 2 + ( d Q d K ) s d V 2 + ( d Q c K ) s c V 2 ( c Q a K ) s a V 1 + ( c Q d K ) s d V 1 + ( c Q c K ) s c V 1 ( c Q a K ) s a V 2 + ( c Q d K ) s d V 2 + ( c Q c K ) s c V 2 ] =\left[\begin{matrix}(aQaK)_saV^1+(aQdK)_sdV^1+(aQcK)_scV^1 & (aQaK)_saV^2+(aQdK)_sdV^2+(aQcK)_scV^2 \\ (dQaK)_saV^1+(dQdK)_sdV^1+(dQcK)_scV^1 & (dQaK)_saV^2+(dQdK)_sdV^2+(dQcK)_scV^2 \\(cQaK)_saV^1+(cQdK)_sdV^1+(cQcK)_scV^1 & (cQaK)_saV^2+(cQdK)_sdV^2+(cQcK)_scV^2 \\\end{matrix}\right] = (aQaK)saV1+(aQdK)sdV1+(aQcK)scV1(dQaK)saV1+(dQdK)sdV1+(dQcK)scV1(cQaK)saV1+(cQdK)sdV1+(cQcK)scV1(aQaK)saV2+(aQdK)sdV2+(aQcK)scV2(dQaK)saV2+(dQdK)sdV2+(dQcK)scV2(cQaK)saV2+(cQdK)sdV2+(cQcK)scV2

现在来考虑embed_dim=1的情况,也就是position_embedding=1, words_embedding=1

所以假设输入的是,由没有符号,所以mask是全0

输入 - [0]
的   - [1]

[ 输入 的 ] = [ 0 1 ] = [ a 1 d 1 ] \left[\begin{matrix}输入\\ 的\end{matrix}\right]=\left[\begin{matrix}0\\ 1\end{matrix}\right]=\left[\begin{matrix}a_1\\ d_1\end{matrix}\right] [输入]=[01]=[a1d1] [1, 2, 1],即batchsize=1, sequence_length = 2, embed_dim = 1

所以Q、K、V运算的full connect的矩阵大小就是[1, 1],也就是一个数字

拿到的Q、K、V的大小是[1, 2, 1], mask = [1, 2, 2] = 0

Q = [ a 1 d 1 ] ⋅ [ Q 0 ] = [ a 1 Q 0 d 1 Q 0 ] Q=\left[\begin{matrix}a_1\\ d_1\end{matrix}\right] \cdot \left[\begin{matrix}Q_0\end{matrix}\right]=\left[\begin{matrix}a_1Q_0\\ d_1Q_0\end{matrix}\right] Q=[a1d1][Q0]=[a1Q0d1Q0] K = [ a 1 K 0 d 1 K 0 ] K=\left[\begin{matrix}a_1K_0\\ d_1K_0\end{matrix}\right] K=[a1K0d1K0] V = [ a 1 V 0 d 1 V 0 ] V=\left[\begin{matrix}a_1V_0\\ d_1V_0\end{matrix}\right] V=[a1V0d1V0]

Q ⋅ K T = [ a 1 Q 0 d 1 Q 0 ] ⋅ [ a 1 K 0 d 1 K 0 ] = [ a 1 2 K 0 a 1 d 1 Q 0 K 0 d 1 a 1 K 0 Q 0 d 1 2 Q 0 K 0 ] Q\cdot K^T=\left[\begin{matrix}a_1Q_0\\ d_1Q_0\end{matrix}\right]\cdot \left[\begin{matrix}a_1K_0 &d_1K_0\end{matrix}\right]=\left[\begin{matrix}a_1^2K_0&a_1d_1Q_0K_0\\ d_1a_1K_0Q_0&d_1^2Q_0K_0\end{matrix}\right] QKT=[a1Q0d1Q0][a1K0d1K0]=[a12K0d1a1K0Q0a1d1Q0K0d12Q0K0]

现在来算最后的输出 attention ( Q , K , V ) = Softmax ( Q ⋅ K T + mask ) ⋅ V \text{attention}(Q,K,V)=\text{Softmax}\left({Q\cdot K^T}+\text{mask}\right)\cdot V attention(Q,K,V)=Softmax(QKT+mask)V

Softmax ( Q ⋅ K T + mask ) = [ Softmax ( a 1 2 K 0 a 1 d 1 Q 0 K 0 ) Softmax ( d 1 a 1 K 0 Q 0 d 1 2 Q 0 K 0 ) ] \text{Softmax}\left({Q\cdot K^T}+\text{mask}\right)=\left[\begin{matrix}\text{Softmax}(a_1^2K_0&a_1d_1Q_0K_0)\\ \text{Softmax}(d_1a_1K_0Q_0&d_1^2Q_0K_0)\end{matrix}\right] Softmax(QKT+mask)=[Softmax(a12K0Softmax(d1a1K0Q0a1d1Q0K0)d12Q0K0)]

= [ ( a 1 2 K 0 ) s ( a 1 d 1 Q 0 K 0 ) s ( d 1 a 1 K 0 Q 0 ) s ( d 1 2 Q 0 K 0 ) s ] =\left[\begin{matrix}(a_1^2K_0)_s&(a_1d_1Q_0K_0)_s\\ (d_1a_1K_0Q_0)_s&(d_1^2Q_0K_0)_s\end{matrix}\right] =[(a12K0)s(d1a1K0Q0)s(a1d1Q0K0)s(d12Q0K0)s]

Softmax ( Q ⋅ K T + mask ) ⋅ V = [ ( a 1 2 K 0 ) s ( a 1 d 1 Q 0 K 0 ) s ( d 1 a 1 K 0 Q 0 ) s ( d 1 2 Q 0 K 0 ) s ] ⋅ [ a 1 V 0 d 1 V 0 ] \text{Softmax}\left({Q\cdot K^T}+\text{mask}\right)\cdot V=\left[\begin{matrix}(a_1^2K_0)_s&(a_1d_1Q_0K_0)_s\\ (d_1a_1K_0Q_0)_s&(d_1^2Q_0K_0)_s\end{matrix}\right]\cdot \left[\begin{matrix}a_1V_0\\ d_1V_0\end{matrix}\right] Softmax(QKT+mask)V=[(a12K0)s(d1a1K0Q0)s(a1d1Q0K0)s(d12Q0K0)s][a1V0d1V0]

= [ ( a 1 2 K 0 ) s a 1 V 0 + ( a 1 d 1 Q 0 K 0 ) s d 1 V 0 ( d 1 a 1 K 0 Q 0 ) s a 1 V 0 + ( d 1 2 Q 0 K 0 ) s d 1 V 0 ] =\left[\begin{matrix}(a_1^2K_0)_sa_1V_0+(a_1d_1Q_0K_0)_sd_1V_0\\ (d_1a_1K_0Q_0)_sa_1V_0+(d_1^2Q_0K_0)_sd_1V_0\end{matrix}\right] =[(a12K0)sa1V0+(a1d1Q0K0)sd1V0(d1a1K0Q0)sa1V0+(d12Q0K0)sd1V0] ,即输出[1, 2, 1]

若是存在个,mask此时就不是全0

像输入 [ 输入 < P A D > ] = [ 0 666 ] = [ a 1 d 1 ] \left[\begin{matrix}输入\\ <PAD>\end{matrix}\right]=\left[\begin{matrix}0&666\end{matrix}\right]=\left[\begin{matrix}a_1\\ d_1\end{matrix}\right] [输入<PAD>]=[0666]=[a1d1] [1,2,1],input_mask的shape和输入相同的[1, 2, 1]

mask的shape是[1, 2, 2]

KaTeX parse error: Expected 'EOF', got '_' at position 14: 若 \text{input_̲mask}=[[1, 0]] …

那么得到的输出就是

Softmax ( Q ⋅ K T + mask ) = [ Softmax ( a 1 2 K 0 − 1 e 6 ) Softmax ( d 1 a 1 K 0 Q 0 − 1 e 6 ) ] = [ ( a 1 2 K 0 ) s 0 ( d 1 a 1 K 0 Q 0 ) s 0 ] \text{Softmax}\left({Q\cdot K^T}+\text{mask}\right)=\left[\begin{matrix}\text{Softmax}(a_1^2K_0&-1e6)\\ \text{Softmax}(d_1a_1K_0Q_0&-1e6)\end{matrix}\right]=\left[\begin{matrix}(a_1^2K_0)_s&0\\ (d_1a_1K_0Q_0)_s&0\end{matrix}\right] Softmax(QKT+mask)=[Softmax(a12K0Softmax(d1a1K0Q01e6)1e6)]=[(a12K0)s(d1a1K0Q0)s00]

Softmax ( Q ⋅ K T + mask ) ⋅ V = [ ( a 1 2 K 0 ) s 0 ( d 1 a 1 K 0 Q 0 ) s 0 ] ⋅ [ a 1 V 0 d 1 V 0 ] \text{Softmax}\left({Q\cdot K^T}+\text{mask}\right)\cdot V=\left[\begin{matrix}(a_1^2K_0)_s&0\\ (d_1a_1K_0Q_0)_s&0\end{matrix}\right]\cdot \left[\begin{matrix}a_1V_0\\ d_1V_0\end{matrix}\right] Softmax(QKT+mask)V=[(a12K0)s(d1a1K0Q0)s00][a1V0d1V0]

= [ ( a 1 2 K 0 ) s a 1 V 0 + 0 ( d 1 a 1 K 0 Q 0 ) s a 1 V 0 + 0 ] =\left[\begin{matrix}(a_1^2K_0)_sa_1V_0+0\\ (d_1a_1K_0Q_0)_sa_1V_0+0\end{matrix}\right] =[(a12K0)sa1V0+0(d1a1K0Q0)sa1V0+0]

此时的项减少了2项,还剩一项的呢,所以达到了减少梯度的目的

RNN或者LSTM内避免pad符号的影响可以参考这个:

numpy实现RNN和LSTM循环神经网络产生古诗 - 知乎 (zhihu.com)

下一篇:
transformer网络内attention使用的mask第二篇 https://blog.csdn.net/m0_50617544/article/details/132182164

参考:

bert/modeling.py at master · google-research/bert (github.com)

Masking in Transformers’ self-attention mechanism | by Samuel Kierszbaum, PhD | Analytics Vidhya | Medium

BrianPulfer/PapersReimplementations: Personal short implementations of Machine Learning papers (github.com)

How Do Self-Attention Masks Work? | by Gabriel Mongaras | MLearning.ai | Medium

Your Repositories (github.com)


https://zhuanlan.zhihu.com/p/645442074

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐