激活函数考点:非线性引入的必然性、sigmoid 的梯度饱和、ReLU 家族的权衡、输出层配置惯例。通关标准:用数值实验说明"没有激活函数,百层网络等价于一层"。深度学习编队第一关,练的是积木的物理性质。
关卡一(单选):去掉所有激活函数后,一个百层全连接网络在数学上等价于:
A. 一个更强大的非线性模型
B. 一个单层线性变换
C. 一棵决策树
D. 无法训练的模型
关卡二(单选):关于 sigmoid 函数,说法正确的是:
A. 输出以零为中心,收敛快
B. 输入绝对值很大时导数接近零,深层网络反向传播中梯度容易消失
C. 计算量比 ReLU 大是它的唯一缺点
D. 现在是隐藏层的默认选择
关卡三(多选):关于 ReLU 家族,正确的有:
关卡四(简答):二分类、多分类、回归任务的输出层通常分别配什么激活?
关卡一选 B。 两层无激活的网络是两个线性映射的复合,仍是线性映射:权重矩阵连乘可以合并成一个矩阵。一百层也救不回来——这正是激活函数存在的理由:在每层之间插入非线性,网络的表达能力才随深度增长。
关卡二选 B。 sigmoid 导数最大值只有四分之一,输入绝对值超过五左右就进入饱和区,导数趋近零;多层连乘后梯度指数级衰减,这就是梯度消失的经典机制。A 错(输出恒正,非零中心);C 错(梯度消失才是结构性缺点);D 错(现代隐藏层默认是 ReLU 系)。
关卡三选 1、2、3。 4 错:ReLU 输出负半轴为零、正半轴任意正数,均值不为零,并非零中心。死亡 ReLU 的成因值得记牢:某神经元权重更新后输入长期为负,梯度恒为零,再也无法自我修复——学习率过大是常见诱因。
关卡四:二分类输出层配 sigmoid(单值概率);多分类配 softmax(输出归一化为概率分布);回归通常不配激活(线性输出),除非目标值域有约束(如非负可配 ReLU 或软加)。
先做"百层等一层"的矩阵验证:
# 无激活的百层网络 = 一层线性变换(数值验证) import random random.seed(0) d = 4 W1 = [[random.gauss(0, 0.3) for _ in range(d)] for _ in range(d)] W2 = [[random.gauss(0, 0.3) for _ in range(d)] for _ in range(d)] def matmul(A, B): return [[sum(A[i][k] * B[k][j] for k in range(len(B))) for j in range(len(B[0]))] for i in range(len(A))] x = [[1.0], [0.5], [-0.3], [2.0]] two_layer = matmul(matmul(W2, W1), x) # 两层无激活 merged = matmul(W2, W1) # 合并成一个矩阵 one_layer = matmul(merged, x) print("两层复合 == 合并后单层?", all(abs(a[0] - b[0]) < 1e-12 for a, b in zip(two_layer, one_layer))) # 输出: # 两层复合 == 合并后单层? True
再看梯度饱和的数值现场——sigmoid 导数在饱和区有多惨:
# sigmoid 梯度饱和实验 import math def sigmoid(x): return 1 / (1 + math.exp(-x)) def dsigmoid(x): s = sigmoid(x); return s * (1 - s) for x in [0, 2, 5, 10, -5, -10]: print(f"输入 {x:>3} → sigmoid {sigmoid(x):.6f} → 导数 {dsigmoid(x):.6f}") # 输出: # 输入 0 → sigmoid 0.500000 → 导数 0.250000 # 输入 2 → sigmoid 0.880797 → 导数 0.104994 # 输入 5 → sigmoid 0.993307 → 导数 0.006648 # 输入 10 → sigmoid 0.999955 → 导数 0.000045 # 输入 -5 → sigmoid 0.006693 → 导数 0.006648 # 输入 -10 → sigmoid 0.000045 → 导数 0.000045
导数从峰值零点二五一路掉到十万分之四点五。想象十个这样的因子连乘:量级衰减到十的负四十次方以下,浮点数直接归零。ReLU 正区间的导数恒为一,就不吃这个亏:
# 五层网络梯度量级对比:sigmoid 连乘 vs ReLU 连乘 sig_chain = 1.0 for x in [8, 7, 9, 6, 8]: # 每层输入都落在饱和区 sig_chain *= dsigmoid(x) relu_chain = 1.0 ** 5 # 正区间导数恒为 1 print(f"五层 sigmoid 链末端梯度量级 ≈ {sig_chain:.2e}") print(f"五层 ReLU 链末端梯度量级 = {relu_chain:.1f}") # 输出: # 五层 sigmoid 链末端梯度量级 ≈ 3.11e-17 # 五层 ReLU 链末端梯度量级 = 1.0
同一深度下,一边梯度蒸发成浮点噪声,一边原封不动传到最前线——选 ReLU 做默认的理由就写在这两个数里。
易错点一:"梯度消失只在很深的网络发生"。不,浅层网络里饱和激活加不当初始化同样能触发,深度只是放大器。排查训练不动时,先打印各层梯度范数再下结论。
易错点二:把"死亡 ReLU"和"梯度消失"混为一谈。死亡 ReLU 是特定神经元输入恒负导致局部梯度恒零(病理是稀疏的);梯度消失是饱和激活的链式全局衰减(病理是系统性的)。药方也不同:前者调学习率、换 Leaky ReLU,后者换激活族、加残差连接、归一化层。
变式一:面试官问"softmax 会不会梯度消失"。答:softmax 用于输出层且常与交叉熵联用,联用后的梯度是概率减标签,形式干净、不饱和;把它挪进隐藏层才谈得上风险,而实践中没人这么干。能分清"激活位置与配套损失",说明理解到了配置层面。
变式二:问"既然 ReLU 这么好,为什么 GELU、Swish 又流行起来"。答:平滑激活在负区非零且可导,配合大模型深层结构优化更稳;选型逻辑仍是"梯度健康 + 优化平稳"这条主线,只是权衡点移动了。
复盘产出:决策卡新增"激活配置速查"——隐藏层 ReLU 系、二分类 sigmoid、多分类 softmax、回归线性。下一关让梯度真正流动起来。