在“编码器—解码器(seq2seq)”⼀节⾥,解码器在各个时间步依赖相同的背景变量来获取输⼊序列信息。当编码器为循环神经⽹络时,背景变量来⾃它最终时间步的隐藏状态。git
如今,让咱们再次思考那⼀节提到的翻译例⼦:输⼊为英语序列“They”“are”“watching”“.”,输出为法语序列“Ils”“regardent”“.”。不难想到,解码器在⽣成输出序列中的每⼀个词时可能只需利⽤输⼊序列某⼀部分的信息。例如,在输出序列的时间步1,解码器能够主要依赖“They”“are”的信息来⽣成“Ils”,在时间步2则主要使⽤来⾃“watching”的编码信息⽣成“regardent”,最后在时间步3则直接映射句号“.”。这看上去就像是在解码器的每⼀时间步对输⼊序列中不一样时间步的表征或编码信息分配不一样的注意⼒⼀样。这也是注意⼒机制的由来。github
仍然以循环神经⽹络为例,注意⼒机制经过对编码器全部时间步的隐藏状态作加权平均来获得背景变量。解码器在每⼀时间步调整这些权重,即注意⼒权重,从而可以在不一样时间步分别关注输⼊序列中的不一样部分并编码进相应时间步的背景变量。面试
在注意⼒机制中,解码器的每⼀时间步将使⽤可变的背景变量。记 ct′ 是解码器在时间步 t′ 的背景变量,那么解码器在该时间步的隐藏状态能够改写为:架构
这⾥的关键是如何计算背景变量 ct′ 和如何利⽤它来更新隐藏状态 st′。下⾯将分别描述这两个关键点。机器学习
咱们先描述第⼀个关键点,即计算背景变量。下图描绘了注意⼒机制如何为解码器在时间步 2 计算背景变量。函数
令编码器在时间步t的隐藏状态为 ht,且总时间步数为 T。那么解码器在时间步 t′ 的背景变量为全部编码器隐藏状态的加权平均:学习
矢量化计算背景变量测试
咱们还能够对注意⼒机制采⽤更⾼效的⽮量化计算。咱们先定义,在上⾯的例⼦中,查询项为解码器的隐藏状态,键项和值项均为编码器的隐藏状态。编码
⼴义上,注意⼒机制的输⼊包括查询项以及⼀⼀对应的键项和值项,其中值项是须要加权平均的⼀组项。在加权平均中,值项的权重来⾃查询项以及与该值项对应的键项的计算。翻译
让咱们考虑⼀个常⻅的简单情形,即编码器和解码器的隐藏单元个数均为 h,且函数 。假设咱们但愿根据解码器单个隐藏状态 st′−1 和编码器全部隐藏状态 ht, t = 1, . . . , T来计算背景向量 ct′ 。咱们能够将查询项矩阵 Q 设为
,并令键项矩阵 K 和值项矩阵 V 相同且第 t ⾏均为
。此时,咱们只须要经过⽮量化计算:
便可算出转置后的背景向量 。当查询项矩阵 Q 的⾏数为 n 时,上式将获得 n ⾏的输出矩阵。输出矩阵与查询项矩阵在相同⾏上⼀⼀对应。
如今咱们描述第⼆个关键点,即更新隐藏状态。以⻔控循环单元为例,在解码器中咱们能够对⻔控循环单元(GRU)中⻔控循环单元的设计稍做修改,从而变换上⼀时间步 t′−1 的输出 yt′−一、隐藏状态 st′−1 和当前时间步t′ 的含注意⼒机制的背景变量 ct′。解码器在时间步: math:t’ 的隐藏状态为:
其中的重置⻔、更新⻔和候选隐藏状态分别为:
其中含下标的 W 和 b 分别为⻔控循环单元的权重参数和误差参数。
本质上,注意⼒机制可以为表征中较有价值的部分分配较多的计算资源。这个有趣的想法⾃提出后获得了快速发展,特别是启发了依靠注意⼒机制来编码输⼊序列并解码出输出序列的变换器(Transformer)模型的设计。变换器抛弃了卷积神经⽹络和循环神经⽹络的架构。它在计算效率上⽐基于循环神经⽹络的编码器—解码器模型一般更具明显优点。含注意⼒机制的变换器的编码结构在后来的BERT预训练模型中得以应⽤并令后者⼤放异彩:微调后的模型在多达11项⾃然语⾔处理任务中取得了当时最早进的结果。不久后,一样是基于变换器设计的GPT-2模型于新收集的语料数据集预训练后,在7个未参与训练的语⾔模型数据集上均取得了当时最早进的结果。除了⾃然语⾔处理领域,注意⼒机制还被⼴泛⽤于图像分类、⾃动图像描述、唇语解读以及语⾳识别。
注意力模型实现中英文机器翻译
数据预处理
首先先下载本目录的数据和代码,并执行 datautil.py,生成中、英文字典。
执行 train.ipynb,训练时间会比较长。
测试模型,运行test.py文件。
做者:@mantchs
GitHub:github.com/NLP-LOVE/ML…