NLP《Tranformer和Self-Attention》
一:自注意力模型
上一篇文章《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》相关推荐
- 机器学习笔记之马尔可夫链蒙特卡洛方法(四)吉布斯采样
机器学习笔记之马尔可夫链蒙特卡洛方法--吉布斯采样 引言 回顾:MH采样算法 基于马尔可夫链的采样方式 细致平衡原则与接收率 MH采样算法的弊端 吉布斯采样方法 吉布斯采样的采样过程 吉布斯采样的推导 ...
- NLP《词汇表示方法(三)word2vec》
Word2Vec是2013年Google发布的工具,也可以说是一个产生词向量的一群模型组合,关于词向量,也就是嵌入词向量的解释之前也解释了,这里不赘述.该工具主要包含两个词向量的生成模型,跳字模型(s ...
- 深入理解深度学习——Word Embedding(六):负采样(Negative Sampling)优化
分类目录:<深入理解深度学习>总目录 相关文章: · Word Embedding(一):word2vec · Word Embedding(二):连续词袋模型(CBOW, The Con ...
- 负采样Negative Sampling
1.噪声对比估计(Noise contrastive estimation) 语言模型中,根据上下文c,在整个语料库V中预测某个单词w的概率,一般采用softmax形式,公式为: NCE:将softm ...
- 自然语言处理中的负采样
目录 word2vec出现的背景 跳字模型(skip-gram) 连续词袋模型(CBOW) 小结 负采样 具体训练过程 word2vec出现的背景 我们都知道,自然语言处理需要对文本进行编码,将语言中 ...
- NLP《词汇表示方法(四)负采样》
一:负采样 在CBOW和Skip-Gram模型中,最后输出的都是词汇的one-hot向量,假如我们的词汇表的数量是10000,嵌入空间的维度是300,再假设此时是以Skip-Gram模型只预测cont ...
- 花书+吴恩达深度学习(二四)蒙特卡罗方法(重要采样,MCMC)
文章目录 0. 前言 1. 重要采样 2. 马尔可夫链蒙特卡罗 MCMC 3. 不同峰值之间的混合挑战 如果这篇文章对你有一点小小的帮助,请给个关注,点个赞喔,我会非常开心的~ 花书+吴恩达深度学习( ...
- 【NLP】word2vec负采样
一.理解负采样之前,需要先回顾一下word2vec的训练流程: 1.初始化一个embedding权重矩阵W1(N*D)→2.根据输入单词直接挑出W1矩阵中对应的行向量→3.相加并求平均得一个向量(1* ...
- [nlp] 负采样 nce_loss
论文:http://demo.clab.cs.cmu.edu/cdyer/nce_notes.pdf 参考:求通俗易懂解释下nce loss? - 知乎 参考:(三)通俗易懂理解--Skip-gram ...
- NLP-词向量(Word Embedding)-2013:Word2vec模型(CBOW、Skip-Gram)【对NNLM的简化】【层次Softmax、负采样、重采样】【静态表示;无法解决一词多义】
一.文本的表示方法 (Representation) 文本是一种非结构化的数据信息,是不可以直接被计算的.因为文本不能够直接被模型计算,所以需要将其转化为向量. 文本表示的作用就是将这些非结构化的信息 ...
最新文章
- linux 下 将 shell script 与 一个桌面图标联系在一起 (2)
- FastReport分页和空行填充
- 10 Reasons Why Your Projects Should Use the Dojo
- MySQL show binlog events命令查看binlog日志内容
- JsTree中提示:Cannot read property 'core' of underfined
- java 10zhuan8,Java代码 10进制转2、8、16进制转换 / 2、8、16进制转10进制转换
- [Python爬虫] Selenium+Phantomjs动态获取CSDN下载资源信息和评论
- swagger在springboot上的快速上手
- Vue学习笔记之02-Mustache语法以及一些指令
- win10中bochs仿真linux0.11环境快速搭建方法
- 佳博GprinterApp编辑软件使用说明
- SpringBoot集成DM数据库
- 面向对象化(封装,继承,多态)
- 图像分辨率+像素+尺寸+文件内存大小
- 关于小程序网易云音乐接口用户登录,繁忙问题
- NVMe-MI协议解读
- 租服务器太贵?流程太麻烦?教你如何免费解决
- leetcode877
- 【ALM】POLARION ALM之需求管理解决方案介绍02
- 我们在使用领英时有必要用领英精灵吗?
热门文章
- 《从零开始学Swift》学习笔记(Day 40)——析构函数
- ecshop设置一个子类对应多个父类并指定跳转url的修改方法
- Kali Linux安装Remmina无法加载RDP插件
- 类与类关系的UML图与代码表现
- Restic 跨平台加密备份工具
- Spring JSF集成教程
- Eclipse的JavaWeb项目导入到IntelliJ IDEA 并且配置Tomcat
- C语言,期末复习之编写程序返回三个整数中的中间数
- c 语言 求文件大小,C程序中如何读取目录中的文件并判断文件大小等信息
- GitHub+jsDelivr+PicGo+Visual Studio Code 打造稳定、快速、高效、免费图床