引言:从概率视角看AI的本质
在探索神经网络奥秘的旅程中,我们不得不先审视一个深刻的认知:无论是当下令人瞩目的生成式 AI,还是朝着通用人工智能(AGI)迈进的探索,本质上都与“概率模型”紧密相连。从单纯的概率框架出发,现实世界复杂事件的联合分布可被统一表征,而神经网络的非线性拟合能力,又依托通用逼近定理、柯尔莫哥洛夫理论等数学基石。信息论中“压缩即智能”的理念,更是为我们理解 AI 如何从海量数据中提炼规律、模拟智能提供了独特视角。
值得深思的是,我们所处的现实世界本身就充满不确定性,是天然的概率模型,可人们往往追求确定性。这种思维转变,对深入理解 AI 本质与大模型运行逻辑,有着至关重要的意义。为了具体地理解这一过程,就让我们一同拆解一个简单的神经网络,探寻其与概率模型、现实世界的交织脉络。
神经网络如下图所示:

一、 网络结构与初始化
1. 网络结构
- 输入层 (Layer 1): 3 个输入神经元,接收初始数据。
- 隐含层 (Layer 2): 2 个神经元,负责非线性变换。
- 权重矩阵 W ( 1 ) \mathbf{W}^{(1)} W(1) 维度为 2×3。
- 偏置向量 b ( 1 ) \mathbf{b}^{(1)} b(1) 维度为 2×1。
- 激活函数:Sigmoid (为了简单示例,当然也可用 ReLU、Tanh 等)。
- 输出层 (Layer 3): 3 个神经元,对应最终 3 个类别的分类。
- 权重矩阵 W ( 2 ) \mathbf{W}^{(2)} W(2) 维度为 3×2。
- 偏置向量 b ( 2 ) \mathbf{b}^{(2)} b(2)维度为 3×1。
- 输出处理:不使用 Sigmoid,而是直接输出 logits,然后通过 Softmax 函数计算概率分布,最后使用 交叉熵 (Cross-Entropy) 作为损失。
关于权重矩阵维度的说明:
例如, W ( 1 ) \mathbf{W}^{(1)} W(1) 连接第1层(3个神经元)和第2层(2个神经元),其维度为 2x3。这保证了 W ( 1 ) a ( 1 ) + b ( 1 ) \mathbf{W}^{(1)} \mathbf{a}^{(1)} + \mathbf{b}^{(1)} W(1)a(1)+b(1) 的矩阵乘法能够顺利进行。
2. 参数初始化
在训练初始,我们可随机初始化参数。为方便演示和复现,这里我们直接给出一组固定的示例数值。
-
输入
a ( 1 ) = [ 1.0 1.0 1.0 ] \mathbf{a}^{(1)} = \begin{bmatrix}1.0 \\ 1.0 \\ 1.0\end{bmatrix} a(1)= 1.01.01.0 -
隐含层参数:
W ( 1 ) = [ 0.10 0.20 0.30 0.40 0.50 0.60 ] , b ( 1 ) = [ 0.10 0.10 ] \mathbf{W}^{(1)} = \begin{bmatrix} 0.10 & 0.20 & 0.30\\ 0.40 & 0.50 & 0.60 \end{bmatrix}, \quad \mathbf{b}^{(1)} = \begin{bmatrix} 0.10 \\ 0.10 \end{bmatrix} W(1)=[0.100.400.200.500.300.60],b(1)=[0.100.10] -
输出层参数 :
W ( 2 ) = [ 0.70 0.80 0.90 1.00 1.10 1.20 ] , b ( 2 ) = [ 0.20 0.20 0.20 ] \mathbf{W}^{(2)} = \begin{bmatrix} 0.70 & 0.80\\ 0.90 & 1.00\\ 1.10 & 1.20 \end{bmatrix}, \quad \mathbf{b}^{(2)} = \begin{bmatrix} 0.20 \\ 0.20 \\ 0.20 \end{bmatrix} W(2)= 0.700.901.100.801.001.20 ,b(2)= 0.200.200.20
二、 前向传播:一步步计算网络输出
前向传播(Forward Propagation)是指数据从输入层流向输出层的过程。
1. 隐含层 (Layer 2) 的计算
首先,计算进入隐含层激活函数前的线性组合
z
(
2
)
\mathbf{z}^{(2)}
z(2)。
z
(
2
)
=
W
(
1
)
a
(
1
)
+
b
(
1
)
\mathbf{z}^{(2)} = \mathbf{W}^{(1)} \mathbf{a}^{(1)} + \mathbf{b}^{(1)}
z(2)=W(1)a(1)+b(1)
由于
W
(
1
)
\mathbf{W}^{(1)}
W(1) 是
2
×
3
2 \times 3
2×3、
a
(
1
)
\mathbf{a}^{(1)}
a(1) 是
3
×
1
3 \times 1
3×1、
b
(
1
)
\mathbf{b}^{(1)}
b(1) 是
2
×
1
2 \times 1
2×1,所以
z
(
2
)
=
[
0.10
0.20
0.30
0.40
0.50
0.60
]
[
1.0
1.0
1.0
]
+
[
0.10
0.10
]
=
[
(
0.10
+
0.20
+
0.30
)
+
0.10
(
0.40
+
0.50
+
0.60
)
+
0.10
]
=
[
0.70
1.60
]
\begin{align} &\mathbf{z}^{(2)} = \begin{bmatrix} 0.10 & 0.20 & 0.30\\ 0.40 & 0.50 & 0.60 \end{bmatrix} \begin{bmatrix} 1.0 \\ 1.0 \\ 1.0 \end{bmatrix} + \begin{bmatrix} 0.10 \\ 0.10 \end{bmatrix} = \\ &\begin{bmatrix} (0.10 + 0.20 + 0.30) + 0.10 \\ (0.40 + 0.50 + 0.60) + 0.10 \end{bmatrix}= \begin{bmatrix} 0.70 \\ 1.60 \end{bmatrix} \end{align}
z(2)=[0.100.400.200.500.300.60]
1.01.01.0
+[0.100.10]=[(0.10+0.20+0.30)+0.10(0.40+0.50+0.60)+0.10]=[0.701.60]
然后,将
z
(
2
)
\mathbf{z}^{(2)}
z(2) 通过 Sigmoid 激活函数,得到隐含层的输出
a
(
2
)
\mathbf{a}^{(2)}
a(2)。
a
(
2
)
=
σ
(
z
(
2
)
)
,
σ
(
x
)
=
1
1
+
e
−
x
\mathbf{a}^{(2)} = \sigma\bigl(\mathbf{z}^{(2)}\bigr), \quad \sigma(x) = \frac{1}{1 + e^{-x}}
a(2)=σ(z(2)),σ(x)=1+e−x1
对应分量:
a
1
(
2
)
=
1
1
+
e
−
0.70
≈
0.66818777
,
a
2
(
2
)
=
1
1
+
e
−
1.60
≈
0.83201839
\begin{align} &a_1^{(2)} = \frac{1}{1 + e^{-0.70}} \approx 0.66818777,\quad \\ &a_2^{(2)} = \frac{1}{1 + e^{-1.60}} \approx 0.83201839 \end{align}
a1(2)=1+e−0.701≈0.66818777,a2(2)=1+e−1.601≈0.83201839
故:
a
(
2
)
≈
[
0.66818777
0.83201839
]
\mathbf{a}^{(2)} \approx \begin{bmatrix} 0.66818777 \\ 0.83201839 \end{bmatrix}
a(2)≈[0.668187770.83201839]
核心概念:
- z通常表示某一层线性计算(权重乘法和偏置加法)的结果。
- a通常表示 z经过激活函数后的输出,它将作为下一层的输入。
2. 输出层 (Layer 3) 的计算
接下来,用隐含层的输出
a
(
2
)
\mathbf{a}^{(2)}
a(2) 计算输出层的线性组合
z
(
3
)
\mathbf{z}^{(3)}
z(3),也称为 logits。
z
(
3
)
=
W
(
2
)
a
(
2
)
+
b
(
2
)
\mathbf{z}^{(3)} = \mathbf{W}^{(2)}\, \mathbf{a}^{(2)} + \mathbf{b}^{(2)}
z(3)=W(2)a(2)+b(2)
然后,对 logits
z
(
3
)
\mathbf{z}^{(3)}
z(3) 应用 Softmax 函数,得到最终的概率分布输出
a
(
3
)
\mathbf{a}^{(3)}
a(3)。其中
W
(
2
)
\mathbf{W}^{(2)}
W(2) 是
3
×
2
3 \times 2
3×2、
a
(
2
)
\mathbf{a}^{(2)}
a(2) 是
2
×
1
2 \times 1
2×1、
b
(
2
)
\mathbf{b}^{(2)}
b(2) 是
3
×
1
3 \times 1
3×1。数值计算如下:
z
(
3
)
=
[
0.70
0.80
0.90
1.00
1.10
1.20
]
[
0.66818777
0.83201839
]
+
[
0.20
0.20
0.20
]
=
[
0.70
×
0.66818777
+
0.80
×
0.83201839
0.90
×
0.66818777
+
1.00
×
0.83201839
1.10
×
0.66818777
+
1.20
×
0.83201839
]
+
[
0.20
0.20
0.20
]
≈
[
1.33334615
1.63338738
1.93240000
]
\begin{aligned} \mathbf{z}^{(3)} &= \begin{bmatrix} 0.70 & 0.80\\ 0.90 & 1.00\\ 1.10 & 1.20 \end{bmatrix} \begin{bmatrix} 0.66818777 \\ 0.83201839 \end{bmatrix} + \begin{bmatrix} 0.20 \\ 0.20 \\ 0.20 \end{bmatrix}\\ &= \begin{bmatrix} 0.70 \times 0.66818777 + 0.80 \times 0.83201839\\ 0.90 \times 0.66818777 + 1.00 \times 0.83201839\\ 1.10 \times 0.66818777 + 1.20 \times 0.83201839 \end{bmatrix} + \begin{bmatrix} 0.20\\ 0.20\\ 0.20 \end{bmatrix}\\ &\approx \begin{bmatrix} 1.33334615 \\ 1.63338738 \\ 1.93240000 \end{bmatrix} \end{aligned}
z(3)=
0.700.901.100.801.001.20
[0.668187770.83201839]+
0.200.200.20
=
0.70×0.66818777+0.80×0.832018390.90×0.66818777+1.00×0.832018391.10×0.66818777+1.20×0.83201839
+
0.200.200.20
≈
1.333346151.633387381.93240000
然后对 logits 做 Softmax 得到输出层的激活
a
(
3
)
\mathbf{a}^{(3)}
a(3):
a
i
(
3
)
=
e
z
i
(
3
)
∑
j
e
z
j
(
3
)
a_i^{(3)} = \frac{e^{z_i^{(3)}}}{\sum_j e^{z_j^{(3)}}}
ai(3)=∑jezj(3)ezi(3)
分母是
e
1.3333
+
e
1.6334
+
e
1.9324
e^{1.3333} + e^{1.6334} + e^{1.9324}
e1.3333+e1.6334+e1.9324。我们分别计算 (取近似):
- e 1.3333 ≈ 3.793 e^{1.3333} \approx 3.793 e1.3333≈3.793
- e 1.6334 ≈ 5.120 e^{1.6334} \approx 5.120 e1.6334≈5.120
-
e
1.9324
≈
6.909
e^{1.9324} \approx 6.909
e1.9324≈6.909
因此分母 ≈ 3.793 + 5.120 + 6.909 = 15.822 \approx 3.793 + 5.120 + 6.909 = 15.822 ≈3.793+5.120+6.909=15.822
各分量: - a 1 ( 3 ) ≈ 3.793 / 15.822 ≈ 0.2397 a_1^{(3)} \approx 3.793 / 15.822 \approx 0.2397 a1(3)≈3.793/15.822≈0.2397
- a 2 ( 3 ) ≈ 5.120 / 15.822 ≈ 0.3236 a_2^{(3)} \approx 5.120 / 15.822 \approx 0.3236 a2(3)≈5.120/15.822≈0.3236
-
a
3
(
3
)
≈
6.909
/
15.822
≈
0.4367
a_3^{(3)} \approx 6.909 / 15.822 \approx 0.4367
a3(3)≈6.909/15.822≈0.4367
故输出层最终得到的概率分布 (Softmax) 为:
a ( 3 ) ≈ [ 0.2397 0.3236 0.4367 ] \mathbf{a}^{(3)} \approx \begin{bmatrix} 0.2397 \\ 0.3236 \\ 0.4367 \end{bmatrix} a(3)≈ 0.23970.32360.4367
至此,一次完整的前向传播完成。我们得到了模型对输入样本的预测概率分布。
三、 损失函数:衡量预测与现实的差距
我们使用交叉熵损失 (Cross-Entropy Loss) 来衡量模型预测
a
(
3
)
\mathbf{a}^{(3)}
a(3)与真实标签 t 之间的差距。
为什么选择交叉熵?
在像大语言模型这样的现代分类任务中,交叉熵是首选损失函数。当预测概率偏离真实标签(概率为1)时,它会产生一个非常大的损失值(梯度很陡),这能更高效地指导模型参数更新,从而加快收敛速度。相比之下,均方差(MSE)在分类问题中容易出现梯度消失,导致训练缓慢。
假设我们的真实标签是类别 1,其 one-hot 编码为
t
=
[
1
,
0
,
0
]
T
\mathbf{t} = [1,\, 0,\, 0]^T
t=[1,0,0]T。
交叉熵损失 (Cross-Entropy) 定义为:
L
=
−
∑
i
t
i
ln
(
a
i
(
3
)
)
L = -\sum_{i} t_i \ln(a_i^{(3)})
L=−i∑tiln(ai(3))
在本例中,只有
t
1
=
1
t_1=1
t1=1,其余为 0,因此
a
(
3
)
≈
[
0.2397
0.3236
0.4367
]
L
=
−
(
t
1
∗
l
n
(
a
1
(
3
)
)
+
t
2
∗
l
n
(
a
2
(
3
)
)
+
t
3
∗
l
n
(
a
3
(
3
)
)
)
L
=
−
(
1
∗
l
n
(
0.2397
)
+
0
∗
l
n
(
0.3236
)
+
0
∗
l
n
(
0.4367
)
)
L
=
−
ln
(
a
1
(
3
)
)
=
−
ln
(
0.2397
)
≈
1.434
\begin{align} &\mathbf{a}^{(3)} \approx \begin{bmatrix} 0.2397 \\ 0.3236 \\ 0.4367 \end{bmatrix} \\ & L = - (t_1 * ln(a^{(3)}_1) + t_2 * ln(a^{(3)}_2) + t_3 * ln(a^{(3)}_3)) \\ &L = - (1 * ln(0.2397) + 0 * ln(0.3236) + 0 * ln(0.4367)) \\ &L = - \ln(a_1^{(3)}) = - \ln(0.2397) \approx 1.434 \\ \end{align}
a(3)≈
0.23970.32360.4367
L=−(t1∗ln(a1(3))+t2∗ln(a2(3))+t3∗ln(a3(3)))L=−(1∗ln(0.2397)+0∗ln(0.3236)+0∗ln(0.4367))L=−ln(a1(3))=−ln(0.2397)≈1.434
计算得到的损失 L ≈ 1.434。这个值表示当前模型预测的“错误程度”,我们的目标就是通过调整权重和偏置来让这个值变得尽可能小。
注意:以上是单个样本的损失。在实际训练中,通常会计算一个批次(mini-batch)中所有样本的平均损失,然后根据这个平均损失进行一次反向传播。
四、 反向传播:误差的逐层归因
反向传播(Backpropagation)是训练神经网络的核心。它通过链式法则,将输出层的总损失(误差)逐层向后传递,并计算出每一层参数(权重和偏置)对总损失应负的“责任”,即梯度。
1. 输出层的梯度
首先计算损失 L 对输出层线性组合
z
(
3
)
\mathbf{z}^{(3)}
z(3) 的梯度,我们称之为误差
δ
(
3
)
δ^{(3)}
δ(3)。对于 Softmax + 交叉熵的组合,这个梯度有一个非常简洁的“黄金公式”:
δ
(
3
)
=
∂
L
∂
z
3
=
a
(
3
)
−
t
\delta^{(3)} = \frac{∂L}{∂z_{3}}=\mathbf{a}^{(3)} - \mathbf{t}
δ(3)=∂z3∂L=a(3)−t
这个公式的美妙之处在于它直接将模型的预测
a
(
3
)
\mathbf{a}^{(3)}
a(3)和真实标签 t联系起来,其差值即为输出层的误差。我们给出这个公式简单的推导过程:推导公式
下面我们根据给出的数值做出计算如下:
δ
(
3
)
=
a
(
3
)
−
t
=
[
0.2397
−
1
0.3236
−
0
0.4367
−
0
]
=
[
−
0.7603
0.3236
0.4367
]
\delta^{(3)} = \mathbf{a}^{(3)} - \mathbf{t}= \begin{bmatrix} 0.2397 - 1 \\ 0.3236 - 0 \\ 0.4367 - 0 \end{bmatrix}= \begin{bmatrix} -0.7603 \\ 0.3236 \\ 0.4367 \end{bmatrix}
δ(3)=a(3)−t=
0.2397−10.3236−00.4367−0
=
−0.76030.32360.4367
接下来,我们利用这个误差 δ ( 3 ) δ^{(3)} δ(3) 计算输出层参数 w ( 2 ) w^{(2)} w(2) 和 b ( 2 ) b^{(2)} b(2) 的梯度。
1.1 权重梯度
∇
W
(
2
)
L
=
δ
(
3
)
⋅
(
a
(
2
)
)
T
\nabla_{\mathbf{W}^{(2)}} L = \delta^{(3)} \cdot (\mathbf{a}^{(2)})^T
∇W(2)L=δ(3)⋅(a(2))T
权重梯度公式推导:推导公式
根据给定的数值计算如下:
δ
(
3
)
=
[
−
0.7603
0.3236
0.4367
]
,
a
(
2
)
=
[
0.66818777
0.83201839
]
\delta^{(3)} = \begin{bmatrix} -0.7603\\ 0.3236\\ 0.4367 \end{bmatrix}, \quad \mathbf{a}^{(2)} = \begin{bmatrix} 0.66818777\\ 0.83201839 \end{bmatrix}
δ(3)=
−0.76030.32360.4367
,a(2)=[0.668187770.83201839]
(
a
(
2
)
)
T
=
[
0.66818777
,
0.83201839
]
(a^{(2)})^T=[0.66818777,0.83201839]
(a(2))T=[0.66818777,0.83201839]
所以:
∇ W ( 2 ) L = [ − 0.7603 × 0.66818777 − 0.7603 × 0.83201839 0.3236 × 0.66818777 0.3236 × 0.83201839 0.4367 × 0.66818777 0.4367 × 0.83201839 ] ≈ [ − 0.508 , − 0.633 0.216 , 0.269 0.292 , 0.364 ] \begin{align} \nabla_{\mathbf{W}^{(2)}} L &= \begin{bmatrix} -0.7603 \times 0.66818777 & -0.7603 \times 0.83201839\\ \ 0.3236 \times 0.66818777 & \ 0.3236 \times 0.83201839\\ \ 0.4367 \times 0.66818777 & \ 0.4367 \times 0.83201839 \end{bmatrix} \\ &\approx \begin{bmatrix} -0.508,\, -0.633 \\ 0.216,\, 0.269 \\ 0.292,\, 0.364 \end{bmatrix} \end{align} ∇W(2)L= −0.7603×0.66818777 0.3236×0.66818777 0.4367×0.66818777−0.7603×0.83201839 0.3236×0.83201839 0.4367×0.83201839 ≈ −0.508,−0.6330.216,0.2690.292,0.364
1.2 偏置梯度
偏置
b
(
2
)
\mathbf{b}^{(2)}
b(2) 的梯度计算公式如下:
∂
L
∂
b
i
(
2
)
=
δ
i
(
3
)
\frac{\partial L}{\partial b_i^{(2)}} = \delta_i^{(3)}
∂bi(2)∂L=δi(3)
即偏置的梯度就是
δ
(
3
)
\delta^{(3)}
δ(3) 的各分量。
∇
b
(
2
)
L
=
[
−
0.7603
0.3236
0.4367
]
\nabla_{\mathbf{b}^{(2)}} L = \begin{bmatrix} -0.7603 \\ 0.3236 \\ 0.4367 \end{bmatrix}
∇b(2)L=
−0.76030.32360.4367
这就是输出层偏置的梯度矩阵。
2. 隐含层的梯度
误差需要从输出层传播回隐含层。隐含层的误差
δ
(
2
)
δ^{(2)}
δ(2)计算如下:
隐含层的误差梯度
δ
(
2
)
=
∂
L
∂
z
(
2
)
\delta^{(2)} = \frac{\partial L}{\partial z^{(2)}}
δ(2)=∂z(2)∂L 根据链式法则
δ
(
2
)
=
∂
L
∂
z
(
3
)
⋅
∂
z
(
3
)
∂
a
(
2
)
⋅
∂
a
(
2
)
∂
z
(
2
)
\delta^{(2)} = \frac{\partial L}{\partial z^{(3)}} \cdot \frac{\partial z^{(3)}}{\partial a^{(2)}} \cdot \frac{\partial a^{(2)}}{\partial z^{(2)}}
δ(2)=∂z(3)∂L⋅∂a(2)∂z(3)⋅∂z(2)∂a(2)
根据
z
(
3
)
=
W
(
2
)
.
a
(
2
)
+
b
(
2
)
z^{(3)}=W^{(2)}.a^{(2)}+b^{(2)}
z(3)=W(2).a(2)+b(2) =>
∂
z
(
3
)
∂
a
(
2
)
=
(
W
(
2
)
)
T
\frac{\partial z^{(3)}}{\partial a^{(2)}}=(W^{(2)})^T
∂a(2)∂z(3)=(W(2))T
(这个推导略可参考权重梯度-偏导构成的雅可比矩阵)
a
(
2
)
=
σ
(
z
(
2
)
)
a^{(2)}=\sigma( \mathbf{z}^{(2)} )
a(2)=σ(z(2)) =>
∂
a
(
2
)
∂
z
(
2
)
=
σ
′
(
z
(
2
)
)
\frac{\partial a^{(2)}}{\partial z^{(2)}}=\sigma'( \mathbf{z}^{(2)} )
∂z(2)∂a(2)=σ′(z(2))
δ
(
3
)
=
∂
L
∂
z
(
3
)
\delta^{(3)} = \frac{\partial L}{\partial z^{(3)}}
δ(3)=∂z(3)∂L
此神经网络隐含层误差梯度公式变为:
δ ( 2 ) = ( W ( 2 ) ) T δ ( 3 ) ⊙ σ ′ ( z ( 2 ) ) \delta^{(2)} = \Bigl(\mathbf{W}^{(2)}\Bigr)^T \delta^{(3)} \,\odot\, \sigma'( \mathbf{z}^{(2)} ) δ(2)=(W(2))Tδ(3)⊙σ′(z(2))
公式解读:
- ( W ( 2 ) ) T δ ( 3 ) \Bigl(\mathbf{W}^{(2)}\Bigr)^T \delta^{(3)} (W(2))Tδ(3): 将输出层的误差 δ ( 3 ) δ^{(3)} δ(3)通过转置后的权重矩阵 W ( 2 ) W^{(2)} W(2) 反向传播回来,实现了误差的“责任分配”。
- σ ′ ( z ( 2 ) ) \sigma'( \mathbf{z}^{(2)} ) σ′(z(2)): 乘以隐含层激活函数(Sigmoid)的导数。这衡量了隐含层自身输出对误差的敏感度。
☉: 表示 Hadamard 积,即矩阵对应元素逐个相乘。
这说明要计算隐含层的误差 δ ( 2 ) δ^{(2)} δ(2),需要将输出层的误差 δ ( 3 ) δ^{(3)} δ(3) 沿着连接权重 W ( 2 ) W^{(2)} W(2) 反向传播回来,并考虑隐含层激活函数的导数。这里 ⊙ \odot ⊙ 表示按元素逐项相乘 (Hadamard product), σ ′ ( z ) = σ ( z ) ( 1 − σ ( z ) ) \sigma'(z) = \sigma(z)(1 - \sigma(z)) σ′(z)=σ(z)(1−σ(z)) 对应 sigmoid 的导数。这里有一个重要的逻辑就是链式法则反向传播中,梯度需从输出层传递到隐含层,需要符合链式法则的"反向传递”特性,其本质是链式法则中"偏导连乘"在矩阵运算中的维度匹配要求,实现了反向加权,也是标量偏导连乘在高维空间满足维度一致性的必然结果,按元素逐项相乘。还有一点就是当梯度用行向量表示时,矩阵乘法顺序与链式法则书写顺序一致;用列向量时则相反。而深度学习框架中通常默认使用列向量梯度,因此反向传播公式里会出现 “转置矩阵在前” 的现象。
先计算
(
W
(
2
)
)
T
δ
(
3
)
(\mathbf{W}^{(2)})^T \delta^{(3)}
(W(2))Tδ(3),
W
(
2
)
\mathbf{W}^{(2)}
W(2) 是
3
×
2
3 \times 2
3×2,所以其转置是
2
×
3
2 \times 3
2×3:
(
W
(
2
)
)
T
=
[
0.70
0.90
1.10
0.80
1.00
1.20
]
(\mathbf{W}^{(2)})^T = \begin{bmatrix} 0.70 & 0.90 & 1.10\\ 0.80 & 1.00 & 1.20 \end{bmatrix}
(W(2))T=[0.700.800.901.001.101.20]
与
δ
(
3
)
\delta^{(3)}
δ(3) (大小
3
×
1
3\times1
3×1) 相乘:
(
W
(
2
)
)
T
δ
(
3
)
=
[
0.70
0.90
1.10
0.80
1.00
1.20
]
[
−
0.7603
0.3236
0.4367
]
(\mathbf{W}^{(2)})^T \delta^{(3)}= \begin{bmatrix} 0.70 & 0.90 & 1.10\\ 0.80 & 1.00 & 1.20 \end{bmatrix} \begin{bmatrix} -0.7603\\ 0.3236\\ 0.4367 \end{bmatrix}
(W(2))Tδ(3)=[0.700.800.901.001.101.20]
−0.76030.32360.4367
计算:
- 第一行: 0.70 × − 0.7603 + 0.90 × 0.3236 + 1.10 × 0.4367 0.70 \times -0.7603 + 0.90 \times 0.3236 + 1.10 \times 0.4367 0.70×−0.7603+0.90×0.3236+1.10×0.4367
- 第二行:
0.80
×
−
0.7603
+
1.00
×
0.3236
+
1.20
×
0.4367
0.80 \times -0.7603 + 1.00 \times 0.3236 + 1.20 \times 0.4367
0.80×−0.7603+1.00×0.3236+1.20×0.4367
故可近似得到:
(
W
(
2
)
)
T
δ
(
3
)
≈
[
0.2394
0.2394
]
(\mathbf{W}^{(2)})^T \delta^{(3)} \approx \begin{bmatrix} 0.2394\\ 0.2394 \end{bmatrix}
(W(2))Tδ(3)≈[0.23940.2394]
再计算
σ
′
(
z
(
2
)
)
\sigma'(\mathbf{z}^{(2)})
σ′(z(2)) ,对于 sigmoid:
σ
′
(
z
)
=
σ
(
z
)
(
1
−
σ
(
z
)
)
\sigma'(z) = \sigma(z)\bigl(1 - \sigma(z)\bigr)
σ′(z)=σ(z)(1−σ(z))
前面我们算过:
z ( 2 ) ≈ [ 0.70 1.60 ] , a ( 2 ) = σ ( z ( 2 ) ) ≈ [ 0.6682 0.8320 ] \mathbf{z}^{(2)} \approx \begin{bmatrix} 0.70\\ 1.60 \end{bmatrix}, \quad \mathbf{a}^{(2)} = \sigma(\mathbf{z}^{(2)}) \approx \begin{bmatrix} 0.6682\\ 0.8320 \end{bmatrix} z(2)≈[0.701.60],a(2)=σ(z(2))≈[0.66820.8320]
因此
σ ′ ( z 1 ( 2 ) ) = 0.6682 × ( 1 − 0.6682 ) ≈ 0.6682 × 0.3318 ≈ 0.2218 \sigma'(z_1^{(2)}) = 0.6682 \times (1 - 0.6682) \approx 0.6682 \times 0.3318 \approx 0.2218 σ′(z1(2))=0.6682×(1−0.6682)≈0.6682×0.3318≈0.2218
σ
′
(
z
2
(
2
)
)
=
0.8320
×
(
1
−
0.8320
)
≈
0.8320
×
0.1680
≈
0.139776
\sigma'(z_2^{(2)}) = 0.8320 \times (1 - 0.8320) \approx 0.8320 \times 0.1680 \approx 0.139776
σ′(z2(2))=0.8320×(1−0.8320)≈0.8320×0.1680≈0.139776
故:
σ
′
(
z
(
2
)
)
≈
[
0.2218
0.1398
]
.
\sigma'(\mathbf{z}^{(2)}) \approx \begin{bmatrix} 0.2218\\ 0.1398 \end{bmatrix}.
σ′(z(2))≈[0.22180.1398].
δ ( 2 ) = [ 0.2394 0.2394 ] ⊙ [ 0.2218 0.1398 ] = [ 0.2394 × 0.2218 0.2394 × 0.1398 ] ≈ [ 0.0531 0.0334 ] . \delta^{(2)} = \begin{bmatrix} 0.2394\\ 0.2394 \end{bmatrix} \odot \begin{bmatrix} 0.2218\\ 0.1398 \end{bmatrix}= \begin{bmatrix} 0.2394 \times 0.2218\\ 0.2394 \times 0.1398 \end{bmatrix} \approx \begin{bmatrix} 0.0531\\ 0.0334 \end{bmatrix}. δ(2)=[0.23940.2394]⊙[0.22180.1398]=[0.2394×0.22180.2394×0.1398]≈[0.05310.0334].
得到隐含层误差 δ ( 2 ) \delta^{(2)} δ(2) 后,我们用同样的方法计算隐含层参数 W ( 1 ) W^{(1)} W(1)和 b ( 1 ) b^{(1)} b(1) 的梯度。
2.1 权重梯度
与输出层类似,这里也是:
∂
L
∂
W
i
j
(
1
)
=
δ
i
(
2
)
⋅
a
j
(
1
)
,
\frac{\partial L}{\partial W_{ij}^{(1)}} = \delta_i^{(2)} \cdot a_j^{(1)},
∂Wij(1)∂L=δi(2)⋅aj(1),
其中
i
=
1
,
2
i=1,2
i=1,2 表示隐含层第
i
i
i 个神经元,
j
=
1
,
2
,
3
j=1,2,3
j=1,2,3 表示输入层第
j
j
j 个神经元。因为
a
(
1
)
=
[
1
,
1
,
1
]
T
\mathbf{a}^{(1)} = [1,1,1]^T
a(1)=[1,1,1]T,所以
∇
W
(
1
)
L
=
δ
(
2
)
⋅
(
a
(
1
)
)
T
=
[
0.0531
0.0334
]
[
1
1
1
]
=
[
0.0531
0.0531
0.0531
0.0334
0.0334
0.0334
]
\begin{align} \\ \nabla_{\mathbf{W}^{(1)}} L &= \delta^{(2)} \cdot (\mathbf{a}^{(1)})^T= \begin{bmatrix} 0.0531\\ 0.0334 \end{bmatrix} \begin{bmatrix} 1 & 1 & 1 \end{bmatrix} \\ &= \begin{bmatrix} 0.0531 & 0.0531 & 0.0531\\ 0.0334 & 0.0334 & 0.0334 \end{bmatrix} \end{align} \\
∇W(1)L=δ(2)⋅(a(1))T=[0.05310.0334][111]=[0.05310.03340.05310.03340.05310.0334]
2.2 偏置梯度
偏置的梯度:
∇
b
(
1
)
L
=
δ
(
2
)
=
[
0.0531
0.0334
]
.
\nabla_{\mathbf{b}^{(1)}} L = \delta^{(2)}= \begin{bmatrix} 0.0531\\ 0.0334 \end{bmatrix}.
∇b(1)L=δ(2)=[0.05310.0334].
五、 参数更新:向正确的方向迈出一步
计算出所有参数的梯度后,我们使用**梯度下降(Gradient Descent)**来更新参数。梯度指明了损失函数上升最快的方向,因此我们沿着梯度的反方向更新参数,就能让损失下降。
更新规则如下,学习率设为 η \eta η,则更新规则为:
W ( l ) ← W ( l ) − η ∇ W ( l ) L , b ( l ) ← b ( l ) − η ∇ b ( l ) L . W^{(l)} \leftarrow W^{(l)} - \eta \,\nabla_{W^{(l)}} L, \quad b^{(l)} \leftarrow b^{(l)} - \eta \,\nabla_{b^{(l)}} L. W(l)←W(l)−η∇W(l)L,b(l)←b(l)−η∇b(l)L.
假设学习率
η
=
0.1
\eta = 0.1
η=0.1,则每个参数都减去
η
\eta
η 乘以对应梯度。
例如,更新输出层权重
W
(
2
)
\mathbf{W}^{(2)}
W(2):
W
i
j
(
2
)
←
W
i
j
(
2
)
−
0.1
×
(
∇
W
(
2
)
L
)
i
j
.
W_{ij}^{(2)} \leftarrow W_{ij}^{(2)} - 0.1 \times \bigl(\nabla_{\mathbf{W}^{(2)}} L\bigr)_{ij}.
Wij(2)←Wij(2)−0.1×(∇W(2)L)ij.
以第一行(对应输出层第1个神经元)为例:
- W 1 , 1 ( 2 ) W_{1,1}^{(2)} W1,1(2) 原先是 0.70,更新后约 0.70 − 0.1 × ( − 0.508 ) = 0.70 + 0.0508 = 0.7508 0.70 - 0.1 \times (-0.508) = 0.70 + 0.0508 = 0.7508 0.70−0.1×(−0.508)=0.70+0.0508=0.7508
- W 1 , 2 ( 2 ) W_{1,2}^{(2)} W1,2(2) 原先是 0.80,更新后约 0.80 − 0.1 × ( − 0.633 ) = 0.80 + 0.0633 = 0.8633 0.80 - 0.1 \times (-0.633) = 0.80 + 0.0633 = 0.8633 0.80−0.1×(−0.633)=0.80+0.0633=0.8633
其他同理。所有 b ( 2 ) \mathbf{b}^{(2)} b(2)、 W ( 1 ) \mathbf{W}^{(1)} W(1)、 b ( 1 ) \mathbf{b}^{(1)} b(1) 也依此更新。
六、 训练迭代与代码实现
上述“前向传播 → 计算损失 → 反向传播 → 更新参数”的完整流程构成了一次迭代。在实际训练中,我们会重复这个过程成千上万次(称为 Epochs),直到损失 L 下降到一个足够小的阈值(如 0.01),或者达到预设的最大迭代次数。
Python 代码实现
下面是整个过程的 Python 实现,它完美复现了我们手动计算的每一步。
import numpy as np
# ------- 1. 初始化参数 -------
np.random.seed(123) # 可固定随机种子
# 这里直接用我们示例中给的固定初始化:
W1 = np.array([[0.10, 0.20, 0.30],
[0.40, 0.50, 0.60]], dtype=float)
b1 = np.array([[0.10],
[0.10]], dtype=float)
W2 = np.array([[0.70, 0.80],
[0.90, 1.00],
[1.10, 1.20]], dtype=float)
b2 = np.array([[0.20],
[0.20],
[0.20]], dtype=float)
# 学习率
eta = 0.1
# 训练目标
x = np.array([[1.0],
[1.0],
[1.0]]) # 输入 a^(1)
t = np.array([[1.0],
[0.0],
[0.0]]) # one-hot 标签
def sigmoid(z):
return 1.0 / (1.0 + np.exp(-z))
def sigmoid_prime(a):
# a = sigmoid(z), so sigma'(z) = a * (1 - a)
return a * (1.0 - a)
def softmax(z):
exp_z = np.exp(z - np.max(z)) # 防止溢出
return exp_z / np.sum(exp_z, axis=0, keepdims=True)
def cross_entropy(y, t):
# y, t shape: (3,1)
return -np.sum(t * np.log(y + 1e-12)) # 加一点防止 log(0)
# ------- 2. 迭代训练 -------
threshold = 0.01
epoch = 0
max_epoch = 10000 # 防止死循环, 只是示例
while True:
epoch += 1
# ----- Forward -----
# Layer 2
z2 = np.dot(W1, x) + b1 # (2,1)
a2 = sigmoid(z2) # (2,1)
# Layer 3 (output)
z3 = np.dot(W2, a2) + b2 # (3,1)
a3 = softmax(z3) # (3,1)
# 计算损失
loss = cross_entropy(a3, t)
# 检查是否达到阈值
if loss < threshold or epoch > max_epoch:
print(f"Epoch={epoch}, Loss={loss:.6f}")
break
# ----- Backward -----
# 输出层梯度 delta^(3)
delta3 = a3 - t # (3,1)
# 输出层参数梯度
dW2 = np.dot(delta3, a2.T) # (3,2)
db2 = delta3 # (3,1)
# 传播到隐层
delta2 = np.dot(W2.T, delta3) * sigmoid_prime(a2) # (2,1)
# 隐层参数梯度
dW1 = np.dot(delta2, x.T) # (2,3)
db1 = delta2 # (2,1)
# ----- Update -----
W2 -= eta * dW2
b2 -= eta * db2
W1 -= eta * dW1
b1 -= eta * db1
# 可输出观察
if epoch % 500 == 0:
print(f"Epoch={epoch}, Loss={loss:.6f}")
print("Training finished!")
print("Final parameters:")
print("W1 =\n", W1)
print("b1 =\n", b1)
print("W2 =\n", W2)
print("b2 =\n", b2)
七、 总结与要点
以上,我们完整地手动推演并实现了一个神经网络的训练过程。其核心步骤可以总结为:
-
前向传播:
- 按层计算 z ( l ) = W ( l − 1 ) a ( l − 1 ) + b ( l − 1 ) z^{(l)} = W^{(l-1)} a^{(l-1)} + b^{(l-1)} z(l)=W(l−1)a(l−1)+b(l−1)
- 激活函数 a ( l ) = σ ( z ( l ) ) a^{(l)} = \sigma(z^{(l)}) a(l)=σ(z(l)) (本示例隐层用 Sigmoid,输出层用 Softmax)
-
损失计算:
- 本文示例使用 Softmax + Cross Entropy
- 单个样本 t \mathbf{t} t 的交叉熵损失 L = − ∑ i t i ln ( a i ) L = -\sum_i t_i \ln(a_i) L=−∑itiln(ai)
-
反向传播:
- 对于 Softmax + Cross Entropy,有简洁公式 δ ( 3 ) = a ( 3 ) − t \delta^{(3)} = a^{(3)} - t δ(3)=a(3)−t
- 隐层梯度 δ ( 2 ) = ( W ( 2 ) ) T δ ( 3 ) ⊙ σ ′ ( z ( 2 ) ) \delta^{(2)} = (W^{(2)})^T \delta^{(3)} \odot \sigma'(z^{(2)}) δ(2)=(W(2))Tδ(3)⊙σ′(z(2))
- 梯度求导 ∇ W ( l ) L = δ ( l ) ⋅ ( a ( l − 1 ) ) T \nabla_{W^{(l)}} L = \delta^{(l)} \cdot (a^{(l-1)})^T ∇W(l)L=δ(l)⋅(a(l−1))T, ∇ b ( l ) L = δ ( l ) \nabla_{b^{(l)}} L = \delta^{(l)} ∇b(l)L=δ(l)
-
更新参数:
- W ( l ) ← W ( l ) − η ∇ W ( l ) L W^{(l)} \leftarrow W^{(l)} - \eta \nabla_{W^{(l)}} L W(l)←W(l)−η∇W(l)L
- b ( l ) ← b ( l ) − η ∇ b ( l ) L b^{(l)} \leftarrow b^{(l)} - \eta \nabla_{b^{(l)}} L b(l)←b(l)−η∇b(l)L
-
迭代: 不断重复以上步骤,直至模型收敛。
我们之所以如此枯燥地从头到尾手搓一个神经网络,是希望大家能看到它与概率模型的深度绑定。从现实世界概率本质的映照,到通用逼近定理等理论支撑下的非线性拟合,再到信息论视角下智能与压缩的关联,神经网络一步步揭开了 AI 运行的神秘面纱。
当我们从“追求确定性”的思维转向“拥抱概率不确定性”,不仅是理解 AI 本质的关键,更是未来与大模型协同创新的思想基石。当我们意识到 AI 模型与现实世界皆以概率为底色,便能以更包容、更契合本质的视角,继续探索人工智能的无限可能,让技术在理解不确定性、模拟智能的道路上,走得更远、更深入。
上一篇文章 从线性到万能近似定理
784

被折叠的 条评论
为什么被折叠?



