1. 先别看一大串公式,给我一个能算的例子
只有一个样本:输入 ,正确答案 。
模型是:
初始参数 ,学习率先设为 。我们选用的 loss 是:
这里 是预测, 是已知的正确答案, 是要学习的参数。训练时改变的是参数,不是把正确答案改到和预测一样。
y-hat = 2,L = 4.5,对吗?
对:
到这里我没有问题。课件对应的是 Lecture 2 第 50 页的线性模型,以及第 63 页的单样本 loss。前面的 是这里选用的约定,求导时刚好能和平方带下来的 抵消。
2. 停,链式法则我有一点忘了
下一步是求 对 的偏导。我第一反应是:第一步到底该怎么写?
先把依赖关系拆开:
先影响预测值,预测值再影响 loss,所以:
分别算两部分。对 求偏导时, 都当作常数:
因此:
对 同理,只是 对 的导数是 :
两个偏导打包在一起就是参数的梯度:。
这部分可以回看 Lecture 2 第 76–77 页的 Partial Derivatives 和 Gradients,以及 Lecture 3 第 42 页的 Chain Rule。先用这个简单例子理解链式法则,再看多层网络的符号,会容易一些。
3. 梯度是负的,为什么参数反而变大?
参数更新的规则是:
于是:
是因为梯度表示让 loss 增加的方向,梯度这里是负的,我们要让 loss 减小的话,就要让 w、b 变大?
这个理解是对的。更准确地说,梯度指向当前位置附近 loss 增长最快的方向,更新时沿负梯度走。这里两个偏导都是负的,表示在当前点,分别增大一点 或 会让 loss 减小。
从预测值也能理解:现在预测是 ,目标是 ,而且 。增大 或 都能把预测往上推。
更新后重新算:
loss 从 降到了 。这就是一次完整的更新:预测、算 loss、求梯度、更新参数,然后检查新结果。
这里说的是“增大一点”。学习率太大,可能跨过合适的位置,让 loss 反而增加。Lecture 3 第 4–11 页就是在讲这种更新和移动方向。
4. 所以这个过程就叫 Linear Regression 吗?
我当时的理解是:预测公式是线性的,先给一组随机的 ,再根据正确答案 和 loss 一点点更新,找到最好的参数。这整个过程是不是就叫 Linear Regression?
需要分开两个概念:
- Linear Regression 是模型和任务的组合:用输入的加权和加偏置,预测数值。
- Gradient Descent 是训练方法:通过梯度一步步调整参数。
所以刚才做的事准确说是:用 Gradient Descent 训练 Linear Regression。
线性回归也可以通过求导、令导数为零来直接求解,Lecture 2 第 55–61 页展示了单特征的推导。初始化也不一定随机,我们这个模型可以从 开始。实际迭代训练的目标是最小化 loss,但有限次更新不代表已经精确到达最小值。
顺便把后来问到的模型和任务记一下:
| 类型 | 关心的是什么 | 例子 |
|---|---|---|
| Regression 任务 | 输出数值 | 预测房价 |
| Classification 任务 | 输出类别 | 判断评论正面或负面 |
| Sequence tagging 任务 | 给每个 token 标标签 | 标出人名、地名 |
| Generation 任务 | 输出序列 | 翻译、生成文本 |
模型则有 Linear Regression、Logistic Regression、Softmax Regression、MLP、Decision Tree 等。同一个任务可以换不同模型,同一类模型也可能服务不同任务。Logistic Regression 虽然名字里有 regression,通常用于分类。这些目前只是认识名字,还不等于我已经会实现了。
5. 老师把刚才的事情写成一行,我就又看不懂了
Lecture 3 第 4 页的更新公式可以整理成:
这个就是更新参数的意思吗?怎么看得我头晕的。
拆开以后,它没有比刚才多出特别神秘的操作:
| 符号 | 我现在怎么读 |
|---|---|
| 把两个参数打包写 | |
| 用右边的新值替换旧值 | |
| 学习率,就是刚才的 | |
| 参与这次计算的一组样本索引 | |
| 这组样本的数量 | |
| 第 个样本的 loss,不是乘方 | |
| 第 个样本对两个参数的梯度 | |
| 加起来,再取平均 |
整行读成:旧参数减去学习率乘这组样本的平均梯度,得到新参数。
刚才只有一个样本,平均梯度还是 ,所以就是:
本文把 当集合、 当数量;课件其他页面也有直接用 表示样本数量的写法,要结合所在页面看。
6. K 个样本又是啥?为什么要平均?
一个样本就是一组输入和正确答案 。例如 、、 就是三个样本。
是因为它们共用一个 loss function,所以要平均吗?
接近,但因果关系需要改一下。每个样本使用同一种 loss 公式,算出的 loss 数值可以不同。我们选择用平均 loss 衡量模型在这组数据上的整体表现:
对平均 loss 求导,就得到平均梯度:
不是“用了同一种 loss 就必须平均”,而是目标定义为平均 loss,求出来的自然就是平均梯度。Lecture 2 第 63–64 页对应这个整体训练目标。
7. 矩阵形式我会,但共用参数的原因还要再分清
如果三套房子,每套有面积和房龄两个特征,那么:
这个 shape 我能答出来。 每行是一套房子,每列是一个特征, 是共用的标量, 表示给每个预测都加上它。课件常简写为 。
因为每套房子对应同一个 loss function,我们只是把预测公式写三次变成矩阵形式?
后半句对,但共用参数的原因是:我们希望学出一条能用于不同房子的规则。变化的是每套房子的输入,参数保持共用,这样第 4 套没见过的房子也能直接代入预测。
共用模型参数和使用同一种 loss 公式,是两件事。分别给每套房子建模型,也能使用同一种平方误差,但那样没有学出一条直接用于新房子的共同规则。
对应 Lecture 2 第 62、65 页。
8. 多个样本的更新,我再算一次
这次只用两个样本 和 ,仍从 开始。
| 样本 | 预测 | 预测减正确答案 | 对 的梯度 | 对 的梯度 |
|---|---|---|---|---|
| 2 | −3 | −6 | −3 | |
| 1 | −2 | −2 | −2 |
注意,两个样本都使用同一组旧参数,中间还没有更新。
平均梯度是:
学习率仍为 :
这就是用两个样本组成一个 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 的训练流程时,我注意到:处理样本的循环外更新,是先累加梯度,再平均。如果每处理一个样本就更新呢?
那会在 先更新一次, 再更新一次。它们找的都是各自样本的局部最优解,最后整体 loss 不会真正降低?
第一句对,后面的判断不对。
首先,每个样本只让参数走一步,没有找到这个样本的最优解。其次,逐样本更新也能降低整体 loss,只是单步不保证整体 loss 都下降。
还是原来的两个样本,仍从 开始:
- 第一个样本更新后,。
- 第二个样本用新参数预测,得到 。
- 第二个样本的两个梯度都是 。
- 再更新,得到 。
初始平均 loss 是 。两次逐样本更新后:
确实比初始低。这个例子说明它可以改善整体表现,不是在保证逐样本方法永远更好。这里逐样本走了两步,batch 方法只走了一步,也不能据此判断谁训练更高效。
代码上也不能只把更新语句挪进循环:逐样本更新应该用当前样本的梯度,batch 更新应该用当前 batch 的平均梯度,不能不改梯度计算就直接移动代码。
11. SGD 原来就是这个,我以前没听过这个名字
SGD 是 Stochastic Gradient Descent,中文叫随机梯度下降。按 Lecture 3 第 13–14 页的定义,每次使用一个样本的梯度更新参数。
“随机”通常指随机抽样,或者每个 epoch 先打乱样本顺序。不是随机决定参数往哪走,方向依然来自梯度。前面两样本的固定顺序计算,只是为了方便展示逐样本更新。
为什么一个样本也能提供有用的方向?假设在同一组当前参数下,三个样本对 的梯度分别是:
全体平均是 ,所以平均梯度建议增大 。如果这步随机抽到第二个样本,就会用 ,让 减小,这一步甚至可能和整体方向相反。
但均匀随机抽样时,在固定参数下:
也就是随机样本梯度的期望,等于全体平均梯度。这里 是训练集样本总数。这解释了随机梯度为什么能作为整体梯度的估计,不是说连续更新时每一步参数都不变,也不是说每一步都一定下降。随机打乱后依次遍历也很常用,但和每一步独立均匀抽样不完全是同一个抽样过程。
如果有一百万个样本,全批量方法要处理完它们才更新一次,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 降低与模型能否预测新数据之间的区别,之后也要继续补。
下次再看到更新公式,可以先拿 代进去。公式读不顺的时候,先问自己:这一项对应我手算的哪一步?
课件复习位置
页码按 PDF 阅读器显示的页数计算,封面为第 1 页。公式使用统一记号整理,额外的数值演算来自这次学习讨论。
| 文件 | 页码 | 内容 |
|---|---|---|
Lecture2_NLP_Tasks_DL_intro.pdf | 50、62 | 线性模型、向量表示 |
| 同上 | 55–61 | 单特征线性回归的直接求解 |
| 同上 | 63–65 | Loss、训练目标、矩阵表示 |
| 同上 | 76–77 | 偏导数与梯度 |
Lecture3_DeepLearning_Background.pdf | 4–11 | 更新公式与梯度下降图示 |
| 同上 | 12–15 | Full-batch、SGD、epoch、mini-batch |
| 同上 | 42 | Chain Rule |