wangshusen的课件:
https://github.com/wangshusen/DeepLearning
本文只介绍注意力和自注意力机制,这是transformer模型的核心组成部分。
注意力机制Attention
Attention机制,对于Seq2Seq模型进行优化,解决遗忘问题:
https://www.youtube.com/watch?v=XhWdv7ghmQQ&list=PLvOO0btloRnuTUGN4XqO85eKPeFSZsEqK&index=9
Seq2Seq模型中,Encoder到Decoder之间只有S0,导致无法进行长期记忆:
Attention机制的办法就是记住Encoder中从h1到hm之间的所有hidden state,代价是更多的计算量。
具体来说,就是增加一个context向量,对h1到hm进行加权平均:
其中权重αi通过hi与s0计算得到(具体计算方式后面介绍):
具体计算αi和c0的过程为:
有了c0之后,计算s1就比较简单了,相比RNN来说,就是加上了c0作为额外的输入:
计算完s1之后,再计算s2时,不能复用之前计算的αi,而是要根据s1重新计算αi,根据αi计算c1,然后以c1作为额外输入,计算s2:
计算hi与si的权重
以hi和s0作为输入为例,现在典型的实现方式是为hi和s0分别构造两个矩阵Wk和WQ,先把hi和s0做转换,然后把转换的两个向量做内积得到数值,最后使用softmax做归一:
小结
上面计算context向量时直接使用了α乘以hi,主流的做法其实是乘以Value向量:
- 根据sj计算Query,根据hi计算Key
- 计算α向量
- 根据sj计算Value,并使用α向量加权计算出
自注意力机制Self-Attention
Attention机制不止应用于Seq2Seq,也可以应用于RNN模型,这就是self-attention(如果只有1个RNN网络)。
开始的时候,把contxt向量c0和状态h0都初始化为0:
由于RNN里面只有hi,区别于前面attention计算时使用si,计算αi时只使用已经计算的hi与当前的状态h。
只是由于c0和h0都是0,计算h1就比较简单:
使用c1和x2为输入,计算h2:
这个时候开始,计算context向量就需要先计算α了(之前是因为c0=0):
计算出c2后,以c2和x3为输入,可以计算出h3,此时有了h1、h2、h3就可以计算出α向量,并且计算出c3,以此类推。
Transformer模型
Attention层
把Attention机制从RNN中剥离,是不是也可以实现seq2seq呢,答案是的。
通过研究RNN+Attention机制发现,其核心逻辑是把encoder转换为Key和Value,把decoder转换为Query:
基于Key、Value和Query,计算α和context vector:
最终计算出所有context向量,组合起来作为输出:
小结
attention层的输入包括Encoder和Decoder两个向量,输出是C,包含三个参数矩阵Q、K和V。
不同于注意力模型,self-attention不用于seq2seq,并且输入的encoder和decoder都是相同的,每个输入转换为Query、Key和Value:
除此之外,计算过程类似attention,即先计算α,然后计算context向量:
把所有context向量组合为C,每个c与所有输入都相关:
我的理解
自注意力机制,通过三个参数矩阵,捕捉输入序列之间的关联信息,是一种压缩和萃取机制。
是否还有其他方式捕捉这种信息呢?