神经网络中如何优化模型和超参数调优(案例为tensor的预测)

news2025/2/24 3:26:04

总结:

初级:简单修改一下超参数,效果一般般但是够用,有时候甚至直接不够用

中级:optuna得出最好的超参数之后,再多一些epoch让train和testloss整体下降,然后结果就很不错。

高级:在中级的基础上,更换更适合的损失函数之后,在train的时候backward反向传播这个loss,optuna也更改这个loss标准,现在效果有质的改变

问题:

最近在做cfd领域,需要流场进行预测,然后流场提取出来再深度学习就是一个多维度tensor,而神经网络的目的就是通过模型预测让预测的tensor与实际的tensor的结果尽可能的接近,具体来说就是让每个值之间的误差尽可能小。

目前情况:现在模型大概以及确定,但是效果一般般,这时候就需要进行下面的调优方法。

优化方法:

一、初级优化:

简单修改一下超参数,效果一般般但是够用,有时候甚至直接不够用

二、中级优化:optuna调参,然后epoch加多

optuna得出最好的超参数之后,再多一些epoch让train和testloss整体下降,然后结果就很不错。

三、高级优化:

在中级的基础上,现在更换更适合的损失函数之后,在train的时候backward反向传播这个loss,optuna也更改这个loss标准,现在效果有质的改变

也就是下面这三行代码

smooth_l1 = F.smooth_l1_loss(out.view(shape1, shape2), y.view(shape1, shape2))#!!!!!!!!!!!!!
smooth_l1.backward() #用这个smooth_l1_loss反向传播#!!!!!!!!!!!!!!!!!!!!!!!!!
return test_smooth_l1  #test中的最后一个epoch的test_smooth_l1!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

通过上面预测的数据和实际的数据进行的对比,可以发现预测的每个结果与实际的结果的误差在大约0.01范围之内(实际数据在[-4,4]之间)

确定损失函数:

要让两个矩阵的值尽可能接近,选择合适的损失函数(loss function)是关键。常见的用于这种目的的损失函数包括以下几种:

  1. 均方误差(Mean Squared Error, MSE):对预测值与真实值之间的平方误差求平均。MSE对大误差比较敏感,能够显著惩罚偏离较大的预测值。

    import torch.nn.functional as F loss = F.mse_loss(predicted, target)

  2. 平均绝对误差(Mean Absolute Error, MAE):对预测值与真实值之间的绝对误差求平均。MAE对异常值不如MSE敏感,适用于数据中存在异常值的情况。

    import torch loss = torch.mean(torch.abs(predicted - target))

  3. 平滑L1损失(Smooth L1 Loss):又称Huber Loss,当误差较小时,平滑L1损失类似于L1损失,当误差较大时,类似于L2损失。适合在有噪声的数据集上使用。

    import torch.nn.functional as F loss = F.smooth_l1_loss(predicted, target)
    总结如下:
  •     MSE:适用于需要显著惩罚大偏差的情况。

  •      MAE:适用于数据中存在异常值,并且你希望对异常值不那么敏感的情况。
  •      Smooth L1 Loss:适用于既有一定抗噪声能力又能对大偏差适当惩罚的情况。

      这里根据任务选择Smooth L1 Loss。

具体做法:

目前这个经过optuna调优,然后先下面处理(想是将loss的反向传播和optuna优化标准全换为更适合这个任务的smooth_l1_loss函数

  • 1.  loss将mse更换为smooth_l1_loss,
  • 2.  l2.backward()更换为smooth_l1.backward(),
  • 3.  return test_l2更改为return test_smooth_l1  

结果:point_data看着值很接近,每个值误差0.01范围内。说明用这个上面这个方法是对的。试了一下图也有优化。并step_loss现在极低。

下面代码中加感叹号的行都是上面思路修改我的项目中对应的代码行,重要!!!

import optuna
import time
import torch.optim as optim
# 求解loss的两个参数
shape1 =  -1   
shape2 = data.shape[1]* 3

def objective1(trial):
    batch_size = trial.suggest_categorical('batch_size', [32])
    learning_rate = trial.suggest_float('learning_rate', 1e-6, 1e-2,log=True)
    layers = trial.suggest_categorical('layers', [2,4,6])
    width = trial.suggest_categorical('width', [10,20,30])#新加的
    weight_decay = trial.suggest_float('weight_decay', 1e-6, 1e-2,log=True)#新加的
    
    #再加个优化器
    optimizer_name = trial.suggest_categorical('optimizer', ['Adam', 'SGD', 'RMSprop'])
    # loss_function_name = trial.suggest_categorical('loss_function', ['LpLoss', 'MSELoss'])
    
    
    """ Read data """
    # data是[1991, 80, 40, 30],而data_cp是为归一化的[2000, 80, 40, 30]
    train_a = data[ntest:-1,:,:]#data:torch.Size:50:, 80, 40, 30。train50对应的是predict50+9+1
    train_u = data_cp[ntest+10:,:,:]#torch.Size([50, 64, 64, 10])#data_cp是未归一化的,第11个对应的是data的第data的第1个,两者差10
    # print(train_a.shape)
    # print(train_u.shape)
    
    test_a = data[:ntest,:,:]#选取最后200个当测试集
    test_u = data_cp[10:ntest+10,:,:]
    # print(test_a.shape)
    # print(test_u.shape)#torch.Size([40, 80, 40, 3])
    train_loader = torch.utils.data.DataLoader(torch.utils.data.TensorDataset(train_a, train_u),
                                               batch_size=batch_size, shuffle=True)
    test_loader = torch.utils.data.DataLoader(torch.utils.data.TensorDataset(test_a, test_u),
                                              batch_size=batch_size, shuffle=False)
    #没有随机的train_loader,用于后面预测可视化
    data_loader_noshuffle = torch.utils.data.DataLoader(torch.utils.data.TensorDataset(data[:,:,:], data_cp[9:,:,:]),
                                               batch_size=batch_size, shuffle=False)
    
    
    # %%
    """ The model definition """
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    model = WNO1d(width=width, level=level, layers=layers, size=h, wavelet=wavelet,
                  in_channel=in_channel, grid_range=grid_range).to(device)
    # print(count_params(model))
    
    # optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate, weight_decay=1e-6)
        #调参数用,优化器选择
    if optimizer_name == 'Adam':
        optimizer = optim.Adam(model.parameters(), lr=learning_rate, weight_decay=weight_decay)
    elif optimizer_name == 'SGD':
        optimizer = optim.SGD(model.parameters(), lr=learning_rate, weight_decay=weight_decay, momentum=0.9)
    else:  # RMSprop
        optimizer = optim.RMSprop(model.parameters(), lr=learning_rate, weight_decay=weight_decay)
        
    scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=step_size, gamma=gamma)
    
    train_loss = torch.zeros(epochs)
    test_loss = torch.zeros(epochs)
    myloss = LpLoss(size_average=False)
    



    """ Training and testing """
    for ep in range(epochs):
        model.train()
        t1 = default_timer()
        train_mse = 0
        train_l2 = 0
        for x, y in train_loader:
            x, y = x.to(device), y.to(device)
    
            optimizer.zero_grad()
            out = model(x)
    
            mse = F.mse_loss(out.view(shape1, shape2), y.view(shape1, shape2))
            # # 训练时使用 Smooth L1 Loss
            smooth_l1 = F.smooth_l1_loss(out.view(shape1, shape2), y.view(shape1, shape2))#!!!!!!!!!!!!!

            l2 = myloss(out.view(shape1, shape2), y.view(shape1, shape2))
            # l2.backward()
            smooth_l1.backward() #用这个smooth_l1_loss反向传播#!!!!!!!!!!!!!!!!!!!!!!!!!

            optimizer.step()
            train_mse += mse.item()
            train_l2 += l2.item()
    
        scheduler.step()
        model.eval()
        test_l2 = 0.0
        test_smooth_l1 =0
        with torch.no_grad():
            for x, y in test_loader:
                x, y = x.to(device), y.to(device)
    
                out = model(x)
                test_l2 += myloss(out.view(shape1, shape2), y.view(shape1, shape2)).item()
                test_smooth_l1  +=F.smooth_l1_loss(out.view(shape1, shape2), y.view(shape1, shape2)).item()#!!!!!!!!!!!!!!!!!!
        train_mse /= ntrain#len(train_loader)
        train_l2 /= ntrain
        test_l2 /= ntest
        test_smooth_l1 /= ntest#!!!!!!!!!!!!!!!!!!!
        
        train_loss[ep] = train_l2
        test_loss[ep] = test_l2
    
        t2 = default_timer()
        print('Epoch-{}, Time-{:0.4f}, [step_loss:] -> Train-MSE-{:0.4f},test_smooth_l1-{:0.4f} Train-L2-{:0.4f}, Test-L2-{:0.4f}'
              .format(ep, t2-t1, train_mse,test_smooth_l1, train_l2, test_l2))#!!!!!!!!!!!!!!!!1
    

    if trial.should_prune():
        raise optuna.exceptions.TrialPruned()

    """防止打印信息错位"""
    print(f"Trial {trial.number} finished with value: {test_l2}")

    return test_smooth_l1  #test中的最后一个epoch的test_smooth_l1!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    
    """ For saving the trained model and prediction data """

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

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

相关文章

使用Docker 实现 MySQL 循环复制(三)

系列文章 使用Docker 实现 MySQL 循环复制(一) 使用Docker 实现 MySQL 循环复制(二) 目录 系列文章1. 在主机上安装MySQL客户端2. 配置循环复制拓扑2.1 进入容器2.2 创建复制用户并授予复制权限2.3 复位二进制日志2.4 配置环形复…

Jenkins-zookeeper-docker-xxljob-rancher

文章目录 Jenkins实战1 新建任务需要的配置pipeline Zookeeper基础 Docker基础实操windows11 docker mysql DockerhouseDockerhubxxl-Job基础实战 Rancher基础思考 实战1 Rancher的某个namespace的scale为0 Jenkins 实战 1 新建任务需要的配置pipeline 该代码是Jenkinsfile&…

【Docker】基于Docker-compose创建LNMP环境

目录 一.Docker-compose 概述 1.容器编排管理与传统的容器管理的区别 2.docker-compose 作用 3.docker-compose 本质 4.docker-compose 的三大概念 二.YML文件格式及编写注意事项 1.yml文件是什么 2.yml问价使用注意事项 3.yml文件的基本数据结构 三.Docker-compose …

5G以太网和5G前传业务的有效解决方案——25G可调DWDM光模块

信息技术的迅猛发展和数据传输需求的不断增加,光通信技术在现代网络中扮演着至关重要的角色。DWDM技术通过在一根光纤上使用多个不同波长的光信号同时传输,大幅提高了数据传输的容量。而可调光模块则能够在多种波长之间进行切换,实现灵活、高…

如何用EXCEL自动解方程/方程组?利用 矩阵乘法X=A-*B,X=mmult(minverse(A), B)

目录 问题的由来 1 数据 → 模拟分析 → 单变量求解 1.1 找一个单元格填入公式 1.2 功能入口 1.3 选择单变量求解,分别填入内容 1.4 求解 1.5 这个感觉用处不大 2 重点介绍,用EXCEL进行矩阵运算解方程的操作 2.1 运用EXCEL进行矩阵运算&…

ETL数据集成丨通过ETLCloud工具,将Oracle数据实时同步至Doris中

ETLCloud是一个全面的数据集成平台,专注于解决大数据量和高合规要求环境下的数据集成需求。采用先进的技术架构,如微服务和全Web可视化的集成设计,为用户提供了一站式的数据处理解决方案。 主要特点和功能包括: 实时数据处理&…

Android 使用FFmpeg解析RTSP流,ANativeWindow渲染 使用SurfaceView播放流程详解

文章目录 ANativeWindow 介绍ANativeWindow 的主要功能和特点ANativeWindow 的常用函数工作流程原理图通过ANativeWindow渲染RGB纯色示例 播放RTSP流工作流程图关键步骤解析自定义SurfaceView组件native 层解码渲染 效果展示注意事项 这篇文章涉及到jni层,以及Ffmpe…

pdf提取其中一页怎么操作?提取PDF其中一页的方法

pdf提取其中一页怎么操作?需要从一个PDF文件中提取特定页码的操作通常是在处理文档时常见的需求。这种操作允许用户选择性地获取所需的信息,而不必操作整个文档。通过选择性提取页面,你可以更高效地管理和利用PDF文件的内容,无论是…

负载均衡 lvs

1. 4层转发(L4) 与 7层转发(L7) 区别 4层转发(L4) 与 7层转发(L7) 区别 转发基于的信息 状态 常用的服务 L4 基于网络层和传输层信息: L4转发主要依赖于网络层IP头部(源地址,目标地址,源端口,目标端口)和传输层头部&#xff…

接口防刷!利用redisson快速实现自定义限流注解

问题: 在日常开发中,一些重要的对外接口,需要加上访问频率限制,以免造成资��损失。 如登录接口,当用户使用手机号验证码登录时,一般我们会生成6位数的随机验证码,并将验…

【论文解读】VoxelNeXt: Fully Sparse VoxelNet for 3D Object Detection and Tracking

VoxelNeXt 摘要引言方法Sparse CNN Backbone AdaptationSparse Prediction Head 3D Tracking实验结论 摘要 3D物体检测器通常依赖于手工制作的方法,例如锚点或中心,并将经过充分学习的2D框架转换为3D。因此,稀疏体素特征需要通过密集预测头进…

电脑没有声音了怎么恢复?3个硬核操作,解救静音危机!

当你沉迷于电脑中的音乐、电影或是游戏时,突然一阵寂静袭来,是不是感觉就像突然按下了暂停键?这无疑是一场大灾难!电脑没有声音了怎么恢复呢?急,今天小编带来了3个硬核操作,让你从无声的幽谷中爬…

二、BIO、NIO、直接内存与零拷贝

一、网络通信编程基础 1、Socket Socket是应用层与TCP/IP协议族通信的中间软件抽象层,是一组接口,由操作系统提供; Socket将复杂的TCP/IP协议处理和通信缓存管理都隐藏在接口后面,对用户来说就是使用简单的接口进行网络应用编程…

【python】OpenCV—Scanner

文章目录 1、需求描述2、代码实现3、涉及到的库函数cv2.arcLengthcv2.approxPolyDPskimage.filters.threshold_localimutils.grab_contours 4、完整代码5、参考 1、需求描述 输入图片 扫描得到如下的结果 用OpenCV构建文档扫描仪只需三个简单步骤: 1.边缘检测 2.使用图像中…

02线性表 - 链表

这里是只讲干货不讲废话的炽念,这个系列的文章是为了我自己以后复习数据结构而写,所以可能会用一种我自己能够听懂的方式来描述,不会像书本上那么枯燥和无聊,且全系列的代码均是可运行的代码,关键地方会给出注释^_^ 全…

windows edge自带的pdf分割工具(功能)

WPS分割pdf得会员,要充值!网上一顿乱找,发现最简单,最好用,免费的还是回到Windows。 Windows上直接在edge浏览器打开PDF,点击 打印 按钮,页面下选择对应页数 打印机 选择 另存为PDF,然后保存就…

memcached 高性能内存对象缓存

memcached 高性能内存对象缓存 memcache是一款开源的高性能分布式内存对象缓存系统,常用于做大型动态web服务器的中间件缓存。 mamcached做web服务的中间缓存示意图 当web服务器接收到请求需要处理动态页面元素时,通常要去数据库调用数据,但…

ProtoBuf的安装(win+ubuntu+centos版本)

Win下安装ProtoBuf教程 WProtoBuf Win版本 上方链接就是ProtoBuf官方在Github上面的仓库,我这里下的是21.11版本,至于你要下哪个版本,可以根据自己的需要去下载。 首先点击链接,进入首页,向下滑就可以找到ProtoBuf…

加密传输及相关安全验证:

1.1. 加密: 1.1.1. 对称加密: 特点:加解密用一个密钥,加解密效率高,速度快,有密钥交互的问题问题:双方如何交互对称密钥的问题,用非对称密钥的公钥加密对称密钥的混合加密方式常用…

IP溯源工具--IPTraceabilityTool

工具地址:xingyunsec/IPTraceabilityTool: 蓝队值守利器-IP溯源工具 (github.com) 工具介绍: 在攻防演练期间,对于值守人员,某些客户要求对攻击IP都进行分析溯源,发现攻击IP的时候,需要针对攻击IP进行分析…