1→2→1 结构 DNN 正向传播 & 反向传播完整推导(带实际数值演示)
网络结构:输入层 1 个神经元 → 隐藏层 2 个神经元 → 输出层 1 个神经元
激活函数:Sigmoid $σ(z)=\frac{1}{1+e^{-z}}$,其导数 $σ'(z)=σ(z)(1-σ(z))$
损失函数:均方误差 $L=\frac{1}{2}(y_{true}-y_{pred})^2$
一、初始化参数
输入与标签
$$ x = \begin{bmatrix} 1 \end{bmatrix}, \quad y_{true} = \begin{bmatrix} 0.5 \end{bmatrix} $$
权重与偏置(第一层:输入→隐藏)
$$ W_1 = \begin{bmatrix} 0.5 \\ 0.3 \end{bmatrix}_{2 \times 1}, \quad b_1 = \begin{bmatrix} 0.1 \\ 0.2 \end{bmatrix}_{2 \times 1} $$
权重与偏置(第二层:隐藏→输出)
$$ W_2 = \begin{bmatrix} 0.4 & 0.6 \end{bmatrix}_{1 \times 2}, \quad b_2 = \begin{bmatrix} 0.1 \end{bmatrix}_{1 \times 1} $$
二、正向传播(Forward Propagation)
第 1 步:输入 → 隐藏层线性变换
$$ z_1 = W_1 \cdot x + b_1 = \begin{bmatrix} 0.5 \\ 0.3 \end{bmatrix} \times \begin{bmatrix} 1 \end{bmatrix} + \begin{bmatrix} 0.1 \\ 0.2 \end{bmatrix} = \begin{bmatrix} 0.5 \times 1 + 0.1 \\ 0.3 \times 1 + 0.2 \end{bmatrix} = \begin{bmatrix} 0.6 \\ 0.5 \end{bmatrix} $$
第 2 步:隐藏层激活(Sigmoid)
$$ h_1 = σ(z_{1,1}) = \frac{1}{1+e^{-0.6}} = \frac{1}{1+0.5488} = \frac{1}{1.5488} = 0.6457 $$ $$ h_2 = σ(z_{1,2}) = \frac{1}{1+e^{-0.5}} = \frac{1}{1+0.6065} = \frac{1}{1.6065} = 0.6225 $$
$$ h = \begin{bmatrix} h_1 \\ h_2 \end{bmatrix} = \begin{bmatrix} 0.6457 \\ 0.6225 \end{bmatrix} $$
第 3 步:隐藏 → 输出层线性变换
$$ z_2 = W_2 \cdot h + b_2 = \begin{bmatrix} 0.4 & 0.6 \end{bmatrix} \times \begin{bmatrix} 0.6457 \\ 0.6225 \end{bmatrix} + \begin{bmatrix} 0.1 \end{bmatrix} $$
$$ z_2 = 0.4 \times 0.6457 + 0.6 \times 0.6225 + 0.1 = 0.2583 + 0.3735 + 0.1 = 0.7318 $$
第 4 步:输出层激活
$$ y_{pred} = σ(z_2) = \frac{1}{1+e^{-0.7318}} = \frac{1}{1+0.4807} = \frac{1}{1.4807} = 0.6753 $$
第 5 步:计算损失
$$ L = \frac{1}{2}(y_{true} - y_{pred})^2 = \frac{1}{2}(0.5 - 0.6753)^2 = \frac{1}{2}(-0.1753)^2 = \frac{1}{2} \times 0.0307 = 0.0154 $$
三、反向传播(Backward Propagation)
反向传播的核心是链式法则(Chain Rule)。我们从输出层开始,逐层向前计算梯度。
符号约定
| 符号 | 含义 | 维度 |
|---|---|---|
| $∂L/∂y_{pred}$ | 损失对输出的梯度 | $1 \times 1$ |
| $∂L/∂z_2$ | 损失对输出层线性输出的梯度 | $1 \times 1$ |
| $∂L/∂W_2$ | 损失对第二层权重的梯度 | $1 \times 2$ |
| $∂L/∂b_2$ | 损失对第二层偏置的梯度 | $1 \times 1$ |
| $∂L/∂h$ | 损失对隐藏层输出的梯度 | $2 \times 1$ |
| $∂L/∂z_1$ | 损失对隐藏层线性输出的梯度 | $2 \times 1$ |
| $∂L/∂W_1$ | 损失对第一层权重的梯度 | $2 \times 1$ |
| $∂L/∂b_1$ | 损失对第一层偏置的梯度 | $2 \times 1$ |
3.1 输出层梯度
#### ① 损失对预测值的梯度
$$ \frac{\partial L}{\partial y_{pred}} = \frac{\partial}{\partial y_{pred}} \left[ \frac{1}{2}(y_{true} - y_{pred})^2 \right] = -(y_{true} - y_{pred}) = y_{pred} - y_{true} $$
代入数值: $$ \frac{\partial L}{\partial y_{pred}} = 0.6753 - 0.5 = 0.1753 $$
#### ② 损失对 $z_2$ 的梯度(链式法则第一步)
$$ \frac{\partial L}{\partial z_2} = \frac{\partial L}{\partial y_{pred}} \cdot \frac{\partial y_{pred}}{\partial z_2} = \frac{\partial L}{\partial y_{pred}} \cdot σ'(z_2) $$
计算 $σ'(z_2)$: $$ σ'(z_2) = σ(z_2)(1-σ(z_2)) = y_{pred}(1-y_{pred}) = 0.6753 \times (1-0.6753) = 0.6753 \times 0.3247 = 0.2193 $$
$$ \frac{\partial L}{\partial z_2} = 0.1753 \times 0.2193 = 0.0384 $$
#### ③ 损失对 $W_2$ 的梯度
$$ \frac{\partial L}{\partial W_2} = \frac{\partial L}{\partial z_2} \cdot \frac{\partial z_2}{\partial W_2} = \frac{\partial L}{\partial z_2} \cdot h^T $$
$$ \frac{\partial L}{\partial W_2} = 0.0384 \times \begin{bmatrix} 0.6457 & 0.6225 \end{bmatrix} = \begin{bmatrix} 0.0384 \times 0.6457 & 0.0384 \times 0.6225 \end{bmatrix} = \begin{bmatrix} 0.0248 & 0.0239 \end{bmatrix} $$
#### ④ 损失对 $b_2$ 的梯度
$$ \frac{\partial L}{\partial b_2} = \frac{\partial L}{\partial z_2} \cdot \frac{\partial z_2}{\partial b_2} = \frac{\partial L}{\partial z_2} \cdot 1 = 0.0384 $$
3.2 隐藏层梯度
#### ⑤ 损失对隐藏层输出 $h$ 的梯度
$$ \frac{\partial L}{\partial h} = W_2^T \cdot \frac{\partial L}{\partial z_2} $$
$$ \frac{\partial L}{\partial h} = \begin{bmatrix} 0.4 \\ 0.6 \end{bmatrix} \times 0.0384 = \begin{bmatrix} 0.4 \times 0.0384 \\ 0.6 \times 0.0384 \end{bmatrix} = \begin{bmatrix} 0.0154 \\ 0.0230 \end{bmatrix} $$
#### ⑥ 损失对 $z_1$ 的梯度(逐元素乘 $\odot$ 表示 Hadamard 积)
$$ \frac{\partial L}{\partial z_1} = \frac{\partial L}{\partial h} \odot σ'(z_1) $$
计算 $σ'(z_1)$(逐元素): $$ σ'(z_{1,1}) = h_1(1-h_1) = 0.6457 \times (1-0.6457) = 0.6457 \times 0.3543 = 0.2288 $$ $$ σ'(z_{1,2}) = h_2(1-h_2) = 0.6225 \times (1-0.6225) = 0.6225 \times 0.3775 = 0.2350 $$
$$ \frac{\partial L}{\partial z_1} = \begin{bmatrix} 0.0154 \times 0.2288 \\ 0.0230 \times 0.2350 \end{bmatrix} = \begin{bmatrix} 0.0035 \\ 0.0054 \end{bmatrix} $$
#### ⑦ 损失对 $W_1$ 的梯度
$$ \frac{\partial L}{\partial W_1} = \frac{\partial L}{\partial z_1} \cdot x^T $$
$$ \frac{\partial L}{\partial W_1} = \begin{bmatrix} 0.0035 \\ 0.0054 \end{bmatrix} \times \begin{bmatrix} 1 \end{bmatrix} = \begin{bmatrix} 0.0035 \\ 0.0054 \end{bmatrix} $$
#### ⑧ 损失对 $b_1$ 的梯度
$$ \frac{\partial L}{\partial b_1} = \frac{\partial L}{\partial z_1} = \begin{bmatrix} 0.0035 \\ 0.0054 \end{bmatrix} $$
四、参数更新(Gradient Descent)
设学习率 $\eta = 0.1$,使用 $W = W - \eta \cdot \frac{\partial L}{\partial W}$ 更新参数。
更新 $W_1$
$$ W_1^{new} = \begin{bmatrix} 0.5 \\ 0.3 \end{bmatrix} - 0.1 \times \begin{bmatrix} 0.0035 \\ 0.0054 \end{bmatrix} = \begin{bmatrix} 0.5 - 0.00035 \\ 0.3 - 0.00054 \end{bmatrix} = \begin{bmatrix} 0.49965 \\ 0.29946 \end{bmatrix} $$
更新 $b_1$
$$ b_1^{new} = \begin{bmatrix} 0.1 \\ 0.2 \end{bmatrix} - 0.1 \times \begin{bmatrix} 0.0035 \\ 0.0054 \end{bmatrix} = \begin{bmatrix} 0.1 - 0.00035 \\ 0.2 - 0.00054 \end{bmatrix} = \begin{bmatrix} 0.09965 \\ 0.19946 \end{bmatrix} $$
更新 $W_2$
$$ W_2^{new} = \begin{bmatrix} 0.4 & 0.6 \end{bmatrix} - 0.1 \times \begin{bmatrix} 0.0248 & 0.0239 \end{bmatrix} = \begin{bmatrix} 0.4 - 0.00248 & 0.6 - 0.00239 \end{bmatrix} = \begin{bmatrix} 0.39752 & 0.59761 \end{bmatrix} $$
更新 $b_2$
$$ b_2^{new} = \begin{bmatrix} 0.1 \end{bmatrix} - 0.1 \times \begin{bmatrix} 0.0384 \end{bmatrix} = \begin{bmatrix} 0.1 - 0.00384 \end{bmatrix} = \begin{bmatrix} 0.09616 \end{bmatrix} $$
五、一次迭代后的验证
用更新后的参数再做一次正向传播,看损失是否下降。
新前向传播
$$ z_1^{new} = W_1^{new} \cdot x + b_1^{new} = \begin{bmatrix} 0.49965 \\ 0.29946 \end{bmatrix} + \begin{bmatrix} 0.09965 \\ 0.19946 \end{bmatrix} = \begin{bmatrix} 0.59930 \\ 0.49892 \end{bmatrix} $$
$$ h^{new} = \begin{bmatrix} σ(0.59930) \\ σ(0.49892) \end{bmatrix} = \begin{bmatrix} \frac{1}{1+e^{-0.59930}} \\ \frac{1}{1+e^{-0.49892}} \end{bmatrix} = \begin{bmatrix} \frac{1}{1+0.5493} \\ \frac{1}{1+0.6073} \end{bmatrix} = \begin{bmatrix} \frac{1}{1.5493} \\ \frac{1}{1.6073} \end{bmatrix} = \begin{bmatrix} 0.6455 \\ 0.6222 \end{bmatrix} $$
$$ z_2^{new} = W_2^{new} \cdot h^{new} + b_2^{new} = 0.39752 \times 0.6455 + 0.59761 \times 0.6222 + 0.09616 = 0.2566 + 0.3719 + 0.09616 = 0.7247 $$
$$ y_{pred}^{new} = σ(0.7247) = \frac{1}{1+e^{-0.7247}} = \frac{1}{1+0.4844} = \frac{1}{1.4844} = 0.6737 $$
新损失
$$ L^{new} = \frac{1}{2}(0.5 - 0.6737)^2 = \frac{1}{2}(-0.1737)^2 = \frac{1}{2} \times 0.0302 = 0.0151 $$
损失对比
$$ L^{old} = 0.0154 \quad \Longrightarrow \quad L^{new} = 0.0151 $$
损失从 0.0154 下降到 0.0151,✅ 梯度下降有效!
六、完整梯度推导总结(公式汇总)
正向传播公式链
$$ \begin{aligned} z_1 &= W_1 x + b_1 \\ h &= σ(z_1) \\ z_2 &= W_2 h + b_2 \\ y_{pred} &= σ(z_2) \\ L &= \frac{1}{2}(y_{true} - y_{pred})^2 \end{aligned} $$
反向传播公式链(从后往前)
$$ \begin{aligned} \frac{\partial L}{\partial y_{pred}} &= y_{pred} - y_{true} \\[4pt] \frac{\partial L}{\partial z_2} &= \frac{\partial L}{\partial y_{pred}} \cdot σ'(z_2) \\[4pt] \frac{\partial L}{\partial W_2} &= \frac{\partial L}{\partial z_2} \cdot h^T \\[4pt] \frac{\partial L}{\partial b_2} &= \frac{\partial L}{\partial z_2} \\[4pt] \frac{\partial L}{\partial h} &= W_2^T \cdot \frac{\partial L}{\partial z_2} \\[4pt] \frac{\partial L}{\partial z_1} &= \frac{\partial L}{\partial h} \odot σ'(z_1) \\[4pt] \frac{\partial L}{\partial W_1} &= \frac{\partial L}{\partial z_1} \cdot x^T \\[4pt] \frac{\partial L}{\partial b_1} &= \frac{\partial L}{\partial z_1} \end{aligned} $$
参数更新
$$ W_i \leftarrow W_i - \eta \frac{\partial L}{\partial W_i}, \quad b_i \leftarrow b_i - \eta \frac{\partial L}{\partial b_i} $$
七、维度检查(重要!)
在实际编码中,维度匹配是调试的关键。
| 变量 | 维度 | 说明 |
|---|---|---|
| $x$ | $1 \times 1$ | 输入样本 |
| $W_1$ | $2 \times 1$ | 输入→隐藏权重 |
| $b_1$ | $2 \times 1$ | 隐藏层偏置 |
| $z_1, h$ | $2 \times 1$ | 隐藏层线性/激活输出 |
| $W_2$ | $1 \times 2$ | 隐藏→输出权重 |
| $b_2$ | $1 \times 1$ | 输出层偏置 |
| $z_2, y_{pred}$ | $1 \times 1$ | 输出层线性/激活输出 |
| $∂L/∂W_2$ | $1 \times 2$ | 与 $W_2$ 同形 |
| $∂L/∂b_2$ | $1 \times 1$ | 与 $b_2$ 同形 |
| $∂L/∂W_1$ | $2 \times 1$ | 与 $W_1$ 同形 |
| $∂L/∂b_1$ | $2 \times 1$ | 与 $b_1$ 同形 |
核心原则:每个参数的梯度与其本身形状完全相同,这是梯度下降更新的前提。
八、关键概念图解
flowchart LR
subgraph 正向传播
x["x = [1]"] --> W1["W₁·x + b₁"]
W1 --> z1["z₁ = [0.6, 0.5]ᵀ"]
z1 --> h["h = σ(z₁) = [0.6457, 0.6225]ᵀ"]
h --> W2["W₂·h + b₂"]
W2 --> z2["z₂ = [0.7318]"]
z2 --> y["y_pred = σ(z₂) = [0.6753]"]
y --> Loss["L = ½(0.5−0.6753)² = 0.0154"]
end
subgraph 反向传播
Loss --> dL_dy["∂L/∂y = 0.1753"]
dL_dy --> dL_dz2["∂L/∂z₂ = 0.0384"]
dL_dz2 --> dL_dW2["∂L/∂W₂ = [0.0248, 0.0239]"]
dL_dz2 --> dL_db2["∂L/∂b₂ = 0.0384"]
dL_dz2 --> dL_dh["∂L/∂h = [0.0154, 0.0230]ᵀ"]
dL_dh --> dL_dz1["∂L/∂z₁ = [0.0035, 0.0054]ᵀ"]
dL_dz1 --> dL_dW1["∂L/∂W₁ = [0.0035, 0.0054]ᵀ"]
dL_dz1 --> dL_db1["∂L/∂b₁ = [0.0035, 0.0054]ᵀ"]
end
九、Python 代码验证
import numpy as np
def sigmoid(z):
return 1 / (1 + np.exp(-z))
def sigmoid_derivative(z):
s = sigmoid(z)
return s * (1 - s)
# 初始化
x = np.array([[1.0]])
y_true = np.array([[0.5]])
W1 = np.array([[0.5], [0.3]])
b1 = np.array([[0.1], [0.2]])
W2 = np.array([[0.4, 0.6]])
b2 = np.array([[0.1]])
eta = 0.1
# 正向传播
z1 = W1 @ x + b1
h = sigmoid(z1)
z2 = W2 @ h + b2
y_pred = sigmoid(z2)
loss = 0.5 * (y_true - y_pred) ** 2
print(f"正向: y_pred={y_pred[0,0]:.4f}, loss={loss[0,0]:.6f}")
# 反向传播
dL_dy = y_pred - y_true
dL_dz2 = dL_dy * sigmoid_derivative(z2)
dL_dW2 = dL_dz2 @ h.T
dL_db2 = dL_dz2
dL_dh = W2.T @ dL_dz2
dL_dz1 = dL_dh * sigmoid_derivative(z1)
dL_dW1 = dL_dz1 @ x.T
dL_db1 = dL_dz1
# 更新
W1 -= eta * dL_dW1
b1 -= eta * dL_db1
W2 -= eta * dL_dW2
b2 -= eta * dL_db2
# 验证
z1_new = W1 @ x + b1
h_new = sigmoid(z1_new)
z2_new = W2 @ h_new + b2
y_pred_new = sigmoid(z2_new)
loss_new = 0.5 * (y_true - y_pred_new) ** 2
print(f"更新后: y_pred={y_pred_new[0,0]:.4f}, loss={loss_new[0,0]:.6f}")
print(f"损失下降: {loss[0,0]:.6f} → {loss_new[0,0]:.6f}")
预期输出:
正向: y_pred=0.6753, loss=0.015365
更新后: y_pred=0.6737, loss=0.015106
损失下降: 0.015365 → 0.015106
十、总结
| 阶段 | 关键操作 | 维度变化 |
|---|---|---|
| 正向 | 线性变换 → 激活 → 线性变换 → 激活 → 损失 | $1 \to 2 \to 1$ |
| 反向 | 链式法则逐层求导,梯度与参数同形 | $1 \to 2 \to 1$(反向传播) |
| 更新 | $W \leftarrow W - \eta \cdot \nabla_W L$ | 保持同形 |
记住三条核心规律
- 梯度与参数同形:$\frac{\partial L}{\partial W}$ 的形状永远等于 $W$ 的形状
- 链式法则的核心:每一层的梯度 = 上层传来的梯度 × 本层激活函数的导数 × 本层输入的转置
- 维度即协议:正向传播中矩阵能相乘,反向传播中就一定能计算——因为转置操作恰好把维度匹配回来