共计 1729 个字符,预计需要花费 5 分钟才能阅读完成。
核心概念:为什么需要反向传播和激活函数?
在神经网络中,反向传播是训练模型的核心算法,它通过计算损失函数对每个参数的梯度,指导参数更新。而激活函数决定了神经元是否被激活,为网络引入非线性能力。二者配合才能实现有效的学习。

新手常见痛点
刚开始手动实现反向传播时,最容易卡在三个地方:
- 混淆对谁求导(是对输入 x 求导还是对参数 w 求导?)
- 梯度公式推导错误(特别是复合函数的链式法则应用)
- 维度不匹配导致计算崩溃
激活函数梯度推导实战
1. Sigmoid 函数
数学表达式:σ(x) = 1/(1+e^{-x})
梯度推导过程:
– 先求 σ(x) 对 x 的导数:σ'(x) = σ(x)(1-σ(x))
– 在实际反向传播时,我们会收到上游梯度 dL/dσ
– 根据链式法则,最终梯度为:dL/dx = dL/dσ * σ'(x)
Python 实现:
def sigmoid_backward(dL_dsigmoid, x):
"""
dL_dsigmoid: 上游梯度 (dL/dσ)
x: 前向传播时的原始输入
返回: dL/dx
"""
sigmoid = 1 / (1 + np.exp(-x)) # 重新计算前向传播结果
dsigmoid_dx = sigmoid * (1 - sigmoid) # 梯度公式
return dL_dsigmoid * dsigmoid_dx # 链式法则
2. ReLU 函数
数学表达式:ReLU(x) = max(0, x)
梯度特点:
– 当 x >0 时,梯度为 1
– 当 x <= 0 时,梯度为 0
Python 实现:
def relu_backward(dL_drelu, x):
"""
dL_drelu: 上游梯度 (dL/dReLU)
x: 前向传播时的原始输入
返回: dL/dx
"""
dx = np.where(x > 0, dL_drelu, 0) # 按条件选择梯度值
return dx
3. Tanh 函数
数学表达式:tanh(x) = (e^x – e^{-x})/(e^x + e^{-x})
梯度推导:
– tanh'(x) = 1 – tanh²(x)
– 最终梯度:dL/dx = dL/dtanh * (1 – tanh²(x))
Python 实现:
def tanh_backward(dL_dtanh, x):
"""
dL_dtanh: 上游梯度 (dL/dtanh)
x: 前向传播时的原始输入
返回: dL/dx
"""
tanh_x = np.tanh(x) # 重新计算前向传播结果
dtanh_dx = 1 - tanh_x ** 2 # 梯度公式
return dL_dtanh * dtanh_dx # 链式法则
单元测试验证
建议用数值梯度检验实现是否正确:
def test_gradient(func, backward_func, x=1.0, eps=1e-7):
# 数值梯度
fx_plus = func(x + eps)
fx_minus = func(x - eps)
numerical_grad = (fx_plus - fx_minus) / (2 * eps)
# 解析梯度
analytic_grad = backward_func(1.0, x) # 假设上游梯度为 1
# 比较差异
assert abs(numerical_grad - analytic_grad) < 1e-6
print(f"测试通过!数值梯度:{numerical_grad:.6f}, 解析梯度:{analytic_grad:.6f}")
# 测试 Sigmoid
test_gradient(lambda x: 1/(1+np.exp(-x)), sigmoid_backward)
性能考量
三种激活函数在反向传播时的特点:
- Sigmoid:
- 需要重新计算前向传播结果
-
梯度最大值为 0.25,容易出现梯度消失
-
ReLU:
- 不需要存储中间结果
- 计算速度最快
-
可能有神经元死亡问题
-
Tanh:
- 类似 Sigmoid 需要重新计算
- 梯度范围 (0,1],比 Sigmoid 稍好
避坑指南
- 维度问题 :
- 确保输入和梯度的 shape 一致
-
必要时使用 np.reshape 保持维度
-
精度问题 :
- 对 Sigmoid/Tanh,大输入值会导致数值不稳定
-
可对输入做裁剪处理
-
中间结果存储 :
- 实践时通常在前向传播时保存计算结果
- 避免反向传播时重复计算
思考题
如何实现 LeakyReLU 的反向传播?提示:
– LeakyReLU(x) = max(αx, x),其中 α 是小的正数 (如 0.01)
– 反向传播时需要根据 x 的正负选择梯度系数
期待你在评论区分享自己的实现方案!
