【Transformer】三、Transformer原论文的背景与核心创新

前言

《Attention is All You Need》论文地址:https://arxiv.org/abs/1706.03762

通过前面的两篇文章,我们知道《Attention is All You Need》的两个核心创新点是: Transformer 架构Self-Attention自注意力机制

那么为什么这两个创新会带来革命性的突破呢?换句话说,在2017年这篇论文出现之前,为什么没有迎来大语言模型时代?

为了搞清楚这个问题,我们就需要知道以往的一些模型结构是什么样的,它们都存在着什么样的瓶颈。从而进一步的理解Transformer做了哪些创新,解决了什么样的难点,以及为什么Transformer能突破这些瓶颈或者限制。

在Transformer论文的摘要中出现了一个词,序列转导模型(Sequence Transduction Model),那么什么是序列转导模型(Sequence Transduction Model)呢?我们就以它入手吧。

一、序列转导模型(Sequence Transduction Model)

序列转导模型(Sequence Transduction Model)是处理序列数据的模型

  • 序列数据:具有顺序关系的数据,每个元素的顺序对于数据的整体含义非常重要
  • 典型的序列转导模型
    • 文本翻译:翻译前的文本(“How are you”) -> 翻译后的文本(“你好吗?”);
    • 文本生成:用户的输入文本(“How are you?”) -> AI生成的回复文本(“I’m fine, thank you.”);
    • 语音转文字:一个音频片段 —> 音频的文字转写;

Transformer出现之前,这些序列转导模型,主要是复杂的卷积神经网络(CNN)和循环神经网络(RNN)。由此,我们知道主流序列转导模型的结构发展如下:

Transformer之前

  1. 基于RNN/CNN
  2. 使用编码器-解码器结构
  3. 使用注意力机制增强

Transformer结构的创新:

  1. 完全摒弃RNN/CNN
  2. (仍然使用编码器-解码器构)
  3. 完全基于注意力机制

为了更好的理解Transformer,让我们先来看一些以往的模型结构以及他们的不足吧。

1.1 前馈神经网络 Feedforward Neural Network(FNN)

在这里插入图片描述
在学习深度学习的时候,FNN是大家接触到的最基本的神经网络,X为输入,Y为输出,W和V分别为对应层的权重矩阵,具体细节这里不过多说明了,主要想探讨一下为什么FNN就不适合做序列转导任务呢?

让我们看一个例子:

输入:水是有毒的

步骤一:分词(Tokenization)
[“水”, “是”, “有毒”, “的”]

步骤二:词向量表示(Embedding)

“水” → [0.2, -0.1, 0.3, 0.0]

“是” → [0.0, 0.5, -0.2, 0.1]

“有毒” → [0.9, -0.3, 0.4, 0.2]

“的” → [0.1, 0.0, 0.0, 0.1]

步骤三:合并词向量(平均或拼接)

  • 平均:将上面四个向量对应位置相加后取平均值,最有得到一个新的1*4的向量,这种方式完全丢掉了词语的顺序

  • 拼接:将上面四个向量收尾相连,变为一个1 * 16的向量。

    • FNN 需要固定维度的输入,对不同长度的句子处理效率低下,比如上图中的FNN接受的收入是x1~x4一个四位的向量,而现在我们是一个1*16的向量,它是处理不了的,除非我们将FNN的输入变为16维或更高维度(大于16的位置补0),但这样的处理方式,如果想要应对非常长的句子,我们就得事先将FNN的属于定义的维度非常高,但是平时更常见的场景是处理短句,后面补很多0,处理效率低下。
    • 仍然会将句子视作一个整体来处理,无法理解真正的“谁先谁后”的关系

1.2 循环神经网络 Recurrent Neural Network (RNN)

由于前馈神经神经网络FNN在处理时序转导模型时,存在以上的一些不足,因此后续诞生了循环神经网络 Recurrent Neural Network (RNN) 。

首先我们看一下RNN解决了什么问题:

  1. 能够建模词序:RNN 是按时间顺序(token 顺序)逐个处理输入的;
  2. 能够建模上下文依赖:RNN 是逐个喂入词语,并且会有“记忆”机制;
  3. 支持不定长输入:不再需要 FNN 那种固定长度的输入格式,句子多长都行;

RNN相对CNN在处理时序信息时有以上三个优势,那RNN是如何达到以上效果的呢?

在这里插入图片描述
可以看到RNN其实也并不复杂,不过是在FNN的基础上加了h位置的一个圈(循环)。

  • 输入 X X X不再表示为 x n x_n xn,而是表示为 x t x_t xt,因为RNN的输入是时序的,每次输入一个时序值,

  • x t x_t xt: t时间步的输入

  • h t h_t ht: t时间步的状态, h t = g ( W x t + U h t − 1 ) h_t = g(Wx_t + Uh_{t-1}) ht=g(Wxt+Uht1)

  • y t y_t yt: t时间步的输出(也可能没有) y t = g ( V ∗ h t ) y_t = g(V*h_t) yt=g(Vht)

  • U , V , W U, V, W U,V,W: 权重矩阵

  • h t h_t ht中的 g g g激活函数,如 R e L U , s i g m o i d ReLU,sigmoid ReLUsigmoid,用于引入非线性,增强表达能力;同时限制数值范围,避免梯度爆炸/消失

  • y t y_t yt中的 g g g:视任务而定,比如如果是分类问题,可能是 s o f t m a x softmax softmax 函数,用于把输出转成概率分布。

对于“我爱水课”这句话,【我】将作为第一个token,即 x 1 x_1 x1进行输入,处理完成后,【爱】作为第二个token进行输入,这便是时序输入。让我们将其过程进行展开:
在这里插入图片描述
h 0 h_0 h0是我们初始化的参数, x 1 x_1 x1 t 1 t_1 t1时刻的输入:【我】,进行运算后得到了第一个输出 y 1 y_1 y1,而中间状态 h 1 h_1 h1,将参与下一个时刻的输入计算,即:
h 1 = g ( W ∗ x 1 + U ∗ h 0 ) y 1 = g ( V ∗ h 1 ) h 2 = g ( W ∗ x 2 + U ∗ h 1 ) y 2 = g ( V ∗ h 2 ) . . . h_1 = g(W * x_1+ U *h_0) \\ y_1 = g(V*h_1) \\ h_2 = g(W * x_2+ U *h_1) \\ y_2 = g(V*h_2) \\ ... h1=g(Wx1+Uh0)y1=g(Vh1)h2=g(Wx2+Uh1)y2=g(Vh2)...

从上图以及公式可以看到一下信息:

  • 对于一个时刻的输入会有两个输出,一个是 y t y_t yt,对于时刻 t t t输入的输出,一个是 h t h_t ht,是对于 t t t时刻输入的中间态,会参与后续时刻的计算。
  • h 1 h_1 h1不仅参与了 y 1 y_1 y1的计算,也参与了 h 2 h_2 h2的计算,也就是前一个时刻计算的中间状态会参与下一个时刻的计算,正式由于这个依赖,后续时刻的输入因为依赖了前置时刻输入的中间态 h t h_t ht从而导致了无法并行计算
  • 为什么 W , U , V W,U,V WUV矩阵在上面公式中不用表示为 W t , U t , V t W_t,U_t,V_t Wt,Ut,Vt,比如 W 1 , W 2 W_1,W_2 W1,W2等,因为上图是将多个时序计算进行了展开方便理解,从而让我们以为有多个 W , U , V W,U,V WUV的错觉,但实际上对于每一个时序的计算,W,U,V矩阵都是一模一样的,就是在循环针对每个时序输入进行计算,所以不用带下标区分。

至此,我们知道了RNN可以解决FNN在处理时序任务时的一些瓶颈问题(能记住输入的顺序,后续输入能知道前置时刻输入的上下文)

但是RNN也有自身的一些局限性

  • 输入输出不等长时怎么办?
  • 无法并行计算,训练效率低

1.3 编码器 - 解码器结构 Encoder and Decoder

可以简单的理解下图:将RNN的上半部分和下半部分分开做

  • Encoder : RNN的下半部分,将所有时序输入进行编码,计算出最后一个中间状态 h 4 h_4 h4,也就是上下文C,他包含了整个时序输入的上下文信息。
  • Decoder: RNN的上半部分, 对上下文C进行解码输出操作,注意:前一个输出(如下图I)以及前一个输出的中间态(如下图S1),都会作为下一个时序的输入参与计算。下图中的S0就是C,即C作为了解码器的原始输入。
    在这里插入图片描述

编码器的输出C:上下文向量(context vector)

  • 它是对整个输入序列的语义编码,是一个固定长度的向量,涵盖了整个输入文本的语义信息,同时也隐式的包含了输入序列的顺序(位置)信息,因为是一个一个时序输入循环计算得来的C,输入时序不一样,得到的C会不一样的。
  • 最简单的编码方式:C = 最后一个时间步的隐藏状态输出(h4)
  • 它将作为 Decoder 的输入,用于生成目标序列。

由于解码到靠后为止的时候,相关信息可能已经被稀释的差不多了,会丢失一些较早信息的特征情况,所以我们又想到了一种方式,给每一个解码器的时间步再输入一次上下文C,如下图:

在这里插入图片描述
但是这种方式也有缺陷:所有时间步的输入在计算当前时刻输出时被同等对待,忽略了不同时间步对当前时刻输出的重要性可能存在的差异。由此引出了注意力机制。

1.4 传统注意力机制

注意力机制解决的问题:

  1. 解决模型处理长序列时的“遗忘”问题:随着序列长度的增长,远距离依赖信息在传递过程中易被稀释,导致模型对长距离依赖关系的建模能力减弱。

  2. 解决不同时间步输入对当前时刻输出的“重要性”问题:所有时间步的输入在计算当前时刻输出时被同等对待,忽略了不同时间步对当前时刻输出的重要性可能存在的差异。

比如下图,我们将上下文C又作为了解码器每个时序解码时的一个输入,而我们知道C是 h 4 h_4 h4 h 4 h_4 h4计算的时候肯定是受离它进的一些时序输入token比较大(如 x 3 x_3 x3),而离它更远的token因为进行了多层的计算和稀释,可能已经被稀释的差不多了。

在这里插入图片描述

那么我们希望解码器的每个时间步可以关注到上下文C中不同的重点,因此这个C对于解码器的每个时间步不能再是相同的了。

此时就因为了基础的注意力机制(注意这个和Transformer中的自注意力机制Q,K,V含义是不同的,不过他们两者的思想是一致的,期望当前token可以关注到上下文中的不同重点

传统注意力机制基本都是与RNN一起使用,将RNN的时序输入对应的输出进行加权求和得到新的输出,步骤如下

  • 一个输入序列,记为 X X X,它由 t t t个元素组成( t t t个时序输入),分别表示为 x ( 1 ) x^{(1)} x(1) x ( t ) x^{(t)} x(t)

  • 注意力分数 w w w=词元 x ( n ) x^{(n)} x(n)与其他词元的点积而得;点积值越大则这两个词元相似度越高(即对齐度越高)

  • 嵌入化词元序列之间的注意力权重 α α α= 注意力分数 w w w的归一化

  • 注意力分数归一化 s o f t m a x softmax softmax后得到每一个词元的注意力权重 α α α,即获得总和为1的注意力权重

  • 最后上下文向量 Z ( n ) = S u m Z(n)=Sum Z(n)=Sum(所有 x ( i ) x^{(i)} x(i)的注意力权重 α α α * 嵌入化词元本身的矩阵),即注意力权重和词元嵌入矩阵相乘后,再求和。

  • 位移词元下标 i i i,循环以上步骤,将所有词元的注意力权重都计算出来。

图中是列举 i = 2 i=2 i=2的此词元注意力上下文向量。

  1. 注意力分数 w = 词元 x ( 2 ) w=词元x^{(2)} w=词元x(2)与其他词元(包括自身)的点积而得,(两个向量点击得到一个数值标量,所以这里与每个词元点积将得到t个标量,可以组成一个维度为t的向量);点积值越大则这两个词元相似度越高(即对齐度越高)
  2. 注意力权重 α = 注意力分数 w 的归一化 注意力权重 α= 注意力分数w的归一化 注意力权重α=注意力分数w的归一化,第一步中的 t t t 维向量经过 s o f t m a x softmax softmax归一化,得到每个词元对于词元 x ( 2 ) x^{(2)} x(2)的注意力权重 a 21 , a 22 , . . . . a 2 t a_{21},a_{22},....a_{2t} a21,a22,....a2t(他们的和为1)
  3. 最后上下文向量 Z ( 2 ) = x ( 1 ) ∗ a 21 + x ( 2 ) ∗ a 22 + . . . + x ( t ) ∗ a 2 t Z(2)= x^{(1)}*a_{21} + x^{(2)}*a_{22} + ... + x^(t) *a_{2t} Z(2)=x(1)a21+x(2)a22+...+x(t)a2t
    在这里插入图片描述

上面仅以 C 2 C_2 C2进行了举例,实际通过以上步骤,我们就可以得到所有的 C i C_i Ci,从而解码器将变为如下形式,每个解码时间步不再关注同一个整体上下文 C C C,而是关注注意力算出来的 C i C_i Ci
在这里插入图片描述

到此为止,我们解决了容易遗忘远距离时候输入的问题,那么还有什么问题没有解决呢?

  • 并行计算能力:RNN 的时序依赖特性导致无法充分利用 GPU 并行能力(即RNN模型中,一句话的每个词是按时间顺序输入的,前一个词计算完之后,将其隐藏状态继续和下一个输入的词计算,如此循环,因此得名循环神经网络,而Transformer是一次性输入的一句话),Transformer 的并行处理能力使其能够高效利用现代硬件资源。

在进入Transformer前,我们先来小结一下:

RNN

  • 能够建模词序(因为是时序输入)
  • 能够建模上下文依赖(前面时序的隐藏状态会作为后面时序输入的一部分)
  • 支持不定长输入(因为是时序输入)

编码器-解码器

  • 支持输入输出不等长(编码器将所有输入信息编码为一个上下文向量,解码器对齐进行解码输出)

注意力机制

  • 解决处理长序列时的“遗忘”问题
  • 解决不同时间步输入对当前时刻输出的“重要性”问题

Transformer

  • 解决串行化计算问题

二、Transformer

Transformer 的自注意力机制是“全局互相关注”,完全摆脱了序列结构,支持并行,是最底层的范式改变。

【Transformer】二、Transformer架构原理通识

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值