系列回顾:前三篇(第17-19篇)把梯度下降、SGD/Mini-batch、Adam 优化器讲透了。AdamW 里的权重衰减(L2 正则化)反复出现,但一直没有正面讲清楚它的数学原理。这一篇补全这块拼图——从正则化的根本动机讲起,推导 L1 和 L2 的几何直觉,再联系到 DeepSeek V3 的 MoE 架构:专家负载均衡损失是另一种形式的正则化,防止"赢者通吃"的路由退化,数学形式和 L1/L2 有深刻的相似性。这篇是优化阶段的收官之作。
先看一个让人困惑的现象:
训练一个神经网络,随着训练时间增加,训练损失持续下降,但测试损失先下降后上升——模型在训练集上越来越好,在测试集上却越来越差。这就是过拟合(Overfitting)。
过拟合的本质:模型记住了训练数据的随机噪声,而不是学到了数据的真实规律。
类比:背题和理解。一个学生把 1000 道例题的答案全背下来(训练损失=0),但遇到一道新题(测试集)却完全不会(测试损失很高)。
正则化(Regularization) 是在损失函数里加入对模型复杂度的惩罚项,让模型在拟合训练数据的同时,保持"简单",从而提升对新数据的泛化能力。
对回归任务,期望测试误差可以分解为三项:
$$\mathbb{E}[(y - \hat{f}(x))^2] = \underbrace{\text{Bias}^2(\hat{f})}_{\text{偏差}^2} + \underbrace{\text{Var}(\hat{f})}_{\text{方差}} + \underbrace{\sigma^2}_{\text{不可消除噪声}}$$
偏差-方差权衡(Bias-Variance Tradeoff):
正则化的作用是在保持较低偏差的同时降低方差——在损失里加入复杂度惩罚,让模型不过度适应训练数据的噪声。
从第15-16篇的信息论来看:
训练集大小 $n$,模型参数量 $p$。当 $p \gg n$ 时(过参数化),模型可以完美记忆训练集(training loss = 0),但这些参数里包含了大量"用于拟合噪声"的信息,泛化性差。
有效参数数量(模型实际使用的自由度)应该远小于名义参数数量。正则化通过惩罚参数的大小,隐式地限制了有效参数数量——小参数对模型输出贡献少,等效于"关闭"了部分参数自由度。
在原始损失 $L(\theta)$ 上加参数的 L2 范数(平方和)惩罚:
$$L_{L2}(\theta) = L(\theta) + \frac{\lambda}{2}\|\theta\|_2^2 = L(\theta) + \frac{\lambda}{2}\sum_j \theta_j^2$$
$\lambda > 0$ 是正则化强度(权衡拟合和惩罚)。
梯度变为:
$$\nabla_\theta L_{L2} = \nabla_\theta L + \lambda\theta$$
更新规则(SGD 下):
$$\theta \leftarrow \theta - \alpha(\nabla_\theta L + \lambda\theta) = (1-\alpha\lambda)\theta - \alpha\nabla_\theta L$$
每步先把参数乘以 $(1-\alpha\lambda) < 1$(权重收缩),再减去梯度。这就是"权重衰减(Weight Decay)"名字的由来——参数在每步都在衰减。
L2 正则化等价于在有约束的优化问题:
$$\min_\theta L(\theta) \quad \text{s.t.} \quad \|\theta\|_2^2 \leq C$$
几何解释:
球面是光滑的(无尖角),切点通常不在坐标轴上,所以 L2 正则化的解通常不会使参数恰好为零,只是把参数缩小。
第12篇讲过:L2 正则化等价于参数的高斯先验下的 MAP 估计。
$$P(\theta) \propto \exp\left(-\frac{\lambda}{2}\|\theta\|^2\right) = \mathcal{N}(0, 1/\lambda \cdot I)$$
训练越充分,这个先验的效果越小(似然主导);训练数据少时,先验把参数往零拉(防止过拟合)。
直觉:高斯先验偏好小参数,说明我们先验认为大部分参数应该接近零(大多数特征不重要),这是神经网络参数的合理假设。
L2 正则化让参数整体缩小,偏好参数分散均匀的解——与其让一个参数很大,不如让多个参数适中(L2 惩罚对大参数的惩罚是平方增长,比均匀分布更重)。
矩阵视角:权重矩阵 $W$ 的 L2 正则化 $\|W\|_F^2$(Frobenius 范数)等于所有奇异值的平方和。L2 正则化偏好奇异值均匀分布的矩阵,而不是集中在少数奇异值上——这有助于减少矩阵的有效秩,防止过拟合。
在原始损失上加参数的 L1 范数(绝对值之和)惩罚:
$$L_{L1}(\theta) = L(\theta) + \lambda\|\theta\|_1 = L(\theta) + \lambda\sum_j |\theta_j|$$
梯度(对 $\theta_j \neq 0$ 时):
$$\frac{\partial L_{L1}}{\partial \theta_j} = \frac{\partial L}{\partial \theta_j} + \lambda \cdot \text{sign}(\theta_j)$$
注意:$|\theta_j|$ 在 $\theta_j = 0$ 处不可导,需要用次梯度(Subgradient)处理:$\partial|\theta_j| = \text{sign}(\theta_j) \in [-1, 1]$。
L1 正则化等价于约束问题:
$$\min_\theta L(\theta) \quad \text{s.t.} \quad \|\theta\|_1 \leq C$$
损失函数的等高线(椭圆)和菱形相切,由于菱形的尖角突出,等高线极有可能第一次接触菱形的尖角——即在某个 $\theta_j = 0$ 的点相切。
结论:L1 正则化天然产生稀疏解(许多参数恰好为零),而 L2 的球面无尖角,切点通常不在坐标轴上,参数不会精确为零。
对简单情形:$L(\theta) = \frac{1}{2}(\theta - z)^2 + \lambda|\theta|$(单参数 L1 正则化最小二乘)。
令梯度为零:$\theta - z + \lambda \cdot \text{sign}(\theta) = 0$。
分三种情况求解:
情形一($z > \lambda$):最优 $\theta = z - \lambda > 0$,$\text{sign}(\theta) = 1$,代入验证 ✓
情形二($z < -\lambda$):最优 $\theta = z + \lambda < 0$,$\text{sign}(\theta) = -1$,代入验证 ✓
情形三($|z| \leq \lambda$):最优 $\theta = 0$(在 $[-\lambda, \lambda]$ 区间内,次梯度包含零)
合并写成软阈值算子(Soft Thresholding):
$$\mathcal{S}_\lambda(z) = \text{sign}(z) \cdot \max(|z| - \lambda, 0)$$
直观含义:
这是 LASSO 产生稀疏解的数学根源,也是压缩感知(Compressed Sensing)和稀疏恢复的核心操作。
L1 正则化的核心用途:自动特征选择。
在高维数据里(特征数量远多于样本数量),大多数特征与目标无关。L1 正则化会把无关特征对应的参数精确归零,自动从大量特征中选出真正有用的少数特征。
在语言模型里,这个思想延伸到:
Elastic Net:将两者组合 $\alpha\|\theta\|_1 + \frac{(1-\alpha)}{2}\|\theta\|_2^2$,同时有稀疏性和参数收缩,适合高度相关特征的情况。
L1/L2 是最经典的参数正则化,但神经网络还有很多其他正则化手段:
每次前向传播随机以概率 $p$ 把神经元置零,等价于训练了指数多个"子网络"的集成(Ensemble)。
Dropout 的隐式正则化:
DeepSeek V3 预训练时不使用 Dropout(数据量足够大,Dropout 减慢收敛且提升有限),但在精细微调小数据集时可能使用。
归一化层把激活值标准化(零均值单位方差),有隐式正则化效果:
DeepSeek V3 使用 RMSNorm(Layer Norm 的简化版),每个子层的输入前都有一个 RMSNorm。
监测验证集损失,在损失开始上升时停止训练。直觉上是限制了训练的"容量"——训练时间有限,模型没时间记住噪声。
理论上,Early Stopping 等价于 L2 正则化(在梯度下降的视角下,限制步数等价于限制参数离初始值的距离)。
通过对训练数据做变换(翻转、裁剪、噪声注入……)人工扩充训练集,让模型看到更多"变体",学到更鲁棒的特征。
语言模型的预训练本身就是一种极大的数据增强——14.8 万亿 token 的多样性提供了天然的正则化。
现在从经典正则化进入 DeepSeek V3 的特有问题:专家混合(Mixture of Experts,MoE) 的负载均衡。
DeepSeek V3 的 FFN 层用 MoE 替代了标准的 FFN:
路由机制(门控网络):对 token 的隐藏状态 $h$ 计算每个专家的亲和力分数,选 Top-$K_r$ 个专家:
$$s_i = \text{Sigmoid}(h \cdot e_i), \quad \text{选择 Top-}K_r\text{ 个} s_i \text{ 最大的专家}$$
问题:如果不加限制,路由会陷入"赢者通吃"的崩溃:
这种路由崩溃(Routing Collapse) 的后果:
这是 MoE 训练中最棘手的问题,也是 MoE 模型(从 Switch Transformer 到 DeepSeek)都要专门解决的问题。
负载均衡损失(Load Balancing Loss) 是一种正则化项,惩罚专家利用率不均衡:
DeepSeek V3 使用辅助损失(Auxiliary Loss):
$$L_{Bal} = \alpha \sum_{i=1}^{N_r} f_i \cdot P_i$$
其中:
$$f_i = \frac{\text{专家}i\text{处理的 token 数}}{\text{总 token 数} \cdot K_r}$$
$$P_i = \frac{1}{T}\sum_{t=1}^T s_{i,t}$$(对当前 batch 的所有 token $t$ 求平均 Sigmoid 亲和力)
直觉:如果所有专家均等使用,$f_i = P_i = \frac{K_r}{N_r}$,则:
$$L_{Bal} = \alpha \sum_i f_i P_i = \alpha \sum_i \left(\frac{K_r}{N_r}\right)^2 = \alpha N_r \cdot \left(\frac{K_r}{N_r}\right)^2 = \alpha \frac{K_r^2}{N_r}$$
当专家利用率不均衡时(某些 $f_i$ 大,某些小),由柯西-施瓦茨不等式:
$$\sum_i f_i P_i \geq ?$$
更直观的论证:若某专家 $i$ 被过度使用($f_i$ 大),通常其亲和力分数 $P_i$ 也大(因为它更常被选中)。于是 $f_i P_i$ 就大,$L_{Bal}$ 就大,损失被惩罚。
最小化 $L_{Bal}$ 的方向是让大 $f_i$ 的专家降低 $P_i$(降低路由概率),让小 $f_i$ 的专家提高 $P_i$——向均匀分布推进。
实际上,$\sum_i f_i P_i$(当 $f_i \approx P_i$ 时)近似等于 $\sum_i f_i^2$,而最小化 $\sum_i f_i^2$ 在约束 $\sum_i f_i = K_r$(总使用量固定)下的解,恰好是 $f_i = K_r/N_r$(均匀分布):
由拉格朗日乘子法,最小化 $\sum_i f_i^2$ 约束 $\sum_i f_i = C$ 的解为 $f_i = C/N_r$(均匀)。
这和 L2 正则化的几何原理完全类比:
DeepSeek V3 还引入了一种不依赖辅助损失的均衡策略:动态偏置(Dynamic Bias)。
对每个专家的路由分数加一个动态偏置 $b_i$:
$$s_i' = s_i + b_i$$
偏置 $b_i$ 在训练过程中根据专家的历史负载自动调整:
$$b_i \leftarrow b_i - \gamma \cdot \mathbb{1}[\text{专家}i\text{过载}] + \gamma \cdot \mathbb{1}[\text{专家}i\text{欠载}]$$
这类似于在线学习里的 EWA(指数加权平均)算法,不需要额外的梯度,只需要统计每个专家的使用频率。
DeepSeek V3 将辅助损失权重设为极小值 $\alpha=0.0001$,主要依赖动态偏置来实现均衡,减少了辅助损失对主损失梯度的干扰。
从贝叶斯角度(第12篇),所有正则化都可以理解为对参数施加先验分布:
统一视角:正则化 = 对模型的某个量(参数、负载、策略……)施加"偏好均匀/简单"的先验,防止模型在某个方向上过度集中。
所有正则化都有一个强度超参数($\lambda$、$\alpha$、$p_{dropout}$……)控制正则化的强弱:
太弱:正则化效果不足,仍然过拟合 太强:模型被过度约束,欠拟合(偏差增大) 刚好:偏差-方差的最优平衡点
实践中通过验证集调参或超参数搜索(Grid Search、Random Search、贝叶斯优化)确定最优值。
DeepSeek V3 的配置: - 权重衰减 $\lambda = 0.1$(相对较大,防止 671B 参数的过拟合) - MoE 均衡损失 $\alpha = 0.0001$(极小,主要起辅助作用,不干扰主损失)
import numpy as np import torch import torch.nn as nn import torch.nn.functional as F np.random.seed(42) torch.manual_seed(42) # ===== 1. L1 vs L2 正则化:几何直觉与稀疏性 ===== print("===== L1 vs L2 正则化:解的稀疏性对比 =====\n") np.random.seed(0) n, d = 50, 20 # 样本数少于特征数(过参数化,需要正则化) X = np.random.randn(n, d) true_w = np.zeros(d) true_w[:5] = np.array([2.0, -1.5, 1.0, -0.8, 0.5]) # 只有5个特征真正有用 y = X @ true_w + 0.1 * np.random.randn(n) def solve_ridge(X, y, lam): """Ridge 回归的解析解:(X^TX + λI)^{-1} X^T y""" n, d = X.shape return np.linalg.solve(X.T @ X + lam * np.eye(d), X.T @ y) def solve_lasso_cd(X, y, lam, n_iter=1000): """LASSO 的坐标下降法(Coordinate Descent)""" n, d = X.shape w = np.zeros(d) for _ in range(n_iter): for j in range(d): r_j = y - X @ w + X[:, j] * w[j] # 排除第j个特征的残差 z_j = X[:, j] @ r_j / n # 软阈值算子 w[j] = np.sign(z_j) * max(abs(z_j) - lam / n, 0) return w lam = 0.5 w_ridge = solve_ridge(X, y, lam) w_lasso = solve_lasso_cd(X, y, lam) print(f"{'参数j':>5} | {'真实值':>8} | {'Ridge估计':>10} | {'Lasso估计':>10} | {'Lasso稀疏?'}") print("-" * 55) for j in range(d): is_sparse = "✓ 零" if abs(w_lasso[j]) < 1e-4 else "" print(f"{j+1:>5} | {true_w[j]:>8.2f} | {w_ridge[j]:>10.4f} | " f"{w_lasso[j]:>10.4f} | {is_sparse}") print(f"\nRidge: {np.sum(np.abs(w_ridge) > 1e-4)} 个非零参数(共{d}个)") print(f"Lasso: {np.sum(np.abs(w_lasso) > 1e-4)} 个非零参数(共{d}个)") print(f"真实: 5 个非零参数") print(f"\n→ Lasso 准确恢复了稀疏结构,Ridge 参数全部非零") # ===== 2. 软阈值算子的可视化 ===== print("\n===== 软阈值算子 S_λ(z) =====\n") def soft_threshold(z, lam): return np.sign(z) * np.maximum(np.abs(z) - lam, 0) lam = 1.0 z_vals = np.array([-3.0, -1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 3.0]) print(f"λ = {lam}") print(f"{'z':>6} | {'S_λ(z)':>10} | {'效果'}") print("-" * 35) for z in z_vals: s = soft_threshold(z, lam) if abs(s) < 1e-10: effect = "→ 置零(|z|≤λ)" else: effect = f"→ 缩减 {lam:.1f}(|z|>λ)" print(f"{z:>6.1f} | {s:>10.4f} | {effect}") # ===== 3. L1/L2 正则化强度 λ 对参数的影响 ===== print("\n===== 正则化强度 λ 对解的影响 =====\n") print(f"{'λ':>8} | {'Ridge非零数':>10} | {'Ridge‖w‖₂':>10} | {'Lasso非零数':>10} | {'Lasso‖w‖₁':>10}") print("-" * 60) for lam in [0.01, 0.1, 0.5, 1.0, 2.0, 5.0]: w_r = solve_ridge(X, y, lam) w_l = solve_lasso_cd(X, y, lam) nz_r = np.sum(np.abs(w_r) > 1e-4) nz_l = np.sum(np.abs(w_l) > 1e-4) print(f"{lam:>8.2f} | {nz_r:>10} | {np.linalg.norm(w_r):>10.4f} | " f"{nz_l:>10} | {np.sum(np.abs(w_l)):>10.4f}") # ===== 4. MoE 路由崩溃与负载均衡损失 ===== print("\n===== MoE 路由崩溃 vs 负载均衡 =====\n") torch.manual_seed(42) n_experts = 8 top_k = 2 n_tokens = 256 d_model = 32 # 模拟路由崩溃:某些专家过热,门控分数偏高 def simulate_routing(n_tokens, n_experts, top_k, bias=None): """模拟 MoE 路由,返回每个专家的负载""" # 随机 token 隐藏状态 H = torch.randn(n_tokens, d_model) # 专家嵌入(门控权重) E = torch.randn(n_experts, d_model) # 计算亲和力分数 scores = torch.sigmoid(H @ E.T) # [n_tokens, n_experts] if bias is not None: scores = scores + bias # 加偏置(动态偏置机制) # Top-k 路由 topk_vals, topk_idx = torch.topk(scores, top_k, dim=-1) # 计算每个专家的负载(处理的token比例) load = torch.zeros(n_experts) for i in range(n_experts): load[i] = (topk_idx == i).sum().float() / (n_tokens * top_k) return load, scores # 均衡损失 def balance_loss(load, scores, alpha=0.01): """DeepSeek 风格的负载均衡损失""" P = scores.mean(dim=0) # 每个专家的平均路由概率 [n_experts] return alpha * (load * P).sum() # 场景1:无均衡损失(可能崩溃) load_no_bal, _ = simulate_routing(n_tokens, n_experts, top_k) # 场景2:均匀偏置模拟动态偏置效果 # 在实际训练中,偏置会动态调整;这里模拟调整后的结果 # 简化:给高负载专家减小偏置 bias = torch.zeros(n_experts) for step in range(50): # 模拟50步动态偏置调整 load, scores = simulate_routing(n_tokens, n_experts, top_k, bias) # 更新偏置 target_load = top_k / n_experts bias = bias - 0.1 * (load - target_load) load_with_bal, _ = simulate_routing(n_tokens, n_experts, top_k, bias) print(f"{'专家':>5} | {'无均衡(负载)':>14} | {'有动态偏置(负载)':>18} | {'目标负载':>10}") print("-" * 58) target = top_k / n_experts for i in range(n_experts): bar_no = "█" * int(load_no_bal[i].item() * 50) bar_bal = "█" * int(load_with_bal[i].item() * 50) print(f"{i+1:>5} | {load_no_bal[i].item():>14.4f} | " f"{load_with_bal[i].item():>18.4f} | {target:>10.4f}") cv_no = (load_no_bal.std() / load_no_bal.mean()).item() cv_bal = (load_with_bal.std() / load_with_bal.mean()).item() print(f"\n变异系数(CV = std/mean,越小越均衡):") print(f" 无均衡: CV = {cv_no:.4f}") print(f" 有动态偏置: CV = {cv_bal:.4f}") print(f"\n→ 动态偏置显著减少了专家负载的不均衡程度") # ===== 5. 负载均衡损失 ∑f_i·P_i 与均匀分布的关系 ===== print("\n===== 负载均衡损失:数学原理 =====\n") n_exp = 8 target_load = 1.0 / n_exp # 均匀分布时每个专家的期望负载 # 不同分布下 ∑f_i² 的值(当 f_i ≈ P_i 时的近似) print("不同负载分布下 ∑f_i² 的值(最小值 = 均匀分布):") print(f"\n{'分布描述':24} | {'∑f_i²':>10} | {'均匀时的∑f_i²':>14} | {'相对值'}") print("-" * 60) uniform_val = n_exp * (1/n_exp)**2 # = 1/n_exp distributions = [ ("均匀(最优)", np.ones(n_exp) / n_exp), ("轻微不均", np.array([0.2, 0.15, 0.15, 0.12, 0.12, 0.1, 0.08, 0.08])), ("中度不均", np.array([0.4, 0.2, 0.1, 0.1, 0.07, 0.06, 0.04, 0.03])), ("严重崩溃(2专家)", np.array([0.45, 0.45, 0.02, 0.02, 0.02, 0.02, 0.01, 0.01])), ("完全崩溃(1专家)", np.array([1.0, 0, 0, 0, 0, 0, 0, 0])), ] for desc, f in distributions: f = np.array(f, dtype=float) f /= f.sum() # 归一化 val = np.sum(f**2) print(f"{desc:24} | {val:>10.6f} | {uniform_val:>14.6f} | {val/uniform_val:.2f}×") print(f"\n→ 均匀分布使 ∑f_i² 最小(=1/n_exp={uniform_val:.4f})") print(f"→ 完全崩溃时 ∑f_i² = 1.0,是均匀时的 {1/uniform_val:.0f}×") print(f"→ 负载均衡损失就是在最小化这个集中度量") # ===== 6. AdamW 权重衰减的效果 ===== print("\n===== 权重衰减 vs 无正则化:过拟合对比 =====\n") torch.manual_seed(1) # 少量训练数据(容易过拟合) n_train, n_test, d = 30, 200, 50 X_train = torch.randn(n_train, d) X_test = torch.randn(n_test, d) true_w = torch.zeros(d) true_w[:5] = torch.tensor([2., -1.5, 1., -0.8, 0.5]) y_train = X_train @ true_w + 0.1 * torch.randn(n_train) y_test = X_test @ true_w + 0.1 * torch.randn(n_test) def train_linear(X_tr, y_tr, X_te, y_te, weight_decay, n_steps=500): model = nn.Linear(d, 1, bias=False) nn.init.normal_(model.weight, std=0.1) opt = torch.optim.AdamW(model.parameters(), lr=0.01, weight_decay=weight_decay) for step in range(n_steps): pred = model(X_tr).squeeze() loss = nn.MSELoss()(pred, y_tr) opt.zero_grad(); loss.backward(); opt.step() train_loss = nn.MSELoss()(model(X_tr).squeeze(), y_tr).item() test_loss = nn.MSELoss()(model(X_te).squeeze(), y_te).item() w_norm = model.weight.norm().item() return train_loss, test_loss, w_norm print(f"{'权重衰减λ':>12} | {'训练损失':>10} | {'测试损失':>10} | {'‖w‖':>8} | 泛化差距") print("-" * 58) for wd in [0.0, 0.001, 0.01, 0.1, 1.0]: tr, te, wn = train_linear(X_train, y_train, X_test, y_test, wd) gap = te - tr flag = " ← 过拟合" if gap > 1.0 else (" ← 欠拟合" if te > 0.5 and wd > 0.5 else "") print(f"{wd:>12.3f} | {tr:>10.4f} | {te:>10.4f} | {wn:>8.3f} | {gap:.4f}{flag}") print(f"\n→ λ=0时训练损失低但测试损失高(过拟合)") print(f"→ 适当的权重衰减使测试损失最低(最优泛化)") print(f"→ λ过大则欠拟合(训练和测试损失都高)")
这篇文章从正则化的根本动机出发,完整推导了 L1/L2 的数学原理和几何直觉,再联系到 DeepSeek V3 的 MoE 专家负载均衡——这是一种"隐藏的正则化",防止路由崩溃,保证所有专家被充分利用。
第一,过拟合源于偏差-方差权衡:模型太复杂方差大(记住噪声),太简单偏差大(学不到规律)。正则化在损失里加复杂度惩罚,限制有效参数数量,改善泛化。
第二,L2 正则化(Ridge)把约束集变成球(无尖角),最优解通常不为零,参数整体收缩。AdamW 的权重衰减就是 L2 正则化的解耦实现,DeepSeek V3 中 $\lambda=0.1$。
第三,L1 正则化(Lasso)把约束集变成菱形(有尖角,尖角在坐标轴上),最优解天然稀疏——许多参数精确为零。软阈值算子 $\mathcal{S}_\lambda(z) = \text{sign}(z) \max(|z|-\lambda, 0)$ 是 L1 的显式解,信号弱于 $\lambda$ 则直接置零。
第四,MoE 的路由崩溃是"赢者通吃"正反馈:被选中的专家变得更好,进而被选中更多,最终少数专家处理所有 token,其余专家废置。
第五,DeepSeek V3 的负载均衡损失 $L_{Bal} = \alpha \sum_i f_i P_i$(其中 $\alpha=0.0001$)是 L2 正则化的类比——最小化专家负载的平方和,使负载分布趋向均匀。$\sum f_i^2$ 的最小值在均匀分布处取得(拉格朗日乘子法),与 L2 正则化使参数均匀收缩同构。
第六,动态偏置机制是另一层保障:根据每个专家的历史负载实时调整路由偏置,过载专家偏置下降(降低被选中概率),欠载专家偏置上升。这是在线学习视角下的自适应均衡,比辅助损失更直接、对主损失干扰更小。
下一篇预告:
从第21篇开始,我们进入第五阶段:神经网络基础。
第21篇讲神经网络的基本结构:从感知机到多层感知机(MLP)——一个神经元计算什么、激活函数为什么必要、MLP 如何组合成通用函数近似器。这是理解 Transformer、MoE、注意力机制的基础构件,把它讲透了,后面的一切都水到渠成。
正则化是一种谦逊:不要相信任何一个参数、任何一个专家、任何一个策略拥有绝对的重要性。通过惩罚"集中"(L2/L1 惩罚大参数,负载均衡损失惩罚过载专家,KL 散度惩罚偏离参考策略),正则化把系统推向"分散"和"均匀"——这不是约束,而是在说:真正鲁棒的知识,应该分散在整个模型里,而不是集中在少数几个地方。
还没有评论,来抢沙发吧!
博客管理员
40 篇文章
还没有评论,来抢沙发吧!