NLP硬核入门-Seq2Seq和Attention机制
本文需要的前序知识储备是: 循环神经网络 RNN ,词向量 WordEmbedding ,门控单元 VanillaRNN/GRU/LSTM 。
1 seq2seq
seq2seq 是 sequence to sequence 的缩写。前一个 sequence 称为编码器 encoder ,用于接收源序列 source sequence 。后一个 sequence 称为解码器 decoder ,用于输出预测的目标序列 target sequence 。
seq2seq 主要用于序列生成任务,例如:机器翻译、文本摘要、对话系统,等等。当然也可以用于文本分类等任务。
图 1.1 seq2seq
最传统的 seq2seq 流程如图 1.1 所示:
( 1 )将源序列输入 encoder 网络。
( 2 ) encoder 将源序列的信息编码成一个定长的向量 encoder vector 。
( 3 ) encoder vector 被送入 decoder 网络。
( 4 ) decoder 根据输入的向量信息,输出预测的目标序列。
seq2seq 在被提出后,马上受到了广泛的关注和应用,也暴露出一些问题。首先被关注到的,就是人们发现把一整个文本序列通过 encoder 压缩到区区一个向量里,很难通过 decoder 进行完美地没有信息缺失的解码。
此外,由于循环神经网络 RNN 的特性,源序列中越迟输入的文本,对 encoder vector 的影响也越大。换句话说, encoder vector 里会包含更多的序列尾的文本信息,而忽略序列头的文本信息。所以在很多早期的论文中,会将文本序列进行倒序后再输入 encoder ,模型测评分数也会有一个显着地提高。
为了让 decoder 能够更好地提取源序列的信息, Bahdanau 在 2014 年提出了注意力机制 Attention Mechanism , Luong 在 2015 年对 Bahdanau Attention 进行了改进。这是两个最经典的注意力机制模型。两个 Attention 模型的本质思路是一样的,下文均以 Luong Attention 模型作为范例。
2 Attention Mechanism
注意力机制的理解,可以参考 CV 领域的思想:我们在看到一幅画的时候,每个时刻总会有一个关注重点,比如说某个人、某个物品、某个动作。
所以,在 NLP 领域,我们在通过 decoder 预测输出目标序列的时候,也希望能够有一种机制,将目标序列当前 step ,和源序列某几个 step 的文本关联起来。
以翻译任务为例,将“我爱机器学习”翻译成“ I love machine learning. ”在 decoder 输出序列第一个 step ,我们希望关注输入序列中的“我”,并将“我”翻译成“ I ”;在第三个 step ,我们希望关注“机器”,并翻译成“ machine ”。
这个例子比较简单,我们就会产生一个初步的想法:是不是把源序列中的每个词语单独翻译成英文,再依次输出,就构成目标序列了呢?
但是,如果进一步思考下,我们就会发现两个问题:
( 1 ) 一词多义 :源序列里的同一个词,在输出序列里,可能根据场景的不同,会有不同的输出。例如“我”可能被翻译成“ I ”,也有可能被翻译成“ me ”。这有点类似于中文的“一词多义”,在英文里估计是叫做“一词多态”吧,我们姑且将这类由一个词可以映射成多个词的现象,广义地统称为“一词多义”。解决“一词多义”问题的一个有效途径,就是参考源序列的语境信息,也就是上下文信息,来生成词向量。
( 2 ) 序列顺序 :源序列和目标序列并不是顺序依次映射的,例如“你是谁?”翻译成“ who are you? ”,不同语言有不同的语法规则和顺序。这就需要在 decoder 输出的每一个 step ,确定当前 step 应该翻译源序列中的哪一个词。
这两个问题也就是 Attention 机制的关注重点。
图 2.1 LuongAttention
图 2.1 是一个 Luong Attention 的示意图,是作者其后续的论文里呈现的一张修订后的示意图。
还有个理解 Attention 的方式,就是参考残差网络 ResNet 。因为源序列太长了,导致早期的信息无法有效地被传递,所以需要一个额外的通道,把早期的信息送到解码器上。送的时候还不能只送一个词的信息,最好把上下文信息一起给送了。
下一节会用一个最简单的模型,介绍 Attention 机制的实现步骤,在此之前,先约定下参数符号:
h(output) : RNN 的隐藏状态,主要用于将信息输出到 RNN 模型外。
s(state) : RNN 的状态,主要用于 RNN 模型内部,模型将信息传递给下一个 step 。
a :对齐向量
c :上下文信息向量。
x :源序列。
y :目标序列。
下标 s 表示源序列,下标 t 表示目标序列。 s1 表示源序列第 1 个 step ,以此类推。
括号里的 output 和 state ,是为了方便读者将论文里的算法理论,和工业实践里 tensorflow 的 tf.nn.dynamic_rnn 函数联系起来,稍微有个印象就好。 dynamic_rnn 函数返回两个向量,第一个是 output ,也就是 encoder 所有 step 、网络最后一层输出的 h ;第二个是 state ,也就是 encoder 最后一个 step 、网络层所有层输出的 s 。
3 Attention 五部曲
3.1 执行 encoder
图 3.1 步骤一:执行 encoder
步骤一的行为是将源数据依次输入 Encoder ,执行 Encoder 。 目的在于将源序列的信息,编译成语义向量,供后续 decoder 使用。
在每个 step , endocer 会输出一个表征当前 step 语义的 output ( h )向量和一个 state ( s )向量:
( 1 ) 我们收集 每个 step 的 output ( h ),构成 output 矩阵,矩阵的维度是 [step_len,dim_rnn] ,即源数据 step 长度,乘以 rnn 单元数量。
( 2 ) 我们收集 最后一个 step 的 state ( s ),作为传入 decoder 的向量。
encoder 对于模型的贡献,在于提供了 outputs 矩阵和 state 向量。
注一:为了便于理解,我这里的 encoder 使用了单层网络,多层网络的 outputs 和 state 见上一节末尾的描述。
注二:很多论文的 h 和 s 的描述并没有一个统一的标准,经常混淆。因为早期论文的 RNN 单元,是用 VanillaRNN 或 GRU 实现的,这两个门控单元在同一个 step ,输出的 h 和 s 是一样的。但是,若通过 LSTM 实现, h 和 s 是不同的,这个需要引起注意。
注三:早期的论文中, encoder 的 state 是直接传递给 decoder ,作为 initial state 的。但是在工程应用中,也存在直接将 0 序列作为 initial state 传递给 decoder 的情况。另外,部分论文也有将 state 进行一些处理,添加一些额外的信息,再传递给 decoder 的算法。总之, encoder 和 decoder 之间传递 state 的方式比较灵活,可以根据实际情况自行选择和改进。
注四: RNN 的单元数量,即为 encoder 输出向量的维度。也就是用 dim_rnn 维度的向量,来表征源序列当前 step 文本的语义信息。对照同样表征语义信息的词向量的维度 dim_word_embd ,我建议两者的维度不宜相差过大,否则会造成浪费。
3.2 计算对齐系数 a
图 3.2 步骤二:计算对齐系数 a
步骤二解决的是第 2 节提出的“序列顺序”的问题。 在 decoder 的每个 step ,我们需要关注源序列的所有 step 和目标序列当前 step 的相关性大小,并输出相关(对齐)系数 a 。
所以,在 decoder 输出一个预测值前,都会针对 encoder 的所有 step ,计算一个 score 。这个 score 表示当前的 decoder 工作,需要从 encoder 的哪些 step 里抽取信息,以及抽取的权重大小。然后将 score 汇总向量化后,每个 decoder step 能获得一个维度为 [step_len,1] 的 score 向量。
这个 score 的计算方式有很多种,图 3.2 中列举了 Luong Attention 提及的 3 种的传统计算方式。我画的流程图中采用的是第 1 种,就是将源序列所有 step 的 output ( h )和目标序列当前 step 的 output ( h )逐个相乘,得到的值即为 score 。有些论文就是在 score 的计算方式上进行创新的。
计算出 score 后,很自然地按惯例使用 softmax 进行归一化,得到对齐向量 a ,维度也是 [step_len,1] 。
注一:很多论文的各种参数的缩写符号都不一样,有一个理清模型流程顺序的小技巧:就是去找 softmax 函数,以 softmax 为锚点。 Attention 常见的使用 softmax 的地方有两个,一个是步骤二的对齐系数 a ,另一个在步骤五将会提到,在输出预测词之前,要对概率分数进行 softmax 归一化处理。
注二:对齐系数 a 虽然只是一个过程数据,但是却蕴含很重要的信息,可用于 PointerNet 和 CopyNet 。
3.3 计算上下文语义向量 c
图 3.3 步骤三:计算上下文语义向量 c
在描述这个步骤前,我们先回顾下词向量的 CBOW 模型。在 CBOW 模型收敛后,每个词的词向量,等于它周围若干个词的词向量的均值。这其中蕴含的意思是: 表征一个词的,不是这个词本身,而是这个词的上下文(语境)。
CBOW 模型是比较简单粗暴地将上下文的词向量求平均。实际上,如果能够以一个加权平均的方式获取词向量,那幺这个词向量一定能够更准确地表达这个词在当前语境里的语义。
举个例子:“孔夫子经历了好几个春秋寒暑,终于修订完成了春秋麟史。”在这里,第一个“春秋”表示“一年”,“经历”、“寒暑”显然和它关系更密切,利用加权上下文构成词向量时,应该赋予更高的权重。第二个“春秋”表示儒家六经之一,“修订”、“麟史”关系和它更密切,同样应该赋予高权重。
在步骤三里, 我们将对齐系数 a 作为权重,对 encoder 每个 step 的 output 向量进行加权求和(对齐向量 a 点乘 outputs 矩阵),得到 decoder 当前 step 的上下文语义向量 c 。
注一: BERT 也有用到对齐系数的思想,而且更为直观漂亮。
3.4 更新 decoder 状态
图 3.4 步骤四:更新 decoder 状态
在步骤四里,需要 更新 decoder 状态,这个状态可以是 h ,也可以是 s 。 能够用于更新 h 和 s 的信息数据,可以是:前 step 的 s ,现 step 的 h ,现 step 的上下文向量 c ,以及其它一些包含有效信息的数据。
BahdanauAttention 和 Luong Attention 最大的区别就在于这个步骤,前者更新的是 s ,后者更新的是 h 。不过由于 Bahdanau 用的是前 step 的 s , Luong 用的是先 step 的 h ,所以后者在工程化实现上会简单点。
具体的更新公式的细节,在这里不作详细描述,因为不同模型可能会采用不同的更新公式,很多论文也是围绕更新公式进行创新点研究的。
需要注意的是,在这个环节,训练模式和预测模式略有差别: decoder 每个 step 都要输入一个数据,在训练模式,输入的数据是目标序列当前 step 的真实值,而不使用前 step 的 h ;在预测模式,输入的数据是前 step 的 h ,而不使用输出序列的真实值。虽然在图 3.4 中,我画了两条输入,但是要根据模型当前处于训练模式还是预测模式,选择其中的一条进行输入。
3.5 计算输出预测词
图 3.5 步骤五:计算输出预测词
这个步骤我在图里没有画全,其实很简单,同 CBOW 模型 /Skip-Gram 模型的隐藏层到输出层的那部分一样,做一个语义向量到目标词表的映射(如果 attention 用于分类模型,那就是做一个到各个分类的映射),然后再进行 softmax 就可以了。
4 其它
4.1 Local Attention 和 Global Attention
前文所提及的 Attention 都是 Global Attention ,还有一个 Local Attention ,将在这个小节作一个简单的说明。
Global Attention 就是针对源序列的所有 step ,求对齐系数 a 。而 LocalAttention 只针对源序列的部分 step ,求对齐系数 a ,这个部分 step 的长度是超参数,需要凭经验人为配置。
Local Attention 所截取的部分 step 的中心点的选取(对齐)方式,是另一个需要关注的点。论文中提及了两个对齐方式:
( 1 ) Monotonicalignment (local-m) :简单粗暴的,直接按源序列和目标序列的 step 绝对值对齐。
( 2 ) Predictivealignment (local-p) :通过模型,学习计算出截断 step 的对齐中心。
Luong 的论文里有提及, LocalAttention 的效果优于 Global Attention 。
注: CV 领域有个 Soft-Attention 和 Hard-Attention ,和这里 NLP 领域的两个 Attention 优点类似。
4.2 常见的可以替换改进的模块
1. 用于生成对齐向量 a 的分值 score 的计算方式。
2.h 和 s 的更新公式。
3. 基本 RNN 的结构,包括替换门控单元、更改 RNN 层数、单向改双向等。
参考资料
[1] Bahdanau D ,Cho K , Bengio Y . Neural Machine Translation by Jointly Learning to Align andTranslate[J]. Computer Science, 2014.
[2] Luong M T ,Pham H , Manning C D . Effective Approaches to Attention-based Neural MachineTranslation[J]. Computer Science, 2015.
[3] Andrew Ng RecurrentNeural Networks
由于微信文章 有 修改字数的限制,故附上知乎文章的链接: https://zhuanlan.zhihu.com/p/73589030
后续有更新或纠错,会在知乎文章上呈现。
本文转载自公众号: 数论遗珠,作者阮智昊