🧠 第一章 AI入门:认识人工智能模型训练
📄 一句话概括

同一个 y = 3x + 2 的问题,人推公式一步得到斜率 3.0147, 机器用梯度下降走 200 步得到 3.0146。两条路殊途同归。 区别在于:公式能写出来的时候人赢,写不出来的时候只剩机器那条路。

📝 本节和前面几节的关系

上一节讲了历史,这一节讲原理的最小内核。 后面所有模型——从线性回归到几千亿参数的 Transformer——用的都是这一个循环,只是规模和形状不同。

一、两条路:推公式,或者试错

给定一批带噪声的点,要找出背后的直线。 人走的路是推导:最小二乘有闭式解,把数代进去一步算完,得到斜率 3.0147、截距 2.0152。 机器走的路是试错:先随便猜一个 w 和 b,算出预测值,看差多少,往差得少的方向挪一点, 重复两百次,得到 3.0146、2.0152。 两条路的结果差在第四位小数——因为它俩解的是同一个优化问题,一个用解析解,一个用迭代解。 那为什么不总是用解析解?因为它要求「误差对参数的导数能写成式子并反解出来」。 线性回归能,多层神经网络不能。能解的时候没人愿意迭代,解不出来的时候迭代是唯一的路。

二、参数是什么

拿一条直线 y = wx + b 来说,w 和 b 就是参数。它们不是人想出来的,是从数据里定出来的。 换成一个九次多项式,参数就是十个系数。 换成一个两层神经网络,参数是两层矩阵里的每个数,几百到几十亿个。 不管多少个,性质一样:一组数定了,函数就定了。 Demo 里那个 sin(3x) 加 0.3cos(7x) 的目标函数,人手写不出闭式解,但可以用点去拟合: 一次多项式误差 0.470,九次压到 0.071。九次多项式只有十个参数,这十个参数就是「学到的规律」。 所以「模型」这个词没那么玄:它就是一个形状固定、参数待定的函数。训练就是找那组参数。

三、为什么大部分问题写不出公式

因为真实世界的映射关系太复杂,而且往往没有解析形式。 「这张图里有没有猫」这个函数的定义域是几百万维的像素空间,值域是两个字——你要怎么写出它的解析式? 还有一层:就算写得出,参数也解不出来。 线性回归的闭式解要算一个矩阵的逆,矩阵一大,计算量按三次方涨,几百亿参数根本算不动。 所以工业界的默认做法是:只要能定义「预测得准不准」,就用迭代去逼近,不去求解析解。 这也解释了为什么「损失函数」在设计模型时那么重要——它是迭代唯一的指路牌。

四、学习的三步循环

第一步前向:把输入代进当前参数,算出预测值。 第二步算误差:拿预测值和真值比,得到一个数(比如均方误差)。 第三步改参数:算误差对每个参数的导数,按导数的反方向挪一小步。 这三步重复几千几万次。 Demo 里那个梯度下降就是最朴素的版本:均方误差从 7.368 一路压到 0.047,两百步。 整个深度学习的复杂度,全在「怎么算导数」和「怎么挪」这两件事上。反向传播解决第一件, 各种优化器(SGD、Adam)解决第二件。 记住这个循环,后面第八章讲神经网络、第九章讲调参,你都能把它套回这三步——因为真的就是这三步。

五、动手 Demo:人推公式 vs 机器试错,同一个答案两条路

先造 80 个带噪声的点,真值斜率 3、截距 2。 然后走两条路:一条用最小二乘的闭式解一步算出,一条用梯度下降走 200 步。 最后换一个写不出公式的目标函数,看两条路还剩几条。

x = rg.uniform(-1, 1, 80)
y = 3.0 * x + 2.0 + rg.normal(0, 0.25, 80)

# ① 人推公式:最小二乘的闭式解
A = np.stack([x, np.ones_like(x)], axis=1)
sol = np.linalg.lstsq(A, y, rcond=None)[0]

# ② 机器试错:梯度下降两百步
w, b = 0.0, 0.0
for _ in range(200):
    g = w * x + b - y
    w -= 0.08 * 2.0 * float((g * x).mean())
    b -= 0.08 * 2.0 * float(g.mean())

print(sol, w, b)

实跑输出:

--------------------------------------------------------------------
核心逻辑:能推出公式的就推公式,推不出来的才交给数据
--------------------------------------------------------------------
  任务:从 80 个带噪声的点里,找出 y = 3x + 2 这条线。

  做法                   斜率 w   截距 b   步数   过程
  -------------------------------------------------------
  人推公式(最小二乘)   3.0147   2.0152      0   一次算完
  机器学(梯度下降)     3.0146   2.0152    200   一步步挪
  两条路都落在真值 3 和 2 上,差在第四位小数。**同一个答案,一个靠推导,一个靠试错。**
  梯度下降把均方误差从 7.368 压到 0.047。

  那有公式为什么还要学?因为这个形状能写成公式,绝大多数真问题写不出来。
  模型         要调的参数个数   训练集均方根误差
  ---------------------------------------------
  1 次多项式                2             0.4704
  3 次多项式                4             0.2097
  9 次多项式               10             0.0710
  目标函数是 sin(3x) 加 0.3cos(7x),**这个式子人手写不出来**,但你可以拿一堆点去拟合它。1 次误差 0.470,9 次压到 0.071。
  1 次那行不是「人写不出来」,是**这条直线描述不了这个形状**——参数少到装不下目标。
  **参数就是公式里待定的那些数。** 深度学习和上面这行多项式拟合没有本质区别:只是参数从 10 个变成几十亿个,函数从多项式换成一层层矩阵乘。

两条路的答案:闭式解 3.0147 / 2.0152,梯度下降 3.0146 / 2.0152。 差在第四位小数,来自迭代次数不够。 多跑几百步还能再靠近,但永远差一点点——迭代法的精度是用步数换的。 注意学习率 0.08 这个数:太大会震荡甚至发散,太慢走不完。 这就是「调参」这件事最原始的样子,第八章还会遇到它。 第二段那个 sin(3x) 加 0.3cos(7x) 的函数,人手写不出闭式解,但机器能拟合:一次误差 0.470, 九次 0.071。参数从 2 个加到 10 个,误差降了六倍多。 要说清的是:九次多项式那 10 个参数不是「规律」,是「拟合」。 它在这 80 个点上贴得很好,换一批点就可能崩——这正是下一节要讲的「训练不等于学对」。

30 秒实验

  1. 把学习率从 0.08 改成 0.2,两百步内误差会震荡;改成 0.01,两百步走不完。 这在二维线性问题上有闭式解兜底,在神经网络里没有兜底——这就是调参为什么让人头疼。
  2. 把梯度下降的步数从 200 加到 2000,看系数能不能追上闭式解的四位小数。 你会发现它越来越近,但收敛速度是几何式的,前 50 步降得快,后面几乎不动。
  3. 把多项式从九次换到十五次,误差还会再降一点——但这是第二段那个「过拟合」的入口。 先记住这个信号,下一节专门算。

常见误区

  1. 「AI 是让机器像人一样思考」。工程上没人这么实现。 实际做法是定义一个可微的函数、给它一堆数据、让它自己调参数。 「像不像人」不是评价指标,「准不准」才是。
  2. 「公式能推出来就别用机器学了」。对,但前提是推得出来。 现实里绝大多数任务的映射关系没有解析式,这就是深度学习的生存空间。
  3. 「参数是模型的『知识』」。更准确地说,参数是在训练数据上压缩出来的统计规律。 它不含「知识」这种实体,所以数据里没有的东西它也不会有。
自测三问(点开对答案) 1. 为什么梯度下降能用,最小二乘的闭式解在神经网络里用不了? —— 闭式解要求能把「误差对参数求导并令其为零」这个方程组解出来。 线性模型能,多层网络加非线性激活之后解不出来,只能迭代逼近。 2. 参数多就一定更好吗? —— 在这一节的例子里是(2 个到 10 个,误差从 0.470 降到 0.071),但那是**训练集误差**。 参数多到一定程度会开始记噪声,测试集误差反而涨——下一节算这个临界点。 3. 三步循环里,哪一步最容易出错? —— 第二步「算误差」。选错损失函数,模型会朝着错的方向优化。比如分类问题用均方误差,梯度会饱和; 用交叉熵才正常。

上一节说「训练就是调参数」,这一节把它拆成了三步循环。下一节追问一句:调完之后怎么知道自己调对了?

相关笔记