引言:从概率视角看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. 参数初始化
在训练初始,我们可随机初始化参数。为方便演示和复现,这里我们直接给出一组固定的示例数值。
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.10 0.40 0.20 0.50 0.30 0.60 ] , b ( 1 ) = [ 0.10 0.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.70 0.90 1.10 0.80 1.00 1.20 , b ( 2 ) = 0.20 0.20 0.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.10 0.40 0.20 0.50 0.30 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 ]
然后,将 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 − x 1
对应分量:
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} a 1 ( 2 ) = 1 + e − 0.70 1 ≈ 0.66818777 , a 2 ( 2 ) = 1 + e − 1.60 1 ≈ 0.83201839
故:
a ( 2 ) ≈ [ 0.66818777 0.83201839 ] \mathbf{a}^{(2)} \approx
\begin{bmatrix}
0.66818777 \\
0.83201839
\end{bmatrix} a ( 2 ) ≈ [ 0.66818777 0.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.70 0.90 1.10 0.80 1.00 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
然后对 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)}}} a i ( 3 ) = ∑ j e z j ( 3 ) e z i ( 3 )
分母是 e 1.3333 + e 1.6334 + e 1.9324 e^{1.3333} + e^{1.6334} + e^{1.9324} e 1.3333 + e 1.6334 + e 1.9324 。我们分别计算 (取近似):
e 1.3333 ≈ 3.793 e^{1.3333} \approx 3.793 e 1.3333 ≈ 3.793
e 1.6334 ≈ 5.120 e^{1.6334} \approx 5.120 e 1.6334 ≈ 5.120
e 1.9324 ≈ 6.909 e^{1.9324} \approx 6.909 e 1.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 a 1 ( 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 a 2 ( 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 a 3 ( 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.2397 0.3236 0.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 ∑ t i ln ( a i ( 3 ) )
在本例中,只有 t 1 = 1 t_1=1 t 1 = 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.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
计算得到的损失 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 ) = ∂ z 3 ∂ 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 ] = \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} = a ( 3 ) − t = 0.2397 − 1 0.3236 − 0 0.4367 − 0 = − 0.7603 0.3236 0.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),在 - 掘金 )
根据给定的数值计算如下:
δ ( 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.7603 0.3236 0.4367 , a ( 2 ) = [ 0.66818777 0.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.633 0.216 , 0.269 0.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)} ∂ b i ( 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.7603 0.3236 0.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.70 0.80 0.90 1.00 1.10 1.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.70 0.80 0.90 1.00 1.10 1.20 ] − 0.7603 0.3236 0.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.2394 0.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.70 1.60 ] , a ( 2 ) = σ ( z ( 2 ) ) ≈ [ 0.6682 0.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 σ ′ ( z 1 ( 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 σ ′ ( z 2 ( 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.2218 0.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.2394 0.2394 ] ⊙ [ 0.2218 0.1398 ] = [ 0.2394 × 0.2218 0.2394 × 0.1398 ] ≈ [ 0.0531 0.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)}, ∂ W ij ( 1 ) ∂ L = δ i ( 2 ) ⋅ a j ( 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.0531 0.0334 ] [ 1 1 1 ] = [ 0.0531 0.0334 0.0531 0.0334 0.0531 0.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.0531 0.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}. W ij ( 2 ) ← W ij ( 2 ) − 0.1 × ( ∇ W ( 2 ) L ) ij .
以第一行(对应输出层第1个神经元)为例:
W 1 , 1 ( 2 ) W_{1,1}^{(2)} W 1 , 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)} W 1 , 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
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 ]])
t = np.array([[1.0 ],
[0.0 ],
[0.0 ]])
def sigmoid (z ):
return 1.0 / (1.0 + np.exp(-z))
def sigmoid_prime (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 ):
return -np.sum (t * np.log(y + 1e-12 ))
threshold = 0.01
epoch = 0
max_epoch = 10000
while True :
epoch += 1
z2 = np.dot(W1, x) + b1
a2 = sigmoid(z2)
z3 = np.dot(W2, a2) + b2
a3 = softmax(z3)
loss = cross_entropy(a3, t)
if loss < threshold or epoch > max_epoch:
print (f"Epoch={epoch} , Loss={loss:.6 f} " )
break
delta3 = a3 - t
dW2 = np.dot(delta3, a2.T)
db2 = delta3
delta2 = np.dot(W2.T, delta3) * sigmoid_prime(a2)
dW1 = np.dot(delta2, x.T)
db1 = delta2
W2 -= eta * dW2
b2 -= eta * db2
W1 -= eta * dW1
b1 -= eta * db1
if epoch % 500 == 0 :
print (f"Epoch={epoch} , Loss={loss:.6 f} " )
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 = − ∑ i t i ln ( a i )
反向传播 :
对于 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 模型与现实世界皆以概率为底色,便能以更包容、更契合本质的视角,继续探索人工智能的无限可能,让技术在理解不确定性、模拟智能的道路上,走得更远、更深入。
上一篇文章 [从线性到万能近似定理](从线性到万能近似定理在人工智能技术不断颠覆我们生活的今天,从基础算法到前沿模型,背后的数学原理与工程智慧如同精密齿轮,推 - 掘金 )