论文笔记 - Attention 综述

Attention and Augmented Recurrent Neural Networks

循环神经网络是深度学习的根基之一,她允许神经网络对序列数据进行处理,比如文本,语音和视频。

这句话形容特别贴切,意思就是rnn能将序列转换成包含了理解,语义的表示。

They can be used to boil a sequence down into a high-level understanding, to annotate sequences, and even to generate new sequences from scratch!


基本的 rnn 在解决 long sequence 时非常挣扎,其变体 LSTM 有效的解决这一问题(但问题依然存在)。

随着时间的发展,出现了各种 augument RNNs. 其中以下4种 stand out exciting.

这些变体都是 RNN 有力的拓展,更令人惊奇的是,他们还能有效的结合在一起,似乎只是广阔空间中的一点。除此之外,他们都依赖于同样的 underlying trick --- attention.

Neural Turing Machines

Neural Turing Machines 神经图灵机将 RNNs 和外部 memory bank 结合在一起。向量用来表示神经网络中的自然语言,memory 是向量的数组。

如上图所示,能够看出其原理是将每一个词的向量表示存储在 memory 中。那么从 memory 中读、以及写入 memory 是怎么操作的呢?
最大的难点在于让整个过程可微(differentiable).特别的是,我们希望在读出和写入的位置具有差异性,以便我们可以知道从哪儿读和写。这很棘手(tricky),因为 memory 地址基本上是离散的。
NMTs 采取了一个非常聪明的方法,每一步读和写都包括 memory 中的所有位置,只是对于不同的位置,读和写的程度不同。

举个例子,这里我们只关注 reading. RNN 输出一个 "attention distribution",表示对于 memory 不同位置的读取程度。这样,读入的操作可以看作加权求和。

\[r \leftarrow \sum_ia_iM_i\]

类似的,在读入的过程中也是对 memory 中所有位置。再一次,输出一个 "attention distribution" 用来表示对每个位置的写入程度。我们在一个 memory 位置获得新的 value 是旧的 memory 和写入值的 凸结合(convex combination).

\[M_i \leftarrow a_iw+(1-a_i)M_i\]

其中 \(w\) 是写入值(write value)。

但是 NTMs 如何确定去注意 memory 中的那一个位置呢? 他们使用了两种不同的方法的结合: content-based attention 和 location-based attention. 前者允许 NMTs 通过匹配 memory 中的每一个位置,并 focus on 最 match 的位置。后者允许 memory 中的相对移动,保证 NMT 能循环。

这种读和写的能力允许 NTM 执行许多简单的算法,而这些算法以前超越了神经网络。 例如,他们可以在 memory中存储一个长序列,然后遍历它,反向重复它。 当他们这样做时,我们可以看他们读和写的地方,以更好地理解他们在做什么:

关于 repeat copy 的实验,可以参考这篇论文Show, attend and tell: Neural image caption generation with visual attention

他们能够模仿一个 lookup table,甚至可以 sort numbers(althought they kind of cheat). 但另一方面,他们仍然不能做很多基本的事儿,比如 add or multiply numbers.

自从 NTM 这篇论文之后,又出现了很多相同方向的令人 exciting 的文章.

The Neural GPU 4 overcomes the NTM’s inability to add and multiply numbers.
Zaremba & Sutskever 5 train NTMs using reinforcement learning instead of the differentiable read/writes used by the original.
Neural Random Access Machines 6 work based on pointers.
Some papers have explored differentiable data structures, like stacks and queues [7, 8].
memory networks [9, 10] are another approach to attacking similar problems.

Code
- Neural Turing MachineTaehoon Kim’s - Neural GPU publication TensorFlow Models repository - Memory Networks, Taehoon Kim’s

关于这篇 paper 真的很难看懂,

Attention Interfaces

当我翻译一个句子时,我特别注意我正在翻译的单词。 当我录制录音时,我会仔细聆听我正在积极写下的片段。 如果你要求我描述我正在坐的房间,那么我会浏览我正在描述的物体。

神经网络能够通过 attention 机制完成上述行为,也就是 focusing on 给出信息的部分内容。举个例子,一个 RNN 能够 attend over 另一个 RNN 的输出,并在每一个时间步, focus on 另一个 RNN 的不同的位置。

为了让 attention 可微,我们采用跟 NTM 同样的方法,focus 所有的位置,每个位置的程度不同。

上图中颜色的深浅表示注意的程度。

其中 attention distribution 是由 content-based attention 生成的。具体过程还是看英文描述吧:

The attending RNN generates a query describing what it wants to focus on. Each item is dot-producted with the query to produce a score, describing how well it matches the query. The scores are fed into a softmax to create the attention distribution.

最经典的使用 RNNs 之间的 attention 就是机器翻译了,Neural machine translation by jointly learning to align and translate. 传统的 seq2seq 模型通过 RNN 将整个输入序列转化为单个向量(也就是最后一层的隐藏状态),然后将其展开得到输出(word by word). 注意力机制避免了这一点,它允许 RNN 在生成输出时,能看到所有输入中的每一个词,并且根据他们之间的相关性,来选择性注意部分词。

原图是可以操作的,大牛们的技术真是厉害。。。可视化也很6。。

这种类型的 RNN 还有很多其他的应用,比如在 语音识别上的使用Listen, Attend and Spell, 使用一个 RNN 来处理音频,然后用另一个 RNN 来遍历它,并在生成一个抄本(transcript)时重点关注相关的部分。

这个图看不出来,不能截出那种效果。 其实可以看出对语音的识别,在生成对应的词时更关注的是对应的音频,并不像文本那种需要长时间依赖。

还有很多其他的应用:
- parsing tree:Grammar as a foreign language - conversational modeling:A Neural Conversational Model - image captioning: attention interface 也可以是 CNN 和 RNN 之间的,它允许 RNN 在每一个时间步生成文本时能关注图像中的不同的位置。

Then an RNN runs, generating a description of the image. As it generates each word in the description, the RNN focuses on the conv net’s interpretation of the relevant parts of the image. We can explicitly visualize this:

图片来自于Show, attend and tell: Neural image caption generation with visual attention

More broadly, attentional interfaces can be used whenever one wants to interface with a neural network that has a repeating structure in its output.

Adaptive Computation time

Standard RNNs do the same amount of computation for each time step. This seems unintuitive. Surely, one should think more when things are hard? It also limits RNNs to doing O(n) operations for a list of length n.

标准的 RNN 在每一个时间步都做着相同的大量的计算。它貌似是很合理的,但当处理的信息很复杂时,是否可以在一个时间步考虑更多?这样同样的计算量的方式限制了 RNN 在处理长度为 n 的序列时,其复杂度也为 O(n).

Adaptive Computation Time [15] is a way for RNNs to do different amounts of computation each step. The big picture idea is simple: allow the RNN to do multiple steps of computation for each time step.

自适应计算时间步(ACT) 能让 RNN 在每一个时间步做不同的计算量. 它的大致原理很简单:允许 RNN 在每一个时间步做多步运算。

In order for the network to learn how many steps to do, we want the number of steps to be differentiable. We achieve this with the same trick we used before: instead of deciding to run for a discrete number of steps, we have an attention distribution over the number of steps to run. The output is a weighted combination of the outputs of each step.

为了让网络学习得到每一个时间步的计算步数,我们希望这个计算步数是可微的(也就是把其步数当作学习得到的参数,然后通过反向传播来学习这个参数)。为了实现这个 trick,我们采用类似之前 NTM 的方式,相比每次计算一个离散的步数,我们使用注意力分布的机制来选择步数,输出的结果是所有步的加权求和。

There are a few more details, which were left out in the previous diagram. Here’s a complete diagram of a time step with three computation steps.

上图中还有更多的细节。下图是 RNN 中的在一个时间步中有3个步数的计算量。

That’s a bit complicated, so let’s work through it step by step. At a high-level, we’re still running the RNN and outputting a weighted combination of the states:

这个图看起来有点复杂,我们会一步一步的解释它。在更高的层次,我们依然运行 RNN 并输出一个状态的加权之和。

S 表示 RNN 中的隐藏状态。

The weight for each step is determined by a “halting neuron.” It’s a sigmoid neuron that looks at the RNN state and gives a halting weight, which we can think of as the probability that we should stop at that step.

每一步的权重由一个“停止神经元”确定。这是一个sigmoid神经元,用来关注当前的 RNN 的状态以及赋予它一个权重。我们可以看作是这一步是否应该停止的概率。

We have a total budget for the halting weights of 1, so we track that budget along the top. When it gets to less than epsilon, we stop

我们设总的停止权重为 1,依次减去每步输出的 halt 值,直到剩余的 halt 值小于 epsilon 后就停止。

When we stop, might have some left over halting budget because we stop when it gets to less than epsilon. What should we do with it? Technically, it’s being given to future steps but we don’t want to compute those, so we attribute it to the last step.

当我们结束后,应该还会遗留一些停止值,因为我们在停止值小于epsilon时停止的。我们该怎么处理这些剩余的停止值?从技术上讲,它们应该传递到后面的计算步骤中去,但我们不想计算这些值,所以我们就把这些剩余的停止值归总到最后一步。

When training Adaptive Computation Time models, one adds a “ponder cost” term to the cost function. This penalizes the model for the amount of computation it uses. The bigger you make this term, the more it will trade-off performance for lowering compute time.

当训练 ACT 模型时,需要给损失函数加上一个惩罚项。用来惩罚整个模型中的总的计算量。这一项越大时,它会在模型性能和计算量的折衷中倾向与减小计算量。

Code:

The only open source implementation of Adaptive Computation Time at the moment seems to be Mark Neumann’s (TensorFlow).

reference: