使用 PyTorch来构建线性回归的实现
🧠 PyTorch线性回归完整案例讲解
一、整体结构
这个案例完整体现了 PyTorch 的四大核心步骤:
| 步骤 | 名称 | 对应代码模块 | 作用 |
|---|---|---|---|
| ① | 数据准备 | make_regression + DataLoader | 生成并批量加载训练数据 |
| ② | 模型构建 | nn.Linear() | 定义线性回归模型结构 |
| ③ | 定义损失和优化器 | nn.MSELoss + optim.SGD | 告诉模型“误差怎么算”和“如何改进” |
| ④ | 模型训练 | loss.backward() + optimizer.step() | 自动微分并更新参数 |
二、代码逐步讲解
🔹1. 导入依赖与配置
import torch
from torch import nn, optim
from torch.utils.data import TensorDataset, DataLoader
from sklearn.datasets import make_regression
import matplotlib.pyplot as plt
torch: 核心计算库(张量、梯度)nn: 网络模块(模型层、损失函数)optim: 优化器模块(SGD、Adam)DataLoader: 用于批量读取训练数据matplotlib: 画图可视化
plt.rcParams['font.sans-serif'] = ['SimHei'] # 支持中文
plt.rcParams['axes.unicode_minus'] = False # 显示负号
🔹2. 数据准备
def create_dataset():x, y, coef = make_regression(n_samples=100, # 样本数n_features=1, # 特征数(1维)noise=10, # 噪声强度bias=1.5, # 偏置项(截距)coef=True # 返回真实权重)x = torch.tensor(x, dtype=torch.float32)y = torch.tensor(y, dtype=torch.float32)return x, y, coef
✅ 输出结果:
x.shape = (100, 1)→ 每个样本一个特征y.shape = (100,)→ 每个样本一个目标值coef ≈ 真实权重 w_true
📘 作用:
生成线性模型:
y=wtruex+b+噪声y = w_{\text{true}}x + b + \text{噪声}y=wtruex+b+噪声
🔹3. 构建模型、损失函数、优化器
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')# 线性模型
model = nn.Linear(in_features=1, out_features=1).to(device)# 均方误差损失函数
criterion = nn.MSELoss().to(device)# 优化器:随机梯度下降
optimizer = optim.SGD(model.parameters(), lr=0.01)
📘 说明:
nn.Linear(1,1)就是 ( y = w x + b )criterion比较预测与真实差距
L=1n∑(ypred−ytrue)2L = \frac{1}{n}\sum (y_{\text{pred}} - y_{\text{true}})^2L=n1∑(ypred−ytrue)2optimizer.step()用梯度下降法更新参数。
🔹4. 数据加载器(批量训练)
data_loader = DataLoader(dataset=TensorDataset(x, y),batch_size=10,shuffle=True
)
📘 功能:
- 每次从数据集中随机取 10 条样本,构成一个 mini-batch;
- 每训练一个 epoch,会打乱样本顺序;
- 有助于加快收敛并减少过拟合。
🔹5. 模型训练核心循环
epochs = 100
loss_epoch = []for epoch in range(epochs):total_loss = 0.0train_sample = 0for train_x, train_y in data_loader:train_x, train_y = train_x.to(device), train_y.to(device)# 1️⃣ 前向传播y_pred = model(train_x)# 2️⃣ 计算损失loss = criterion(y_pred, train_y.reshape(-1, 1))# 3️⃣ 反向传播准备optimizer.zero_grad()# 4️⃣ 自动微分(计算梯度)loss.backward()# 5️⃣ 参数更新optimizer.step()# 记录损失total_loss += loss.item()train_sample += len(train_y)epoch_loss = total_loss / train_sampleloss_epoch.append(epoch_loss)
📘 每轮训练做的事情:
| 步骤 | 说明 | 对应代码 |
|---|---|---|
| 1 | 前向传播 | y_pred = model(train_x) |
| 2 | 计算损失 | loss = criterion(...) |
| 3 | 梯度清零 | optimizer.zero_grad() |
| 4 | 反向传播 | loss.backward() |
| 5 | 更新参数 | optimizer.step() |
🔹6. 可视化损失变化
plt.plot(range(epochs), loss_epoch)
plt.title('损失变化曲线')
plt.xlabel('训练轮数')
plt.ylabel('平均损失')
plt.grid()
plt.show()
📈 曲线逐渐下降表示:
模型参数在逐渐逼近真实的 ( w_{true}, b_{true} )。
🔹7. 可视化预测结果与真实函数对比
plt.scatter(x, y, label='原始数据', alpha=0.6)# 真实曲线
x_line = torch.linspace(x.min(), x.max(), 100)
y_true = x_line * coef + 1.5# 模型预测曲线
with torch.no_grad():y_pred = model(x_line.reshape(-1, 1))plt.plot(x_line, y_pred, label='模型拟合', color='red')
plt.plot(x_line, y_true, label='真实关系', color='green', linestyle='--')
plt.legend()
plt.title('线性回归拟合效果')
plt.show()
📊 结果说明:
- 红线:模型学到的 ( y = wx + b )
- 绿虚线:真实关系
- 蓝点:原始数据(带噪声)
若两条线几乎重合 → 模型成功学会真实规律 ✅
三、完整可运行版本 ✅
import torch
from torch import nn, optim
from torch.utils.data import TensorDataset, DataLoader
from sklearn.datasets import make_regression
import matplotlib.pyplot as pltplt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = Falsedef create_dataset():x, y, coef = make_regression(n_samples=100, n_features=1, noise=10, bias=1.5, coef=True)x = torch.tensor(x, dtype=torch.float32)y = torch.tensor(y, dtype=torch.float32)return x, y, coefx, y, coef = create_dataset()
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = nn.Linear(1, 1).to(device)
criterion = nn.MSELoss().to(device)
optimizer = optim.SGD(model.parameters(), lr=0.01)
data_loader = DataLoader(TensorDataset(x, y), batch_size=10, shuffle=True)epochs = 100
loss_epoch = []
for epoch in range(epochs):total_loss = 0.0total_sample = 0for x_batch, y_batch in data_loader:x_batch, y_batch = x_batch.to(device), y_batch.to(device)y_pred = model(x_batch)loss = criterion(y_pred, y_batch.view(-1, 1))optimizer.zero_grad()loss.backward()optimizer.step()total_loss += loss.item()total_sample += len(y_batch)loss_epoch.append(total_loss / total_sample)plt.plot(range(epochs), loss_epoch)
plt.title('损失变化曲线')
plt.xlabel('epoch')
plt.ylabel('平均损失')
plt.show()plt.scatter(x, y, label='原始数据', alpha=0.6)
x_line = torch.linspace(x.min(), x.max(), 100)
y_true = x_line * coef + 1.5
with torch.no_grad():y_pred = model(x_line.unsqueeze(1))
plt.plot(x_line, y_pred, label='模型拟合', color='red')
plt.plot(x_line, y_true, label='真实关系', color='green', linestyle='--')
plt.legend()
plt.show()
四、训练结束后可查看模型参数
print("训练得到的权重:", model.weight.item())
print("训练得到的偏置:", model.bias.item())
print("真实权重:", coef)
一般结果示例:
训练得到的权重: 92.8
训练得到的偏置: 1.48
真实权重: 93.1
✅ 表示模型成功学到了真实线性关系。

