注意力机制(显示考虑随意线索)
随意线索:查询query
每个输入是一个value和不随意线索key的对
通过注意力池化层偏向性选择某些输入
历史演变:
- 非参注意力池化层:60年代提的Nadaraya-Watson核回归,类似于knn
- 如果使用高斯核,fx 函数类似于softmax和y(y是一个value)的乘积
- 参数化注意力机制:在这基础上引入可以学习的w(w是个标量),就是在softmax里面加入w
批量矩阵乘法:torch.bmm
注意力分数(query和key的相似度)
- 回顾:注意力分数是softmax里面的函数a,和softmax一起整体就是注意力权重alpha(大于等于0,加起来等于1,是分数的softmax结果)
- 讨论注意力分数函数a:
1)Additive Attention(加性注意力):等价于将key和query合并起来放入到一个隐藏大小为h输出大小为1的单隐藏层MLP,好处是key、value、query可以是任意长度
2) Scaled Dot-Product Attention(缩放点积注意力):query和key都是同样长度,q和ki作内积再除以根号d,d是query的维度,d的作用是使得对参数不那么敏感(如果下一次输入很长,计算的注意力分数a会很大) - 代码实现时注意:
遮蔽softmax(masked_softmax):invalid数要设置为很小:1e-6,不能是0,为了解决padding后只考虑valid的值
使用注意力机制的seq2seq
- 加入注意力:
1)编码器对每次词的输出作为key和value(它们是一样的,就是每次rnn最后的输出)
2)解码器rnn对上一个词的预测输出是query
3)注意力输出和下一个词的词嵌入合并进入rnn - Seq2seq中通过隐状态在编码器和解码器中传递信息
- 注意力机制根据解码器rnn的输出匹配合适的编码器rnn输出更有效的传递信息(如何更有效的使用encode的信息)
延伸:图像attention:会去扣patch,扣很多子图出来,一个子图就是一个key-value
自注意力和位置编码
自注意力:
- 自注意力池化层将xi当作key、value、query来对序列抽取得到y1,…,yn
- 自注意力适合很长的序列,因为能看的比较长,最长路径是o(1)
- 完全并行、最长序列为1、但对长序列计算复杂度高
位置编码: - 跟CNN/RNN不同,自注意力并没有记录位置信息
- 位置编码将位置信息注入到输入里(假设序列是X,使用位置编码矩阵P来输出X+P作为自编码输入,P有点类似于计算机二进制编码,使用sin、cos函数,表示相对位置-类似于旋转投影线性变换),使得自注意力能够记忆位置信息
self-attention就是一个layer(网络层)
Transformer
架构:
- 基于编码器-解码器架构处理序列对
- 与使用注意力的seq2seq不同,Transformer是纯基于注意力(注意力是类似于self-attention)
多头注意力: - 对同一key、value、query,希望抽取不同的信息:例如使用短距离关系和长距离关系
- 多头注意力使用h个独立的注意力池化:合并各head输出得到最终输出
有掩码的多头注意力: - 解码器对序列中一个元素输出时,不应考虑该元素之后的元素
- 可以通过掩码来实现,即设置valid长度
基于位置的前馈网络: - 将输入形状由(b,n,d)变换成(bn,d)
- 作用2个全连接层
- 输出形状由(bn,d)变化回(b,n,d)
- 等价于2层和窗口为1的1维卷积层
残差和层归一化: - 残差为了做很深
- 批量归一化对特征/通道里元素进行归一化:不适合序列长度会变的nlp应用
- 层归一化对每个样本里的元素进行归一化
信息传递: - 将编码器中输出y1,…,yn作为解码器中第I个Tranformer块中多头注意力的key和value:它的query来自目标序列
- 意味着编码器和解码器中块的个数和输出维度都是一样的
预测: - 预测第t+1个输出时,解码器中输入前t个预测值
- 在自注意力中,前t个预测值作为key和value,第t个预测值还作为query
总结: - Tranformer是一个纯使用注意力的编码-解码器
- 编码器和解码器都有n个Transformer块
- 每个块里使用多头(自)注意力,基于位置的前馈网络和层归一化