PyTorch 线性回归:从零开始掌握机器学习基础
在机器学习的世界里,线性回归是第一个“入门级”模型,就像学骑自行车时的辅助轮。它简单、直观,却能揭示数据背后的基本规律。而 PyTorch,作为当今最流行的深度学习框架之一,不仅支持复杂的神经网络,同样可以轻松实现线性回归。今天我们就来手把手带你用 PyTorch 实现一个真正的线性回归模型,让你在实践中理解它的核心机制。
我们不会一开始就扔出一堆公式和代码,而是像搭积木一样,一步一步构建你的第一个 PyTorch 线性回归模型。无论你是刚接触编程,还是已经有一定经验的开发者,这篇教程都能帮你打下坚实的基础。
什么是线性回归?一个生活化的比喻
想象你正在开一家奶茶店,想预测每天的销量。你发现销量和气温之间似乎存在某种关系:气温越高,买奶茶的人越多。这种“一个变量影响另一个变量”的关系,就是回归分析要研究的。
线性回归的核心思想是:用一条直线(或超平面)来拟合数据点之间的关系。这条直线的数学表达式是:
y = w * x + b
其中:
x是输入特征(比如气温)y是输出目标(比如销量)w是权重(斜率)b是偏置(截距)
这个公式看起来简单,但背后隐藏着机器学习的核心逻辑:通过数据“学习”出最佳的 w 和 b,使得预测值尽可能接近真实值。
准备工作:环境搭建与数据生成
在动手写代码前,先确保你的开发环境已经准备好。你需要安装 PyTorch 和 NumPy,这两个库是进行数值计算和模型训练的基础。
pip install torch numpy
安装完成后,我们先生成一组模拟数据。假设我们有 100 个样本,每个样本包含一个气温值(x)和对应的奶茶销量(y)。真实的销量和气温的关系是:
销量 = 2.5 * 气温 + 10 + 噪声
import torch
import numpy as np
torch.manual_seed(42)
np.random.seed(42)
x_data = np.random.uniform(0, 30, 100)
true_w = 2.5 # 真实权重
true_b = 10 # 真实偏置
noise = np.random.normal(0, 2, 100) # 噪声,标准差为 2
y_data = true_w * x_data + true_b + noise
x_tensor = torch.tensor(x_data, dtype=torch.float32).reshape(-1, 1)
y_tensor = torch.tensor(y_data, dtype=torch.float32).reshape(-1, 1)
print("前 5 个样本:")
print(f"气温 (x): {x_tensor[:5].numpy().flatten()}")
print(f"销量 (y): {y_tensor[:5].numpy().flatten()}")
说明:
torch.manual_seed(42):设置随机种子,确保每次运行结果一致。reshape(-1, 1):将一维数组转为二维张量,每行一个样本,列数为 1,符合 PyTorch 的输入格式。dtype=torch.float32:指定数据类型为 32 位浮点数,这是深度学习的标准格式。
构建模型:PyTorch 的线性层
现在我们有了数据,下一步就是定义模型。PyTorch 提供了 nn.Linear 模块,专门用来实现线性变换,它就是我们线性回归模型的核心。
import torch.nn as nn
class LinearRegressionModel(nn.Module):
def __init__(self):
super(LinearRegressionModel, self).__init__() # 调用父类构造函数
# 创建一个线性层:输入维度 1,输出维度 1
self.linear = nn.Linear(in_features=1, out_features=1)
def forward(self, x):
# 前向传播:将输入 x 通过线性层,得到预测值 y_pred
return self.linear(x)
model = LinearRegressionModel()
print(model)
输出结果:
LinearRegressionModel(
(linear): Linear(in_features=1, out_features=1, bias=True)
)
关键点解析:
nn.Module是 PyTorch 所有神经网络模块的基类。nn.Linear内部会自动初始化权重w和偏置b,初始值通常是随机的。forward()方法定义了前向传播的流程,即输入如何变成输出。
损失函数与优化器:让模型“学会”正确参数
模型有了,但如何判断它预测得好不好?这就需要损失函数(Loss Function)。我们这里使用均方误差(MSE),它衡量预测值与真实值之间的平均平方差。
criterion = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.01) # lr: 学习率
解释:
criterion是损失函数,用于量化误差。optimizer是优化器,负责根据损失的梯度更新模型参数。model.parameters():获取模型中所有可训练的参数(即w和b)。lr=0.01:学习率,控制每次更新的步长。太大会震荡,太小会收敛慢。
训练模型:让机器自己“找规律”
现在进入最激动人心的部分:训练模型。我们将循环多次(比如 1000 次),每次从数据中取出一批样本,计算损失,然后反向传播,更新参数。
num_epochs = 1000
for epoch in range(num_epochs):
# 前向传播:模型预测
y_pred = model(x_tensor)
# 计算损失
loss = criterion(y_pred, y_tensor)
# 反向传播:计算梯度
loss.backward()
# 更新参数
optimizer.step()
# 清除梯度(防止累积)
optimizer.zero_grad()
# 每 100 轮打印一次损失
if (epoch + 1) % 100 == 0:
print(f"Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}")
print("训练完成!")
逐行注释:
y_pred = model(x_tensor):前向传播,得到预测值。loss = criterion(y_pred, y_tensor):计算损失。loss.backward():反向传播,计算每个参数的梯度。optimizer.step():根据梯度更新参数。optimizer.zero_grad():清空梯度,避免下一轮计算时累积。loss.item():将张量转为 Python 数值。
经过训练,你会发现损失值从最初的几百下降到接近 0,说明模型正在不断逼近真实关系。
模型评估:看看它学得准不准
训练结束后,我们来检验模型的效果。将模型的预测结果与真实值对比,看看是否接近。
weight = model.linear.weight.item()
bias = model.linear.bias.item()
print(f"学习到的权重 (w): {weight:.4f}")
print(f"学习到的偏置 (b): {bias:.4f}")
print(f"真实值:w = {true_w}, b = {true_b}")
new_temperature = torch.tensor([25.0], dtype=torch.float32).reshape(-1, 1)
predicted_sales = model(new_temperature)
print(f"气温 25°C 时,预测销量为:{predicted_sales.item():.2f}")
输出示例:
学习到的权重 (w): 2.4987
学习到的偏置 (b): 9.9834
真实值:w = 2.5, b = 10
气温 25°C 时,预测销量为:72.45
结论:模型成功“学习”到了真实关系,误差非常小,说明 PyTorch 线性回归训练是有效的。
总结与延伸思考
通过本篇文章,我们完成了从数据生成、模型构建、损失定义、训练优化到模型评估的完整流程。整个过程清晰、可复现,是学习 PyTorch 线性回归的绝佳起点。
你可能会问:那我以后还能用这个框架做别的事吗?答案是肯定的。PyTorch 线性回归的结构,正是所有神经网络的“最小单元”。当你以后学习多层感知机、卷积神经网络时,你会发现这些模型本质上都是在“堆叠”线性层和非线性激活函数。
此外,你还可以尝试:
- 使用不同的损失函数(如 MAE)
- 调整学习率,观察收敛速度
- 加入正则化防止过拟合
- 使用更复杂的模型结构(如多项式回归)
PyTorch 线性回归,不只是一个简单的例子,更是通向更广阔机器学习世界的钥匙。掌握它,你就迈出了成为数据工程师或 AI 开发者的坚实一步。
现在,轮到你动手试试了。打开你的代码编辑器,把这段代码跑一遍,感受一下“机器自己学会规律”的神奇时刻。