后摩智能 AI Infra 实习
Q: 梯度下降怎么求导?链式求导法则?
梯度下降是神经网络训练的核心优化算法:沿损失函数梯度的反方向更新参数,逐步逼近局部最小值。
更新规则:w = w - lr * dL/dw,其中 lr 是学习率,dL/dw 是损失 L 对参数 w 的偏导数。
链式法则(Chain Rule):复合函数求导的基本工具。若 L = f(g(w)),则 dL/dw = dL/dg * dg/dw。多层网络中每层都是复合函数,梯度通过链式法则从输出层逐层传播回输入层。
反向传播(Backpropagation)就是链式法则的系统化应用:
- 前向传播:计算每层输出并保存中间结果(激活值)
- 反向传播:从 loss 出发,逐层计算梯度。每层利用保存的激活值和上游梯度计算本层参数的梯度
- 时间复杂度与前向相同(约 2x 前向),这是深度学习可训练的基础
PyTorch 的 Autograd:动态记录计算图(每个 tensor 操作形成一条 grad_fn 链),反向时自动遍历图执行链式法则。
Q: ReLU激活函数在0点如何求导?
ReLU 定义:f(x) = max(0, x) = { x, if x > 0; 0, if x <= 0 }
导数:
- x > 0:f’(x) = 1
- x < 0:f’(x) = 0
- x = 0:严格来说不可导(左导数 = 0,右导数 = 1,不相等)
实践处理:定义 x=0 处导数为 0(或 1,或 0.5,不同框架可能不同,PyTorch 用 0)。这是次梯度(subgradient)的概念——对于凸函数在不可导点取次梯度集中的任一值即可。
为什么不影响训练:
- 浮点数精确等于 0 的概率极小(趋近于 0)
- 即使偶尔发生,梯度为 0 只是该步不更新,不会导致错误
- SGD 的随机性保证了不会永远停在 0 点
ReLU 的问题:Dead ReLU——如果某些神经元输出始终 <0(梯度始终为 0),该神经元永远无法恢复。解决:LeakyReLU(x<0 时 f(x)=0.01x)、GELU/SiLU(平滑近似,无死区)。
Q: Softmax的实现及溢出问题?
标准公式:softmax(x_i) = exp(x_i) / sum_j(exp(x_j))
将任意实数向量映射为概率分布(所有元素 >0 且和为 1)。
溢出问题:
- 上溢:exp(x) 当 x > 710(FP64)或 x > 88(FP32)时溢出为 inf
- 下溢:exp(x) 当 x 很小负数时下溢为 0,导致分母可能为 0
解决方案——Safe Softmax(减最大值):
1 | m = max(x) |
数学等价性证明:
1 | exp(x_i - m) / sum(exp(x_j - m)) |
减去 max 后最大的指数变为 exp(0)=1,不会上溢;其他值变为负数的 exp,可能下溢为 0 但不影响结果(它们概率就应该接近 0)。
实现要点:需要两遍遍历(第一遍求 max,第二遍计算 exp 和 sum)。Online Softmax 优化为一遍同时维护 running max 和 running sum。