这是博客的第一篇笔记,用来验证公式渲染、代码高亮和复制按钮是否正常。内容是一个最经典的入门例子。
问题:用一条直线拟合数据#
线性回归要找一个线性模型 $y = \mathbf{w}^\top \mathbf{x} + b$,让它尽量贴合训练数据。 核心思路是把“模型好坏”变成一个可以优化的数字(损失),再不断调整参数让它变小。
损失函数:均方误差#
用均方误差(MSE)衡量预测值与真实值的差距:
$$ \mathcal{L}(\mathbf{w}, b) = \frac{1}{n} \sum_{i=1}^{n} \left( \hat{y}_i - y_i \right)^2 $$其中 $\hat{y}_i = \mathbf{w}^\top \mathbf{x}_i + b$ 是模型对第 $i$ 个样本的预测值,$y_i$ 是真实值。
求解:梯度下降#
参数沿负梯度方向更新,学习率为 $\eta$:
$$ \mathbf{w} \leftarrow \mathbf{w} - \eta \, \nabla_{\mathbf{w}} \mathcal{L}, \qquad b \leftarrow b - \eta \, \frac{\partial \mathcal{L}}{\partial b} $$直观地说:损失函数像一片地形,梯度指向“上坡”,我们就朝“下坡”走一小步,一步步走到最低点(最优解)。
PyTorch 实现#
下面用 PyTorch 的自动求导跑一遍梯度下降,体会“不用手算梯度”的便利:
import torch
# 1. 造数据:y = 2x + 3 + 噪声
torch.manual_seed(0)
X = torch.linspace(-1, 1, 100).reshape(-1, 1)
y = 2 * X + 3 + 0.1 * torch.randn_like(X)
# 2. 可训练参数(requires_grad=True 让 PyTorch 跟踪它的梯度)
w = torch.zeros(1, requires_grad=True)
b = torch.zeros(1, requires_grad=True)
lr = 0.1 # 学习率 η
for epoch in range(100):
y_hat = X * w + b # 前向:线性模型
loss = ((y_hat - y) ** 2).mean() # MSE 损失
loss.backward() # 反向传播:自动算梯度
with torch.no_grad():
w -= lr * w.grad # 梯度下降更新
b -= lr * b.grad
w.grad.zero_(); b.grad.zero_() # 清空梯度(PyTorch 会累加)
print(f"训练完成:w ≈ {w.item():.3f}(真值 2),b ≈ {b.item():.3f}(真值 3)")运行后会看到 $w$ 收敛到 2 附近、$b$ 收敛到 3 附近——模型自己“学”到了数据背后的规律。
小结#
这套流程几乎就是所有神经网络训练的骨架:
- 定义模型(这里是线性模型,后面会换成神经网络);
- 算损失(MSE 只是其一,分类任务会用交叉熵);
- 梯度更新(
loss.backward()+ 手动下降)。
把这三步记住,后面学更复杂的模型时,变化的只是每一步的具体形式。