反向传播
概念
反向传播(Backpropagation)是计算损失函数对神经网络中每个参数的梯度的算法。它应用微积分中的链式法则,从输出层向输入层逐层传递梯度。
设损失函数为
- 权重梯度
- 偏置梯度
这些梯度用于优化器更新参数。
链式法则
标量链式法则
若
矩阵链式法则
神经网络中的操作都是矩阵/向量级别的。考虑一个线性层:
给定损失对输出的梯度
线性层的梯度推导
1. 对输入的梯度
从元素角度展开。设
对某个
即
2. 对权重的梯度
对某个
即
3. 对偏置的梯度
偏置对每个样本的输出贡献相同:
即 keepdims=True)。
激活层的梯度
激活函数逐元素操作
其中
| 激活函数 | |
|---|---|
| ReLU | |
| Sigmoid | |
| Tanh |
代码实现:LinearLayer.backward()
src/nn/layers/linearLayer.py:107-150:
python
def backward(self, outputGradient: np.ndarray) -> np.ndarray:
# dL/dX = dL/dY @ W^T
inputGradient = outputGradient @ self.weights.T
# dL/dW = X^T @ dL/dY
self.gradWeights[...] = self.inputCache.T @ outputGradient
# dL/dBias = sum(dL/dY, axis=0, keepdims=True)
if self.useBias and self.gradBias is not None:
self.gradBias[...] = np.sum(outputGradient, axis=0, keepdims=True)
return inputGradient注意 [...] = 语法是就地覆盖(不是累加)。这意味着每次 backward 前必须先 zeroGrad() 清除旧的梯度。
全局反向传播流程
src/nn/models/sequentialModel.py:91-112 中的 SequentialModel.backward() 协调全局反向传播:
python
def backward(self, outputGradient: np.ndarray) -> np.ndarray:
inputGradient = outputGradient
# 从最后一层向前,逐层反向传播
for layer in reversed(self.layers):
inputGradient = layer.backward(inputGradient)
return inputGradient完整训练步骤中的梯度流:
每一步的 layer.backward() 同时:
- 计算并存储该层参数的梯度(
self.gradWeights,self.gradBias) - 返回对输入的梯度(供上一层继续传播)
具体数值示例
以下是一个极简的二层网络反向传播演示。
设定:
- 输入
(2 个样本,2 维特征) , ,
前向传播:
假设损失梯度
反向传播第 2 层:
❌
等等 — 这里让我更正。
反向传播第 1 层(ReLU):
- ReLU 的导数掩码:
(所有值 > 0)
反向传播第 1 层(Linear):
这些梯度随后由优化器用于参数更新。