文章有点看不下去了,所以先来输出一波吧。唠一唠attention机制。本文将从attention机制的背景(什么问题推动想出这个解决方案的),到seq2seq中的attention机制与self-attention的详细计算流程进行介绍,最后再说一下啥是multi-head。
一、背景:
attention机制出家自NLP中的文本翻译。最朴素的翻译是,一个单词一个单词的蹦。翻译出来的效果那就是七零八落,能稍微明白个意思。那要想翻译好怎么整呢,长难句老师教我们,先看一遍整个句子,然后找出定语从句… 那就是说要关注单词和单词之间的联系了。
那这个单词和单词之间的联系要怎么度量呢?
attention 机制!
我们都知道单词可以用word2vec学习到其向量表示。seq2seq模型中,单词被一个一个的输入encoder,然后再被输出到一个softmax层,输出一个一个翻译后的单词。
主要有下图的两种模式:(图来自于吴恩达的深度学习视频)
二、 针对第一种模型(seq2seq):
可以看出,前面翻译的单词是不会注意到后面单词是啥的,那么怎么让它注意到呢?把后面的单词加权加到前面单词表达上:(你可能会说bidirectional RNN也可以,但是它只能选择记住or遗忘,无法对不同单词有不同程度的关注,效果肯定没这种好。而且句子一长,它也记不了那么多信息,翻译效果就没那么好了)
上述都是文字and图,来点公式直观表达一下整个翻译过程:
变量名 | 含义 |
---|---|
x < t > x^{<t>} x<t> | 输入的第 t t t个单词 |
y < t > y^{<t>} y<t> | 输出的第 t t t个单词 |
g ( ) g() g(), f ( ) f() f() | 激活函数 |
a < 0 > a^{<0>} a<0> 和 S < 0 > S^{<0>} S<0> | 初始值,可以设为全零向量 |
W a a , W a x , W s s , b a , b s W_{aa},W_{ax},W_{ss},b_a,b_s Waa,Wax,Wss,ba,bs | 要学习的参数 |
我们的目标是学习到参数
α
t
,
i
\alpha^{t,i}
αt,i :翻译出第 t 个单词时,对第
i
i
i个单词的关注度。
如何学习 α t , i \alpha_{t,i} αt,i:
先来看如何计算
α
t
,
i
\alpha_{t,i}
αt,i:
我们先计算当前得到的汇总向量 和其他单词的相似性,然后对所有单词的相似性进行归一。
如果采用第一种点乘的方法,其实我们要学的参数就还是那几个
W
W
W。也就是说我们通过反向传播的方式学习到
W
,
b
W,b
W,b后,就相当于学到了
α
\alpha
α
好的说完第一种模式了,我们再来唠唠第二种模式。第二种模式这个叫self-attention,想出这个方法的人感觉他的脑子一定很神奇。
三、self-attention(针对第二种模型)
我们先来看下加了self-attention的翻译模型长什么样:
encoder
拆出其中的一个包含self-attention模块的encoder模块:
可以看出encoder的目标是把输入的单词向量
x
x
x ,变为包含其他输入单词信息的新向量
r
r
r。 变身过程如下:
来张图形象的看一下这个过程吧
4、把 Z i Z_i Zi 放到一个神经网络,训练得到 r i r_i ri
这里 W = [ W Q , W K , W V ] W = [W^Q,W^K,W^V] W=[WQ,WK,WV] 就是我们要训练的参数。
multi-head
介绍完基本的self-attention, 我们再来介绍一下multihead机制。multi-head就是指,我们可以训练多个 W W W ,得到单词之间的多种关系。 eg:张三去银行存了一笔钱。 可能第一个 W W W 学到的关系是 “张三” 和 “存”, 第二个 W W W 学到的关系是 “张三” 和 “银行” 以及 “钱”
multi-head 训练过程 :
1、随机初始化8个 [ W Q , W K , W V ] [W^Q,W^K,W^V] [WQ,WK,WV] 矩阵 (当然不是非得要8个,这里只是举个例子)
2、 [ Q , K , V ] = X ⋅ W [Q,K,V] = X\cdot W [Q,K,V]=X⋅W
3、 Z = s o f t m a x ( Q ⋅ K ) ⋅ V Z = softmax(Q\cdot K) \cdot V Z=softmax(Q⋅K)⋅V
4、将 Z 0 , Z 1 , Z 2 . . . Z 7 Z_0,Z_1,Z_2...Z_7 Z0,Z1,Z2...Z7 拼接起来,然后乘以 矩阵 W O W^O WO ,得到最终的 z z z。 再将 z z z 放到神经网络中去训练,得到 r r r
这里
W
Q
,
W
K
,
W
V
,
W
O
W^Q,W^K,W^V,W^O
WQ,WK,WV,WO 都是训练过程中要学习的参数。
decoder
最后一层encoder输出 一个 K K K 和 一个 V V V, 作为 decoder的输入。每次decoder 翻译出一个单词(输出),翻译出的单词将一起作为下一步 decoder的输入,直到输出一个代表结束的符号。(这里也会将位置信息 embedding,然后加到单词上。)
linear 层将decoder的输出,变为one-hot编码维度。(比如有1000个单词,就变为1000维的向量)最后 Softmax 计算概率。
附录、其他训练小细节
1、position embedding
把单词在句子中的位置做一个embedding,加到单词的embedding vector上
x i x_i xi = x i + p o s i t i o n x_i + position xi+position e m b e d d i n g embedding embedding
2、residual
-
在self-attention前后用了 residual,把self-attention之前的embedding vector 加到 self-attention之后的vector上;
z i = z i + x i z_i = z_i + x_i zi=zi+xi
-
在神经网络前后也用了 residual
3、layer normalization
相比于batch normalization , layer normalization 可以忽略batch size带来的影响,在layer中把数据变为均值为 μ \mu μ , 方差为 σ \sigma σ 的分布。(没太明白,看论文吧)
源码: 第一个是pytorch,第二个是tensorflow keras