梯度下降 (Gradient Descent)
📌 核心定义 (What)
Section titled “📌 核心定义 (What)”一句话定义:梯度下降是一种迭代优化算法,用于寻找函数的最小值(在 AI 中通常是寻找损失函数的最小值,即让模型预测最准确的参数)。
你可以把它想象成模型学习的”指南针”,它告诉模型应该往哪个方向调整参数,才能让错误率下降得最快。
🎨 交互演示 (Interactive)
Section titled “🎨 交互演示 (Interactive)”动手试试!这是一个简单的函数 。 点击 “迭代一步”,观察红球(参数)是如何沿着坡度(梯度)滑向谷底的。
📊梯度下降可视化
f(x) = x² (凸函数,有唯一最小值)
✅ 学习率适中
当前位置 x: -4.0000 | 梯度 ∇: -8.0000 | Loss: 16.0000 | 迭代: 0
🏠 生活类比 (Analogy)
Section titled “🏠 生活类比 (Analogy)”🏔️ “蒙眼下山”的故事
Section titled “🏔️ “蒙眼下山”的故事”想象你被蒙住双眼,放置在一座高山的某个位置(初始参数)。你的目标是下到山谷的最低点(最小损失),那里有宝藏。
- 感受坡度(计算梯度):因为看不见,你只能用脚感受周围的地势。你发现左边是上坡,右边是下坡,且右边坡度最陡。
- 迈出一步(更新参数):你决定往最陡的下坡方向走一步。
- 步子太小(学习率过低):下山慢,走到天黑都不到。
- 步子太大(学习率过高):可能一步跨过头,甚至冲到对面的山上去了。
- 重复(迭代):你不断重复”感受-迈步”的过程,直到感觉到四周都是上坡,说明你已经(大概率)到了谷底。
🎬 视频详解 (Video)
Section titled “🎬 视频详解 (Video)”🎯 为什么需要它 (Why)
Section titled “🎯 为什么需要它 (Why)”在深度学习中,模型可能有数亿个参数(权重 和偏置 )。我们无法直接算出哪组参数能让误差最小(就像无法直接算出复杂方程的解)。
梯度下降提供了一种通用的、自动化的方法:
- 不需要知道函数的全局形状。
- 只需要知道当前位置往哪走能让误差变小。
- 通过成千上万次微小的调整,最终找到最优解。
📊 数学原理 (Math)
Section titled “📊 数学原理 (Math)”核心公式非常简单,就是不断更新参数 :
参数更新公式
其中:
- : 当前的参数(位置)
- : 更新后的参数(下一步的位置)
- : 学习率 (Learning Rate) - 控制步长大小
- : 梯度 (Gradient) - 损失函数上升最快的方向
- : 减号表示往梯度的反方向走(因为我们要下山,不是上山)
💻 代码实现 (Code)
Section titled “💻 代码实现 (Code)”看看如何在 Python 中从零实现一个简单的线性回归梯度下降。
import numpy as np
# 1. 准备数据 (y = 2x + 1)X = np.array([1, 2, 3, 4, 5])y = np.array([3, 5, 7, 9, 11])
# 2. 初始化参数w = 0.0 # 权重b = 0.0 # 偏置lr = 0.01 # 学习率epochs = 1000 # 迭代次数
# 3. 开始迭代for epoch in range(epochs): # 前向传播:计算预测值 y_pred = w * X + b
# 计算 Loss (均方误差 MSE) loss = ((y_pred - y)**2).mean()
# 反向传播:计算梯度 (手动推导导数) # d_loss/dw = 2 * (y_pred - y) * x dw = (2 * (y_pred - y) * X).mean() # d_loss/db = 2 * (y_pred - y) db = (2 * (y_pred - y)).mean()
# 更新参数 w = w - lr * dw b = b - lr * db
if epoch % 100 == 0: print(f"Epoch {epoch}: w={w:.3f}, b={b:.3f}, loss={loss:.3f}")
print(f"最终结果: w={w:.3f}, b={b:.3f}")# 预期接近: w=2.000, b=1.000import torch
# 1. 准备数据X = torch.tensor([1, 2, 3, 4, 5], dtype=torch.float32)y = torch.tensor([3, 5, 7, 9, 11], dtype=torch.float32)
# 2. 初始化参数 (requires_grad=True 开启自动求导)w = torch.tensor(0.0, dtype=torch.float32, requires_grad=True)b = torch.tensor(0.0, dtype=torch.float32, requires_grad=True)
lr = 0.01epochs = 1000
# 3. 开始迭代for epoch in range(epochs): # 前向传播 y_pred = w * X + b
# 计算 Loss loss = ((y_pred - y)**2).mean()
# 反向传播:自动计算梯度 loss.backward()
# 更新参数 (需要在 no_grad 模式下更新,否则更新操作也会被记录梯度) with torch.no_grad(): w -= lr * w.grad b -= lr * b.grad
# 清空梯度 (否则会累加) w.grad.zero_() b.grad.zero_()
if epoch % 100 == 0: print(f"Epoch {epoch}: w={w.item():.3f}, b={b.item():.3f}, loss={loss.item():.3f}")⚠️ 常见误区 (Pitfalls)
Section titled “⚠️ 常见误区 (Pitfalls)”🔗 相关概念
Section titled “🔗 相关概念”- 反向传播 (Backpropagation) - 如何高效计算梯度
- 损失函数 (Loss Function) - 定义”山”的形状
- 优化器 (Optimizers) - 步子迈多大、怎么调整步伐