**«Из-за курицы я выгнала мужа и ни о чём не жалею»**
В тот день я была на грани. Утро началось с уборки гостиной, развешивания белья, сбора и# PyTorch实现线性回归
## 1. 目标
1. 实现线性回归模型具体包括使用 `pytorch` 实现线性回归模型的理论部分和代码部分,使用 `nn.Linear«optim.SGD` 等实现线性回归模型
2. 了解 `pytorch` 实现模型的基本流程,包括:**数据处理****构建模型****定义损失函数****定义优化器****训练模型****模型保存与加载**等
3. 掌握 `pytorch` 的 `tensor` 和 `autograd` 机制,能够使用 `pytorch` 实现简单的模型
## 2. 线性回归的理论基础
### 2.1 线性回归的基本概念
线性回归是一种**监督学习**算法,它假设输入变量 ($X$) 和输出变量 ($Y$) 之间存在**线性关系**线性回归的目标是找到最佳的线性模型,即最佳的**权重** ($W$) 和**偏置** ($b$),以最小化**预测值**和**真实值**之间的**误差**
数学表达式为:
$$
\hat{Y} = XW + b
$$
其中:
— $\hat{Y}$ 是预测值
— $X$ 是输入变量
— $W$ 是权重
— $b$ 是偏置
### 2.2 损失函数
为了衡量模型的预测效果,我们使用**损失函数**(Loss Function)在线性回归中,常用的损失函数是**均方误差**(Mean Squared Error, MSE),其数学表达式为:
$$
L = \frac{1}{n} \sum_{i=1}^{n} (y_i — \hat{y}_i)^2
$$
其中:
— $n$ 是样本数量
— $y_i$ 是第 $i$ 个样本的真实值
— $\hat{y}_i$ 是第 $i$ 个样本的预测值
### 2.3 优化方法
为了最小化损失函数,我们使用**梯度下降**(Gradient Descent)算法梯度下降通过**迭代**的方式**更新**权重和偏置,以逐步减小损失函数的值
权重和偏置的更新公式为:
$$
W = W — \alpha \frac{\partial L}{\partial W}
$$
$$
b = b — \alpha \frac{\partial L}{\partial b}
$$
其中:
— $\alpha$ 是**学习率**(Learning Rate),控制每次更新的步长
— $\frac{\partial L}{\partial W}$ 和 $\frac{\partial L}{\partial b}$ 分别是损失函数对权重和偏置的**偏导数**
## 3. PyTorch 实现线性回归
### 3.1 导入必要的库
首先,我们需要导入 `PyTorch` 和其他必要的库
«`python
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
import matplotlib.pyplot as plt
from torch.utils.data import TensorDataset, DataLoader
«`
### 3.2 生成数据
为了演示线性回归,我们首先生成一些**模拟数据**假设真实模型为 $y = 2x + 1 + \epsilon$,其中 $\epsilon$ 是噪声
«`python
# 设置随机种子以保证实验的可重复性
torch.manual_seed(42)
# 生成输入数据
x = torch.linspace(0, 10, 100).reshape(-1, 1)
# 生成真实模型(带噪声)
true_w = 2
true_b = 1
y = true_w * x + true_b + torch.randn(x.size()) * 2
# 可视化数据
plt.scatter(x.numpy(), y.numpy(), label=’Data’)
plt.plot(x.numpy(), (true_w * x + true_b).numpy(), ‘r’, label=’True Model’)
plt.xlabel(‘x’)
plt.ylabel(‘y’)
plt.legend()
plt.show()
«`
### 3.3 数据加载
在训练模型之前,我们需要将数据划分为**训练集**和**测试集**,并创建 `DataLoader` 以便于批量加载数据
«`python
# 划分训练集和测试集
train_size = int(0.8 * len(x))
test_size = len(x) — train_size
x_train, x_test = torch.split(x, [train_size, test_size])
y_train, y_test = torch.split(y, [train_size, test_size])
# 创建数据集和数据Loader
train_dataset = TensorDataset(x_train, y_train)
test_dataset = TensorDataset(x_test, y_test)
batch_size = 10
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)
«`
### 3.4 定义线性回归模型
在 `PyTorch` 中,我们可以通过继承 `nn.Module` 来定义自己的模型线性回归模型的实现如下:
«`python
class LinearRegression(nn.Module):
def __init__(self, input_dim, output_dim):
super(LinearRegression, self).__init__()
self.linear = nn.Linear(input_dim, output_dim)
def forward(self, x):
return self.linear(x)
«`
### 3.5 实例化模型损失函数和优化器
接下来,我们实例化模型选择损失函数(MSE)和优化器(SGD)
«`python
# 实例化模型
input_dim = 1
output_dim = 1
model = LinearRegression(input_dim, output_dim)
# 定义损失函数
criterion = nn.MSELoss()
# 定义优化器
learning_rate = 0.01
optimizer = optim.SGD(model.parameters(), lr=learning_rate)
«`
### 3.6 训练模型
现在,我们可以开始训练模型了训练过程包括**前向传播****计算损失****反向传播**和**参数更新**
«`python
# 训练参数
num_epochs = 100
loss_history = []
# 训练模型
for epoch in range(num_epochs):
for batch_x, batch_y in train_loader:
# 前向传播
outputs = model(batch_x)
loss = criterion(outputs, batch_y)
# 反向传播和优化
optimizer.zero_grad()
loss.backward()
optimizer.step()
# 记录损失
loss_history.append(loss.item())
if (epoch + 1) % 10 == 0:
print(f’Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}’)
# 可视化训练损失
plt.plot(loss_history)
plt.xlabel(‘Epoch’)
plt.ylabel(‘Loss’)
plt.title(‘Training Loss’)
plt.show()
«`
### 3.7 模型评估
训练完成后,我们需要评估模型在测试集上的表现
«`python
# 测试模型
model.eval()
with torch.no_grad():
test_outputs = model(x_test)
test_loss = criterion(test_outputs, y_test)
print(f’Test Loss: {test_loss.item():.4f}’)
# 可视化预测结果
plt.scatter(x_test.numpy(), y_test.numpy(), label=’Test Data’)
plt.plot(x_test.numpy(), test_outputs.numpy(), ‘r’, label=’Predicted Model’)
plt.xlabel(‘x’)
plt.ylabel(‘y’)
plt.legend()
plt.show()
«`
### 3.8 保存和加载模型
训练好的模型可以保存到磁盘,以便后续使用
«`python
# 保存模型
torch.save(model.state_dict(), ‘linear_regression_model.pth’)
# 加载模型
loaded_model = LinearRegression(input_dim, output_dim)
loaded_model.load_state_dict(torch.load(‘linear_regression_model.pth’))
loaded_model.eval()
«`
## 4. 完整代码
以下是完整的代码示例:
«`python
import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
import matplotlib.pyplot as plt
from torch.utils.data import TensorDataset, DataLoader
# 设置随机种子
torch.manual_seed(42)
# 生成数据
x = torch.linspace(0, 10, 100).reshape(-1, 1)
true_w = 2
true_b = 1
y = true_w * x + true_b + torch.randn(x.size()) * 2
# 可视化数据
plt.scatter(x.numpy(), y.numpy(), label=’Data’)
plt.plot(x.numpy(), (true_w * x + true_b).numpy(), ‘r’, label=’True Model’)
plt.xlabel(‘x’)
plt.ylabel(‘y’)
plt.legend()
plt.show()
# 划分训练集和测试集
train_size = int(0.8 * len(x))
test_size = len(x) — train_size
x_train, x_test = torch.split(x, [train_size, test_size])
y_train, y_test = torch.split(y, [train_size, test_size])
# 创建DataLoader
train_dataset = TensorDataset(x_train, y_train