点击上方,选择星标置顶,每天给你送干货

阅读大概需要15分钟

跟随小博主,每天进步一丢丢

来自:数论遗珠

本文需要的前序知识储备是:循环神经网络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

后续有更新或纠错,会在知乎文章上呈现。


方便交流学习,备注:昵称-学校(公司)-方向,进入DL&NLP交流群。

方向有很多:机器学习、深度学习,python,情感分析、意见挖掘、句法分析、机器翻译、人机对话、知识图谱、语音识别等。

记得备注呦

推荐阅读:

【ACL 2019】腾讯AI Lab解读三大前沿方向及20篇入选论文

【一分钟论文】IJCAI2019 | Self-attentive Biaffine Dependency  Parsing

【一分钟论文】 NAACL2019-使用感知句法词表示的句法增强神经机器翻译

【一分钟论文】Semi-supervised Sequence Learning半监督序列学习

【一分钟论文】Deep Biaffine Attention for Neural Dependency Parsing

详解Transition-based Dependency parser基于转移的依存句法解析器

经验 | 初入NLP领域的一些小建议

学术 | 如何写一篇合格的NLP论文

干货 | 那些高产的学者都是怎样工作的?

一个简单有效的联合模型

近年来NLP在法律领域的相关研究工作


让更多的人知道你“在看”

NLP硬核入门-Seq2Seq和Attention机制相关推荐

  1. 完全图解RNN、RNN变体、Seq2Seq、Attention机制

    完全图解RNN.RNN变体.Seq2Seq.Attention机制 本文作者:思颖 2017-09-01 18:16 导语:帮助初学者开启全新视角 雷锋网(公众号:雷锋网) AI科技评论按:本文作者何 ...

  2. seq2seq与Attention机制

    学习目标 目标 掌握seq2seq模型特点 掌握集束搜索方式 掌握BLEU评估方法 掌握Attention机制 应用 应用Keras实现seq2seq对日期格式的翻译 4.3.1 seq2seq se ...

  3. 《自然语言处理学习之路》15 Seq2Seq、Attention机制

    书山有路勤为径,学海无涯苦作舟 黑发不知勤学早,白首反悔读书迟. 1. Sequence-to-Sequence(N to M) 1.1 简介 先编码,再解码.STAR开始解码,END终止解码. EN ...

  4. js websocket同步等待_WebSocket硬核入门:200行代码,教你徒手撸一个WebSocket服务器...

    本文原题"Node.js - 200 多行代码实现 Websocket 协议",为了提升内容品质,有较大修订. 1.引言 最近正在研究 WebSocket 相关的知识,想着如何能自 ...

  5. Seq2Seq模型及Attention机制

    Seq2Seq模型及Attention机制 Seq2Seq模型 Encoder部分 Decoder部分 seq2seq模型举例 LSTM简单介绍 基于CNN的seq2seq Transformer A ...

  6. Glove与Attention机制资料的整理

    前言 2021.7.31 学习是一个持续的过程,重新梳理一下自己的文章.突然发现这篇文章好像是之前组会的时候准备汇报资料学习的参考文献2333.真的很推荐去看. 1 Glove 论文出处:<&l ...

  7. 深入理解attention机制

    深入理解attention机制 1. 前言 2. attention机制的产生 3. attention机制的发展 4. attention机制的原理 5. attention的应用 参考文献 1. ...

  8. Transformer详解(二):Attention机制

    1.Encoder-Decoder中的attention机制 上一篇文章最后,在Encoder-Decoder框架中,输入数据的全部信息被保存在了C.而这个C很容易受到输入句子长度的影响.当句子过长时 ...

  9. 深度学习与自然语言处理教程(6) - 神经机器翻译、seq2seq与注意力机制(NLP通关指南·完结)

    作者:韩信子@ShowMeAI 教程地址:https://www.showmeai.tech/tutorials/36 本文地址:https://www.showmeai.tech/article-d ...

  10. 「NLP」 聊聊NLP中的attention机制

    https://www.toutiao.com/i6716536091681227267/ 本篇介绍在NLP中各项任务及模型中引入相当广泛的Attention机制.在Transformer中,最重要的 ...

最新文章

  1. Test on 11/10/2016
  2. Oracle 聚合函数(Aggregate Functions)说明
  3. QPS过万,redis大量连接超时怎么解决?
  4. php替换时 css中的图片不显示不出来,URL重写:CSS,JS和图像未加载
  5. linux qemu 报错 Unable to reserve 0xfffff000 bytes of virtual address space at 0x1000 解决方法
  6. 数据库更新记录,但程序查不到新记录问题
  7. android预加载布局,Android 懒加载优化
  8. PHP魔法函数性能分析
  9. 获取网络时间并刷新本地时间(源码2)
  10. linux文件被覆盖如何恢复_在Linux下误删文件后恢复
  11. 打开QQ快捷键截屏 CTRL+ALT+A
  12. Linux内核启动:setup_arch
  13. English——视频总结(一)
  14. java中list、set和map 实例
  15. C语言课设图书管理系统(大作业)
  16. PCB LAYOUT 设计民睿科技有限公司承接PCBLAYOUT项目
  17. 不能创建对象qmdispatch_按键精灵更新时提示 ActiveX 部件不能创建对象 错误代码 800a01ad_电脑故障...
  18. Python爬虫实战——反爬策略之代理IP【无忧代理】
  19. DNS区域(ZONE)相关概念
  20. Android studio中assets文件更换之后不生效

热门文章

  1. 结构与表现分离的思想
  2. Linux下的压缩和解压缩命令——compress/uncompress
  3. Nginx/Apache/Tomcat记录屏蔽真实IP
  4. 任正非“2012实验室”讲话全文曝光
  5. vue-awesome-swiper 的安装和使用
  6. django数据模型中关于on_delete的使用
  7. HTML 5 input placeholder 属性 实现搜索框提示文字点击输入后消失
  8. ECMAscript6入门(1)
  9. java对获取的字节数组进行处理
  10. Docker Swarm学习教程