Zhanbo's Blog
Back to home

CS546 Learning Notes:原来这就是更新参数,从 Linear Regression 到 SGD

Algorithm/Learning Notes
2026-09-07
12 min read
0 reads
AIMachine Learning

In brief

CS546 从第二节课开始,我就感觉有些跟不上了。很多东西本科听过概念,但没有实际用过,课件一换成公式就开始头晕。 所以这次先停下来,用几个数字把训练过程算一遍。这篇记录的是我从“这个就是更新参数的意思吗”到能分清 batch、step、epoch 和 SGD 的过程,还没有进入多层神经网络。

1. 先别看一大串公式,给我一个能算的例子

只有一个样本:输入 x=2x=2,正确答案 y=5y=5

模型是:

y^=wx+b\hat y=wx+b

初始参数 w=1,b=0w=1,b=0,学习率先设为 0.10.1。我们选用的 loss 是:

L=12(y^y)2L=\frac12(\hat y-y)^2

这里 y^\hat y 是预测,yy 是已知的正确答案,w,bw,b 是要学习的参数。训练时改变的是参数,不是把正确答案改到和预测一样。

y-hat = 2,L = 4.5,对吗?

对:

y^=1×2+0=2\hat y=1\times2+0=2 L=12(25)2=4.5L=\frac12(2-5)^2=4.5

到这里我没有问题。课件对应的是 Lecture 2 第 50 页的线性模型,以及第 63 页的单样本 loss。前面的 1/21/2 是这里选用的约定,求导时刚好能和平方带下来的 22 抵消。

2. 停,链式法则我有一点忘了

下一步是求 LLww 的偏导。我第一反应是:第一步到底该怎么写?

先把依赖关系拆开:

wy^=wx+bL=12(y^y)2w\longrightarrow\hat y=wx+b\longrightarrow L=\frac12(\hat y-y)^2

ww 先影响预测值,预测值再影响 loss,所以:

Lw=Ly^y^w\frac{\partial L}{\partial w} =\frac{\partial L}{\partial\hat y} \cdot\frac{\partial\hat y}{\partial w}

分别算两部分。对 ww 求偏导时,x,y,bx,y,b 都当作常数:

Ly^=y^y,y^w=x\frac{\partial L}{\partial\hat y}=\hat y-y, \qquad \frac{\partial\hat y}{\partial w}=x

因此:

Lw=(y^y)x=(3)×2=6\frac{\partial L}{\partial w}=(\hat y-y)x=(-3)\times2=-6

bb 同理,只是 wx+bwx+bbb 的导数是 11

Lb=y^y=3\frac{\partial L}{\partial b}=\hat y-y=-3

两个偏导打包在一起就是参数的梯度:(w,b)L=(6,3)\nabla_{(w,b)}L=(-6,-3)

这部分可以回看 Lecture 2 第 76–77 页的 Partial Derivatives 和 Gradients,以及 Lecture 3 第 42 页的 Chain Rule。先用这个简单例子理解链式法则,再看多层网络的符号,会容易一些。

3. 梯度是负的,为什么参数反而变大?

参数更新的规则是:

新参数=旧参数学习率×梯度\text{新参数}=\text{旧参数}-\text{学习率}\times\text{梯度}

于是:

wnew=10.1×(6)=1.6w_{\text{new}}=1-0.1\times(-6)=1.6 bnew=00.1×(3)=0.3b_{\text{new}}=0-0.1\times(-3)=0.3

是因为梯度表示让 loss 增加的方向,梯度这里是负的,我们要让 loss 减小的话,就要让 w、b 变大?

这个理解是对的。更准确地说,梯度指向当前位置附近 loss 增长最快的方向,更新时沿负梯度走。这里两个偏导都是负的,表示在当前点,分别增大一点 wwbb 会让 loss 减小。

从预测值也能理解:现在预测是 22,目标是 55,而且 x=2>0x=2>0。增大 wwbb 都能把预测往上推。

更新后重新算:

y^=1.6×2+0.3=3.5\hat y=1.6\times2+0.3=3.5 L=12(3.55)2=1.125L=\frac12(3.5-5)^2=1.125

loss 从 4.54.5 降到了 1.1251.125。这就是一次完整的更新:预测、算 loss、求梯度、更新参数,然后检查新结果。

这里说的是“增大一点”。学习率太大,可能跨过合适的位置,让 loss 反而增加。Lecture 3 第 4–11 页就是在讲这种更新和移动方向。

4. 所以这个过程就叫 Linear Regression 吗?

我当时的理解是:预测公式是线性的,先给一组随机的 w,bw,b,再根据正确答案 yy 和 loss 一点点更新,找到最好的参数。这整个过程是不是就叫 Linear Regression?

需要分开两个概念:

  • Linear Regression 是模型和任务的组合:用输入的加权和加偏置,预测数值。
  • Gradient Descent 是训练方法:通过梯度一步步调整参数。

所以刚才做的事准确说是:用 Gradient Descent 训练 Linear Regression。

线性回归也可以通过求导、令导数为零来直接求解,Lecture 2 第 55–61 页展示了单特征的推导。初始化也不一定随机,我们这个模型可以从 w=0,b=0w=0,b=0 开始。实际迭代训练的目标是最小化 loss,但有限次更新不代表已经精确到达最小值。

顺便把后来问到的模型和任务记一下:

类型关心的是什么例子
Regression 任务输出数值预测房价
Classification 任务输出类别判断评论正面或负面
Sequence tagging 任务给每个 token 标标签标出人名、地名
Generation 任务输出序列翻译、生成文本

模型则有 Linear Regression、Logistic Regression、Softmax Regression、MLP、Decision Tree 等。同一个任务可以换不同模型,同一类模型也可能服务不同任务。Logistic Regression 虽然名字里有 regression,通常用于分类。这些目前只是认识名字,还不等于我已经会实现了。

5. 老师把刚才的事情写成一行,我就又看不懂了

Lecture 3 第 4 页的更新公式可以整理成:

(w,b)(w,b)ηKiK(w,b)L(i)(w,b)(w,b)\leftarrow(w,b) -\frac{\eta}{|K|}\sum_{i\in K}\partial_{(w,b)}L^{(i)}(w,b)

这个就是更新参数的意思吗?怎么看得我头晕的。

拆开以后,它没有比刚才多出特别神秘的操作:

符号我现在怎么读
(w,b)(w,b)把两个参数打包写
\leftarrow用右边的新值替换旧值
η\eta学习率,就是刚才的 0.10.1
KK参与这次计算的一组样本索引
K\lvert K\rvert这组样本的数量
L(i)L^{(i)}ii 个样本的 loss,不是乘方
(w,b)L(i)\partial_{(w,b)}L^{(i)}ii 个样本对两个参数的梯度
1KiK\frac1{\lvert K\rvert}\sum_{i\in K}加起来,再取平均

整行读成:旧参数减去学习率乘这组样本的平均梯度,得到新参数。

刚才只有一个样本,平均梯度还是 (6,3)(-6,-3),所以就是:

(w,b)(1,0)0.1(6,3)=(1.6,0.3)(w,b)\leftarrow(1,0)-0.1(-6,-3)=(1.6,0.3)

本文把 KK 当集合、K|K| 当数量;课件其他页面也有直接用 KK 表示样本数量的写法,要结合所在页面看。

6. K 个样本又是啥?为什么要平均?

一个样本就是一组输入和正确答案 (x,y)(x,y)。例如 (2,5)(2,5)(1,3)(1,3)(3,7)(3,7) 就是三个样本。

是因为它们共用一个 loss function,所以要平均吗?

接近,但因果关系需要改一下。每个样本使用同一种 loss 公式,算出的 loss 数值可以不同。我们选择用平均 loss 衡量模型在这组数据上的整体表现

Lˉ(w,b)=1KiKL(i)(w,b)\bar L(w,b)=\frac1{|K|}\sum_{i\in K}L^{(i)}(w,b)

对平均 loss 求导,就得到平均梯度:

Lˉw=1KiKL(i)w\frac{\partial\bar L}{\partial w} =\frac1{|K|}\sum_{i\in K}\frac{\partial L^{(i)}}{\partial w}

不是“用了同一种 loss 就必须平均”,而是目标定义为平均 loss,求出来的自然就是平均梯度。Lecture 2 第 63–64 页对应这个整体训练目标。

7. 矩阵形式我会,但共用参数的原因还要再分清

如果三套房子,每套有面积和房龄两个特征,那么:

y^=Xw+b1\hat{\mathbf y}=X\mathbf w+b\mathbf1 X:(3,2),w:(2,1),y^:(3,1)X:(3,2),\qquad\mathbf w:(2,1),\qquad\hat{\mathbf y}:(3,1)

这个 shape 我能答出来。XX 每行是一套房子,每列是一个特征,bb 是共用的标量,b1b\mathbf1 表示给每个预测都加上它。课件常简写为 Xw+bX\mathbf w+b

因为每套房子对应同一个 loss function,我们只是把预测公式写三次变成矩阵形式?

后半句对,但共用参数的原因是:我们希望学出一条能用于不同房子的规则。变化的是每套房子的输入,参数保持共用,这样第 4 套没见过的房子也能直接代入预测。

共用模型参数和使用同一种 loss 公式,是两件事。分别给每套房子建模型,也能使用同一种平方误差,但那样没有学出一条直接用于新房子的共同规则。

对应 Lecture 2 第 62、65 页。

8. 多个样本的更新,我再算一次

这次只用两个样本 (2,5)(2,5)(1,3)(1,3),仍从 w=1,b=0w=1,b=0 开始。

样本预测预测减正确答案ww 的梯度bb 的梯度
(2,5)(2,5)2−3−6−3
(1,3)(1,3)1−2−2−2

注意,两个样本都使用同一组旧参数,中间还没有更新

平均梯度是:

gw=622=4,gb=322=2.5g_w=\frac{-6-2}{2}=-4,\qquad g_b=\frac{-3-2}{2}=-2.5

学习率仍为 0.10.1

wnew=1.4,bnew=0.25w_{\text{new}}=1.4,\qquad b_{\text{new}}=0.25

这就是用两个样本组成一个 batch,平均后更新一次。

9. Batch、Step、Epoch 终于能分开了

名字意思
Batch一次更新使用的那组样本
Batch size这组有多少个样本
Step在我们这个训练流程中,一次参数更新
Epoch把整个训练集完整遍历一遍

100 个样本,batch size 为 10,每个 batch 更新一次,那么一个 epoch 是 10 steps。训练 3 epochs,就是 30 次更新。

下一个 step 接着上一个 step 的参数继续算,进入下一个 epoch 也不会把参数重置。Lecture 3 第 12–15 页对应这些概念。

10. 放在循环里面更新也可以?我以为这样只顾各自样本

我们看普通 Python 的训练流程时,我注意到:处理样本的循环外更新,是先累加梯度,再平均。如果每处理一个样本就更新呢?

那会在 (2,5)(2,5) 先更新一次,(1,3)(1,3) 再更新一次。它们找的都是各自样本的局部最优解,最后整体 loss 不会真正降低?

第一句对,后面的判断不对。

首先,每个样本只让参数走一步,没有找到这个样本的最优解。其次,逐样本更新也能降低整体 loss,只是单步不保证整体 loss 都下降。

还是原来的两个样本,仍从 (w,b)=(1,0)(w,b)=(1,0) 开始:

  1. 第一个样本更新后,(w,b)=(1.6,0.3)(w,b)=(1.6,0.3)
  2. 第二个样本用新参数预测,得到 1.6×1+0.3=1.91.6\times1+0.3=1.9
  3. 第二个样本的两个梯度都是 1.93=1.11.9-3=-1.1
  4. 再更新,得到 (w,b)=(1.71,0.41)(w,b)=(1.71,0.41)

初始平均 loss 是 (4.5+2)/2=3.25(4.5+2)/2=3.25。两次逐样本更新后:

Lˉ=12[12(3.835)2+12(2.123)2]=0.535825\bar L=\frac12\left[\frac12(3.83-5)^2+\frac12(2.12-3)^2\right] =0.535825

确实比初始低。这个例子说明它可以改善整体表现,不是在保证逐样本方法永远更好。这里逐样本走了两步,batch 方法只走了一步,也不能据此判断谁训练更高效。

代码上也不能只把更新语句挪进循环:逐样本更新应该用当前样本的梯度,batch 更新应该用当前 batch 的平均梯度,不能不改梯度计算就直接移动代码。

11. SGD 原来就是这个,我以前没听过这个名字

SGD 是 Stochastic Gradient Descent,中文叫随机梯度下降。按 Lecture 3 第 13–14 页的定义,每次使用一个样本的梯度更新参数。

“随机”通常指随机抽样,或者每个 epoch 先打乱样本顺序。不是随机决定参数往哪走,方向依然来自梯度。前面两样本的固定顺序计算,只是为了方便展示逐样本更新。

为什么一个样本也能提供有用的方向?假设在同一组当前参数下,三个样本对 ww 的梯度分别是:

6,+2,5-6,\quad+2,\quad-5

全体平均是 3-3,所以平均梯度建议增大 ww。如果这步随机抽到第二个样本,就会用 +2+2,让 ww 减小,这一步甚至可能和整体方向相反。

但均匀随机抽样时,在固定参数下:

Ei[L(i)(w,b)]=1Ni=1NL(i)(w,b)\mathbb E_i[\nabla L^{(i)}(w,b)] =\frac1N\sum_{i=1}^{N}\nabla L^{(i)}(w,b)

也就是随机样本梯度的期望,等于全体平均梯度。这里 NN 是训练集样本总数。这解释了随机梯度为什么能作为整体梯度的估计,不是说连续更新时每一步参数都不变,也不是说每一步都一定下降。随机打乱后依次遍历也很常用,但和每一步独立均匀抽样不完全是同一个抽样过程。

如果有一百万个样本,全批量方法要处理完它们才更新一次,SGD 处理一个就能更新。它的单次更新便宜,但方向波动大;达到相同效果的总时间不一定更短。

方法一次更新用多少数据使用的梯度
Full-batch Gradient Descent整个训练集全体平均梯度
单样本 SGD一个样本当前样本梯度
Mini-batch Gradient Descent一小组样本这组的平均梯度

所以我们之前一起算两个样本:如果这就是全部训练数据,叫 full-batch;如果只是更大训练集里的一小组,叫 mini-batch。Mini-batch SGD 这个名称也会出现,课件第 15 页就是这样写的,要结合 batch size 判断实际怎么更新。

12. 现在我搞定了哪一部分?

我已经能手算单样本和两样本的梯度更新,能解释参数为什么沿负梯度移动,也能拆开老师那一行平均梯度公式。Batch、step、epoch 和逐样本 SGD 之间的关系,现在有实际数字可以对应了。

但这还不等于已经会训练神经网络。普通 Python 的训练循环目前只是读懂了核心流程,还需要自己写、运行和修改;softmax、分类 loss、多层网络、完整反向传播和词向量也还没有展开。训练 loss 降低与模型能否预测新数据之间的区别,之后也要继续补。

下次再看到更新公式,可以先拿 x=2,y=5,w=1,b=0x=2,y=5,w=1,b=0 代进去。公式读不顺的时候,先问自己:这一项对应我手算的哪一步?

课件复习位置

页码按 PDF 阅读器显示的页数计算,封面为第 1 页。公式使用统一记号整理,额外的数值演算来自这次学习讨论。

文件页码内容
Lecture2_NLP_Tasks_DL_intro.pdf50、62线性模型、向量表示
同上55–61单特征线性回归的直接求解
同上63–65Loss、训练目标、矩阵表示
同上76–77偏导数与梯度
Lecture3_DeepLearning_Background.pdf4–11更新公式与梯度下降图示
同上12–15Full-batch、SGD、epoch、mini-batch
同上42Chain Rule
ZB

Zhanbo Chen

Java Backend & AI Agent Developer

Back to home
Comments