注意力机制Attention Mechanism

  • Q,K,V
  • 注意力分数
  • seq2seq中注意力机制的应用

注意力机制源于对人类视觉的研究。在认知科学中,由于信息处理的瓶颈,人类会选择性地关注所有信息的一部分,同时忽略其他可见的信息,上述机制通常被称为注意力机制。
例如在NLP中,当要捕捉一句话中词与词的关系时,如:


当看到eating这个词时,我们更希望看到食物apple,而对颜色green并不在意,此时我们就可以使用注意力机制来衡量词之间的相关性。相比于序列模型,它能够通过矩阵运算实现并行化,提高效率。

Q,K,V

注意力机制中有三个要素:Q(query),K(key),V(value),它们均由张量表示,在NLP中,Q可以理解成要输入的某个词(即要研究那个词与其他词的相关性),K可以理解为所有的词或者规定的词(即要与Q计算相关性的词),V可以理解为K对应的值(最后需要再和Q与K出来的结果做运算)。K和V可以是一个词,可以都有相同的向量表示,但意义不一样,比如上图中的apple,它本身的属性可以理解成K,但是它对最后的输出的属性可以理解成V(虽然它们是一样的)。大致如下图:

图选自沐神的动手学深度学习,应该放在下面,但要先展示一下注意力机制的流程就贴这了,可以先不看注意力评分函数。
虽然注意力机制是这几年提出的,但早期就有这种思想,如经典的Nadaraya-Watson核回归
f ( x ) = ∑ i = 1 n K ( x − x i ) ∑ j = 1 n K ( x − x j ) y i f(x)=\sum_{i=1}^n\frac{K(x-x_i)}{\sum_{j=1}^nK(x-x_j)}y_i f(x)=i=1∑n​∑j=1n​K(x−xj​)K(x−xi​)​yi​
这是一种回归方法,基本思想就是使用已知样本的加权平均作为新样本的预测,其中n为样本数,K为核函数(可以选用高斯核等),用来度量查询x与键xi的相关性,函数值越大说明查询与键相关性越大,也为对应的值yi赋予了更大的权重。

注意力分数

注意力分数实际就是Q与K相关性的大小,在Nadaraya-Watson核回归可以类比为yi的权重。一般化中,假定query为长度为q的向量,ki为长度为k的向量,vi为长度为v的向量,则:
f ( q u e r y , ( k 1 , v 1 ) , . . . , ( k m , v m ) ) = ∑ i = 1 m a ( q u e r y , k i ) v i ∈ R v f(query,(k_1,v_1),...,(k_m,v_m))=\sum_{i=1}^ma(query,k_i)v_i\in R^v f(query,(k1​,v1​),...,(km​,vm​))=i=1∑m​a(query,ki​)vi​∈Rv
这里的a(query,ki)即为注意力分数,a表示计算注意力分数的方式,结果还需要softmax归一化。
方式1:additive attention
若query与ki的长度不一样
a ( q u e r y , k i ) = v T t a n h ( W k k i + W q q u e r y ) a(query,k_i)=v^{T}tanh(W_kk_i+W_qquery) a(query,ki​)=vTtanh(Wk​ki​+Wq​query)
其中 W k , W q W_k,W_q Wk​,Wq​分别为hxk,hxq形状的矩阵,v为长度为h的向量,这里算出来的是一个数。
多维并行见代码,沐神在将这个代码时没有很清楚(也可能是个人理解不够),经过一段时间琢磨,一下为一点思考(可以照着上面公式看):

class AdditiveAttention(nn.Module):"""加性注意力"""def __init__(self, key_size, query_size, num_hiddens, dropout, **kwargs):super(AdditiveAttention, self).__init__(**kwargs)self.W_k = nn.Linear(key_size, num_hiddens, bias=False)self.W_q = nn.Linear(query_size, num_hiddens, bias=False)self.w_v = nn.Linear(num_hiddens, 1, bias=False)self.dropout = nn.Dropout(dropout)def forward(self, queries, keys, values, valid_lens):queries, keys = self.W_q(queries), self.W_k(keys)# 在维度扩展后,# queries的形状:(batch_size,查询的个数,1,num_hiddens)# key的形状:(batch_size,1,“键-值”对的个数,num_hiddens)# 使用广播方式进行求和, 求和之后的形状是:(batch_size,查询的个数,键-值对的个数,num_hiddens)features = queries.unsqueeze(2) + keys.unsqueeze(1) features = torch.tanh(features)# self.w_v仅有一个输出,因此从形状中移除最后那个维度(使num_hiddens)为1。# scores的形状:(batch_size,查询的个数,“键-值”对的个数)scores = self.w_v(features).squeeze(-1)self.attention_weights = masked_softmax(scores, valid_lens)# values的形状:(batch_size,“键-值”对的个数,值的维度)return torch.bmm(self.dropout(self.attention_weights), values)

masked_softmax是为了去掉冗余信息,加了mask的softmax函数,可以先不管,若想了解可以去看https://zh-v2.d2l.ai/chapter_attention-mechanisms/attention-scoring-functions.html,代码主要难顶的是forward里面的广播机制(看懂之后我直呼NB)。
开始时查询queries的形状是(batch_szie,查询的个数,query_size),keys的形状是(batch_size,“键-值”对的个数,key_size),首先通过线性层使它们的query_size与key_size都变成了num_hiddens。然后,也是最重要的一点,因为现在queries与keys的形状还不能相加,使用了unsqueeze扩展了维度,queries的形状变成(batch_size,查询的个数,1,num_hiddens),keys的形状变成(batch_size,1,“键-值”对的个数,num_hiddens),都成了四维张量,先不看batch_size(或者假设batch_size为1),这里的广播就是用每一个查询(形状为1xnum_hiddens)去加形状为(“键-值”对的个数,num_hiddens)的矩阵,得到每一个形状为(“键-值”对的个数,num_hiddens)的矩阵,然后加入查询个数这个维度,代码中features的形状就变成(batch_size,查询的个数,键-值对的个数,num_hiddens)。最后再由一个线性层将features形状变成(batch_size,查询的个数,键-值对的个数,1),去掉最后的维度,最后形状就是(batch_size,查询的个数,键-值对的个数),其中每个元素意义就是查询的词与key的注意力分数。
方式2:scaled dot-product attention
若query与ki均为d维向量
a ( q u e r y , k i ) = q u e r y × k i T d a(query,k_i)=\frac{query\times{k_i^{T}}}{\sqrt{d}} a(query,ki​)=d ​query×kiT​​
这算出来的也是一个数。
若query为二维张量Q(表示查询多个词),此时K,V均为二维张量,假定 Q ∈ R n × d , K ∈ R m × d , V ∈ R m × v Q\in R^{n\times{d}},K\in R^{m\times{d}},V\in R^{m\times{v}} Q∈Rn×d,K∈Rm×d,V∈Rm×v,可以实现并行计算:
f = s o f t m a x ( Q K T d ) V ∈ R n × v f=softmax(\frac{QK^{T}}{\sqrt{d}})V\in R^{n\times{v}} f=softmax(d ​QKT​)V∈Rn×v
这里softmax里面出来的形状是(n,m),n表示查询的个数,m表示key-value键值对的个数,最后得到输出的长度由V部分决定,输出长度为nxv的矩阵(v是由实际任务定义,如在机器翻译中,v就是可供选择的翻译出的词的数量)。
代码:

class DotProductAttention(nn.Module):"""缩放点积注意力"""def __init__(self, dropout, **kwargs):super(DotProductAttention, self).__init__(**kwargs)self.dropout = nn.Dropout(dropout)# queries的形状:(batch_size,查询的个数,d)# keys的形状:(batch_size,“键-值”对的个数,d)# values的形状:(batch_size,“键-值”对的个数,值的维度)# valid_lens的形状:(batch_size,)或者(batch_size,查询的个数)def forward(self, queries, keys, values, valid_lens=None):d = queries.shape[-1]# 设置transpose_b=True为了交换keys的最后两个维度scores = torch.bmm(queries, keys.transpose(1,2)) / math.sqrt(d)self.attention_weights = masked_softmax(scores, valid_lens)return torch.bmm(self.dropout(self.attention_weights), values)

由于queries与keys的最后一个维度相同,就直接转置相乘得到形状为(batch_size,查询的个数,“键-值”对的个数)即(batch_size,n,m)的张量,softmax出来的结果也是这个形状,这个就是第二种方式的注意力分数,与mxv的张量V相乘得到nxv的张量,这个是最后的输出了。
scaled dot-product attention的自注意力机制版本:

seq2seq中注意力机制的应用

seq2seq原论文:Sequence to Sequence Learning with Neural Networks
加入attention的seq2seq原论文:NEURAL MACHINE TRANSLATION BY JOINTLY LEARNING TO ALIGN AND TRANSLATE
在没有引入注意力机制的seq2seq模型中,解码器接受的输入是编码器的输出,即编码器最后时刻的隐藏状态,但这在机器翻译任务中不太可取。

因为每个生成的词可能源于句子中不同的词,比如上图,“她”与句子中的“She”关系最大,“苹果”与“apple”关系最大,但原始的seq2seq的Decoder只接受Encoder的最后状态,即句子的压缩信息,所以可能会使生成的词捕捉不到关键的针对性的信息,在翻译长句子时效果很差,就需要加入注意力机制。

加入注意力就是使解码器在任何时刻的输出都考虑全部的key,每个key会有一个注意力分数,根据分数的大小分配权重,下图出自吴恩达老师https://www.bilibili.com/video/BV1FT4y1E74V?p=180&spm_id_from=333.1007.top_right_bar_window_history.content.click。

上图下方是Encoder,上方是Decoder,下方使用的是双向的RNN得到每一个句子单词的隐状态(特征向量)。在训练时是实现知道输出的y,所以可以得到每个翻译输出的query与keys的注意力分数,使用注意力机制得到Decoder每个时刻的输入C,由于Decoder也是RNN结构,输出时考虑上一时刻的隐状态与上一时刻的输出与Encoder由注意力机制得到的C。

参考资料:
李沐—动手学深度学习v2
https://lilianweng.github.io/lil-log/2018/06/24/attention-attention.html?spm=a2c4e.10696291.0.0.4c5619a4PZdBIF

深度学习笔记 2022/01/04

注意力机制Attention Mechanism及论文相关推荐

  1. 注意力机制(Attention)最新综述论文及相关源码

    来源:专知 注意力机制(Attention)起源于模仿人类的思维方式,后被广泛应用于机器翻译.情感分类.自动摘要.自动问答等.依存分析等机器学习应用中.专知编辑整理了Arxiv上一篇关于注意力机制在N ...

  2. 计算机视觉中的注意力机制--attention mechanism

    转载:https://zhuanlan.zhihu.com/p/56501461 张戎 引言 在机器翻译(Machine Translation)或者自然语言处理(Natural Language P ...

  3. 图像处理注意力机制Attention汇总(附代码)

    原文链接: 图像处理注意力机制Attention汇总(附代码,SE.SK.ECA.CBAM.DA.CA等) 1. 介绍 注意力机制(Attention Mechanism)是机器学习中的一种数据处理方 ...

  4. 注意力机制Attention详解

    注意力机制Attention详解 一.前言 2018年谷歌提出的NLP语言模型Bert一提出,便在NLP领域引起热议,之所以Bert模型能够火出圈,是由于Bert模型在NLP的多项任务中取得了之前所有 ...

  5. 论文阅读: 图像分类中的注意力机制(attention)

    本文简要总结一下attention机制在图像分类任务中的应用.attention作为一种机制,有其认知神经或者生物学原理: 注意力的认知神经机制是什么? 如何从生物学的角度来定义注意力? 在计算机视觉 ...

  6. 神经网络注意力机制--Attention in Neural Networks

    Attention in Neural Networks and How to Use It http://akosiorek.github.io/ml/2017/10/14/visual-atten ...

  7. VALSE学习(四):注意力机制-Attention Network

    VALSE2019 会议论文 一.精细化图像理解与多媒体内容创作 Trilinear Attention Sampling Network 近年来,精细化图像识别任务通常采用具有"注意力&q ...

  8. 翻译: 详细图解Transformer多头自注意力机制 Attention Is All You Need

    1. 前言 The Transformer--一个使用注意力来提高这些模型的训练速度的模型.Transformer 在特定任务中的表现优于谷歌神经机器翻译模型.然而,最大的好处来自于 The Tran ...

  9. 注意力机制 Attention

    注意力机制 前沿 注意力 认知神经学中的注意力 人工神经网络中的注意力机制 HAN(Hierarchical Attention Networks) Bi-LSTM + Attention + ten ...

最新文章

  1. node.js express php,nodejs开发——express路由与中间件
  2. linux自动执行top,Linux top 命令使用
  3. LeetCode-175. 组合两个表(SQL语句中的LEFT JOIN)
  4. Spring-Cloud中各个组件的职责
  5. JS 前20个常用操作字符串的函数
  6. HYSBZ - 1101——莫比乌斯反演
  7. 计算(a+b)/c的值(信息学奥赛一本通-T1008)
  8. 配置hosts快速访问GitHub
  9. SpringBoot开发流程
  10. activereport
  11. 构建一个可行的BI系统的造价是多少,实施周期?具备条件基础是什么? 数据量有要求么
  12. Markdown用法——带圆圈的数字编号
  13. vue如何把html转换word,vue前端html导出word文档
  14. ice的意思_ice是什么意思_ice的翻译_音标_读音_用法_例句_爱词霸在线词典
  15. 快车解密php,PHP迅雷、快车、旋风下载专用链转换代码
  16. 深度探索二维码及其应用
  17. Cocos2dx之精灵坐标系
  18. 如何学习大型项目的源码?
  19. 将String字符串转化为int
  20. 二、如何写好学术/学位论文

热门文章

  1. 推荐一款C端的低代码产品
  2. 思维模型 阿伦森效应
  3. 学习VC中所得的点点心
  4. 数据库设计的面试题目
  5. alfred 开发_适用于开发人员设计师和博客的7种Alfred工作流程
  6. c语言自动循环输入,C语言用for如何实现多次循环的输入输出
  7. free命令常用参数详解
  8. 蓝牙协议栈 电话免提协议HFP(Hands-Free)概念讲解
  9. 大A社群丨全球宽基ETF轮动(GP02)
  10. 世界各国用电电压介绍