Skip to content

Transformer架构

一、注意力机制

  • 前馈神经网络(Feedforward Neural Network,FNN),即数据从输入层单向流动到输出层,无循环结构,各层之间通过全连接或特定方式传递信息,其中多层感知机(Multi-Layer Perceptron,MLP)是最常见的形式,每一层的神经元都和上下两层的每一个神经元完全连接

    image.png

  • 卷积神经网络(Convolutional Neural Network,CNN),即训练参数量远小于全连接神经网络的卷积层来进行特征提取和学习

image.png

  • 循环神经网络(Recurrent Neural Network,RNN),能够使用历史信息作为输入、包含环和自重复的网络

image.png

由于 NLP 任务所需要处理的文本往往是序列,因此专用于处理序列、时序数据的 RNN 往往能够在 NLP 任务上取得最优的效果。事实上,在注意力机制横空出世之前,RNN 以及 RNN 的衍生架构 LSTM 是 NLP 领域当之无愧的霸主

但 RNN 及 LSTM 虽然具有捕捉时序信息、适合序列生成的优点,却有两个难以弥补的缺陷:

  1. 序列依序计算的模式能够很好地模拟时序信息,但限制了计算机并行计算的能力。由于序列需要依次输入、依序计算,图形处理器(Graphics Processing Unit,GPU)并行计算的能力受到了极大限制,导致 RNN 为基础架构的模型虽然参数量不算特别大,但计算时间成本却很高;
  2. RNN 难以捕捉长序列的相关关系。在 RNN 架构中,距离越远的输入之间的关系就越难被捕捉,同时 RNN 需要将整个序列读入内存依次计算,也限制了序列的长度。虽然 LSTM 中通过门机制对此进行了一定优化,但对于较远距离相关关系的捕捉,RNN 依旧是不如人意的。

针对这样的问题,Vaswani 等学者参考了在 CV 领域被提出、被经常融入到 RNN 中使用的注意力机制(Attention)(注意,虽然注意力机制在 NLP 被发扬光大,但其确实是在 CV 领域被提出的),创新性地搭建了完全由注意力机制构成的神经网络——Transformer,也就是大语言模型(Large Language Model,LLM)的鼻祖及核心架构,从而让注意力机制一跃成为深度学习最核心的架构之一。

注意力机制最先源于计算机视觉领域,其核心思想为当我们关注一张图片,我们往往无需看清楚全部内容而仅将注意力集中在重点部分即可。而在自然语言处理领域,我们往往也可以通过将重点注意力集中在一个或几个 token,从而取得更高效高质的计算效果。

注意力机制有三个核心变量:Query(查询值)、Key(键值)和 Value(真值)。我们可以通过一个案例来理解每一个变量所代表的含义。例如,当我们有一篇新闻报道,我们想要找到这个报道的时间,那么,我们的 Query 可以是类似于“时间”、“日期”一类的向量(为了便于理解,此处使用文本来表示,但其实际是稠密的向量),Key 和 Value 会是整个文本。通过对 Query 和 Key 进行运算我们可以得到一个权重,这个权重其实反映了从 Query 出发,对文本每一个 token 应该分布的注意力相对大小。通过把权重和 Value 进行运算,得到的最后结果就是从 Query 出发计算整个文本注意力得到的结果。

具体而言,注意力机制的特点是通过计算 Query 与Key的相关性为真值加权求和,从而拟合序列中每个词同其他词的相关关系

二、Encoder-Decoder

在《Attention is All You Need》一文中,作者通过仅使用注意力机制而抛弃传统的 RNN、CNN 架构搭建出 Transformer 模型,从而带来了 NLP 领域的大变革。在 Transformer 中,使用注意力机制的是其两个核心组件——Encoder(编码器)和 Decoder(解码器)。事实上,后续基于 Transformer 架构而来的预训练语言模型基本都是对 Encoder-Decoder 部分进行改进来构建新的模型架构,例如只使用 Encoder 的 BERT、只使用 Decoder 的 GPT 等。

Transformer 由 Encoder 和 Decoder 组成,每一个 Encoder(Decoder)又由 6个 Encoder(Decoder)Layer 组成。输入源序列会进入 Encoder 进行编码,到 Encoder Layer 的最顶层再将编码结果输出给 Decoder Layer 的每一层,通过 Decoder 解码后就可以得到输出目标序列了。

接下来,我们将首先介绍 Encoder 和 Decoder 内部传统神经网络的经典结构——前馈神经网络(FNN)、层归一化(Layer Norm)和残差连接(Residual Connection),然后进一步分析 Encoder 和 Decoder 的内部结构。

前馈神经网络

前馈神经网络(Feed Forward Neural Network,下简称 FNN),每一层的神经元都和上下两层的每一个神经元完全连接的网络结构。每一个 Encoder Layer 都包含一个上文讲的注意力机制和一个前馈神经网络。前馈神经网络的实现是较为简单的:

python
class MLP(nn.Module):
    '''前馈神经网络'''
    def __init__(self, dim: int, hidden_dim: int, dropout: float):
        super().__init__()
        # 定义第一层线性变换,从输入维度到隐藏维度
        self.w1 = nn.Linear(dim, hidden_dim, bias=False)
        # 定义第二层线性变换,从隐藏维度到输入维度
        self.w2 = nn.Linear(hidden_dim, dim, bias=False)
        # 定义dropout层,用于防止过拟合
        self.dropout = nn.Dropout(dropout)

    def forward(self, x):
        # 前向传播函数
        # 首先,输入x通过第一层线性变换和RELU激活函数
        # 最后,通过第二层线性变换和dropout层
        return self.dropout(self.w2(F.relu(self.w1(x))))

注意,Transformer 的前馈神经网络是由两个线性层中间加一个 RELU 激活函数组成的,以及前馈神经网络还加入了一个 Dropout 层来防止过拟合。Dropout 层只在训练时开启,推理/测试阶段关闭,所以许多Transformer结构示意图中不会画出该层。

层归一化

层归一化,也就是 Layer Norm,是深度学习中经典的归一化操作。神经网络主流的归一化一般有两种,批归一化(Batch Norm)和层归一化(Layer Norm)。

归一化核心是为了让不同层输入的取值范围或者分布能够比较一致。由于深度神经网络中每一层的输入都是上一层的输出,因此多层传递下,对网络中较高的层,之前的所有神经层的参数变化会导致其输入的分布发生较大的改变。也就是说,随着神经网络参数的更新,各层的输出分布是不相同的,且差异会随着网络深度的增大而增大。但是,需要预测的条件分布始终是相同的,从而也就造成了预测的误差。

因此,在深度神经网络中,往往需要归一化操作,将每一层的输入都归一化成标准正态分布。批归一化是指在一个 mini-batch 上进行归一化,相当于对一个 batch 对样本拆分出来一部分,首先计算样本的均值:

image.png

但是,批归一化存在一些缺陷,例如:

  • 当显存有限,mini-batch 较小时,Batch Norm 取的样本的均值和方差不能反映全局的统计分布信息,从而导致效果变差;
  • 对于在时间维度展开的 RNN,不同句子的同一分布大概率不同,所以 Batch Norm 的归一化会失去意义;
  • 在训练时,Batch Norm 需要保存每个 step 的统计信息(均值和方差)。在测试时,由于变长句子的特性,测试集可能出现比训练集更长的句子,所以对于后面位置的 step,是没有训练的统计量使用的;
  • 应用 Batch Norm,每个 step 都需要去保存和计算 batch 统计量,耗时又耗力

因此,出现了在深度神经网络中更常用、效果更好的层归一化(Layer Norm)。相较于 Batch Norm 在每一层统计所有样本的均值和方差,Layer Norm 在每个样本上计算其所有层的均值和方差,从而使每个样本的分布达到稳定。Layer Norm 的归一化方式其实和 Batch Norm 是完全一样的,只是统计统计量的维度不同。

残差连接

由于 Transformer 模型结构较复杂、层数较深,为了避免模型退化,Transformer 采用了残差连接的思想来连接每一个子层。残差连接,即下一层的输入不仅是上一层的输出,还包括上一层的输入。残差连接允许最底层信息直接传到最高层,让高层专注于残差的学习。

例如,在 Encoder 中,在第一个子层,输入会先进行层归一化(Layer Norm),然后进入多头自注意力层,其输出会与原输入相加。在第二个子层也是一样。即:

image.png

Encoder and Decoder

  • Encoder:Encoder 由 N 个 Encoder Layer 组成,每一个 Encoder Layer 包括一个注意力层和一个前馈神经网络。
  • Decoder:类似的,我们也可以先搭建 Decoder Layer,再将 N 个 Decoder Layer 组装为 Decoder。但是和 Encoder 不同的是,Decoder 由两个注意力层和一个前馈神经网络组成。第一个注意力层是一个掩码自注意力层,即使用 Mask 的注意力计算,保证每一个 token 只能使用该 token 之前的注意力分数;第二个注意力层是一个多头注意力层,该层将使用第一个注意力层的输出作为 query,使用 Encoder 的输出作为 key 和 value,来计算注意力分数。最后,再经过前馈神经网络

最后更新于: