细讲:Attention模型的机制原理
Posted striving长亮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了细讲:Attention模型的机制原理相关的知识,希望对你有一定的参考价值。
目录
前言
最近两年,注意力模型(Attention Model)被广泛使用在自然语言处理(Natural Language Processing, NLP)、图像识别及语音识别等各种不同类型的深度学习任务中,是深度学习技术中最值得关注与深入了解的核心技术之一,甚至于是传统的时序数据的预测,都很容易遇到注意力模型的身影。
在NLP领域,BERT(Bidirectional Encoder Representations from Transformers)近期提出之后,作为一个Word2Vec的替代者,其在NLP领域的11个方向大幅刷新了精度,在许多方向甚至都达到了SOTA(state of the art),可以说是近年来自残差网络(ResNet)最有突破性的一项技术了,在NLP中达到了全新的高度,将已经走向瓶颈期的Word2Vec带向了一个新的方向,并再一次炒火了《Attention is All you Need》这篇论文(强烈建议大家精读此文章),而BERT所采用的就是在各领域所霸榜的Transformer。
而Transformer所采用的主要算法模型即Attention(multi-headed self-attention、masked multi-headed self-attention以及Encoder-Decoder Attention),所以,了解注意力机制的工作原理至关重要。
由于个人接下来的实验也要用到Attention机制,好记性不如烂笔头,为了加深印象,也为了分享给大家我的理解和看法,我将把我的理解、心得做个记录,接下来我还要继续分享Transformer(主要是对《Attention is All you Need》的深度解析)、BERT以及Word2Vec模型的原理、机制,希望大家多多关注哈,感谢感谢🙏🙏!
ps:尽管我在知乎、简书、博客园、知乎等收藏了很多博文、专栏,也写过一些文章,做过很多笔记,但都没发布过,这是我真正意义上第一次发布文章,如果哪里写的不好,欢迎大家批评指正!
pps:本人的个人主页汇总了很多关于机器学习、深度学习、强化学习、自然语言处理、Tensorflow、Java、Python的使用、本人的一些项目开发、部署经验以及服务器的使用(自己基本都亲身尝试过)等等的一些收藏博文,大家可以自行查看。
ppps:本人目前在攻读硕士学位,主要研究方向是智慧水务、强化学习、自动控制、数字孪生、智能系统以及预测性维护方面,因此我并不是研究方向为NLP的学生,但我本人对NLP特别感兴趣,希望博士期间我可以找到一个主要研究方向为NLP的博导吧😊(任重而道远啊)
废话不多说,开讲!
提示:上面全是废话,以下才是本篇文章正文内容
Encoder-Decoder框架
要了解深度学习中的注意力模型,就不得不先谈Encoder-Decoder框架,因为目前大多数注意力模型附着在Encoder-Decoder框架下,当然,其实注意力模型可以看作一种通用的思想,本身并不依赖于任何特定框架,这点需要注意。
关于 Encoder-Decoder,有2 点需要说明:
-
不论输入和输出的长度是什么,中间的「向量 c」 长度都是固定的(这也是它的缺陷)
-
根据不同的任务可以选择不同的编码器和解码器(可以是一个 RNN ,但通常是其变种 LSTM 或者 GRU )
只要是符合上面的框架,都可以统称为 Encoder-Decoder 模型。说到 Encoder-Decoder 模型就经常提到一个名词—— Seq2Seq。
Seq2Seq( Sequence-to-sequence),就如字面意思,输入一个序列,输出另一个序列。这种结构最重要的地方在于输入序列和输出序列的长度是可变的。例如下图:
Seq2Seq和Encoder-Decoder的关系
- Seq2Seq(强调目的)不特指具体方法,满足「输入序列、输出序列」的目的,都可以统称为 Seq2Seq 模型。
- Seq2Seq 使用的具体方法基本都属于Encoder-Decoder 模型(强调方法)的范畴。
总结一下:
- Seq2Seq 属于 Encoder-Decoder 的大范畴
- Seq2Seq 更强调目的,Encoder-Decoder 更强调方法
看起来Encoder-Decoder就是根据输入句子Source生成了目标句子Target,比如:
-
如果Source是中文句子,Target是英文句子,那么这就是解决机器翻译问题的Encoder-Decoder框架;
-
如果Source是一篇文章,Target是概括性的几句描述语句,那么这是文本摘要的Encoder-Decoder框架;
-
如果Source是一句问句,Target是一句回答,那么这是问答系统或者对话机器人的Encoder-Decoder框架。
由此可见,在文本处理领域,Encoder-Decoder的应用领域相当广泛。
Encoder-Decoder框架不仅仅在文本领域广泛使用,在语音识别、图像处理等领域也经常使用。比如对于语音识别来说,该框架完全适用,区别无非是Encoder部分的输入是语音流,输出是对应的文本信息;而对于“图像描述”任务来说,Encoder部分的输入是一副图片,Decoder的输出是能够描述图片语义内容的一句描述语。
一般而言,文本处理和语音识别的Encoder部分通常采用RNN模型,图像处理的Encoder一般采用CNN模型。
Attention怎么来的
从注意力模型的命名方式看,很明显,该模型借鉴了人类的注意力机制。
视觉注意力机制是人类视觉所特有的大脑信号处理机制。人类视觉通过快速扫描全局图像,获得需要重点关注的目标区域,也就是一般所说的注意力焦点,而后对这一区域投入更多注意力资源,以获取更多所需要关注目标的细节信息,而抑制其他无用信息。
这是人类利用有限的注意力资源从大量信息中快速筛选出高价值信息的手段,是人类在长期进化中形成的一种生存机制,人类视觉注意力机制极大地提高了视觉信息处理的效率与准确性。
为什么需要Attention
前馈网络和循环网络都有很强的能力。但为什么还要引入注意力机制呢?
上文提到:Encoder(编码器)和 Decoder(解码器)之间只有一个「向量 c」来传递信息,且 c 的长度固定。因此Encoder-Decoder 存在一个问题:当输入信息太长时,会丢失掉一些信息。
-
计算能力的限制:当要记住很多“信息“,模型就要变得更复杂,然而目前计算能力依然是限制神经网络发展的瓶颈。
-
优化算法的限制:虽然局部连接、权重共享以及pooling等优化操作可以让神经网络变得简单一些,有效缓解模型复杂度和表达能力之间的矛盾;但是,如循环神经网络中的长距离以来问题,信息“记忆”能力并不高。
可以借助人脑处理信息过载的方式,例如Attention机制可以提高神经网络处理信息的能力。
Attention 机制就是为了解决“信息过长,信息丢失”的问题。
Attention模型的特点是 Eecoder 不再将整个输入序列编码为固定长度的「中间向量 C」,而是编码成一个向量的序列。目标句子中的每个单词都应该学会其对应的源语句子中单词的注意力分配概率信息。这意味着在生成每个单词的时候,原先都是相同的中间语义表示C会被替换成根据当前生成单词而不断变化的 C i C_{i} Ci。
理解Attention模型的关键就是这里,即由固定的中间语义表示C换成了根据当前输出单词并调整成加入注意力模型的变化的 C i C_{i} Ci。增加了注意力模型的Encoder-Decoder框架理解起来如下图所示:
这样,在产生每一个输出的时候,都能够做到充分利用输入序列携带的信息。而且这种方法在翻译任务中取得了非常不错的成果,并已延伸到很多非NLP领域的任务当中。
Attention的思想如同它的名字一样,就是“注意力”,在预测结果时把注意力放在不同的特征上。
举个例子。比如在预测“我妈今天做的这顿饭真好吃”的情感时,如果只预测正向还是负向,那真正影响结果的只有“真好吃”这三个字,前面说的“我妈今天做的这顿饭”基本没什么用,如果是直接对token embedding进行平均去求句子表示,会引入不少噪声。所以引入attention机制,让我们可以根据任务目标赋予输入token不同的权重,理想情况下前半句的权重相应的降低,后三个字的权重则会提高,比如是“0.3, 0.3, 0.3”,那么在计算句子表示时就变成了:
最终表示 C i C_{i} Ci= 0.01x我+0.01x妈+0.01x今+0.01x天+0.01x做+0.01x的+0.01x这+0.01x顿+0.02x饭+0.3x真+0.3x好+0.3x吃
并且所有的权重之和必须为1,这就不得不提到老生常谈的softmax函数了。
现在我们已经大概知道Attention是什么东东了,怎么用也大概清楚了,那么问题来了,这个权重具体应该怎么计算呢?
Attention的机制原理
本节先以机器翻译作为例子讲解目前最常见的Soft Attention模型的基本原理,之后抛离Encoder-Decoder框架抽象出了注意力机制的本质思想,然后介绍一下Transformer所采用也是最近广为使用的Self Attention的基本思路。
这是本文的最最最重点的内容了,废话不多说,开始!
Soft Attention
先看几张图,图片来自吴恩达所讲授的线上deeplearning.ai,视频链接:179 & 180
(推荐大家看一下吴恩达教授的机器学习以及深度学习课程,讲的很不错,B站均有资源,建议观看顺序:ML–CS229–DL–CS230),
不得不说,吴教授的笔记就是这么不拘一格但又一目了然,下面我用一张图大概描述一下上面的过程。
Soft Attention的计算过程
比如将机器翻译中的“机器学习”变成"machine learning",计算过程如图所示:
其中
h
i
h^{i}
hi是编码器每个step的输出,
z
i
z^{i}
zi是解码器每个step的输出,计算步骤是这样的:
Encoder:通过Word Embedding方式(如Word2vec,glove等)将汉字转化成词向量,然后通过模型训练,得到 [ h 1 h^{1} h1, h 2 h^{2} h2, h 3 h^{3} h3, h 4 h^{4} h4],此处一般采用RNN模型,LSTM/GRU居多。
Decoder:开始解码了,先用固定的start token也就是 z 0 z^{0} z0和每个 h i h^{i} hi计算(在不同论文里可能会采取不同的方法进行计算,一般采用神经网络即可),然后通过softmax函数,得到加权的 c 0 c^{0} c0, z 0 z^{0} z0可以随机初始化,不过一般采用的是Encoder的最后一个输出。
用 c 0 c^{0} c0作为解码的RNN输入(同时还有上一步的 z 0 z^{0} z0),得到 z 1 z^{1} z1 并预测出第一个词是machine。
再继续预测的话,就是用
z
1
z^{1}
z1 去求attention,需要注意的是,上一个Decoder输出
y
i
−
1
y_{i-1}
yi−1也会当成输入之一,即:
z
i
=
f
(
y
i
−
1
,
c
i
−
1
,
z
i
−
1
)
y
i
=
g
(
z
i
)
z^{i} = f(y_{i-1},c^{i-1},z^{i-1})\\\\ y_{i} = g(z^{i})
zi=f(yi−1,ci−1,zi−1)yi=g(zi)
注意:索引
i
i
i从0开始
绝大多数Soft Attention模型都是采取上述的计算框架来计算注意力分配概率分布信息,区别只是在Attention的定义及计算方式上可能有所不同而已。
上述内容就是经典的Soft Attention模型的基本思想,那么怎么理解Attention模型的物理含义呢?一般在自然语言处理应用里会把Attention模型看作是输出Target句子中某个单词和输入Source句子每个单词的对齐模型,这是非常有道理的。
目标句子生成的每个单词对应输入句子单词的概率分布可以理解为输入句子单词和这个目标生成单词的对齐概率,这在机器翻译语境下是非常直观的:传统的统计机器翻译一般在做的过程中会专门有一个短语对齐的步骤,而注意力模型其实起的是相同的作用。
Attention的本质思想
如果把Attention机制从上文讲述例子中的Encoder-Decoder框架中剥离,并进一步做抽象,可以更容易看懂Attention机制的本质思想。
我们可以这样来看待Attention机制:将Source中的构成元素想象成是由一系列的<Key,Value>数据对构成,此时给定Target中的某个元素Query,通过计算Query和各个Key的相似性或者相关性,再利用softmax函数,得到每个Key对应Value的权重系数,然后对Value进行加权求和,即得到了最终的Attention数值。所以本质上Attention机制是对Source中元素的Value值进行加权求和,而Query和Key用来计算对应Value的权重系数。即:
A
t
t
e
n
t
i
o
n
v
a
l
u
e
=
∑
s
o
f
t
m
a
x
(
F
(
Q
u
e
r
y
,
K
e
y
i
)
∗
V
a
l
u
e
i
)
Attention \\ value=\\sum{softmax (F(Query,Key_{i})*Value_{i})}
Attention value=∑softmax(F(Query,Keyi)∗Valuei)
上文所举的机器翻译的例子里,因为在计算Attention的过程中,Source中的Key和Value合二为一,指向的是同一个东西,也即输入句子中每个单词对应的语义编码。F则为MLP。
Self Attention
传统的Attention是计算Q和K之间的依赖关系以及相关性,而self attention则是分别计算Q和K自身的依赖关系。
了解了模型大致原理,我们可以详细的看一下究竟Self-Attention结构是怎样的。
Scaled Dot-Product Attention
上述attention可以被描述为将query和key-value键值对的一组集合映到输出,其中 query,keys,values和输出都是向量,输出被计算为values的加权和,其中分配给每个value的权重由query与对应key的相似性函数计算得来。这种attention的形式被称为“Scaled Dot-Product Attention”。
Self Attention计算过程
上面说的可能比较抽象,我们来看一个具体的例子(图片来源于https://jalammar.github.io/illustrated-transformer/,该博客讲解的极其清晰,强烈推荐)。
假如我们要翻译一个词组Thinking Machines,其中Thinking的输入的embedding vector用 x 1 x_{1} x1表示,Machines的embedding vector用 x 2 x_{2} x2表示。
-
当我们处理Thinking这个词时,我们需要计算句子中所有词与它的Attention Score,这就像将当前词作为搜索的Query,去和句子中所有词(包含该词本身)的key去匹配,看看相关度有多高。
-
我们用q1代表Thinking对应的query vector,k1和k2分别代表Thinking以及Machines对应的key vector,则计算Thinking的attention score的时候我们需要计算q1与k1,k2的点乘,同理,我们计算Machines的attention score的时候需要计q2与k1,k2的点乘。
-
如上图中所示我们分别得到q1与k1,k2的点乘积,然后我们进行尺度缩放与softmax归一化。显然,当前单词与其自身的attention score一般最大,其他单词根据与当前单词重要程度有相应的score。然后我们在用这些attention score与value vector相乘,得到加权的向量。
-
如果将输入的所有向量合并为矩阵形式,则所有query, key, value向量也可以合并为矩阵形式表示
也就是说, x 1 x_{1} x1与 W Q W^{Q} WQ权重矩阵相乘得到 q 1 q_{1} q1, 就是与这个单词相关的查询向量。最终使得输入序列的每个单词的创建一个查询向量、一个键向量和一个值向量。
6. 上述操作即可简化为矩阵形式
以上就是self attention的具体计算过程。
Soft Attention和Self Attention的区别
Name | Description |
---|---|
Soft Attention | 在一般任务的Encoder-Decoder框架中,输入Source和输出Target内容是不一样的,比如对于英-中机器翻译来说,Source是英文句子,Target是对应的翻译出的中文句子,Attention机制发生在Target的元素Query和Source中的所有元素之间。 |
Self Attention | 1. Self Attention顾名思义,指的不是Target和Source之间的Attention机制,而是Source内部元素之间或者Target内部元素之间发生的Attention机制,也可以理解为Target=Source这种特殊情况下的注意力计算机制。其具体计算过程是一样的,只是计算对象发生了变化而已。2. 其次,很明显,引入Self Attention后会更容易捕获句子中长距离的相互依赖的特征,因为如果是RNN或者LSTM,需要依次序序列计算,对于远距离的相互依赖的特征,要经过若干时间步步骤的信息累积才能将两者联系起来,而距离越远,有效捕获的可能性越小。但是Self Attention在计算过程中会直接将句子中任意两个单词的联系通过一个计算步骤直接联系起来,所以远距离依赖特征之间的距离被极大缩短,有利于有效地利用这些特征。除此外,Self Attention对于增加计算的并行性也有直接帮助作用。这是为何Self Attention逐渐被广泛使用的主要原因。 |
Attention的分类
Soft Attention和Self Attention是现如今最为常用的Attention模型,但并不代表只有这两种模型,在茫茫计算机科学当中,依旧存在很多不常用但是活跃在各大NLP任务当中的Attention模型,具体分为以下几类:
-
Soft/Hard Attention
soft attention:传统attention,可被嵌入到模型中去进行训练并传播梯度
hard attention:不计算所有输出,依据概率对encoder的输出采样,在反向传播时需采用蒙特卡洛进行梯度估计。主要采用了强化学习(RL)的思想,相当于在soft attention的情况下,对这个概率进行采样,即是hard attention的一个样本,输出为one-hot向量,并聚焦于某一点。MC sampling是RL常用的一种方法(如Policy gradient的实现中依赖MC方法来估计梯度) -
Global/Local Attention
global attention:传统attention,对所有encoder输出进行计算
local attention:介于soft和hard之间,会预测一个位置并选取一个窗口进行计算 -
Self Attention
传统attention是计算Q和K之间的依赖关系,而self attention则分别计算Q和K自身的依赖关系。
其余Attention模型的具体计算逻辑,大家可以自行百度,在此不多赘述。
Attention模型的优缺点
-
优点:
一步到位获取全局与局部的联系,不会像RNN网络那样对长期依赖的捕捉会收到序列长度的限制。
由固定的中间语义表示C换成了根据当前输出单词并调整成加入注意力模型的变化的 C i C_{i} Ci,有效解决“信息过长,信息丢失”的问题
每步的结果不依赖于上一步,可以做成并行的模式
相比CNN与RNN,参数少,模型复杂度低。(根据attention实现方式不同,复杂度不一)
-
缺点:
没有任何东西是完美的,再好的模型肯定会存在缺点的,Attention的缺点就是没法捕捉位置信息,即没法学习序列中的顺序关系,也就是缺少位置信息,比方说有十个输入词向量,我会将10个输入均等看待,哪个先哪个后,Attention不关心,解决办法就是通过加入位置信息,如通过位置向量来改善,在每一个输入里面再加一个位置向量,告诉模型哪个第一个,哪个第二个等,具体可以参考最近大火的BERT模型(后期我也会进行讲解,敬请期待哟!)。
总结
现如今,Attention大有替代传统RNN的架势,由于其卓越的实际效果,目前在深度学习领域里得到了广泛的使用,了解并熟练使用对于解决实际问题会有极大帮助。
第一次写文章,参考了很多大佬的笔记、博文,文章链接都附在参考当中,我在此均表示万分感谢🙏,!
如果哪里写的不对,欢迎大家批评指正,共同进步!
展望
本章所讲述的主要是原理分析以及计算过程,缺少一定的实战演练。
接下来我将根据本章的attention模型原理给出代码分析以及效果展示,希望大家继续关注,感谢!
参考
- https://zhuanlan.zhihu.com/p/43493999
- https://blog.csdn.net/malefactor/article/details/78767781 (特别感谢张俊林博士!)
- https://segmentfault.com/a/1190000020843265
- https://blog.csdn.net/fkyyly/article/details/104881616?utm_source=app&app_version=4.13.0&code=app_1562916241&uLinkId=usr1mkqgl919blen
- https://zhuanlan.zhihu.com/p/53682800
- https://zhuanlan.zhihu.com/p/48612853
- https://jalammar.github.io/illustrated-transformer/
- Vaswani A, Shazeer N, Parmar N, et al. Attention is all you need[C]//Advances in neural information processing systems. 2017: 5998-6008 链接
以上是关于细讲:Attention模型的机制原理的主要内容,如果未能解决你的问题,请参考以下文章