深度学习02-pytorch-09(pytorch完结篇)-基本使用介绍-线性回归案例

news2025/4/9 5:19:52
使用PyTorch的基本流程:
  • 数据准备:通过make_regression生成回归数据,使用 TensorDatasetDataLoader 来封装数据。

  • 模型定义:使用 nn.Module 或内置层(如 nn.Linear)来定义模型结构。

  • 损失函数和优化器:定义用于衡量误差的损失函数和用于优化参数的优化器。案例使用均方误差作为损失函数,用随机梯度下降法优化模型参数。

  • 训练过程:通过前向传播计算预测值,使用损失函数计算损失值,反向传播计算梯度,最后更新模型参数,迭代训练模型。

  • 评估模型:在测试集上评估模型的性能。

  • 可视化结果:绘制损失变化曲线和模型预测结果与真实数据的对比,帮助理解模型的训练效果。

以线性回归案例来讲解:

	# •	使用PyTorch的基本流程:
	# 1.	数据准备:通过make_regression生成回归数据,
    #.      并使用TensorDataset和DataLoader封装数据,以支持批量训练。
	# 2.	定义模型:使用nn.Linear定义一个线性模型,输入输出均为1。
	# 3.	损失函数和优化器:使用均方误差作为损失函数,用随机梯度下降法优化模型参数。
	# 4.	训练过程:通过前向传播计算预测值,使用损失函数计算损失值,
    #.       反向传播计算梯度,最后更新模型参数。
	# 5.	可视化结果:绘制损失变化曲线和模型预测结果与真实数据的对比,
    #.       帮助理解模型的训练效果。


# 导入相关模块
import torch
from torch.utils.data import TensorDataset, DataLoader  # 构造数据集对象和数据加载器
from torch import nn, optim  # nn模块包含神经网络相关功能,optim模块包含优化器
from sklearn.datasets import make_regression  # 用于生成回归模型的数据集
import matplotlib.pyplot as plt

# 配置matplotlib参数以显示中文和负号
plt.rcParams['font.family'] = 'PingFang HK'  # 设置mac 电脑的基本使用字体
plt.rcParams['axes.unicode_minus'] = False  # 解决坐标轴负号显示问题

def create_dataset():
    """
    创建用于线性回归的数据集,数据包括输入特征x和目标y。
    返回值包括生成的数据x, y和真实系数coef。
    """
    x, y, coef = make_regression(n_samples=100,  # 样本数
                                 n_features=1,  # 特征数
                                 noise=20,  # 噪声等级
                                 coef=True,  # 返回回归系数
                                 random_state=0,  # 固定随机种子,保证结果一致性
                                 bias=1.5)  # 偏置值
    
    # 转换为PyTorch张量类型
    x = torch.tensor(x, dtype=torch.float32)
    y = torch.tensor(y, dtype=torch.float32)
    return x, y, coef

if __name__ == '__main__':
    # 生成的数据
    x, y, coef = create_dataset()

    # 构造数据集对象,将x和y封装到TensorDataset中
    dataset = TensorDataset(x, y)
    
    # 使用DataLoader批量加载数据,batch_size表示每次训练使用16个样本,shuffle=True表示随机打乱数据
    dataloader = DataLoader(dataset=dataset, batch_size=16, shuffle=True)

    # 定义线性模型:输入特征为1(x),输出为1(y),即简单的线性回归模型
	# •	in_features=1:输入的特征数量是一维的,即一个特征。
	# •	out_features=1:输出也是一维的,即输出一个预测的值。
    # 这个配置是典型的用于简单线性回归的模型,因为我们只需要输入一个特征并输出一个预测结果。
    model = nn.Linear(in_features=1, out_features=1)
    
    # 定义损失函数为均方误差MSE,用于计算模型预测与真实值的差异
    criterion = nn.MSELoss()
    
    # 使用随机梯度下降(SGD)优化器,学习率为0.01
    # •	optim.SGD:创建了一个随机梯度下降优化器,用来调整模型的参数。
    # SGD 是 Stochastic Gradient Descent(随机梯度下降) 的缩写。它是一种常用的优化算法。简单来说,梯度下降是一种通过计算损失函数的梯度来逐步优化模型参数的方法。
	# •	model.parameters():告诉优化器要更新模型中的哪些参数。
    # model.parameters() 返回的是模型中的可训练参数,即模型的权重和偏置。权重(weight):用来对输入数据进行线性变换的参数。偏置(bias):模型中的偏置项,用于调整输出。
	# •	lr=0.01:定义了学习率,表示每次参数更新时沿梯度的步长大小。
    # lr 是 learning rate(学习率) 的缩写。学习率是优化器中的一个重要超参数,它控制每次更新时,模型参数的变化幅度。
    optimizer = optim.SGD(model.parameters(), lr=0.01)
    
    # 定义训练轮数(epochs)
    num_epochs = 100
    # 用于存储每个训练轮次epoch的平均损失值
    loss_per_epoch = []

    # 开始训练过程
    for epoch in range(num_epochs):
        total_loss = 0.0  # 每轮训练的总损失
        total_samples = 0  # 总样本数
        
        # 迭代每个批次的数据
        for batch_x, batch_y in dataloader:
            # 前向传播:将输入数据通过模型得到预测值
            predictions = model(batch_x)
            
            # 计算损失值(均方误差):预测值,真实值
            # batch_y.view(-1, 1) 将目标值调整为 [N, 1] 的形状,以便和 predictions 匹配。
            loss = criterion(predictions, batch_y.view(-1, 1))
            
            # 梯度清零,避免累积
            optimizer.zero_grad()
            
            # 反向传播计算梯度
            loss.backward()
            
            # 优化模型参数
            optimizer.step()
            
            # 累积损失和样本数
            total_loss += loss.item()
            total_samples += len(batch_x)
        
        # 计算平均损失并保存
        avg_loss = total_loss / total_samples
        loss_per_epoch.append(avg_loss)
    
    # 绘制损失函数随着训练轮数的变化曲线
    plt.plot(range(num_epochs), loss_per_epoch, label='训练损失')
    plt.title('损失函数变化曲线')
    plt.xlabel('Epoch')
    plt.ylabel('平均损失')
    plt.grid(True)
    plt.legend()
    plt.show()

    # 绘制真实的线性回归结果和模型预测结果的比较
    plt.scatter(x, y, label='数据点')  # 原始数据点
    
    # 使用模型预测的线性回归曲线
    # 在x轴上生成连续的点
    x_line = torch.linspace(x.min(), x.max(), 1000).view(-1, 1)  
    y_pred = model(x_line).detach()  # 使用模型预测并脱离计算图
    plt.plot(x_line, y_pred, label='模型预测', color='r')
    
    # 将 coef 转换为 PyTorch 张量,避免类型冲突
    coef_tensor = torch.tensor(coef, dtype=torch.float32)
    
    # 绘制真实的线性回归曲线
    y_true = coef_tensor * x_line + 1.5  # 真实的线性回归直线
    plt.plot(x_line, y_true, label='真实直线', color='g')
    
    plt.title('真实直线与模型预测对比')
    plt.xlabel('x')
    plt.ylabel('y')
    plt.grid(True)
    plt.legend()
    plt.show()

 # 定义训练轮数(epochs)为10次的时候 num_epochs = 10

 # 定义训练轮数(epochs)为100次的时候 num_epochs = 100,可见和真实值拟合更好了。

梯度的趋势,也是越来越小的趋势,所以证明我们拟合的还不错。上面就是我们通过线性回归的案例来讲解 pytorch 的基本使用过程。

我们总结下:

使用 PyTorch 的基本流程:

  1. 数据准备

    • 通常你需要将数据转换为 PyTorch 张量。对于小数据集,可以使用手动创建的张量,对于大数据集,

    • 可以使用 torch.utils.data.Datasettorch.utils.data.DataLoader 来进行批量加载。

    • 例如,可以使用 make_regressionmake_classification 来生成用于回归或分类任务的测试数据集,并将其转换为张量。

    from sklearn.datasets import make_regression
    import torch
    ​
    # 生成样本数据
    x, y = make_regression(n_samples=100, n_features=1, noise=20)
    x = torch.tensor(x, dtype=torch.float32)
    y = torch.tensor(y, dtype=torch.float32)

            

  2. 构建数据集和数据加载器

    • 使用 TensorDatasetDataLoader 来封装数据并支持批量训练。DataLoader 可以帮助你随机打乱数据,并在每次训练时提供一部分样本。

    from torch.utils.data import TensorDataset, DataLoader
    ​
    # 封装数据
    dataset = TensorDataset(x, y)
    dataloader = DataLoader(dataset, batch_size=16, shuffle=True)
  3. 定义模型

    • 你可以通过继承 torch.nn.Module 或使用内置的 torch.nn.Linear 等层来构建你的模型。模型的 forward 方法负责定义前向传播的过程。

    import torch.nn as nn
    ​
    # 定义线性模型,只有一个x, 一个y 的模型
    model = nn.Linear(in_features=1, out_features=1)

  4. 定义损失函数和优化器

    • 损失函数用于衡量模型的预测值与真实值之间的差距,PyTorch 提供了许多常用的损失函数,例如 nn.MSELoss()(用于回归),nn.CrossEntropyLoss()(用于分类)。

    • 优化器用于根据损失值来调整模型的参数。常见的优化器有 optim.SGD()optim.Adam() 等。

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

  5. 训练过程

    • 训练模型通常包括以下几个步骤:

      1. 前向传播:将输入数据传入模型,计算预测值。

      2. 计算损失:使用损失函数计算预测值与真实值之间的差距。

      3. 反向传播:调用 loss.backward() 来计算梯度。

      4. 更新参数:使用优化器的 optimizer.step() 更新模型参数。

      5. 梯度清零:使用 optimizer.zero_grad() 清除上一轮迭代的梯度。

    # 定义训练轮数
    num_epochs = 100
    ​
    for epoch in range(num_epochs):
       total_loss = 0.0
       
       for batch_x, batch_y in dataloader:
           # 前向传播
           predictions = model(batch_x)
           
           # 计算损失
           loss = criterion(predictions, batch_y.view(-1, 1))
           
           # 梯度清零
           optimizer.zero_grad()
           
           # 反向传播
           loss.backward()
           
           # 更新参数
           optimizer.step()
           
           # 累积损失
           total_loss += loss.item()
       
       print(f'Epoch {epoch+1}, Loss: {total_loss}')

  6. 评估模型

    • 在模型训练完成后,通常会使用验证集或测试集来评估模型的性能。你可以通过在训练结束后使用模型进行预测,并计算测试数据上的损失来进行评估。

    model.eval()  # 切换到评估模式
    with torch.no_grad():  # 禁止计算梯度
       predictions = model(x_test)  # x_test 是测试数据
       test_loss = criterion(predictions, y_test)
       print(f'Test Loss: {test_loss.item()}')

  7. 可视化训练结果

    • 通常我们会绘制损失函数随训练轮次变化的曲线,以观察模型是否在收敛。

    • 你还可以将模型的预测结果与真实数据进行对比,进一步评估模型的性能。

    import matplotlib.pyplot as plt
    ​
    plt.plot(range(num_epochs), loss_per_epoch)
    plt.title('训练损失变化')
    plt.xlabel('Epochs')
    plt.ylabel('Loss')
    plt.show()

总结:

  • 数据准备:使用 TensorDatasetDataLoader 来封装数据。

  • 模型定义:使用 nn.Module 或内置层(如 nn.Linear)来定义模型结构。

  • 损失函数和优化器:定义用于衡量误差的损失函数和用于优化参数的优化器。

  • 训练过程:通过前向传播、反向传播和参数更新,迭代训练模型。

  • 评估模型:在测试集上评估模型的性能。

  • 可视化结果:绘制损失变化曲线和预测结果,以分析模型表现。

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

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

相关文章

【全网最全】2024年华为杯研赛D题成品论文获取入口(后续会更新)

您的点赞收藏是我继续更新的最大动力! 一定要点击如下的卡片,那是获取资料的入口! 点击链接加入【2024华为杯研赛资料汇总】:https://qm.qq.com/q/XzdIsvbiM0https://qm.qq.com/q/XzdIsvbiM0 你是否在寻找数学建模比赛的突破点…

【他山之石】优化 JavaScript 的乐趣与价值(下)

前言 继本文的 上篇 发表之后,没想到反响还挺好,看来大家在 JS 优化的问题上越来越注重“与国际接轨”了。一起来看本文的下篇,也是干货满满。 文章目录 6. Avoid large objectsWhat the eff should I do about this? 7. Use eval8. Use str…

多元形式助力商业价值最大化,王鹤棣商业影响力遥遥领先

明星商业代言层出不穷,但在个人影响力的升级玩法上,当代青年偶像王鹤棣以其独特的个人魅力和卓越的商业头脑,正逐步搭建起一个以个人形象为核心,与各大品牌相互成就的立体商业模型。通过一系列创新的商务合作模式,王鹤…

[Java并发编程] synchronized(含与ReentrantLock的区别)

文章目录 1. synchronized与ReentrantLock的区别2. synchronized的作用3. synchronized的使用3.1 修饰实例方法,作用于当前实例,进入同步代码前需要先获取实例的锁3.2 修饰静态方法,作用于类的Class对象,进入修饰的静态方法前需要…

React组件如何暴露自身的方法

一、研究背景 最近遇到一个如何暴露React组件自身方法的问题。在某些时候,我们需要调用某个组件内部的方法以实现某个功能,因此我们需要了解如何暴露组件内部API的方法。 二、实践过程 本文主要介绍React组件暴露子组件API的方法,以下是实…

2024年研赛-华为杯数模竞赛C题论文首发+论文讲解+代码分享

2024年华为杯-研赛分享资料(论文分享部分代码)(已更新部分代码):链接:https://pan.baidu.com/s/1HGIYjV3lqzUc_3H0vg5H8w 提取码:sxjm 题 目: _基于数据驱动下磁性元件的磁芯损耗建模…

leetcode第十三题:罗马数字转整数

罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例如&#x…

OpenCV特征检测(7)角点检测函数goodFeaturesToTrack()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 确定图像上的强角点。 该函数根据 240中所描述的方法查找图像中最显著的角点或者指定图像区域内的最显著角点。 函数使用 cornerMinEigenVal 或…

华南理工大学信息工程高频电子线路课程设计——基于锁相环的调试解调器设计

完整报告链接如下: 通过网盘分享的文件:高频课设报告.docx 链接: https://pan.baidu.com/s/1J83UCDSU0UHcv4ONYxfyhg?pwdzqyr 提取码: zqyr --来自百度网盘超级会员v5的分享 懒得贴上来了,放一下截图。

ICM20948 DMP代码详解(34)

接前一篇文章:ICM20948 DMP代码详解(33) 上一回解析了inv_icm20948_initialize_lower_driver函数中设置FIFO_RST和FIFO_CFG寄存器相关的代码,本回继续往下解析inv_icm20948_initialize_lower_driver函数的后续代码。为了便于理解和…

蓝桥杯【物联网】零基础到国奖之路:十. OLED

蓝桥杯【物联网】零基础到国奖之路:十.OLED 第一节 硬件解读第二节 MDK配置 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/fa7660b81be9407aa19c603561553db0.png)第三节 代码 第一节 硬件解读 OLED硬件知识: 第二节 MDK配置 第三节 代码 include头文件。 编…

Webui 显卡有显存,会报错:CUDA out of memory

Webui 显卡明明有显存,会报错:CUDA out of memory 网上找了很多资料,都没有能解决这个问题 ,后来发现和电脑虚拟内存设置有关,这里记录一下具体的解决方法: 什么是 CUDA Out of Memory 错误? …

【MySQL】字符集与Collation

今天做项目,突然发现,项目中使用的MySQL的库排序规则是 utf8mb4_general_ci,而我自己用的MySQL8默认库规则是utf8mb4_0900_ai_ci,于是想要弄清楚 出处(写的非常详细):mysql设置了utf8mb4&#x…

WPF自定义Dialog模板,内容用不同的Page填充

因为审美的不同,就总有些奇奇怪怪的需求,使用框架自带的对话框已经无法满足了,这里记录一下我这边初步设计的对话框。别问为啥要用模板嵌套Page来做对话框,问就是不想写太多的窗体。。。。 模板窗体(XAML)…

面试-设计模式

策略模式 定义了一组算法,分别封装起来,这些算法直接可以相互替换 设计模式的开闭原则:对修改关闭,对扩展开放 装饰模式 将某种算法作为一个装饰品添加到对象身上,同时可以自由穿戴更换装饰品 两个主要的角色&…

C语言 | Leetcode C语言题解之第423题从英文中重建数字

题目&#xff1a; 题解&#xff1a; char * originalDigits(char * s) {int lenstrlen(s);int arr[26]{0},num[10]{0},cot0;for(int i 0; i < len; i)arr[s[i] - a];num[0] arr[z-a];num[2] arr[w-a];num[4] arr[u-a];num[6] arr[x-a];num[8] arr[g-a];num[1] arr[o…

[JavaEE] UDP协议

目录 再谈端口号 一、端口号的划分 二、UDP协议 三、UDP的特点 再谈端口号 一、端口号的划分 0-1023&#xff1a;知名端口号&#xff0c;端口号固定&#xff0c;其中包括HTTP&#xff0c;FTP&#xff0c;SSH等广为使用的应用层协议。 1024-65535&#xff1a;操作系统动态分…

演示jvm锁存在的问题

文章目录 1、AlbumInfoApiController --》testLock()2、redis添加键值对3、AlbumInfoServiceImpl --》testLock() 没有加锁4、使用ab工具测试4.1、安装 ab 工具4.2、查看 redis 中的值 5、添加本地锁 synchronized6、集群情况下问题演示 jvm锁&#xff1a;synchronized lock 只…

面试金典题2.4

给你一个链表的头节点 head 和一个特定值 x &#xff0c;请你对链表进行分隔&#xff0c;使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 你不需要 保留 每个分区中各节点的初始相对位置。 示例 1&#xff1a; 输入&#xff1a;head [1,4,3,2,5,2], x 3 输出&a…

LeetCode从入门到超凡(二)递归与分治算法

引言 大家好&#xff0c;我是GISer Liu&#x1f601;&#xff0c;一名热爱AI技术的GIS开发者。本系列文章是我跟随DataWhale 2024年9月学习赛的LeetCode学习总结文档&#xff1b;在算法设计中&#xff0c;递归和分治算法是两种非常重要的思想和方法。它们不仅在解决复杂问题时表…