要了解深度学习中的注意力模型,就不得不先谈 Encoder-Decoder 框架,因为目前大多数注意力模型附着在 Encoder-Decoder 框架下,当然,其实注意力模型可以看作一种通用的思想,本身并不依赖于特定框架,这点需要注意。
Encoder-Decoder 框架可以看作是一种深度学习领域的研究模式,应用场景异常广泛。下图是文本处理领域里常用的 Encoder-Decoder 框架最抽象的一种表示
文本处理领域的 Encoder-Decoder 框架可以这么直观地去理解:可以把它看作适合处理由一个句子(或篇章)生成另外一个句子(或篇章)的通用处理模型。对于句子对 < S o u r c e , T a r g e t > <Source,Target>,我们的目标是给定输入句子 Source,期待通过Encoder-Decoder 框架来生成目标句子 Target。Source 和 Target 可以是同一种语言,也可以是两种不同的语言。而 Source 和 Target 分别由各自的单词序列构成
S o u r c e = ( x 1 , x 2 , … , x m ) T a r g e t = ( y 1 , y 2 , … , y n ) Source = (x_1,x_2,\ldots,x_m) \\ Target = (y_1,y_2,\ldots,y_n) \\ Source=(x1,x2,…,xm)Target=(y1,y2,…,yn)
Encoder 顾名思义就是对输入句子 Source 进行编码,将输入句子通过非线性变换转化为中间语义表示 C
C = F ( x 1 , x 2 , … , x m ) C = F(x_1,x_2,\ldots,x_m) C=F(x1,x2,…,xm)
对于解码器 Decoder 来说,其任务是根据句子 Source 的中间语义表示 C 和之前已经生成的历史信息 y 1 , y 2 , … , y i − 1 y_1,y_2,\ldots,y_{i-1} y1,y2,…,yi−1来生成i时刻要生成的单词
y i = G ( C , y 1 , y 2 , … , y i − 1 ) y_i = G(C,y_1,y_2,\ldots,y_{i-1}) yi=G(C,y1,y2,…,yi−1)
聊天机器人是一种many to many的网络拓扑结构,核心还是用Encoder-Decoder对不同长度的序列进行处理
注意力模型最近几年在深度学习各个领域被广泛使用,无论是图像处理、语音识别还是自然语言处理的各种不同类型的任务中,都很容易遇到注意力模型的身影。
觉注意力机制是人类视觉所特有的大脑信号处理机制。人类视觉通过快速扫描全局图像,获得需要重点关注的目标区域,也就是一般所说的注意力焦点,而后对这一区域投入更多注意力资源,以获取更多所需要关注目标的细节信息,而抑制其他无用信息。这是人类利用有限的注意力资源从大量信息中快速筛选出高价值信息的手段,是人类在长期进化中形成的一种生存机制,人类视觉注意力机制极大地提高了视觉信息处理的效率与准确性。
简单的描述一下上图,Attention机制主要是在Decoder的地方加了一层Attention Layer,以往Decoder从Encoder中获取的信息只有Encoder最后的隐状态,包含的信息量不够,或者说在做翻译任务的时候,我们拿笼统的一句话去做翻译是效率比较低的,要关注不同语言相同语义的词语的位置信息,如中文: 你好吗? 英文: How are you? 你
的位置不同,吗
的位置也不同,Attention机制就是解决这种问题的;
所以在每个Encoder隐状态 S i S_i Si向下一时刻传递的时候,会将 S i S_i Si与Encoder的每一时刻的隐状态 h 1 , … , h n h_1, \ldots, h_n h1,…,hn计算相似度, 再将相似度进行softmax归一化操作,得到权重(使得权重之和为1), 再用权重与各个隐状态相乘相加得到 C i C_i Ci, 这个 C i C_i Ci就是Attention Layer的产物,最后将 S i , C i , S i − 1 ( 上 一 时 刻 的 输 出 , 这 一 时 刻 的 输 入 ) S_i,C_i,S_{i-1}(上一时刻的输出,这一时刻的输入) Si,Ci,Si−1(上一时刻的输出,这一时刻的输入)进行拼接,再计算得到结果
注意
这里说的下标,与上图标注的有一些偏差,以上图来说,就是 S i , C i − 1 , S i − 1 S_i,C_{i-1},S_{i-1} Si,Ci−1,Si−1进行拼接;(具体要看S与C从几开始数,如果都是从0开始数的话,上图就是正确的,如果S从0开始数,C从1开始说,那么上文就是正确的,理解即可)
以 S 0 S_0 S0去计算权重为例
其中 V T , W V^T,W VT,W都是要计算的矩阵,然后对每个计算出的 α i ~ \tilde{\alpha_i} αi~进行softmax变换,得到 α i \alpha_i αi
其中 W K , W Q W_K,W_Q WK,WQ都是要计算的矩阵
前面说的Attention机制是在Encoder与Decoder之间计算相似性的一种方式,关注的点在于两种不同序列的相关关系,而Self-Attention则是在Encoder或Decoder中,取代RNN或者LSTM层的一种机制,因为RNN不能很好的做到并行计算,总是会有序列依赖,导致计算只能串行
上图就是Self-Attention计算第一个时刻的上下文向量的过程,计算的 b i b_i bi都不依赖于序列信息,可以并行计算
Self-Attention的作者认为一组 W q , W k , W v W^q,W^k,W^v Wq,Wk,Wv矩阵还不够爽,于是拿了 j j j组 W q , W k , W v W^q,W^k,W^v Wq,Wk,Wv,计算 b i , j b_{i,j} bi,j,最后将 j j j组b拼接起来,再乘上矩阵 W O W^O WO得到一个时刻的上下文向量 b i b_i bi
如下图所示,线越深表示两者关系越紧密,在英语中的area
与在法语中的zone
的意思是相同的,只是两种语言之间的语法有区别(我猜的…),所以Attention是用于解决Decoder应该侧重学习Encoder的哪些方面的问题
如下图所示,线越深表示两者关系越紧密,Self-attention的作用可以总结为指代消歧
,能得出某一个序列内部词语的相关性,将一些指代不明的词转换成有意义的词语,或者能记住一些固定搭配…