文章

白话 DeepSeek 02|如何计算神经网络的参数

白话 DeepSeek 02|如何计算神经网络的参数

全文总结于 Bilibili UP 主飞天闪客的一小时到 Transformer 系列视频!

如何计算神经网络的参数:从损失函数到梯度下降与反向传播

摘要

这篇文章用直观比喻与必要数学并重的方式,讲清楚三件事:

  • 为什么需要“损失函数”来量化预测与真实之间的差距

  • 如何用“梯度下降”把参数一步步调到更好

  • 反向传播如何高效地计算大规模参数的梯度

阅读后,你应能独立回答:给定一个网络结构、数据与损失函数,如何把参数训练出来。

一、量化误差:损失函数(Loss Function)

训练的目标是找到一组最佳参数 $(w,b)$,使模型的预测 $\hat{y}$ 尽可能接近真实值 $y$。这个“接近”要有可计算的度量——这就是损失函数。

假设我们有一组数据:$x$(比如房屋面积)和 $y$(比如房价)。现在要找一条直线 $y=wx+b$ 来拟合这些点,怎么判断哪条线更好? 看下面的对比:左图的直线离大多数点很近,右图的直线明显偏离——但“近”和“远”需要一个可计算的标准,这就是损失函数的作用,它能把“预测与真实的差距”变成一个具体的数字。

1.1 从单点到整体

  • 单个样本的误差可以理解为“预测点到真实点的距离”。

  • 对于全体样本,把误差做“汇总 + 平均”更合理。

对单个样本来说,误差就像“预测点到真实点的竖直线段长度”。比如某个样本的真实房价是 $y$ ,模型预测是 $ŷ$ ,那单个误差可以用$|y-ŷ|$表示(绝对误差)。

但对全体样本,我们需要汇总误差:把所有样本的误差加起来再取平均,这样能反映整体拟合效果。

最常见的回归损失是均方误差(MSE):先把每个误差平方(避免正负抵消,同时放大 outliers 的影响),再求平均值。公式如下:

\[L(w,b)=\frac{1}{N}\sum_{i=1}^N\big(y_i-\hat{y}_i\big)^2\]

其中 $N$ 为样本数,$\hat{y}_i=f(x_i;w,b)$ 是模型对于第 $i$ 个样本的预测值。

从参数视角看,$L$ 是关于所有 $w,b$ 的函数,不同的 $w$ 和 $b$ 会计算出不同的 $L$ 。我们的任务就是寻找使 $L$ 尽可能小的 $(w,b)$。

1.2 几何直觉:一座“山”

如果把 $w$ 和 $b$ 当作横轴(高维参数就是无数个横轴),$L$ 当作纵轴,损失函数就像一座高低起伏的山。训练神经网络的过程,就像一个人站在山上,要找到通往谷底( $L$ 最小)的路。这时候问题来了:怎么找到下山的方向?

二、把损失降下来:梯度下降(Gradient Descent)

参数很少时(比如简单线性回归 $y=wx+b$ ),我们可以用“令偏导数为0”直接算出最优 $w$ 和 $b$ (解析解)。但神经网络是复杂的非线性函数,损失山的地形坑坑洼洼(非凸函数),没有直接的“谷底公式”,只能用“一步一步试”的迭代方法——梯度下降。

2.1 线性回归的精解 vs. 神经网络的挑战

  • 在线性回归 $y=wx+b$ 中,损失常是凸函数,求偏导为零可直接得到解析解。

  • 神经网络是非线性的复合函数,损失地形复杂且非凸,难有解析解,因此采用“迭代逼近”的梯度下降。

2.2 梯度告诉你“下坡最快的方向”

  • 梯度(Gradient)是由所有偏导数组成的向量:

  • 想象你站在损失山上,闭着眼睛也能感觉到“哪个方向走一步,高度降得最快”——这个方向就是梯度的反方向。梯度是一个向量,由损失函数对所有参数的偏导数组成:

\[\nabla L=\left(\frac{\partial L}{\partial w_1},\frac{\partial L}{\partial w_2},\dots,\frac{\partial L}{\partial b_1},\dots\right)\]
  • 几何意义:梯度指向“上升最快”的方向。

  • 要让损失减小,就沿“梯度的反方向”走:

\[w_{\text{new}}=w_{\text{old}}-\eta\,\frac{\partial L}{\partial w},\qquad b_{\text{new}}=b_{\text{old}}-\eta\,\frac{\partial L}{\partial b}\]

其中 $\eta$ 为学习率,控制每一步的步长。

实践要点:

  • 学习率太大易“跳过低谷”,太小则收敛很慢。

  • 常用自适应优化器(如 Adam、RMSProp)会在学习率调度与一阶二阶动量上做改进,本质仍属“沿梯度方向迭代”。

2.3 通俗理解:试错调整

比如你先随便选一个 $w$ 值,计算出 $L$ ;然后稍微增大 $w$,如果 $L$ 变大了,说明“往这个方向走是上山”,下次就减小 $w$ ;如果 $L$ 变小了,就继续往这个方向调。通过不断试错,让 $w$ 和 $b$ 慢慢靠近能让L最小的值——这就是梯度下降的朴素逻辑。

三、如何高效算梯度:反向传播(Backpropagation)

梯度下降的关键是“算出每个参数的偏导数”,但神经网络有几十上百万个参数,直接逐个计算会累死计算机。反向传播就是解决这个问题的“高效算法”,核心是链式法则和“中间结果复用”。

3.1 链式法则让复杂变简单

神经网络可以看作很多“线性变换 + 非线性激活”的复合:比如输入 $x$ 经过第一层线性变换$z_1=w_1x+b_1$ ,再经过激活函数 $a_1=f(z_1)$;然后a₁作为第二层输入,经过 $z_2=w_2a_1+b_2$、$a_2=f(z_2)$…… 最后输出 $\hat y$。整个过程是函数的复合:

\[\hat{y}=f_L\big(\cdots f_2(f_1(x))\cdots\big)\]

要求 $\frac{\partial L}{\partial w_1}$,用链式法则把大问题拆成局部偏导的乘积:

\[\frac{\partial L}{\partial w_1}=\frac{\partial L}{\partial \hat{y}}\cdot\frac{\partial \hat{y}}{\partial z}\cdot\frac{\partial z}{\partial w_1}\]
  • $\frac{\partial z}{\partial w_1}$:线性部分的局部导数

  • $\frac{\partial \hat{y}}{\partial z}$:激活函数的局部导数

  • $\frac{\partial L}{\partial \hat{y}}$:损失函数的局部导数

3.2 从右到左地复用中间量

反向传播从输出层开始,逐层向输入层传播梯度。每一层的梯度计算会复用后一层已算好的中间结果,避免重复计算,从而把“算一整个网络的所有偏导”的复杂度降到可训练的量级。

四、一次完整训练循环(Putting it all together)

  1. 前向传播:给定当前参数与输入 $x$,计算输出 $\hat{y}$ 与损失 $L$。

  2. 反向传播:基于链式法则,计算 $L$ 对所有参数的梯度。

  3. 参数更新:按梯度反方向、用学习率 $\eta$ 更新 $w,b$。

  4. 多轮迭代:重复 1–3,直到损失足够小或满足停止条件。

五、常见疑问与实践建议

  • 为什么不用绝对误差(MAE)?

  • 学习率如何设?

  • 一定会到“全局最低点”吗?

小结

  • 损失函数把“好不好”变成可计算的数。

  • 梯度下降提供了“往更好走”的方向与步长。

  • 反向传播让“大量参数的梯度”计算变得高效。

理解这三者的协同关系,就掌握了“如何计算并训练神经网络参数”的核心。

本文由作者按照 CC BY 4.0 进行授权