机器学习入门——手写线性回归与梯度下降

个人主页: > for_ever_love__ < (欢迎各位大佬莅临😊)
其他栏目: > 我想学python了 <

其他栏目: > iOS项目总结大全 <

其他栏目: > iOS UI <

文章目录

机器学习入门------手写线性回归与梯度下降

一、从"预测"说起

假设你手里有一组「房子面积 → 房价」的数据,现在来了个 90 平的房子,让你估价。你会怎么做?最朴素的想法:在图上把已知数据点画出来,画一条最贴合的直线,用这条直线去预测。

这条直线,就是最简单的机器学习模型------线性回归 。而"找出最贴合的直线"的过程,就是训练。

今天我们不用任何框架,只用 NumPy(数据处理那篇刚好派上用场),把线性回归和梯度下降从零写一遍。写完你就会明白:所谓"模型训练",本质就是一个求函数最小值的迭代过程。

二、模型与损失函数

1. 模型假设

线性回归假设输入和输出之间是线性关系:

复制代码
ŷ = w·x + b
  • x:输入(房子面积)
  • w:权重(斜率),b:偏置(截距)------这两个就是模型要学的参数
  • ŷ:模型预测值(读作 y-hat,区别于真实值 y)

2. 损失函数:量化"预测得有多差"

预测值和真实值的差距用均方误差(MSE)衡量:

复制代码
L = (1/N) · Σ (ŷᵢ - yᵢ)²

把 N 个样本的预测误差平方后取平均。平方有两个好处:放大偏差、且处处可导(方便求梯度)。

训练目标:找到让 L 最小的 w 和 b。

3. 梯度下降:下山的过程

想象你蒙着眼站在山上,想走到最低点(损失最小的位置)。策略很简单:

  1. 用脚感受当前位置的坡度(求梯度)
  2. 朝最陡的下坡方向走一小步(沿负梯度更新参数)
  3. 重复,直到坡度接近 0

写成公式:

复制代码
w ← w - η · ∂L/∂w
b ← b - η · ∂L/∂b

η 是学习率:步子太大容易跨过谷底来回震荡,太小则收敛极慢。

学习率 行为
太大(如 1.0) 损失上下震荡甚至发散
合适(如 0.01) 平滑下降、稳定收敛
太小(如 1e-8) 下降极慢,像没训练

三、动手实现

1. 生成模拟数据

python 复制代码
import numpy as np

np.random.seed(42)
N = 200
x = np.random.rand(N) * 100          # 房子面积 0~100
y = 3.0 * x + 2.0 + np.random.randn(N) * 10   # 真实关系 y=3x+2,加噪声

2. 训练循环

python 复制代码
w, b = 0.0, 0.0          # 参数初始化为 0
lr = 1e-4                # 学习率
epochs = 1000            # 迭代轮数

for epoch in range(epochs):
    # 前向:算预测值
    y_pred = w * x + b
    # 损失:均方误差
    loss = np.mean((y_pred - y) ** 2)
    # 反向:算梯度(对 MSE 求导的结果)
    grad_w = 2 * np.mean((y_pred - y) * x)
    grad_b = 2 * np.mean(y_pred - y)
    # 更新参数
    w -= lr * grad_w
    b -= lr * grad_b

    if epoch % 100 == 0:
        print(f"epoch={epoch:4d}  loss={loss:10.2f}  w={w:.3f}  b={b:.3f}")

print(f"最终结果: w={w:.3f} (真实值 3.0), b={b:.3f} (真实值 2.0)")

运行输出(节选):

复制代码
epoch=   0  loss=  30584.67  w=1.527  b=0.030
epoch= 100  loss=   1452.95  w=2.527  b=0.842
epoch= 500  loss=     98.03  w=2.984  b=1.914
epoch= 900  loss=     95.31  w=3.002  b=2.003
最终结果: w=3.004 (真实值 3.0), b=2.008 (真实值 2.0)

可以看到:损失从 3 万多一路降到 95 左右,参数 w、b 收敛到真实值附近。剩下的 95 就是数据里噪声本身的最小误差------模型不可能把随机噪声也"学掉"。

四、三个必须理解的关键点

1. 为什么要"平方"?

如果用绝对值误差 |ŷ-y|,函数在 0 点不可导,梯度法走不动;平方函数处处光滑,梯度信息完整。这是 MSE 流行的核心原因。

2. 梯度方向的直觉

grad_w = 2·mean((y_pred-y)·x):当预测值普遍偏高(误差为正),梯度为正,w 减小 → 预测下调;偏低则反之。梯度永远指向"损失上升最快的方向",所以我们减它。

3. 特征尺度问题

如果 x 的取值是 0~100000 而不是 0~100,同样 lr=1e-4 会直接发散。原因是梯度里带着 x,输入越大梯度越大,步长失控。解决方案是特征归一化:

python 复制代码
x_norm = (x - x.mean()) / x.std()   # 转成均值 0、标准差 1

这也是为什么深度学习里输入数据几乎都要做标准化------梯度下降对尺度极其敏感。

五、常见坑与排查方法

现象 可能原因 解决
loss 变 NaN / 巨大 学习率太大 缩小 lr(每次除以 10 试试)
loss 几乎不动 lr 太小 / 参数初始化离谱 调大 lr,或归一化输入
loss 收敛但预测差 数据有异常值 画散点图排查,MSE 对离群点极敏感
每次结果不一样 忘记固定随机种子 np.random.seed(42)

调试口诀:先看 loss 曲线,再怀疑一切。loss 不降是参数问题,loss 降但预测差是数据问题。

六、对比:手写 vs 用 sklearn

对比项 手写 NumPy sklearn
理解原理 ✅ 彻底搞懂梯度下降 ❌ 黑盒
代码量 ~20 行 ~3 行
灵活性 任意改动 受限于 API
生产适用性 低 高

生产中当然用现成库,但学习阶段手写一遍的价值无可替代------PyTorch 的自动求导做的正是我们今天手动算梯度的那一步。

七、小结

  1. 线性回归 = ŷ = wx + b,训练 = 找让 MSE 最小的 w、b
  2. 梯度下降三步:前向算预测 → 反向算梯度 → 沿负梯度更新
  3. 学习率是第一优先级超参数:大了发散、小了龟速
  4. 特征尺度不一致时必须归一化
  5. loss 曲线是最重要的调试工具

明天进入深度学习与 PyTorch:让"自动求导"替我们完成今天手动推的梯度,训练第一个真正的神经网络。

一句话总结:所谓训练,就是让参数沿着"损失下降最快的方向",一小步一小步地走到谷底。

相关推荐
打工仔折腾 AI1 小时前
从 Demo 到生产级 Agent:8 个关键设计机制与 Python 实现拆解
java·jvm·人工智能·后端·python·langchain·ai agent 实战
在猴站学算法1 小时前
(SQL注入学习)无回显的报错注入(Error-Based)
学习·网络安全·sql注入·ctf竞赛
I Am a robert girl1 小时前
当传感器学会“说谎“:拆解可靠性门控的稀疏惯性动捕融合
python·姿态估计·传感器融合·惯性动捕·imu传感器·可靠性门控·可穿戴计算
匠测AI说1 小时前
AI for Testing 提效实战·测试设计(二):让 AI 按等价类 + 边界值把用例补全
人工智能·测试覆盖率
CHEEVEN_QY1 小时前
液冷板热阻计算与流阻优化的实战方法
人工智能·算法·机器学习
李航19831 小时前
AI定制柜建模,需要详细的建模规范和标准流程
人工智能·python·计算机视觉·ai·ai编程
能源革命1 小时前
AI 日报 · 2026-10-03
人工智能
hahaha60161 小时前
色彩恒常性概述
人工智能·嵌入式硬件·数码相机·计算机视觉
FL16238631292 小时前
无人机视角海边沙滩垃圾检测数据集VOC+YOLO格式603张3类别
人工智能·yolo