重练AI小号:大模型小白的重修日记(一.前向传播,梯度下降与反向传播)

重练AI小号:大模型小白的重修日记(一.前向传播,梯度下降与反向传播)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


前言

从计算机视觉(CV)跨界到大模型方向,是我近期科研路径上的一个重要转折。但方向的转换往往伴随着阵痛,底层逻辑的差异让我在初期的推进中遇到了明显的瓶颈。

与其在知识断层中挣扎,不如退回原点,重新打牢根基。这段时间,我开始了对人工智能底层知识的“重修”计划。这篇博客将作为我的学习备忘录,沉淀我转向大模型以来的最新知识总结与核心体悟。这既是一次对现有瓶颈的突围,也是为了后续研究的厚积薄发。


一、前向传播

前向传播没有任何“智能学习”的魔法,它是一次纯粹的、确定性信息正向流动。它是对当前网络参数的一次效果检验,其根本目的是为了得到一个预测值,从而为后续的“纠错机制”(反向传播)提供计算误差的依据。

1.1单个神经元

在这里插入图片描述


假设某一神经元的输入特征为 x 1 , x 2 , x 3 x_1, x_2, x_3 x1​,x2​,x3​,对应的权重参数为 w 1 , w 2 , w 3 w_1, w_2, w_3 w1​,w2​,w3​,偏置项为 b b b。在标准的神经网络示意图中,圆圈通常指代神经元节点中的具体数值,而节点之间的连线则代表网络模型需要学习和更新的权重。图中偏置(bias)对应的输入节点之所以恒定为 1 1 1,是因为在数学表达上,权重 b b b 与输入 1 1 1 的乘积等效于偏置项本身(即 1 × b = b 1 \times b = b 1×b=b)。因此,该单个神经元的完整计算公式为 f ( w 1 x 1 + w 2 x 2 + w 3 x 3 + b ) f(w_1x_1 + w_2x_2 + w_3x_3 + b) f(w1​x1​+w2​x2​+w3​x3​+b),其中 f f f 为激活函数,将在后续章节展开详细讨论。具体矩阵表达形式如下:
w T x + b = [ w 1 w 2 w 3 ] [ x 1 x 2 x 3 ] + b \mathbf{w}^T \mathbf{x} + b = \begin{bmatrix} w_1 & w_2 & w_3 \end{bmatrix} \begin{bmatrix} x_1 \\ x_2 \\ x_3 \end{bmatrix} + b wTx+b=[w1​​w2​​w3​​]​x1​x2​x3​​​+b

1.2 单层神经网络

在这里插入图片描述


单层神经网络的前向传播的核心公式为 a = f ( W x + b ) a = f(Wx + b) a=f(Wx+b)具体的矩阵表述为: [ a 1 a 2 a 3 ] = f ( [ w 11 w 12 w 13 w 21 w 22 w 23 w 31 w 32 w 33 ] [ x 1 x 2 x 3 ] + [ b 1 b 2 b 3 ] ) \begin{bmatrix} a_1 \\ a_2 \\ a_3 \end{bmatrix} = f \left( \begin{bmatrix} w_{11} & w_{12} & w_{13} \\ w_{21} & w_{22} & w_{23} \\ w_{31} & w_{32} & w_{33} \end{bmatrix} \begin{bmatrix} x_1 \\ x_2 \\ x_3 \end{bmatrix} + \begin{bmatrix} b_1 \\ b_2 \\ b_3 \end{bmatrix} \right) ​a1​a2​a3​​​=f​​w11​w21​w31​​w12​w22​w32​​w13​w23​w33​​​​x1​x2​x3​​​+​b1​b2​b3​​​​执行矩阵乘法 ( W x Wx Wx) 和加法 ( + b +b +b) 后,它的终极内部形态如下: [ a 1 a 2 a 3 ] = f ( [ w 11 x 1 + w 12 x 2 + w 13 x 3 + b 1 w 21 x 1 + w 22 x 2 + w 23 x 3 + b 2 w 31 x 1 + w 32 x 2 + w 33 x 3 + b 3 ] ) \begin{bmatrix} a_1 \\ a_2 \\ a_3 \end{bmatrix} = f \left( \begin{bmatrix} w_{11}x_1 + w_{12}x_2 + w_{13}x_3 + b_1 \\ w_{21}x_1 + w_{22}x_2 + w_{23}x_3 + b_2 \\ w_{31}x_1 + w_{32}x_2 + w_{33}x_3 + b_3 \end{bmatrix} \right) ​a1​a2​a3​​​=f​​w11​x1​+w12​x2​+w13​x3​+b1​w21​x1​+w22​x2​+w23​x3​+b2​w31​x1​+w32​x2​+w33​x3​+b3​​​​对于第 1 个神经元,它接收到的偏置信号是:节点值(+1) × 连线权重(b1) = b1
对于第 2 个神经元,它接收到的偏置信号是:节点值(+1) × 连线权重(b2) = b2
对于第 3 个神经元,它接收到的偏置信号是:节点值(+1) × 连线权重(b3) = b3。
因为乘数永远是 1,所以连线上的权重值就原封不动地加到了对应的神经元里。

1.3多层神经网络

随着层数的增加,为了防止不同层的权重符号混淆,在数学表达上需要引入上标来区分层数。约定:上标 ( l ) (l) (l) 表示第 l l l 层的参数。例如, W ( 1 ) W^{(1)} W(1) 表示第一层的权重矩阵。下标 i j ij ij 表示从上一层的第 j j j 个节点连接到本层第 i i i 个神经元的权重。 f f f 代表激活函数。下面这个图是一个包含输入层 -> 隐藏层1 -> 隐藏层2 -> 输出层的网络。我们将它拆解为三次矩阵接力计算。

在这里插入图片描述


第一层:输入层 → \rightarrow → 隐藏层 1: a ( 1 ) = f ( W ( 1 ) x + b ( 1 ) ) a^{(1)} = f(W^{(1)}x + b^{(1)}) a(1)=f(W(1)x+b(1))
[ a 1 ( 1 ) a 2 ( 1 ) a 3 ( 1 ) ] = f ( [ w 11 ( 1 ) w 12 ( 1 ) w 13 ( 1 ) w 21 ( 1 ) w 22 ( 1 ) w 23 ( 1 ) w 31 ( 1 ) w 32 ( 1 ) w 33 ( 1 ) ] [ x 1 x 2 x 3 ] + [ b 1 ( 1 ) b 2 ( 1 ) b 3 ( 1 ) ] ) \begin{bmatrix} a_1^{(1)} \\ a_2^{(1)} \\ a_3^{(1)} \end{bmatrix} = f \left( \begin{bmatrix} w_{11}^{(1)} & w_{12}^{(1)} & w_{13}^{(1)} \\ w_{21}^{(1)} & w_{22}^{(1)} & w_{23}^{(1)} \\ w_{31}^{(1)} & w_{32}^{(1)} & w_{33}^{(1)} \end{bmatrix} \begin{bmatrix} x_1 \\ x_2 \\ x_3 \end{bmatrix} + \begin{bmatrix} b_1^{(1)} \\ b_2^{(1)} \\ b_3^{(1)} \end{bmatrix} \right) ​a1(1)​a2(1)​a3(1)​​​=f​​w11(1)​w21(1)​w31(1)​​w12(1)​w22(1)​w32(1)​​w13(1)​w23(1)​w33(1)​​​​x1​x2​x3​​​+​b1(1)​b2(1)​b3(1)​​​​

第二层:隐藏层 1 → \rightarrow → 隐藏层 2 a ( 2 ) = f ( W ( 2 ) a ( 1 ) + b ( 2 ) ) a^{(2)} = f(W^{(2)}a^{(1)} + b^{(2)}) a(2)=f(W(2)a(1)+b(2)) [ a 1 ( 2 ) a 2 ( 2 ) ] = f ( [ w 11 ( 2 ) w 12 ( 2 ) w 13 ( 2 ) w 21 ( 2 ) w 22 ( 2 ) w 23 ( 2 ) ] [ a 1 ( 1 ) a 2 ( 1 ) a 3 ( 1 ) ] + [ b 1 ( 2 ) b 2 ( 2 ) ] ) \begin{bmatrix} a_1^{(2)} \\ a_2^{(2)} \end{bmatrix} = f \left( \begin{bmatrix} w_{11}^{(2)} & w_{12}^{(2)} & w_{13}^{(2)} \\ w_{21}^{(2)} & w_{22}^{(2)} & w_{23}^{(2)} \end{bmatrix} \begin{bmatrix} a_1^{(1)} \\ a_2^{(1)} \\ a_3^{(1)} \end{bmatrix} + \begin{bmatrix} b_1^{(2)} \\ b_2^{(2)} \end{bmatrix} \right) [a1(2)​a2(2)​​]=f​[w11(2)​w21(2)​​w12(2)​w22(2)​​w13(2)​w23(2)​​]​a1(1)​a2(1)​a3(1)​​​+[b1(2)​b2(2)​​]​

第三层:隐藏层 2 → \rightarrow → 输出层 h W , b ( x ) = f ( W ( 3 ) a ( 2 ) + b ( 3 ) ) h_{W,b}(x) = f(W^{(3)}a^{(2)} + b^{(3)}) hW,b​(x)=f(W(3)a(2)+b(3))
[ h 1 h 2 ] = f ( [ w 11 ( 3 ) w 12 ( 3 ) w 21 ( 3 ) w 22 ( 3 ) ] [ a 1 ( 2 ) a 2 ( 2 ) ] + [ b 1 ( 3 ) b 2 ( 3 ) ] ) \begin{bmatrix} h_1 \\ h_2 \end{bmatrix} = f \left( \begin{bmatrix} w_{11}^{(3)} & w_{12}^{(3)} \\ w_{21}^{(3)} & w_{22}^{(3)} \end{bmatrix} \begin{bmatrix} a_1^{(2)} \\ a_2^{(2)} \end{bmatrix} + \begin{bmatrix} b_1^{(3)} \\ b_2^{(3)} \end{bmatrix} \right) [h1​h2​​]=f([w11(3)​w21(3)​​w12(3)​w22(3)​​][a1(2)​a2(2)​​]+[b1(3)​b2(3)​​])

1.4激活函数(篇幅有限,后续会有独立文章讲解)

激活函数的目的是为了引入非线性,但是到是什么是非线性,不引入激活函数会怎么样呢?
假设我们有一个极其深度的神经网络,有 100 层。为了方便推演,我们先看两层,并且故意去掉激活函数 f f f。在没有激活函数的情况下,前向传播的公式变成了纯粹的线性映射:隐藏层 1: a ( 1 ) = W ( 1 ) x + b ( 1 ) a^{(1)} = W^{(1)}x + b^{(1)} a(1)=W(1)x+b(1)隐藏层 2: a ( 2 ) = W ( 2 ) a ( 1 ) + b ( 2 ) a^{(2)} = W^{(2)}a^{(1)} + b^{(2)} a(2)=W(2)a(1)+b(2)我们把第一层的公式直接代入到第二层中: a ( 2 ) = W ( 2 ) ( W ( 1 ) x + b ( 1 ) ) + b ( 2 ) a^{(2)} = W^{(2)}(W^{(1)}x + b^{(1)}) + b^{(2)} a(2)=W(2)(W(1)x+b(1))+b(2)根据矩阵乘法分配律,把它展开: a ( 2 ) = ( W ( 2 ) W ( 1 ) ) x + ( W ( 2 ) b ( 1 ) + b ( 2 ) ) a^{(2)} = (W^{(2)}W^{(1)})x + (W^{(2)}b^{(1)} + b^{(2)}) a(2)=(W(2)W(1))x+(W(2)b(1)+b(2))仔细观察这个展开后的式子! W ( 2 ) W^{(2)} W(2) 是个矩阵, W ( 1 ) W^{(1)} W(1) 也是个矩阵。两个矩阵相乘,结果依然只是一个全新的矩阵。 我们把它记作 W n e w W_{new} Wnew​。 W ( 2 ) b ( 1 ) W^{(2)}b^{(1)} W(2)b(1) 是个向量, b ( 2 ) b^{(2)} b(2) 也是个向量。两个向量相加,结果依然只是一个全新的向量。 我们把它记作 b n e w b_{new} bnew​。所以,这个两层网络的最终数学形态变成了: a ( 2 ) = W n e w x + b n e w a^{(2)} = W_{new}x + b_{new} a(2)=Wnew​x+bnew​核心结论: 只要你不用激活函数,无论你叠 10 层、100 层还是 10000 层隐藏层,由于矩阵乘法的结合律,它们在数学上等价于极其平凡的一层线性网络。

二、神经网络的训练方式

2.1损失函数

从数学和架构的本质来看,损失函数就是一个误差测量仪。它接收网络预测的答案 y ^ \hat{y} y^​ 和现实世界的真实标签(标准答案) y y y,然后通过一套严格的数学公式,吐出一个单一的数字(标量)。这个数字越大,说明网络错得越离谱;越接近 0,说明预测越完美。

2.1.1均方误差(Mean Squared Error, MSE)----> 回归任务

对于 n n n 个样本,MSE 的公式定义如下: L = 1 n ∑ i = 1 n ( y i − y ^ i ) 2 L = \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2 L=n1​i=1∑n​(yi​−y^​i​)2 y i y_i yi​ 是真实值。 y ^ i \hat{y}_i y^​i​ 是预测的房值。

2.1.2交叉熵损失(Cross-Entropy Loss)-----> 分类任务

在这里插入图片描述

数学公式(以二分类为例) L = − [ y log ⁡ ( y ^ ) + ( 1 − y ) log ⁡ ( 1 − y ^ ) ] L = - [y \log(\hat{y}) + (1-y) \log(1-\hat{y})] L=−[ylog(y^​)+(1−y)log(1−y^​)] y y y 是真实标签(猫为 1,狗为 0)。 y ^ \hat{y} y^​ 是预测为猫的概率(介于 0 到 1 之间)。深度剖析:,因为 y y y 只能是 1 或 0,所以公式每次其实只有一半在起作用:当真实图片是猫( y = 1 y=1 y=1)时: 公式后半部分消失,变成 L = − log ⁡ ( y ^ ) L = - \log(\hat{y}) L=−log(y^​)。如果网络非常自信且正确( y ^ = 0.99 \hat{y} = 0.99 y^​=0.99), − log ⁡ ( 0.99 ) -\log(0.99) −log(0.99) 非常接近 0,损失极小。如果网络极其自信但大错特错( y ^ = 0.01 \hat{y} = 0.01 y^​=0.01), − log ⁡ ( 0.01 ) -\log(0.01) −log(0.01) 的值会趋近于无限大。当真实图片是狗( y = 0 y=0 y=0)时: 公式前半部分消失,变成 L = − log ⁡ ( 1 − y ^ ) L = - \log(1-\hat{y}) L=−log(1−y^​),逻辑同理

2.2梯度下降

梯度的定义: 梯度是损失函数 J ( θ ) J(\bm{\theta}) J(θ) 对所有参数求偏导数组合成的一个向量,记作 ∇ J ( θ ) \nabla J(\bm{\theta}) ∇J(θ)。 ∇ J ( θ ) = [ ∂ J ∂ θ 1 ∂ J ∂ θ 2 ⋮ ∂ J ∂ θ n ] \nabla J(\bm{\theta}) = \begin{bmatrix} \frac{\partial J}{\partial \theta_1} \\ \frac{\partial J}{\partial \theta_2} \\ \vdots \\ \frac{\partial J}{\partial \theta_n} \end{bmatrix} ∇J(θ)=​∂θ1​∂J​∂θ2​∂J​⋮∂θn​∂J​​​梯度的物理意义(最重要的一点): 在山上的任何一个位置,梯度向量永远指向当前位置最陡峭的“上坡”方向。
梯度下降 (Gradient Descent):参数更新的标准公式如下: θ n e w = θ o l d − α ∇ J ( θ o l d ) \bm{\theta}_{new} = \bm{\theta}_{old} - \alpha \nabla J(\bm{\theta}_{old}) θnew​=θold​−α∇J(θold​)
在严格的传统微积分中,梯度确实是定义在向量上的(即列向量)。但在深度学习中,为了计算和代码实现方便,我们将梯度的概念“泛化”到了矩阵(甚至高维张量)上。
在深度学习的反向传播中,有一个极其重要的原则:标量损失函数 L L L 对某个参数的导数(也就是我们俗称的“梯度”),其形状必须与该参数的形状完全一致。如果参数 b b b 是一个标量,那么 ∂ L ∂ b \frac{\partial L}{\partial b} ∂b∂L​ 就是一个标量。如果参数 v \bm{v} v 是一个 n × 1 n \times 1 n×1 的列向量,那么 ∂ L ∂ v \frac{\partial L}{\partial \bm{v}} ∂v∂L​ 就是一个 n × 1 n \times 1 n×1 的列向量。如果参数 W \bm{W} W 是一个 m × n m \times n m×n 的矩阵,那么 ∂ L ∂ W \frac{\partial L}{\partial \bm{W}} ∂W∂L​ 就必须被定义为一个 m × n m \times n m×n 的矩阵。
回顾一下之前推导出的第一层权重矩阵 W ( 1 ) W^{(1)} W(1)(形状是 3 × 3 3 \times 3 3×3): W o l d ( 1 ) = [ w 11 w 12 w 13 w 21 w 22 w 23 w 31 w 32 w 33 ] W^{(1)}_{old} = \begin{bmatrix} w_{11} & w_{12} & w_{13} \\ w_{21} & w_{22} & w_{23} \\ w_{31} & w_{32} & w_{33} \end{bmatrix} Wold(1)​=​w11​w21​w31​​w12​w22​w32​​w13​w23​w33​​​当网络前向传播完毕,算出 Loss L L L 后,反向传播算法会计算出 L L L 对这个矩阵中每一个元素的偏导数。把这些偏导数按照原有的位置摆放,就形成了一个 3 × 3 3 \times 3 3×3 的梯度矩阵: ∂ L ∂ W ( 1 ) = [ ∂ L ∂ w 11 ∂ L ∂ w 12 ∂ L ∂ w 13 ∂ L ∂ w 21 ∂ L ∂ w 22 ∂ L ∂ w 23 ∂ L ∂ w 31 ∂ L ∂ w 32 ∂ L ∂ w 33 ] \frac{\partial L}{\partial W^{(1)}} = \begin{bmatrix} \frac{\partial L}{\partial w_{11}} & \frac{\partial L}{\partial w_{12}} & \frac{\partial L}{\partial w_{13}} \\ \frac{\partial L}{\partial w_{21}} & \frac{\partial L}{\partial w_{22}} & \frac{\partial L}{\partial w_{23}} \\ \frac{\partial L}{\partial w_{31}} & \frac{\partial L}{\partial w_{32}} & \frac{\partial L}{\partial w_{33}} \end{bmatrix} ∂W(1)∂L​=​∂w11​∂L​∂w21​∂L​∂w31​∂L​​∂w12​∂L​∂w22​∂L​∂w32​∂L​​∂w13​∂L​∂w23​∂L​∂w33​∂L​​​
既然 W o l d W_{old} Wold​ 和它的梯度 ∂ L ∂ W ( 1 ) \frac{\partial L}{\partial W^{(1)}} ∂W(1)∂L​ 是两个形状完全相同的 3 × 3 3 \times 3 3×3 矩阵,学习率 α \alpha α 是一个标量(比如 0.01 0.01 0.01)。那么,现实中真实的梯度下降公式,就是一次优雅的矩阵减法: W n e w ( 1 ) = W o l d ( 1 ) − α ⋅ ∂ L ∂ W ( 1 ) W^{(1)}_{new} = W^{(1)}_{old} - \alpha \cdot \frac{\partial L}{\partial W^{(1)}} Wnew(1)​=Wold(1)​−α⋅∂W(1)∂L​我们把它彻底展开,看看 GPU 在一瞬间到底执行了什么: [ w 11 n e w w 12 n e w w 13 n e w w 21 n e w w 22 n e w w 23 n e w w 31 n e w w 32 n e w w 33 n e w ] = [ w 11 w 12 w 13 w 21 w 22 w 23 w 31 w 32 w 33 ] − α [ ∂ L ∂ w 11 ∂ L ∂ w 12 ∂ L ∂ w 13 ∂ L ∂ w 21 ∂ L ∂ w 22 ∂ L ∂ w 23 ∂ L ∂ w 31 ∂ L ∂ w 32 ∂ L ∂ w 33 ] \begin{bmatrix} w_{11}^{new} & w_{12}^{new} & w_{13}^{new} \\ w_{21}^{new} & w_{22}^{new} & w_{23}^{new} \\ w_{31}^{new} & w_{32}^{new} & w_{33}^{new} \end{bmatrix} = \begin{bmatrix} w_{11} & w_{12} & w_{13} \\ w_{21} & w_{22} & w_{23} \\ w_{31} & w_{32} & w_{33} \end{bmatrix} - \alpha \begin{bmatrix} \frac{\partial L}{\partial w_{11}} & \frac{\partial L}{\partial w_{12}} & \frac{\partial L}{\partial w_{13}} \\ \frac{\partial L}{\partial w_{21}} & \frac{\partial L}{\partial w_{22}} & \frac{\partial L}{\partial w_{23}} \\ \frac{\partial L}{\partial w_{31}} & \frac{\partial L}{\partial w_{32}} & \frac{\partial L}{\partial w_{33}} \end{bmatrix} ​w11new​w21new​w31new​​w12new​w22new​w32new​​w13new​w23new​w33new​​​=​w11​w21​w31​​w12​w22​w32​​w13​w23​w33​​​−α​∂w11​∂L​∂w21​∂L​∂w31​∂L​​∂w12​∂L​∂w22​∂L​∂w32​∂L​​∂w13​∂L​∂w23​∂L​∂w33​∂L​​​合并后(也就是矩阵加减法的对应元素运算): W n e w ( 1 ) = [ ( w 11 − α ∂ L ∂ w 11 ) ( w 12 − α ∂ L ∂ w 12 ) ( w 13 − α ∂ L ∂ w 13 ) ( w 21 − α ∂ L ∂ w 21 ) ( w 22 − α ∂ L ∂ w 22 ) ( w 23 − α ∂ L ∂ w 23 ) ( w 31 − α ∂ L ∂ w 31 ) ( w 32 − α ∂ L ∂ w 32 ) ( w 33 − α ∂ L ∂ w 33 ) ] W^{(1)}_{new} = \begin{bmatrix} \left(w_{11} - \alpha \frac{\partial L}{\partial w_{11}}\right) & \left(w_{12} - \alpha \frac{\partial L}{\partial w_{12}}\right) & \left(w_{13} - \alpha \frac{\partial L}{\partial w_{13}}\right) \\ \left(w_{21} - \alpha \frac{\partial L}{\partial w_{21}}\right) & \left(w_{22} - \alpha \frac{\partial L}{\partial w_{22}}\right) & \left(w_{23} - \alpha \frac{\partial L}{\partial w_{23}}\right) \\ \left(w_{31} - \alpha \frac{\partial L}{\partial w_{31}}\right) & \left(w_{32} - \alpha \frac{\partial L}{\partial w_{32}}\right) & \left(w_{33} - \alpha \frac{\partial L}{\partial w_{33}}\right) \end{bmatrix} Wnew(1)​=​(w11​−α∂w11​∂L​)(w21​−α∂w21​∂L​)(w31​−α∂w31​∂L​)​(w12​−α∂w12​∂L​)(w22​−α∂w22​∂L​)(w32​−α∂w32​∂L​)​(w13​−α∂w13​∂L​)(w23​−α∂w23​∂L​)(w33​−α∂w33​∂L​)​​第三步:偏置向量的同步更新同理,偏置 b ( 1 ) b^{(1)} b(1) 是一个 3 × 1 3 \times 1 3×1 的列向量。标量 L L L 对偏置向量 b ( 1 ) b^{(1)} b(1) 的梯度,也是一个 3 × 1 3 \times 1 3×1 的列向量: ∂ L ∂ b ( 1 ) = [ ∂ L ∂ b 1 ∂ L ∂ b 2 ∂ L ∂ b 3 ] \frac{\partial L}{\partial b^{(1)}} = \begin{bmatrix} \frac{\partial L}{\partial b_1} \\ \frac{\partial L}{\partial b_2} \\ \frac{\partial L}{\partial b_3} \end{bmatrix} ∂b(1)∂L​=​∂b1​∂L​∂b2​∂L​∂b3​∂L​​​它的矩阵梯度下降更新公式是: b n e w ( 1 ) = b o l d ( 1 ) − α ⋅ ∂ L ∂ b ( 1 ) b^{(1)}_{new} = b^{(1)}_{old} - \alpha \cdot \frac{\partial L}{\partial b^{(1)}} bnew(1)​=bold(1)​−α⋅∂b(1)∂L​展开后: [ b 1 n e w b 2 n e w b 3 n e w ] = [ ( b 1 − α ∂ L ∂ b 1 ) ( b 2 − α ∂ L ∂ b 2 ) ( b 3 − α ∂ L ∂ b 3 ) ] \begin{bmatrix} b_1^{new} \\ b_2^{new} \\ b_3^{new} \end{bmatrix} = \begin{bmatrix} \left(b_1 - \alpha \frac{\partial L}{\partial b_1}\right) \\ \left(b_2 - \alpha \frac{\partial L}{\partial b_2}\right) \\ \left(b_3 - \alpha \frac{\partial L}{\partial b_3}\right) \end{bmatrix} ​b1new​b2new​b3new​​​=​(b1​−α∂b1​∂L​)(b2​−α∂b2​∂L​)(b3​−α∂b3​∂L​)​​

2.3 反向传播

笔者在这一块也是晕了好久,感觉还是要从具体的例子,具体的矩阵展开才能方便理解。现在我们从一个最简单,最通用的(2,3,2)简易神经网络,完整的走一遍整个前向传播,梯度计算,反向传播的流程。

在这里插入图片描述

第一阶段:前向传播

构建一个结构为 (2, 3, 2) 的全连接前馈神经网络,网络包含输入层、单隐藏层与输出层。设输入向量为 x = [ x 1 x 2 ] \bm{x} = \begin{bmatrix} x_1 \\ x_2 \end{bmatrix} x=[x1​x2​​]输入层至隐藏层的权重矩阵与偏置向量分别为 W ( 1 ) = [ w 11 ( 1 ) w 12 ( 1 ) w 21 ( 1 ) w 22 ( 1 ) w 31 ( 1 ) w 32 ( 1 ) ] , b ( 1 ) = [ b 1 ( 1 ) b 2 ( 1 ) b 3 ( 1 ) ] \bm{W}^{(1)} = \begin{bmatrix} w_{11}^{(1)} & w_{12}^{(1)} \\ w_{21}^{(1)} & w_{22}^{(1)} \\ w_{31}^{(1)} & w_{32}^{(1)} \end{bmatrix}, \quad \bm{b}^{(1)} = \begin{bmatrix} b_1^{(1)} \\ b_2^{(1)} \\ b_3^{(1)} \end{bmatrix} W(1)=​w11(1)​w21(1)​w31(1)​​w12(1)​w22(1)​w32(1)​​​,b(1)=​b1(1)​b2(1)​b3(1)​​​隐藏层加权和为 z ( 1 ) = W ( 1 ) x + b ( 1 ) = [ w 11 ( 1 ) x 1 + w 12 ( 1 ) x 2 + b 1 ( 1 ) w 21 ( 1 ) x 1 + w 22 ( 1 ) x 2 + b 2 ( 1 ) w 31 ( 1 ) x 1 + w 32 ( 1 ) x 2 + b 3 ( 1 ) ] \bm{z}^{(1)} = \bm{W}^{(1)}\bm{x} + \bm{b}^{(1)} = \begin{bmatrix} w_{11}^{(1)}x_1 + w_{12}^{(1)}x_2 + b_1^{(1)} \\ w_{21}^{(1)}x_1 + w_{22}^{(1)}x_2 + b_2^{(1)} \\ w_{31}^{(1)}x_1 + w_{32}^{(1)}x_2 + b_3^{(1)} \end{bmatrix} z(1)=W(1)x+b(1)=​w11(1)​x1​+w12(1)​x2​+b1(1)​w21(1)​x1​+w22(1)​x2​+b2(1)​w31(1)​x1​+w32(1)​x2​+b3(1)​​​经激活函数 σ ( ⋅ ) \sigma(\cdot) σ(⋅) 后得到隐藏层输出 a ( 1 ) = σ ( z ( 1 ) ) \bm{a}^{(1)} = \sigma(\bm{z}^{(1)}) a(1)=σ(z(1))隐藏层至输出层的权重矩阵与偏置向量分别为 W ( 2 ) = [ w 11 ( 2 ) w 12 ( 2 ) w 13 ( 2 ) w 21 ( 2 ) w 22 ( 2 ) w 23 ( 2 ) ] , b ( 2 ) = [ b 1 ( 2 ) b 2 ( 2 ) ] \bm{W}^{(2)} = \begin{bmatrix} w_{11}^{(2)} & w_{12}^{(2)} & w_{13}^{(2)} \\ w_{21}^{(2)} & w_{22}^{(2)} & w_{23}^{(2)} \end{bmatrix}, \quad \bm{b}^{(2)} = \begin{bmatrix} b_1^{(2)} \\ b_2^{(2)} \end{bmatrix} W(2)=[w11(2)​w21(2)​​w12(2)​w22(2)​​w13(2)​w23(2)​​],b(2)=[b1(2)​b2(2)​​]输出层加权和为 z ( 2 ) = W ( 2 ) a ( 1 ) + b ( 2 ) = [ w 11 ( 2 ) a 1 ( 1 ) + w 12 ( 2 ) a 2 ( 1 ) + w 13 ( 2 ) a 3 ( 1 ) + b 1 ( 2 ) w 21 ( 2 ) a 1 ( 1 ) + w 22 ( 2 ) a 2 ( 1 ) + w 23 ( 2 ) a 3 ( 1 ) + b 2 ( 2 ) ] \bm{z}^{(2)} = \bm{W}^{(2)}\bm{a}^{(1)} + \bm{b}^{(2)} = \begin{bmatrix} w_{11}^{(2)}a_1^{(1)} + w_{12}^{(2)}a_2^{(1)} + w_{13}^{(2)}a_3^{(1)} + b_1^{(2)} \\ w_{21}^{(2)}a_1^{(1)} + w_{22}^{(2)}a_2^{(1)} + w_{23}^{(2)}a_3^{(1)} + b_2^{(2)} \end{bmatrix} z(2)=W(2)a(1)+b(2)=[w11(2)​a1(1)​+w12(2)​a2(1)​+w13(2)​a3(1)​+b1(2)​w21(2)​a1(1)​+w22(2)​a2(1)​+w23(2)​a3(1)​+b2(2)​​]最终网络输出为 y ^ = σ ( z ( 2 ) ) = [ y ^ 1 y ^ 2 ] \hat{\bm{y}} = \sigma(\bm{z}^{(2)}) = \begin{bmatrix} \hat{y}_1 \\ \hat{y}_2 \end{bmatrix} y^​=σ(z(2))=[y^​1​y^​2​​]对比预测值 y ^ \bm{\hat{y}} y^​ 和真实标签 y \bm{y} y。 L L L 是一个标量(比如算出来 L = 1.25 L = 1.25 L=1.25)。前向传播结束。 现在,显存里保存了 x , z ( 1 ) , a ( 1 ) , z ( 2 ) , y ^ \bm{x}, \bm{z}^{(1)}, \bm{a}^{(1)}, \bm{z}^{(2)}, \bm{\hat{y}} x,z(1),a(1),z(2),y^​ 这些具体的数值矩阵。(实际上,框架通常优先存 a a a 弃 z z z。)

第二阶段:反向传播与“误差项 δ \bm{\delta} δ”

反向传播的目标,是求出标量 L L L 对那两个权重矩阵 W ( 2 ) \bm{W}^{(2)} W(2) 和 W ( 1 ) \bm{W}^{(1)} W(1) 的导数。核心插曲:误差项 δ \bm{\delta} δ 到底是个啥?定义:第 l l l 层的误差项 δ ( l ) \bm{\delta}^{(l)} δ(l),等于损失 L L L 对该层未激活状态 z ( l ) \bm{z}^{(l)} z(l) 的导数。 δ ( l ) = ∂ L ∂ z ( l ) \bm{\delta}^{(l)} = \frac{\partial L}{\partial \bm{z}^{(l)}} δ(l)=∂z(l)∂L​它在 GPU 里具体是什么?假设输出层 z ( 2 ) = [ 2.0 − 1.0 ] \bm{z}^{(2)} = \begin{bmatrix} 2.0 \\ -1.0 \end{bmatrix} z(2)=[2.0−1.0​]。程序算完偏导数后,得出 δ ( 2 ) = [ 0.4 − 0.2 ] \bm{\delta}^{(2)} = \begin{bmatrix} 0.4 \\ -0.2 \end{bmatrix} δ(2)=[0.4−0.2​]。这就是具体数值!这组数值的物理含义是:如果把 z 1 ( 2 ) z^{(2)}_1 z1(2)​ (当前是 2.0) 偷偷增加 1,总损失 L L L 就会增加 0.4。如果把 z 2 ( 2 ) z^{(2)}_2 z2(2)​ (当前是 -1.0) 偷偷增加 1,总损失 L L L 就会减少 0.2。所以, δ \bm{\delta} δ 矩阵里的每一个数字,就是一个明确的指导信号:告诉对应的神经元,你的值是该往上调还是往下调,调的幅度是多大。
梯度下降的最终目的,确实是求出损失函数 L L L 对每个参数矩阵(权重 W W W 和偏置 b b b)的偏导数,以此来更新参数。即: W = W − α ∂ L ∂ W W = W - \alpha \frac{\partial L}{\partial W} W=W−α∂W∂L​ b = b − α ∂ L ∂ b b = b - \alpha \frac{\partial L}{\partial b} b=b−α∂b∂L​ 但是为什么要重点去求对“未激活状态 z z z”的偏导数(即误差项 δ \delta δ)呢?因为在微积分的链式法则(Chain Rule)中,求出 δ \delta δ 是求出 W W W 偏导数的“必经之路”,也是误差能够一层一层从后往前传递的“接力棒”。
在神经网络中,参数 W ( l ) W^{(l)} W(l) 并不是直接决定损失 L L L 的,它的作用需要经过中间变量的传递。对于第 l l l 层,前向传播的计算顺序是:权重 W ( l ) W^{(l)} W(l) 乘以上一层的输入 a ( l − 1 ) a^{(l-1)} a(l−1),加上偏置 b ( l ) b^{(l)} b(l),得到未激活的线性输出 z ( l ) z^{(l)} z(l): z ( l ) = W ( l ) a ( l − 1 ) + b ( l ) z^{(l)} = W^{(l)} a^{(l-1)} + b^{(l)} z(l)=W(l)a(l−1)+b(l) z ( l ) z^{(l)} z(l) 经过激活函数(如 ReLU、Sigmoid),得到激活后的输出 a ( l ) a^{(l)} a(l)。这个过程不断向后传递,最终计算出总损失 L L L。可以看到,因果链条是: W ( l ) → z ( l ) → ⋯ → L W^{(l)} \rightarrow z^{(l)} \rightarrow \dots \rightarrow L W(l)→z(l)→⋯→L。2. 链式法则:必须“借道” z z z 才能求 W W W既然 L L L 是受 z ( l ) z^{(l)} z(l) 影响的,而 z ( l ) z^{(l)} z(l) 又是受 W ( l ) W^{(l)} W(l) 影响的。根据高数中的链式法则,我们要想求 L L L 对 W ( l ) W^{(l)} W(l) 的导数,就必须拆分为两步相乘: ∂ L ∂ W ( l ) = ∂ L ∂ z ( l ) ⋅ ∂ z ( l ) ∂ W ( l ) \frac{\partial L}{\partial W^{(l)}} = \frac{\partial L}{\partial z^{(l)}} \cdot \frac{\partial z^{(l)}}{\partial W^{(l)}} ∂W(l)∂L​=∂z(l)∂L​⋅∂W(l)∂z(l)​你看等式右边的第一项 ∂ L ∂ z ( l ) \frac{\partial L}{\partial z^{(l)}} ∂z(l)∂L​,这正是我们所定义的误差项 δ ( l ) \delta^{(l)} δ(l)。
一旦我们算出了这个核心的 δ ( l ) \delta^{(l)} δ(l),接下来求参数梯度的数学计算就易如反掌了。根据前面的公式 z ( l ) = W ( l ) a ( l − 1 ) + b ( l ) z^{(l)} = W^{(l)} a^{(l-1)} + b^{(l)} z(l)=W(l)a(l−1)+b(l),我们可以轻易得出 z z z 对 W W W 的导数,其实就是上一层传过来的输入 a ( l − 1 ) a^{(l-1)} a(l−1)。所以,把 δ ( l ) \delta^{(l)} δ(l) 代入上面的链式法则,我们最终真正用来更新参数的梯度公式(写成矩阵乘法形式)就变成了: ∂ L ∂ W ( l ) = δ ( l ) ( a ( l − 1 ) ) T \frac{\partial L}{\partial W^{(l)}} = \delta^{(l)} (a^{(l-1)})^T ∂W(l)∂L​=δ(l)(a(l−1))T ∂ L ∂ b ( l ) = δ ( l ) \frac{\partial L}{\partial b^{(l)}} = \delta^{(l)} ∂b(l)∂L​=δ(l)
误差项 δ \delta δ 的本质,就是当前这个神经元,对最终模型犯错所需要承担的『责任大小』,或者叫『敏感度』。

Step 1: 求输出层的误差项 δ ( 2 ) \bm{\delta}^{(2)} δ(2)
假设我们用的是最常见的均方误差(MSE): L = 1 2 ∑ i = 1 2 ( y ^ i − y i ) 2 L = \frac{1}{2} \sum_{i=1}^{2} (\hat{y}_i - y_i)^2 L=21​∑i=12​(y^​i​−yi​)2。注意: y ^ i \hat{y}_i y^​i​ 其实就是 a i ( 2 ) a^{(2)}_i ai(2)​,也就是 f ( z i ( 2 ) ) f(z^{(2)}_i) f(zi(2)​)。现在我们要对输出层的第一个神经元的 z 1 ( 2 ) z^{(2)}_1 z1(2)​ 求偏导(链式法则): ∂ L ∂ z 1 ( 2 ) = ∂ L ∂ y ^ 1 ⋅ ∂ y ^ 1 ∂ z 1 ( 2 ) \frac{\partial L}{\partial z^{(2)}_1} = \frac{\partial L}{\partial \hat{y}_1} \cdot \frac{\partial \hat{y}_1}{\partial z^{(2)}_1} ∂z1(2)​∂L​=∂y^​1​∂L​⋅∂z1(2)​∂y^​1​​第一部分: ∂ L ∂ y ^ 1 \frac{\partial L}{\partial \hat{y}_1} ∂y^​1​∂L​ 就是对 1 2 ( y ^ 1 − y 1 ) 2 \frac{1}{2}(\hat{y}_1 - y_1)^2 21​(y^​1​−y1​)2 求导,结果是 ( y ^ 1 − y 1 ) (\hat{y}_1 - y_1) (y^​1​−y1​)。第二部分: ∂ y ^ 1 ∂ z 1 ( 2 ) \frac{\partial \hat{y}_1}{\partial z^{(2)}_1} ∂z1(2)​∂y^​1​​,因为 y ^ 1 = f ( z 1 ( 2 ) ) \hat{y}_1 = f(z^{(2)}_1) y^​1​=f(z1(2)​),所以导数就是 f ′ ( z 1 ( 2 ) ) f'(z^{(2)}_1) f′(z1(2)​)。两者相乘,第一个神经元的误差项就是: δ 1 ( 2 ) = ( y ^ 1 − y 1 ) ⋅ f ′ ( z 1 ( 2 ) ) \delta^{(2)}_1 = (\hat{y}_1 - y_1) \cdot f'(z^{(2)}_1) δ1(2)​=(y^​1​−y1​)⋅f′(z1(2)​)。同理,第二个神经元的误差项是: δ 2 ( 2 ) = ( y ^ 2 − y 2 ) ⋅ f ′ ( z 2 ( 2 ) ) \delta^{(2)}_2 = (\hat{y}_2 - y_2) \cdot f'(z^{(2)}_2) δ2(2)​=(y^​2​−y2​)⋅f′(z2(2)​)。逐元素相乘(Hadamard Product,符号是 ⊙ \odot ⊙)的意思就是:上下两个形状一模一样的矩阵,对应位置的元素自己乘自己,不搞复杂的矩阵乘法(行乘列)。 δ ( 2 ) = [ y ^ 1 − y 1 y ^ 2 − y 2 ] ⊙ [ f ′ ( z 1 ( 2 ) ) f ′ ( z 2 ( 2 ) ) ] = [ ( y ^ 1 − y 1 ) ⋅ f ′ ( z 1 ( 2 ) ) ( y ^ 2 − y 2 ) ⋅ f ′ ( z 2 ( 2 ) ) ] \bm{\delta}^{(2)} = \begin{bmatrix} \hat{y}_1 - y_1 \\ \hat{y}_2 - y_2 \end{bmatrix} \odot \begin{bmatrix} f'(z^{(2)}_1) \\ f'(z^{(2)}_2) \end{bmatrix} = \begin{bmatrix} (\hat{y}_1 - y_1) \cdot f'(z^{(2)}_1) \\ (\hat{y}_2 - y_2) \cdot f'(z^{(2)}_2) \end{bmatrix} δ(2)=[y^​1​−y1​y^​2​−y2​​]⊙[f′(z1(2)​)f′(z2(2)​)​]=[(y^​1​−y1​)⋅f′(z1(2)​)(y^​2​−y2​)⋅f′(z2(2)​)​]这就是 δ ( 2 ) \bm{\delta}^{(2)} δ(2) 的真实面貌。即: δ ( 2 ) = ∂ L ∂ z ( 2 ) = ( y ^ − y ) ⊙ f ′ ( z ( 2 ) ) \bm{\delta}^{(2)} = \frac{\partial L}{\partial \bm{z}^{(2)}} = (\bm{\hat{y}} - \bm{y}) \odot f'(\bm{z}^{(2)}) δ(2)=∂z(2)∂L​=(y^​−y)⊙f′(z(2))
Step 2: 求输出层权重 W ( 2 ) \bm{W}^{(2)} W(2) 的梯度矩阵
拿到 δ ( 2 ) \bm{\delta}^{(2)} δ(2) 后,直接套公式(误差项乘以前一层输出的转置): ∂ L ∂ W ( 2 ) = δ ( 2 ) ( a ( 1 ) ) T \frac{\partial L}{\partial \bm{W}^{(2)}} = \bm{\delta}^{(2)} (\bm{a}^{(1)})^T ∂W(2)∂L​=δ(2)(a(1))T
上面这个公式怎么来的呢?我们不跳步,先看单个权重,再拼成矩阵。回忆一下第二层(输出层)的线性计算公式展开: z 1 ( 2 ) = W 11 ( 2 ) a 1 ( 1 ) + W 12 ( 2 ) a 2 ( 1 ) + W 13 ( 2 ) a 3 ( 1 ) + b 1 ( 2 ) 。 z^{(2)}_1 = W^{(2)}_{11}a^{(1)}_1 + W^{(2)}_{12}a^{(1)}_2 + W^{(2)}_{13}a^{(1)}_3 + b^{(2)}_1。 z1(2)​=W11(2)​a1(1)​+W12(2)​a2(1)​+W13(2)​a3(1)​+b1(2)​。 z 2 ( 2 ) = W 21 ( 2 ) a 1 ( 1 ) + W 22 ( 2 ) a 2 ( 1 ) + W 23 ( 2 ) a 3 ( 1 ) + b 2 ( 2 ) z^{(2)}_2 = W^{(2)}_{21}a^{(1)}_1 + W^{(2)}_{22}a^{(1)}_2 + W^{(2)}_{23}a^{(1)}_3 + b^{(2)}_2 z2(2)​=W21(2)​a1(1)​+W22(2)​a2(1)​+W23(2)​a3(1)​+b2(2)​现在,我们要问:损失 L L L 对权重 W 11 ( 2 ) W^{(2)}_{11} W11(2)​ 的偏导数是多少?(链式法则) ∂ L ∂ W 11 ( 2 ) = ∂ L ∂ z 1 ( 2 ) ⋅ ∂ z 1 ( 2 ) ∂ W 11 ( 2 ) \frac{\partial L}{\partial W^{(2)}_{11}} = \frac{\partial L}{\partial z^{(2)}_1} \cdot \frac{\partial z^{(2)}_1}{\partial W^{(2)}_{11}} ∂W11(2)​∂L​=∂z1(2)​∂L​⋅∂W11(2)​∂z1(2)​​前面这一项 ∂ L ∂ z 1 ( 2 ) \frac{\partial L}{\partial z^{(2)}_1} ∂z1(2)​∂L​,我们刚刚在上面求过了!它就是 δ 1 ( 2 ) \delta^{(2)}_1 δ1(2)​。后面这一项 ∂ z 1 ( 2 ) ∂ W 11 ( 2 ) \frac{\partial z^{(2)}_1}{\partial W^{(2)}_{11}} ∂W11(2)​∂z1(2)​​,你看上面的展开式,对 W 11 ( 2 ) W^{(2)}_{11} W11(2)​ 求导,剩下的常数系数是谁?是 a 1 ( 1 ) a^{(1)}_1 a1(1)​。所以: ∂ L ∂ W 11 ( 2 ) = δ 1 ( 2 ) ⋅ a 1 ( 1 ) \frac{\partial L}{\partial W^{(2)}_{11}} = \delta^{(2)}_1 \cdot a^{(1)}_1 ∂W11(2)​∂L​=δ1(2)​⋅a1(1)​。同理,随便挑一个,比如对 W 23 ( 2 ) W^{(2)}_{23} W23(2)​ 求导: ∂ L ∂ W 23 ( 2 ) = δ 2 ( 2 ) ⋅ a 3 ( 1 ) \frac{\partial L}{\partial W^{(2)}_{23}} = \delta^{(2)}_2 \cdot a^{(1)}_3 ∂W23(2)​∂L​=δ2(2)​⋅a3(1)​。拼成矩阵:我们要计算的梯度矩阵 ∂ L ∂ W ( 2 ) \frac{\partial L}{\partial \bm{W}^{(2)}} ∂W(2)∂L​ 应该和 W ( 2 ) \bm{W}^{(2)} W(2) 形状一样,是 2 × 3 2 \times 3 2×3 的。我们把刚才推导的所有 6 个元素的偏导数填进去: ∂ L ∂ W ( 2 ) = [ δ 1 ( 2 ) ⋅ a 1 ( 1 ) δ 1 ( 2 ) ⋅ a 2 ( 1 ) δ 1 ( 2 ) ⋅ a 3 ( 1 ) δ 2 ( 2 ) ⋅ a 1 ( 1 ) δ 2 ( 2 ) ⋅ a 2 ( 1 ) δ 2 ( 2 ) ⋅ a 3 ( 1 ) ] \frac{\partial L}{\partial \bm{W}^{(2)}} = \begin{bmatrix} \delta^{(2)}_1 \cdot a^{(1)}_1 & \delta^{(2)}_1 \cdot a^{(1)}_2 & \delta^{(2)}_1 \cdot a^{(1)}_3 \\ \delta^{(2)}_2 \cdot a^{(1)}_1 & \delta^{(2)}_2 \cdot a^{(1)}_2 & \delta^{(2)}_2 \cdot a^{(1)}_3 \end{bmatrix} ∂W(2)∂L​=[δ1(2)​⋅a1(1)​δ2(2)​⋅a1(1)​​δ1(2)​⋅a2(1)​δ2(2)​⋅a2(1)​​δ1(2)​⋅a3(1)​δ2(2)​⋅a3(1)​​]你看这个 2 × 3 2 \times 3 2×3 的矩阵,它不正是用一个 2 × 1 2 \times 1 2×1 的列向量乘以一个 1 × 3 1 \times 3 1×3 的行向量得到的吗? [ δ 1 ( 2 ) δ 2 ( 2 ) ] × [ a 1 ( 1 ) a 2 ( 1 ) a 3 ( 1 ) ] \begin{bmatrix} \delta^{(2)}_1 \\ \delta^{(2)}_2 \end{bmatrix} \times \begin{bmatrix} a^{(1)}_1 & a^{(1)}_2 & a^{(1)}_3 \end{bmatrix} [δ1(2)​δ2(2)​​]×[a1(1)​​a2(1)​​a3(1)​​]
一句话通透总结它的本质:
“一个权重的梯度(即它要背的锅),本质上等于它所连接的『下游节点的误差大小( δ \delta δ)』,乘以『上游节点传来的信号强度( a a a)』。”
Step 3: 求隐藏层的误差项 δ ( 1 ) \bm{\delta}^{(1)} δ(1)

现在,误差要跨越矩阵传回隐藏层。隐藏层不知道最终的 L L L 是啥,它只能通过 W ( 2 ) \bm{W}^{(2)} W(2) 接收上面传下来的 δ ( 2 ) \bm{\delta}^{(2)} δ(2)。公式是: δ ( 1 ) = ( ( W ( 2 ) ) T δ ( 2 ) ) ⊙ f ′ ( z ( 1 ) ) \bm{\delta}^{(1)} = \left( (\bm{W}^{(2)})^T \bm{\delta}^{(2)} \right) \odot f'(\bm{z}^{(1)}) δ(1)=((W(2))Tδ(2))⊙f′(z(1))

为什么隐藏层的误差 δ ( 1 ) \bm{\delta}^{(1)} δ(1) 要用权重矩阵的转置乘以下一层的误差?我们要计算隐藏层第一个神经元的误差项: δ 1 ( 1 ) = ∂ L ∂ z 1 ( 1 ) \delta^{(1)}_1 = \frac{\partial L}{\partial z^{(1)}_1} δ1(1)​=∂z1(1)​∂L​。微积分的多变量链式法则告诉我们:如果一条河分成了两条支流,最后又汇合,你要算总流量的变化,必须把所有支流的变化加起来。隐藏层的第一个神经元的输出 a 1 ( 1 ) a^{(1)}_1 a1(1)​,它同时连接到了输出层的所有神经元( z 1 ( 2 ) z^{(2)}_1 z1(2)​ 和 z 2 ( 2 ) z^{(2)}_2 z2(2)​)。所以,求导时必须求和: δ 1 ( 1 ) = ∂ L ∂ z 1 ( 1 ) = ( ∂ L ∂ z 1 ( 2 ) ∂ z 1 ( 2 ) ∂ a 1 ( 1 ) + ∂ L ∂ z 2 ( 2 ) ∂ z 2 ( 2 ) ∂ a 1 ( 1 ) ) ⋅ ∂ a 1 ( 1 ) ∂ z 1 ( 1 ) \delta^{(1)}_1 = \frac{\partial L}{\partial z^{(1)}_1} = \left( \frac{\partial L}{\partial z^{(2)}_1}\frac{\partial z^{(2)}_1}{\partial a^{(1)}_1} + \frac{\partial L}{\partial z^{(2)}_2}\frac{\partial z^{(2)}_2}{\partial a^{(1)}_1} \right) \cdot \frac{\partial a^{(1)}_1}{\partial z^{(1)}_1} δ1(1)​=∂z1(1)​∂L​=(∂z1(2)​∂L​∂a1(1)​∂z1(2)​​+∂z2(2)​∂L​∂a1(1)​∂z2(2)​​)⋅∂z1(1)​∂a1(1)​​
我们一步步替换成我们认识的符号: ∂ L ∂ z 1 ( 2 ) \frac{\partial L}{\partial z^{(2)}_1} ∂z1(2)​∂L​ 是 δ 1 ( 2 ) \delta^{(2)}_1 δ1(2)​ ∂ L ∂ z 2 ( 2 ) \frac{\partial L}{\partial z^{(2)}_2} ∂z2(2)​∂L​ 是 δ 2 ( 2 ) \delta^{(2)}_2 δ2(2)​看上面 z ( 2 ) z^{(2)} z(2) 的展开式, ∂ z 1 ( 2 ) ∂ a 1 ( 1 ) \frac{\partial z^{(2)}_1}{\partial a^{(1)}_1} ∂a1(1)​∂z1(2)​​ 其实就是权重 W 11 ( 2 ) W^{(2)}_{11} W11(2)​; ∂ z 2 ( 2 ) ∂ a 1 ( 1 ) \frac{\partial z^{(2)}_2}{\partial a^{(1)}_1} ∂a1(1)​∂z2(2)​​ 就是权重 W 21 ( 2 ) W^{(2)}_{21} W21(2)​。 ∂ a 1 ( 1 ) ∂ z 1 ( 1 ) \frac{\partial a^{(1)}_1}{\partial z^{(1)}_1} ∂z1(1)​∂a1(1)​​ 就是激活函数导数 f ′ ( z 1 ( 1 ) ) f'(z^{(1)}_1) f′(z1(1)​)。代入进去,隐藏层第一个神经元的误差就是: δ 1 ( 1 ) = ( δ 1 ( 2 ) W 11 ( 2 ) + δ 2 ( 2 ) W 21 ( 2 ) ) ⋅ f ′ ( z 1 ( 1 ) ) \delta^{(1)}_1 = (\delta^{(2)}_1 W^{(2)}_{11} + \delta^{(2)}_2 W^{(2)}_{21}) \cdot f'(z^{(1)}_1) δ1(1)​=(δ1(2)​W11(2)​+δ2(2)​W21(2)​)⋅f′(z1(1)​)仔细看括号里的部分: ( δ 1 ( 2 ) W 11 ( 2 ) + δ 2 ( 2 ) W 21 ( 2 ) ) (\delta^{(2)}_1 W^{(2)}_{11} + \delta^{(2)}_2 W^{(2)}_{21}) (δ1(2)​W11(2)​+δ2(2)​W21(2)​)。这不就是用 W ( 2 ) \bm{W}^{(2)} W(2) 的第一列,去和 δ ( 2 ) \bm{\delta}^{(2)} δ(2) 这个向量做点积吗!
我们要一次性求出隐藏层 3 个神经元的误差括号里的部分:

里插入图片描述


左边这个矩阵,不偏不倚,正好是原权重矩阵 W ( 2 ) \bm{W}^{(2)} W(2)(尺寸 2 × 3 2 \times 3 2×3)的转置矩阵 ( W ( 2 ) ) T (\bm{W}^{(2)})^T (W(2))T(尺寸 3 × 2 3 \times 2 3×2)!所以,前面这部分总和,用矩阵写出来就是 ( W ( 2 ) ) T δ ( 2 ) (\bm{W}^{(2)})^T \bm{\delta}^{(2)} (W(2))Tδ(2)。
最后,再逐元素乘以各自的激活函数导数 ⊙ f ′ ( z ( 1 ) ) \odot f'(\bm{z}^{(1)}) ⊙f′(z(1)),就完成了所有隐藏层神经元误差项 δ ( 1 ) \bm{\delta}^{(1)} δ(1) 的计算。
在真实的大模型中,可能有几百层。我们 引入一个通用递推公式:第 l l l 层的误差项怎么来? δ ( l ) = ( ( W ( l + 1 ) ) T δ ( l + 1 ) ) ⊙ f ′ ( z ( l ) ) \delta^{(l)} = ((W^{(l+1)})^T \delta^{(l+1)}) \odot f'(z^{(l)}) δ(l)=((W(l+1))Tδ(l+1))⊙f′(z(l))只要你有最后一层的 δ \delta δ,就能像多米诺骨牌一样推回第一层。

总结:“把下游神经元的误差( δ \delta δ),乘上它们之间连接的权重( W W W),加起来,就是上一层神经元该背的锅!”

Step 4: 求隐藏层权重 W ( 1 ) \bm{W}^{(1)} W(1) 的梯度矩阵
和 Step 2 一模一样,拿到自己的 δ \bm{\delta} δ 后,乘以自己接收的输入的转置: ∂ L ∂ W ( 1 ) = δ ( 1 ) x T \frac{\partial L}{\partial \bm{W}^{(1)}} = \bm{\delta}^{(1)} \bm{x}^T ∂W(1)∂L​=δ(1)xT
为了防晕,我们可以做个简单的对比表:

在这里插入图片描述


简单来说:找 W W W 帮忙,是为了把误差 δ \delta δ 往回传;找 a a a 帮忙,是为了把梯度算出来去更新 W W W。

Step 5: 偏置b的梯度矩阵
每一层最开始的那个线性方程: z = W x + b \bm{z} = \bm{W}\bm{x} + \bm{b} z=Wx+b现在我们要算损失 L L L 对偏置 b \bm{b} b 的导数。根据链式法则: ∂ L ∂ b = ∂ L ∂ z ⋅ ∂ z ∂ b \frac{\partial L}{\partial \bm{b}} = \frac{\partial L}{\partial \bm{z}} \cdot \frac{\partial \bm{z}}{\partial \bm{b}} ∂b∂L​=∂z∂L​⋅∂b∂z​前半部分 ∂ L ∂ z \frac{\partial L}{\partial \bm{z}} ∂z∂L​,这就是我们辛辛苦苦算出来的** 误差项 δ \bm{\delta} δ**。后半部分 ∂ z ∂ b \frac{\partial \bm{z}}{\partial \bm{b}} ∂b∂z​ 是多少呢?看上面的线性方程,对于 b \bm{b} b 来说,它的系数就是 1(可以看作是加上了 1 ⋅ b 1 \cdot \bm{b} 1⋅b)。所以, z \bm{z} z 对 b \bm{b} b 的局部导数就是 1(严格来说是单位矩阵 I \mathbf{I} I)。任何数乘以 1 都不变,所以: ∂ L ∂ b = δ ⋅ 1 = δ \frac{\partial L}{\partial \bm{b}} = \bm{\delta} \cdot 1 = \bm{\delta} ∂b∂L​=δ⋅1=δ
只要有了各层的误差项 δ \bm{\delta} δ,剩下的全是机械的矩阵拼接:
【输出层 (Layer 2)】
1.权重梯度: ∂ L ∂ W ( 2 ) = δ ( 2 ) ( a ( 1 ) ) T \frac{\partial L}{\partial \boldsymbol{W}^{(2)}} = \boldsymbol{\delta}^{(2)}(\boldsymbol{a}^{(1)})^T ∂W(2)∂L​=δ(2)(a(1))T (需要乘以前一层的输出信号)
2.偏置梯度: ∂ L ∂ b ( 2 ) = δ ( 2 ) \frac{\partial L}{\partial \boldsymbol{b}^{(2)}} = \boldsymbol{\delta}^{(2)} ∂b(2)∂L​=δ(2) (原封不动的误差项)
【隐藏层 (Layer 1)】
3.权重梯度: ∂ L ∂ W ( 1 ) = δ ( 1 ) x T \frac{\partial L}{\partial \boldsymbol{W}^{(1)}} = \boldsymbol{\delta}^{(1)}\boldsymbol{x}^T ∂W(1)∂L​=δ(1)xT (需要乘以最开始的输入信号)
4.偏置梯度: ∂ L ∂ b ( 1 ) = δ ( 1 ) \frac{\partial L}{\partial \boldsymbol{b}^{(1)}} = \boldsymbol{\delta}^{(1)} ∂b(1)∂L​=δ(1) (原封不动的误差项)

当 ∂ L ∂ W ( 1 ) \frac{\partial L}{\partial W^{(1)}} ∂W(1)∂L​ 和 ∂ L ∂ W ( 2 ) \frac{\partial L}{\partial W^{(2)}} ∂W(2)∂L​ 以及两个偏置的梯度 ∂ L ∂ b ( 1 ) \frac{\partial L}{\partial b^{(1)}} ∂b(1)∂L​ 和 ∂ L ∂ b ( 2 ) \frac{\partial L}{\partial b^{(2)}} ∂b(2)∂L​全部计算完毕,并且这些梯度矩阵安安静静地躺在 GPU 的显存里时,“反向传播 (Backpropagation)” 这个动作就彻底宣告结束了。反向传播只负责算,不负责改。它的唯一任务,就是利用链式法则(误差项 δ \bm{\delta} δ 层层回传),把所有参数对 Loss 的偏导数(梯度)给算出来。一旦所有的梯度矩阵都计算完成,反向传播的历史使命就完成了。此时,神经网络的权重 W W W 和 b b b 一丁点也没有改变。
Step 6: 参数更新
拿到了反向传播提供的“情报”(梯度矩阵)后,接下来登场的就是优化器(Optimizer,最基础的就是梯度下降算法)。它不管前面是怎么算的,只是执行矩阵减法: W n e w ( 1 ) = W o l d ( 1 ) − α ⋅ ∂ L ∂ W ( 1 ) W^{(1)}_{new} = W^{(1)}_{old} - \alpha \cdot \frac{\partial L}{\partial W^{(1)}} Wnew(1)​=Wold(1)​−α⋅∂W(1)∂L​ W n e w ( 2 ) = W o l d ( 2 ) − α ⋅ ∂ L ∂ W ( 2 ) W^{(2)}_{new} = W^{(2)}_{old} - \alpha \cdot \frac{\partial L}{\partial W^{(2)}} Wnew(2)​=Wold(2)​−α⋅∂W(2)∂L​(偏置 b b b 也同理执行更新)执行完这一步,参数才真正发生了改变,模型才真正“学到了”一点东西,损失函数 L L L 才会在理论上往下降了一点点。

三 理顺思路

第一步:误差源头(最后一层 L L L)误差在这里产生,它是所有梯度的动力源。公式: δ ( L ) = ∇ a ( L ) L ⊙ f ′ ( z ( L ) ) \delta^{(L)} = \nabla_{a^{(L)}} \mathcal{L} \odot f'(z^{(L)}) δ(L)=∇a(L)​L⊙f′(z(L)) ∇ a ( L ) L \nabla_{a^{(L)}} \mathcal{L} ∇a(L)​L:损失函数对输出值的导数。 f ′ ( z ( L ) ) f'(z^{(L)}) f′(z(L)):最后一层的激活函数导数。

第二步:误差递推(从 L L L 层传回 L − 1 L-1 L−1 层)有了最后一层 L L L 的“锅”,我们要算出倒数第二层 L − 1 L-1 L−1 的“锅”:公式: δ ( L − 1 ) = ( ( W ( L ) ) T δ ( L ) ) ⊙ f ′ ( z ( L − 1 ) ) \delta^{(L-1)} = \left( (W^{(L)})^T \delta^{(L)} \right) \odot f'(z^{(L-1)}) δ(L−1)=((W(L))Tδ(L))⊙f′(z(L−1)) ( W ( L ) ) T δ ( L ) (W^{(L)})^T \delta^{(L)} (W(L))Tδ(L):这是把第 L L L 层的误差,通过它们之间的连接线(权重 W ( L ) W^{(L)} W(L))逆向传回给 L − 1 L-1 L−1 层。 ⊙ f ′ ( z ( L − 1 ) ) \odot f'(z^{(L-1)}) ⊙f′(z(L−1)):这是 L − 1 L-1 L−1 层自己的激活函数“门控效应”。

第三步:参数算账(计算 L L L 层的梯度)既然我们要更新的是连接 L − 1 L-1 L−1 层和 L L L 层之间的权重 W ( L ) W^{(L)} W(L),公式如下:1. 权重的梯度: ∂ L ∂ W ( L ) = δ ( L ) ( a ( L − 1 ) ) T \frac{\partial \mathcal{L}}{\partial W^{(L)}} = \delta^{(L)} (a^{(L-1)})^T ∂W(L)∂L​=δ(L)(a(L−1))T公式精髓: 这一层的误差 δ ( L ) \delta^{(L)} δ(L),乘以前一层传过来的信号 a ( L − 1 ) a^{(L-1)} a(L−1)。2. 偏置的梯度: ∂ L ∂ b ( L ) = δ ( L ) \frac{\partial \mathcal{L}}{\partial b^{(L)}} = \delta^{(L)} ∂b(L)∂L​=δ(L)第四步:执行更新(参数进化)拿到梯度后,优化器正式修改参数: W ( L ) = W ( L ) − α ∂ L ∂ W ( L ) W^{(L)} = W^{(L)} - \alpha \frac{\partial \mathcal{L}}{\partial W^{(L)}} W(L)=W(L)−α∂W(L)∂L​ b ( L ) = b ( L ) − α ∂ L ∂ b ( L ) b^{(L)} = b^{(L)} - \alpha \frac{\partial \mathcal{L}}{\partial b^{(L)}} b(L)=b(L)−α∂b(L)∂L​

四 总结

当我们把这些公式从 3 层推导到 L L L 层,从单个神经元想象到千亿参数时,我们可以发现:大模型其实就是一个极其巨大的、有着无数连线的‘分锅大会’现场。所谓的‘学习’,不过是在每一次前向传播后,拿着那张名为 Loss 的账单,从后往前,把每一个权重该负的责任、该领的罚单(梯度)算清楚,然后让他们在下一次表现得更好一点。搞懂了这套‘分锅’逻辑,我发现 Transformer 里的 Self-Attention 也好,各种层归一化(LayerNorm)也好,不过是在这套通用的反向传播框架下,增加了更复杂的‘分锅规则’罢了。

Read more

我和 AI 聊了一晚上,第二天它说“你好,请问有什么可以帮你?“凌晨我的 AI 尽然悄悄把记忆清空了!——OpenClaw Session 完全生存指南:重置、压缩、剪枝、记忆一网打尽

凌晨4点,我的 AI 悄悄把记忆清空了——OpenClaw Session 避坑指南 摘要:用 OpenClaw 搭了个 AI 助手,聊得好的,第二天一早它就"失忆"了?本文从一个真实踩坑出发,系统拆解 OpenClaw 的 Session 机制——重置(Reset)、压缩(Compaction)、剪枝(Pruning)、记忆(Memory)、会话控制(Session Tool)——帮你彻底搞懂"对话为什么会消失"以及"怎么让 AI 记住你"。 🤯 踩坑现场 事情是这样的: 我用 OpenClaw

OpenClaw WebSocket Channel开发实战:从零打造自定义 AI 通信通道

OpenClaw WebSocket Channel开发实战:从零打造自定义 AI 通信通道

🎯 项目背景 为什么做这个项目? 最近 OpenClaw 特别火🔥,这是一个强大的个人 AI 助手网关,支持接入 WhatsApp、Telegram、Discord 等 15+ 个消息平台。作为一个技术爱好者,我决定深入学习一下它的架构设计。 学习目标: * ✅ 理解多通道 AI 网关的架构模式 * ✅ 掌握 OpenClaw 插件化开发技能 * ✅ 实践 WebSocket 实时双向通信 * ✅ 为社区贡献一个实用的教学案例 项目定位:这不是一个生产级项目,而是一个学习性质的教学案例,帮助其他开发者快速上手 OpenClaw 插件开发。 技术栈 前端层:Vue 3 + WebSocket ↓ 服务端:Python + aiohttp + uv ↓ 通道层:Node.js + ws + OpenClaw Plugin SDK

被问爆的Agent实战:从0到1搭建可落地AI智能体

被问爆的Agent实战:从0到1搭建可落地AI智能体

🎁个人主页:User_芊芊君子 🎉欢迎大家点赞👍评论📝收藏⭐文章 🔍系列专栏:AI 文章目录: * 【前言】 * 一、先搞懂:2026年爆火的AI Agent,到底是什么? * 1.1 Agent的核心定义 * 1.2 Agent的4大核心能力 * 1.3 2026年Agent的3个热门落地场景 * 二、框架选型:2026年6大主流Agent框架,新手该怎么选? * 三、实战环节:从0到1搭建可落地的“邮件处理Agent”(全程代码+步骤) * 3.1 实战准备:环境搭建(10分钟搞定) * 3.1.1 安装Python环境 * 3.1.2 创建虚拟环境(避免依赖冲突) * 3.

做了一个 AI 鸿蒙 App,我发现逻辑变了

做了一个 AI 鸿蒙 App,我发现逻辑变了

子玥酱(掘金 / 知乎 / ZEEKLOG / 简书 同名) 大家好,我是子玥酱,一名长期深耕在一线的前端程序媛 👩‍💻。曾就职于多家知名互联网大厂,目前在某国企负责前端软件研发相关工作,主要聚焦于业务型系统的工程化建设与长期维护。 我持续输出和沉淀前端领域的实战经验,日常关注并分享的技术方向包括前端工程化、小程序、React / RN、Flutter、跨端方案, 在复杂业务落地、组件抽象、性能优化以及多端协作方面积累了大量真实项目经验。 技术方向:前端 / 跨端 / 小程序 / 移动端工程化 内容平台:掘金、知乎、ZEEKLOG、简书 创作特点:实战导向、源码拆解、少空谈多落地 文章状态:长期稳定更新,大量原创输出 我的内容主要围绕 前端技术实战、真实业务踩坑总结、框架与方案选型思考、行业趋势解读 展开。文章不会停留在“API 怎么用”,而是更关注为什么这么设计、在什么场景下容易踩坑、