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

总结:

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

中级: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.mfbz.cn/a/843097.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【人工智能】机器学习 -- 贝叶斯分类器

目录 一、使用Python开发工具,运行对iris数据进行分类的例子程序NaiveBayes.py,熟悉sklearn机器实习开源库。 1. NaiveBayes.py 2. 运行结果 二、登录https://archive-beta.ics.uci.edu/ 三、使用sklearn机器学习开源库,使用贝叶斯分类器…

Raid5数据恢复—Raid5热备盘同步失败导致通用卷不可用的数据恢复案例

Raid5算法: Raid5算法也被称为“异或运算”。异或是一个数学运算符,它应用于逻辑运算。异或的数学符号为“⊕”,计算机符号为“xor”。异或的运算法则为:a⊕b (a ∧ b) ∨ (a ∧b)。如果a、b两个值不相同,则异或结果为…

探索XEX数字资产交易的优势与操作指南

随着数字资产市场的快速发展,越来越多的投资者开始关注并参与其中。XEX交易所作为一个新兴的数字资产交易平台,以其用户友好的界面和高效的交易服务,迅速吸引了大量用户。本文将介绍XEX数字资产交易的主要特点和优势,帮助新手更好…

[Spring Boot]Protobuf解析MQTT消息体

简述 本文主要针对在MQTT场景下,使用Protobuf协议解析MQTT的消息体 Protobuf下载 官方下载 https://github.com/protocolbuffers/protobuf/releases网盘下载 链接:https://pan.baidu.com/s/1Uz7CZuOSwa8VCDl-6r2xzw?pwdanan 提取码:an…

网易易盾图标点选验证码识别代码

简介 网易图标点选一直都是一个大难题,如上图所示。难点之一是图标变幻莫测,很难刷出有重复的图标,所以使用传统等等方式去标注、识别具有较大的难度。 经过我们大量的数据标注,终于完成了这款验证码的识别。 目前我们提供两种识…

基于若依的ruoyi-nbcio流程管理系统修正自定义业务表单的回写bug

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码: https://gitee.com/nbacheng/ruoyi-nbcio 演示地址:RuoYi-Nbcio后台管理系统 http://218.75.87.38:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码: h…

均值滤波算法及实现

均值滤波器的使用场景: 均值滤波器使用于处理一些如上述蓝色线的高斯噪声场景 红色曲线是经过均值滤波处理后的数据。主要因为均值滤波设置数据缓冲区(也即延时周期),使得测量值经过缓冲不会出现特别大的变化。 黄色曲线为高斯噪声…

新版GPT-4omini上线!快!真TM快!

大半夜,OpenAI突然推出了GPT-4o mini版本。 当我看到这条消息时,正准备去睡觉。mini版本质上是GPT-4o模型的精简版本,没有什么革命性的创新,因此我并没有太在意。 结果今天早上一觉醒来发现伴随GPT-4o mini上线,官网和…

linux进程优先级——优先值、调度算法、进程性质

前言:本篇内容主要讲解linux下进程的优先级。 优先级的内容相对较少, 最重要的内容就是cpu的调度方法。 内容相对容易理解。 ps:本节内容适合了解冯诺依曼和操作系统的管理方式以及进程PCB的友友们进程观看 进程的优先级是什么 进程的优先级…

Android11 framework 禁止三方应用开机自启动

Android11应用自启动限制 大纲 Android11应用自启动限制分析验证猜想:Android11 AOSP是否自带禁止三方应用监听BOOT_COMPLETED​方案禁止执行非系统应用监听到BOOT_COMPLETED​后的代码逻辑在执行启动时判断其启动的广播接收器一棍子打死方案(慎用&#…

【Spark官方文档部分翻译】RDD编程指南(RDD Programming Guide)

写在前面 内容如何选择 本翻译只翻译本人认为精华的部分,本人认为的Spark的一些核心理念,编程思想。一些特别基础的操作包括但不限于搭建环境就不在此赘述了。 配套版本 本系列基于Spark 3.3.1,Scala 2.12.10,进行翻译总结 原…

专业PDF编辑工具:Acrobat Pro DC 2024.002.20933绿色版,提升你的工作效率!

软件介绍 Adobe Acrobat Pro DC 2024绿色便携版是一款功能强大的PDF编辑和转换软件,由Adobe公司推出。它是Acrobat XI系列的后续产品,提供了全新的用户界面和增强功能。用户可以借助这款软件将纸质文件转换为可编辑的电子文件,便于传输、签署…

stm32:CAN通讯

目录 介绍 物理层​编辑 差分信号 总线网络 协议层 CAN的 帧/报文 种类 数据帧 远程帧(遥控帧) 错误帧 过载帧 帧间隔 总线仲裁 位同步 数据同步 波特率 stm32的CAN外设 工作模式 测试模式 功能框图 时序 标准时序 例子 环回静默…

应用层——HTTP

像我们电脑和手机使用的应用软件就是在应用层写的,当我们的数据需要传输的时候换将数据传递到传输层。 应用层专门给用户提供应用功能,比如HTTP,FTP… 我们程序员写的一个个解决我们实际的问题都在应用层,我们今天来聊一聊HTTP。 协议 协议…

游泳耳机哪个牌子最好?公认最好的四大游泳耳机测评分享

游泳耳机,作为水上运动爱好者的贴心伴侣,已被公认为提升水下体验的利器。然而,在抖音、贴吧等社交平台上,我们也不难发现一些关于游泳耳机性能不佳、使用效果差,甚至对耳朵造成不适的反馈。这种矛盾现象的出现&#xf…

HTML5大作业三农有机,农产品,农庄,农旅网站源码

文章目录 1.设计来源1.1 轮播图页面头部效果1.2 栏目列表页面效果1.3 页面底部导航效果 2.效果和源码2.1 源代码 源码下载万套模板,程序开发,在线开发,在线沟通 作者:xcLeigh 文章地址:https://blog.csdn.net/weixin_4…

基于pytorch演练线性回归模型

引言 本文的目的是在前文基于numpy演练可视化梯度下降的代码基础上,使用pytorch来实现一个功能齐全的线性回归训练模型。 为什么仍然使用线性回归模型? 线性回归模型简单,它能让我们聚集在pytorch是如何工作的,而不是模型内部的…

使用百度语音技术实现文字转语音

使用百度语音技术实现文字转语音 SpringBootVue前后端分离项目 调用api接口需要使用AK和SK生成AccessToken,生成getAccessToken的接口有跨域限制,所以统一的由后端处理了 部分参数在控制台->语音技术->在线调试里面能找到 Controller RestController RequestMapping(&q…

C++ | Leetcode C++题解之第268题丢失的数字

题目&#xff1a; 题解&#xff1a; class Solution { public:int missingNumber(vector<int>& nums) {int n nums.size();int total n * (n 1) / 2;int arrSum 0;for (int i 0; i < n; i) {arrSum nums[i];}return total - arrSum;} };

探索 Framer Motion 高级动画技巧:提升前端设计水平

在现代的网页和应用设计中&#xff0c;动画不仅仅是视觉的点缀&#xff0c;更是用户体验的重要组成部分。它能够使界面更具吸引力&#xff0c;提升交互的流畅性&#xff0c;甚至在不经意间传达品牌的个性和态度。然而&#xff0c;要创造出令人惊叹的动效并不容易——直到有了 F…