Self_Attention
1、简介
seq2seq模型有两个RNN网络, 一个encoder, 一个decoder。这里介绍self-attention, 把attention用在一个RNN网络上。
attention的第一篇文章发表在2015年, 用来改进seq2seq模型, 解决RNN的遗忘问题。其实attention并不局限于seq2seq模型, attention可以用在所有的RNN上。下面介绍Self-Attention, 文章发表在2016年, 比第一篇attention论文晚一年。
Self-Attention的原始论文把attention用在LSTM上, 把它们的论文做了简化。为了方便理解, 把LSTM换成simple RNN。
现在开始simple RNN与Self-Attention的结合,初始的时候状态向量h与context vector c都是全零向量。
RNN读入第一个输出x1, 需要更新状态h。把x1的信息压缩到新的状态h里面。标准的simple RNN是这样计算状态h1的。新的状态h1依赖于旧的状态h0与新的输入x1。
上面的公式中, 新的输入x1与旧的状态h做concatination, 然后把得到的向量乘到参数矩阵A上。用tanh做激活函数, 对括号中的向量做非线性变换, 输出向量h1就是新的状态。
用Self-Attention的话, RNN这样更新状态。用context vector c0取代h0, 其余的都一样, 唯一的区别就是h0换成了c0。可以用其他的方法来更新状态h, 比如可以把x1, c0还有旧的状态h0这三个向量做concatination, 而不是x1和c0这两个向量。
算出新的状态h1, 下一步就是计算新的context vector c1。
新的context vector c1是已有状态h的加权平均。 由于初始状态h0是全零向量, 我们忽略到h0, 那么已有状态的加权平均就等于h1, 所以新的context vector c1就等于h1。
有了状态h1与context vector c1。 下一步要计算新的状态h2, 用这个公式来计算状态h2, h2是c1和x2的函数。
下面计算新的context vector c。要计算c, 首先要计算权重α, 权重向量αi是状态向量h1与h2的相关性, 拿当前状态与已有状态做对比, 包括h2跟自己做对比。
这样可以计算出两个权重α。每个α对应一个h, 对已有的两个状态h1和h2做加权平均来计算c。 由于h0是全零向量, 以后就忽略h0。
加权平均的结果就是新的context vector c2。c2=α1h1 + α2h2。
输入新的向量x3, RNN就会更新状态h。 新的状态h3依赖于x3, c2, 用同样的公式计算新的状态h3。
现在有了状态h3, 该计算新的context vector c3。首先计算权重α, 拿当前状态h3与已有状态h1、h2、h3三个向量做对比,计算出权重α1, α2, α3。
每个权重α对应一个h, 对三个状态h做加权平均, 加权平均的结果就是context vector c3。
重复这个过程, 以此类推。
2、总结
Self-Attention每一轮更新状态前都会用context vector c看一遍之前的所有状态, 这样就不会遗忘之前的状态。
Self-Attention可以用在所有的RNN上, 不会局限于seq2seq。
除了避免遗忘, Self-Attention还可以帮助RNN关注相关的信息。 下图是论文中的插入, RNN从左往右读入一句话, 红色是当前的输入, 高亮标注的是权重α很大的位置。这些权重α说明全文中最相关的词是哪几个。