一:自注意力模型
上一篇文章《seq2seq》中我们学习到了attention机制,它可以看到全局的信息,并且它也可以正确地去关注到相关的有用的信息。

原始的encoder是以RNN为基础的,RNN机制实际中存在长程梯度消失的问题,对于较长的句子,我们很难寄希望于将输入的序列转化为(编码为)定长的向量而保存所有的有效信息,所以随着所需处理的句子的长度的增加,这种结构的效果会显著下降。

从encoder到特定向量C过程中,会存在信息丢失问题,因为那么多丰富的语言,怎么可能用一个特定长度的向量表示的下呢?很难吧。之前的模型很容易由于梯度消失,距离过长导致长期依赖失效,也就是有用信息丢失。而且注意力分散,导致有用信息和无用信息无法更好区分不开。

所以,attention解决了信息提取的问题,既关注全局信息,也正确把握关键信息。这其实也是一种方法论。我关注全部,但是每一部分我关注多少?

以上纯属回顾

但是这就完美了么?虽然使用了Attention机制,只解决了encoder关键信息提取的问题(从全局出发,保证关键信息能被正确关注到,而不是使用一个向量C来试图包含所有信息(理论上显然太勉强)),但是还是基于RNN模型的啊,RNN模型只能被递归运算,无法做到并行化,我们也看到了,也许注意力就是最后集中在部分,而非全局,那么理应能够被并行化计算,加快运算速度才对。

一个想法就是CNN,CNN可以做到并行化计算,似然能这样,单每一层只关注局部信息,只有在更高层才能关注到更广一点的信息,或者是全局信息,这很明显带来了另外的计算量,顾此失彼。想一想人家seq2seq的attention机制,虽然是递归运算的,但是也就是一层就可以得到全局信息。

有没有两全其美的做法呢?即可以用attention机制去获得全局信息,正确关注到应该被关注的部分,还可以并行化计算。这就是self-attention的工作了。

显然不能使用RNN结构,这个结构天然就是递归。

所以我们一起来看看self-attention做的工作吧。
如下图所示:


这一层就这么愉快表示了。并且Wq,Wk,Wv矩阵都是学习来的,权值共享的。

但是一般呢,我们还会做出一些优化。
1:假如位置信息,因为我们看到上述式子,输入的词向量之间的位置信息丢失了。“我爱你”和“爱我你”是输出一样的结果,这显然也不符合思维的,因此需要加入位置向量信息。

所以Step 1需要做适量修改,增加一步位置向量相关的操作:

其中P={p1,p2,p3,…,pn},维度和E是一样的,且每个元素取值是-1~1之间。
这样一来将位置向量添加到词嵌入中使得它们在接下来的运算中,能够更好地表达的词与词之间的距离。

2:多头self-attention(muti-head self-attention)
简单来说呢,我们希望能从不能的角度去看待位置的注意力。
实现也简单,就是设置多个完全独立的Wq,Wk,Wv矩阵,多组独立运算,分别得到自己的输出B。假设我有H个头。也就是有H组Wq,Wk,Wv矩阵,分别独立地进行运算。

最后将这H个B对应位置输出拼接起来,做一个线性变换即可。得,第i个位置输出是。

W_O也是学习到的。

如上图所示,将多个头的值concat一起,每一行拼接后形成新的第几个输出,每一列是单个头的所有N个输出。
多头拓展了专注于不同位置的能力。

Self-attention完全依赖注意力机制来刻画输入和输出之间的全局依赖关系,而且不使用递归运算的RNN网络了。这样的好处就是:
第一:可以有效的防止RNN存在的梯度消失的问题从而导致的有用信息丢失问题(这也是基本的attention机制的好处),既可以考虑全局信息,也能正确关注到应该关注的关键信息。
第二:是允许所有的字全部同时训练(RNN的训练是迭代的,一个接一个的来,当前这个字过完,才可以进下一个字),即训练并行,大大加快了计算效率。

切记,此结构只用于替换RNN的一个层结构。

现在我们就可以试图把所有RNN的结构够可以替换成 self-attention结构了。
这样一来就可以并行化计算了,可以使用GPU进行加速处理。

这个结构是Transformer结构中提出来的,将被大量使用在Transformer结构中。

二:transformer模型

下面我们来学习一下大名鼎鼎的Transformer机制。
Seq-2-Seq的主要还是encoder-decoder的结构,但是内部结构之前是RNN和CNN。效果好点的呢,就是之前学习的,增加了Attention机制的seq-2-seq了。
现在为了并行化计算,有利于GPU加速,直接使用self-attention替换掉了RNN结构。
如下图所示:

整体而言,是由一个encoders部分和一个decoders部分组成的,解码器最后有一个线性层和一个softmax层,输出对应词语的one-hot向量。

Encoders部分:
是由N个小编码器堆叠而成。
每个小编码器又是由一个多头self-attention层,和一个小的FFNN(前馈神经网络)组成。

Decoders部分:
是由N个小解码器堆叠而成。
每个小解码器又是由一个masked多头self-attention层,一个encoder-decoder多头 self-attention层,和一个小的FFNN(前馈神经网络)组成。

下面我们仔细讲解各个层:
0)Add && Norm Layer(相加归一层)
这个结构在后面很多层都有用到,因此我们先讲解这个层,方便定义符号和讲解。

先是一个残差计算。一点就是借鉴残差网络的思路,因为在应用中这个网络很深,残差结构的好多之前也学习过,防止网络过深,梯度消失,导致前面的参数无法很好更新。

然后还要做归一化操作,也就是类似于batch-normorlize的操作,目的就是归一化数据特征的分布,使其分布服从N(0~1),有利于收敛速度加快,这个在学习batch-norm的时候也学习过的,计算过程也很类似。

1)Muti-Head Self-Attention Layer(多头self-attention层)
这个不用多讲了,因为本文第一章节最开始就学习了这个计算过程。

加上相加归一层

2)FFNN Layer
这是一个 Position-wise 前向神经网络,encoder和decoder的每一层都包含一个前向神经网络,激活函数顺序是线性、RELU、线性。

加上相加归一层

3)Masked Muti-Head Self-Attention Layer
我们给词汇表增加如下词汇
< BOS>:句子开始
< EOS>:句子结尾
< UNK>:未知词汇
作为翻译的时候,比如从“我有一只猫”翻译到“I have a cat”
并行计算,先从encoder一次性计算结束,等待decoer递归迭代运算,此时decoder有点像是RNN了。每一次输入的序列都是把上一次输出的序列。

比如第一次先输入< BOS>,输出< I> ,落下去。
比如第二次先输入< I>,输出< have> ,落下去。
比如第三次先输入< I have >,输出< a> ,落下去。
比如第四次先输入< I have a >,输出< cat>,落下去。
比如第五次先输入< I have a cat >,输出< EOS>
翻译任务的话,遇到了EOS就终止了。

因此decoder每次输入的句子的长度是不一致的。怎么办呢?有多长取多长,这一层只被允许处理输出序列中更靠前的那些位置。在softmax步骤前,它会把后面的位置都是无效的,因为都没有诞生呢,无效的都给隐去(把它们设为-inf,softmax层计算后就是权值为0,也就是不关心)。因此对于不存在的序列我们就不关心了。只看存在的序列,如下图所示啊,这是前俩过程。

其他步骤都是和正常的self-attention的一致的,再加上加法归一层。

4)encoder-decoder Muti-Head Self-Attention Layer
这一层的目的就是给encoder最后生成的结果C做self-attention操作,也就是对encoder的每一层的都关注多少注意力,也就是充分利用原始句子的信息来影响自己的输出。

Encoder最后成功的矩阵C,每一行都是输入词汇的计算输出。有多少输入词汇,C就有多少行,这个矩阵会给每一个小decoder都传过去,让每一个小decoder都去对这个结果进行注意力运算。

唯一不同的是,attention过程中K和V矩阵的生成变了。
正常的self-attention的QKV矩阵都是E自己生成的,现在却变成了,E只产生Q矩阵,而是用C来生成K和V矩阵。

其他步骤都是和正常的self-attention的一致的。再加上加法归一层。

5)最终的Liner Layer和sofatmax Layer
这一层就是最后输出一个词汇的输出层了,此层的输入到输出如下:

最后输出是一个词汇的one-hot向量,输出到终结,否则落下去到下一次计算。

6)损失函数依然是交叉熵损失函数,这个不多讲了,之前在学习语言模型和词向量的时候都学习过的。下面说两个训练小技巧。
a)LabelSmooth,对于词语数量巨大的话,不要将one-hot向量标记为非0即1,非1即0,而可以试图将1改为0.95,剩下的0.05由任意五个词汇平分,每一个是0.01,。
b)学习率变化:可以尝试用如下的学习率变化趋势来学习模型。简单的说,就是先让学习率线性增长到某个最大的值,然后再按指数的方式衰减,如下图。

7)总结
核心就是transformer结构,这种结构完全依赖于注意力机制,取代了基于Encoder-Decoder的循环层,并且引入了位置嵌入,Multi-Head Attention机制。
优点就是,可解释性强,且容易并行计算,继承了attention机制的好处。

NLP《Tranformer和Self-Attention》相关推荐

  1. 机器学习笔记之马尔可夫链蒙特卡洛方法(四)吉布斯采样

    机器学习笔记之马尔可夫链蒙特卡洛方法--吉布斯采样 引言 回顾:MH采样算法 基于马尔可夫链的采样方式 细致平衡原则与接收率 MH采样算法的弊端 吉布斯采样方法 吉布斯采样的采样过程 吉布斯采样的推导 ...

  2. NLP《词汇表示方法(三)word2vec》

    Word2Vec是2013年Google发布的工具,也可以说是一个产生词向量的一群模型组合,关于词向量,也就是嵌入词向量的解释之前也解释了,这里不赘述.该工具主要包含两个词向量的生成模型,跳字模型(s ...

  3. 深入理解深度学习——Word Embedding(六):负采样(Negative Sampling)优化

    分类目录:<深入理解深度学习>总目录 相关文章: · Word Embedding(一):word2vec · Word Embedding(二):连续词袋模型(CBOW, The Con ...

  4. 负采样Negative Sampling

    1.噪声对比估计(Noise contrastive estimation) 语言模型中,根据上下文c,在整个语料库V中预测某个单词w的概率,一般采用softmax形式,公式为: NCE:将softm ...

  5. 自然语言处理中的负采样

    目录 word2vec出现的背景 跳字模型(skip-gram) 连续词袋模型(CBOW) 小结 负采样 具体训练过程 word2vec出现的背景 我们都知道,自然语言处理需要对文本进行编码,将语言中 ...

  6. NLP《词汇表示方法(四)负采样》

    一:负采样 在CBOW和Skip-Gram模型中,最后输出的都是词汇的one-hot向量,假如我们的词汇表的数量是10000,嵌入空间的维度是300,再假设此时是以Skip-Gram模型只预测cont ...

  7. 花书+吴恩达深度学习(二四)蒙特卡罗方法(重要采样,MCMC)

    文章目录 0. 前言 1. 重要采样 2. 马尔可夫链蒙特卡罗 MCMC 3. 不同峰值之间的混合挑战 如果这篇文章对你有一点小小的帮助,请给个关注,点个赞喔,我会非常开心的~ 花书+吴恩达深度学习( ...

  8. 【NLP】word2vec负采样

    一.理解负采样之前,需要先回顾一下word2vec的训练流程: 1.初始化一个embedding权重矩阵W1(N*D)→2.根据输入单词直接挑出W1矩阵中对应的行向量→3.相加并求平均得一个向量(1* ...

  9. [nlp] 负采样 nce_loss

    论文:http://demo.clab.cs.cmu.edu/cdyer/nce_notes.pdf 参考:求通俗易懂解释下nce loss? - 知乎 参考:(三)通俗易懂理解--Skip-gram ...

  10. NLP-词向量(Word Embedding)-2013:Word2vec模型(CBOW、Skip-Gram)【对NNLM的简化】【层次Softmax、负采样、重采样】【静态表示;无法解决一词多义】

    一.文本的表示方法 (Representation) 文本是一种非结构化的数据信息,是不可以直接被计算的.因为文本不能够直接被模型计算,所以需要将其转化为向量. 文本表示的作用就是将这些非结构化的信息 ...

最新文章

  1. linux 下 将 shell script 与 一个桌面图标联系在一起 (2)
  2. FastReport分页和空行填充
  3. 10 Reasons Why Your Projects Should Use the Dojo
  4. MySQL show binlog events命令查看binlog日志内容
  5. JsTree中提示:Cannot read property 'core' of underfined
  6. java 10zhuan8,Java代码 10进制转2、8、16进制转换 / 2、8、16进制转10进制转换
  7. [Python爬虫] Selenium+Phantomjs动态获取CSDN下载资源信息和评论
  8. swagger在springboot上的快速上手
  9. Vue学习笔记之02-Mustache语法以及一些指令
  10. win10中bochs仿真linux0.11环境快速搭建方法
  11. 佳博GprinterApp编辑软件使用说明
  12. SpringBoot集成DM数据库
  13. 面向对象化(封装,继承,多态)
  14. 图像分辨率+像素+尺寸+文件内存大小
  15. 关于小程序网易云音乐接口用户登录,繁忙问题
  16. NVMe-MI协议解读
  17. 租服务器太贵?流程太麻烦?教你如何免费解决
  18. leetcode877
  19. 【ALM】POLARION ALM之需求管理解决方案介绍02
  20. 我们在使用领英时有必要用领英精灵吗?

热门文章

  1. 《从零开始学Swift》学习笔记(Day 40)——析构函数
  2. ecshop设置一个子类对应多个父类并指定跳转url的修改方法
  3. Kali Linux安装Remmina无法加载RDP插件
  4. 类与类关系的UML图与代码表现
  5. Restic 跨平台加密备份工具
  6. Spring JSF集成教程
  7. Eclipse的JavaWeb项目导入到IntelliJ IDEA 并且配置Tomcat
  8. C语言,期末复习之编写程序返回三个整数中的中间数
  9. c 语言 求文件大小,C程序中如何读取目录中的文件并判断文件大小等信息
  10. GitHub+jsDelivr+PicGo+Visual Studio Code 打造稳定、快速、高效、免费图床