Skip to content

深度神经网络

DNN

深度神经网络(Deep Neural Network, DNN)是一个广义的伞状术语(Broad Term),一般来说,任何满足以下两个条件的人工神经网络都可以被称为DNN:

  • 由多个相互连接的节点(人工神经元)组成
  • 有多个隐藏层,故而有“深度”

常见的深度神经网络包括:(按照时间顺序)

  • MLP/DFF,深度前馈网络,第一个最为重要的神经网络模型
  • RNN,循环神经网络,早期的序列建模尝试
  • CNN,卷积神经网络,图像识别领域的巨大突破
  • LSTM,长短时记忆网络,成熟的序列建模(RNN升级版)
  • GAN,生成对抗网络,开启了AI生成的时代
  • Transformer,用自注意力机制开启了大模型时代
  • MoE,混合专家模型(仍然以Transformer为核心)
  • Diffusion Models,生成领域的最新重要突破

一般我们说的深度学习,都是指深度神经网络。

神经网络结构

绝大多数深度神经网络都是由下列这样的结构组成的:

1759604199775

对于大部分神经网络,我们的目标就是通过不断调整网络内部的所有参数\(\Theta\),来让衡量其表现有多差的损失函数\(J(\Theta)\)的值变得最小。这里的参数就是上图中层和层之间的参数,代表神经网络传递过程中的传递机制。最终我们得到的结果,就是一个代表着概率可能的结论,比如“80%是老虎,15%是猫,5%是其他”。

当然,神经网络发展到今天,针对不同的目标和任务发展出了不同的架构,但是其本质核心思想和上面所说的并无太大差别。

为了让损失函数值最小,我们可以想象把损失函数画出来。当然实际的神经网络模型不可能只有两个变量,但是我们拿单变量及双变量来类比说明。

对于单变量的凸函数和非凸函数,其画面如下:

1759604623630

对于双变量的凸函数和非凸函数,其画面如下:

1759604564935

可以看到,凸函数就是有一个唯一的最低点的图像,这个最低点被称为全局最优解。而非凸函数除了那个最低的点,还有很多其他的像是小山谷一样的地方,这些地方叫做局部最优解。

几乎所有的深度神经网络的损失函数都是非凸的。因此训练深度神经网络模型,一般的意思就是说,找到这个深度神经网络模型损失函数的最低点(或者近似最低点)。


既然我们的目标是让损失函数最小化,那么我们就需要知道损失函数长什么样子。上面我们已经看到,神经网络就是由许多层组成的一个传递结构,在每一层到下一层的传递过程中,层间都会有一个对应的关系,也就是函数。我们将所有层间函数复合起来,就形成了我们的神经网络模型本身。我们使用损失函数来衡量模型的表现。因此在这里,有几个比较重要的概念总结如下:

  • 输入x:也就是我们输入到神经网络中的向量,一般有很多维
  • \(\Theta\):神经网络中所有可学习的参数,包括权重w和偏置b
  • 神经网络模型:\(f(x;\Theta)\),即根据输入得到最终的输出
  • y:真实标签

我们把上面的概念组合在一起,便得到了损失函数(Loss Function)

\[ L(f(x;\Theta),y) \]

损失函数代表了模型在一道题目上的表现,比如你输入了一个图像向量,得到了一个结果;该结果表明图像(模型的预测)是个猩猩,但其实图像(真实标签)是个狒狒,这里在预测上的偏差就是损失(Loss)。之后类似的概念我们都用损失这个专业术语来说,以免出现歧义。

举例来说,我们设定狒狒是[0,0,1,0],猩猩是[0,1,0,0],然后我们把一张100x100像素的灰度图输入到模型里,这个输入x就是10000维的向量。经过神经网络各层参数的运算后,最终输出了一个包含4个数字的预测f(x;θ):[0.05,0.1,0.8,0.05]。这个结果表明,该神经网络认为该输入图片是狒狒的可能性是80%,猩猩的可能性是10%。然后我们发现这张图片其实是猩猩,我们把[0,1,0,0]和[0.05,0.1,0.8,0.05]对比计算一下,就得到了损失。

既然我们知道如何得到一张图片的损失,那我们就能知道如何得到10000张图片的损失。我们不断把图片输入到模型中,计算损失,根据损失情况再调整参数,最终使得模型对这10000张图片的损失降到尽可能低,我们就完成了一次神经网络训练。

为了方便衡量这个最终的损失数值,我们需要把每一张图片的损失统合整理到一个整体性的框架中,这个整体框架就是成本函数(Cost Function)

\[ J(\theta) = \mathbb{E}_{(x,y)\sim \hat{p}_{\text{data}}}\bigl[\,L\bigl(f(x;\theta),\,y\bigr)\bigr] \]

上面是一个成本函数的示例,其用了Stochastic Averaging来求所有损失的平均值,然后得到整体成本。在后面,我们用成本来形容整个神经网络模型在训练集中的整体损失表现。


现在我们再来仔细看一下神经网络模型\(f(x;\Theta)\)

在神经网络模型中,输入数据后,经过层层计算和连接,最终输出结果。举例来说,每一层的若干个node,都会得到上一层的输入,这些输入经过权重W和偏置b来计算,可以得到一个数值,每一个node都可以得到这样一个数值,我们把这个过程叫做线性变换(linear transformation)

\[ z = W^{T}h + b \]

此刻得到的z是一个中间值,也叫做激活前的值(pre-activation)。

神经网络中结点的数量、连接方式、参数的存在等是模型本身的结构决定的,权重和偏置的具体数值通过训练学习来得到。当每一个结点接收到上述线性变换的结果z后,就对z本身进行一次非线性加工,然后输出一个最终的信号值,这个过程就是激活(Activation)

\[ a = g\!\left(W^{T}x + b\right) \]

g就是激活函数。ReLU就是一种激活函数,你可以想象电视台要播出节目,制作组制作好片子后发给了电视台,电视台拿到这个成片(中间产品)后又审查了一下,发现这个片子充满暴力,可能会有负面影响,于是就不准播出,这个审查过程就是激活,不准播出就是激活函数的结果。

路径是神经网络结构决定的,然后这个值继续会经过权重w和偏置b的计算传递到下一层。在一次次训练中,权重w和偏置b不断被修正,以获得一个更好的神经网络模型。当最终我们把神经网络训练地能够得到一个几乎最低的成本函数时,此时带有权重和偏置信息的神经网络就是我们训练好的模型。

以上就是整个神经网络训练的大概思路,假设一个神经网络有三个隐藏层,那么其复合函数就是:

\[ f(x;\theta)=g_{3}\!\left(W_{3}\cdot g_{2}\!\left(W_{2}\cdot g_{1}\!\left(W_{1}x+b_{1}\right)+b_{2}\right)+b_{3}\right) \]

有时候我们会省略偏置b,而把神经网络写作:

\[ f(x;\theta)=f_{L}\circ f_{L-1}\circ \cdots \circ f_{1}(x) \]

其中每一层定义为:

\[ a^{(l)} = g^{(l)}\!\left(W^{(l)} a^{(l-1)} + b^{(l)}\right) \]

万能近似定理

Linear model并不关注feature之间的关系,但以图像识别为例,像素和像素之间的关系并不是相互独立的,而是相互影响的。又比如今天的大语言模型,输入的内容中的每一个token和其他token之间的关系都会影响输出结果。

理论上,我们可以手动设计一个非常复杂的函数,我们称之为embedding\(\phi(x)\))。由于手动设计这样的函数非常困难,因此我们设计了人工神经元

  • Input:该人工神经元接收多个输入信号(\(x_1,x_2,...,x_n\)),类似于生物神经元的树突
  • Weights:对每个输入信号,我们都乘以一个对应的权重(\(w_1,w_2,...,w_n\)),权重代表了这个输入信号的重要性
  • Sum:我们把所有加权后的输入信号加在一起,得到一个总的网络输入(Network Input Net)
  • Activation Function:激活函数,这个综合的Net会被送入一个激活函数,该函数的作用是引入非线性,并决定神经元是否应该被激活以及激活的程度
  • Output:激活函数输出的就是这个神经元的最终输出

我们把多个神经元并列放置,就形成了一个layer,来自input的所有特征会连接到这一层的每一个神经元上,每个神经元独立地进行“加权求和->非线性激活”的计算,最终输出一个结果。整个过程可以看做是一次并行的矩阵运算(输入向量X权重矩阵)加上一次非线性变换。

将多个这样的layer层串联起来,就构成了深度神经网络(Deep Neural Network, DNN)。前一层的输出,会变成后一层的输入。从数学上看,这就是一个层层嵌套的函数。

在这个过程中,如果没有非线性激活函数(Nonlinearities),整个DNN最终将会退化为一个简单的线性函数。因为多次连续的线性变换,其结果等价于一次线性变换。因此非线性激活函数是DNN可以建地很深,实现每一层来学习前一层无法表达的、更复杂的特征的重要原因。

现代的DNN拥有数百万甚至数十亿的参数(权重w),由于DNN是复合函数,因此我们利用微积分中的链式法则(chain rule) 来求导。这个工作流程是:

  1. 前向传播:从输入x开始,逐层计算,直到得到最终的输出和损失值L
  2. 反向传播:从最终的损失L开始,反向逐层计算梯度

在实际应用中,我们不需要手动实现反向传播。现代深度学习框架如PyTorch,TensorFlow,Keras等,都内置了自动微分功能,可以自动为我们构建计算图并执行反向传播。

我们费这么大劲训练DNN,它到底有什么理论上的优势?

万能近似定理 (Universal Approximation Theorem) (非正式地)指出,只要一个神经网络的宽度或深度足够,它就可以以任意小的误差 ε近似任何一个连续函数 f(x)

  • 它可以是一个“ 浅而宽 ”的网络(一层,但有大量神经元)。
  • 它可以是一个“ 深而窄 ”的网络(多层,每层神经元不多)。

实践证明,深层网络通常比浅层网络在学习复杂模式时更有效率。不过要注意,这个定理只保证了DNN有足够的表达能力(expressive power) 去“表示”任意函数,它不保证我们一定能通过训练(如SGD)找到正确的权重来学到这个函数。学习(训练)过程本身是另一个巨大的挑战。

梯度消失

梯度消失(Vanishing Gradients) 发生在反向传播过程中,其发生的根本原因就在于反向传播的链式法则。由于一个神经网络的梯度计算本质上是一长串导数的连乘,因此假设一个有L层的网络,损失函数L对第一层权重W1的梯度粗略地可以表示为:

\[ \frac{\partial L}{\partial W_1} \approx \frac{\partial L}{\partial a_L} \cdot \frac{\partial a_L}{\partial a_{L-1}} \cdot \frac{\partial a_{L-1}}{\partial a_{L-2}} \cdot \ldots \cdot \frac{\partial a_2}{\partial a_1} \]

当连乘的这些项大部分都小于1时,他们的乘积会随着层数的增加而呈指数级速度衰减,最终趋近于零。造成这种现象的主要原因包括:

  • 饱和的激活函数:如Sigmoid函数的导数最大值仅为0.25,Tanh函数的导数最大值也仅为1
  • 不恰当的权重初始化:如果权重被初始化为非常小的值,那么连乘中也会导致梯度衰减

现代深度学习一般用以下方法解决梯度消失问题:

  • 使用非饱和激活函数,如ReLU;当输入>0时,ReLU的导数恒为1,因此梯度可以顺畅传播而不衰减
  • Residual Connections 残差连接:ResNet的核心,通过创建捷径,让梯度可以直接跳过多层网络,无衰减地向前传播
  • Batch Normalization 批归一化:将每层网络的输入重新调整到均值为0、方差为1的分布,使其落入激活函数的“非饱和区”,从而稳定梯度传播
  • 更好的权重初始化:使用Xavier或He初始化方法,让权重从一开始就处在一个合适的大小,使得各层输出的方差保持稳定

梯度爆炸

与梯度消失相反,当连乘的这些项大部分都大于1的时候,他们的乘积会随着层数的增加而呈现指数级增长,最终变得非常巨大。梯度爆炸(Exploding Gradients) 会导致训练过程非常不稳定,损失值(Loss)剧烈震荡;在极端情况下,梯度值会超出计算机的表示范围,导致数值溢出,出现NaN,从而直接中断训练过程。

现代深度学习最常见的处理方法:

  • Gradient Clipping 梯度裁剪:最直接有效的方案,设定一个梯度的上限阈值,如果在反向传播中计算出的梯度范围数超过了这个阈值,就手动将其缩放到阈值大小。这相当于给大喇叭增加了一个音量限制器。
  • 更好的权重初始化
  • Batch Normalization 批归一化

MLP

深度前馈网络(Deep Feedforward Network),也叫做前馈神经网络(Feedforward Neural Network)多层感知机(Multilayer Perceptron, MLP),是典型的深度学习模型。这一部分的主要知识点在Ian经典教材的第六章,有时间可以详细阅读以下。因为现在赶进度,所以只做一些重点说明。

CNN

卷积神经网络(Convolutional Neural Networks) 的名字来源于数学中的卷积(convolution)操作:卷积作用于两个函数f和g,并生成一个新的函数。在CNN中,f通常是filter(滤波器)或者说kernel(卷积核),g是图像(image)。通过对他们进行卷积,即可生成一个新的图像,称为特征图(feature map)。

CNN相比于传统全连接网络,有着独特的优势,这种有事来源于被称为归纳偏置(inductive biases)的两个关键设计原则:

  1. Locality 局部性:假设图像中临近的区域之间有更强的关联性;在实现中神经元只与输入图像的一个小局部区域相连接,而不是连接到所有像素。这有助于网络学习局部的模式(如边缘、角落等)并保持空间结构
  2. Translation Invariance 平移不变性:假设图像中某个特征(比如一只眼睛)无论出现在哪个位置,它都具有相同的意义;在实现中可以在整个图像上使用相同的滤波器(权重共享)来检测同一个特征,这意味着网络不需要在每个位置上重新学习识别同一个物体。

1760317490635

CNN通过不同的滤波器filter来捕捉图像中的空间依赖关系。CNN通过池化(Pooling)或者说下采样(Downsampling)来降低特征图维度。下图是一个经典的CNN模型——LeNet(1998)的结构和每一层的作用示意图:

1760317981772

CNN采用了机器学习中两个非常重要的特性:

  1. Equivariant 等变性:\(f(g(x))=g(f(x))\)
  2. Invariance 不变性:\(f(g(x))=f(x)\)

1760318191230

这两个特性本身不是CNN专属的,但是CNN非常好的利用了这两个特性:

  • 卷积层是等变的
  • 池化层引入不变性
  • 整个CNN网络的目标是不变的

此外,依据上述特性,我们可以通过数据增强(Data Augmentation)来提升模型的泛化能力。其原理就是我们在训练时对原始数据进行各种变换,比如裁剪、旋转、翻转、调整颜色等,人为地创造出更多的训练样本,这样做等于是在告诉模型:这些看起来不一样的图片,其实都代表同一种东西。通过学习这些变换后的数据,模型能够学会对这些变换保持不变性,从而提高泛化能力。

1760318528056

循环神经网络

RNN

循环神经网络(Recurrent Neural Networks, RNN)是处理时间序列(Time Series)的经典模型。RNN的核心思想是:

  • 采用顺序处理的方式:并不是一次性看完全部数据,而是一个时间步一个时间步地读取
  • 关键在于隐藏状态(Hidden State, \(h_t\)),他会结合上一个时间步的记忆(\(h_{t-1}\))和当前时间步的输入(\(x_t\))来更新自己,形成新的记忆\(h_t\)。这个过程用公式表达就是:
\[ h_t = \sigma(W_h^{T}[h_{t-1}, x_t]) \]
  • 最终的输出\(y_t\)由当前时间步的记忆\(h_t\)决定:
\[ \mathbf{y}_t = \sigma(\mathbf{W}_y^{\top} \mathbf{h}_t) \]

1760318893167

上图所示链式结构非常直观地展示了RNN的工作流程,其中:

  • 最下面一行的蓝色圆圈是输入层,代表在不同时间点输入的数据,这构成了一个输入序列
  • 中间一行的橙色圆圈是隐藏层,这是RNN的核心,每一个橙色圆圈都是一个时间步的隐藏状态,可以被看做是RNN到那个时间点为止的记忆,它包含了之前所有输入信息的摘要
  • 在第t个时间步的隐藏状态\(h_t\)是由上一个时间步的隐藏状态\(h_{t-1}\)和当前时间步的输入\(x_t\)共同计算得出的,这个记忆会一直向后传递,影响后续所有时间步的计算
  • 最上面一层是输出层(青色圆圈),代表在每个时间点的输出,第t个时间步的输出是由当前时间步的隐藏状态\(h_t\)
  • 向上的蓝色箭头:就是将当前时间步的输入\(x_t\)传递到隐藏层
  • 水平的绿色箭头:这就是循环(Recurrent)的核心所在,代表了记忆的传递
  • 向上的粉色箭头:从隐藏层的记忆中生成输出
  • 反向传播的红色箭头:时间反向传播(Backpropagation Through Time, BPTT)

RNN的核心问题和致命弱点是难以学习长距离的依赖关系。在模型训练的时候,梯度需要沿着这个长长的链条反向传播(红色箭头)。当序列很长时,梯度在传播过程中会不断地连乘,从而可能导致梯度消失、梯度爆炸、计算和内存开销过大等问题。

LSTM

长短期记忆网络(Long Short-Term Memory, LSTM) 是一种非常重要的RNN变体,专门用来解决标准RNN的长期依赖问题。

1760320028360

相比于RNN仅依赖于一个隐藏状态作为记忆,LSTM设计了一个能记录更多内容的记忆机制:

  • 创建一个名为细胞状态(Cell State)的通道,是LSTM的长期记忆核心,专门用来存储长期信息。这个通道像一个传送带,信息可以很容易地在上面流动而不会发生剧变,从而解决了梯度消失问题。
  • 创建了三个可学习的gate来充当管理员,他们可以动态地、有选择的选择:

  • Forget Gate:忘记哪些旧的记忆?决定从细胞状态中丢弃多少旧信息,1代表完全保留,0代表完全丢弃。

  • Input Gate:存入哪些记忆?决定让多少新信息写入细胞状态,一个Sigmoid层决定哪些值需要更新,一个tanh层创建一个候选的新记忆向量:两者结合共同
  • Output Gate:输出哪些记忆?

通过这种精巧的设置,LSTM能够主动管理信息流,既能保留重要的长期记忆,又能处理当前的短期输入,因此得名“长短期记忆网络”。信息在细胞状态上传递,只通过门的控制进行微调。

GRU

GRU

生成模型

本节介绍VAE, GAN, Diffusion Model等生成式模型。这里要注意,虽然ChatGPT这样的大语言模型(LLM)现在也被用于机器人学(比如给机器人下达“去厨房给我拿个苹果”这样的高级指令),但 具体执行动作的底层轨迹生成 ,更适合用Diffusion等模型来完成。因此,从机器人学的应用角度出发,介绍VAE、GAN和Diffusion是更直接、更对口的。而ChatGPT相关的内容参见Transformer一节。

1760325030241

上图展示了当今最流行的三种生成式模型范式以及不可能三角:

  • Quality 质量:生成样本的逼真程度
  • Speed 速度:生成样本的速度
  • Coverage 覆盖率:模型能否生成各种不同类型的样本,覆盖真实数据的全部模式

不可能三角中的高多样性(覆盖率)指的是模型生成样本的丰富程度和覆盖面,比如你让他画狗,他能画出各种不同品种、不同姿势、不同背景的狗;快速采样的意思是从模型中提取或生成一个新样本的速度。其中:

  • VAE倾向于快速采样和多样性(高覆盖率),但生成的样本质量通常较低
  • GAN倾向于生成高质量图像和快速采样,但是有时候会牺牲多样性(模式崩溃)
  • Diffusion Models倾向于高质量和高多样性,但代价是采样速度非常慢。

GAN

GAN是对抗生成的代表,通过博弈生成数据

Diffusion Models

Diffursion Models从噪声中还原生成数据

VAE

VAE是概率生成的代表,从学习到的潜在空间中生成数据

Transformer

Attention机制

Transformer是一个旨在完全取代LSTM的全新架构,其核心思想和RNN完全不同。RNN像人阅读一样,一个词一个词地处理,信息通过隐藏状态(记忆)在时间步之间依次传递。这种结构天然地包含了序列的顺序信息,但是缺点也非常显著:不能并行计算,必须算完第99个词才能算第100个词,因而在处理长序列时非常慢。同时,RNN在长距离上问题明显,LSTM缓解了这个问题,但信息从第一个词传递到第一百个词,依然要经过99步,路径太长,信息仍然可能丢失。

Transformer完全抛弃了RNN的思路,改为采用自注意力机制(Self-Attention):它一次性地看到整个句子,然后计算句子中的每个词对于其他所有词的重要性或关联度。其处理机制是并行的,因为所有词的重要性都是同时计算的,因而极大地利用了现代GPU的并行计算能力;同时句子中任意两个词之间的距离都是1,因此模型可以直接建立第一个词和第一百个词之间的联系,而无需信息逐步传递。

Transformer中一些非常重要的核心概念:

  • Positional Encoding 位置编码:由于Transformer一次性看到所有的词,因而它本身无法分辨“狗咬人”和“人咬狗”的区别,于是Transformer使用一个独特的数字向量来让每个词获得一个位置编码向量来记录该词语在整个序列中的位置。
  • Encoder 编码器:接收并完整阅读输入信息,然后将信息压缩为一组富含信息的数字向量(称为上下文向量或记忆)。编码让语言脱离了词语本身,让语言转换为一种代表着概念的向量。将人话转换为数字向量的过程就是编码(Encoding)。
  • Decoder 解码器:接收来自Encoder的概念向量,然后根据这个概念向量所代表的抽象含义,一个词一个词地生成目标输出。将数字向量转换为具体的人类语言的过程就是解码(Decoding)。

这里注意,位置编码是Transformer独创的一个概念,而Encoder和Decoder则在更早的Seq2Seq架构(Sequence-to-Sequence)中提出。Transformer的革命性就在于用一种全新的方式来实现Encoder和Decoder。在RNN中,Encoder和Decoder分别由一个RNN和另一个RNN组成;LSTM中也是如此。


在深度学习中,Embedding是一个过程,这个过程将离散的、非数值的类别数据(如单词、用户ID、电影名称)转换成连续的、稠密的、低维的数字向量,其结果(也就是那个转换后生成的数字向量本身),也叫一个embedding或embedding vector。

举例来说,如果词典里有5万个词,你可以创建一个5万维的向量,对于猫这个词(假设是第500个词),就在第500个位置设为1,其他全是0。然而,这个方法向量维度太高,非常稀疏。所有词向量之间都是互相独立的(正交的),无法体现词与词之间的关系。比如,"猫""小猫" 的关系,与 "猫""汽车" 的关系,在数学上看起来完全一样。

我们采用更好的Embedding方法:我们不用一个5万维的向量,而是用一个比如300维的 稠密向量 (dense vector)来表示 "猫":

  • "猫" -> [0.12, -0.45, 0.98, ..., 0.67] (一个300维的浮点数向量)

这个向量不是随机的,它是通过在大量数据上 训练神经网络学习到的 。网络会调整向量中的数值,使得 意思相近的词,它们的向量在多维空间中的位置也相近 。一个经典的例子就是:embedding("国王") - embedding("男人") + embedding("女人") 在向量空间中会非常接近 embedding("女王")embedding("小猫")embedding("猫") 的向量会很接近。

总结来说,Embedding 就是一个 可学习的查找表 (learnable lookup table) 。输入一个词(或ID),它会输出一个能代表其语义信息的低维稠密向量,作为神经网络后续层真正的输入。

在Transformer中,Embedding被应用到了极致,并且增加了一个关键的补充:位置编码。我们来看一下Transformer在机器翻译任务重的具体完成步骤,来看一下Transformer是如何一步步将一句英文翻译为法文的:

阶段一:编码器(Encoder)

阶段一第一步:理解输入句子

  1. Tokenization: 将句子分割成最小的单元(token)。假设我们现在输入一句话,比如“The cat sat”,首先我们把这句话分为几个token:"The", "cat", "sat"。
  2. Token Embedding: 每个token都会通过一个可学习的embedding层(lookup table)来转换为一个固定维度的数字向量。例如,如果数字向量的维度是 512,那么这句话就变成了 3 个 512 维的向量。
  3. Positional Encoding: 在将词向量输入模型主体之前,每个词向量加上一个位置编码向量。因而最终输入=Token Embedding + Positional Encoding,这样模型接收到的每个向量就同时包含了词的语义信息(来自token embedding)和词的位置信息(来自positional encoding)。

阶段一第二步:编码层(Encoder Layer Processing)

这些准备好的向量会被送入一个由 N 层(原论文中 N=6)相同的编码器层堆叠而成的结构。我们来看其中一层是如何工作的:

  1. Multi-Head Self-Attention: 多头自注意力机制,让句子中的每个词都能“看到”句子中的所有其他词,从而理解上下文。对于 "cat" 这个词,自注意力机制会计算出 "The" 和 "sat" 对理解 "cat" 的重要性得分。然后,它会根据这些得分,将所有词的向量信息进行加权求和,生成一个全新的、包含了整个句子上下文信息的 "cat" 向量。这个过程对所有词同时并行进行。“多头” 指的是这个过程会并行地做多次(比如8次),每次关注点不同(比如一个头关注语法关系,另一个头关注语义关系),最后将所有头的结果拼接起来,获得更丰富的信息。
  2. Add & Norm: 残差连接与层归一化:将自注意力层的输入直接加到它的输出上(这被称为残差连接),然后进行层归一化。这是一种帮助网络更深、训练更稳定的技巧。
  3. Feed-Forward Network: 前馈神经网络,将上一步的输出向量,独立地通过一个简单的全连接神经网络。这可以增加模型的非线性能力,进一步处理信息。
  4. 再次Add & Norm.

这一整套流程(4-7步)构成了一个 完整的编码器层 。这6层编码器会依次处理这些向量,每一层都会让向量的表示更加丰富和抽象。编码阶段结束时,我们得到了一组最终的向量(每个输入词一个),它们是解码器可以随时查阅的、对原始句子的“深刻理解”。

阶段二: 解码器 (Decoder) - "生成"输出句子

解码器的目标是利用编码器提供的“理解”,一个词一个词地生成法文翻译。这是一个自回归(auto-regressive) 的过程。

首先解码器接收一个特殊的起始字符(start-of-sequence)作为第一个输入,告诉它开始生成,解码器启动。解码器同样由N=6 个解码器层堆叠而成。我们来看其中一层如何生成第一个法文词:

  1. 和编码器一样,起始字符也要经过词嵌入和位置编码。
  2. Masked Multi-Head Self-Attention:带掩码的多头自注意力,目的是让解码器在生成当前词时,只能“看到”它已经生成的那些词。其过程与编码器的自注意力类似,但带有一个“掩码 (mask)”。因为现在只生成了第一个词,所以它只能看到起始符 <s>。这个掩码确保了模型不会“作弊”去偷看未来的答案。
  3. Cross-Attention:这是连接编码器和解码器的桥梁,目的是让解码器回顾编码器对原始英文句子的理解。这一层的输入来自上一步(带掩码的自注意力),但它的计算过程会去查询 编码器最终输出的那组向量 。它会问:“基于我现在要生成一个法文词的需求,英文句子里的哪个词最重要?”。它可能会发现 "The" 和 "cat" 在此刻最重要。
  4. 前馈网络及归一化:与编码器中的步骤完全相同(残差连接、层归一化、前馈网络...)。

Output Embedding: 在Decoder的最后,模型会生成一个最终的向量。为了将这个向量变回一个具体的词,需要再经过一个线性层和一个Softmax层,这个线性层本质上也是一个embedding层(通常与输入层的 Token Embedding 共享权重),它将高维的语义表示投影回词汇表空间,从而预测出下一个最可能的词。

以我们正在讨论的翻译任务为例具体来说明:经过N=6 层解码器层的处理后,我们得到一个最终的输出向量。这个向量会经过一个 线性层 (Linear Layer) ,将其维度放大到整个法文词典的大小(比如3万个词)。然后通过 Softmax 函数 ,将这些数值转换成每个词的生成概率。我们选择概率最高的那个词,比如 "Le" ,作为第一个输出。

"Le" 现在被当作解码器在 下一个时间步的新输入 。然后解码器重复之前的整个流程,直到生成一个特殊的终止符 </s> (end-of-sequence) 为止:

  1. 准备新一轮的输入,此时输入序列变成了 <s>"Le"。这两个词会分别经过词嵌入和位置编码,形成一个新的输入序列向量。
  2. 再次通过解码器层:这个新的序列向量被送入N=6层的解码器中。在 Masked Multi-Head Self-Attention 步骤中,模型会处理 <s>"Le"。当计算 "Le" 的注意力时,掩码机制确保它只能关注到自己和前面的 <s>,而不能偷看未来。在 Cross-Attention 步骤中,解码器会再次审视编码器对 "The cat sat" 的理解。但这一次,它的问题变成了:“我已经说了'Le',现在应该生成什么词?” 此时,注意力机制可能会高度聚焦于编码器输出中与 "cat" 对应的那个向量。
  3. 后续的前馈网络等步骤与之前完全一致。
  4. 生成第二个词 :经过所有解码器层后,最终的输出向量通过线性层和Softmax函数,预测出下一个最可能的词,这一次很可能是 "chat"
  5. 循环往复 : 现在, "chat" 又被追加到输入序列的末尾。在第三轮中,解码器的输入是 <s>, "Le", "chat"。它将重复上述所有步骤,并利用交叉注意力去关注英文句子中的 "sat",最终生成 "s'assit"

这个自回归(Auto-Regressive) 的过程会一直持续下去,每一步都将上一步的输出作为下一步的输入,直到模型预测出概率最高的词是特殊的 终止符 </s> 。当这个符号被生成时,解码过程停止,翻译任务完成。

最终,通过这个逐词生成、循环往复的过程,模型便将 "The cat sat" 完整地翻译成了 "Le chat s'assit"。


Transformer 是一种极其通用的架构,其影响力已远远超出了它最初的自然语言处理(NLP)领域。当前最著名的一些大语言模型,如 GPTs (Generative Pre-trained Transformers)、PaLM、LLaMA 等。这些模型无一例外都是基于 Transformer 架构构建的。

同时,Transformer也被应用于计算机视觉领域:Vision Transformer (ViT)。ViT 将一张图片分割成一个个小图块(patches),然后将这些图块“展平”成一个序列。之后,ViT 就可以像处理一句话里的单词一样,用标准的 Transformer Encoder 来处理这些图块序列,从而实现图像识别等任务。这完全颠覆了此前由卷积神经网络(CNN)统治的计算机视觉领域。

在强化学习领域,Decision Transformer通过序列建模来解决强化学习:它将强化学习中的轨迹(即一系列的“状态-动作-奖励”组合)看作是一个长序列。然后,它训练一个 Transformer 模型来预测在这个序列的下一步应该采取什么“动作”。这把一个复杂的决策问题,转化成了一个 Transformer 极其擅长的序列预测问题。

Transformer的成功并非偶然,它高度scalable:由于其并行化的设计(没有RNN的顺序依赖),我们可以通过增加模型大小、数据量和计算资源,来持续地、显著地提升其性能。当前的大语言模型竞赛,本质上就是 Transformer 架构可扩展性的直接体现。

Transformer与传统模型的对比:

  • vs. CNN : CNN 的“视野”受限于卷积核大小,难以捕捉全局和远距离的依赖关系。
  • vs. RNN/LSTM : RNN/LSTM 必须按顺序处理数据,训练速度慢,且受梯度消失影响,学习长距离依赖仍然困难。
  • vs. MLP (全连接网络) : 参数量过大,无法处理可变长度的输入(比如长短不一的句子)。

在Sutton的著名文章《The Bitter Lesson》中,Sutton直言AI 领域最惨痛的教训是,那些试图模仿人类知识、构建复杂精巧规则的方法,长远来看总是输给那些简单、通用、并能充分利用巨大计算能力的方法。成功的两大通用方法是搜索 (Search)学习 (Learning) 。Transformer 正是“学习”这条路线的完美典范。它的设计简单通用,使其能够最大限度地利用当今海量的数据和算力,通过“暴力”学习来获得惊人的智能。

值得注意的是,虽然我们都知道ChatGPT等现代大语言生成式模型的核心架构就是Transformer,但是Transformer本身是一种架构(architecture),而不是一种模型类型。准确来说,ChatGPT属于和VAE, GAN, Diffusion(接下来的小节中会讲到)不同的另一大类生成模型——自回归模型(Autoregressive Models)

Transformer既可以用于生成式模型,也可以用于判别式模型:

  • GPT,仅解码器。GPT的唯一任务就是预测序列中的下一个词,所以是一个纯粹的生成式模型。典型应用:聊天机器人、文章写作、代码生成。
  • BERT,仅编码器。BERT的目标是深度理解文本,因而核心任务用于理解和分类数据,典型应用包括情感分析、文本分类、问答系统等。

Autoencoder

无监督学习

MoE

混合专家模型