Seq2Seq(Sequence To Sequence)
Seq2seq 由Google首次引入机器翻译。在此之前,翻译工作非常幼稚。您以前键入的每个单词都被转换为其目标语言,而不考虑其语法和句子结构。Seq2seq通过深度学习彻底改变了翻译过程。它不仅在翻译时考虑了当前单词/输入,还考虑了其邻域。
如今,它可用于各种不同的应用程序,例如图像字幕,会话模型,文本摘要等。
Seq2seq工作:
- Seq2Seq将一系列单词(句子或句子)作为输入,并生成一个输出单词序列。它通过使用递归神经网络(RNN)来实现。尽管很少使用RNN的原始版本,但使用了更高级的版本,即LSTM或GRU。这是因为RNN存在梯度消失的问题。Google提出的版本使用LSTM。它通过在每个时间点进行两次输入来发展单词的上下文。一个来自用户,另一个来自其先前的输出,因此名称为recurrent(输出作为输入)。
- Seq2Seq是用于序列预测任务(例如语言建模和机器翻译)的模型。这个想法是使用一个LSTM编码器一次一次读取输入序列,以获得较大的固定维矢量表示(上下文矢量),然后使用另一个LSTM解码器提取输出。该向量的序列。第二个LSTM本质上是递归神经网络语言模型,除了它以输入序列为条件。
它主要有两个部分,即编码器和解码器,因此有时被称为编码器-解码器网络。
编码器: 它使用深层神经网络层并将输入的单词转换为相应的隐藏向量。每个向量代表当前单词和该单词的上下文。
解码器: 类似于编码器。它以编码器生成的隐藏矢量,其自身的隐藏状态和当前单词作为输入,以生成下一个隐藏矢量并最终预测下一个单词。
除了这两个之外,还有其他优化引导seq2seq的组件:
Attention:解码器的输入是单个向量,必须存储有关上下文的所有信息。这对于大序列来说是一个问题。因此,应用了attention机制,其允许解码器选择性地查看输入序列。
Beam Search:解码器选择最高概率词作为输出。但是,由于贪婪算法的基本问题,这并不总是能产生最佳结果。因此,应用Beam Search,建议在每个步骤可能进行平移。这样就形成了具有最高k个结果的树。
Buckting: seq2seq模型中的可变长度序列是可能的,因为对输入和输出都进行了0填充。但是,如果我们设置的最大长度为100,而句子的长度仅为3个字,则会浪费大量空间。因此,我们使用Bucking的概念。我们制作不同大小的存储桶,例如(4,8)(8,15),依此类推,其中4是我们定义的最大输入长度,而8是定义的最大输出长度。
Attention
Self-attention机制:
Attention机制允许输出将注意力集中在输入上,同时产生输出,而Self-attention模型则允许输入彼此交互(即,计算一个输入对所有其他输入的关注)。
- 第一步是将每个编码器输入向量与我们在训练过程中训练的三个权重矩阵相乘。这个矩阵乘法将为我们每个输入向量提供三个向量:关键(key)向量,查询(query)向量和值(value)向量。
- 第二步是将当前输入的查询向量与其他输入的关键向量相乘。
- 在第三步中,我们将分数除以关键向量的尺寸的平方根。其背后的原因是,如果点积变大,那么在将来应用softmax函数后,这会使一些Self-attention得分变得很小。
- 在第四步中,我们将对查询词(此处为第一个词)计算出的所有Self-attention得分应用softmax函数。
- 在第五步中,将值向量乘以上一步中计算出的向量。
- 在最后一步中,我们总结了在上一步中获得的加权值向量,这将为给定单词提供Self-attention输出。
以上过程适用于所有输入序列。数学上,输入矩阵的自注意矩阵的计算公式为:
Multi-headed-attention:
以下是计算Multi-headed-attention机制的分步过程:
- 接受输入句子的每个单词,并从中生成嵌入词。
- 在这种机制中,创建了h个不同的attention heads,每个头具有不同的权重矩阵。
- 在此步骤中,将输入矩阵与每个权重矩阵相乘,以生成每个attention head的键(key),值(value)和查询(query)矩阵。
- 现在,我们将attention机制应用于这些key,value和query矩阵,从而为我们提供了来自每个attention head的输出矩阵。
- 在这一步中,我们将从权重为的每个attention head和点积获得的输出矩阵连接起来,以生成multi-headed attention层的输出。
数学上的Multi-headed-attention可以表示为:
Attention in Transformer architecture
–Transformer 架构使用attention模型在三个步骤中使用multi-headed attention:
第一个是编码器-解码器 attention层,在这种类型的层中,查询来自上一个解码器层,而键和值来自编码器输出。这允许解码器中的每个位置都注意输入序列的所有位置。
-
第二种类型是编码器中包含的self-attention层,该层从先前的编码器层的输出中接收键,值和查询输入。编码器中的每个位置都可以从上一个编码器层中的每个位置获取attention得分。
-
第三种是解码器中的self-attention ,这类似于编码器中的所有内容,所有查询,键和值都来自上一层的self-attention。self-attention解码器允许每个位置参加直到并包括该位置的每个位置。将来的值用(-Inf)掩盖。这就是所谓的“self-attention”。
复杂性
在NLP任务中使用self-attention层的优势在于,与其他操作相比,执行该过程的计算成本较低。下表是表示不同操作的复杂性的表:
FLOPs | |
---|---|
Self-Attention | O() |
RNN(LSTM) | O() |
Convolution | O() |
Transformer
transformer的基本组成部分是self-attention。首先,我们需要克服顺序处理,重复性和LSTM!只需更改输入表示形式即可!
集合和标记化
transformer 革命始于一个简单的问题:为什么不输入整个输入序列?隐藏状态之间没有依赖性!
例如,句子“hello,I love you”:
这个处理步骤通常称为标记化,这是在我们将输入输入模型之前的三个步骤中的第一步。
因此,我们现在有了一组元素,而不是元素序列。
集合是不同的元素,其中集合中元素的排列并集合不是无所谓。
换句话说,顺序无关紧要。我们将输入集表示为, 其中 。序列的元素被称为标记。
标记化后,我们将词投影到一个分布的几何空间中,或简单地构建词嵌入
词嵌入
通常,嵌入是连续值向量的分布低维空间中符号(词,字符,句子)的表示。
词不是离散符号。它们彼此之间密切相关。这就是为什么当我们在连续的欧几里德空间中投影它们时,我们可以找到它们之间的关联。
然后,根据任务,我们可以将词嵌入推得更远或保持在一起。
理想情况下,嵌入是通过将语义相似的输入并排放置在嵌入空间中来捕获输入的语义。
在自然语言中,我们可以找到相似的词义甚至相似的句法结构(即,对象聚在一起)。无论如何,当您将它们投影到2D或3D空间中时,都可以直观地识别出某些群集。如下图3D效果图
位置编码
将序列转换为集合(标记化)时,会失去顺序的概念。您是否可以从以下顺序中找到单词(标记)的顺序:“hello,I love you”?类似简短点可以!但是30个无序单词呢?
机器学习与规模有关。神经网络当然不能理解集合中的任何顺序。
由于transformer将序列作为一组处理,因此从理论上讲它们是置换不变的。
让我们通过根据位置稍微更改嵌入来帮助他们有秩序感。位置编码是一组小的常量,这些常量会在第一个self-attention层之前添加到词嵌入向量中。
因此,如果同一单词出现在不同的位置,则实际表示将略有不同,具体取决于它在输入句子中出现的位置。
在变压器论文中,作者提出了用于位置编码的正弦函数。正弦函数告诉模型要注意特定的波长 ,给定信号 波长将是 。在我们的情况下 将取决于句子中的位置。 用于区分奇数和偶数位置。
数学上:
作为记录, ,这是嵌入向量的维数。
高维空间中的向量相似度
在几何中,内部矢量积被解释为矢量投影。定义矢量相似度的一种方法是通过计算归一化内积。在低维空间中,如下面的2D示例,这将对应于余弦值。
数学公式:
我们可以通过计算缩放的点积(即角度的余弦)来关联表示任何事物(即动物)的向量之间的相似性。
在transformer中,这是最基本的操作,由我们前面提到的self-attention层处理。接下来我们进一步对self-attention做补充学习。
self-attention
自我注意,有时也称为内部注意,是一种与单个序列的不同位置相关联的注意力机制,目的是计算序列的表示形式。
self-attention使我们能够找到表示句子的句法和上下文结构的输入的不同单词之间的相关性。
让我们以输入序列“hello,I love you”为例。经过训练的self-attention层会将“love”一词与“I”和“you”一词联系起来,其权重要高于“hello”一词。从语言学的角度来看,我们知道这些单词共享主语-动词-宾语的关系,这是一种理解self-attention的直观方法。
实际上,Transformer使用3种不同的表示形式:嵌入矩阵的query,key和value。这可以很容易地通过乘以我们的输入来完成 3种不同的重量矩阵 , 和 。本质上,它只是初始词嵌入中的矩阵乘法。
有了query,vakue和key矩阵,我们现在可以将self-attention层应用为:
只是作为比例因子,以确保矢量不会爆炸。
我们已经区分了按键从值作为不同的表示形式。因此,最终的表示是self-attention矩阵乘以值矩阵。
首先,我们有矩阵而不是向量,结果是矩阵乘法。其次,我们不按向量大小按比例缩小,而是按矩阵大小按比例缩小,(即句子中的词数!句子大小各不相同:)
接下来要做规范化和短跳转连接,类似于在卷积或递归后处理张量
残留短跳转连接
在语言中,有一个重要的概念是对世界和我们将思想结合起来的能力有更广泛的了解。人类广泛利用这些自上而下的影响(我们的期望)来组合不同上下文中的单词。跳过连接以一种非常粗糙的方式赋予了Transformer很小的能力,使不同级别的处理表示形式可以交互。
通过形成多条路径,我们可以将对最后一层的高级理解“传递”到先前的层。这使我们能够重新调整我们对输入的理解。同样,这是与人类自上而下的理解相同的想法,无非是期望。
规范化层
在规范化层(Layer Norm-LN)中,均值和方差是在通道和空间暗淡之间计算的。在语言中,每个单词都是一个向量。由于我们要处理向量,因此我们只有一个空间维度。
在具有合并空间尺寸的4D张量中,我们可以使用下图将其可视化:
在应用规范化层并形成残余跳转连接之后:
即使这可能是一个独立的构建块,该Transformer的创建者也会在顶部添加另一个线性层,并将其与另一个跳转连接一起重新规范化
线性层
是矩阵,
这是具有N个此类构造块的Transformer的编码器部分,如下所示:
实际上,这几乎是Transformer的编码器。有一个区别:multi-head attention
Multi-head attention 和 并行应用
我们将key,query,value矩阵的独立集合映射到不同的较低维空间中,并在那里计算attention(输出称为“head”)。通过将每个矩阵与单独的权重矩阵相乘来实现映射,表示为和
为了补偿额外的复杂性,将输出矢量大小除以head数量。具体来说,在香草变压器中,他们使用 和 头,这给了我们64的矢量表示。现在,该模型具有多个独立的路径(方式)来理解输入。
然后使用平方权重矩阵将这些头连接起来并进行变换,因为 放在一起,我们得到:
然后
由于head是彼此独立的,因此我们可以在不同的worker上并行执行self-attention计算:
multi-head attetion背后的直觉是,它使我们每次都可以不同地关注序列的不同部分。这实际上意味着:
- 该模型可以更好地捕获位置信息,因为每个head都将参与输入的不同部分。它们的组合将为我们提供更强大的表示。
- 通过以独特的方式关联单词,每个head也将捕获不同的上下文信息。
multi-head attention使模型可以共同关注来自不同位置的不同表示子空间的信息。简单的attention head,取平均值可以抑制这种情况
我们将在以下图表中描述multi-head self-attention:
总结:Transformer编码器
要处理一个句子,我们需要以下三个步骤:
输入句子的词嵌入是同时计算的。
然后,将位置编码应用于每个嵌入,从而生成词矢量,该词矢量还包含位置信息。
词向量被传递到第一编码器块。
每个块均由以下几层按相同顺序组成:
-
- multi-head self-attention,用于查找每个单词之间的相关性
-
- 规范化层
-
- 前两个子层周围的残余跳转连接
-
- 线性层
-
- 第二规范化层
-
- 第二个残余跳转连接
上述块可以复制多次以形成编码器。在这里中,编码器由6个相同的块组成。
Transformer 解码器
解码器包括所有上述组件以及两个新颖的组件。像之前一样:
- 输出序列将全部输入,并计算单词嵌入
- 再次应用位置编码
- 并将向量传递到第一个解码器块
每个解码器块包括:
- Masked multi-head self-attention层
- 紧随残差连接规范化层
- 新的multi-head self-attention(Encoder-Decoder attention)
- 第二次规划层和残差连接
- 线性层和第三次残差连接
解码器块再次出现6次。最终输出通过最终线性层进行转换,并使用标准softmax函数计算输出概率
输出概率预测输出语句中的下一个标记。本质上,我们为法语中的每个单词分配一个概率,我们只保留得分最高的单词。
Masked Multi-head attention
果您尚未意识到,在解码阶段,我们会预测一个单词(标记)一个接一个。在诸如机器翻译之类的NLP问题中,顺序标记预测是不可避免的。结果,需要修改self-attention层,以便仅考虑到目前为止已生成的输出语句。
在我们的翻译示例中,解码器在第三遍的输入将为“ Bonjour”,“ je”…………”。
如您所知,这里的区别在于我们不知道整个句子,因为它还没有产生出来。这就是为什么我们需要忽略未知词。否则,模型将只复制下一个单词!为此,我们屏蔽了下一个单词嵌入(将它们设置为-inf)。
数学上,我们有:
其中矩阵M是由0和-inf组成
零将成为指数的-,而无穷变成0
这实际上具有与删除相应连接相同的效果。其余原理与编码器的注意完全相同。再一次,我们可以并行实现它们以加快计算速度。
显然,为了我们计算的每个新标记,每一个mask都会更改。
编码器-解码器 attention
实际上,这是解码器处理编码表示的地方。编码器生成的attention矩阵将与先前的Masked Multi-head attention块的结果一起传递到另一个attention层。
编码器-解码器注意层背后的直觉是将输入和输出语句组合在一起。编码器的输出封装了输入语句的最终嵌入。就像我们的数据库。因此,我们将使用编码器输出来生成Key和Value矩阵。另一方面,Masked Multi-head attention块的输出包含到目前为止生成的新句子,并在attention层中表示为Query矩阵。同样,它是数据库中的“搜索”。
训练编码器-解码器attention以将输入句子与相应的输出词相关联
最终将确定每个英语单词与法语单词的关联程度。这基本上就是英语和法语之间发生映射的地方。
注意,编码器最后一个块的输出将在每个解码器块中使用
Transformer优势
-
- 每个块的分布式和独立表示:每个transformer块都有情境化表示。可以将其视为卷积层的多个特征图,这些特征图可捕获图像中的不同特征。卷积的不同之处在于,这里我们对其他空间有多个视图(线性重投影)。当然,这可以通过最初将单词表示为欧式空间中的向量(而不是离散符号)来实现。
-
- 含义在很大程度上取决于上下文:这正是self-attention的全部内容!我们将attention权重表示的单词表示之间的关系关联起来。因为我们自然会让模型建立全局关联,所以没有局部性的概念。
-
- 多个编码器和解码器块:模型具有更多层,可以进行更多抽象表示。类似于堆叠递归或卷积块,我们可以堆叠多个transformer块。第一个块将字向量对,双双第二个对,三双第三个对等相关联,依此类推。平行地,multi-head专注于该对的不同段。这类似于接受域,但是在成对的分布式表示方面。
-
- 高级别和低级别信息的组合:当然,还有跳转连接!它们使自上而下的理解能够与向后流动的多个梯度路径一起向后流动。
参考
Sequence to Sequence papaerswithcode web
seq2seq model in Machine Learning
Seq2Seq code-github_1
Seq2Seq code-github_2
Self -attention in NLP
How Transformers work in deep learning and NLP: an intuitive introduction