PyTorch & Numpy 实现线性回归详解

PyTorch & Numpy 实现线性回归详解

线性回归是机器学习入门最经典的算法,核心是拟合出一条最优直线(高维场景为超平面),让模型预测值与真实值误差最小。本文分别使用 Numpy(手动梯度)PyTorch(自动求导) 实现梯度下降版线性回归,对比两种实现思路与差异。

一、线性回归核心原理

1. 模型公式

假设输入特征为 XXX,真实标签为 yyy,线性回归模型表达式:

y^=wX+b\hat{y} = wX + by^=wX+b

  • y^\hat{y}y^:模型预测值
  • www:权重参数
  • bbb:偏置项

2. 损失函数(均方误差 MSE)

使用均方误差 衡量预测值与真实值的差距,nnn 为样本总数:

MSE=1n∑i=1n(y^i−yi)2MSE = \frac{1}{n}\sum_{i=1}^{n}(\hat{y}_i - y_i)^2MSE=n1i=1∑n(y^i−yi)2

3. 梯度下降

通过梯度下降迭代更新参数 www 和 bbb,最小化损失函数。对损失函数求偏导得到梯度:

∂MSE∂w=2nXT(y^−y)\frac{\partial MSE}{\partial w} = \frac{2}{n}X^T(\hat{y}-y)∂w∂MSE=n2XT(y^−y)

∂MSE∂b=2n∑i=1n(y^i−yi)\frac{\partial MSE}{\partial b} = \frac{2}{n}\sum_{i=1}^{n}(\hat{y}_i - y_i)∂b∂MSE=n2i=1∑n(y^i−yi)

参数更新规则:

w=w−lr⋅∂MSE∂ww = w - lr \cdot \frac{\partial MSE}{\partial w}w=w−lr⋅∂w∂MSE

b=b−lr⋅∂MSE∂bb = b - lr \cdot \frac{\partial MSE}{\partial b}b=b−lr⋅∂b∂MSE

lrlrlr 为学习率,控制参数更新步长。


二、Numpy 手动实现线性回归

Numpy 基于纯数值计算,需要手动推导并计算梯度,适合理解线性回归底层数学逻辑。

1. 完整代码

python 复制代码
import numpy as np
import matplotlib.pyplot as plt

# 1. 设置随机种子,保证实验结果可复现
np.random.seed(42)

# 2. 生成模拟数据集:真实关系 y = 2x + 3,叠加高斯噪声
X = np.random.rand(100, 1)  # 100个样本,1个特征
y = 2 * X + 3 + np.random.randn(100, 1) * 0.1

# 3. 初始化参数 w(权重)、b(偏置)
w = np.random.randn(1, 1)
b = np.random.randn(1)

# 4. 定义预测函数
def predict(X, w, b):
    return np.dot(X, w) + b

# 5. 定义均方误差损失函数
def compute_loss(y_pred, y_true):
    return np.mean((y_pred - y_true) ** 2)

# 6. 超参数设置
learning_rate = 0.1
epochs = 1000  # 迭代轮数

# 7. 梯度下降训练
for epoch in range(epochs):
    # 前向传播:计算预测值
    y_pred = predict(X, w, b)
    # 计算损失
    loss = compute_loss(y_pred, y)
    
    # 手动计算梯度
    dw = (2 / len(X)) * np.dot(X.T, (y_pred - y))
    db = (2 / len(X)) * np.sum(y_pred - y)
    
    # 更新参数
    w -= learning_rate * dw
    b -= learning_rate * db
    
    # 每100轮打印损失
    if epoch % 100 == 0:
        print(f"Epoch {epoch}, Loss: {loss:.4f}")

# 输出最终训练参数
print(f"\n【Numpy 训练结果】w = {w[0][0]:.4f}, b = {b[0]:.4f}")

# 8. 可视化原始数据 + 拟合直线
y_pred_final = predict(X, w, b)
plt.scatter(X, y, label="True Data")
plt.plot(X, y_pred_final, color="red", label="Fitted Line")
plt.xlabel("X")
plt.ylabel("y")
plt.title("Linear Regression (Numpy)")
plt.legend()
plt.show()

2. 运行说明

  1. 模拟数据基于公式 y=2x+3y=2x+3y=2x+3 生成,叠加微小噪声;
  2. 全程手动计算梯度、更新参数,无框架封装;
  3. 训练完成后参数会无限逼近真实值 w=2,b=3w=2,b=3w=2,b=3。

三、PyTorch 实现线性回归

PyTorch 依托张量(Tensor) 计算,内置自动求导、网络层、损失函数与优化器,无需手动计算梯度,是深度学习主流实现方式。

1. 完整代码

python 复制代码
import torch
import torch.nn as nn
import matplotlib.pyplot as plt
import numpy as np

# 复用上方 Numpy 生成的数据集
np.random.seed(42)
X = np.random.rand(100, 1)
y = 2 * X + 3 + np.random.randn(100, 1) * 0.1

# 1. 转换为 PyTorch 浮点张量
torch.manual_seed(42)
X_tensor = torch.from_numpy(X).float()
y_tensor = torch.from_numpy(y).float()

# 2. 定义线性回归模型:输入特征1维,输出特征1维
model = nn.Linear(in_features=1, out_features=1)

# 3. 定义损失函数 & 优化器
criterion = nn.MSELoss()  # 均方误差损失
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)  # 随机梯度下降

# 4. 模型训练
epochs = 1000
for epoch in range(epochs):
    # 前向传播
    y_pred = model(X_tensor)
    # 计算损失
    loss = criterion(y_pred, y_tensor)
    
    # 反向传播 + 参数更新
    optimizer.zero_grad()  # 清空历史梯度(必写)
    loss.backward()        # 自动反向传播求梯度
    optimizer.step()      # 根据梯度更新参数
    
    # 每100轮打印损失
    if epoch % 100 == 0:
        print(f"Epoch {epoch}, Loss: {loss.item():.4f}")

# 提取训练后的权重与偏置
w_final = model.weight.item()
b_final = model.bias.item()
print(f"\n【PyTorch 训练结果】w = {w_final:.4f}, b = {b_final:.4f}")

# 5. 可视化拟合结果
# detach() 分离梯度,再转 Numpy 数组绘图
y_pred_tensor = model(X_tensor)
y_pred_np = y_pred_tensor.detach().numpy()

plt.scatter(X, y, label="True Data")
plt.plot(X, y_pred_np, color="red", label="Fitted Line")
plt.xlabel("X")
plt.ylabel("y")
plt.title("Linear Regression (PyTorch)")
plt.legend()
plt.show()

2. 关键注意点

  1. 数据转换 :Numpy 数组需通过 torch.from_numpy() 转为张量,并指定浮点类型;
  2. 梯度清空optimizer.zero_grad() 必须执行,否则梯度会累加;
  3. 自动求导loss.backward() 自动完成梯度计算,无需手动推导;
  4. 张量转 Numpy :带梯度的张量需先用 .detach() 分离计算图,再调用 .numpy()

四、两种实现方式对比

维度 Numpy 实现 PyTorch 实现
梯度计算 手动推导公式计算梯度 框架自动求导
代码复杂度 偏繁琐,需手写前向、损失、梯度 简洁,复用内置层/损失/优化器
算力支持 仅 CPU 计算,无 GPU 加速 支持 CPU/GPU 一键切换
适用场景 学习数学原理、基础数值计算 深度学习模型开发、工程落地
扩展性 复杂模型代码冗余、易出错 轻松扩展为深层神经网络

五、总结

  1. Numpy 版本 适合吃透线性回归的数学原理、梯度下降的底层逻辑,是打基础的首选;
  2. PyTorch 版本 封装了大量底层细节,开发效率更高,是工业界和深度学习学习的主流方案;
  3. 两种实现最终拟合效果一致,参数都会收敛至真实值 w≈2,b≈3w \approx 2,b \approx 3w≈2,b≈3;
  4. 核心训练流程统一:前向传播 → 计算损失 → 反向传播(求梯度) → 更新参数

个人能力有限,有问题随时交流~

相关推荐
papership1 小时前
【入门级-数据结构-1、线性结构:链 表(单链表、双向链表、循环链表 )】
数据结构·算法·链表
董董灿是个攻城狮1 小时前
AI 会吃了天涯吗?
人工智能
天风之翼1 小时前
AI 模型部署从入门到生产 —— ONNX 转换、TensorRT 加速、推理服务搭建
人工智能
A15362551 小时前
从 AI 零引用到高转化:GEO 落地价值解析
人工智能
Omics Pro1 小时前
P4医学4大支柱需绑定4大数字技术才可落地
人工智能·python·算法·机器学习·plotly
csdn_aspnet1 小时前
C++ 霍尔分区算法(Hoare‘s Partition Algorithm)
数据结构·c++·算法
段一凡-华北理工大学1 小时前
工业领域的Hadoop架构学习~系列文章07:Spark内存计算引擎
大数据·人工智能·hadoop·学习·架构·高炉炼铁·高炉炼铁智能化
机器学习是魔鬼1 小时前
在矩池云上开箱即用Energy Forecasting:能源电力电价预测实战指南
人工智能·python·机器学习