PyTorch深度学习模型训练流程的python实现:回归

news2024/9/25 15:24:41

回归的流程与分类基本一致,只需要把评估指标改动一下就行。回归输出的是损失曲线、R^2曲线、训练集预测值与真实值折线图、测试集预测值散点图与真实值折线图。输出效果如下:

 注意:预测值与真实值图像处理为按真实值排序,图中呈现的升序与数据集趋势无关。

代码如下:

from functools import partial
import numpy as np
import pandas as pd
from sklearn.preprocessing import label_binarize
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, confusion_matrix, roc_curve, r2_score

import torch
import torch.nn as nn
from torch.utils.data import DataLoader, TensorDataset, Dataset
from visdom import Visdom

from typing import Union, Optional
from sklearn.base import TransformerMixin
from torch.optim.optimizer import Optimizer


def regress(
        data: tuple[Union[np.ndarray, Dataset], Union[np.ndarray, Dataset]],
        model: nn.Module,
        optimizer: Optimizer,
        criterion: nn.Module,
        scaler: Optional[TransformerMixin] = None,
        batch_size: int = 64,
        epochs: int = 10,
        device: Optional[torch.device] = None
) -> nn.Module:
    """
    回归任务的训练函数。
    :param data: 形如(X,y)的np.ndarray类型,及形如(train_data,test_data)的torch.utils.data.Dataset类型
    :param model: 回归模型
    :param optimizer: 优化器
    :param criterion: 损失函数
    :param scaler: 数据标准化器
    :param batch_size: 批大小
    :param epochs: 训练轮数
    :param device: 训练设备
    :return: 训练好的回归模型
    """
    if isinstance(data[0], np.ndarray):
        X, y = data
        # 分离训练集和测试集,指定随机种子以便复现
        X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
        # 数据标准化
        if scaler is not None:
            X_train = scaler.fit_transform(X_train)
            X_test = scaler.transform(X_test)
        # 转换为tensor
        X_train = torch.from_numpy(X_train.astype(np.float32))
        X_test = torch.from_numpy(X_test.astype(np.float32))
        y_train = torch.from_numpy(y_train.astype(np.float32))
        y_test = torch.from_numpy(y_test.astype(np.float32))
        # 将X和y封装成TensorDataset
        train_dataset = TensorDataset(X_train, y_train)
        test_dataset = TensorDataset(X_test, y_test)

    elif isinstance(data[0], Dataset):
        train_dataset, test_dataset = data
    else:
        raise ValueError('Unsupported data type')

    train_loader = DataLoader(
        dataset=train_dataset,
        batch_size=batch_size,
        shuffle=True,
        num_workers=2,
    )
    test_loader = DataLoader(
        dataset=test_dataset,
        batch_size=batch_size,
        shuffle=True,
        num_workers=2,
    )

    model.to(device)
    vis = Visdom()
    # 训练模型
    for epoch in range(epochs):
        for step, (batch_x_train, batch_y_train) in enumerate(train_loader):
            batch_x_train = batch_x_train.to(device)
            batch_y_train = batch_y_train.to(device)
            # 前向传播
            output = model(batch_x_train)
            loss = criterion(output, batch_y_train)
            # 反向传播
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()

            niter = epoch * len(train_loader) + step + 1  # 计算迭代次数
            if niter % 100 == 0:
                # 评估模型
                model.eval()
                with torch.no_grad():
                    eval_dict = {
                        'test_loss': [],
                        'test_r2': [],
                        'y_test': [],
                        'y_pred': [],
                    }
                    for batch_x_test, batch_y_test in test_loader:
                        batch_x_test = batch_x_test.to(device)
                        batch_y_test = batch_y_test.to(device)
                        test_output = model(batch_x_test)
                        test_predicted_tuple = (batch_y_test.numpy(), test_output.numpy())
                        # 计算并记录损失、R^2、真实值、预测值
                        eval_dict['test_loss'].append(criterion(test_output, batch_y_test))
                        eval_dict['test_r2'].append(r2_score(*test_predicted_tuple))
                        eval_dict['y_test'].append(batch_y_test)
                        eval_dict['y_pred'].append(test_output)

                    # 画出损失曲线
                    vis.line(
                        X=torch.ones((1, 2)) * (niter // 100),
                        Y=torch.stack((loss, torch.mean(torch.tensor(eval_dict['test_loss'])))).unsqueeze(0),
                        win='loss',
                        update='append',
                        opts=dict(title='Loss', legend=['train_loss', 'test_loss']),
                    )
                    # 画出R^2曲线
                    train_r2 = r2_score(batch_y_train.numpy(), output.numpy())
                    vis.line(
                        X=torch.ones((1, 2)) * (niter // 100),
                        Y=torch.tensor((train_r2, np.mean(eval_dict['test_r2']))).unsqueeze(0),
                        win='R^2',
                        update='append',
                        opts=dict(title='R^2', legend=['train_R^2', 'test_R^2'], ytickmin=0, ytickmax=1),
                    )
                    # 画出训练集预测值和真实值折线图
                    sorted_train_idx = torch.argsort(batch_y_train)  # 按真实值排序
                    vis.line(
                        X=torch.arange(batch_size).repeat(2, 1).t(),
                        Y=torch.stack((batch_y_train[sorted_train_idx], output[sorted_train_idx]), dim=1),
                        win='batch_train_line',
                        opts=dict(title='Predicted vs. Actual (Train Set)', legend=['Actual', 'Predicted']),
                    )
                    # 画出测试集预测值散点图和真实值折线图
                    x = list(range(len(y_test)))
                    y_test = torch.cat(eval_dict['y_test'])
                    y_pred = torch.cat(eval_dict['y_pred'])
                    sorted_test_idx = torch.argsort(y_test)
                    vis._send({
                        'data': [
                            {'x': x, 'y': y_test[sorted_test_idx].tolist(), 'type': 'custom', 'mode': 'lines', 'name': 'Actual'},
                            {'x': x, 'y': y_pred[sorted_test_idx].tolist(), 'type': 'custom', 'mode': 'markers', 'name': 'Predicted', 'marker': {'size': 3}}
                        ],
                        'win': 'test_line',
                        'layout': {'title': 'Predicted vs. Actual (Test Set)'},
                    })
    return model

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

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

相关文章

聚合智链已获道富环球投资,正式上线AI合约策略资金托管平台

全球最大的托管银行之一道富环球首次进军加密货币领域,聚合智链获得其投资支持,打造出全球领先的AI合约策略资金托管平台,将在2024年8月 28 日正式上线。 道富环球集团的总部位于美国,其成立于1792年,是一家专注于托管…

easypoi模板导出word多页导出加强版

说明 上一篇文章提到多页导出,但是后边发现一个问题,如果用同一个模板导出多页内容,我们去获取多页内容的时候,会发现全部都一样,举个例子: XWPFDocument document WordExportUtil.exportWord07(outputU…

深度学习入门-第4章-神经网络的学习

学习就是从训练数据中自动获取最优权重参数的过程。引入损失函数这一指标,学习的目的是找出使损失函数达到最小的权重参数。使用函数斜率的梯度法来找这个最小值。 人工智能有两派,一派认为实现人工智能必须用逻辑和符号系统,自顶向下看问题…

java-Mybatis框架

简介 MyBatis 是一款优秀的持久层框架,它支持自定义 SQl、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Obje…

DFS 算法:全排列问题

我的个人主页 {\large \mathsf{{\color{Red} 我的个人主页} } } 我的个人主页 往 {\color{Red} {\Huge 往} } 往 期 {\color{Green} {\Huge 期} } 期 文 {\color{Blue} {\Huge 文} } 文 章 {\color{Orange} {\Huge 章}} 章 DFS 算法:记忆化搜索 此系列更新频繁&…

k8s中service对象

文章目录 一、Service简介Service和kube-proxy的作用与区别Service的工作过程kube-proxy的工作过程总结 二、具体实践ClusterIPClusterIP 基本概念应用场景 NodePortNodePort 简介应用场景 ExternalName简介应用场景 一、Service 简介 Kubernetes (k8s) 中的 Service 对象是一…

使用redis设计延迟队列

目录 延迟队列概念与重要性 定义:延迟队列的基本概念 重要性:延迟队列在处理异步任务中的关键作用 图表:延迟队列的工作流程图 ​编辑延迟队列设计案例 背景介绍 设计目标 系统架构 设计要点 现有物理拓扑 图表:有赞延迟…

GStreamer 简明教程(五):Pad 相关概念介绍,Pad Capabilities/Templates

系列文章目录 GStreamer 简明教程(一):环境搭建,运行 Basic Tutorial 1 Hello world! GStreamer 简明教程(二):基本概念介绍,Element 和 Pipeline GStreamer 简明教程(三…

自修C++Primer----3.2标准库类型string

目录 1.String的相关操作 1.1拷贝初始化&&直接初始化 1.2显示创建临时对象 1.3读取string对象内容 1.4一次读取多个未知对象 1.5使用getline读取一整行内容 1.6size()的返回值size_type类型 1.7两个string对象比较 1.8string对象赋值 1.9两个string对象相加 1…

策略产品 ①算法逻辑

目录 一、机器学习与AI的关系 二、机器学习全流程 1. 问题定义 2. 数据处理 3. 特征工程 4. 模型训练 5. 模型评估 6. 模型应用 机器学习是AI的关键技术之一,是指机器从历史数据中学习规律,从而提升系统某个性能度量的过程。这篇文章,我们在作…

C Primer Plus第十四章编程练习,仅供参考

第十四章编程练习 第一个问题让我们改写复习题5&#xff0c;创建一个函数去计算一年到某个月份的天数&#xff0c;在一个结构数组中去存储相关数据。完整程序代码以及运行结果如下&#xff1a; #include<stdio.h> #include<string.h> #include<ctype.h> st…

当外接硬盘接入到macOS上,只读不可写时,应当格式化

当windows磁盘格式例如 NTFS 的硬盘接入到macOS上时&#xff0c;会发现无法新建文件夹&#xff0c;无法删除、重命名。原因是磁盘格式对不上macOS&#xff0c;需要进行格式化。格式化时请注意备份重要数据。具体做法如下&#xff0c;在macOS中找到磁盘工具&#xff0c;然后对磁…

【HTML】常用几种模拟动画效果【附源代码】

1. 模拟音频波纹加载效果 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthde…

计算机视觉编程

目录 灰色度 缩略图 拷贝粘贴区域 调整图像尺寸 旋转图像45 画图线、描点 灰色度 灰度是指图像中每个像素的亮度值&#xff0c;用来描述图像中各个像素的明暗程度。在计算机视觉中&#xff0c;灰度可以通过以下方式来计算&#xff1a; 1. 平均值法&#xff1a;将图像中每…

如何在程序中创建出多条线程

多线程是编程中的一个重要概念&#xff0c;它允许程序同时执行多个任务&#xff0c;每个任务可以看作是一个线程。在Java中&#xff0c;多线程尤为常见且强大&#xff0c;它通过允许程序在并发环境下运行&#xff0c;提高了程序的执行效率和响应速度。以下是对Java多线程的详细…

数学建模~~~预测方法--决策树模型

目录 0.直击重点 1.决策树概念 2.节点特征的选择算法 3.基尼系数的计算 4.决策树的分类 5.模型的搭建 6.模型的改进和评价 ROC曲线 参数调优 &#xfeff;GridSearch网格搜索 使用搜索结果重新建模 0.直击重点 这个文章&#xff0c;我们从三个维度进行说明介绍&#…

如何使用Python快速修改文件的标签(如何将歌词嵌入到音乐文件中,含歌词嵌入接口源码)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 Python与Music 📒📝 1. 初探音乐文件的标签📝 使用Python修改标签📝 将歌词嵌入音乐文件⚓️ 相关链接 ⚓️📖 介绍 📖 你是否曾经听过一首好听的歌曲,却发现它的标签信息(元数据信息)杂乱无章?甚至找不到歌词?…

【Remi Pi开发板镜像烧录】使用sd卡进行瑞米派镜像的烧录

烧录大典 按照《软件开发指南》4.2.1和4.2.2的顺序进行&#xff0c;具体烧录哪个镜像结合你自己的需求&#xff0c;每个镜像的区别参考以下链接 https://mbb.eet-china.com/forum/topic/143906_1_1.html Tera term界面全屏如下设置看着比较舒服 设置完之后setup->save-&g…

智能优化特征选择|基于鹦鹉优化(2024年新出优化算法)的特征选择(分类器选用的是KNN)研究Matlab程序 【优化算法可以替换成其他优化方法】

智能优化特征选择|基于鹦鹉优化&#xff08;2024年新出优化算法&#xff09;的特征选择&#xff08;分类器选用的是KNN&#xff09;研究Matlab程序 【优化算法可以替换成其他优化方法】 文章目录 一、PO基本原理PO基本原理基本流程示例应用 二、实验结果三、核心代码四、代码获…

npm pack使用

npm pack 的作用主要是从包中创建一个压缩文件&#xff08;tarball&#xff09;&#xff0c;通常具有.tgz扩展名&#xff0c;包含了打包的模块及其依赖&#xff0c;可用于分发或部署。其应用场景包括私有库或组件的分发、离线环境的依赖安装、CI/CD 自动化构建等。 在使用npm管…