参数初始化与信号尺度:参考答案#
说明#
以下答案与正文10道题逐题对应。推导题给出主要步骤;编程和实验题给出参考程序和检查方法,并说明结果适用于哪些条件。
独立且零均值给出 \(\mathbb E(w_{jk}a_k)=0\)。互不相关的求和项满足 \(\operatorname{Var}(z_j)=\sum_k\operatorname{Var}(w_{jk}a_k)\),而独立性给出 \(\operatorname{Var}(w_{jk}a_k)=\operatorname{Var}(w_{jk})\operatorname{Var}(a_k)\),故共有 \(d_{\mathrm{in}}\) 个同分布项时得到题中等式。若权重或激活非零均值、项间相关或方差不相同,必须保留额外的协方差或逐项方差,简式不再严格成立。
记权重方差为 \(v_w\)。若输入近似零均值,各输入分量具有相同的二阶矩,则线性运算结果满足
\[\mathbb E(z_j^2) \approx d_{\mathrm{in}}v_w\mathbb E(a_k^2).\]对关于 0 近似对称的线性运算结果,ReLU 函数约保留一半二阶矩,因此
\[\mathbb E[\operatorname{ReLU}(z_j)^2] \approx \frac{d_{\mathrm{in}}v_w}{2}\mathbb E(a_k^2).\]若希望前向传播前后的二阶矩大致不变,应取 \(v_w\approx2/d_{\mathrm{in}}\),这就是 fan-in 模式 He 初始化的目标。
后向传播也有对应的尺度条件。设 \(g_j\) 是从后一层传到 ReLU 输出的梯度。在独立、零均值且约有一半 ReLU 单元处于激活状态的近似下,传回某个输入分量的梯度方差满足
\[\operatorname{Var}\!\left(\frac{\partial\mathcal J}{\partial a_k}\right) \approx \frac{d_{\mathrm{out}}v_w}{2}\operatorname{Var}(g_j).\]若优先保持后向梯度的尺度,应取 \(v_w\approx2/d_{\mathrm{out}}\),这就是 fan-out 模式的目标。当 \(d_{\mathrm{in}}\ne d_{\mathrm{out}}\) 时,\(2/d_{\mathrm{in}}\) 与 \(2/d_{\mathrm{out}}\) 不相等,同一个权重方差无法同时精确满足两个目标。实际使用时可以根据更关心前向激活还是后向梯度选择模式,也可以采用折中尺度。普通 Xavier 正态初始化的方差为 \(2/(d_{\mathrm{in}}+d_{\mathrm{out}})\);若再乘入 ReLU 的增益 \(\sqrt 2\),折中方差变为 \(4/(d_{\mathrm{in}}+d_{\mathrm{out}})\)。这些结论来自近似尺度分析,不保证有限宽网络中的统计量精确不变。
设第 \(t\) 步的整套参数在交换这两个神经元时保持不变。它们对每个输入产生相同的线性运算结果和激活;由于通向下一层的对应权重也相同,交换操作不改变网络输出和损失,链式法则便给出成对相同的输入权重梯度、偏置梯度和输出权重梯度。使用相同学习率更新后,整套参数仍具有同一交换对称性。初始步成立,数学归纳法说明所有更新步均成立。因此两个神经元只能学习重复特征。仅令输入权重和偏置相同还不够:若输出权重不同,第一次后向传播得到的隐藏层梯度就可能不同。随机小扰动、不同的 Dropout 掩码或其他破坏对称性的机制也会改变结论。
代入 \(d_{\mathrm{in}}=128\) 和 \(d_{\mathrm{out}}=64\),四种初始化的标准差分别为
\[\begin{split}\begin{aligned} \sigma_{\mathrm{Xavier}} &=\sqrt{\frac{2}{128+64}} =\sqrt{\frac{1}{96}}\approx0.1021,\\ \sigma_{\mathrm{He,in}} &=\sqrt{\frac{2}{128}}=0.1250,\\ \sigma_{\mathrm{He,out}} &=\sqrt{\frac{2}{64}}\approx0.1768,\\ \sigma_{\mathrm{ReLU\text{-}gain}} &=\sqrt{\frac{4}{128+64}} =\sqrt{\frac{1}{48}}\approx0.1443. \end{aligned}\end{split}\]输入二阶矩为 1 时,fan-in 模式 He 初始化使线性运算结果的二阶矩约为
\[\mathbb E(Z^2)\approx128\frac{2}{128}=2, \qquad \mathbb E[\operatorname{ReLU}(Z)^2]\approx\frac12\mathbb E(Z^2)=1.\]因此,这一分析保持的是 ReLU 输出的二阶矩,而不一定是严格方差。若进一步近似 \(Z\sim\mathcal N(0,2)\),则 \(\mathbb E[\operatorname{ReLU}(Z)]=1/\sqrt\pi\),严格方差为 \(1-1/\pi\approx0.6817\)。
下面的实现使用全连接层和标准卷积层常见的权重存放顺序。全连接权重维度为
(fan_out, fan_in);卷积权重维度为(out_channels, in_channels_per_group, *kernel_size)。from numbers import Integral import numpy as np def calculate_fans(shape): try: dims = tuple(shape) except TypeError as exc: raise ValueError("shape 必须是维度序列") from exc if len(dims) < 2: raise ValueError("权重至少需要两个轴") if any(not isinstance(size, Integral) or size <= 0 for size in dims): raise ValueError("每个权重维度都必须是正整数") receptive_field = int(np.prod(dims[2:], dtype=np.int64)) fan_in = int(dims[1] * receptive_field) fan_out = int(dims[0] * receptive_field) return fan_in, fan_out def init_weight(shape, kind, rng, normal_std=None, mode="fan_in"): fan_in, fan_out = calculate_fans(shape) dims = tuple(shape) if kind == "zero": return np.zeros(dims, dtype=np.float64) if kind == "normal": if normal_std is None or not np.isfinite(normal_std): raise ValueError("normal 初始化需要有限的标准差") if normal_std < 0: raise ValueError("标准差不能为负数") variance = float(normal_std) ** 2 elif kind == "xavier": variance = 2.0 / (fan_in + fan_out) elif kind == "he": if mode not in {"fan_in", "fan_out"}: raise ValueError("He 初始化的 mode 必须是 fan_in 或 fan_out") fan = fan_in if mode == "fan_in" else fan_out variance = 2.0 / fan elif kind == "xavier_relu": # 普通 Xavier 方差乘以 ReLU 增益平方 2 variance = 4.0 / (fan_in + fan_out) else: raise ValueError("未知初始化方法") return rng.normal(0.0, np.sqrt(variance), size=dims)
调用
init_weight(shape, "he", rng, mode="fan_in")和mode="fan_out"即可得到两种 He 初始化;kind="xavier_relu"对应带 ReLU 增益的折中方案。卷积层的感受野大小是所有卷积核空间维度的乘积,因此(16, 8, 3, 3)得到fan_in=72、fan_out=144。分组卷积的第二个轴已经是每组输入通道数;转置卷积的权重轴含义不同,使用时应根据框架的存放顺序调整前两个轴。数值对照应比较大量权重的经验均值和方差,而不是要求自编程序与 PyTorch 逐元素相同。设
w是 PyTorch 中按(fan_out, fan_in)存放的权重,可分别调用import torch from torch.nn import init init.xavier_normal_(w, gain=1.0) init.xavier_normal_(w, gain=init.calculate_gain("relu")) init.kaiming_normal_(w, mode="fan_in", nonlinearity="relu") init.kaiming_normal_(w, mode="fan_out", nonlinearity="relu")
这四种调用对应普通 Xavier、带 ReLU 增益的 Xavier 折中、fan-in 模式 He 和 fan-out 模式 He。它们的理论方差依次为 \(2/(d_{\mathrm{in}}+d_{\mathrm{out}})\)、\(4/(d_{\mathrm{in}}+d_{\mathrm{out}})\)、\(2/d_{\mathrm{in}}\) 和 \(2/d_{\mathrm{out}}\)。
kaiming_normal_的nonlinearity="relu"会使用 ReLU 增益;mode决定优先保持前向激活还是后向梯度。PyTorch 的 fan 计算默认权重用于x @ w.T。若程序使用x @ w,应对转置后的权重调用初始化函数,否则 fan-in 与 fan-out 会交换。网络核验时,前向钩子应记录激活均值和二阶矩,例如
(output.detach() ** 2).mean();梯度钩子记录各层梯度范数。使用相同输入分别检查两种mode和两种gain,才能判断自编实现是否与对应框架设置一致。若激活二阶矩或梯度范数随深度迅速趋近 0 或持续增大,应先核对初始化模式、激活函数和权重存放顺序。测试可分为确定性检查、统计检查和错误输入检查。使用两个由相同种子创建的
np.random.default_rng,相同调用应得到逐元素相同的权重;零初始化应满足np.count_nonzero(weight) == 0。二维权重(64, 128)必须得到fan_in=128、fan_out=64,因此两种 He 模式的理论方差分别为 \(2/128\) 和 \(2/64\),不能返回相同尺度。可执行检查例如shape = (64, 128) w_in = init_weight( shape, "he", np.random.default_rng(7), mode="fan_in" ) w_out = init_weight( shape, "he", np.random.default_rng(7), mode="fan_out" ) np.testing.assert_allclose(w_in.var(), 2 / 128, rtol=0.15) np.testing.assert_allclose(w_out.var(), 2 / 64, rtol=0.15) assert w_out.std() > w_in.std()
卷积权重
(16, 8, 3, 3)应得到fan_in=72、fan_out=144。还应分别检查普通 Xavier 和带 ReLU 增益折中的经验方差,覆盖指定标准差的正态初始化,并确认空维度、一维权重、零长度轴、非整数维度、负标准差、未知方法和非法mode都会明确报错。统计容差应随权重元素数确定,不能要求有限随机样本精确等于理论方差。六种方法应明确为零初始化、过小高斯、过大高斯、普通 Xavier、fan-in 模式 He 和 fan-out 模式 He。所有方法使用相同的数据划分、网络结构、优化器、训练更新次数、批次顺序和随机种子集合;不同初始化方法可以使用各自独立但可复现的参数随机数生成器。每个随机种子都要保留,失败或产生非有限损失的运行也应报告,不能只挑选成功结果。
结果表应包含训练集、验证集和测试集任务指标及其多次运行的均值与波动、达到预先规定验证指标所需时间、总训练时间、固定批量预测时间、参数量和峰值内存。还应逐层记录训练开始时及训练过程中的激活二阶矩和梯度范数。零初始化通常难以打破隐藏神经元的对称性;过小或过大高斯可能造成信号逐层衰减或放大;fan-in 模式 He 更关注 ReLU 网络的前向激活,fan-out 模式 He 更关注后向梯度。普通 Xavier 是不含 ReLU 增益的前后向折中,但具体结果仍取决于网络宽度、数据和优化设置。网络结构相同时,参数量和预测计算过程不因初始化方法而改变,固定批量预测时间的微小差异通常只是计时波动。
本题共有 \(3\times3=9\) 个“初始化方法—学习率”组合:普通 Xavier、fan-in 模式 He、fan-out 模式 He 分别与三个预先给定的学习率组合。所有组合使用相同的数据划分、网络结构、批量大小、训练轮数、批次顺序和随机种子集合;三个学习率必须在实验前确定,不能根据测试集结果为某一种初始化方法单独增加候选值。
对每个组合报告任务性能、训练是否稳定、损失是否保持有限、达到验证指标所需的更新次数和时间、总训练时间、固定批量预测时间、参数量和峰值内存,并画出训练损失与验证指标随更新次数变化的曲线。比较时既要在同一初始化方法内观察学习率变化,也要在同一学习率下比较三种初始化方法。较大的初始化尺度与较大学习率同时出现时更容易造成更新过大;较小学习率则可能在规定训练轮数内尚未收敛。初始化方法和学习率不会改变网络参数量,主要差异应体现在优化轨迹、稳定性和任务表现上。
四组实验可明确写为“tanh 函数 + 普通 Xavier”“tanh 函数 + fan-in 模式 He”“ReLU 函数 + 普通 Xavier”和“ReLU 函数 + fan-in 模式 He”。如果选择其他 He 模式,必须在实验开始前说明,并在所有相关组中保持一致。四组使用相同的数据划分、网络深度与宽度、随机种子集合、优化器、训练更新次数和评价程序,只改变激活函数与初始化方法的组合。
这四组形成一个简单的二因素比较:在初始化相同时比较 tanh 函数与 ReLU 函数,可以分析激活函数的影响;在激活函数相同时比较普通 Xavier 与 He 初始化,可以分析初始化尺度的影响。tanh 函数与普通 Xavier、ReLU 函数与 fan-in 模式 He 通常是较匹配的组合,但不能在看到结果之前认定它们一定最好。除任务指标外,应逐层报告激活均值、激活二阶矩和梯度范数,并报告训练时间、固定批量预测时间和峰值内存。四组结构相同时参数量相同,不应把少量计时波动解释成结构性效率差异。