查看全课大纲(第 19 / 82 节)
  1. 1.函数与数据泛化
  2. 2.向量:从几何直觉到高维空间
  3. 3.矩阵与张量
  4. 4.特征值与特征向量:矩阵变换的不动方向
  5. 5.凸函数:从向量求导的矩阵记号到好优化的函数形状
  6. 6.概率与统计:机器学习的数学基础
  7. 7.独立性与随机变量:贝叶斯公式与二项分布
  8. 8.期望、方差与协方差:随机变量的数字画像
  9. 9.联合概率:当一条轴不够用的时候
  10. 10.概率分布(一):从伯努利到伽马函数
  11. 11.概率分布(二):贝塔、泊松、正态与两个贝叶斯故事
  12. 12.机器学习的模型:找输入与输出的关系
  13. 13.机器学习的应用
  14. 14.过拟合
  15. 15.机器学习的分类
  16. 16.有监督学习:从房价预测说起
  17. 17.损失函数
  18. 18.梯度下降(上):更新规则与学习速率
  19. 19.梯度下降(2)
  20. 20.牛顿方法
  21. 21.KNN简介
  22. 22.距离测算
  23. 23.朴素贝叶斯
  24. 24.朴素贝叶斯的实际应用
  25. 25.信息熵:决策树构建的度量基础
  26. 26.信息增益与决策树的构建
  27. 27.ID3算法
  28. 28.决策树节点的划分
  29. 29.CART树
  30. 30.Bagging
  31. 31.Boosting:自适应提升算法
  32. 32.Gradient Boosting
  33. 33.线性模型:回归与分类的同一副骨架
  34. 34.最小二乘:把最优参数直接解出来
  35. 35.最小二乘法的几何与概率视角
  36. 36.极大似然:给最小二乘一个概率出身
  37. 37.逻辑回归(1):把线性模型接到分类上
  38. 38.逻辑回归(2):损失函数与多分类
  39. 39.---- 手造数据: 5 个样本, 2 个特征; x2 几乎 = 2*x1 (偏差手工指定, 无随机) ----
  40. 40.讲师例: 向量 "23014" -- 三把范数尺子量同一个向量
  41. 41.优化方法(1):坐标下降与前向选择
  42. 42.优化方法(2):前向策略与最小角回归
  43. 43.拉格朗日乘子法(1):从无约束到等式约束
  44. 44.拉格朗日乘子法(2):等式约束下的平行条件与拉格朗日函数
  45. 45.拉格朗日乘子法(3):不等式约束与 KKT 条件
  46. 46.最大间隔:把分类问题变成优化问题
  47. 47.拉格朗日对偶问题:把 w 和 b 全部换成 α
  48. 48.支持向量:边界上的少数派
  49. 49.SVM 计算过程:一笔到底算完,再走进核方法
  50. 50.贝叶斯公式:概率即信念
  51. 51.隐含变量和概率模型:给看不见的原因建模
  52. 52.EM 算法:期望与最大化的迭代
  53. 53.琴生不等式:EM 的数学钥匙
  54. 54.三个硬币问题:EM 的复盘与衔接
  55. 55.高斯混合模型:用隐变量解释双峰数据
  56. 56.隐马尔可夫模型
  57. 57.隐马尔可夫模型(2):前向算法与动态混合模型
  58. 58.隐马尔可夫模型在 NLP 中的运用
  59. 59.EM 算法:把「为什么收敛」推到底
  60. 60.HMM 在 NLP 中的运用:从分词到机器翻译
  61. 61.HMM 参数估计:Baum-Welch 的三块拉格朗日
  62. 62.高维下的高斯模型
  63. 63.主题模型:从词袋到隐含主题
  64. 64.Dirichlet 分布(1)
  65. 65.Dirichlet 分布(2)
  66. 66.统计学习内容回顾
  67. 67.K-means 算法
  68. 68.PCA 降维
  69. 69.SVD 降维
  70. 70.从聚类到流形
  71. 71.局部线性嵌入
  72. 72.随机邻域嵌入:SNE 与 t-SNE
  73. 73.无参模型:让数据自己说话
  74. 74.高斯过程:函数空间里的正态分布
  75. 75.高斯过程(2):噪声、正则化与核的线性组合
  76. 76.神经网络简介:从感知器到自编码器
  77. 77.反向传播:把误差一层层传回去
  78. 78.卷积神经网络(CNN):让特征自己学出来
  79. 79.循环神经网络(RNN):给网络装上记忆
  80. 80.深度学习回顾:静态一类,动态一类
  81. 81.增强学习(1):蒙特卡洛、树搜索与 Q-learning
  82. 82.强化学习(2):从乌鸦吃核桃到井字棋的 value 回传

梯度下降(2)

约 33 分钟

📺 正在播放小象官方高清录播(支持倍速与清晰度调节)

小象实战讲义 · 机器学习算法精讲

上一节我们把更新规则 θ←θ−α⋅∂J∂θ\theta \leftarrow \theta - \alpha \cdot \frac{\partial J}{\partial \theta} 立了起来,也用三档 α\alpha 亲眼看过了步子太大与太小的后果。但有一个地方始终没打开:更新式里的偏导 ∂J∂θ\frac{\partial J}{\partial \theta},从头到尾是个黑盒——用讲师的话说,我们实际上只求了一半。本节就把这一半补上:亲手推出线性回归里两个参数的梯度,把整套方法推广到多变量情形,直面实战中的特征缩放问题,最后认识 batch 家族,以及梯度下降与最小二乘的关系。

💡 核心导读

  • 打开黑盒:完整推导 θ0\theta_0、θ1\theta_1 的偏导——链式法则上场,4.2 节那个 12\frac{1}{2} 的伏笔在此兑现。
  • 同时更新:两个参数必须在同一个点上量出梯度、一起更新——用代码看清”同时”与”顺序”走的是两条路。
  • 推广到多变量:hθ(x)=θTxh_\theta(x) = \theta^T x、通用更新公式,以及参数的”权重”语义——用房价的四特征读懂每个系数。
  • 特征缩放:尺度不齐会把碗压得特别扁;两种归一化把它扶圆。
  • 更大的图景:batch / mini-batch / 随机梯度下降,与”最小二乘 vs 梯度下降”的对照。

打开黑盒:求出两个偏导

先把设定摆齐。假设函数 hθ(x)=θ1x+θ0h_\theta(x) = \theta_1 x + \theta_0(对第 ii 个数据,就是 θ1x(i)+θ0\theta_1 x^{(i)} + \theta_0),代价函数沿用上一章的:

J(θ0,θ1)=12N∑i=1N(hθ(x(i))−y(i))2J(\theta_0, \theta_1) = \frac{1}{2N} \sum_{i=1}^{N} \left( h_\theta(x^{(i)}) - y^{(i)} \right)^2

更新要分两条写:

θ0←θ0−α⋅∂J(θ0,θ1)∂θ0,θ1←θ1−α⋅∂J(θ0,θ1)∂θ1\theta_0 \leftarrow \theta_0 - \alpha \cdot \frac{\partial J(\theta_0, \theta_1)}{\partial \theta_0}, \qquad \theta_1 \leftarrow \theta_1 - \alpha \cdot \frac{\partial J(\theta_0, \theta_1)}{\partial \theta_1}

现在把两个偏导真正解出来。先复习一个求导工具——链式法则:复合函数 f(g(x))f(g(x)) 对 xx 求导,等于 f′(g(x))⋅g′(x)f'(g(x)) \cdot g'(x)——先在外层求导,再乘上里层的导数。

对 θ0\theta_0 求偏导。 把 JJ 的定义代入,外层是平方函数、里层是 hθ(x(i))−y(i)h_\theta(x^{(i)}) - y^{(i)}:

∂J∂θ0=12N∑i=1N2(hθ(x(i))−y(i))⋅∂∂θ0(hθ(x(i))−y(i))\frac{\partial J}{\partial \theta_0} = \frac{1}{2N} \sum_{i=1}^{N} 2\left( h_\theta(x^{(i)}) - y^{(i)} \right) \cdot \frac{\partial}{\partial \theta_0}\left( h_\theta(x^{(i)}) - y^{(i)} \right)

注意两件事。第一,平方求导翻出来的 22,恰好和分母里的 12\frac{1}{2} 约掉——4.2 节说那个 12\frac{1}{2} 是”为了数学上的方便”,方便就兑现在这里,系数干净地变成 1N\frac{1}{N}。第二,里层对 θ0\theta_0 求导:hθ(x(i))=θ1x(i)+θ0h_\theta(x^{(i)}) = \theta_1 x^{(i)} + \theta_0,前一项与 θ0\theta_0 无关,θ0\theta_0 对自己求导是 11——乘 11 等于没乘,直接省去:

∂J∂θ0=1N∑i=1N(hθ(x(i))−y(i))\frac{\partial J}{\partial \theta_0} = \frac{1}{N} \sum_{i=1}^{N} \left( h_\theta(x^{(i)}) - y^{(i)} \right)

对 θ1\theta_1 求偏导。 流程完全一样,唯一的区别在里层:hθ(x(i))=θ1x(i)+θ0h_\theta(x^{(i)}) = \theta_1 x^{(i)} + \theta_0 对 θ1\theta_1 求导,得到的不是 11 而是 x(i)x^{(i)}:

∂J∂θ1=1N∑i=1N(hθ(x(i))−y(i))⋅x(i)\frac{\partial J}{\partial \theta_1} = \frac{1}{N} \sum_{i=1}^{N} \left( h_\theta(x^{(i)}) - y^{(i)} \right) \cdot x^{(i)}

于是两条更新规则完整成型:

θ0←θ0−α⋅1N∑i=1N(hθ(x(i))−y(i))\theta_0 \leftarrow \theta_0 - \alpha \cdot \frac{1}{N} \sum_{i=1}^{N} \left( h_\theta(x^{(i)}) - y^{(i)} \right)

θ1←θ1−α⋅1N∑i=1N(hθ(x(i))−y(i))⋅x(i)\theta_1 \leftarrow \theta_1 - \alpha \cdot \frac{1}{N} \sum_{i=1}^{N} \left( h_\theta(x^{(i)}) - y^{(i)} \right) \cdot x^{(i)}

读一遍它的意思:每条数据先算出误差 h−yh - y;θ0\theta_0 的更新用误差本身,θ1\theta_1 的更新用误差乘上对应的特征值。初始时随机给定 θ0\theta_0、θ1\theta_1,梯度就能算出来;有了梯度就能更新;不断迭代,就能修出越来越好的参数。

同时更新:两个参数必须一起动

上一节立过规矩:更新必须同时(simultaneous)。这里把原因说透:θ0\theta_0 的更新式里用到了 θ1\theta_1(它藏在 hh 里),θ1\theta_1 的更新式里也用到了 θ0\theta_0——两个式子互指”当前值”。所以正确做法是:在当前这组 (θ0,θ1)(\theta_0, \theta_1) 上把两个梯度都算完,再一起赋值;不能先更新 θ0\theta_0,再拿新 θ0\theta_0 去算 θ1\theta_1 的梯度。用代码把两条路摆在一起看:

# 演示一:同时更新 vs 顺序更新——同一个起点、同一个 alpha,走出两条路
data = [(1, 2), (2, 4), (3, 5)]

def h(t0, t1, x):
    return t0 + t1 * x

def J(t0, t1):
    return sum((h(t0, t1, x) - y) ** 2 for x, y in data) / (2 * len(data))

def grads(t0, t1):
    n = len(data)
    g0 = sum(h(t0, t1, x) - y for x, y in data) / n
    g1 = sum((h(t0, t1, x) - y) * x for x, y in data) / n
    return g0, g1

alpha = 0.3
t0s, t1s = 0.0, 0.0   # 同时更新(正确的梯度下降)
t0q, t1q = 0.0, 0.0   # 顺序更新(错误示范)
for it in range(1, 11):
    # 正确:在当前点同时量出两个梯度,一起赋值
    g0, g1 = grads(t0s, t1s)
    t0s, t1s = t0s - alpha * g0, t1s - alpha * g1
    # 错误:先把 theta0 更新掉,再拿新 theta0 去算 theta1 的梯度
    g0, _ = grads(t0q, t1q)
    t0q = t0q - alpha * g0
    _, g1 = grads(t0q, t1q)
    t1q = t1q - alpha * g1
    if it in (1, 2, 10):
        print(f"轮{it:2d}  同时: ({t0s:.4f}, {t1s:.4f}) J={J(t0s, t1s):.4f}   "
              f"顺序: ({t0q:.4f}, {t1q:.4f}) J={J(t0q, t1q):.4f}")
轮 1  同时: (1.1000, 2.5000) J=3.3217   顺序: (1.1000, 1.8400) J=0.6861
轮 2  同时: (0.3700, 0.8400) J=1.4798   顺序: (0.7660, 1.3044) J=0.0831
轮10  同时: (0.6517, 1.4767) J=0.0298   顺序: (0.7851, 1.4499) J=0.0288

从第 1 轮起,两条轨迹就分道扬镳:顺序更新在算 θ1\theta_1 的梯度时,用的是”新 θ0\theta_0 + 旧 θ1\theta_1“拼出来的点——那个点从来不在同时更新的轨道上。说句公道话:在这个温和的凸玩具问题里,两条路最后都收敛了(顺序更新这个走法其实是”逐坐标更新”那族算法的近亲,凸问题对它也很宽容);但它是另一个算法。梯度下降的定义就是:在当前点上,把所有梯度一起量出来,一起走。规矩要守在定义上,而不是守在运气上。

推广到多变量:h = θᵀx

到目前为止我们玩的都是二维参数(θ0\theta_0、θ1\theta_1)的简单情形。回想最一般的线性框架:多变量线性回归(multivariate linear regression)的假设函数是

hθ(x)=θTx=∑j=0nθj xj,θ∈Rn+1h_\theta(x) = \theta^T x = \sum_{j=0}^{n} \theta_j \, x_j, \qquad \theta \in \mathbb{R}^{n+1}

讲师用卖房子把它讲活了。美国的房子有这些特征:x1x_1 是面积(平方英尺),x2x_2 是有几个卧室,x3x_3 是有几层(一层、两层、三层——如果没想错,大家都喜欢要三层的),x4x_4 是房龄(有 45 年的、40 年的、30 年的)。于是

hθ(x)=θ1x1+θ2x2+θ3x3+θ4x4+θ0x0h_\theta(x) = \theta_1 x_1 + \theta_2 x_2 + \theta_3 x_3 + \theta_4 x_4 + \theta_0 x_0

其中 x0x_0 恒等于 11,所以 θ0x0\theta_0 x_0 就是 ax+bax + b 里那个单独的 bb——本质上就是一个线性组合。

参数的”权重”语义

学出来的 θ\theta 非常好读,它就是每个特征的权重:

  • 正负号 = 相关方向:面积越大价格越高,所以 θ1\theta_1 应该是正数;房龄越大越不值钱,所以 θ4\theta_4 应该是负数。正值是 positive correlated,负值是 negative correlated。
  • 绝对值 = 贡献程度:如果 θ1\theta_1 比 θ2\theta_2、θ3\theta_3 都大,说明这套房价里看的最重要的特征是面积。房间四个还是五个,区别往往没有面积那么大,系数就相对小。
  • 讲师给了个试金石:30 年跟 31 年的房子价格相差很大,说明 ∣θ4∣|\theta_4| 很大、人们很在意新旧;31 年跟 30 年没太大区别,说明 ∣θ4∣|\theta_4| 很小。

这种线性组合是非常常用的一类模型:给你一个高维向量,每个特征对目标”有多重要、往哪个方向推”,全部写在一串系数里。不过要留一个心眼:系数的大小还受特征单位的影响——面积以平方英尺计、数值动辄上千,“每平方英尺多少钱”的系数天然显得小;房间数只有个位数,“每间卧室多少钱”的系数天然显得大。想严格比较特征的重要性,得先把尺度统一——这正好是下一节的伏笔。

通用更新公式

多变量的梯度下降,形式跟二维如出一辙,只是对每个 θj\theta_j 各写一条:

θj←θj−α⋅∂J(θ)∂θj,j=0,1,…,n\theta_j \leftarrow \theta_j - \alpha \cdot \frac{\partial J(\theta)}{\partial \theta_j}, \qquad j = 0, 1, \ldots, n

代价函数不变,只是 θ\theta 换成了高维向量。求偏导的过程和刚才一模一样:外层平方配 12\frac{1}{2} 照样约掉,里层 hh 对 θj\theta_j 的导数就是 xjx_j。于是:

θj←θj−α⋅1N∑i=1N(hθ(x(i))−y(i))⋅xj(i)\theta_j \leftarrow \theta_j - \alpha \cdot \frac{1}{N} \sum_{i=1}^{N} \left( h_\theta(x^{(i)}) - y^{(i)} \right) \cdot x_j^{(i)}

这里 xj(i)x_j^{(i)} 要读仔细:x(i)x^{(i)} 是第 ii 个数据,本身是一个 n+1n+1 维向量 (x0(i),x1(i),…,xn(i))(x_0^{(i)}, x_1^{(i)}, \ldots, x_n^{(i)});xj(i)x_j^{(i)} 就是它在第 jj 个方向上的分量。验证一下一致性:j=0j=0 时 x0(i)=1x_0^{(i)} = 1,公式退化回 θ0\theta_0 那条更新式——分毫不差。

特征缩放:把压扁的碗扶圆

迭代学习真正跑起来,还有很多比想象中复杂的实际问题(practical issue),第一个就是特征缩放(feature scaling)——各个特征的”尺度”不齐。

回头看房价的例子:面积从 700 到 3000 平方英尺,数值是几千;卧室两三个、层数一到三,是个位数;房龄 10 到 50 年,是几十。如果直接用原始数值,面积这一维会dominate(统治)其他分量的变化——反映到代价函数的等高线上,碗被压得特别扁、特别狭长,梯度的寻找会走得很辛苦。做一次缩放(归一化),把每个维度都拉到相近的尺度,碗变圆了,最优值就好找多了。两种最简单的做法:

  • A 法(压进 0~1):xj′=xj−min⁡(xj)max⁡(xj)−min⁡(xj)x_j' = \dfrac{x_j - \min(x_j)}{\max(x_j) - \min(x_j)}。比如面积这一维,max⁡−min⁡=3000−700=2300\max - \min = 3000 - 700 = 2300,一套 1500 平方英尺的房子归一化后就是 (1500−700)/2300≈0.35(1500-700)/2300 \approx 0.35。所有维度都落进 [0,1][0, 1]。
  • B 法(均值归一化,以 0 为中心):xj′=xj−μjmax⁡(xj)−min⁡(xj)x_j' = \dfrac{x_j - \mu_j}{\max(x_j) - \min(x_j)},μj\mu_j 是该维的均值。结果有正有负,大致对称地分布在 0 附近。

用一份手工构造的房价数据(价格恰好由一条线性函数精确生成,便于验证)把两种处境跑一遍:

# 演示二:四特征房价上的多变量梯度下降——原始尺度 vs 均值归一化
houses = [
    # (面积平方英尺, 卧室数, 层数, 房龄年, 价格美元)
    (700,  5, 1, 10, 117000), (3000, 2, 3, 50, 320000),
    (1500, 3, 2, 30, 181000), (2000, 4, 1, 25, 230000),
    (1000, 2, 3, 40, 128000), (2500, 5, 2, 20, 299000),
    (1200, 4, 2, 45, 144000), (2800, 3, 1, 15, 313000),
    (1800, 2, 3, 35, 212000), (2200, 5, 3, 30, 271000),
    (900,  3, 1, 20, 119000), (2600, 4, 2, 50, 280000),
]

y = [p for a, r, f, g, p in houses]
X_raw = [[1, a, r, f, g] for a, r, f, g, p in houses]   # x0 恒为 1

def gd(X, alpha, iters):
    m, n = len(X), len(X[0])
    theta = [0.0] * n
    for _ in range(iters):
        errs = [sum(theta[j] * X[i][j] for j in range(n)) - y[i] for i in range(m)]
        # 通用公式的直接实现:先在当前点算好全部梯度,再同时更新
        theta = [theta[j] - alpha * sum(errs[i] * X[i][j] for i in range(m)) / m
                 for j in range(n)]
    cost = sum((sum(theta[j] * X[i][j] for j in range(n)) - y[i]) ** 2
               for i in range(m)) / (2 * m)
    return theta, cost

J0 = sum(p * p for p in y) / (2 * len(y))
print(f"初始 J(参数全零)= {J0:.4e}")
print()

theta_raw, J_raw = gd(X_raw, alpha=1e-7, iters=2000)
print("原始特征(alpha 只敢用 1e-7,跑 2000 轮):")
print(f"  J = {J_raw:.4e},学到的参数 = {[round(t, 2) for t in theta_raw]}")
print()

# B 法均值归一化:每个特征减均值、除以极差(x0 恒为 1 的列不动)
m, n = len(X_raw), len(X_raw[0])
means = [sum(row[j] for row in X_raw) / m for j in range(n)]
lo = [min(row[j] for row in X_raw) for j in range(n)]
hi = [max(row[j] for row in X_raw) for j in range(n)]
X_b = [[1.0 if j == 0 else (row[j] - means[j]) / (hi[j] - lo[j]) for j in range(n)]
       for row in X_raw]

theta_b, J_b = gd(X_b, alpha=0.5, iters=2000)
print("均值归一化后(alpha 可以放心用 0.5,跑 2000 轮):")
print(f"  J = {J_b:.4e},学到的参数 = {[round(t, 2) for t in theta_b]}")
初始 J(参数全零)= 2.6549e+10

原始特征(alpha 只敢用 1e-7,跑 2000 轮):
  J = 1.4125e+08,学到的参数 = [1.07, 114.89, 5.32, 1.6, 6.96]

均值归一化后(alpha 可以放心用 0.5,跑 2000 轮):
  J = 3.9264e-21,学到的参数 = [217833.33, 230000.0, 15000.0, 20000.0, -32000.0]

对照着读,特征缩放的价值一目了然:

  • 原始特征:面积的数值上千,α\alpha 只敢取 10−710^{-7}(再大就发散);跑了 2000 轮,JJ 从 2.65×10102.65 \times 10^{10} 磨到 1.41×1081.41 \times 10^8——降了两个数量级,但离最优(这套数据可以精确拟合,最优是 0)还远得很。看学到的参数更直观:面积系数冲到了 115 附近(它”单打独斗”的最优值),而卧室、层数的系数才爬到 5.3 和 1.6(真实值分别是 5000 和 10000),基本还躺在起点。这就是被压扁的碗:一个方向早就滑到底了,其他方向还在半山腰慢慢挪。
  • 归一化之后:α\alpha 可以放心用 0.5,同样 2000 轮,JJ 直接压到 10−2110^{-21} 量级——浮点意义下的零。学到的参数可以手工验证:B 法缩放后,θj\theta_j 的真实值恰好是”原系数 × 该维极差”(面积 100×2300=230000100 \times 2300 = 230000,卧室 5000×3=150005000 \times 3 = 15000,层数 10000×2=2000010000 \times 2 = 20000,房龄 −800×40=−32000-800 \times 40 = -32000),截距项等于均值特征处的预测值。而参数的语义此刻完全兑现:面积一项的系数 230000 遥遥领先——尺度统一后,谁重要一目了然;房龄系数为负——越老越不值钱。

batch、mini-batch 与随机梯度下降

再介绍一个实用视角。我们至今用的梯度下降,叫 batch(批量) 的方法——“batch”就是一摞、一堆数据:看更新公式就知道,每一轮更新都要把全部 NN 条数据的误差都算一遍。数据有多少,计算量就跟着涨多少——复杂度是 O(N)O(N)。

数据量特别大的时候怎么办?两个方向:

  • 随机梯度下降(stochastic gradient descent,SGD):不把所有数据都算一遍,而是按数据的概率分布采出一部分样本,用这些采样来估计梯度方向——运算量立刻减下来。
  • mini-batch(小批量):把数据分成很多小堆,每次用一小堆算一次更新——深度学习训练里的标配。

这两位以后在具体应用里还会正式登场,这里先混个脸熟。

回到起点:这个问题到底是什么

梯度下降讲完,回头看我们最初的问题到底长什么样。现在有好多数据:(x1,y1)(x_1, y_1)、(x2,y2)(x_2, y_2)……一直到 (xN,yN)(x_N, y_N)——输入和标签全都给了,这是一个监督学习(supervised learning)问题;而且它不是分类(classification),是回归/预测(regression / prediction):给定一个新的 x∗x^*,学到的线性函数在它身上取的值,就是预测的 y∗y^*。

有意思的是,这个问题在数学上早就有”完美解”:线性代数里有一个特别传统的算法叫最小二乘法(least mean square),直接通过矩阵乘法就能把最优参数一次求出来。那梯度下降的价值在哪?

  • 最小二乘是数学上完美的解——前提是你得会它,而且问题规模允许你把矩阵算动。
  • 梯度下降是用计算的方式找出来的、非常 practical 的解:哪怕你不会最小二乘,随便给定一个 θ0\theta_0、θ1\theta_1,靠着”量梯度、走一步”不断循环,也能找到最好的拟合。这也是我们如何从数学一步步过渡到计算机科学的生动一例。

最后送一个讲师的彩蛋:类似梯度下降这种迭代方法,其实牛顿时代就有了——可惜牛顿的时代没有计算机,也没办法写这种不断循环的程序来解决这些问题。想法早就躺在那里,是计算把它唤醒的。

📝 动手练一练

  1. 读懂一组系数:假设在原始特征(面积/平方英尺、卧室数、层数、房龄/年)上学到的模型参数为:θ0=20000\theta_0 = 20000、θ1=60\theta_1 = 60、θ2=4500\theta_2 = 4500、θ3=9000\theta_3 = 9000、θ4=−700\theta_4 = -700。请回答: ① 哪个特征与价格负相关? ② 面积每增加 100 平方英尺,预测价格大约增加多少? ③ 如果市场上 30 年和 31 年房龄的房子能差出明显的价格,你预计 ∣θ4∣|\theta_4| 偏大还是偏小? ④ θ1=60\theta_1 = 60 比 θ2=4500\theta_2 = 4500 小得多,为什么不能就此断定”卧室数比面积重要”?
👉 点击查看参考答案

① 房龄(θ4<0\theta_4 < 0:越老越不值钱)。② 60×100=600060 \times 100 = 6000 美元。③ 偏大——本节的试金石:系数绝对值衡量该特征对目标的贡献程度,一年之差都值钱,说明人们很在意新旧。④ 系数大小受特征单位和取值范围影响:面积动辄上千平方英尺,“每平方英尺 60 美元”累积起来贡献巨大(一套 2300 平方英尺的房子差出 13.8 万美元);卧室数只有 2~5,“每间 4500 美元”撑死差 1.35 万。要严格比较特征重要性,得先统一尺度——这正是特征缩放的用武之地。

  1. 手算两种归一化:面积样本为 [700,1500,2200,3000][700, 1500, 2200, 3000](平方英尺,极差 2300、均值 1850)。请手算:① A 法 x−min⁡max⁡−min⁡\frac{x - \min}{\max - \min} 的四个结果;② B 法 x−μmax⁡−min⁡\frac{x - \mu}{\max - \min} 的四个结果;③ 说说两组结果各自的分布形态。
👉 点击查看参考答案

① A 法:(700−700)/2300=0(700-700)/2300 = 0,(1500−700)/2300≈0.3478(1500-700)/2300 \approx 0.3478,(2200−700)/2300≈0.6522(2200-700)/2300 \approx 0.6522,(3000−700)/2300=1(3000-700)/2300 = 1——全部落在 [0,1][0, 1]。

② B 法:(700−1850)/2300=−0.5(700-1850)/2300 = -0.5,(1500−1850)/2300≈−0.1522(1500-1850)/2300 \approx -0.1522,(2200−1850)/2300≈0.1522(2200-1850)/2300 \approx 0.1522,(3000−1850)/2300=0.5(3000-1850)/2300 = 0.5——以 0 为中心、正负对称。

③ A 法的结果全部非负、贴着 [0,1][0,1] 区间;B 法有正有负、关于 0 大致对称。两种都把各维度的尺度拉平了,B 法额外把数据中心挪到了 0——演示二里用的正是 B 法。

本章小结

本节把梯度下降的”另一半”补齐了。我们亲手推出 θ0\theta_0、θ1\theta_1 的偏导(链式法则 + 12\frac{1}{2} 与 2 相约),确认了两个参数必须同时更新,并把更新规则推广到多变量线性回归:hθ(x)=θTxh_\theta(x) = \theta^T x,每个参数 θj\theta_j 按通用公式 θj←θj−α⋅1N∑(hθ(x(i))−y(i)) xj(i)\theta_j \leftarrow \theta_j - \alpha \cdot \frac{1}{N}\sum(h_\theta(x^{(i)}) - y^{(i)})\, x_j^{(i)} 更新。参数的”权重语义”让我们能读懂模型(正负=相关方向、绝对值=贡献程度),而特征缩放解决了各维度尺度不齐把碗压扁的问题——同样 2000 轮,原始特征卡在半路,归一化后直捣最优。我们还认识了 batch / mini-batch / SGD 一家,以及梯度下降与最小二乘的分工:一个是数学上的完美解,一个是算出来的实用解(最小二乘的正片在第 8 章)。至于结尾那个”牛顿时代就有类似方法”的彩蛋——下一节的牛顿方法,正是它的正面登场。

📋 行动清单

学完本节,你可以立即:

  • 合上讲义推一遍:从 J(θ0,θ1)J(\theta_0, \theta_1) 出发,独立推出 ∂J∂θ0\frac{\partial J}{\partial \theta_0} 与 ∂J∂θ1\frac{\partial J}{\partial \theta_1},卡住的地方回头看链式法则。
  • 亲手缩放一次:找一份身边的数据(身高体重、气温销量都行),按 A 法和 B 法各归一化一遍,感受尺度的变化。
  • 读一个真实模型:搜索一个公开的线性回归案例,看它的系数正负与大小,用本节的”权重语义”讲给同事听。

—— 小象教研组

配套资料 · 直接下载

课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。

  • 第4章课件:机器学习的数学基础 III
    下载
  • 第4章笔记:梯度下降
    下载