前言
最近几年,注意力——在深度学习社区中,已然成为最广为流行的概念和实用工具。在这篇博客里,我们将一起回顾它是如何被“发明”出来的,以及引申出来的各种变种和模型,如 transformer和SNAIL。
目录
- Seq2Seq问题所在
- 为”翻译“而生
- 定义
- 注意力机制”家族“
- 概要
- 自注意力机制(Self-Attention)
- 柔性 vs 刚性注意力
- 全局 vs 局部注意力
- 指针网络(Pointer Network)
- Transformer
- key, Value, Query
- Multi-Head 自注意力
- 编码器
- 解码器
- 整体结构
- SNAIL
- 自注意力 GAG
- 文献
注意力,在某种程度上,受启发于我们是如何关注图片中的某些区域,或者句子中的某些相关词。举个栗子:
人类的视觉注意力,使得我们能够在图片的“低解析度”背景下,更加关注具有“高解析度或辨识度”(High resolution)的特定区域(如黄色区域中狗的耳朵),然后逐渐调整焦点,移动到另一个耳朵、眼睛、鼻子等,最后进行推断整张图片的信息。给定图片中的一小块补丁区域,图片中其余的像素点也可以提供这块补丁应该展示什么的信息。在上图中,假设我们先看到了狗的鼻子、尖尖的右耳和Shiba迷离的眼睛,因此我们就会理所当然的期望在黄色区域看到另一只尖尖的耳朵。但是像毯子和毛衣的信息对于解析狗的特征信息几乎没有什么帮助。
同样地,我们可以解释一句话或者上下文中词与词之间的关系。当看到“eating”这个词时,我们会期望在后面不远的位置看到“食物“描述的词。下图中有色词表示食物,但并不是每个词都与”eating“直接强相关。
简而言之,在深度学习中,注意力可以广泛的借助重要性权重向量来实现:在预测或推断一个元素时,如图片中的像素点或句中的一个词,我们使用注意力向量来判断,它与其他元素有多强的关联性,然后对加权后的向量求和以逼近最后的目标值(target)。
Seq2Seq问题所在
Seq2Seq模型诞生于语言模型领域(Sutskever, et al. 2014)——广泛的讲,它是将一个输入序列(source)转化为另一个序列(target),两个序列都可以是不定长的。转化任务的场景包括多语言机器翻译(文本或语音)、问答对话对话生成系统、甚至是句子解析为语法树。
Seq2Seq模型一般都会包含编码-解码结构,包括:
- 编码器——处理序列输入并压缩信息到一个固定长度的上下文向量中(sentence embedding 或者 “thought” vector)。上下文向量被当做是输入序列的语义概要。
- 解码器——由上下文向量初始化,并每次产生一个转码输出。早期的研究仅使用编码网络的最后一个状态作为下次解码的初始状态。
编码器和解码器都是循环神经网络结构,如LSTM或者GRU单元
固定长度上下文向量具有一个明显的致命缺点——无法记忆长句子。一旦完成编码器输入序列的处理,就会遗忘开始的部分。因此注意力机制(Bahdanau et al., 2015)被提出,解决这个问题。
为”翻译“而生
注意力机制”生来“就是为机器翻译任务帮助记忆长序列的句子输入。相对于原始借助编码器的最后一个隐藏单元的输出构建单一上下文向量,注意力机制的独家”秘方“在于,其考虑了上下文向量和所有序列输入的信息,构建了”连接“。每一个输出元素下的连接的权重都是自动学习的。
上下文向量已经考虑了整体输入序列信息,我们不需要担心遗忘的问题。源输入和目标输出的语义对齐问题由上下文向量学习和控制。实际上上下文向量处理三方面的信息:
- 编码器的隐藏状态
- 解码器的隐藏状态
- 源输入和目标输出的对齐
定义
接下来我们以理论的角度定义注意力机制。我们用X表示长度为n的源输入序列,用Y**表示长度为m*的目标输出序列:
(加粗的变量表示向量,下同)
编码器是一个双向RNN结构(也可选其他RNN结构)——包括前向和后向隐藏层状态。简单的维度拼接可以表示当下编码状态,可以理解为同时考虑了中心词的上、下文信息:
解码网络在t时刻有隐藏状态St——包括上一个序列隐藏状态,上一输出和上下文向量(所有输入序列的加权求和),权重如下:
对齐模型会针对第i个输入序列和第t个输出序列,分配一个对齐得分,以评判(yt,xi)的对齐效果。在Bahdanau的文章中,对齐得分向量是由单个隐藏层的前向网络来组织的,并和整体网络的其他部分进行联合训练。score计算函数方式输入下:
对齐得分矩阵是一个很好的副产物,并可以可视化的表示输入序列和输出序列的关联程度。
这里有一个Tensorflow团队提供的一个实现方法的很好教程。
注意力机制”家族“
由于注意力的帮助,源输入和目标输出序列之间的依赖不再受限于距离问题。这在机器翻译任务中,收益颇大。不久被很好的拓展到计算机视觉领域(Xu et al. 2015),人们开始探索注意力机制的各种变种(Luong, et al., 2015; Britz et al., 2017; Vaswani, et al., 2017)。
概要
下表是几种主流的注意力机制(或更宽泛的注意力机制)
- (*)在Luong, et al., 2015表示”concat“,在Vaswani, et al.表示”累积注意力(additive attention)“
- (^) 添加了尺度因子1/sqrt(n)——当输入很大时,softmax函数可能具有极小的梯度,导致难以高效的更新学习
- (&) 指“intra-attention”
自注意力
自注意力,又称”intra-attention“,是一种在计算同一序列表示时,权重和序列的位置相关机制,被证明在机器阅读理解,抽象概要(abstractive summarization)和图片描述生成中非常有效。
这篇[long short-term memory network]论文使用了自注意力机制做机器阅读。如下图,自注意力机制能够学习到当前词和句中先前词之前的关联性。
在[show, attend and tell]这篇文章中,自注意力机制被应用在图片生成描述任务中。图片首先被CNN编码,然后输入到带有自注意力机制的RNN网络中,来学习图片各个特征与描述中每个词之前的映射关系。注意力权重的可视化清晰地的展示了模型每关注一部分特征都会输出一个词。
柔性 vs 刚性注意力
”柔性“ vs ”刚性“是如何定义注意力的另一种方式,原始思想最初在[show, attend and tell]文章中提出——基于注意力是否需要处整篇图片还是仅仅局部一小块:
-
柔性注意力:对齐权重通过源图片所有的”patch“进行学习映射,和Bahdanau et al., 2015想法一致
- Pro: 模型是平滑且可导的
- Con: 当输入图片很大时,训练代价很高
-
刚性注意力:每次仅选取图片中一个”patch“
- Pro: 在inference阶段计算量更小
- Con: 模型是不可导的,需要更复杂的技术手段——如降低方差(variance reduction)或者强化学习去训练(Luong, et al., 2015)
全局 vs 局部注意力
Luong, et al., 2015提出了”全局“和”局部“注意力的概念。全局注意力和柔性注意力很相似;局部注意力是”柔性“和”刚性“的糅合——相对于刚性,改进使其可导:模型首先预测当前目标词的粗略对齐位置,然后在这个源输入的位置上应用一个中心窗口框住,计算上下文向量。
指针网络(Pointer Network)
在排序或者旅行推销员问题上,输入和输入都是序列数据。输出元素的离散类别总数事先是未知的,取决于输入变量的尺度。这很难通过经典的Seq2Seqm或者NMT模型来解决。指针网络(Ptr-Net; Vinyals, et al. 2015)被提出来解决此类问题:当输出元素和输入序列的位置相关时,指针网络并非是借助注意力来将编码器的隐藏状态糅合仅上下文向量(如图8),而是将注意力机制应用在输入元素上,每次选取一个座位解码步骤的输出。
Ptr-Net输出的是序列的整数索引c=(c1, ..., cm),给定输入序列向量x=(x1, ..., xn)且1<ci<n (可以取等号)。模型仍然沿用了编码-解码框架。编码解码的隐藏状态分别为(h1, ..., hn)和(s1, ..., sm)。其中si是解码器单元激活的输出门。指针网络在隐藏状态间应用了了累积注意力,人后通过softmax进行归一化。
注意力机制被简化了,因为指针网络并非是借助注意力权重将编码状态糅合仅输出。在这里,输出仅和位置相关,和输入内容无关。
Transformer
[Attention is All you Need]这篇文章,毫无疑问是2017年最有影响力的文章。它表示柔性注意力有了很大的提升,并使无RNN单元的Seq2Seq建模成为了可能,提出的”transformer“模型全部仅由自注意力机制构建。
秘密在于它的网络架构。
key, Value 和 Query
transformer的主要由称之为multi-head self-attention mechanism的单元组成——它将输入元素的编码表示看做key-value对(k, v),均为n维(n为输入序列长度);在NMT的上下文中,keys和values都是编码器的隐藏状态。在解码器中,先前步的输出被压缩进一个queryQ中(m维),且下一步输出由这个query映射到keys和values集合来产生。
transformer采用了scaled dot-product attention:输出是有values加权求和得到,其中分配给每一项的权重由query和所有keys点积求得。
multi-head自注意力机制
相对于一次性计算注意力,multi-head注意力机制借助尺度化的点积注意力机制进行并行化多次计算。每个独立的注意力输出通过简单拼接并线性的转换到指定的维度空间。难道因为集成总是有效的?根据文章描述: ”multi-head attention allows the model to jointly attend to information from different representation subspaces at different positions. With a single attention head, averaging inhibits this.”
编码器
编码器能够生成一个基于注意力的表示,具有从潜在的无限大上下文空间中定位相关信息片段的能力。
- N=6的相同层堆叠
- 每一层都有一个multi-head self-attention layer和一个位置敏感的全连接前向网络
- 每一个子网络层都采用了残差连接和网络层正则化。所有的子层输出数据都是512维
解码器
解码器能够从编码器的表示中抽取分析信息。
- N=6的相同层堆叠
- 每一层都有两个带有multi-head self-attention layer的子网络结构和一个全连接前向网络
- 和解码器相似,每一个子网络层采用了残差和网络正则化
- 第一个multi-head self-attention sub-layer被修改以防止位置信息被传导到后续位置,正如当我们预测当下位置的信息时,并不想要偷瞥属于目标序列的未来信息。
整体结构
最后我们整体看一下transformer的网络结构:
- 源输入和目标输出序列首先都会经过embedding层得到均为512维度的数据
- 为了保留位置信息,一个基于正弦波的位置编码器被整合应用到embedding层
- softmax和线性层被添加到最后的解码输出中
尝试去实现Transformer网络是很有趣的事情,这个是原博主实现的代码:lilianweng/transformer-tensorflow
SNAIL
transformer模型中没有RNN或者CNN结构,即使在embedding向量中引入了位置相关的编码,也是一种序列顺序的弱整合。对于位置敏感的任务如增强学习,这是一个问题。
Simple Neural Attention Meta-Learner(SNAIL)被提出部分解决了这个问题——借助带有temporal的Transformer自注意力机制。实验表明这种网络在监督学习和强化学习任务中都比较擅长。
SNAIL 诞生于元学习(meta-learning)——很值得另开一个博客单独介绍它。简单地说,he meta-learning model is expected to be generalizable to novel, unseen tasks in the similar distribution
详细的内容可以参考这里
自注意力GAN
最后我想提一下最近流行的对抗生成网络,以及自注意力GAN(SAGAN; Zhang et al., 2018),并展示注意力机制是如何提高生成图片的质量的。
经典的深度卷积对抗生成网络(DCGAN)均用多层CNN网络表示生成器和判别器。但是网络表示能力受限于卷积核大小,因为一个像素的特征被限制在很小的局部区域里。为了连接更远的区域,特征必须通过卷积操作被稀释,并且依赖性信息不保征被保留。
在视觉任务里,柔性注意力机制下的上下文向量可以明确的学习一个像素和其他位置之间的关系,即使相隔较远的区域,这可以很容易的捕捉全局依赖性。因此带有注意力机制的GAN也同样能够捕捉这种细节。
SAGAN采用了非局部神经网络来计算注意力权重。卷积的图片特征可以将x映射成三份copy,分别与Transformer中的key,value和query相对应。
之后我们采用点击计算最后特征输出的注意力权重:
其中αij是注意力映射中的一个实例,表明当模型合成第j位置像素时应该分配给i位置多大权重。W均为1×1的卷积核。如果你觉得1×1的卷积核很诡异,可以浏览一下Andrew Ng的这篇教程。输出oj是最终输出o=(o1, ..., oj, ..., oN)的列向量。
然后,注意力层的输出乘上尺度参数,累加原始的输入特征映射:
其中尺度参数γ在训练过程中从0开始增加,网络首先比较依赖局部区域,然后渐渐的通过分配权重给较远的区域去更新学习。
*如果你注意到本博客中的一些错误地方,请及时联系liujiezhangbupt@gmail.com。
文献
- [1] “Attention and Memory in Deep Learning and NLP.” - Jan 3, 2016 by Denny Britz
- [2] “Neural Machine Translation (seq2seq) Tutorial”
- [3] Dzmitry Bahdanau, Kyunghyun Cho, and Yoshua Bengio. “Neural machine translation by + jointly learning to align and translate.” ICLR 2015.
- [4] Kelvin Xu, Jimmy Ba, Ryan Kiros, Kyunghyun Cho, Aaron Courville, Ruslan Salakhudinov, Rich Zemel, and Yoshua Bengio. “Show, attend and tell: Neural image caption generation with visual attention.” ICML, 2015.
- [5] Ilya Sutskever, Oriol Vinyals, and Quoc V. Le. “Sequence to sequence learning with neural networks.” NIPS 2014.
- [6] Thang Luong, Hieu Pham, Christopher D. Manning. “Effective Approaches to Attention-based Neural Machine Translation.” EMNLP 2015.
- [7] Denny Britz, Anna Goldie, Thang Luong, and Quoc Le. “Massive exploration of neural machine translation architectures.” ACL 2017.
- [8] Ashish Vaswani, et al. “Attention is all you need.” NIPS 2017.
- [9] Jianpeng Cheng, Li Dong, and Mirella Lapata. “Long short-term memory-networks for machine reading.” EMNLP 2016.
- [10] Xiaolong Wang, et al. “Non-local Neural Networks.” CVPR 2018
- [11] Han Zhang, Ian Goodfellow, Dimitris Metaxas, and Augustus Odena. “Self-Attention Generative Adversarial Networks.” arXiv preprint arXiv:1805.08318 (2018).
- [12] Nikhil Mishra, Mostafa Rohaninejad, Xi Chen, and Pieter Abbeel. “A simple neural attentive meta-learner.” NIPS Workshop on Meta-Learning. 2017.
- [13] “WaveNet: A Generative Model for Raw Audio” - Sep 8, 2016 by DeepMind.
- [14] Oriol Vinyals, Meire Fortunato, and Navdeep Jaitly. “Pointer networks.” NIPS 2015.