L大语言模型从理论到实践
阅读 PDF ↗
CHAPTER 03

神经网络基础

神经网络把仿射变换与非线性组合为可训练函数。本章先快速串联神经元、激活函数、损失、Softmax、梯度下降、反向传播和训练循环,再用张量与自动微分说明这些步骤如何可靠地落到批量计算上。一个损失函数即使在统计意义上合理,如果计算时交换了样本轴与特征轴、遗漏了共享参数的梯度,仍然会得到错误的训练过程。

本章采用行向量批处理约定,从线性映射出发建立矩阵微分,再将链式法则组织成计算图。随后推导分类损失、广播和嵌入查表的反向计算,并完成一个可以逐项复核的两层网络例题。这里讨论的是梯度如何正确产生;如何选择更新方向、学习率和正则化,属于第17章《优化及泛化》中的优化问题。

3.1前馈神经网络

神经元计算

一个人工神经元先计算输入的加权和,再通过激活函数得到输出:

\[ z=w^{\mathsf T}x+b,\qquad a=\phi(z). \tag{3.1}\]

\(w\) 决定各输入对结果的作用,\(b\) 调整激活阈值,\(\phi\) 提供非线性。把多个神经元并排写成矩阵形式,便得到一层网络 \(A=\phi(XW+b)\)。层数增加并不改变这一基本单元,只是让前一层的输出成为后一层的输入。

常见激活函数包括 ReLU、Sigmoid 和双曲正切:

\[ \operatorname{ReLU}(z)=\max(0,z),\qquad \sigma(z)=\frac{1}{1+e^{-z}},\qquad \tanh(z)=\frac{e^z-e^{-z}}{e^z+e^{-z}}. \tag{3.2}\]

ReLU 计算简单,正区间梯度不衰减;Sigmoid 将数值压到 \((0,1)\),适合表示二元概率;\(\tanh\) 输出以零为中心。Sigmoid 和 \(\tanh\) 在绝对值较大时导数接近零,深层或长序列中容易出现梯度消失。激活函数的选择既改变表达能力,也改变梯度传播。

标量损失目标

网络输出必须通过损失函数与目标比较。回归常用均方误差

\[ \mathcal L_{\mathrm{MSE}}=\frac{1}{B}\sum_{i=1}^{B}(\hat y_i-y_i)^2. \tag{3.3}\]

互斥多分类先用 Softmax 把分数 \(u_j\) 变成概率,再用交叉熵评价目标类别:

\[ q_j=\frac{e^{u_j}}{\sum_{k=1}^{C}e^{u_k}},\qquad \ell=-\sum_{j=1}^{C}y_j\log q_j. \tag{3.4}\]

Softmax 的各输出共享同一个分母,所以类别概率相互耦合。它适合“只能选一个类别”的任务;多标签任务通常对各标签分别使用 Sigmoid。实际计算交叉熵时应直接使用原始分数的稳定实现,避免先算极小概率再取对数。

3.2训练、梯度下降及反向传播

训练的目标是寻找使训练目标较小的参数 \(\theta\)。最基本的梯度下降更新为

\[ \theta_{t+1}=\theta_t-\eta\nabla_\theta\mathcal L(\theta_t), \tag{3.5}\]

其中 \(\eta\) 是学习率。学习率过小会使训练缓慢,过大可能越过低损失区域而振荡或发散。小批量训练用一部分样本估计梯度,降低单步成本,也引入抽样噪声。

一次训练迭代包含五个阶段:取出一个批次;执行前向传播;计算标量损失;反向传播得到所有参数的梯度;由优化器统一更新参数。反向传播只负责求梯度,梯度下降或 Adam 等优化器负责如何更新,两者不能混为一谈。更新之前还应清楚梯度是按样本求和还是求平均,是否跨多个批次累积。

训练集损失下降说明优化正在拟合训练数据,不等同于模型对新数据有效。验证集用于选择超参数和训练停止点,测试集用于最后评估;若测试信息参与选择,它就不再是独立测试。更完整的学习率、初始化、正则化和泛化问题见第17章《优化及泛化》

3.3张量、形状及线性映射

形状表达计算对象的语义

在本书的计算语境中,张量(tensor)指带有若干索引轴的数值数组。标量没有轴,向量有一个轴,矩阵有两个轴。三维张量 \(X\in\Real^{B\times T\times d}\) 可以表示 \(B\) 个样本、每个样本 \(T\) 个位置、每个位置 \(d\) 个特征。\(X_{itj}\) 则是第 \(i\) 个样本在第 \(t\) 个位置的第 \(j\) 个特征。 1 形状只给出各轴的长度,轴的语义还需要文字约定。两个形状同为 \(B\times B\) 的矩阵,一个可能描述样本之间的相似度,另一个可能只是特征维数碰巧等于批量大小;形状相同不意味着含义相同。

本章主要讨论二维批处理,并使用下列符号。单个向量在定义梯度和雅可比时视为列向量;批量矩阵中每个样本按行存放。两种约定之间通过转置明确转换。

符号 含义 形状或范围
\(B,d,h,C\) 批量大小、输入宽度、隐藏宽度、类别数 正整数
\(X\) 批量输入,每行一个样本 \(B\times d\)
\(W_1,b_1\) 第一层权重和偏置 \(d\times h,\ h\)
\(Z,A\) 隐藏层预激活和激活 \(B\times h\)
\(W_2,b_2\) 第二层权重和偏置 \(h\times C,\ C\)
\(U,Q,Y\) 分类分数、预测概率和目标分布 \(B\times C\)
\(\mathcal L\) 批量平均损失 标量
\(\overline R\) 损失对中间量 \(R\) 的梯度 \(R\) 同形
\(\mathbf1_B\) 元素全为一的列向量 \(B\)

矩阵乘法的公共轴归约

\(X\in\Real^{B\times d}\)\(W\in\Real^{d\times h}\),则线性映射 \(Z=XW\) 的分量形式为

\[ Z_{ij}=\sum_{k=1}^{d}X_{ik}W_{kj},\qquad Z\in\Real^{B\times h}. \tag{3.6}\]

这里被求和的 \(k\) 是输入特征轴;样本轴 \(i\) 与输出特征轴 \(j\) 得以保留。对每个样本使用同一个 \(W\),意味着参数在样本之间共享,而不是为每一行分配一套权重。

若加入偏置 \(b\in\Real^h\),仿射映射为

\[ Z=XW+\mathbf1_Bb^{\mathsf T},\qquad Z_{ij}=\sum_kX_{ik}W_{kj}+b_j. \tag{3.7}\]

偏置平移输出,因此严格说包含偏置的层是仿射层。习惯上所称的线性层常包含这项平移,推导时应保留它的独立梯度。

矩阵乘法不同于逐元素乘法。\(A\odot D\) 要求元素一一对应,或先按明确规则广播;\(AD\) 则沿一个公共轴收缩。将 \(XW\) 误写成逐元素运算,可能直接触发形状错误,也可能因特殊尺寸而得到合法却完全不同的函数。核对分量公式可以识别后一种隐蔽错误。

序列上的共享线性层可以写为

\[ Z_{itj}=\sum_{k=1}^{d}X_{itk}W_{kj}+b_j, \qquad Z\in\Real^{B\times T\times h}. \tag{3.8}\]

它只变换最后一个特征轴,不混合不同位置。暂时将前两个轴合并为 \(BT\) 行,是执行同一计算的一种方式,前提是恢复形状时保留位置与样本的对应关系。

转置、重排及存储布局

转置 \(X^{\mathsf T}\) 交换矩阵的两个索引:\((X^{\mathsf T})_{ji}=X_{ij}\)。重塑形状则按约定的元素顺序重新分组。将一个 \(2\times3\) 数组直接重塑为 \(3\times2\),通常不等于转置;前者不自动把行索引变成列索引。在多头注意力等运算中,重排轴与合并轴必须分别说明,否则即使元素总数不变,位置之间的关系也可能被破坏。

数学上的形状还应与物理存储区分。某些重排可由索引步长描述,不必立即复制数据;另一些后续运算会要求重新组织连续存储。两种实现可能计算同一函数,却具有不同的数据搬运代价。本章首先保证语义正确,存储带宽和算子效率将在算力与推理部分讨论。

3.4矩阵梯度

梯度刻画标量函数的一阶变化

对于可微函数 \(\mathcal L:\Real^n\to\Real\),在 \(x\) 附近有

\[ \mathcal L(x+\Delta x)=\mathcal L(x) +\nabla_x\mathcal L^{\mathsf T}\Delta x+o(\|\Delta x\|). \tag{3.9}\]

梯度的第 \(j\) 个分量是 \(\frac{\partial\mathcal L}{\partial x_j}\)。该展开中的线性项常记为全微分 \(\dif\mathcal L=\nabla_x\mathcal L^{\mathsf T}\dif x\)。它描述任意微小扰动的损失变化,而不仅是沿某一个坐标的变化。

对矩阵 \(X\),将各元素的贡献相加,得到

\[ \dif\mathcal L=\sum_{i,j}\overline X_{ij}\dif X_{ij} =\langle\overline X,\dif X\rangle_F =\operatorname{tr}(\overline X^{\mathsf T}\dif X). \tag{3.10}\]

其中 \(\langle A,B\rangle_F=\sum_{ij}A_{ij}B_{ij}\) 是 Frobenius 内积,\(\operatorname{tr}\) 表示方阵对角元素之和。式(3.10)定义了与 \(X\) 同形的矩阵梯度;不必把矩阵展平后再写一个高阶导数数组。

例如,\(\mathcal L=\frac12\|X\|_F^2=\frac12\sum_{ij}X_{ij}^2\),故 \(\dif\mathcal L=\sum_{ij}X_{ij}\dif X_{ij}\),于是 \(\overline X=X\)。若系数 \(\frac{1}{2}\) 被省略,梯度变成 \(2X\)。这类常数不会改变单独最小化该项的极小点,却会改变与其他损失项组合时的相对尺度。

线性层梯度的推导

\(Z=XW+\mathbf1_Bb^{\mathsf T}\),上游已经给出 \(G=\overline Z\in\Real^{B\times h}\)。在一次微分中,三个输入分别产生

\[ \dif Z=(\dif X)W+X(\dif W)+\mathbf1_B(\dif b)^{\mathsf T}. \tag{3.11}\]

代入矩阵内积,并利用迹在维数相容时的循环性质,可得

\begin{align} \dif\mathcal L &=\operatorname{tr}\!\left(G^{\mathsf T}(\dif X)W\right) +\operatorname{tr}\!\left(G^{\mathsf T}X(\dif W)\right) +\operatorname{tr}\!\left(G^{\mathsf T}\mathbf1_B(\dif b)^{\mathsf T}\right)\tag{3.12}\\ &=\operatorname{tr}\!\left((GW^{\mathsf T})^{\mathsf T}\dif X\right) +\operatorname{tr}\!\left((X^{\mathsf T}G)^{\mathsf T}\dif W\right) +(G^{\mathsf T}\mathbf1_B)^{\mathsf T}\dif b. \tag{3.13}\end{align}

与梯度的定义逐项比较,得到

\[ \boxed{\overline X=GW^{\mathsf T},\qquad \overline W=X^{\mathsf T}G,\qquad \overline b=G^{\mathsf T}\mathbf1_B.} \tag{3.14}\]

这三个式子分别回答:误差如何传回输入、各样本如何共同调整权重,以及共享偏置如何接收整批样本的影响。

也可以用索引检查权重梯度。由于 \(\frac{\partial Z_{ij}}{\partial W_{kr}}=X_{ik}\mathbf1[j=r]\),链式法则给出

\[ \frac{\partial\mathcal L}{\partial W_{kr}} =\sum_{i,j}G_{ij}X_{ik}\mathbf1[j=r] =\sum_iX_{ik}G_{ir}=(X^{\mathsf T}G)_{kr}. \tag{3.15}\]

求和不是一种额外的经验处理,而是共享参数影响多个输出所必需的结果。梯度形状也随之确定:\(GW^{\mathsf T}\)\(B\times d\)\(X^{\mathsf T}G\)\(d\times h\)\(G^{\mathsf T}\mathbf1_B\)\(h\)

逐元素非线性及不可微点

\(A_{ij}=\phi(Z_{ij})\),各输出仅依赖对应输入,故

\[ \overline Z=\overline A\odot\phi'(Z). \tag{3.16}\]

整流线性单元(Rectified Linear Unit,ReLU)为 \(\phi(z)=\max(0,z)\)。在 \(z>0\) 时导数为一,在 \(z<0\) 时为零。因此正区间直接传递梯度,负区间阻断经过该节点的局部梯度;在零点不存在通常意义下的唯一导数。 2

如果两个仿射层之间没有非线性,则 \((XW_1+\mathbf1_Bb_1^{\mathsf T})W_2+\mathbf1_Bb_2^{\mathsf T}\) 仍可合并为一个仿射映射。非线性使不同输入区域具有不同的有效映射,是两层网络超出单层表达形式的关键。其反向代价则是梯度要乘以依赖前向状态的局部导数,因而需要保存或重新计算该状态。

3.5计算图及自动微分

链式法则的依赖结构

\(z=f(x)\in\Real^m\)\(x\in\Real^n\)。雅可比矩阵(Jacobian matrix)定义为 \(J_f\in\Real^{m\times n}\),其中 \((J_f)_{ij}=\frac{\partial z_i}{\partial x_j}\)。微分满足 \(\dif z=J_f\dif x\)。若 \(\mathcal L=g(z)\),则

\[ \dif\mathcal L=\overline z^{\mathsf T}J_f\dif x, \qquad \overline x=J_f^{\mathsf T}\overline z. \tag{3.17}\]

正向计算把输入映射到输出;反向计算把输出上的损失敏感度映射回输入。后者对应向量雅可比积(Vector–Jacobian Product,VJP):行向量形式为 \(\overline z^{\mathsf T}J_f\),本章使用其转置 \(J_f^{\mathsf T}\overline z\) 表示列梯度。它通常不必显式形成整个雅可比。

计算图把基本运算表示为节点,把依赖表示为有向边。对于无循环的计算图,可按拓扑顺序求出前向值,再按相反顺序应用式(3.17)。即使模型包含循环结构,有限次展开的一次执行也可以表达为这样的依赖序列。

一个变量若经由两条路径影响损失,两条路径的贡献必须相加。考虑 \(a=x^2\)\(b=3x\)\(\mathcal L=ab\)。前向在 \(x=2\) 时得到 \(a=4\)\(b=6\)\(\mathcal L=24\);反向先得到 \(\overline a=b=6\)\(\overline b=a=4\),再得到

\[ \overline x=\overline a(2x)+\overline b\,3 =6\times4+4\times3=36. \tag{3.18}\]

直接对 \(3x^3\) 求导同样得到 \(9x^2=36\)。若仅保留最后一条路径,结果便会错误地变成 \(12\)。权重共享、残差连接和重复嵌入编号都遵循同一条累加原则。

共享输入的计算图。实线表示前向依赖,虚线表示从乘法节点返回的梯度。
图 3.1 共享输入的计算图。实线表示前向依赖,虚线表示从乘法节点返回的梯度。

正向模式及反向模式

自动微分按照基本运算的导数规则,对实际执行的组合函数计算导数。它与把表达式化简成一个符号公式不同,也不通过微小扰动近似导数。除基本运算与浮点计算本身的误差外,链式法则不引入有限差分那样的步长截断误差。

正向模式给定输入方向 \(v\),随前向传播计算 \(J_fv\);反向模式给定输出权重 \(w\),从后向前计算 \(J_f^{\mathsf T}w\)。如果一个函数具有大量参数而只有一个标量损失,反向模式以输出端种子 \(\overline{\mathcal L}=1\) 开始,一次反向遍历即可得到所有参数的梯度。逐坐标使用正向模式则通常需要多次遍历。因此,标量训练目标特别适合反向模式。若输入方向很少、需要多个输出的方向响应,正向模式也有价值。

反向模式并非没有成本。局部梯度往往依赖前向中间量,例如线性层需要 \(X\),ReLU 需要知道 \(Z\) 的符号。这些量可以保存在计算过程中,也可以在反向时重新计算。保存占用内存,重算消耗计算,二者的取舍构成后续激活重计算方法的基础。

梯度计算及参数更新

在一次前向和反向之间,参数以及反向所需的中间量必须保持一致。若计算 \(\overline W_2\) 后立刻更新 \(W_2\),再使用更新后的 \(W_2\) 计算隐藏层梯度,那么该梯度已经不再对应原来的前向函数。正确过程是完成当前损失的全部反向计算,再进行参数更新。

对于多个小批量,梯度既可以在每批后清除,也可以有意累加。但累加的归一化必须与目标一致:两个批次分别含 \(B_1,B_2\) 个有效样本时,总体平均梯度为

\[ g=\frac{B_1g_1+B_2g_2}{B_1+B_2}, \tag{3.19}\]

其中 \(g_1,g_2\) 是各自的平均梯度。简单平均两个批次的平均梯度,仅在两批大小相等或目标确实赋予每批相等权重时成立。

计算图中的切断梯度会保留某个数值却改变对其来源的求导关系。离散索引选择、阈值决策、随机采样也不能不加说明地按光滑函数处理。训练模式和是否记录梯度同样是两个问题:随机失活等机制影响前向函数,梯度记录则决定是否保存求导依赖。关闭梯度记录不会自动把随机训练函数变成确定性的评估函数。

算法3.1 标量损失的反向自动微分

输入:有限无环计算图、输入与固定参数,各节点的前向运算及局部反向规则。输出:损失对各可训练参数的梯度。

  1. 按拓扑顺序执行前向计算,保存局部求导所需状态,得到标量损失 \(\mathcal L\)

  2. 将所有节点的伴随量初始化为零,并令 \(\overline{\mathcal L}=1\)

  3. 按逆拓扑顺序访问每个节点 \(v=f(u_1,\ldots,u_k)\)。对每条输入边,执行 \(\overline u_i\leftarrow\overline u_i+J_{f,u_i}^{\mathsf T}\overline v\);重复引用同一节点时仍逐条累加。

  4. 返回参数节点的伴随量。完成全部反向计算后,优化器才可更新参数。

不变量:访问某节点时,其所有后继已将经过各自路径的贡献累加到该节点。若单个基本运算的反向成本与前向同阶,总算术成本与计算图执行成本同阶;保存中间状态的内存另计。不可微点采用已声明的求导约定。

3.6分类损失的导数及数值稳定性

Softmax 的雅可比

设单个样本的分数列向量为 \(u\in\Real^C\),其第 \(j\) 类概率为

\[ q_j=\frac{\exp(u_j)}{S},\qquad S=\sum_{k=1}^{C}\exp(u_k). \tag{3.20}\]

分子在 \(j=r\) 时依赖 \(u_r\),分母在所有情况下都依赖 \(u_r\)。同时求导,得到

\begin{align} \frac{\partial q_j}{\partial u_r} &=\frac{\mathbf1[j=r]\exp(u_j)S-\exp(u_j)\exp(u_r)}{S^2}\tag{3.21}\\ &=q_j\bigl(\mathbf1[j=r]-q_r\bigr). \tag{3.22}\end{align}

因此对角元素为 \(q_j(1-q_j)\),非对角元素为 \(-q_jq_r\),矩阵形式为

\[ J_{\softmax}=\operatorname{diag}(q)-qq^{\mathsf T}. \tag{3.23}\]

非对角项体现类别之间的竞争:一个分数升高时,其他类别概率会因公共分母增大而下降。只保留对角项会遗漏这种耦合。

给定概率端的梯度 \(g=\overline q\),式(3.23)\(g\) 的乘积可以写为

\[ \overline u=q\odot\left(g-(q^{\mathsf T}g)\mathbf1_C\right). \tag{3.24}\]

显式雅可比需要 \(C^2\) 个元素,而这个向量形式只需要长度为 \(C\) 的数组及一次内积。公式相同不意味着必须采用同样的存储方式。

由于 \(J_{\softmax}\mathbf1_C=0\),沿所有分数同时增加相同常数的方向,概率不变。这也可由 \(\softmax(u+c\mathbf1_C)=\softmax(u)\) 直接验证。对归一化交叉熵,其分数梯度各分量之和为零,正是同一不变性的另一种表现。

交叉熵梯度化简

设目标分布 \(y_j\ge0\)\(\sum_jy_j=1\),交叉熵为 \(\ell=-\sum_jy_j\log q_j\)。先对概率求导,再代入 Softmax 雅可比:

\begin{align} \frac{\partial\ell}{\partial u_r} &=\sum_j\left(-\frac{y_j}{q_j}\right) q_j\bigl(\mathbf1[j=r]-q_r\bigr)\tag{3.25}\\ &=-y_r+q_r\sum_jy_j=q_r-y_r. \tag{3.26}\end{align}

因此,对 \(B\) 个样本取平均并沿类别轴归一化时,\(\overline U=\frac{Q-Y}{B}\)。独热标签是 \(Y\) 的特例;软标签只要保持非负且行和为一,也满足相同公式。

若目标权重之和为 \(s\ne1\),梯度实际为 \(sq-y\),不能继续机械使用 \(q-y\)。例如多标签向量可以同时含多个一,其语义是多个二元事件,通常不应强行放入互斥类别的归一化模型。这说明损失的张量形状相同,也不保证任务定义相同。

分数空间损失

对独热目标类别 \(k\),交叉熵可以直接写为

\[ \ell(u,k)=-u_k+\log\sum_j e^{u_j}. \tag{3.27}\]

\(m=\max_j u_j\),利用指数的公共因子得到

\[ \log\sum_j e^{u_j}=m+\log\sum_j e^{u_j-m}. \tag{3.28}\]

右侧指数的自变量均不大于零,且至少一个等于零,从而避免直接计算巨大正分数的指数。对于有限分数,数学上的 Softmax 概率严格为正;浮点计算却可能将极小概率舍入为零。若先形成概率再取对数,就可能得到无穷损失;直接使用式(3.28)可以避免这条不稳定路径。

例如 \(u=(1000,999)\),直接计算 \(e^{1000}\) 可能溢出,减去最大值后只需计算 \((1,e^{-1})\)。两种写法在实数算术中等价,数值可靠性却不同。稳定变换也不能修复输入本身已经包含的非有限值;对异常输入仍应追溯其上游来源。

二分类及多标签的对应关系

二分类用一个分数 \(z\) 表示正类相对于负类的对数几率,通过 \(\sigma(z)=\frac{1}{1+e^{-z}}\) 得到正类概率。对目标 \(y\in[0,1]\),二元交叉熵为

\begin{align} \ell(z,y)&=-y\log\sigma(z)-(1-y)\log(1-\sigma(z))\tag{3.29}\\ &=\log(1+e^z)-yz\tag{3.30}\\ &=\max(z,0)-yz+\log(1+e^{-|z|}). \tag{3.31}\end{align}

最后一式给出稳定的计算形式。由中间一式求导可得

\[ \frac{\partial\ell}{\partial z}=\frac{e^z}{1+e^z}-y=\sigma(z)-y. \tag{3.32}\]

把两类 Softmax 分数设为 \((0,z)\),恰好得到相同的概率和损失,因此二者的梯度结果是一致的。多标签任务则对每个类别分别构造这样的二元损失,不要求各类别概率之和为一。

模型输出原始分数之后,应将其交给包含该稳定变换的损失计算。若先进行一次 Sigmoid,再把所得概率当成分数传入同类损失,相当于优化另一个复合函数,既改变预测范围,也改变梯度。是否已经执行概率变换应由公式判断,而不是仅凭变量名称判断。

考虑两层感知机(Multilayer Perceptron,MLP):

\[ Z=XW_1+\mathbf1_Bb_1^{\mathsf T},\quad A=\operatorname{ReLU}(Z),\quad U=AW_2+\mathbf1_Bb_2^{\mathsf T},\quad Q=\softmax(U). \tag{3.33}\]

\(B=d=h=C=2\),给定

\[ X=\begin{bmatrix}1&2\\-2&1\end{bmatrix},\quad W_1=\begin{bmatrix}1&-1\\1&1\end{bmatrix},\quad W_2=\begin{bmatrix}\frac{1}{2}&-\frac{1}{2}\\-\frac{1}{2}&\frac{1}{2}\end{bmatrix}, \quad b_1=b_2=\begin{bmatrix}0\\0\end{bmatrix}. \tag{3.34}\]

第一个样本属于第1类,第二个样本属于第2类,故目标矩阵 \(Y=I_2\)。这里的参数特意取为便于手算的数值,例题检验的是计算过程,不代表经过训练的模型。

逐步相乘得到

\begin{align} Z&=\begin{bmatrix}1+2&-1+2\\-2+1&2+1\end{bmatrix} =\begin{bmatrix}3&1\\-1&3\end{bmatrix},\tag{3.35}\\ A&=\begin{bmatrix}3&1\\0&3\end{bmatrix},\qquad U=\begin{bmatrix}1&-1\\-\frac{3}{2}&\frac{3}{2}\end{bmatrix}. \tag{3.36}\end{align}

第二个样本的第一隐藏单元处在 ReLU 负区间,因此输出为零。定义 \(a=(1+e^2)^{-1}\approx0.119203\)\(b=(1+e^3)^{-1}\approx0.047426\),则

\[ Q=\begin{bmatrix}1-a&a\\b&1-b\end{bmatrix} \approx\begin{bmatrix}0.880797&0.119203\\0.047426&0.952574\end{bmatrix}. \tag{3.37}\]

取批量平均交叉熵,有

\[ \mathcal L=-\frac12\bigl(\log(1-a)+\log(1-b)\bigr) =\frac12\bigl(\log(1+e^{-2})+\log(1+e^{-3})\bigr) \approx0.087758. \tag{3.38}\]

至此,损失值、所有中间量和参数均来自同一次前向计算,反向过程应保持这组数值不变。

两层网络的前向与反向路径。图中 $G=\overline U$,$D=\overline Z$;各仿射层还分别产生权重与偏置梯度。
图 3.2 两层网络的前向与反向路径。图中 \(G=\overline U\)\(D=\overline Z\);各仿射层还分别产生权重与偏置梯度。

由交叉熵的推导,首先得到

\[ G=\overline U=\frac{Q-Y}{2} =\frac12\begin{bmatrix}-a&a\\b&-b\end{bmatrix}. \tag{3.39}\]

输出层参数梯度为

\begin{align} \overline W_2=A^{\mathsf T}G &=\begin{bmatrix}-\frac{3a}{2}&\frac{3a}{2}\\\frac{-a+3b}{2}&\frac{a-3b}{2}\end{bmatrix} \approx\begin{bmatrix}-0.178804&0.178804\\0.011537&-0.011537\end{bmatrix},\tag{3.40}\\ \overline b_2=G^{\mathsf T}\mathbf1_2 &=\begin{bmatrix}\frac{b-a}{2}\\\frac{a-b}{2}\end{bmatrix} \approx\begin{bmatrix}-0.035889\\0.035889\end{bmatrix}. \tag{3.41}\end{align}

在计算隐藏激活的梯度时仍使用原来的 \(W_2\)

\[ \overline A=GW_2^{\mathsf T} =\frac12\begin{bmatrix}-a&a\\b&-b\end{bmatrix}. \tag{3.42}\]

这里 \(\overline A\) 恰好与 \(G\) 数值相同,是本例所选权重的结果,不是一般恒等式。ReLU 的局部导数矩阵为 \(\mathbf1[Z>0]=\begin{bmatrix}1&1\\0&1\end{bmatrix}\),故

\[ D=\overline Z=\overline A\odot\mathbf1[Z>0] =\frac12\begin{bmatrix}-a&a\\0&-b\end{bmatrix}. \tag{3.43}\]

第二个样本的第一隐藏单元反向被阻断,这与其前向处于负区间相对应。

继续使用式(3.14)可得

\begin{align} \overline W_1=X^{\mathsf T}D &=\begin{bmatrix}-\frac{a}{2}&\frac{a}{2}+b\\-a&a-\frac{b}{2}\end{bmatrix} \approx\begin{bmatrix}-0.059601&0.107027\\-0.119203&0.095490\end{bmatrix},\tag{3.44}\\ \overline b_1=D^{\mathsf T}\mathbf1_2 &=\begin{bmatrix}-\frac{a}{2}\\\frac{a-b}{2}\end{bmatrix} \approx\begin{bmatrix}-0.059601\\0.035889\end{bmatrix},\tag{3.45}\\ \overline X=DW_1^{\mathsf T} &=\begin{bmatrix}-a&0\\\frac{b}{2}&-\frac{b}{2}\end{bmatrix}. \tag{3.46}\end{align}

输入梯度虽然不是这里需要更新的参数,却仍有明确含义:它描述当前损失对输入特征的局部敏感度。若 \(X\) 来自更早的可训练模块,这个梯度正是该模块收到的上游信息。

\(W_{1,11}\) 为例,其梯度为 \(-\frac{a}{2}\approx-0.059601\)。仅对这个坐标施加正扰动 \(\delta\) 时,一阶损失变化约为 \(-0.059601\delta\)。如果所有参数沿负梯度作足够小的共同更新,则一阶变化为 \(-\eta\|\nabla_\theta\mathcal L\|^2\)。这只是在可微邻域中的局部判断;过大的步长可能跨过激活边界或使高阶项占据主导,因此不能从梯度符号直接推断任意步长都会降低损失。

本例完成了从输入、两次仿射变换、非线性和概率归一化,到损失以及全部参数梯度的闭合计算。每个矩阵均可用形状、逐元素求导和数值扰动交叉核对,三种证据互相补充。

3.7广播、归约及嵌入查表

广播运算的反向归约

广播(broadcasting)把长度为一或缺失的轴按规则扩展,使同一个参数参与多个位置的运算。其本质是参数共享,不必理解成实际复制数据。对 \(Z_{ij}=X_{ij}+b_j\),有

\[ \overline b_j=\sum_i\overline Z_{ij},\qquad \overline X_{ij}=\overline Z_{ij}. \tag{3.47}\]

\(Z_{itj}=X_{itj}+b_j\),则 \(b_j\) 同时沿样本轴和位置轴广播,故

\[ \overline b_j=\sum_{i=1}^{B}\sum_{t=1}^{T}\overline Z_{itj}. \tag{3.48}\]

反向后应恢复偏置原来的形状,而不是保留扩展后的每个位置一份梯度。

例如 \(B=T=2\),某一通道的上游梯度在四个位置分别为 \(1,2,3,4\),共享偏置收到的梯度是 \(10\)。如果前向还有一个在四个位置上取平均的损失,其 \(\frac{1}{4}\) 系数应已通过上游梯度传来;不能在偏置反向时再无条件除以四。

反过来,归约求和 \(s_j=\sum_iX_{ij}\) 的反向将 \(\overline s_j\) 广播回每一行;均值 \(s_j=B^{-1}\sum_iX_{ij}\) 的反向还要乘以 \(\frac{1}{B}\)。广播与归约之所以互为对应,是因为它们分别表达共享和聚合。

对带掩码的损失,设 \(M_{it}\in\{0,1\}\) 表示有效位置,\(N=\sum_{it}M_{it}>0\),则

\[ \mathcal L=\frac1N\sum_{it}M_{it}\ell_{it},\qquad \overline U_{itj}=\frac{M_{it}}{N}(Q_{itj}-Y_{itj}). \tag{3.49}\]

分母是有效位置数,而不一定是填充后张量的元素数。掩码固定时此式成立;若权重本身由可训练模块生成,分母和权重的求导需要另行处理。

嵌入查表的稀疏梯度

设词表大小为 \(V\),嵌入矩阵为 \(E\in\Real^{V\times d}\)。编号 \(k\) 的独热向量 \(e_k\) 满足 \((e_k)_j=\mathbf1[j=k]\),因此

\[ e_k^{\mathsf T}E=E_{k,:}. \tag{3.50}\]

对一批编号 \(k_1,\ldots,k_B\),令选择矩阵 \(S\in\{0,1\}^{B\times V}\) 的第 \(i\) 行为 \(e_{k_i}^{\mathsf T}\),则嵌入输出为 \(H=SE\)。根据线性层的求导结果,

\[ \overline E=S^{\mathsf T}\overline H,\qquad \overline E_{j,:}=\sum_{i:k_i=j}\overline H_{i,:}. \tag{3.51}\]

选择矩阵仅用于论证;实际计算可以直接按编号访问参数行,避免构造巨大的独热数组。

设编号为 \((2,1,2)\),按本章从一开始的行编号,三个输出的梯度分别为 \((1,2)\)\((3,4)\)\((5,6)\)。则第1行的梯度为 \((3,4)\),第2行为 \((6,8)\),未被选中的其他行在这条查表路径上的梯度为零。第2行必须把两次出现的贡献相加,而不是用最后一次覆盖前一次。 3

查表不提供对整数编号本身的通常导数;它对被选取的连续参数可微。若嵌入表还被其他路径使用,例如同时作为输出投影的权重,那么那些路径的梯度也要累加。即使某一行的数据梯度为零,动量状态或权重衰减仍可能使优化步骤改变该行,因此不能把“本批未出现”直接等同于“参数绝不变化”。

对长度为 \(T\) 的序列,显式独热表示需要 \(BTV\) 个元素,编号只需要 \(BT\) 个整数;查表后的连续表示需要 \(BTd\) 个元素。这种计算表示的变化不改变数学含义,却决定了大词表输入是否具有可行的存储成本。

3.8有限差分及梯度核验

中心差分的误差来源

将全部参数按固定顺序看作向量 \(\theta\),选取单位方向 \(v\),定义单变量函数 \(f(t)=\mathcal L(\theta+tv)\)。若该方向邻域内具有足够光滑的三阶导数,则 Taylor 展开给出

\[ \frac{\mathcal L(\theta+\varepsilon v)-\mathcal L(\theta-\varepsilon v)}{2\varepsilon} =v^{\mathsf T}\nabla_\theta\mathcal L+O(\varepsilon^2). \tag{3.52}\]

中心差分消去了展开中的偶次项,截断误差为二阶。但当 \(\varepsilon\) 很小时,两个接近的损失值相减会放大舍入误差;若损失求值的绝对误差量级为 \(uM\),差商中的该项约为 \(O(\frac{uM}{\varepsilon})\),其中 \(u\) 为机器精度尺度,\(M\) 为求值的相关尺度。

因此步长不是越小越好。应使用足够精细的数值精度,在一组合理的步长上观察误差先下降、随后受舍入影响的区间。根据上述理想误差模型平衡两项时,步长呈 \(u^{\frac{1}{3}}\) 的尺度关系,但实际常数还取决于参数尺度、损失尺度和三阶导数;不能将它作为对所有模型固定适用的数值。

只扰动上述两层网络中的 \(W_{1,11}\),将扰动记为 \(t\)。当 \(|t|<\frac{1}{2}\) 时,四个隐藏预激活仍保持原来的正负状态,因此 ReLU 分支不变。此时两个正确类别的分数差分别为 \(2+t\)\(3\),损失可以直接化为

\[ f(t)=\frac12\log(1+e^{-2-t})+\frac12\log(1+e^{-3}). \tag{3.53}\]

由这个独立的标量表达式可得

\[ f'(0)=-\frac{1}{2(1+e^2)}=-0.059601461\ldots, \tag{3.54}\]

与矩阵反向结果一致。取 \(\varepsilon=10^{-4}\),式(3.52)同样给出约 \(-0.059601461\)。这一核对有意义,是因为它绕过了矩阵反向程序,直接从扰动后的损失计算变化。

梯度一致性的判定边界

梯度校验应固定输入、标签、参数及随机选择,并避免扰动跨越 ReLU 折点或离散分支。若原点本身位于不可微处,中心差分可能给出左右变化率的平均值,它并不等于实现选定的次梯度。随机失活若在两次求值时使用不同掩码,差商还会混入函数本身变化造成的噪声。

比较时应同时报告绝对误差和相对尺度。例如令 \(a\) 为解析方向导数,\(n\) 为数值差商,可考察 \(|a-n|\),并辅以 \(\frac{|a-n|}{\max(\delta,|a|+|n|)}\),其中 \(\delta>0\) 避免近零分母。只比较相对误差会对接近零的导数过度敏感,只比较绝对误差又可能掩盖大尺度量上的错误。

通过校验说明当前输入和参数附近的计算图与导数相容,不能证明类别标签正确、样本划分合理,或损失符合业务目标。尤其是错误地沿样本轴执行 Softmax,仍然定义了一个可微函数,自动微分可以正确求出这个错误函数的梯度。因此,可靠检查应先确认轴与任务语义,再检查分量公式和数值导数,最后才讨论训练效果。


  1. 微分几何中的张量还涉及坐标变换法则。本章使用深度学习计算中的数组含义,不将数组维数与几何张量的变换性质混为一谈。↩︎

  2. ReLU 是凸函数,其零点次微分为 \([0,1]\)。计算实现需要约定零点取值,常见约定为零。这不意味着包含 ReLU 的整个非凸网络拥有相同的凸分析性质。↩︎

  3. 程序中的词元编号常从零开始,书中矩阵行号从一开始。转换时应整体调整编号约定,不应只修改一处索引。↩︎

WORKBOOK / 习题

配套习题与解析

先独立作答,再展开参考解析。选修题保留原书标记。

习题 3.1

\(X\in\Real^{3\times4}\)\(W\in\Real^{4\times2}\)\(b\in\Real^2\)。写出 \(Z=XW+\mathbf1_3b^{\mathsf T}\) 的分量式,并给出上游梯度为 \(G\) 时三个输入梯度的形状。解释为什么偏置梯度不是 \(G\) 本身。

展开参考解析

\(Z_{ij}=\sum_{k=1}^4X_{ik}W_{kj}+b_j\)\(G\in\Real^{3\times2}\)。由 \(\dif Z=(\dif X)W+X\dif W+\mathbf1_3\dif b^{\mathsf T}\)\(\overline X=GW^{\mathsf T}\in\Real^{3\times4}\)\(\overline W=X^{\mathsf T}G\in\Real^{4\times2}\)\(\overline b=G^{\mathsf T}\mathbf1_3\in\Real^2\)。同一偏置在三行复用,其梯度必须对三条路径求和。

习题 3.2选修

从矩阵内积定义出发,推导 \(\mathcal L=\frac12\|XW-T\|_F^2\)\(W\)\(X\) 的梯度,其中 \(T\) 为固定目标矩阵。若损失改为对样本数取平均,哪些项需要改变?

展开参考解析

\(R=XW-T\)\(\dif\mathcal L=\operatorname{tr}[R^{\mathsf T}((\dif X)W+X\dif W)]\),循环移动迹中因子可得 \(\nabla_W\mathcal L=X^{\mathsf T}R\)\(\nabla_X\mathcal L=RW^{\mathsf T}\)。若对 \(B\) 个样本平均,目标乘 \(\frac{1}{B}\),两个梯度也乘 \(\frac{1}{B}\);不能额外再除输出宽度,除非所定义目标还按元素平均。

习题 3.3

\(q=(\frac{1}{2},\frac{1}{3},\frac{1}{6})\) 写出完整 Softmax 雅可比,验证各行之和为零,并用一个给定向量检查显式矩阵乘积与向量形式相等。

展开参考解析

\[J=\operatorname{diag}(q)-qq^{\mathsf T} =\begin{bmatrix}\frac{1}{4}&-\frac{1}{6}&-\frac{1}{12}\\-\frac{1}{6}&\frac{2}{9}&-\frac{1}{18}\\-\frac{1}{12}&-\frac{1}{18}&\frac{5}{36}\end{bmatrix}.\] 每行和为零。任选 \(v=(1,2,3)^{\mathsf T}\)\(q^{\mathsf T}v=\frac{5}{3}\),故 \(Jv=q\odot(v-\tfrac53\mathbf1)=(-\frac{1}{3},\frac{1}{9},\frac{2}{9})^{\mathsf T}\),与逐行矩阵乘法相同。题目未指定向量,这是一种可复核选择。

习题 3.4选修

将目标改为权重向量 \(y=(1,1,0)\),推导 \(-\sum_jy_j\log q_j\) 的分数梯度。说明它为何不再等于 \(q-y\),以及它与三个独立二元分类目标有何区别。

展开参考解析

\(s=\sum_jy_j\),展开损失为 \(-\sum_jy_jz_j+s\log\sum_ke^{z_k}\),故梯度为 \(sq-y\)。本题 \(s=2\),得到 \(2q-(1,1,0)\)。Softmax类别共享一个分母;三个独立二元任务使用各自Sigmoid,梯度是 \(\sigma(z_j)-y_j\),不存在该互斥归一化约束。

习题 3.5

\(X\in\Real^{2\times3\times4}\),偏置形状为 \(1\times3\times1\)。写出 \(Z=X+b\) 的反向求和轴。若前向又对全部24个元素取平均,说明归一化系数在反向中的位置。

展开参考解析

\(\overline b_{1j1}=\sum_{i=1}^2\sum_{k=1}^4\overline Z_{ijk}\),即对批量轴及最后一轴求和,保留维度。若 \(\mathcal L=\operatorname{mean}(Z)\),则每个 \(\overline Z_{ijk}=\frac{1}{24}\),偏置梯度为 \(\frac{8}{24}=\frac{1}{3}\)。若平均的是后续逐元素损失,其局部导数先乘 \(\frac{1}{24}\) 再沿广播轴求和。

习题 3.6

嵌入编号为 \((1,3,1,3)\),四个位置的上游梯度依次为 \((1,0)\)\((0,1)\)\((2,3)\)\((-1,2)\)。求嵌入表各行的梯度,并说明按最后一次出现覆盖会造成什么错误。

展开参考解析

第1行梯度为 \((1,0)+(2,3)=(3,3)\),第3行为 \((0,1)+(-1,2)=(-1,3)\),未出现行均为零。覆盖写入只保留最后一项,将得到错误的 \((2,3)\)\((-1,2)\)。反向应执行按编号的散射求和,而非赋值覆盖。

习题 3.7选修

在本章两层网络例题中,单独扰动 \(W_{1,12}\)。保持 ReLU 分支不变,写出标量损失关于扰动的表达式,并核对其零点导数为 \(\frac{a}{2}+b\)

展开参考解析

\(W_{1,12}\) 增加 \(t\),两个相关预激活变为 \(1+t\)\(3-2t\)。例如 \(|t|<\frac{1}{2}\) 保证激活分支不变。正确类别分数差分别为 \(2-t\)\(3-2t\),故 \[f(t)=\tfrac12\log(1+e^{-2+t})+\tfrac12\log(1+e^{-3+2t}), \quad f'(0)=\frac{a}{2}+b\approx0.1070273.\] 求偏导时其他参数固定;同时更新其他参数将不再是这个单变量函数。

习题 3.8

\(f(x)=\max(0,x)\)\(x=0\) 使用中心差分。所得值是多少?它为什么不能用于否定零点取零的求导约定?再解释在 \(x=1\) 附近如何选择扰动才能避开折点。

展开参考解析

中心差分为 \(\frac{[f(\varepsilon)-f(-\varepsilon)]}{2\varepsilon}=\frac{1}{2}\)。零点不存在普通导数,差分跨越左右两分支,所以不能据此否定框架取零的次梯度约定。在 \(x=1\) 附近取 \(0<\varepsilon<1\) 可保持两点都在正半轴,差分精确为1;浮点计算还需避免扰动过小产生消减误差。

习题 3.9

一个长度不同的序列批次用填充后的总位置数作交叉熵分母,另一个实现用有效词元数作分母。分别写出两种目标,分析它们在填充比例变化时的梯度尺度。即使二者均通过有限差分校验,是否足以认定目标相同?

展开参考解析

记有效损失和为 \(S\),填充后位置数 \(N_p\)、有效数 \(N_v>0\),则 \(L_p=\frac{S}{N_p}\)\(L_v=\frac{S}{N_v}\),并有 \(\nabla L_p=(\frac{N_v}{N_p})\nabla L_v\)。填充比例变动会改变前者梯度尺度;若不同批次有效长度不同,也改变批次贡献。两种函数都可通过各自有限差分测试,该测试只检验导数实现,不证明目标相同。

习题 3.10

某语言模型的自动微分梯度与中心差分一致,但训练目标把每个位置的当前词元当作标签。说明这项检查能证明什么;构造一个长度为3的词元序列,写出正确与错误的输入标签配对,并设计独立于梯度差分的检查。讨论在 ReLU 折点附近做差分时应如何解释不一致。

展开参考解析

差分一致支持所实现标量函数的局部导数计算正确,不能证明该函数符合预测任务。对序列 \((a,b,c)\),下一词元预测使用输入 \((a,b)\)、标签 \((b,c)\);若标签为 \((a,b)\),当前词元已出现在该位置输入中,模型可能学到复制。应手算一个短序列的目标位置与有效词元掩码,逐位置核对损失,并通过改变未来词元检查因果隔离。语义检查通过后,再在光滑点比较中间量与梯度。ReLU 折点处经典导数不存在,跨越两侧的中心差分可与框架选用的次梯度不同;应换用远离折点的输入,不能据此单独判定反向传播实现错误。

REFERENCES

参考文献

搜索全书

搜索全书正文、习题与解析