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. 核心训练流程统一:前向传播 → 计算损失 → 反向传播(求梯度) → 更新参数。

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

相关推荐
微尘hjx44 分钟前
【ByteTrack 04】多轨迹算法ByteTrack改进点
算法·yolo·目标检测·目标跟踪·bytetrack·ultralytics·车跟踪
云和数据.ChenGuang1 小时前
Python 重写(Override)深度解析:从 MRO 到 super() 的完整机制
java·开发语言·人工智能·python·langchain·1024程序员节
西西木科技丨Shopify开发机构1 小时前
CalDigit TS4案例:AI产品图的Shopify整站接入与验收
人工智能·shopify·独立站
2601_965448872 小时前
AI视频制作:做系列节气民俗视频音色不统一,AI 音色克隆省事的方法
人工智能·机器学习·音视频
美狐美颜SDK开放平台2 小时前
视频美颜SDK试用DEMO阶段应该测试什么?直播APP接入实操指南
开发语言·人工智能·深度学习·音视频·美颜sdk·直播美颜sdk·第三方美颜sdk
HRaitest2 小时前
秋招技术岗招聘提效:三类 AI 招聘方案的技术底层与选型逻辑
大数据·人工智能·求职招聘·ai-native
天远数科2 小时前
零信任架构实战:基于天远企业股权变更构建自动化商业银行对公授信存续期股权异动与资产抽逃预警网关
运维·人工智能·架构·自动化
车软学堂2 小时前
从测试转开发,到底要补什么
网络·人工智能·python·功能测试·单片机·车载系统·自动化
海盗12343 小时前
AI 新闻日报 10-28:Atria Dawn 完整版开源、Cursor Agent SDK 转正、Genie 4 实时世界模型
人工智能·机器人·开源·人工智能aigc
志尊宝3 小时前
AI原生前端开发(035):AI时代的工程化最佳实践总结
人工智能·ai-native