ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

深度学习系列13:Transformer

2021-02-21 22:32:40  阅读:549  来源: 互联网

标签:输出 13 16 self attention Transformer Encoder 深度 256


数年前,encoder-decoder还是深度学习书籍里面一个非常不惹眼的章节,随着如今算力不断提高,已然要取代CNN一统天下了。

1. 基础

1.1 Embedding

首先需要用到embedding:从数学上来说其实是一种降维技术,把K维的0-1特征向量用k维的浮点数特征向量表示。直观代码如下:

from keras.models import Sequential
from keras.layers import Embedding
model = Sequential()
model.add(Embedding(100,2, input_length=7))#输入维,输出维
data = np.array([[0,2,0,1,1,0,0],[0,1,1,2,1,0,0],[0,1,12,1,15,0,1]])
model.predict(data)

100维数据被映射成2维数据.
图片同样可以做embedding,我们要把 N ∗ N ∗ 256 N*N*256 N∗N∗256(前两个是尺寸,最后是灰度)的图像用 N / 16 ∗ N / 16 ∗ 1000 N/16*N/16*1000 N/16∗N/16∗1000来表示,假设我们有M张图,则网络层的维度变化为:
[ M , N / 16 , N / 16 , 16 ∗ 16 ∗ 256 ] → [ M , N / 16 , N / 16 , 1000 ] → [ M , N / 16 , N / 16 , 16 ∗ 16 ∗ 256 ] [M,N/16,N/16,16*16*256]\to [M,N/16,N/16,1000] \to [M,N/16,N/16,16*16*256] [M,N/16,N/16,16∗16∗256]→[M,N/16,N/16,1000]→[M,N/16,N/16,16∗16∗256]
编码过程是 [ 16 ∗ 16 ∗ 256 , 1000 ] [16*16*256,1000] [16∗16∗256,1000]的矩阵,每一行的1000维数据就是每个块的embedding表示。在图像中,这个embedding可以作为像素块的特征向量。

1.2 Encoder-Decoder 结构

在这里插入图片描述
关于 Encoder-Decoder,有2点需要说明:
1)不论输入和输出的长度是什么,中间的「向量 c」 长度都是固定的(这也是它的缺陷,下文会详细说明)
根据不同的任务可以选择不同的编码器和解码器(可以是一个 RNN ,但通常是其变种 LSTM 或者 GRU )
2)只要是符合上面的框架,都可以统称为 Encoder-Decoder 模型。说到 Encoder-Decoder 模型就经常提到一个名词—— Seq2Seq。

Seq2Seq(是 Sequence-to-sequence 的缩写),就如字面意思,输入一个序列,输出另一个序列。这种结构最重要的地方在于输入序列和输出序列的长度是可变的。例如下图:
在这里插入图片描述
Seq2Seq(强调目的)不特指具体方法,满足「输入序列、输出序列」的目的,都可以统称为 Seq2Seq 模型。常见的应用有:机器翻译、对话机器人、诗词生成、代码补全、文章摘要(文本 - 文本)

1.3 Attention机制

Encoder-Decoder 当输入信息太长时,会丢失掉一些信息(在编码时进行了压缩,这是必然的)。Attention 机制就是为了解决「信息过长,信息丢失」的问题,简单来说,Attention 模型的特点是 Eecoder 不再将整个输入序列编码为固定长度的「中间向量 C」 ,而是编码成一个向量的序列。引入了 ttention 的 Encoder-Decoder 模型如下图:
在这里插入图片描述
其实结构上还是非常像RNN的。

1.4 Self-attention

self-attention是一种迭代优化词嵌入的方法。词嵌入学习的是单词之间的关系,而self-attention学习了单词在句子上下文环境中的关系(transformer中甚至还显式的加上了位置编码)。注意和Attention机制区分开。
换种方式说明:假设我们得到了一段输入文本,并且从文本中的单词嵌入 W 开始。我们需要找到一种 Embedding 方法来度量同一文本中其他单词嵌入相对于 W 的重要度,并合并它们的信息来创建更新的嵌入W’。
具体做法是:自注意力机制会将 Embedding 输入文本中的每个单词线性投影到三个不同的空间中(这些矩阵在训练过程中需要学习),从而产生三种新的表示形式:即查询query、键key和值value。这些新的嵌入将用于获得一个得分,该得分将代表 W 和每个Wn 之间的依赖性(如果 W 依赖于 W’,则结果为绝对值很高的正数,如果 W 与W’不相关,则结果为绝对值很高的负值)。这个分数将被用来组合来自不同 Wn 单词嵌入的信息,为单词 W 创建更新的嵌入W’。
在这里插入图片描述
用矩阵形式,直观表达如下:
在这里插入图片描述
在这里插入图片描述
注意到这些新向量的维度比输入词向量的维度要小(512–>64),并不是必须要小的,是为了让多头attention的计算更稳定。

下面是个例子:对“Thinking Matchines”这句话,对“Thinking”(pos#1)计算attention 分值。我们需要计算每个词与“Thinking”的评估分,这个分决定着编码“Thinking”时(某个固定位置时),每个输入词需要集中多少关注度。
这个分,通过“Thing”对应query-vector与所有词的key-vec依次做点积得到。所以当我们处理位置#1时,第一个分值是q1和k1的点积,第二个分值是q1和k2的点积。除以8,这样梯度会更稳定。然后加上softmax操作,归一化分值使得全为正数且加和为1。将softmax分值与value-vec按位相乘。保留关注词的value值,削弱非相关词的value值。将所有加权向量加和,产生该位置的self-attention的输出结果。
在这里插入图片描述

下图是一个self-attention的可视化例子:
在这里插入图片描述

2. Transformer

2.1 整体结构

Transformer中抛弃了传统的 CNN 和 RNN,整个网络结构完全由 Attention 机制组成,并且采用了 6 层 Encoder-Decoder 结构。
在这里插入图片描述
为了方便理解,我们只看其中一个Encoder-Decoder 结构。
Encoder部分由一个self-attention+前馈网络构成,Decoder部分中间多了一个Encoder-Decoder-attention层。
在这里插入图片描述

2.2 Embedding

(1) 将文字转换为固定维度的特征向量,即word2vec。
在这里插入图片描述

(2) 位置做encoding,最简单的可以是直接将绝对坐标 0,1,2 编码。这里使用的是Tranformer的sin-cos 规则:
在这里插入图片描述
下面是可视化的结果:
在这里插入图片描述

(3)每个编码器的都会接收到一个list(每个元素都是词向量),只不过其他编码器的输入是前个编码器的输出。list的尺寸是可以设置的超参,通常是训练集的最长句子的长度。

2.3 进入self-attention模块

transformer使用了多头机制,赋予attention多种子表达方式。简单来说,就是embedding中加入了更多的句子上下文信息。

像下面的例子所示,在多头下有多组query/key/value-matrix,而非仅仅一组(论文中使用8-heads)。每一组都是随机初始化,经过训练之后,输入向量可以被映射到不同的子表达空间中。
在这里插入图片描述
如果我们计算multi-headed self-attention的,分别有八组不同的Q/K/V matrix,我们得到八个不同的矩阵。
在这里插入图片描述
前向网络并不能接收八个矩阵,而是希望输入是一个矩阵,所以要有种方式处理下八个矩阵合并成一个矩阵。
在这里插入图片描述
现在加入attention heads之后,重新看下当编码“it”时,哪些attention head会被集中。
在这里插入图片描述

2.4 进入前馈模块

前馈网络比较简单,所有的向量都共享相同的权重。
在这里插入图片描述
编码器结构中值得提出注意的一个细节是,在每个子层中(self-attention, ffnn),都有残差连接,并且紧跟着layer-normalization(下图的虚线部分)。
在这里插入图片描述

2.5 进入解码器

最后的编码器的输出被转换为K和V,它俩被每个解码器的"encoder-decoder atttention"层来使用,帮助解码器集中于输入序列的合适位置。"Encoder-Decoder Attention "层工作方式跟multi-headed self-attention是一样的,除了一点,它从前层获取输出转成query矩阵,接收最后层编码器的key和value矩阵做key和value矩阵。

在解码器中的self attention 层与编码器中的稍有不同,在解码器中,self-attention 层仅仅允许关注早于当前输出的位置。在softmax之前,通过遮挡未来位置(将它们设置为-inf)来实现。
在这里插入图片描述
在这里插入图片描述

假设两层编码器+两层解码器组成Transformer,由于有残差结构,因此我们看到的设计如下:
在这里插入图片描述

2.6 输出结果

解码器最后输出浮点向量,如何将它转成词?这是最后的线性层和softmax层的主要工作。
线性层是个简单的全连接层,将解码器的最后输出映射到一个非常大的logits向量上。假设模型已知有1万个单词(输出的词表)从训练集中学习得到。那么,logits向量就有1万维,每个值表示是某个词的可能倾向值。
softmax层将这些分数转换成概率值(都是正值,且加和为1),最高值对应的维上的词就是这一步的输出单词。
在这里插入图片描述

2.7 损失函数

我们用一个简单的例子来示范训练,比如翻译“merci”为“thanks”。那意味着输出的概率分布指向单词“thanks”,但是由于模型未训练是随机初始化的,不太可能就是期望的输出。
在这里插入图片描述
如何对比两个概率分布呢?简单采用 cross-entropy或者Kullback-Leibler divergence中的一种。
鉴于这是个极其简单的例子,更真实的情况是,使用一个句子作为输入。比如,输入是“je suis étudiant”,期望输出是“i am a student”。
在这里插入图片描述
在足够大的训练集上训练足够时间之后,我们期望产生的概率分布如下所示:
在这里插入图片描述
现在,因为模型每步只产生一组输出,假设模型选择最高概率,扔掉其他的部分,这是种产生预测结果的方法,叫做greedy 解码。另外一种方法是beam search,每一步仅保留最头部高概率的两个输出,根据这俩输出再预测下一步,再保留头部高概率的两个输出,重复直到预测结束。top_beams是超参可试验调整。

2.8 完整示意图

在这里插入图片描述
多头的意义在于, Q K T QK^T QKT得到的矩阵就叫注意力矩阵,它可以表示每个字与其他字的相似程度。因为,向量的点积值越大,说明两个向量越接近。
在这里插入图片描述
我们的目的是,让每个字都含有当前这个句子中的所有字的信息,用注意力层,我们做到了。
需要注意的是,在上面

标签:输出,13,16,self,attention,Transformer,Encoder,深度,256
来源: https://blog.csdn.net/kittyzc/article/details/113866591

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有