查看全课大纲(第 41 / 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 回传

优化方法(1):坐标下降与前向选择

约 17 分钟

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

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

上一节结尾留了话:L1 范数在零点不可导,梯度下降做不出梯度,“会用其他的方法来求这个 LASSO 的优化”。这一节就兑现——介绍几种定量的计算方法。要优化的目标没变,还是上一节那个 min⁡θ12N(∥Xθ−y∥22+λ∥θ∥1)\min_\theta \frac{1}{2N}(\Vert X\theta-y\Vert_2^2 + \lambda\Vert\theta\Vert_1);变的是”怎么走”。

💡 核心导读

  • 方法一:坐标下降(coordinate descent)——与梯度下降对照:一个根据梯度下降,一个根据坐标轴下降。
  • 机制:固定其他所有维度,在单根坐标轴上搜到最低点 stop、固定,换下一根轴,再搜——路径走成”之”字。
  • 起点是个 trick:可以从与 yy 相关性最大的维度开始,更有效率——但影响有限,按顺序搜照样能到。
  • 方法二:前向选择(forward selection)——从最小二乘的几何出发:yy 在特征平面上的投影,一个方向一个方向地搭出来。
  • 共同代价:一个维度一个维度地走,计算复杂度摆在那里;维度特别大时,先选谁是有学问的。

方法一:坐标下降

先摆对照:我们原先的方法叫 gradient descent,根据梯度进行下降;这个叫 coordinate descent,根据坐标轴下降。

道理非常简单。假设是二维空间,参数只有 θ1\theta_1、θ2\theta_2,损失函数 J(θ)J(\theta) 的等高线一圈圈摆在那里。我们先随便取一个起点,在给定的这个点上,看沿哪个方向值最小——比如沿 θ1\theta_1 这根轴更低,那就先沿 θ1\theta_1 走到这根轴上的最低点,stop,把这个维度的值固定住;然后换 θ2\theta_2 的方向,在 θ2\theta_2 这根轴上再搜最低点,再 stop、再固定;回过头来再搜 θ1\theta_1……如此往复。走出来的路径是一个”之”字:横一步、竖一步、再横一步,可以没完地继续走下去,直到走不动为止。

一般化到 nn 维也是一样:θ\theta 有 j=1∼nj = 1 \sim n 个维度,先调整 θ1\theta_1,再调整 θ2\theta_2,一路到 θn\theta_n,循环往复——每次只在某一个维度上找最小值,找到了就固定,再选另一个维度继续搜。

从哪个维度开始? 有个技巧:可以先求各个 θj\theta_j 与 yy 之间的 correlation(相关度/相似度),从相似度最大的那个维度开始,使搜索更有效率。但注意讲师的原话:这样做”最后的影响是有限的”——它是个 trick,不是必需品。从 θ1\theta_1 顺着往下走、甚至随机走,也都能取到最优值。所以坐标下降的性格是:比较粗暴、比较简单,但不需要任何其他技巧。它的代价是每一个维度都要去搜索一遍。

把这套”逐轴找最低点”跑起来。先看普通最小二乘损失(λ=0\lambda=0),再看 LASSO 损失(λ>0\lambda>0,绝对值的尖角照样搜得动):

# ---- 4 个样本, 两个特征相关 (内积 9): 坐标下降会走出看得见的"之"字 ----
X = [
    [1.0, 1.0],
    [1.0, 2.0],
    [2.0, 1.0],
    [2.0, 2.0],
]
y = [3.2, 4.8, 3.8, 6.2]

def J(t1, t2, lam):
    s = 0.0
    for row, yi in zip(X, y):
        s += (row[0] * t1 + row[1] * t2 - yi) ** 2
    s *= 0.5
    return s + lam * (abs(t1) + abs(t2))

def axis_min(t_other, axis, lam):
    # 固定另一坐标后, 轴上的损失 = 两段抛物线拼一个尖角(绝对值项)。
    # 最低点必在三个候选之一: 正半轴顶点 / 负半轴顶点 / 尖角零点 -- 逐个代入 J 挑最小。
    c = d = 0.0
    for row, yi in zip(X, y):
        xj = row[axis - 1]
        r = yi - row[2 - axis] * t_other     # 固定另一坐标后的残差
        c += xj * r
        d += xj * xj
    cand = [0.0]
    for z in (c - lam, c + lam):
        v = z / d
        if v > 1e-15 or v < -1e-15:
            cand.append(v)
    def J_axis(v):
        a, b = (v, t_other) if axis == 1 else (t_other, v)
        return J(a, b, lam)
    return min(cand, key=J_axis)

def coordinate_descent(lam, max_rounds=300):
    t1 = t2 = 0.0
    snaps = {}
    for r in range(1, max_rounds + 1):
        old = (t1, t2)
        t1 = axis_min(t2, 1, lam)
        t2 = axis_min(t1, 2, lam)
        if r in (1, 2, 3, 5, 10, 20, 50):
            snaps[r] = (t1, t2)
        if max(abs(t1 - old[0]), abs(t2 - old[1])) < 1e-12:
            return t1, t2, r, snaps
    return t1, t2, max_rounds, snaps

print("数据 (x1, x2 -> y), 两个特征相关 (内积 9):")
for row, yi in zip(X, y):
    print(f"  ({row[0]:.0f}, {row[1]:.0f}) -> {yi}")

t1, t2, r0, s0 = coordinate_descent(0.0)
print("\nlambda = 0.0 (普通最小二乘损失):")
for r, (a, b) in sorted(s0.items()):
    print(f"  轮 {r:2d}: theta = ({a:.3f}, {b:.3f})  J = {J(a, b, 0.0):.3f}")
print(f"  轮 {r0}: 收敛, theta = ({t1:.6f}, {t2:.6f})")
XTX = [[sum(X[i][a] * X[i][b] for i in range(4)) for b in range(2)] for a in range(2)]
XTy = [sum(X[i][a] * y[i] for i in range(4)) for a in range(2)]
check = [XTX[0][0] * t1 + XTX[0][1] * t2 - XTy[0], XTX[1][0] * t1 + XTX[1][1] * t2 - XTy[1]]
print(f"  验证: (X^T X)theta - X^T y = ({check[0]:.1e}, {check[1]:.1e})  <- 站在正规方程的零点上")

t1, t2, r5, s5 = coordinate_descent(0.5)
print("\nlambda = 0.5 (LASSO 损失, 同一套轴搜索照样跑得动):")
for r, (a, b) in sorted(s5.items()):
    if r in (1, 2, 3, 5, 10, 20):
        print(f"  轮 {r:2d}: theta = ({a:.3f}, {b:.3f})")
print(f"  轮 {r5}: 收敛, theta = ({t1:.6f}, {t2:.6f})  <- 比正规方程解恰好各小 0.026")
数据 (x1, x2 -> y), 两个特征相关 (内积 9):
  (1, 1) -> 3.2
  (1, 2) -> 4.8
  (2, 1) -> 3.8
  (2, 2) -> 6.2

lambda = 0.0 (普通最小二乘损失):
  轮  1: theta = (2.800, 0.380)  J = 3.158
  轮  2: theta = (2.458, 0.688)  J = 2.099
  轮  3: theta = (2.181, 0.937)  J = 1.405
  轮  5: theta = (1.775, 1.303)  J = 0.650
  轮 10: theta = (1.270, 1.757)  J = 0.149
  轮 20: theta = (1.033, 1.970)  J = 0.081
  轮 50: theta = (1.000, 2.000)  J = 0.080
  轮 129: 收敛, theta = (1.000000, 2.000000)
  验证: (X^T X)theta - X^T y = (6.6e-12, 3.6e-15)  <- 站在正规方程的零点上

lambda = 0.5 (LASSO 损失, 同一套轴搜索照样跑得动):
  轮  1: theta = (2.750, 0.375)
  轮  2: theta = (2.413, 0.679)
  轮  3: theta = (2.139, 0.925)
  轮  5: theta = (1.738, 1.286)
  轮 10: theta = (1.240, 1.734)
  轮 20: theta = (1.006, 1.945)
  轮 128: 收敛, theta = (0.973684, 1.973684)  <- 比正规方程解恰好各小 0.026

读这张路径表。“之”字:θ1\theta_1 第一步冲到 2.800(过冲),θ2\theta_2 被它拽到 0.380(欠着);下一轮 θ1\theta_1 回落到 2.458,θ2\theta_2 升到 0.688——两个维度互相牵扯,因为这两个特征相关(内积 9)。每一步 J 都在降:3.158 → 2.099 → … → 0.080,单调往下,从不停顿。终点双保险:λ=0\lambda=0 时 129 轮后精确站在正规方程的解 (1,2)(1, 2) 上,代回 (XTX)θ−XTy(X^TX)\theta - X^Ty 只剩 10−1210^{-12} 量级的浮点毛边;λ=0.5\lambda=0.5 时同一套循环在 LASSO 损失上照样收敛,解变成 (0.9737,1.9737)(0.9737, 1.9737)——比正规方程解恰好各小 0.026,绝对值惩罚把两个系数各削了一刀。这正是”求 LASSO 的优化”的第一种方法:不需要梯度,只要每根轴上找得到最低点。

方法二:前向选择

第二个方法叫 forward selection,前向选择。要理解它,必须记得上次课讨论最小二乘时的向量空间视角——当时讲它,就是为了给这一课打基础。

回顾一下。给定数据矩阵 XX,它的列向量 x1x_1、x2x_2 张成一个平面;我们希望学到的值是 yy,但 yy 压根就不在 x1,x2x_1, x_2 构成的平面里——无论怎么线性组合都构造不出等于 yy 的向量。我们能求的是 yy 在这个平面上的投影 y^\hat{y}:它完全由 y^=θ1x1+θ2x2+θ0\hat{y} = \theta_1x_1 + \theta_2x_2 + \theta_0 构造出来,而残差 e=y−y^e = y - \hat{y} 必须与整个平面垂直。这正是最小二乘解的几何意义(第 8 章)。把矩阵形式写全(讲师特意把常数列也写上):

[1x11x121x21x22][β0β1β2]=[y1y2]\begin{bmatrix}1 & x_{11} & x_{12}\\ 1 & x_{21} & x_{22}\end{bmatrix}\begin{bmatrix}\beta_0\\ \beta_1\\ \beta_2\end{bmatrix} = \begin{bmatrix}y_1\\ y_2\end{bmatrix}

按列看,它说的就是 β1x1+β2x2+β0⋅1=y\beta_1 x_1 + \beta_2 x_2 + \beta_0 \cdot \mathbf{1} = y——把两个向量各自等比伸缩,再相加,凑出目标向量(省略常数列本质上是一样的)。

前向选择做的事:不是一口气求出 θ1\theta_1、θ2\theta_2,而是一个方向一个方向地搭。第一步,先看 x1x_1 和 x2x_2 哪个跟 yy 的关系更近;假设 x1x_1 更近,就先在 x1x_1 的方向上找一个合适的 θ1\theta_1,让 θ1x1\theta_1x_1 落在 yy 的投影途中。做完这一步,它们之间仍然有距离。第二步,在 x2x_2 的方向上再延伸一段 θ2x2\theta_2x_2——最后延到的那个点,正好是 yy 在平面上的投影,残差最小。跑一遍(这份演示数据里 x1x_1 与 x2x_2 严格正交,yy 带着一段平面外的分量):

# ---- 前向选择: 4 个样本, x1 与 x2 严格正交, y 带一段平面外的分量 ----
x1 = [1.0, 1.0, -1.0, -1.0]
x2 = [1.0, -1.0, 1.0, -1.0]
y = [3.1, 1.1, -0.9, -2.9]

def dot(a, b):
    return sum(u * v for u, v in zip(a, b))

def scale(v, s):
    return [s * u for u in v]

def sub(a, b):
    return [u - v for u, v in zip(a, b)]

print("数据: x1 = (1,1,-1,-1), x2 = (1,-1,1,-1) (正交), y = (3.1, 1.1, -0.9, -2.9)")
print(f"第一步 选择: <x1,y> = {dot(x1, y):.1f},  <x2,y> = {dot(x2, y):.1f}  -> 选 x1 (跟 y 关系更近)")

theta1 = dot(x1, y) / dot(x1, x1)
pred = scale(x1, theta1)
res = sub(y, pred)
print(f"第一步 投影: theta1 = {dot(x1, y):.1f} / {dot(x1, x1):.1f} = {theta1:.3f}")
print(f"  预测 = {[round(v, 1) for v in pred]},  残差 = {[round(v, 1) for v in res]}")

theta2 = dot(x2, res) / dot(x2, x2)
pred2 = [a + b for a, b in zip(pred, scale(x2, theta2))]
res2 = sub(y, pred2)
print(f"第二步 延伸: 残差与 x2 的内积 = {dot(x2, res):.1f},  theta2 = {dot(x2, res):.1f} / {dot(x2, x2):.1f} = {theta2:.3f}")
print(f"  预测 = {[round(v, 1) for v in pred2]},  残差 = {[round(v, 1) for v in res2]}")

print(f"\n验证 残差垂直于整个平面: <残差,x1> = {dot(res2, x1):.3f},  <残差,x2> = {dot(res2, x2):.3f}")
print(f"最终: y_hat = {theta1:.1f}*x1 + {theta2:.1f}*x2,  残差平方和 = {dot(res2, res2):.2f}")
数据: x1 = (1,1,-1,-1), x2 = (1,-1,1,-1) (正交), y = (3.1, 1.1, -0.9, -2.9)
第一步 选择: <x1,y> = 8.0,  <x2,y> = 4.0  -> 选 x1 (跟 y 关系更近)
第一步 投影: theta1 = 8.0 / 4.0 = 2.000
  预测 = [2.0, 2.0, -2.0, -2.0],  残差 = [1.1, -0.9, 1.1, -0.9]
第二步 延伸: 残差与 x2 的内积 = 4.0,  theta2 = 4.0 / 4.0 = 1.000
  预测 = [3.0, 1.0, -1.0, -3.0],  残差 = [0.1, 0.1, 0.1, 0.1]

验证 残差垂直于整个平面: <残差,x1> = 0.000,  <残差,x2> = -0.000
最终: y_hat = 2.0*x1 + 1.0*x2,  残差平方和 = 0.04

三处观察。选择看相关:x1x_1 与 yy 的内积 8.0,x2x_2 只有 4.0——第一步选 x1x_1,投影系数 θ1=8/4=2\theta_1 = 8/4 = 2。延伸看残差:剩下的残差 (1.1,−0.9,1.1,−0.9)(1.1, -0.9, 1.1, -0.9) 与 x2x_2 的内积是 4.0,θ2=1\theta_2 = 1——搭完两步,y^=2x1+x2\hat{y} = 2x_1 + x_2,残差 (0.1,0.1,0.1,0.1)(0.1, 0.1, 0.1, 0.1) 正是 yy 平面外的那段分量。垂直性的数值兑现:残差与 x1x_1、x2x_2 的内积分别是 0.000 和 −0.000——数学上精确为零,机器上带 10−1710^{-17} 量级的毛边(那个 −0.000 就是毛边压出来的负零,第 8 章见过同款)。

实践注:这份演示数据里 x1x_1 与 x2x_2 垂直,两步投影恰好一次就落在 yy 的整体投影上;特征不垂直时,第二步会把第一步的落点拽偏——想精确落位,就得像坐标下降那样一轮一轮来回走。两种方法在这里悄悄接上了头。

代价与收尾

前向选择的问题也很直白:它需要一个维度一个维度地求、一个方向一个方向地走,存在计算复杂度的问题。维度比较小的时候,这是很合适的方法;维度特别大的时候,先选择哪一个、后选择哪一个,也是有学问的——要看每一个维度跟 yy 之间的 correlation。(本节视频到这里收尾,更多优化方法下一节继续。)

📝 动手练一练

  1. 两种下降的本质区别:梯度下降和坐标下降,在”往哪儿走”这件事上有什么本质不同?对 LASSO 这种零点不可导的目标,为什么坐标下降照样能走?
👉 点击查看参考答案
  • 梯度下降:每次计算损失关于所有参数的梯度,全体参数沿梯度的反方向同时挪一小步(步长 α\alpha)——它需要梯度处处存在。
  • 坐标下降:每次只挑一根坐标轴,固定其他参数,沿这根轴走到最低点 stop;换下一根轴再走——它不需要整体梯度,只要单根轴上”能找到最低点”。
  • 对 LASSO:L1 范数在零点不可导,整体梯度做不出来,梯度下降失灵;但固定其他坐标后,单变量损失是两段抛物线拼一个尖角,最低点照样找得到(演示代码里就是代入三个候选挑最小)——所以坐标下降能走。
  1. 前向选择手算:三个样本,x1=(1,1,2)x_1 = (1, 1, 2)、x2=(1,−1,0)x_2 = (1, -1, 0)(两者正交),y=(2.5,0.5,1.5)y = (2.5, 0.5, 1.5)。按前向选择的步骤手算:第一步该选哪个特征?θ1\theta_1 是多少?第二步的 θ2\theta_2 呢?最终残差是多少,验证它与两个特征都垂直。
👉 点击查看参考答案

第一步:⟨y,x1⟩=2.5+0.5+3=6\langle y, x_1\rangle = 2.5 + 0.5 + 3 = 6,⟨y,x2⟩=2.5−0.5=2\langle y, x_2\rangle = 2.5 - 0.5 = 2——选 x1x_1。投影:θ1=6/∥x1∥2=6/6=1\theta_1 = 6 / \Vert x_1\Vert^2 = 6/6 = 1,预测 (1,1,2)(1, 1, 2),残差 (1.5,−0.5,−0.5)(1.5, -0.5, -0.5)。

第二步:残差与 x2x_2 的内积 =1.5+0.5+0=2= 1.5 + 0.5 + 0 = 2,θ2=2/∥x2∥2=2/2=1\theta_2 = 2/\Vert x_2\Vert^2 = 2/2 = 1,y^=x1+x2=(2,0,2)\hat{y} = x_1 + x_2 = (2, 0, 2)。

最终残差 =(0.5,0.5,−0.5)= (0.5, 0.5, -0.5);验证垂直:⟨e,x1⟩=0.5+0.5−1=0\langle e, x_1\rangle = 0.5 + 0.5 - 1 = 0 ✓,⟨e,x2⟩=0.5−0.5=0\langle e, x_2\rangle = 0.5 - 0.5 = 0 ✓——正是 yy 在特征平面外的那段分量,残差平方和 0.750.75。

本章小结

  • 定位:LASSO 的 L1 在零点不可导、梯度下降失灵——本节给出两种”用其他方法”的定量解法。
  • 坐标下降:与梯度下降对照(根据梯度 vs 根据坐标轴);固定其余维度、单轴搜到最低 stop、换轴再搜,路径走”之”字;可以从与 yy 相关性最大的维度起步(trick,影响有限);粗暴、简单、不需要其他技巧。
  • 数值实证:相关特征上 129 轮收敛到正规方程解 (1,2)(1, 2)(代回只剩浮点毛边);LASSO 损失同一套循环收敛到 (0.9737,1.9737)(0.9737, 1.9737),比正规方程解恰好各小 0.026。
  • 前向选择:最小二乘几何的延伸——yy 不在特征平面内,先选与 yy 关系更近的方向投影,再沿下一方向延伸,最终 y^\hat{y} 落在 yy 的投影上、残差 ee 垂直于平面(数值验证内积为 0)。
  • 代价:一个维度一个维度走,计算复杂度摆着;维度特别大时,先选谁有学问(看每个维度与 yy 的 correlation)。

📋 行动清单

  • 用自己的话讲清”根据梯度下降”与”根据坐标轴下降”的区别,以及为什么后者不怕绝对值的尖角
  • 跑代码一:把起点从 (0,0)(0,0) 改成 (2.5,0.0)(2.5, 0.0),观察”之”字路径殊途同归
  • 跑代码一:把 λ\lambda 改成 55,看两个系数被削掉多少、会不会有谁恰好归零
  • 跑代码二:给 yy 再加一段平面外分量(如 (0.2,0,0,−0.2)(0.2, 0, 0, -0.2)),验证最终残差恰好等于它、且仍与两特征垂直
  • 预习下一节《优化方法(2)》

—— 小象教研组

配套资料 · 直接下载

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

  • 第9章笔记:广义与普通最小二乘(GOLS)
    下载
  • 第9章笔记:线性模型正则化
    下载
  • 第9章笔记:正则化线性模型的优化
    下载