PyTorch - 线性回归
PyTorch - 线性回归
Section titled “PyTorch - 线性回归”线性回归(Linear regression)是一种基础的监督机器学习(supervised machine learning)算法,用于模拟因变量(目标变量,target)与一个或多个自变量(预测变量或特征,predictors or features)之间的线性关系。在其最简单的形式(简单线性回归)中,我们尝试找到穿过数据点集的最佳拟合直线。
这种关系通过以下方程建模:
Y = wX + b其中 Y 是预测的目标值,X 是输入特征,w 是权重(直线的斜率),b 是偏置(y 轴截距)。我们的目标是找到最优的 w 和 b 值,以最小化预测的 Y 与实际目标值之间的差异。
这涉及两个关键概念:
- 成本函数(Cost Function):衡量模型表现好坏的函数。对于线性回归,通常使用均方误差(Mean Squared Error, MSE)。
- 梯度下降(Gradient Descent):一种优化算法,通过迭代调整模型参数(
w和b)沿着成本函数的梯度相反方向移动,从而最小化成本函数。
对于方程 Y = wX + b:
- ‘w’(权重或斜率)的值表示当 X 变化一个单位时,Y 变化多少。
- ‘b’(偏置或 y 轴截距)的值表示当 X 为 0 时,Y 的值。
- 训练的目标是找到 ‘w’ 和 ‘b’,使得直线 Y = wX + b 能够最好地拟合训练数据。
从图形上看,线性回归试图找到一条直线,使其尽可能紧密地穿过二维平面上绘制的所有数据点(对于简单线性回归)。
让我们使用 PyTorch 实现线性回归:
步骤 1:导入必要的库
Section titled “步骤 1:导入必要的库”我们将需要 torch 用于 PyTorch 功能,numpy 用于创建样本数据,以及 matplotlib 用于绘图。
import torchimport torch.nn as nnimport numpy as npimport matplotlib.pyplot as plt# For a slightly nicer plot style (optional)# import seaborn as sns# sns.set_style(style='whitegrid')# plt.rcParams["patch.force_edgecolor"] = True步骤 2:准备训练数据
Section titled “步骤 2:准备训练数据”让我们创建一些具有已知线性关系并添加一些噪声的合成数据。
# Define true parameters# 定义真实参数true_w = 2.0true_b = 3.0num_samples = 256
# Generate random x values# 生成随机 x 值X_numpy = np.random.rand(num_samples, 1).astype(np.float32)
# Generate y values based on y = w*x + b + noise# 根据 y = w*x + b + 噪声 生成 y 值noise = np.random.randn(num_samples, 1).astype(np.float32) * 0.2 # Smaller noisey_numpy = X_numpy * true_w + true_b + noise
# Convert NumPy arrays to PyTorch tensors# 将 NumPy 数组转换为 PyTorch 张量X_tensor = torch.from_numpy(X_numpy)y_tensor = torch.from_numpy(y_numpy)
# Optional: Plot the raw data# 可选:绘制原始数据# plt.figure(figsize=(8, 5))# plt.scatter(X_numpy, y_numpy, label='Original data', s=10)# plt.xlabel('x')# plt.ylabel('y')# plt.legend()# plt.show()步骤 3:使用 PyTorch 实现线性回归
Section titled “步骤 3:使用 PyTorch 实现线性回归”我们将使用 torch.nn.Module 定义一个简单的线性回归模型。
# Define the model# 定义模型class LinearRegressionModel(nn.Module): def __init__(self, input_dim, output_dim): super().__init__() # Modern Python 3 super() call # 现代 Python 3 的 super() 调用 self.linear = nn.Linear(input_dim, output_dim)
def forward(self, x): out = self.linear(x) return out
# Model parameters# 模型参数input_dim = 1 # Single feature# 单个特征output_dim = 1 # Single output value# 单个输出值
# Instantiate the model# 实例化模型model = LinearRegressionModel(input_dim, output_dim)
# Define loss function (Mean Squared Error)# 定义损失函数 (均方误差)criterion = nn.MSELoss()
# Define optimizer (Stochastic Gradient Descent)# 定义优化器 (随机梯度下降)learning_rate = 0.1optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
# Training loop# 训练循环epochs = 100for epoch in range(epochs): # Forward pass: Compute predicted y by passing x to the model # 前向传播:将 x 输入模型计算预测 y 值 predictions = model(X_tensor)
# Compute loss # 计算损失 loss = criterion(predictions, y_tensor)
# Backward pass: Zero gradients, perform backpropagation, and update weights # 反向传播:清零梯度,执行反向传播,更新权重 optimizer.zero_grad() # Clear previous gradients # 清除之前的梯度 loss.backward() # Compute gradients of loss w.r.t. model parameters # 计算损失相对于模型参数的梯度 optimizer.step() # Update model parameters # 更新模型参数
if (epoch + 1) % 10 == 0: # Get current learned parameters (w, b) # 获取当前学习到的参数 (w, b) # .item() gets the value as a Python number from a single-element tensor # .item() 从单个元素张量获取 Python 数字值 # .data gives access to the tensor without gradient tracking # .data 提供对张量的访问,不跟踪梯度 learned_w = model.linear.weight.data.item() learned_b = model.linear.bias.data.item() print(f'Epoch [{epoch+1}/{epochs}], Loss: {loss.item():.4f}, Learned w: {learned_w:.3f}, Learned b: {learned_b:.3f}')
# Plot the results after training# 训练后绘制结果def plot_fit(title="Fitted Line"): plt.figure(figsize=(10, 6)) plt.title(title) plt.scatter(X_numpy, y_numpy, s=15, label='Original data')
# Get predictions from the trained model # 从训练好的模型获取预测值 with torch.no_grad(): # Disable gradient calculation for inference # 推断时禁用梯度计算 predicted_values = model(X_tensor).numpy()
plt.plot(X_numpy, predicted_values, color='red', label='Fitted line') plt.xlabel('x (input)') plt.ylabel('y (target/predicted)') plt.legend() plt.grid(True) plt.show()
plot_fit('Linear Regression Fit After Training')
# You can also inspect the final learned parameters:# 你也可以查看最终学习到的参数:final_w = model.linear.weight.item()final_b = model.linear.bias.item()print(f'\nTrue w: {true_w}, True b: {true_b}')print(f'Learned w: {final_w:.4f}, Learned b: {final_b:.4f}')输出将首先在训练过程中按间隔打印损失值和学习到的参数。最后,它将显示一个包含原始数据点和 PyTorch 模型拟合的回归线的图。学习到的 ‘w’ 和 ‘b’ 应该接近用于生成数据的真实值 true_w 和 true_b。