针对语音、视频等序列数据,我们需要进行全局时序信息考虑,因此RNN模型是最初最基础的模型结构。
主要可以分析的任务:语音识别、语音合成、视频摘要生成、音视频情感预测等。
存在问题:输出的序列长度与输入序列长度保持一致,不能任意变化。
seq2seq,由Encoder和Decoder两个部分组成,每部分都是一个RNNCell(RNN、LSTM、GRU等)结构。
Encoder将一个序列编码为一个固定长度的语义向量,Decoder将该语义向量解码为另一个序列。
主要有两种形式存在,区别在于Decoder解码端,Encoder是一致的。
Encoder:
Decoder:
paper: Cho et al.(2014) Learning Phrase Representations using RNN Encoder–Decoder for Statistical Machine Translation
Decoder端,每个时刻都会接收来自Encoder端的语义向量C, 与当前输入信号、隐藏状态一起, 进入RNN cell
上述yt为解码端输入,开始信号一般为
paper: Sutskever et al.(2014) Sequence to Sequence Learning with Neural Networks
Decoder端,将Encoder端的语义向量C作为初始隐藏状态,与当前信号一起,进入RNN cell
因此,需要注意的是,该方式在Decoder端后续时刻并不接收C
存在问题:seq2seq框架用Encoder将输入序列编码成一个固定大小的语义向量,这个过程是对信息压缩的过程,不可不免地会损失很多信息,Decoder在解码时无法关注到输入序列的更多细节
注意力机制引入使为了解码端可以充分利用编码端完整的数据信息,减少信息损失。在解码层,生成每个时刻的y,都会利用到编码端的x1,x2,x3....,而不再仅仅利用最后时刻的隐藏状态向量
因此,在Encoder-Decoder结构中引入attention,以机器翻译任务为例,大致过程如下:
但是,Attention 并不一定要在 Encoder-Decoder 框架下使用的,他是可以脱离 Encoder-Decoder 框架的,如下图所示:
具体可以理解为:图书馆(source)有很多书(value),每本书都有自己的编号(key),当我们想了解关于AI编程(query)方面的内容时,并不是所有书都仔细看,我们就主要关注其中相关的书籍(value2和value5)
attention计算主要分为三个阶段:
第一步: query 和 key 进行相似度计算,得到权值
第二步:将权值进行归一化,得到直接可用的权重
第三步:将权重和 value 进行加权求和
从计算区域、所用信息、结构层次、使用模型和权值计算方式5个方面对Attention的形式进行归类:
1. 计算区域
1)Soft Attention,这是比较常见的Attention方式,对所有key求权重概率,每个key都有一个对应的权重,是一种全局的计算方式(也可以叫Global Attention)。
2)Hard Attention,这种方式是直接精准定位到某个key,其余key就都不管了,相当于这个key的概率是1,其余key的概率全部是0。因此这种对齐方式要求很高,要求一步到位,如果没有正确对齐,会带来很大的影响。另一方面,因为不可导,一般需要用强化学习的方法进行训练。
3)Local Attention,这种方式其实是以上两种方式的一个折中,对一个窗口区域进行计算。先用Hard方式定位到某个地方,以这个点为中心可以得到一个窗口区域,在这个小区域内用Soft方式来算Attention。
2. 所用信息
1)General Attention,这种方式利用到了外部信息,常用于需要构建两段文本关系的任务,query一般包含了额外信息,根据外部query对原文进行对齐。
2)Self Attention,这种方式只使用内部信息,key和value以及query只和输入原文有关,key=value=query,相当于寻找原文内部的关系。
3. 结构层次
结构方面根据是否划分层次关系,分为单层attention,多层attention和多头attention:
1)单层Attention,这是比较普遍的做法,用一个query对一段原文进行一次attention。
2)多层Attention,一般用于文本具有层次关系的模型,假设我们把一个document划分成多个句子,在第一层,我们分别对每个句子使用attention计算出一个句向量(也就是单层attention);在第二层,我们对所有句向量再做attention计算出一个文档向量(也是一个单层attention),最后再用这个文档向量去做任务。
3)多头Attention,用多个query对一段原文进行了多次attention,每个query都关注到原文的不同部分,相当于重复做多次单层attention:
4. 模型方面
1)CNN+Attention
CNN的卷积操作可以提取重要特征,也算是Attention的思想,但是CNN的卷积感受视野是局部的,需要通过叠加多层卷积区去扩大视野。
Max Pooling直接提取数值最大的特征,也像是hard attention的思想,直接选中某个特征。
CNN上加Attention可以加在这几方面:
a. 在卷积操作前做attention
b. 在卷积操作后做attention
c. 在pooling层做attention,代替max pooling。
2)LSTM+Attention
LSTM内部有Gate机制,其中input gate选择哪些当前信息进行输入,forget gate选择遗忘哪些过去信息,算是一定程度的Attention
LSTM通常使用Attention机制,对所有step的hidden state进行加权,把注意力集中到整段文本中比较重要的hidden state信息。
3)纯Attention
一堆向量去计算attention。
5. 相似度计算方式
1)点乘:
2)矩阵相乘:
3)cos相似度:
4)串联方式:
5)多层感知机:
以点积为例介绍attention的具体计算方式。
可以理解为:
query对应的是需要被表达的序列(称为序列A),key和value对应的是用来表达A的序列(称为序列B)。
序列A和序列B在高维空间α中的表达 A_α的每个位置分别和B_α计算相似度,产生的权重作用于序列B在高维空间β中的高维表达B_β,获得序列A(query)在高维空间β中的高维表达A_β
这两种机制都是基于2.1 Cho Encoder-Decoder的结构,编码端Encoder是一致的,差异在于解码端Decoder
Encoder:
x为Encoder端输入,h为Encoder端隐藏层,o为Encoder端输出
1. Bahdanau Attention
paper:Bahdanau et.al(2014)
Decoder分为两步进行:
1)生成当前时刻的语义向量C
当前时刻权值e_t由 Decoder端隐藏层状态s_t-1 (query)和 Encoder端隐藏层状态h_t (key)计算得到;最终的attention由 权值e 和 Encoder端隐藏层状态h (value)计算得到
2)传递隐层信息并预测
解码端Decoder的RNN cell, 以 s_t-1,y_t-1,c_t的拼接为输入 (y_t-1为Decoder端上一时刻输出, 即当前时刻输入),进行预测
2. Luong Attention
paper: Luong et.al(2015)
Decoder分为三步进行:
1) 传递隐层信息
解码端Decoder的RNN cell, 以 s_t-1,y_t-1的拼接为输入 (y_t-1为Decoder端上一时刻输出, 即当前时刻输入)
2)生成当前时刻的语义向量C
当前时刻权值e_t由 Decoder端隐藏层状态s_t (query)和 Encoder端隐藏层状态h_t (key)计算得到;最终的attention由 权值e 和 Encoder端隐藏层状态h (value)计算得到
3)传递attention隐层信息并预测
相比于上述Bahdanau Attention,该结构新添加concatenation layer (也可是其他模型结构),以Decoder端隐藏层状态s_t 和当前时刻的语义向量C 为输入,产生一个注意力隐状态,然后进行预测
paper:Attention is All you Need (nips.cc)
Encoder端:
多个multi-head attention层 (self-attention)
Decoder端:
多个masked multi-head attention层 (self-attention)
多个multi-head attention层 (cross-attention)
涉及的其他部分:
Positional Embedding
【self-attention】encoder中的self-attention的query, key, value都对应了源端序列(即A和B是同一序列),decoder中的self-attention的query, key, value都对应了目标端序列。
【cross-attention】decoder中的cross-attention的query对应了目标端序列,key, value对应了源端序列(每一层中的cross-attention用的都是encoder的最终输出)
Attention是将query和key映射到同一高维空间中去计算相似度,而对应的multi-head attention把query和key映射到高维空间α的不同子空间中去计算相似度。
具体而言:如果是N头注意力,则将高维空间维度划分N份,形成N个子空间,每个子空间进行attention计算,然后在最后合并不同子空间的attention信息。
在参数总量保持不变的情况下,降低了计算每个head的attention时每个向量的维度,降低整体计算量;
由于Attention在不同子空间中有不同的分布,Multi-head Attention实际上是寻找了序列之间不同角度的关联关系,增强了attention表现力;
Transformer模型属于自回归模型,在Decoder端后面预测的token的推断是基于前面的token的。
在推理阶段,token是按照从左往右的顺序推理的。也就是说,在推理timestep=T的token时,decoder只能“看到”timestep < T的 T-1 个Token, 不能和timestep大于它自身的token做attention。
因此,为了保证训练时和推理时的一致性,在训练时要同样防止token与它之后的token去做attention,加入mask矩阵。
下图为Decoder端,输入矩阵"
Mask 操作是在 Self-Attention 的 Softmax 之前使用的
具体操作可分析为:
1)通过输入矩阵 X 计算得到 Q, K, V 矩阵。然后计算 Q 和 K
2)使用 Mask 矩阵遮挡住每一个单词之后的信息
3)进行softmax操作
4)与V矩阵进行计算
Why: 为什么需要位置编码?
Transformer模型抛弃了RNN作为序列学习的基本模型(ransformer的特性使得encoder的输入向量之间完全平等)。RNN本身是一种顺序结构,天生就包含了词在序列中的位置信息。
当抛弃RNN,完全采用Attention取而代之,这些词序信息就会丢失,模型就没有办法知道每个词在句子中的相对和绝对的位置信息。
因此,有必要把词序信号加到词向量上帮助模型学习这些信息,位置编码(Positional Encoding)就是用来解决这种问题的方法。
What: 位置编码是什么?
位置编码(Positional Encoding)是一种用词的位置信息对序列中的每个词进行二次表示的方法。
优势?
How: 怎么实现位置编码?
一种好的位置编码方案需要满足以下几条要求:
Transformer的作者们提出:首先,这种编码不是单一的一个数值,而是包含句子中特定位置信息的d维向量(非常像词向量)。第二,这种编码没有整合进模型,而是用这个向量让每个词具有它在句子中的位置的信息。
位置向量(PE)的维度等于词向量(WE)的维度
论文中使用的Positional Encoding(PE)是正余弦函数,位置(pos)越小,波长越长,每一个位置对应的PE都是唯一的。
具体而言:给定一个长度为n的输入序列,t 表示词在序列中的位置,d 是位置向量的维度,生成位置向量的函数定义为:
可以认为,位置编码向量是一个包含每个频率的正弦和余弦对。
后续?
位置编码向量和序列的embedding向量相加,送入之后的模型中。
seq2seq中的两种attention机制(图+公式) - 知乎 (zhihu.com)
一文看懂 Attention(本质原理+3大优点+5大类型) - 知乎 (zhihu.com)
【经典精读】Transformer模型深度解读 - 知乎 (zhihu.com)
Transformer 模型详解 - 简书 (jianshu.com)
一文读懂Transformer模型的位置编码 - 知乎 (zhihu.com)