课程承诺:1 个核心概念(损失函数)+1 个核心思想(梯度下降)+1 段纯手写训练代码。学完你将彻底看懂所有 AI 的训练过程,再也不会觉得 "fit ()" 函数是黑魔法。

本节课目标:搞懂上一课中model.fit(X, y)这行代码背后到底发生了什么,亲手写出 AI 的 "学习大脑",亲眼看着它一步步找到规律。


🧩 先回答上一课的思考题

上一课最后我让你试试把数据改成不完美的:

python

运行

X = np.array([[1], [2], [3], [4], [5]])  # 学习时间(小时)
y = np.array([60, 70, 80, 90, 95])      # 考试分数(有一个异常点)

运行后你会发现,AI 预测学习 8 小时能考113 分,而不是完美的 130 分。

关键问题:为什么 AI 不画一条经过前 4 个点的直线(预测 130 分),而是画了一条 "歪歪扭扭" 的线?它是怎么决定哪条线是 "最好" 的?

这就是本节课要解决的核心问题。


🧠 第一个核心概念:损失函数(Loss Function)

最通俗的解释

把 AI 想象成一个正在做题的学生:

  • 每一道题(一个数据点),它都会给出一个答案(预测值)
  • 答案和正确答案的差距,就是它这道题扣的分
  • 所有题扣的分加起来,就是它的总分

这个 "总分",在机器学习里就叫损失函数

  • ✅ 损失越小 → AI 犯的错误越少 → 模型越好
  • ❌ 损失越大 → AI 犯的错误越多 → 模型越差

我们的例子

对于 "学习时间→考试分数" 这个问题,AI 找到的规律是一条直线:分数 = w × 学习时间 + b(w 叫 "斜率",b 叫 "截距",这两个就是 AI 要学习的参数

对于每一个数据点:

  • 真实分数:y
  • AI 预测的分数:y_pred = w*x + b
  • 这道题扣的分:(y_pred - y)² (平方是为了让正负误差都变成正数)
  • 总损失(所有题的扣分总和):损失 = 1/n × Σ(y_pred - y)²

这个就是最常用的均方误差损失函数,也是线性回归用的损失函数。

回到刚才的问题

AI 为什么不选经过前 4 个点的直线(w=10, b=50)?我们算一下这条直线的损失:

  • 第 5 个点:预测分数 = 10×5+50=100,真实分数 = 95,扣分 =(100-95)²=25
  • 总损失 = 25/5=5

而 AI 最终选的直线(w≈7.5, b≈53)的损失是多少呢?

  • 总损失≈2.3,比刚才的 5 小很多!

结论:AI 选择 "最好" 的直线的唯一标准,就是让损失函数的值最小


💡 第一个核心思想:梯度下降(Gradient Descent)

现在问题变成了:怎么找到一组参数 (w, b),让损失函数的值最小?

这就是机器学习最核心的算法 ——梯度下降。所有的 AI,从简单的线性回归到复杂的 GPT 大模型,本质上都是用这个算法训练出来的。

最形象的比喻

把损失函数想象成一座山,我们现在站在山上的某个位置,目标是走到山谷的最低点(损失最小的地方)。

我们该怎么走?

  1. 站在原地,环顾四周,找到山坡最陡的下坡方向
  2. 朝着这个方向走一小步
  3. 到达新的位置后,重复步骤 1 和 2,直到走到山谷

这就是梯度下降的全部思想!

  • 梯度:就是山坡最陡的下坡方向
  • 下降:朝着这个方向走一步,让损失变小

对应到我们的问题

  • 山的高度 = 损失函数的值
  • 我们的位置 = 当前的参数 (w, b)
  • 每走一步 = 更新一次参数 (w, b)
  • 山谷最低点 = 损失最小的参数 (w*, b*)

一个非常重要的参数:学习率(Learning Rate)

我们每一步走多大?这个 "步长" 就叫学习率

  • 学习率太小:走得非常慢,需要走很多步才能到达山谷
  • 学习率太大:一步跨太大,直接跳过最低点,甚至会越走越高,从山上掉下去

这是机器学习中最容易调错的参数,没有之一。


💻 第一个纯手写训练代码:不用 scikit-learn,自己写 AI 的大脑

前置要求:安装 matplotlib(用于画图)

bash

运行

pip install matplotlib

完整代码(复制粘贴就能运行)

python

运行

import numpy as np
import matplotlib.pyplot as plt

# 1. 准备数据(和上一课一样)
X = np.array([1, 2, 3, 4, 5])
y = np.array([60, 70, 80, 90, 95])

# 2. 初始化参数(AI一开始什么都不知道,随机猜一个值)
w = 0.0  # 斜率
b = 0.0  # 截距

# 3. 设置超参数
learning_rate = 0.01  # 学习率(步长)
epochs = 1000         # 训练次数(走多少步)

# 用来记录每一步的损失,方便画图
loss_history = []

# 4. 梯度下降训练过程(核心!)
for i in range(epochs):
    # 4.1 用当前的w和b做预测
    y_pred = w * X + b
    
    # 4.2 计算损失
    loss = np.mean((y_pred - y) ** 2)
    loss_history.append(loss)
    
    # 4.3 计算梯度(山坡最陡的方向)
    dw = 2 * np.mean((y_pred - y) * X)
    db = 2 * np.mean(y_pred - y)
    
    # 4.4 朝着梯度的反方向走一步(更新参数)
    w = w - learning_rate * dw
    b = b - learning_rate * db
    
    # 每100步打印一次训练进度
    if i % 100 == 0:
        print(f"第{i}次训练,损失:{loss:.4f},w:{w:.4f},b:{b:.4f}")

# 5. 训练完成,打印最终结果
print("\n训练完成!")
print(f"最终参数:w={w:.4f}, b={b:.4f}")
print(f"最终规律:分数 = {w:.2f} × 学习时间 + {b:.2f}")
print(f"预测学习8小时的分数:{w*8 + b:.2f}")

# 6. 画出损失下降曲线
plt.figure(figsize=(12, 5))
plt.subplot(1, 2, 1)
plt.plot(loss_history)
plt.xlabel("训练次数")
plt.ylabel("损失")
plt.title("损失下降曲线")

# 7. 画出拟合的直线
plt.subplot(1, 2, 2)
plt.scatter(X, y, color='red', label='真实数据')
plt.plot(X, w*X + b, color='blue', label='AI拟合的直线')
plt.xlabel("学习时间(小时)")
plt.ylabel("考试分数(分)")
plt.legend()
plt.title("数据与拟合直线")
plt.show()

🔍 逐行拆解核心训练过程

这就是model.fit(X, y)背后的全部秘密!所有 AI 的训练,都是这个循环:

plaintext

循环很多次:
    1. 用当前参数做预测
    2. 计算预测错了多少(损失)
    3. 计算往哪个方向走能让损失变小(梯度)
    4. 往那个方向走一小步(更新参数)

关键细节解释

  1. 参数初始化:一开始 w 和 b 都是 0,相当于 AI 猜 "不管学习多久,分数都是 0 分",这显然是错的,但没关系,它会慢慢修正。

  2. 梯度计算:这行代码dw = 2 * np.mean((y_pred - y) * X)就是数学上求导的结果。你现在不需要记住这个公式,只要知道它能告诉我们 "w 和 b 往哪个方向变,损失会变小" 就行。

  3. 参数更新:注意这里是减号w = w - learning_rate * dw因为梯度是上坡的方向,我们要往下走,所以要减去梯度。


✨ 神奇的实验:亲手体验学习率的影响

这是本节课最重要的实验,一定要做!

实验 1:把学习率改成 0.1

python

运行

learning_rate = 0.1

运行后你会发现什么?

  • 损失不仅没有下降,反而越来越大,最后变成了无穷大!
  • 这就是学习率太大的后果:一步跨太大,直接从山上掉下去了。

实验 2:把学习率改成 0.0001

python

运行

learning_rate = 0.0001

运行后你会发现什么?

  • 损失下降得非常非常慢,训练 1000 次后还没到达最低点
  • 这就是学习率太小的后果:走得太慢,需要训练几万次才能收敛。

实验 3:把训练次数改成 10000

python

运行

epochs = 10000

你会发现,损失下降到一定程度后就不再变了,说明 AI 已经走到了山谷的最低点,找到了最好的参数。


📝 本节课总结

  1. 核心概念:损失函数是衡量 AI 预测错误程度的指标,AI 的目标就是让损失最小
  2. 核心思想:梯度下降是让损失最小的方法,就像从山上往下走,每一步都朝着最陡的下坡方向
  3. 核心代码:所有 AI 的训练都是 "预测→算损失→算梯度→更新参数" 这个循环
  4. 你已经做到了:没有用任何机器学习库,纯手写了一个 AI 的训练过程!

最重要的一句话:从今天起,世界上再也没有 "黑魔法" 一样的 AI 了。不管是 ChatGPT 还是 AlphaGo,它们的训练过程和你刚才写的这几十行代码,本质上是完全一样的。


🎯 课后作业(必须做)

  1. 运行上面的代码,确保能看到损失下降曲线和拟合直线
  2. 尝试不同的学习率(0.001, 0.005, 0.02),观察损失下降的速度有什么不同
  3. 把数据改成上一课的房价数据,用你自己写的梯度下降算法训练,看看和 scikit-learn 的结果是不是一样的
  4. 思考一个问题:如果损失函数不是一个 "碗" 形,而是有多个山谷,梯度下降会发生什么?
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐