注意力机制(Attention Mechanism)源于对人类视觉的研究。在认知科学中,由于信息处理的瓶颈,人类会选择性地关注所有信息的一部分,同时忽略其他可见的信息。这种机制被称为注意力机制。举个例子来说,当我们观赏一幅画时,虽然我们可以看到整幅画的全貌,但是在我们深入仔细地观察时,其实眼睛聚焦的就只有很小的一块,这个时候人的大脑主要关注在这一小块图案上,也就是说这个时候人脑对整幅图的关注并不是均衡的,是有一定的权重区分的。这就是深度学习里的Attention Model的核心思想。在神经网络中,注意力机制是一种通过自主学习出的一组权重系数来强调感兴趣的区域并抑制不相关背景区域的机制。
注意力机制主要有两个方面:一是决定需要关注输入的哪部分;二是分配有限的信息处理资源给重要的部分。注意力机制可以分为软注意力和硬注意力。软注意力是处处可微的,即能够通过基于梯度下降法的神经网络训练所获得,因此其应用相对来说也比较广泛。软注意力按照不同维度(如通道、空间、时间、类别等)出发,目前主流的注意力机制可以分为通道注意力、空间注意力以及自注意力(Self-attention)。通道注意力旨在建模出不同通道(特征图)之间的相关性,通过网络学习的方式来自动获取到每个特征通道的重要程度,最后再为每个通道赋予不同的权重系数,从而来强化重要的特征抑制非重要的特征。
注意力机制是机器学习中的一种数据处理方法,广泛应用在自然语言处理、图像识别及语音识别等各种不同类型的机器学习任务中。在计算能力有限的情况下,注意力机制是一种解决信息超载问题的主要手段,通过将计算资源分配给更重要的任务,来提高模型的性能和效率。
1. 编码器-解码器
我在之前的文章中介绍过编码器和解码器(神经网络7-时间卷积神经网络-CSDN博客)。神经网络的编码器-解码器(Encoder-Decoder)是一种深度学习模型架构,广泛应用于各种任务,如图像生成、自然语言处理、语音识别等。
- 编码器(Encoder)通常由多层神经网络组成,负责将输入数据映射到一个低维表示,俗称“降维”。这个低维表示可以被视为对原始数据的一种抽象,具有更好的可解释性和更强的表达能力。例如,在图像生成任务中,编码器将输入图像转换为一个向量或矩阵,该向量或矩阵包含了输入图像的主要特征信息。
- 解码器(Decoder)与编码器相反,它将低维表示映射回高维空间以生成输出,即“升维”。在许多情况下,解码器采用与编码器相同的架构,并使用反向传播算法来更新权重和偏置。例如,在图像生成任务中,解码器从编码后的低维向量或矩阵开始生成一张新图片。
编码器-解码器架构的一个典型应用是自动编码器(Auto-encoder),它由一个编码器和一个解码器组成。自动编码器通过学习如何重建输入数据来压缩信息并发现潜在特征。训练过程中,在给定输入数据后,自动编码器首先使用其编码器将数据压缩为一个低维向量,然后使用解码器将该向量解码回原始数据。模型的目标是最小化重构误差,即输入和输出之间的差异。下图展示了一个基于TCN的“编码器-解码器”结构:
“encoder-decoder”模型是一种应用于seq2seq问题的模型。seq2seq问题简单的说,就是根据一个输入序列x,来生成另一个输出序列y。常见的应用有机器翻译,文档提取,问答系统等。Encoder-Decoder模型中的编码,就是将输入序列转化成一个固定长度的向量;解码,就是将之前生成的固定向量再转化成输出序列。
Encoder-Decoder(编码-解码)是深度学习中非常常见的一个模型框架,比如无监督算法的auto-encoding就是用编码-解码的结构设计并训练的;比如这两年比较热的image caption的应用,就是CNN-RNN的编码-解码框架;再比如神经网络机器翻译NMT模型,往往就是LSTM-LSTM的编码-解码框架。因此,准确地说,Encoder-Decoder并不是一个具体的模型,而是一类框架。Encoder和Decoder部分可以是任意的,比如:时间序列/文字/语音/图像/视频/...,模型可以采用CNN,RNN,BiRNN、LSTM、GRU等等。所以基于Encoder-Decoder,我们可以设计出各种各样的应用算法。
Encoder-Decoder框架可以看作是一种文本处理领域的研究模式,应用场景异常广泛,下图是文本处理领域里常用的Encoder-Decoder框架最抽象的一种表示:
对于序列对<X,Y>,我们的目标是给定输入序列X,期待通过Encoder-Decoder框架来生成目标序列Y。X和Y可以是同一种序列,也可以是两种不同的序列:
Encoder顾名思义就是对输入的序列X进行编码,将输入序列通过非线性变换转化为中间语义表示C:。对于解码器Decoder来说,其任务是根据序列X的中间语义表示C和之前已经生成的历史信息来生成时刻要生成的下一个值:。
但是Encoder-Decoder框架会有一个明显的缺点。Encoder会把输入序列X编码为一个固定长度的隐向量(语义编码c),会导致隐向量无法完全表示输入序列X的信息。可以从两个方面理解:
- 隐向量的大小有限,无法表示信息丰富的序列;
- 由于RNN类网络特点,网络会更加看中序列后面的信息,无法总揽全局。
最简单的解决思路就是把所有RNNcell的输出组合起来使用,而不只使用最后一个RNNcell的输出,这个可以做到充分利用序列的信息,可以在一定程度上解决问题。但是一般越明确的网络学习目标可以获得越好的效果,如果可以获得每个RNNcell的输出的权重来加权编码,就可以更加明确学习目标提升学习效果。Attention Model的思路就是如此。如何设计网络,进行加权操作,并且使用合理的loss就是Attention Model的重难点。
2. Attention 机制
在Encoder-Decoder框架中,在预测每一个输入序列的encode时,对应的语义编码c都是一样的,也就意味着序列X中的任意一个数值点对输出Y中的每一个数值点的影响都是相同的。这样就会产生两个弊端:一是语义向量无法完全表示整个序列的信息,再者就是先输入的内容携带的信息会被后输入的信息稀释掉,或者说被覆盖了。输入序列越长,这个现象就越严重。这就使得在解码的时候一开始就没有获得输入序列足够的信息, 那么解码的准确度自然也就要打个折扣了。
为了解决上面的弊端,Attention Model(注意力模型)应运而生。比如在机器翻译的时候,让生成词不是只能关注全局的语义编码向量c,而是增加了一个“注意力范围”,表示接下来输出词时候要重点关注输入序列中的哪些部分,然后根据关注的区域来产生下一个输出。模型结构如下:
此时生成目标句子单词的过程就成了下面的形式:
比如输入的是英文句子:Tom chase Jerry,Encoder-Decoder框架逐步生成中文单词:“Tom”,“chase”,“Jerry”。在没加入Attention Model之前,生成的语义编码C是一致的,而加入之后,对应的语义编码可能如下:
其中,函数代表Encoder对输入英文单词的某种变换函数,比如如果Encoder是用的RNN模型的话,这个函数的结果往往是某个时刻输入后隐层节点的状态值;代表Encoder根据单词的中间表示合成整个句子中间语义表示的变换函数,一般的做法中,函数就是对构成元素加权求和,也就是常常在论文里看到的下列公式:
假设中那个就是上面的“汤姆”,那么就是3,代表输入句子的长度,,,,对应的注意力模型权值分别是0.6, 0.2, 0.2,所以函数就是个加权求和函数。如果形象表示的话,翻译单词“Tom”的时候,数学公式对应的中间语义表示的形成过程类似下图:
这里还有一个问题:生成目标句子某个单词,比如“Tom”的时候,你怎么知道AM模型(Attention Model)所需要的输入句子单词注意力分配概率分布值呢?就是说“Tom”对应的概率分布:。此时的Encoder和Decoder都采用RNN模型,我们来看看现在的Encoder-Decoder模型结构:
用下图可以较为便捷地说明注意力分配概率分布值的通用计算过程:
对于采用RNN的Decoder来说,如果要生成单词,在时刻,我们是可以知道在生成之前的隐层节点时刻的输出值的,而我们的目的是要计算生成时的输入句子单词“Tom”、“Chase”、“Jerry”对来说的注意力分配概率分布,那么可以用时刻的隐层节点状态去一一和输入句子中每个单词对应的RNN隐层节点状态进行对比,即通过函数来获得目标单词和每个输入单词对应的对齐可能性,这个函数在不同论文里可能会采取不同的方法,然后函数的输出经过Softmax进行归一化就得到了符合概率分布取值区间的注意力分配概率分布数值。绝大多数AM模型都是采取上述的计算框架来计算注意力分配概率分布信息,区别只是在的定义上可能有所不同。
上述中提出的解决方法是对于每一个Decoder的输出都可以进行加权,然后使用Encoder输出信息,以Tom chase Jerry,Encoder-Decoder “汤姆”,“追逐”,“杰瑞”为例子,不计算起止符号,输出为3个单元,输入为3个单元。然而,有时输入单元与输出数目会不一致,这时候就会产生如下问题:
- 每组权重如何合理化表示?虽然利用softMax可以帮助我们权重之和为1。
- 汇总权重信息时使用add还是concat(私以为add更加合适)?
- 如何表示权重?
- 如何优化权重?
这里我们假设输入为个,输出为个。由于每个由决定,因此每个都会综合所有的信息,对于每个都需要考虑个的影响。同时要求个的信息权重之和为1。因此对于输入为个,输出为个的任务一共有个权重要计算,如此多的参数就会产生以上问题。
3. Attention 定义
Attention模型的普遍结构图模型如下图所示。在下图中,表示输入序列,表示输出序列,表示编码层的第时刻的隐藏层状态,表示解码层第时刻的隐藏层状态,表示第时刻解码时注意力分布,这是注意力机制计算的关键。我们通过这个图来说明怎么解决上面的问题。
在注意力机制中,总体是为了计算条件概率分布 :
其中,, 表示解码输出时,第个输出词与第个输入序列词之间的相关因子。表示的是softmax函数,表示归一化所有的注意力权重。具体计算公式为:
其中 在文中为对齐模型(前馈神经网络)。计算的函数又被统称为配分函数,即score函数。后面会介绍多种配分函数的计算方式。通过上述方式,我们可以将任意大小的输入序列与任意大小的输出序列进行注意力匹配。
4. Attention 本质
尽管从数学层面确实说清楚了Attention机制是怎么进行计算的,但是仅仅基于数学公式理解起来却比较抽象,甚至不容易弄懂具体原理。但如果我们把Attention机制从上文讲述例子中的Encoder-Decoder框架中剥离,并进一步做抽象,可以更容易看懂Attention机制的本质思想。
我们可以这样来看待Attention机制(参考上图):注意力机制需要做的最核心的工作就是计算出输入句子中单词注意力分配概率的分布值,即上图中的Attention Value。然而我们现在拥有的数据只有当前单词之前的隐层节点的输出值的,输入句子中每个单词对应的隐层节点状态值,即Source。对于一个新来的单词Query,我们怎么获得他的Attention Value呢?
我们可以将Source中的构成元素想象成是由一系列的<Key,Value>数据对构成,此时给定Target中的某个元素Query,通过计算Query和各个Key的相似性或者相关性,得到每个Key对应Value的权重系数,然后对Value进行加权求和,即得到了最终的Attention数值。所以本质上Attention机制是对Source中元素的Value值进行加权求和,而Query和Key用来计算对应Value的权重系数。即可以将其本质思想改写为如下公式:
其中,||Source||代表Source的长度,公式含义即如上所述。上文所举的机器翻译的例子里,因为在计算Attention的过程中,Source中的Key和Value合二为一,指向的是同一个东西,也即输入句子中每个单词对应的语义编码,所以可能不容易看出这种能够体现本质思想的结构。
当然,从概念上理解,把Attention仍然理解为从大量信息中有选择地筛选出少量重要信息并聚焦到这些重要信息上,忽略大多不重要的信息,这种思路仍然成立。聚焦的过程体现在权重系数的计算上,权重越大越聚焦于其对应的Value值上,即权重代表了信息的重要性,而Value是其对应的信息。
从图中可以引出另外一种理解,也可以将Attention机制看作一种软寻址(Soft Addressing):Source可以看作存储器内存储的内容,元素由地址Key和值Value组成,当前有个Key=Query的查询,目的是取出存储器中对应的Value值,即Attention数值。通过Query和存储器内元素Key的地址进行相似性比较来寻址,之所以说是软寻址,指的不像一般寻址只从存储内容里面找出一条内容,而是可能从每个Key地址都会取出内容,取出内容的重要性根据Query和Key的相似性来决定,之后对Value进行加权求和,这样就可以取出最终的Value值,也即Attention值。所以不少研究人员将Attention机制看作软寻址的一种特例,这也是非常有道理的。
至于Attention机制的具体计算过程,如果对目前大多数方法进行抽象的话,可以将其归纳为两个过程:第一个过程是根据Query和Key计算权重系数,第二个过程根据权重系数对Value进行加权求和。而第一个过程又可以细分为两个阶段:第一个阶段根据Query和Key计算两者的相似性或者相关性;第二个阶段对第一阶段的原始分值进行归一化处理;这样,可以将Attention的计算过程抽象为如下图展示的三个阶段。
在第一个阶段,可以引入不同的函数和计算机制,根据Query,计算两者的相似性或者相关性,最常见的方法包括:求两者的向量点积、求两者的向量Cosine相似性或者通过再引入额外的神经网络来求值。第一阶段产生的分值根据具体产生的方法不同其数值取值范围也不一样。第二阶段引入类似SoftMax的计算方式对第一阶段的得分进行数值转换,一方面可以进行归一化,将原始计算分值整理成所有元素权重之和为1的概率分布;另一方面也可以通过SoftMax的内在机制更加突出重要元素的权重。第二阶段的计算结果即为对应的权重系数,然后进行加权求和即可得到Attention数值。
通过如上三个阶段的计算,即可求出针对Query的Attention数值,目前绝大多数具体的注意力机制计算方法都符合上述的三阶段抽象计算过程。
5. Attention 分类
注意力机制发展至今,研究者从各个方面对其进行了改进,也就产生了注意力的各种形式,下面我将对最常见的几种注意力机制进行介绍。
5.1 Soft attention VS Hard attention
该类attention来源于图片生成文字描述的任务(Image Caption),文中使用注意力捕获文字与图中特定区域的联系。
- Soft attention:NLP中尝试用的注意力方式,取值为[0, 1]的权重概率分布,使用了所有编码层的隐层状态,与上两节的介绍相同,可以直接在模型训练过程中,通过后向传播优化对参数进行优化。
- Hard attention:在原文中被称为随机硬注意力(Stochastic hard attention),这里的随机是指对编码层隐状体的采样过程,Hard attention 没有使用到所有的隐层状态,而是使用one-hot的形式对某个区域提取信息,使用这种方式无法直接进行后向传播(梯度计算),需要蒙特卡洛采样的方法来估计梯度。
5.2 Global attention VS Local attention
- Global attention:以下简称Global attention为GA, GA在推导 时考虑了所有的编码层隐层状态,模型图如下图所示,其中蓝色表示编码码层,红色表示解码层。可以看到global attention 是在计算 时考虑了当前的目标解码隐层状态和所有编码隐层状态,这里的 为全局对齐权重。若不指定说明,一般attention都是指global attention。
Local attention:Global attention存在两个缺点:一方面每次解码目标词,都要计算所有的编码隐层向量,在翻译或处理长文本序列时计算代价高。另一方面当文本序列过长,也有可能导致注意力不集中、过度分散。Local attention 相对于global attention 直观的感受,专注于小窗口的上下文,也就是不考虑所有的编码隐层状态。为实现该想法,要在每一时刻解码时构造一个位置变量,记录当前解码位置,该窗口就可以表示为 ,其中D为窗口大小,为实验选值。
5.3 Self attention
Self-attention 又称为intra attention,顾名思义,其不是计算source-target之间的注意力分布,而是单一计算source或target内部的注意力分布,也可以看作特殊的source=target的情况,即文本序列内部不同词之间的联系。具体来讲,self attention具有以下优点:
- 可以捕获句法特征和语义特征(可视化结果);
- 相比RNN依次序列计算,在长距离依赖特征上表现更好;
- 可并行化计算。
5.4 Multi-Head attention
Multi-Head attention是注意力并行化的代表,多头注意力不仅计算一次注意力,而是并行化计算多次注意力,这样模型可以同时关注多个子空间的信息。
5.5 Hierarchical attention
Hierarchical attention (层次注意力)由词级别、句子级别注意力机制组成,在文档级别的任务上,往往由多篇章、多句子、多词语组成,Hierarchical attention能够更好捕获global和local的信息。
5.6 Channel attention
通道注意力机制是一种注意力机制,它关注输入数据中不同通道之间的相关性,通过为每个通道赋予不同的权重系数来强调重要的特征并抑制非重要的特征。在计算机视觉领域,通道注意力机制通常用于处理图像数据,其中每个通道代表一种特定的特征,如颜色、纹理等。
通道注意力机制的实现方式多种多样,但核心思想都是通过网络自主学习出一组权重系数,这些权重系数用于动态地调整每个通道的重要程度。一种常见的实现方式是使用卷积神经网络(CNN)中的全连接层或全局平均池化层来生成通道级别的统计信息,然后利用这些信息来为每个通道生成权重系数。另一种实现方式是利用自注意力机制,通过计算输入数据中不同通道之间的相关性来生成权重系数。
通道注意力机制在多种计算机视觉任务中都取得了显著的效果,如图像分类、目标检测、图像分割等。其中,最具代表性的工作是SENet(Squeeze-and-Excitation Networks),它通过引入通道注意力机制来改进ResNet等主流网络结构,在多个图像分类任务中取得了优异的性能。