Lecture by X.Dan

深度神经网络在机器学习应用、学习复杂概率分布方面表现出色。但是,训练深度神经网络存在诸多挑战。我们将从以下几个方面探讨深度学习架构:

  • 更好的优化方法
    • 克服非凸损失函数
    • 自适应学习率
    • 基于动量的方法
  • 梯度消失与梯度爆炸问题
    • 归一化技术
    • 残差连接
    • 谨慎的初始化策略
  • 过拟合与正则化
    • 正则化技术
    • 早停和模型选择
  • 现代神经网络架构
    • 卷积神经网络
    • 循环神经网络
    • 转换器架构
    • 图像神经网络

# 优化方法

# 现代神经网络架构

# 卷积神经网络 (CNNs)

在对图像的全连接神经网络中,参数数量随着输入图像大小的增加而急剧增加。对于 4×44\times 4 的图像,平坦化后有 1616 个输入神经元。而对于 100×100100\times 100 的 RGB 图像,平坦化后有 30,00030,000 个输入神经元。如果使用一个隐藏层,隐藏层有 1,0001,000 个神经元,那么全连接后的参数数量将达到 30,000,00030,000,000 个。这种庞大的参数量不仅增加了计算复杂度,还容易导致过拟合,忽视了图像的空间结构信息。

卷积神经网络(Convolutional Neural Networks, CNNs) 的核心思想是利用权重共享(Weight Sharing)局部连接(Local Connectivity) 来减少参数数量。通过在输入图像上滑动一个小的滤波器,卷积操作能够像探针一样在保持空间局部结构的前提下提取特征。这种方法不仅显著减少了参数数量,还提高了模型的泛化能力。

例如,对 3×33\times 3 的图像编码

Img=[123456789]\mathrm{Img}=\begin{bmatrix}1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9\end{bmatrix}

使用 2×22\times 2 的滤波器

ker=[1234]\mathrm{ker}=\begin{bmatrix}1&2\\ 3&4\end{bmatrix}

进行卷积操作,得到的特征图为

Imgker:=[[1245][1234][2356][1234][4578][1234][5689][1234]]=[37476777]\mathrm{Img}*\mathrm{ker}:=\begin{bmatrix}\begin{bmatrix}1&2\\4&5\end{bmatrix}*\begin{bmatrix}1&2\\3&4\end{bmatrix} & \begin{bmatrix}2&3\\5&6\end{bmatrix}*\begin{bmatrix}1&2\\3&4\end{bmatrix} \\ \\ \begin{bmatrix}4&5\\7&8\end{bmatrix}*\begin{bmatrix}1&2\\3&4\end{bmatrix} & \begin{bmatrix}5&6\\8&9\end{bmatrix}*\begin{bmatrix}1&2\\3&4\end{bmatrix}\end{bmatrix}=\begin{bmatrix}37 & 47 \\ 67 & 77\end{bmatrix}

离散卷积(Discrete Convolution) 作为 CNNs 的核心运算,将输入数据体与一组可学习滤波器之间进行如下运算得到特征图(Feature Maps) IK:=ZI*K:=Z,其每一个元素的计算公式为

(IK)i,j=m=0M1n=0N1Ii+m,j+nKm,n(I*K)_{i,j}=\sum_{m=0}^{M-1}\sum_{n=0}^{N-1}I_{i+m,j+n}K_{m,n}

其中 II 是输入图像,KK滤波器(Filter)卷积核M×NM\times N 是滤波器的尺寸。多通道卷积扩展了这一概念,以 RGB 图像为例,其特征图的计算公式为

Zi,j,k=c=0C1m=0M1n=0N1Xi+m,j+n,cWm,n,c,k+bkZ_{i,j,k}=\sum_{c=0}^{C-1}\sum_{m=0}^{M-1}\sum_{n=0}^{N-1}X_{i+m,j+n,c}W_{m,n,c,k}+b_k

其中 XX 是尺寸为 H×WH\times W 的、具有 CC 个通道的输入数据体;WW 是尺寸为 (M,N,C,K)(M,N,C,K) 的滤波器张量,即 KK 个尺寸为 M×NM\times N 的滤波器,每个滤波器有 CC 个通道,和输入数据体的通道对应。bkb_k 是偏置项;ZZ 是输出特征图,尺寸为 (H,W,K)(H',W',K),表示在 KK 个滤波器作用下得到的 KK 个特征图。

卷积操作自然地减少了特征图的高、宽尺寸。例如,输入图像尺寸为 H×WH\times W,使用 M×NM\times N 的滤波器进行卷积后,输出特征图的尺寸变为 (HM+1)×(WN+1)(H-M+1)\times (W-N+1)。为了控制输出特征图的尺寸,有以下几种常用技术。

填充(Padding):在输入图像四周添加额外的像素行和列包裹,通常填充为零,允许滤波器在边缘位置进行卷积操作,从而保持输出特征图的尺寸不变。

对之前例子中的图像进行填充:

Imgpad=[0000001230045600789000000]\mathrm{Img_{pad}}=\begin{bmatrix}0 & 0 & 0 & 0 & 0 \\ 0 & 1 & 2 & 3 & 0 \\ 0 & 4 & 5 & 6 & 0 \\ 0 & 7 & 8 & 9 & 0 \\ 0 & 0 & 0 & 0 & 0\end{bmatrix}

使用相同的 2×22\times 2 滤波器进行卷积操作,得到的特征图为

Imgpadker:=[[0001][1234][0012][1234][0023][1234][0104][1234][1245][1234][2356][1234][0407][1234][4578][1234][5689][1234]]=[41016223747406777]\mathrm{Img_{pad}}*\mathrm{ker}:=\begin{bmatrix}\begin{bmatrix}0&0\\0&1\end{bmatrix}*\begin{bmatrix}1&2\\3&4\end{bmatrix} & \begin{bmatrix}0&0\\1&2\end{bmatrix}*\begin{bmatrix}1&2\\3&4\end{bmatrix} & \begin{bmatrix}0&0\\2&3\end{bmatrix}*\begin{bmatrix}1&2\\3&4\end{bmatrix} \\ \\ \begin{bmatrix}0&1\\0&4\end{bmatrix}*\begin{bmatrix}1&2\\3&4\end{bmatrix} & \begin{bmatrix}1&2\\4&5\end{bmatrix}*\begin{bmatrix}1&2\\3&4\end{bmatrix} & \begin{bmatrix}2&3\\5&6\end{bmatrix}*\begin{bmatrix}1&2\\3&4\end{bmatrix} \\ \\ \begin{bmatrix}0&4\\0&7\end{bmatrix}*\begin{bmatrix}1&2\\3&4\end{bmatrix} & \begin{bmatrix}4&5\\7&8\end{bmatrix}*\begin{bmatrix}1&2\\3&4\end{bmatrix} & \begin{bmatrix}5&6\\8&9\end{bmatrix}*\begin{bmatrix}1&2\\3&4\end{bmatrix}\end{bmatrix}=\begin{bmatrix}4 & 10 & 16 \\ 22 & 37 & 47 \\ 40 & 67 & 77\end{bmatrix}

尺寸变回了 3×33\times 3

步幅(Stride):通过在卷积操作中跳过某些位置来控制输出特征图的尺寸。步幅 SS 表示每次移动滤波器时跳过的像素数(横向和纵向均跳过 S1S-1 个像素),直接通过减少采样点来降低输出特征图的尺寸。

例如,使用步幅 S=2S=24×44\times 4 图像进行卷积操作:

Img=[12345678910111213141516]\mathrm{Img}=\begin{bmatrix}1 & 2 & 3 & 4 \\ 5 & 6 & 7 & 8 \\ 9 & 10 & 11 & 12 \\ 13 & 14 & 15 & 16\end{bmatrix}

使用 2×22\times 2 的滤波器

ker=[1001]\mathrm{ker}=\begin{bmatrix}1&0\\0&1\end{bmatrix}

进行卷积操作,得到的特征图为

Imgker:=[[1256][1001][3478][1001][9101314][1001][11121516][1001]]=[7112327]\mathrm{Img}*\mathrm{ker}:=\begin{bmatrix}\begin{bmatrix}1&2\\5&6\end{bmatrix}*\begin{bmatrix}1&0\\0&1\end{bmatrix} & \begin{bmatrix}3&4\\7&8\end{bmatrix}*\begin{bmatrix}1&0\\0&1\end{bmatrix} \\ \\ \begin{bmatrix}9&10\\13&14\end{bmatrix}*\begin{bmatrix}1&0\\0&1\end{bmatrix} & \begin{bmatrix}11&12\\15&16\end{bmatrix}*\begin{bmatrix}1&0\\0&1\end{bmatrix}\end{bmatrix}=\begin{bmatrix}7 & 11 \\ 23 & 27\end{bmatrix}

尺寸变为 2×22\times 2

对输入图 H×WH\times W 使用 M×NM\times N 的滤波器,填充为 PP,步幅为 SS,则输出特征图的尺寸为

O=WK+2PS+1O=\dfrac {W-K+2P}{S}+1

其中 OO 是输出特征图的宽度或高度,KK 是滤波器的宽度或高度。

线性采样结束后,通常还会进行非线性变换,以增强模型的表达能力。对特征图 ZZ 应用非线性激活函数后,得到激活特征图 AA

Ai,j,k=f(Zi,j,k)A_{i,j,k}=f(Z_{i,j,k})

其中,常用的激活函数包括

  • ReLU(线性整流单元):f(x)=max(0,x)f(x)=\max(0,x)
  • Sigmoid(S 型函数):f(x)=11+exf(x)=\dfrac{1}{1+e^{-x}}
  • Tanh(双曲正切函数):f(x)=exexex+exf(x)=\dfrac{e^{x}-e^{-x}}{e^{x}+e^{-x}}

最后通过池化操作进一步降低特征图的尺寸和复杂度。

对先前例子中的特征图线性整流 f(x)=50xf(x)=|50-x|,得到激活特征图

[41016223747406777]f[46403428133101727]\begin{bmatrix}4 & 10 & 16 \\ 22 & 37 & 47 \\ 40 & 67 & 77\end{bmatrix}\xrightarrow{f}\begin{bmatrix}46 & 40 & 34 \\ 28 & 13 & 3 \\ 10 & 17 & 27\end{bmatrix}

池化(Pooling) 通过对局部区域进行汇总操作来减少特征图的尺寸。

Pi,j,k=pool(Asi:si+p;sj:sj+p;k)P_{i,j,k}=\text{pool}(A_{si:si+p;sj:sj+p;k})

其中,PP池化特征图pp池化窗口的尺寸,ss池化步幅pool()\text{pool}(\cdot)池化函数。常见的池化方法包括最大池化和平均池化。

例如,对激活特征图进行 2×22\times 2 最大池化,步幅为 22,得到池化特征图

[46403428133101727]max pool[46341727]\begin{bmatrix}46 & 40 & 34 \\ 28 & 13 & 3 \\ 10 & 17 & 27\end{bmatrix}\xrightarrow{\text{max pool}}\begin{bmatrix}46 & 34 \\ 17 & 27\end{bmatrix}

这里根据步幅 22,从左上角开始,会超出边界,它将自动填充为负无穷。

CNNs 的核心架构是局部连接、权重共享和池化操作的组合,分别用于提取局部特征、减少参数数量和降低特征图尺寸,使得极大优化了全连接神经网络的参数尺寸、鲁棒于平移变换,并提升了模型的泛化能力。

CNNs 应用常见于图像分类、目标检测、语义分割、图像生成、医学图像分析、视频处理等领域。里程碑式的 CNN 架构包括 LeNet、AlexNet、VGG、GoogLeNet、ResNet 等。

对于 RGB 图像,卷积神经网络的输入通常是一个三维张量,尺寸为 H×W×3H\times W\times 3,其中 HH 是图像的高度,WW 是图像的宽度,33 代表 RGB 三个颜色通道。通过多层卷积和池化操作,CNNs 能够逐步提取图像的低级到高级特征,具体体现为如下例子

  • 128×128×3128\times 128\times 3:输入一张彩色图片;
  • 128×128×32128\times 128\times 32:第一层卷积层使用 32323×33\times 3 的滤波器组 I,每个滤波器先提取不同通道的局部特征,然后相加,得到一张特征图,经过 3232 个滤波器组后,得到 3232 张特征图;
  • 64×64×3264\times 64\times 32:第一层池化层,使用 2×22\times 2 的最大池化,步幅为 22,将每张特征图的尺寸减半;
  • 64×64×6464\times 64\times 64:第二层卷积层,使用 64643×33\times 3 的滤波器组,提取更复杂的特征;
  • 32×32×6432\times 32\times 64:第二层池化层,再次使用 2×22\times 2 的最大池化,步幅为 22,将特征图尺寸减半;
  • 32×32×12832\times 32\times 128:第三层卷积层,使用 1281283×33\times 3 的滤波器组,提取更高级的特征;
  • 16×16×12816\times 16\times 128:第三层池化层,使用 2×22\times 2 的最大池化,步幅为 22,将特征图尺寸减半;
  • 3276832768:将 16×16×12816\times 16\times 128 的特征图展平为一维向量,作为输入,全连接第一隐藏层为 10241024 个神经元,全连接第二隐藏层为 512512 个神经元,输出层用 Softmax 激活为 10001000 个类别的概率分布。

可以看见,由于池化 - 卷积,其实越后面的卷积,在空间尺寸上越小,但通道数越来越多,提取的特征也越来越复杂。一开始,卷积提取的是边缘、颜色等低级特征,随着网络加深,卷积提取的特征逐渐变得抽象和复杂,如纹理、形状(由颜色通道的组合形成),最后可能是物体的部分或整体表示(由纹理和形状的组合形成)。这个过程是从低级到高级特征的逐步抽象和组合的过程。

CNNs 中,一个卷积层的总参数数量计算公式为:

Total Parameters=(Kw×Kh×Cin+1)×Cout\text{Total Parameters}=(K_w\times K_h \times C_{in} + 1) \times C_{out}

其中,KwK_wKhK_h 分别是滤波器的宽度和高度,CinC_{in} 是输入通道数,CoutC_{out} 是输出通道数,+1+1 代表每个滤波器的偏置项。

一个简单的例子为

  • 输入 RGB 图像,尺寸为 32×32×332\times 32\times 3
  • 卷积层使用 64643×33\times 3 的滤波器组;
  • 步幅为 11,填充为 11

则该卷积层的总参数数量为

(3×3×3+1)×64=(27+1)×64=28×64=1792(3\times 3 \times 3 + 1) \times 64 = (27 + 1) \times 64 = 28 \times 64 = 1792

# 循环神经网络 (RNNs)

标准的 FNNs 是静态的,它们将输入映射到输出,而不考虑时间或序列信息,假设它们是 i.i.d. 的数据点。但对于含有序列数据的任务,如自然语言处理、时间序列预测、音视频分析等,时序和上下文信息至关重要。现在的问题是,如何让神经网络具备记忆和处理序列数据的能力?即如何记住过去的信息,并将其应用于当前的输入?

循环神经网络(Recurrent NNs) 是为处理序列数据而设计的神经网络架构。RNNs 通过在网络中引入循环连接(Recurrent Connections),使得当前时刻的输出不仅依赖于当前输入,还依赖于前一时刻的隐藏状态,从而实现对序列信息的记忆和处理。此外,RNNs 还可以通过共享权重,在不同时间步上使用相同的参数,从而有效地处理变长序列数据。

RNNs 的基本单元包括输入层、隐藏层和输出层。对于每个时间步 tt,RNNs 接收当前输入 xtx_t 和前一时刻的隐藏状态 ht1h_{t-1},通过以下公式计算当前隐藏状态 hth_t 和输出 yty_t

ht¡1htht+1xt¡1xtxt+1

上述图像描述了 RNNs 的基本结构,其中 xtx_t 是在时间步 tt 的输入,hth_t 是在时间步 tt 的隐藏状态,箭头表示信息流动的方向。隐藏状态 hth_t 通过循环连接将前一时刻的隐藏状态 ht1h_{t-1} 传递到当前时刻,输出依赖于当前输入 xtx_t 和前一隐藏状态 ht1h_{t-1}。更具体地,RNNs 的基本单元为

ytht¡1htxt


其中 tt 代表时间步,即序列中的位置,hth_t 是隐藏状态,xtx_t 是输入,yty_t 是输出,具体关系为

{ht=σ(Whhht1+Wxhxt+bh)yt=Whyht+by\begin{cases} h_t=\sigma(W_{hh}h_{t-1}+W_{xh}x_t+b_h)\\[6pt] y_t=W_{hy}h_t+b_y \end{cases}

WW 是权重矩阵,bb 是偏置项,σ\sigma 是激活函数。

RNN 有多种变体,可以根据输入层和输出层的关系进行分类:

  • 单对单(One-to-One):标准的前馈神经网络,输入和输出都是单一的。
  • 单对多(One-to-Many):输入是单一的,输出是一个序列。例如,图像描述生成。

y1y2y3h1h2h3x

  • 多对单(Many-to-One):输入是一个序列,输出是单一的。例如,情感分析。

yh1h2h3x1x2x3

  • 多对多(Many-to-Many):输入和输出都是序列。例如,机器翻译。

y1y2y3h1h2h3x1x2x3

深度 RNNs(Deep RNNs) 通过堆叠多个 RNN 层来增强模型的表达能力。每一层的输出作为下一层的输入,从而捕捉更复杂的时序特征。深度 RNNs 的计算过程如下:

O1O2O3OTH(L)1H(L)2H(L)3¢¢¢H(L)T............H(2)1H(2)2H(2)3¢¢¢H(2)TH(1)1H(1)2H(1)3¢¢¢H(1)TX1X2X3¢¢¢XT

其中 XtX_t 是输入序列,Ht(l)H_t^{(l)} 是第 ll 层在时间步 tt 的隐藏状态,OtO_t 是输出序列。每一层的隐藏状态通过循环连接传递信息,同时每一层之间也有前馈连接,将上一层的输出作为下一层的输入。

双向 RNNs(Bidirectional RNNs) 提供两个反向的隐藏状态,一个从前向后处理序列,另一个从后向前处理序列,最终的输出取决于前文和后文的信息。这种结构特别适用于需要全局上下文信息的任务,如命名实体识别和语音识别。

O1O2O3OTHbackward1Hbackward2Hbackward3¢¢¢HbackwardTHforward1Hforward2Hforward3¢¢¢HforwardTX1X2X3XT

RNNs 也存在挑战和限制,比如在长序列中,梯度可能会随着时间步的增加而指数衰减或爆炸,导致模型难以学习长期依赖关系记忆跨度有限。具体可以从反向传播的表达式中看出,对于单层的 RNNs,其反向传播的梯度链式法则为

hthk=i=k+1thihi1=i=k+1tWhhTdiag(σ(Whhhi1+Wxhxi+bh))\dfrac {h_t}{h_k}=\prod_{i=k+1}^{t}\dfrac {\partial h_i}{\partial h_{i-1}}=\prod_{i=k+1}^{t}W_{hh}^T\mathrm{diag}(\sigma'(W_{hh}h_{i-1}+W_{xh}x_i+b_h))

其中 σ\sigma 对内部线性组合的作用是逐一应用于每个元素上,因此其导数 σ\sigma' 也是一个对角矩阵。

σ[z1z2zn]=[σ(z1)σ(z2)σ(zn)]σ(z)z=diag(σ(z))=[σ(z1)000σ(z2)000σ(zn)]\sigma\begin{bmatrix}z_1 \\ z_2 \\ \vdots \\ z_n\end{bmatrix}=\begin{bmatrix}\sigma(z_1) \\ \sigma(z_2) \\ \vdots \\ \sigma(z_n)\end{bmatrix}\implies \dfrac {\partial \sigma(z)}{\partial z}=\mathrm{diag}(\sigma'(z))=\begin{bmatrix}\sigma'(z_1) & 0 & \cdots & 0 \\ 0 & \sigma'(z_2) & \cdots & 0 \\ \vdots & \vdots & \ddots & \vdots \\ 0 & 0 & \cdots & \sigma'(z_n)\end{bmatrix}

解决方案有以下几种:长短期记忆网络、门控循环单元、梯度裁剪和初始化策略等。

长短期记忆网络和门控循环单元通过引入门控机制(Gating Mechanisms)门控腔体(Gated Cells),有效地控制信息的流动和记忆,从而缓解了梯度消失和梯度爆炸问题,提升了模型对长期依赖关系的捕捉能力。

长短期记忆网络(Long Short-Term Memory, LSTM) 的架构为输入、遗忘和输出三个门控机制,分别控制信息的流入、保留和输出,保有一个称为细胞状态(Cell State) 的独立记忆单元。LSTM 强力,但是计算复杂度较高,训练时间较长。核心图表为

MemoryCt¡1Ct¡1¯FtsumCtIt¯~CttanhCtFtIt~CtOtHiddenHt¡1[Ht¡1;Xt]tanhCt¯OtHtInputXttanh¾¾tanh¾

LSTM 引入了细胞状态层,通过三个门控机制来输入序列的信息流动。当 XtX_tHt1H_{t-1} 进入 LSTM 单元时,首先通过遗忘门 FtF_t 决定保留多少先前的细胞状态 Ct1C_{t-1}(通过逐点相乘,遗忘,即减少不重要的分量的权重)。接着,输入门 ItI_t 控制当前输入信息 C~t\tilde{C}_t 的流入,流入的新信息和遗忘操作后的细胞状态相加,得到更新后的细胞状态 CtC_t,作用 tanh\tanh 后,通过逐点相乘调整最基本的输出门 OtO_t,最终得到当前隐藏状态 HtH_t

需要指出,σ\sigma 是 Sigmoid 激活函数,其值域在 0011 之间,tanh\tanh 是 Tanh 激活函数,其值域在 1-111 之间,\odot 是逐点相乘操作,a,b,ca,b,c 是权重矩阵。调用 Sigmoid 激活函数的门控机制可以将信息压缩到 0011 之间,是对信息的 “过滤” 过程,即是否保留信息,而调用 Tanh 激活函数则是对信息进行非线性变换,重新编码信息,两者逐点相乘后,起到调整信息强度的作用。具体细节可以表述为

Forget Gate:What to discard from the cell stateFt=σ(Wf[Ht1,Xt]+bf)Input Gate:What new information to storeIt=σ(Wi[Ht1,Xt]+bi)C~t=tanh(WC[Ht1,Xt]+bC)Cell State Update:Combine forget and input decisionsCt=FtCt1+ItC~tOutput Gate:What to output from the cell stateOt=σ(Wo[Ht1,Xt]+bo)Ht=Ottanh(Ct)\begin{array}{ll} \text{Forget Gate:} & \text{What to discard from the cell state} \\[6pt] &F_t=\sigma(W_f\cdot[H_{t-1},X_t]+b_f) \\[6pt] \text{Input Gate:} & \text{What new information to store} \\[6pt] & I_t=\sigma(W_i\cdot[H_{t-1},X_t]+b_i) \\[6pt] & \tilde C_t=\tanh(W_C\cdot[H_{t-1},X_t]+b_C) \\[6pt] \text{Cell State Update:} & \text{Combine forget and input decisions} \\[6pt] & C_t=F_t\odot C_{t-1}+I_t\odot \tilde C_t \\[6pt] \text{Output Gate:} & \text{What to output from the cell state} \\[6pt] & O_t=\sigma(W_o\cdot[H_{t-1},X_t]+b_o) \\[6pt] &H_t=O_t\odot \tanh(C_t) \end{array}

其中 [,][\cdot, \cdot ] 表示向量连接操作。其中,Wf,Wi,WC,WoW_f,W_i,W_C,W_o 是权重矩阵,bf,bi,bC,bob_f,b_i,b_C,b_o 是偏置项。

门控机制通过学习这些权重和偏置,动态地调整信息的流动,从而有效地捕捉长期依赖关系。LSTM 有效避免了传统 RNN 中的梯度消失问题,因为细胞状态通过线性路径传递信息。

Ct=FtCt1+ItC~tC_t=F_t\odot C_{t-1}+I_t\odot \tilde C_t

允许梯度在时间步之间更稳定地传播。

门控循环单元(Gated Recurrent Unit, GRU) 是 LSTM 的简化版本,结合了遗忘门和输入门为一个更新门(Update Gate) ZtZ_t,并引入重置门(Reset Gate) RtR_t 来控制过去信息的遗忘。不包含独立的细胞状态,而是直接在隐藏状态中进行信息的存储和更新。GRU 的架构为

Ht¡1GPUCellHtXt

具体而言,更新门控制当前隐藏状态中有多少信息需要从过去传递过来,并平衡新信息的引入,类似于 LSTM 的遗忘门和输入门的组合。重置门决定了多少过去的信息需要被遗忘,决定了当前和过去隐藏状态的关联性,有助于捕捉短期依赖关系。GRU 的计算过程如下:

# 转换器架构 (Transformers)

语言建模问题(Language Modeling) 是指给定上下文,预测下一个最可能的词语,比如

I swam across the river to get to the other_bank_I walked across the road to get cash from the_bank_\begin{array}{ll}\text{I swam across the river to get to the other } \_bank\_ \\ \\ \text{I walked across the road to get cash from the } \_bank\_\end{array}

这里可以看到存在技术挑战是:

  1. 长距离依赖关系:需要捕捉远距离词语关系;
  2. 多义性处理:相同词语在不同上下文的含义不同;
  3. 复杂逻辑:理解语法、常识和推理。

一旦有了语言模型,就可以生成人类语言。

语言模型的核心是计算条件概率

P(xnx1,x2,,xn1)P(x_n|x_1,x_2,\ldots,x_{n-1})

其中给定前 n1n-1 个词语,预测第 nn 个词语的概率分布。

比如考虑词汇表:

{I,can,do,it}\{\text{I},\text{can},\text{do},\text{it}\}

给定上下文 I can do\text{I can do},预测下一个词语的概率分布为

[P(itI,can,do)P(II,can,do)P(canI,can,do)P(doI,can,do)]=[0.70.10.10.1]\begin{bmatrix}P(\text{it }|\text{ I},\text{ can},\text{ do}) \\ P(\text{ I }|\text{ I},\text{ can},\text{ do}) \\ P(\text{ can }|\text{ I},\text{ can},\text{ do}) \\ P(\text{ do }|\text{ I},\text{ can},\text{ do})\end{bmatrix}=\begin{bmatrix}0.7 \\ 0.1 \\ 0.1 \\ 0.1\end{bmatrix}

模型将预测下一个词为 it\text{it},概率为 0.70.7,最高。

分词过程是将语句分解成词元(Tokens),然后将词元映射为数字表示的过程。

分词建立了自然语言和数字表示之间的桥梁,后者是语言模型可以处理的输入形式。词元可以是单词、子词或字符,具体取决于所使用的分词方法。

比特对齐编码(Byte Pair Encoding, BPE) 是一种常用的子词分词方法,通过迭代地合并最频繁出现的字符对来构建子词词汇表,从而有效地处理未登录词和减少词汇表大小。它的步骤是

  1. 初始化词汇表为所有单个字符;
  2. 统计训练语料中所有相邻字符对的频率;
  3. 合并频率最高(且字典序最小)的字符对,形成新的子词,并将其添加到词汇表中;
  4. 重复步骤 2 和 3,直到达到预定的词汇表大小或没有更多的字符对可以合并。

BPE 可以处理未登录词,紧凑地表示常见词语,可以跨语言使用。。它找到了在词层次和字符层次之间的平衡,既能捕捉词语的语义信息,又能处理未登录词。例如词缀 “un-”、“-ing” 可以作为子词单独存在。

例如,考虑以下训练语料:

low lower newest widest\text{low lower newest widest}

初始词汇表为所有单个字符:

{l,o,w,e,r,n,s,t,i,d}\{\text{l,o,w,e,r,n,s,t,i,d}\}

现在的语料被表示为字符序列:

l o w _ l o w e r _ n e w e s t _ w i d e s t\text{l o w \_ l o w e r \_ n e w e s t \_ w i d e s t}

接着统计相邻字符对的频率,发现最频繁且字典序最小的字符对为

(e,s)es(\text{e},\text{s})\rightarrow \text{es}

将其合并,更新词汇表为

{l,o,w,e,r,n,s,t,i,d,es}\{\text{l,o,w,e,r,n,s,t,i,d,es}\}

现在的语料被表示为

l o w _ l o w e r _ n e w es t _ w i d es t\text{l o w \_ l o w e r \_ n e w es t \_ w i d es t}

重复操作,下一个最频繁且字典序最小的字符对为

(es,t)est(\text{es},\text{t})\rightarrow \text{est}

更新词汇表为

{l,o,w,e,r,n,s,t,i,d,es,est}\{\text{l,o,w,e,r,n,s,t,i,d,es,est}\}

现在的语料被表示为

l o w _ l o w e r _ n e w est _ w i d est\text{l o w \_ l o w e r \_ n e w est \_ w i d est}

继续迭代,直到达到预定的词汇表大小或没有更多的字符对可以合并。最终得到的子词词汇表可以是

{l,o,w,e,r,n,s,t,i,d,es,est,lo,low,er,lower,newest,widest}\{\text{l,o,w,e,r,n,s,t,i,d,es,est,lo,low,er,lower,newest,widest}\}

最终的语料被表示为

low _ lower _ newest _ widest\text{low \_ lower \_ newest \_ widest}

这无法再合并了。

BPE 应用在最高频率的字符对上,具有贪心性质,不考虑全局最优,但是在实践中是高效的。

BPE 具有很多优势,诸如可以处理未登录词、紧凑地表示常见词语(减少词汇表大小)、可以跨语言使用(算法是一致的)、捕捉单词结构形态,以及能得到良好的词汇表大小(比单词级别更小,比字符级别更大)。同时也有许多局限,比如它采用贪心策略(可能无法捕捉全局最优的子词划分)、歧义(同一子词可能有多种划分方式)、过度分割、训练成本高(需要庞大的语料库进行统计),以及对不同语言的适应性有限(因为 BPE 是基于字符频率的,某些语言可能需要不同的分词策略)。

例如,对于语料 unhappiness\text{unhappiness},BPE 可能会将其分割为子词

un, happi, ness\text{un, happi, ness}

而不是更语义化的划分(其实 happy\text{happy} 没有出现,但是更符合语义)

un, happy, ness\text{un, happy, ness}

这可能会影响模型对词语含义的理解。

对单词进行标记(映射为数字 ID),但是问题在于整数标记无法表达语义关系,所以解决方案是将词元映射到高维向量空间。

embedding:NRd\mathrm{embedding}:\mathbb N\to \mathbb R^d

它具备可学习性(通过训练可以自动优化嵌入映射)、能通过分量捕捉语义关系(相似词语在向量空间中距离较近)、维度可调节(可以根据任务需求选择嵌入维度 dd 的大小)。

词嵌入(Embeddings) 是将离散的词元映射到连续的高维向量空间的技术。嵌入技术是将离散符号用稠密空间的连续向量表示出来。

嵌入通过功能被分为静态嵌入和上下文相关嵌入。现代嵌入方法通常是动态、上下文相关的嵌入,并且在子词级别进行嵌入。

例如,词嵌入映射将以下单词映入高维向量空间

king[0.25,0.1,0.3,,0.4]queen[0.2,0.15,0.25,,0.35]apple[0.1,0.4,0.2,,0.05]banana[0.15,0.35,0.25,,0.1]\begin{array}{ll}\text{king} & \rightarrow [0.25, 0.1, -0.3, \ldots , 0.4] \\[6pt] \text{queen} & \rightarrow [0.2, 0.15, -0.25, \ldots , 0.35] \\[6pt] \text{apple} & \rightarrow [-0.1, 0.4, 0.2, \ldots , -0.05] \\[6pt] \text{banana} & \rightarrow [-0.15, 0.35, 0.25, \ldots , -0.1]\end{array}

从这里可以看到,king\text{king}queen\text{queen} 的嵌入向量在空间中距离较近,反映了它们的语义相似性,而 apple\text{apple}banana\text{banana} 也表现出类似的关系。这个结果不是一开始就有的,而是通过训练数据学习,不断调整嵌入规则得到的。

词嵌入在 LLMs 中的工作原理是引入一个嵌入层(Embedding Layer),将输入的词元 ID 映射为对应的嵌入向量。

TokensVToken IDsEmbedding:=EEmbedding LayerDense Vectors\text{Tokens}\xrightarrow{V}\text{Token IDs}\xrightarrow{\text{Embedding}:=E}\text{Embedding Layer}\rightarrow\text{Dense Vectors}

其中映射 EE 是一个可学习的参数矩阵

ERV×d:VRdE\in \mathbb R^{V\times d}:\quad V\to \mathbb R^d

映射 VV 是词元到其对应整数 ID 的映射,这里也表示词汇表尺寸(即词元总数),dd 是嵌入维度。因为 Token IDs\text{Token IDs} 可以看作是一行索引

V:={token1,token2,,tokenV}{1,2,,V}NV:=\{\text{token}_1,\text{token}_2,\ldots,\text{token}_V\}\to \{1,2,\ldots,V\}\subseteq \mathbb N

EE 的每一行对应一个词元的嵌入向量:

E=[embedding(token1)embedding(token2)embedding(tokenV)]=[a11a12a1da21a22a2daV1aV2aVd]E=\begin{bmatrix}\text{embedding}(\text{token}_1) \\ \text{embedding}(\text{token}_2) \\ \vdots \\ \text{embedding}(\text{token}_V)\end{bmatrix}=\begin{bmatrix}a_{11} & a_{12} & \cdots & a_{1d} \\ a_{21} & a_{22} & \cdots & a_{2d} \\ \vdots & \vdots & \ddots & \vdots \\ a_{V1} & a_{V2} & \cdots & a_{Vd}\end{bmatrix}

注意,输入索引是从 11 开始的整数,因此嵌入层的查找操作可以表示为

embedding(tokeni)=(0,,0,1,0,,0)E=ai:\text{embedding}(\text{token}_i)=(0,\ldots,0,1,0,\ldots,0) E=a_{i:}

其中 (0,,0,1,0,,0)(0,\ldots,0,1,0,\ldots,0) 是一个独热编码向量。

通过训练,嵌入矩阵具有以下性质:语义相似的词元在嵌入空间中距离较近;

catdog\text{cat}\approx \text{dog}

类比性强,即嵌入空间的向量运算表示语义偏移

kingman+womanqueen\text{king}-\text{man}+\text{woman}\approx \text{queen}

上下文相关性,即得到嵌入空间后,通过后续加入网络层,可以根据上下文动态调整词元的表示(因为嵌入向量刻画了词元的多种语义特征,只需要在后续网络中学习如何组合这些特征即可);维数可调节,通常在 d[512,4096]d\in[512,4096] 之间选择,具体取决于任务复杂度和计算资源。

Word2Vec 是一种经典的词嵌入方法。它通过训练一个浅层神经网络来预测词语的上下文,从而调整词语的嵌入向量。Word2Vec 有两种主要的架构:连续词袋模型(Continuous Bag of Words, CBOW)跳字模型(Skip-Gram)。CBOW 通过上下文预测目标词语,而 Skip-Gram 则通过目标词语预测其上下文。它的优点是简单高效,能够捕捉词语的语义关系,不需要深度网络结构。

在这个方法下,学习 king\text{king}queen\text{queen} 的嵌入向量的相关性,是通过分析它们的上下文语境的相似性来实现的。

跳字模型的训练目标是给定目标词,预测其邻近的上下文区间内的词语。具体而言,给定上下文语料(句子):

The quick brown fox jumps\text{The quick brown fox jumps}

那么对于目标词 brown\text{brown},假设上下文窗口大小为 11,则其上下文词语为 quick\text{quick}fox\text{fox}。跳字模型希望在给出目标词时,能够预测出这些上下文词语,事实上就是在最大化以下目标函数:

t=1Tcjc,j0P(wordt+jwordt)\prod_{t=1}^{T}\prod_{-c\leq j\leq c,j\neq 0}P(\text{word}_{t+j}|\text{word}_t)

其中 cc 是上下文窗口大小,TT 是语料中词语的总数。例如对于句子

is it good or is it bad\text{is it good or is it bad}

当窗口大小为 11 时,目标函数为

Function:=[P(itis)][P(goodit)P(isit)][P(orgood)P(itgood)][P(isor)P(goodor)][P(itis)P(oris)][P(badit)P(isit)][P(itbad)]\begin{array}{ll}\mathrm{Function}:&=[P(\text{it}|\text{is})]\cdot[P(\text{good}|\text{it})\cdot P(\text{is}|\text{it})]\cdot [P(\text{or}|\text{good})\cdot P(\text{it}|\text{good})]\cdot \\ \\ &\quad [P(\text{is}|\text{or})\cdot P(\text{good}|\text{or})]\cdot [P(\text{it}|\text{is})\cdot P(\text{or}|\text{is})]\cdot [P(\text{bad}|\text{it})\cdot P(\text{is}|\text{it})]\cdot \\ \\ &\quad [P(\text{it}|\text{bad})]\end{array}

可以看出,函数里面的 P(isit)P(\text{is}|\text{it})P(itis)P(\text{it}|\text{is}) 都出现了两次。说明 is\text{is} 的附近可以猜测到 it\text{it},反之亦然。因此要最大化这个目标函数,就要让出现频次高的条件概率尽可能大(在整个语料中),这就是跳字模型的训练目标。

Context1InputWordHiddenLayerWinputContext2¢¢¢

在上图中,输入词语(查询)先独热编码,然后通过嵌入矩阵 WinputW_{\mathrm{input}} 映射到隐藏层(即嵌入空间上的一个向量),接着通过检测与其他词语的语义关联(即嵌入向量之间的内积)将其作为预测的依据,最终输出预测的上下文词语。通过这个过程,模型会不断调整嵌入矩阵 WinputW_{\mathrm{input}},使得语义相似的词语在嵌入空间中距离较近。

其中,预测依据是根据向量内积来计算的,需要查询的词对应的嵌入向量 v0v_0 和嵌入矩阵中所有词语的嵌入向量进行内积计算,得到一组实数 v0,vi\langle v_0,v_i\rangle,然后通过 Softmax 函数转化

P(viv0)=exp(v0,vi)j=1Vexp(v0,vj)P(v_i|v_0)=\dfrac {\exp(\langle v_0,v_i\rangle)}{\sum_{j=1}^{V}\exp(\langle v_0,v_j\rangle)}

即给定查询词语 v0v_0,预测上下文词语 viv_i 的概率分布。

CBOW 模型的训练目标是给定上下文词语,预测目标词语。具体而言,给定上下文语料(句子):

The quick brown fox jumps\text{The quick brown fox jumps}

给定上下文词语 The\text{The}brown\text{brown},CBOW 模型希望预测出目标词语 quick\text{quick}。我们认为,当训练足够理想时,语义可以通过向量平均来表达:

12(vThe+vbrown)vquick\dfrac 12(v_{\text{The}}+v_{\text{brown}})\approx v_{\text{quick}}

于是我们先计算左边,然后对照 vquickv_{\text{quick}} 的位置,调整嵌入矩阵 WinputW_{\mathrm{input}},使得上式的两者确实很接近。

注意,嵌入向量的分量不一定是有明确意义的,但向量之间的关系是有意义的。从某种程度上看,如果通过训练,模型学会了一个模式:词语的句子成分角色,那么至少可以合理解释向量相加的意义。比如在嵌入向量的一个分量上,5010050-100 通常表示冠词,120300120-300 通常表示形容词,100500100-500 通常表示名词,600700600-700 通常表示动词。那么对于上面的例子,不妨假设它们的嵌入向量在这些分量上的值分别为

vThe=[100,]vquick=[250,]vbrown=[300,]vfox=[450,]vjumps=[650,]\begin{array}{ll}v_{\text{The}} & =[100,\ldots] \\[6pt] v_{\text{quick}} & =[250,\ldots] \\[6pt] v_{\text{brown}} & =[300,\ldots]\\[6pt] v_{\text{fox}} & =[450,\ldots] \\[6pt] v_{\text{jumps}} & =[650,\ldots]\end{array}

那么取 vThev_{\text{The}}vbrownv_{\text{brown}} 的平均,对应分量确实落在形容词和名词的区间内,符合 quick\text{quick} 的句子成分角色。至少按照训练的语料,模型不会猜测目标为动词 jumps\text{jumps},因为它的嵌入向量在动词分量上远高于平均值。

这不过是一个形象的理解,而机器学习模型学到的模式可能更加复杂和抽象,这个分量并不具有所谓 “句子成分角色” 的明确意义。

这对应分布式语义基本假设:一个词的意义是由它周围的词决定的。

注意力机制(Attention Mechanism) 是一种模仿人类视觉注意力的机制,其核心思想是为每个词元计算与其他词元的关联权重:权重越大表示关系越重要,并且这个过程是自动学习的。基础的注意力机制是缩放点积注意力(Scaled Dot-Product Attention),其计算过程为

Attention(Q,K,V)=softmax(QKTdk)V\mathrm{Attention}(Q,K,V)=\mathrm{softmax}\left(\dfrac {QK^T}{\sqrt{d_k}}\right)V

其中 QRn×dkQ\in \mathbb R^{n\times d_k} 是查询矩阵,KRm×dkK\in \mathbb R^{m\times d_k} 是键矩阵,VRm×dvV\in \mathbb R^{m\times d_v} 是值矩阵,dkd_k 是键的维度,nn 是查询的数量,mm 是键值对的数量。键 - 值对(Key-Value Pairs) 的概念源自于信息检索系统,键负责记录信息的标签,而值则存储实际的信息内容。在注意力机制中,键和值分别对应输入序列中的词元表示,查询则是当前需要关注的词元表示。

注意力机制通过计算查询和键之间的相似度(点积),然后通过 Softmax 函数归一化,得到权重分布,最后加权求和值矩阵,得到最终的输出表示。其中 Softmax 是对行进行归一化操作。

引入键值对的优势是,可以灵活地调整关注的内容。对于一般的嵌入向量,它们本身是词元的一种键,但是维度是受到限制的,但通过映射到键上,就有丰富的组合。

比如对于 apple\text{apple} 这个词,它的嵌入向量可能包含了多个方面的信息,比如水果、手机、公司、颜色等,再通过一次线性变换(键映射),就可以将这些信息重新组合,形成多个不同的键,比如红色水果、科技公司等,这样一方面它可以在键的层次上更好区分红太阳和红苹果(因为在颜色、种类外多了一个红色水果的维度),另一方面可以强调苹果具有红色水果和科技公司两个属性。

而具体如何强调这两个属性,就是通过查询矩阵和键矩阵来放大这些维度的影响力的。

句子

I swam across the river to get to the other bank\text{I swam across the river to get to the other bank}

中,通过计算关联权重,最终应该得到对 bank\text{bank} 的权重表

Iswamacrosstherivertogettothe otherbank0.050.10.10.050.40.050.10.050.1\begin{array}{c|ccccccccc} & \text{I} & \text{swam} & \text{across} & \text{the} & \text{river} & \text{to} & \text{get} & \text{to} & \text{the other} \\ \hline \text{bank} & 0.05 & 0.1 & 0.1 & 0.05 & 0.4 & 0.05 & 0.1 & 0.05 & 0.1 \end{array}

可以看到,river\text{river}bank\text{bank} 的影响最大,说明模型学会了捕捉长距离依赖关系。

例如,考虑句子

I went to the bank\text{I went to the bank}

现在要计算 bank\text{bank} 的注意力,首先它的查询向量

qbank=embedding(bank)WQq_{\text{bank}}=\text{embedding}(\text{bank})W^Q

是嵌入向量通过一个查询权重矩阵 WQW^Q 映射得到的。接着,句子中每个词语的键和值向量分别为

ki=embedding(wordi)WK,vi=embedding(wordi)WVk_i=\text{embedding}(\text{word}_i)W^K,\quad v_i=\text{embedding}(\text{word}_i)W^V

其中 WKW^KWVW^V 分别是键和值的权重矩阵。然后计算查询向量和每个键向量的点积,得到相似度分数

scorei=qbank,ki\mathrm{score}_i=\langle q_{\text{bank}},k_i\rangle

接着通过缩放和 Softmax 函数,得到注意力权重

αi=exp(scorei/dk)jexp(scorej/dk)\alpha_i=\dfrac {\exp(\mathrm{score}_i/\sqrt{d_k})}{\sum_{j}\exp(\mathrm{score}_j/\sqrt{d_k})}

最后,通过加权求和值向量,得到最终的注意力输出

Attentionbank=Outputbank=iαivi\mathrm{Attention}_{\text{bank}}=\mathrm{Output}_{\text{bank}}=\sum_{i}\alpha_i v_i

其中,bank\text{bank} 作为一个词元,其嵌入向量是任意初始化的,通过训练不断调整嵌入矩阵和权重矩阵 WQ,WK,WVW^Q,W^K,W^V,使得嵌入矩阵能将语义相近的词元映射到相近的向量空间位置,权重矩阵能调整注意力机制,比如给出 bank\text{bank} 这个词元时,合适的嵌入矩阵可以将它的向量位置调整到靠近与金融相关的词元(如 money\text{money}account\text{account})的位置,而实际上 bank\text{bank} 也可能靠近与河岸相关的词元(如 river\text{river}water\text{water})。但合适的权重矩阵 WQ,WK,WVW^Q,W^K,W^V 可以调整注意力机制,WQW^Q 可以让 bank\text{bank} 的查询向量更关注与金融相关和河岸相关的键(即分量或分量的组合),WKW^K 可以让词汇库中与金融相关和河岸相关的词元的键向量更容易与 bank\text{bank} 的查询向量匹配,WVW^V 随着嵌入矩阵(输入方式)的调整,也要调整(输出内容),使得后面的网络层能更好地利用这些信息。

即注意力机制一方面通过嵌入矩阵调整模型对词语自身含义的理解,另一方面还留意了它在上下文比较中应当关注哪些方面的信息,这两者结合起来,才能更好地捕捉词语的多义性和长距离依赖关系。

查询、键和值同源,即它们都是由同一个嵌入矩阵映射得到的,只不过通过不同的权重矩阵 WQ,WK,WVW^Q,W^K,W^V 进行了线性变换,从而调整了它们在注意力计算中的角色和功能。

Q=XWQ,K=XWK,V=XWVQ=XW^Q,\quad K=XW^K,\quad V=XW^V

这样的注意力计算被称为自注意力(Self-Attention)。不同源的查询、键和值则被称为交叉注意力(Cross-Attention),例如在机器翻译中,查询可能来自目标语言的嵌入表示,而键和值则来自源语言的嵌入表示。

缩放因子 dk\sqrt{d_k} 的引入是为了防止点积结果过大,导致 Softmax 函数的梯度过小,从而影响模型的训练效果。因为当 dkd_k 较大时,点积的方差也会增大,可能导致 Softmax 输出过于平坦或过于尖锐,影响注意力权重的分布。

注意力机制的优势在于并行计算(不像 RNN 需要逐步处理序列,可以同时计算所有词元的注意力),在多头注意力(Multi-Head Attention) 中,就可以通过多个注意力头并行计算,捕捉不同子空间的语义关系,从而增强模型的表达能力。我们已经知道 WQ,WK,WVW^Q,W^K,W^V 可以用来调整模型对词语含义的理解和关注重点,那么多头注意力就是通过多个不同的 WiQ,WiK,WiVW_i^Q,W_i^K,W_i^V,来让模型从多个角度理解词语的含义。

Qi=XWiQWiQRdmodel×dkKi=XWiKWiKRdmodel×dkVi=XWiVWiVRdmodel×dv\begin{array}{ll}Q_i=XW^Q_i &W_i^Q\in \mathbb R^{d_{\mathrm{model}}\times d_k} \\[6pt]K_i=XW^K_i &W_i^K\in \mathbb R^{d_{\mathrm{model}}\times d_k} \\[6pt]V_i=XW^V_i &W_i^V\in \mathbb R^{d_{\mathrm{model}}\times d_v}\end{array}

其中 i{1,2,,h}i\in\{1,2,\ldots,h\}hh 是注意力头的数量。每个头独立计算注意力输出

headi=Attention(Qi,Ki,Vi)\mathrm{head}_i=\mathrm{Attention}(Q_i,K_i,V_i)

最后将所有头的输出拼接,并通过一个线性变换得到最终输出

MultiHead(Q,K,V)=Concat(head1,head2,,headh)WO\mathrm{MultiHead}(Q,K,V)=\mathrm{Concat}(\mathrm{head}_1,\mathrm{head}_2,\ldots,\mathrm{head}_h)W^O

其中 WORhdv×dmodelW^O\in \mathbb R^{hd_v\times d_{\mathrm{model}}} 是输出权重矩阵,拼接 Concat()\mathrm{Concat}(\cdot) 是将多个头的输出在特征维度上连接起来(从左到右依次排列对齐)

Concat(head1,head2)=[head1head2]\mathrm{Concat}(\mathrm{head}_1,\mathrm{head}_2)=\begin{bmatrix}\mathrm{head}_1 & \mathrm{head}_2\end{bmatrix}

多头注意力的行为和 CNN 中的多通道卷积类似。

通常分为 88 头或 1616 头,具体取决于模型规模和计算资源。其中

dk=dv=dmodelhd_k=d_v=\dfrac {d_{\mathrm{model}}}h

计算复杂度为 O(n2dmodel)O(n^2\cdot d_{\mathrm{model}}),与单头注意力相同,但能捕捉更多样化的语义关系。多头注意力的参数数量为

h(dmodeldk+dmodeldk+dmodeldv)+(hdvdmodel)h\cdot (d_{\mathrm{model}}\cdot d_k + d_{\mathrm{model}}\cdot d_k + d_{\mathrm{model}}\cdot d_v) + (hd_v\cdot d_{\mathrm{model}})

即每个头的 WiQ,WiK,WiVW_i^Q,W_i^K,W_i^V 和输出权重矩阵 WOW^O 的参数总和。

虽然多头注意力的每一个头用到的键的维度降低了,但是需要指出其实总键数量并没有减少,只不过它们被分为了多类,每一类用不同的权重分配来强调不同的语义关系模式。准确度变高了。

当然,多头注意力会出现一些问题,比如头部冗余(Head Redundancy),即多个注意力头可能学习到相似的模式,导致资源浪费。为了解决这个问题,可以引入正则化技术,鼓励不同头之间的多样性,或者在训练过程中动态调整头的数量。相关的想法在混合专家模型(Mixture of Experts, MoE) 中也有体现。

可以指出的是,可以通过检测梯度下降的方向、相似性来衡量头部冗余;通过损失函数下降的速度来衡量训练效率。

# 图神经网络 (GNNs)

传统神经网络假设数据的形式是序列网格的,例如 CNNs 在处理图像就是基于像素的二维网格结构,而 RNNs 则是处理一维的时间序列数据。然而,许多现实世界的数据具有更复杂的结构,比如社交网络、分子结构、交通网络等,这些数据可以自然地表示为图。

图(Graphs) 由节点(顶点)、边(连接)构成,点表示实体,边表示实体间的关系。图可以是有向的或无向的,可以包含权重,表示关系的强度。图神经网络(Graph Neural Networks, GNNs) 通过在图结构上进行信息传播和聚合,学习节点和图的表示。

例如,论文的影响因子表明,内容固然重要,但引用关系也很重要。

GNNs 的核心假设是节点是由其邻居节点决定的,即一个节点的表示不仅取决于它自身的特征,还取决于其邻居节点的特征。它强调通过关系来学习节点的表示。