从零手写线性回归模型:PyTorch 实现深度学习入门教程

news2025/1/8 11:03:23

系列文章目录

01-PyTorch新手必看:张量是什么?5 分钟教你快速创建张量!
02-张量运算真简单!PyTorch 数值计算操作完全指南
03-Numpy 还是 PyTorch?张量与 Numpy 的神奇转换技巧
04-揭秘数据处理神器:PyTorch 张量拼接与拆分实用技巧
05-深度学习从索引开始:PyTorch 张量索引与切片最全解析
06-张量形状任意改!PyTorch reshape、transpose 操作超详细教程
07-深入解读 PyTorch 张量运算:6 大核心函数全面解析,代码示例一步到位!
08-自动微分到底有多强?PyTorch 自动求导机制深度解析
09-从零手写线性回归模型:PyTorch 实现深度学习入门教程
10-PyTorch 框架实现线性回归:从数据预处理到模型训练全流程


文章目录

  • 系列文章目录
  • 前言
  • 一、构建数据集
    • 1.1 示例代码
    • 1.2 示例输出
  • 二、构建假设函数
    • 2.1 示例代码
  • 三、损失函数
    • 3.1 示例代码
  • 四、优化方法
    • 4.1 示例代码
  • 五、训练函数
    • 5.1 示例代码
    • 5.2 绘制结果
  • 六、调用训练函数
    • 6.1 示例输出
  • 七、小结
    • 7.1 完整代码


前言

在机器学习的学习过程中,我们接触过 线性回归 模型,并使用过如 Scikit-learn 这样的工具来快速实现。但在本文中,将深入理解线性回归的核心思想,并使用 PyTorch 从零开始手动实现一个线性回归模型。这包括:

  1. 数据集的构建;
  2. 假设函数的定义;
  3. 损失函数的设计;
  4. 梯度下降优化方法的实现;
  5. 模型训练和损失变化的可视化。

一、构建数据集

线性回归需要一个简单的线性数据集,我们将通过sklearn.datasets.make_regression 方法生成。

1.1 示例代码

import torch
from sklearn.datasets import make_regression
import matplotlib.pyplot as plt
import random

def create_dataset():
    """
    使用 make_regression 生成线性回归数据集,并转换为 PyTorch 张量。
    """
    x, y, coef = make_regression(
        n_samples=120,  # 样本数量,即数据点个数
        n_features=1,   # 每个样本只有一个特征
        noise=15,       # 添加噪声,模拟真实场景
        coef=True,      # 是否返回生成数据的真实系数
        bias=12.0,      # 偏置值,即 y = coef * x + bias
        random_state=42 # 随机种子,保证结果一致性
    )

    # 转换为 PyTorch 张量
    x = torch.tensor(x, dtype=torch.float32)  # 输入特征张量
    y = torch.tensor(y, dtype=torch.float32).reshape(-1, 1)  # 输出标签张量转换为二维

    return x, y, coef  # 返回输入特征张量、输出标签张量和真实系数

# 数据加载器,用于批量获取数据
def data_loader(x, y, batch_size):
    """
    数据加载器,按批次随机提取训练数据。
    参数:
        x: 输入特征张量
        y: 输出标签张量
        batch_size: 批量大小
    """
    data_len = len(y)  # 数据集长度
    indices = list(range(data_len))  # 创建索引列表
    random.shuffle(indices)  # 随机打乱索引,保证数据随机性
    num_batches = data_len // batch_size  # 计算批次数

    for i in range(num_batches):  # 遍历每个批次
        start = i * batch_size  # 当前批次起始索引
        end = start + batch_size  # 当前批次结束索引

        # 提取当前批次的数据
        batch_x = x[indices[start:end]]  # 当前批次输入
        batch_y = y[indices[start:end]]  # 当前批次输出

        yield batch_x, batch_y  # 返回当前批次数据

1.2 示例输出

运行 create_dataset 后的数据分布为线性趋势,同时包含噪声点。例如:

x:
tensor([[-1.3282],
        [ 0.1941],
        [ 0.8944],
        ...])
y:
tensor([-40.2345,  15.2934,  45.1282, ...])
coef:
tensor([35.0])

二、构建假设函数

线性回归的假设函数可以表示为:
y ​ = w ⋅ x + b y ^ ​ =w⋅x+b y=wx+b
其中,( w ) 是权重,( b ) 是偏置。使用 PyTorch 张量定义这些参数。

2.1 示例代码

# 模型参数初始化
w = torch.tensor(0.5, requires_grad=True, dtype=torch.float32)  # 权重
b = torch.tensor(0.0, requires_grad=True, dtype=torch.float32)  # 偏置

# 假设函数
def linear_regression(x):
    return w * x + b

三、损失函数

我们使用均方误差(MSE)作为损失函数,其公式为:

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

3.1 示例代码

def square_loss(y_pred, y_true):
    return (y_pred - y_true) ** 2

四、优化方法

为了更新模型参数 ( w ) 和 ( b ),使用 随机梯度下降(SGD) 算法,其更新公式为:

w = w − η ⋅ ∂ L ∂ w , b = b − η ⋅ ∂ L ∂ b w = w - \eta \cdot \frac{\partial L}{\partial w}, \quad b = b - \eta \cdot \frac{\partial L}{\partial b} w=wηwL,b=bηbL
其中,η 是学习率。

4.1 示例代码

def sgd(lr=0.01, batch_size=16):
    # 更新权重和偏置
    w.data = w.data - lr * w.grad.data / batch_size
    b.data = b.data - lr * b.grad.data / batch_size

五、训练函数

将前面定义的所有组件组合在一起,构建训练函数,通过多个 epoch 来优化模型。

5.1 示例代码

# 模型训练函数
def train():
    """
    训练线性回归模型。
    """
    # 加载数据集
    x, y, coef = create_dataset()

    # 设置训练参数
    epochs = 50  # 训练轮次
    learning_rate = 0.01  # 学习率
    batch_size = 16  # 每批次的数据大小

    # 使用 PyTorch 内置优化器
    optimizer = torch.optim.SGD([w, b], lr=learning_rate)

    epoch_loss = []  # 用于记录每轮的平均损失

    for epoch in range(epochs):  # 遍历每一轮
        total_loss = 0.0  # 累计损失

        for batch_x, batch_y in data_loader(x, y, batch_size):  # 遍历每个批次
            # 使用假设函数计算预测值
            y_pred = linear_regression(batch_x)

            # 计算损失
            loss = square_loss(y_pred, batch_y)  # 当前批次的平均损失
            total_loss += loss.item()  # 累加总损失

            # 梯度清零
            optimizer.zero_grad()

            # 反向传播计算梯度
            loss.backward()

            # 使用随机梯度下降更新参数
            optimizer.step()

        # 记录当前轮次的平均损失
        epoch_loss.append(total_loss / len(y))
        print(f"轮次 {epoch + 1}, 平均损失: {epoch_loss[-1]:.4f}")  # 打印损失

    # 可视化训练结果
    plot_results(x, y, coef, epoch_loss)

5.2 绘制结果

# 可视化训练结果
def plot_results(x, y, coef, epoch_loss):
    """
    绘制训练结果,包括拟合直线和损失变化曲线。
    参数:
        x: 输入特征张量
        y: 输出标签张量
        coef: 数据生成时的真实权重
        epoch_loss: 每轮的平均损失
    """
    # 绘制训练数据点和拟合直线
    plt.scatter(x.numpy(), y.numpy(), label='数据点', alpha=0.7)  # 数据点
    x_line = torch.linspace(x.min(), x.max(), 100).unsqueeze(1)  # 连续 x 值
    y_pred = linear_regression(x_line).detach().numpy()  # 模型预测值
    coef_tensor = torch.tensor(coef, dtype=torch.float32)  # 将 coef 转换为 PyTorch 张量
    y_true = coef_tensor * x_line + 12.0  # 真实直线(生成数据时的公式)
    plt.plot(x_line.numpy(), y_pred, label='拟合直线', color='red')  # 拟合直线
    plt.plot(x_line.numpy(), y_true.numpy(), label='真实直线', color='green')  # 真实直线
    plt.legend()
    plt.grid()
    plt.title('线性回归拟合')
    plt.xlabel('特征值 X')
    plt.ylabel('标签值 Y')
    plt.show()

    # 绘制损失变化曲线
    plt.plot(range(len(epoch_loss)), epoch_loss)
    plt.title('损失变化曲线')
    plt.xlabel('轮次')
    plt.ylabel('损失')
    plt.grid()
    plt.show()

六、调用训练函数

在主程序中调用 train 函数,训练模型并观察输出。

if __name__ == "__main__":
    train()

6.1 示例输出

  • 拟合直线:
    在这里插入图片描述
  • 损失变化曲线:
    在这里插入图片描述

七、小结

本文通过手动实现线性回归模型,完成了以下内容:

  1. 构建数据集并设计数据加载器;
  2. 定义线性假设函数;
  3. 设计均方误差损失函数;
  4. 实现随机梯度下降优化方法;
  5. 训练模型并可视化损失变化和拟合直线。

7.1 完整代码

import torch
from sklearn.datasets import make_regression
import matplotlib.pyplot as plt
import random

# 设置 Matplotlib 支持中文
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False   # 用来正常显示负号

# 数据集生成函数
def create_dataset():
    """
    使用 make_regression 生成线性回归数据集,并转换为 PyTorch 张量。
    """
    x, y, coef = make_regression(
        n_samples=120,  # 样本数量,即数据点个数
        n_features=1,   # 每个样本只有一个特征
        noise=15,       # 添加噪声,模拟真实场景
        coef=True,      # 是否返回生成数据的真实系数
        bias=12.0,      # 偏置值,即 y = coef * x + bias
        random_state=42 # 随机种子,保证结果一致性
    )

    # 转换为 PyTorch 张量
    x = torch.tensor(x, dtype=torch.float32)  # 输入特征张量
    y = torch.tensor(y, dtype=torch.float32).reshape(-1, 1)  # 输出标签张量转换为二维

    return x, y, coef  # 返回输入特征张量、输出标签张量和真实系数

# 数据加载器,用于批量获取数据
def data_loader(x, y, batch_size):
    """
    数据加载器,按批次随机提取训练数据。
    参数:
        x: 输入特征张量
        y: 输出标签张量
        batch_size: 批量大小
    """
    data_len = len(y)  # 数据集长度
    indices = list(range(data_len))  # 创建索引列表
    random.shuffle(indices)  # 随机打乱索引,保证数据随机性
    num_batches = data_len // batch_size  # 计算批次数

    for i in range(num_batches):  # 遍历每个批次
        start = i * batch_size  # 当前批次起始索引
        end = start + batch_size  # 当前批次结束索引

        # 提取当前批次的数据
        batch_x = x[indices[start:end]]  # 当前批次输入
        batch_y = y[indices[start:end]]  # 当前批次输出

        yield batch_x, batch_y  # 返回当前批次数据

# 模型参数初始化
w = torch.tensor(0.5, requires_grad=True, dtype=torch.float32)  # 权重,初始值为 0.5
b = torch.tensor(0.0, requires_grad=True, dtype=torch.float32)  # 偏置,初始值为 0

# 线性假设函数
def linear_regression(x):
    """
    线性回归假设函数。
    参数:
        x: 输入特征张量
    返回:
        模型预测值
    """
    return w * x + b  # 线性模型公式

# 损失函数(均方误差)
def square_loss(y_pred, y_true):
    """
    均方误差损失函数。
    参数:
        y_pred: 模型预测值
        y_true: 数据真实值
    返回:
        每个样本的平方误差
    """
    return ((y_pred - y_true) ** 2).mean()  # 返回均方误差

# 模型训练函数
def train():
    """
    训练线性回归模型。
    """
    # 加载数据集
    x, y, coef = create_dataset()

    # 设置训练参数
    epochs = 50  # 训练轮次
    learning_rate = 0.01  # 学习率
    batch_size = 16  # 每批次的数据大小

    # 使用 PyTorch 内置优化器
    optimizer = torch.optim.SGD([w, b], lr=learning_rate)

    epoch_loss = []  # 用于记录每轮的平均损失

    for epoch in range(epochs):  # 遍历每一轮
        total_loss = 0.0  # 累计损失

        for batch_x, batch_y in data_loader(x, y, batch_size):  # 遍历每个批次
            # 使用假设函数计算预测值
            y_pred = linear_regression(batch_x)

            # 计算损失
            loss = square_loss(y_pred, batch_y)  # 当前批次的平均损失
            total_loss += loss.item()  # 累加总损失

            # 梯度清零
            optimizer.zero_grad()

            # 反向传播计算梯度
            loss.backward()

            # 使用随机梯度下降更新参数
            optimizer.step()

        # 记录当前轮次的平均损失
        epoch_loss.append(total_loss / len(y))
        print(f"轮次 {epoch + 1}, 平均损失: {epoch_loss[-1]:.4f}")  # 打印损失

    # 可视化训练结果
    plot_results(x, y, coef, epoch_loss)

# 可视化训练结果
def plot_results(x, y, coef, epoch_loss):
    """
    绘制训练结果,包括拟合直线和损失变化曲线。
    参数:
        x: 输入特征张量
        y: 输出标签张量
        coef: 数据生成时的真实权重
        epoch_loss: 每轮的平均损失
    """
    # 绘制训练数据点和拟合直线
    plt.scatter(x.numpy(), y.numpy(), label='数据点', alpha=0.7)  # 数据点
    x_line = torch.linspace(x.min(), x.max(), 100).unsqueeze(1)  # 连续 x 值
    y_pred = linear_regression(x_line).detach().numpy()  # 模型预测值
    coef_tensor = torch.tensor(coef, dtype=torch.float32)  # 将 coef 转换为 PyTorch 张量
    y_true = coef_tensor * x_line + 12.0  # 真实直线(生成数据时的公式)
    plt.plot(x_line.numpy(), y_pred, label='拟合直线', color='red')  # 拟合直线
    plt.plot(x_line.numpy(), y_true.numpy(), label='真实直线', color='green')  # 真实直线
    plt.legend()
    plt.grid()
    plt.title('线性回归拟合')
    plt.xlabel('特征值 X')
    plt.ylabel('标签值 Y')
    plt.show()

    # 绘制损失变化曲线
    plt.plot(range(len(epoch_loss)), epoch_loss)
    plt.title('损失变化曲线')
    plt.xlabel('轮次')
    plt.ylabel('损失')
    plt.grid()
    plt.show()


# 调用训练函数
if __name__ == "__main__":
    train()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2273168.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【python】matplotlib(radar chart)

文章目录 1、功能描述和原理介绍2、代码实现3、效果展示4、完整代码5、多个雷达图绘制在一张图上6、参考 1、功能描述和原理介绍 基于 matplotlib 实现雷达图的绘制 一、雷达图的基本概念 雷达图(Radar Chart),也被称为蛛网图或星型图&…

数据库环境安装(day1)

网址:MySQL 下载(环境准备): (2-5点击此处,然后选择合适的版本) 1.linux在线YUM仓库 下载/安装: wget https://repo.mysql.com//mysql84-community-release-el9-1.noarch.rpm rpm -i https://r…

Fabric链码部署测试

参考链接:运行 Fabric 应用程序 — Hyperledger Fabric Docs 主文档 (hyperledger-fabric.readthedocs.io) (2)fabric2.4.3部署运行自己的链码 - 知乎 (zhihu.com) Fabric2.0测试网络部署链码 - 辉哥哥~ - 博客园 (cnblogs.com) 1.启动测试…

数据结构与算法之二叉树: LeetCode 107. 二叉树的层序遍历 II (Ts版)

二叉树的层序遍历 II https://leetcode.cn/problems/binary-tree-level-order-traversal-ii/description/ 描述 给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历&a…

Python插件化开发实战:开发个图片浏览器

在本篇教程中,我将详细介绍如何使用Python开发一个基于插件架构的图片浏览器。这个项目将展示如何实现插件系统、如何处理图片显示,以及如何使用wxPython构建GUI界面。 “C:\pythoncode\pythonplugin\your_project\main_app.py” 项目概述 我们将开发一个具有以下…

根据python代码自动生成类图的实现方法[附带python源码]

概述 利用python库抽象语法树(AST)和类图描述语言(PlantUML),实现自动将python代码生成类图的目的。 环境 windowsvscodepythonplantuml ✒️网上好像大部分都是用Pyreverse库来实现的,但是我实际测试发现只能在一个文件中才能行,当然应该有解决方法…

下载b站高清视频

需要使用的edge上的一个扩展插件,所以选择使用edge浏览器。 1、在edge浏览器上下载 强力视频下载合并 扩展插件 2、在edge上打开b站,登录自己账号(登录后才能下载到高清!!)。打开一个视频,选择自…

flutter 专题二十四 Flutter性能优化在携程酒店的实践

Flutter性能优化在携程酒店的实践 一 、前言 携程酒店业务使用Flutter技术开发的时间快接近两年,这期间有列表页、详情页、相册页等页面使用了Flutter技术栈进行了跨平台整合,大大提高了研发效率。在开发过程中,也遇到了一些性能相关问题和…

UE5 打包要点

------------------------- 1、需要环境 win sdk ,大约3G VS,大约10G 不安装就无法打包,就是这么简单。 ----------------------- 2、打包设置 编译类型,开发、调试、发行 项目设置-地图和模式,默认地图 项目…

vulnhub靶场【DC系列】之5

前言 靶机:DC-5,IP地址为192.168.10.4 攻击:kali,IP地址为192.168.10.2 都采用VMWare,网卡为桥接模式 对于文章中涉及到的靶场以及工具,我放置网盘中https://pan.quark.cn/s/2fcf53ade985 主机发现 使用…

双模态视觉特征流用于医学报告生成|文献速递-视觉大模型医疗图像应用

Title 题目 Dual-modality visual feature flow for medical report generation 双模态视觉特征流用于医学报告生成 01 文献速递介绍 医学报告生成是一项新兴的跨模态文本生成任务(X. Zeng et al., 2020;Najdenkoska et al., 2022;Li et…

基于Fluent和深度学习算法驱动的流体力学计算与应用

物理模型与深度学习的融合:研究如何将传统的物理模型与深度学习算法相结合,以提高流体力学问题的预测准确性和计算效率。复杂流动模拟:利用深度学习技术对复杂流动现象进行模拟和分析,包括湍流、多相流、非牛顿流体等,…

记PasteSpider部署工具的Windows.IIS版本开发过程之草稿-动态表单(2)

接1的内容,那么有这么一个需求! 需求分析 需要修改某一个配置的时候 1.从对应的api中读取消息,消息内容为Json格式的 2.基于当前的Json渲染成表单提供给管理端的客户呈现 3.管理端的用户可以基于这个表单的内容进行修改,然后提交…

pycharm-pyspark 环境安装

1、环境准备:java、scala、pyspark、python-anaconda、pycharm vi ~/.bash_profile export SCALA_HOME/Users/xunyongsun/Documents/scala-2.13.0 export PATH P A T H : PATH: PATH:SCALA_HOME/bin export SPARK_HOME/Users/xunyongsun/Documents/spark-3.5.4-bin…

Clisoft SOS设置Workarea

Clisoft SOS设置Workarea 本人也是刚刚接触这个软件,可能有些方面不够完善,欢迎大佬指点。 这里就不演示创建创建Server和Project,可以参考Clisoft SOS设置Server和Project 创建Workarea 创建好目录并设置好权限 # 创建组 [bhlumaster ~]$…

数据结构:LinkedList与链表—无头双向链表(二)

目录 一、什么是LinkedList? 二、LinkedList的模拟实现 1、display()方法 2、addFirst(int data)方法 3、addLast(int data)方法 4、addIndex(int index,int data)方法 5、contains(int key)方法 6、remove(int key)方法 7、removeAllKey(int key)方法 8、…

基于SpringBoot实现的保障性住房管理系统

🥂(❁◡❁)您的点赞👍➕评论📝➕收藏⭐是作者创作的最大动力🤞 💖📕🎉🔥 支持我:点赞👍收藏⭐️留言📝欢迎留言讨论 🔥🔥&…

【Linux】硬链接和软连接(符号连接)

目录 硬链接 软连接 硬链接和软连接的区别 硬链接 ln根据linux系统分配给文件inode(ls -li)进行建立,没办法跨越文件系统 格式:ln 被链接的文件(源文件) 生成的链接文件(目标文件) 1) 硬链接的属性 - 相当于生成一个副本 起别名 2) 修改内容都变化…

多目标优化算法——基于聚类的不规则Pareto前沿多目标优化自适应进化算法(CA-MOEA)

基于聚类的不规则Pareto前沿多目标优化自适应进化算法(CA-MOEA) 一、算法简介 简介: 现有的多目标进化算法(moea)在具有规则Pareto前沿且Pareto最优解在目标空间上连续分布的多目标优化问题(MOPs&#xff…

基于SpringBoot的乐器商城购物推荐系统

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏:…