深度学习系列26:transformer机制

1. 多头注意力机制

首先补充一下注意力和自注意力区别:自注意力有3个矩阵KQV;而注意力只有KV,可以理解为最终结果被用来当做Q了。
深度学习系列26:transformer机制_第1张图片
多头注意力机制在自注意力机制上又加了一层多头的概念,即图中从多个不同角度做attention(用不同的方式初始化即可),然后按列拼接起来。一般需要把v/k/q维度也降下来, d ′ = d / h d'=d/h d=d/h,这样拼接起来后和原来的维度相同。

2. transformer机制

2.1 整体结构

Transformer中抛弃了传统的 CNN 和 RNN,整个网络结构完全由 Attention 机制组成,并且采用了 6 层 Encoder-Decoder 结构。
深度学习系列26:transformer机制_第2张图片
为了方便理解,我们只看其中一个Encoder-Decoder 结构。
Encoder部分由一个self-attention+前馈网络构成,Decoder部分中间多了一个Encoder-Decoder-attention层。
深度学习系列26:transformer机制_第3张图片

2.2 Embedding

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

(2) 加入位置encoding,最简单的可以是直接将绝对坐标 0,1,2 编码。这里使用的是Tranformer的sin-cos 规则:
深度学习系列26:transformer机制_第4张图片
下面是可视化的结果:
深度学习系列26:transformer机制_第5张图片

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

2.3 进入self-attention模块

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

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

2.4 进入前馈模块

前馈网络比较简单,所有的向量都共享相同的权重。
深度学习系列26:transformer机制_第10张图片
编码器结构中值得提出注意的一个细节是,在每个子层中(self-attention, ffnn),都有残差连接,并且紧跟着layer-normalization(下图的虚线部分)。
深度学习系列26:transformer机制_第11张图片

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)来实现。
深度学习系列26:transformer机制_第12张图片
深度学习系列26:transformer机制_第13张图片

假设两层编码器+两层解码器组成Transformer,由于有残差结构,因此我们看到的设计如下:
深度学习系列26:transformer机制_第14张图片

2.6 输出结果

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

2.7 损失函数

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

2.8 完整示意图

深度学习系列26:transformer机制_第19张图片
多头的意义在于, Q K T QK^T QKT得到的矩阵就叫注意力矩阵,它可以表示每个字与其他字的相似程度。因为,向量的点积值越大,说明两个向量越接近。

我们的目的是,让每个字都含有当前这个句子中的所有字的信息,用注意力层,我们做到了。
需要注意的是,在上面 的计算过程中,我们通常使用 ℎ,也就是一次计算多句话,上文举例只用了一个句子。
每个句子的长度是不一样的,需要按照最长的句子的长度统一处理。对于短的句子,进行 Padding 操作,一般我们用 0 来进行填充。

最后加入了残差设计和层归一化操作,目的是为了防止梯度消失,加快收敛。

  1. 残差设计:我们在上一步得到了经过注意力矩阵加权之后的 , 也就是 (, , ),我们对它进行一下转置,使其和 的维度一致, 也就是 [ℎ , ℎ, ] ,然后把他们加起来做残差连接,直接进行元素相加,因为他们的维度一致。在之后的运算里,每经过一个模块的运算,都要把运算之前的值和运算之后的值相加,从而得到残差连接,训练的时候可以使梯度直接走捷径反传到最初始层。
  2. 层归一化
    作用是把神经网络中隐藏层归一为标准正态分布,也就是 .. 独立同分布, 以起到加快训练速度, 加速收敛的作用。
    之后引入两个可训练参数 α , β \alpha,\beta α,β来弥补归一化的过程中损失掉的信息,注意表示元素相乘而不是点积。
    最后加入两层线性映射并用激活函数激活。

你可能感兴趣的:(深度学习系列,transformer,深度学习,自然语言处理)