神经网络中如何优化模型和超参数调优(案例为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]* 3def 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+1train_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:  # RMSpropoptimizer = 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 = 0train_l2 = 0for 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 Losssmooth_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.0test_smooth_l1 =0with 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 /= ntraintest_l2 /= ntesttest_smooth_l1 /= ntest#!!!!!!!!!!!!!!!!!!!train_loss[ep] = train_l2test_loss[ep] = test_l2t2 = 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))#!!!!!!!!!!!!!!!!1if 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.mzph.cn/news/874192.shtml

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

相关文章

c++应用网络编程之五Windows常用的网络IO模型

一、Windows的网络编程 其实对开发者而言,只有Windows和其它平台。做为一种普遍流行的图形OS,其一定会与类Linux的编程有着明显的区别,这点当然也会体现在网络编程上。Windows有着自己一套相对独立的上层Socket编程模型或者说框架&#xff0…

Redis集群部署Windows版本

Redis集群 之前因为数据量的原因,并没有进行Redis集群的配置需要,现在由于数据量大,需要进行集群部署。 最初在windows系统部署,需要Redis的windows版本,但官方没有windows版本,所以需要去gitHub上找由民…

STM32 移植MQTT

在STM32上移植MQTT客户端库(如Paho MQTT C库)涉及几个关键步骤,包括库的选择、环境配置、代码集成和测试。下面是一个概括的指南,帮助你开始这个过程。 1. 选择MQTT库 对于STM32,你可以选择多个MQTT库,但…

【STM32】MPU内存保护单元

注:仅在F7和M7系列上使用介绍 功能: 设置不同存储区域的存储器访问权限(管理员、用户) 设置存储器(内存和外设)属性(可缓冲、可缓存、可共享) 优点:提高嵌入式系统的健壮…

Bash 学习摘录

文章目录 1、变量和参数的介绍(1)变量替换$(...) (2)特殊的变量类型export位置参数shift 2、引用(1)引用变量(2)转义 3、条件判断(1)条件测试结构&#xff08…

Qt+OpenCascade开发笔记(一):occ的windows开发环境搭建(一):OpenCascade介绍、下载和安装过程

若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/140604141 长沙红胖子Qt(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV…

[C++进阶]模板进阶

此篇是学完stl后对于模板的补充 建议先看看这个[C初阶]模板初阶-CSDN博客 一、类模板 此处是对初阶讲过的 1. 类模板的定义格式 template<class T1, class T2, …, class Tn> class 类模板名 {}; 例如我们之前学习过的vector类&#xff1a; template<class T>…

C++中的多路转接技术之epoll

epoll 是干什么的&#xff1f;举个简单的例子 epoll的相关系统调用**epoll_create**和epoll_create1区别 epoll_ctl参数解释 **epoll_wait**参数说明返回值 epoll的使用 **epoll**工作原理epoll的优点(和 **select** 的缺点对应)epoll工作方式**水平触发**Level Triggered 工作…

Springboot 启动时Bean的创建与注入(一)-面试热点-springboot源码解读-xunznux

Springboot 启动时Bean的创建与注入&#xff0c;以及对应的源码解读 文章目录 Springboot 启动时Bean的创建与注入&#xff0c;以及对应的源码解读构建Web项目流程图&#xff1a;堆栈信息&#xff1a;堆栈信息简介堆栈信息源码详解1、main:10, DemoApplication (com.xun.demo)2…

出海收款平台有哪些?全球首要15种收付平台收费比较

在跨境电商的浪潮中&#xff0c;收款问题一直是企业面临的最大挑战之一。随着全球化贸易的不断深入&#xff0c;越来越多的外国企业希望进入中国市场&#xff0c;但受限于法律法规和支付体系的不同&#xff0c;他们往往无法直接从中国用户手中收取款项。这时&#xff0c;第三方…

HashMap与ConcurrentHashMap

文章目录 HashMap1.1 HashMap 的数据结构&#xff1f;1.2 HashMap 的动态扩容1.3 Hash实现方法1.4 如何解决Hash冲突 ConcurrentHashMap HashMap 1.1 HashMap 的数据结构&#xff1f; 哈希表结构&#xff08;链表散列&#xff1a;数组链表&#xff09;实现&#xff0c;结合数…

详细分析Springboot自定义启动界面(附Demo)

目录 前言1. banner.text1.1 配置文件关闭1.2 启动类关闭1.3 命令行关闭 2. 自定义Banner类3. 自动配置类4. 总结 前言 实现自定义启动动画是一项有趣的任务&#xff0c;虽然Spring Boot本身不提供内置的动画功能&#xff0c;但可以通过一些技巧来实现 以下主要以Demo的形式展…

三字棋游戏(C语言详细解释)

hello&#xff0c;小伙伴们大家好&#xff0c;算是失踪人口回归了哈&#xff0c;主要原因是期末考试完学校组织实训&#xff0c;做了俄罗斯方块&#xff0c;后续也会更新&#xff0c;不过今天先从简单的三字棋说起 话不多说&#xff0c;开始今天的内容 一、大体思路 我们都知…

pytest钩子hook使用2

pytest是一种用于编写单元测试的Python库。它允许程序员编写测试用例来验证代码的正确性&#xff0c;并提供了一系列的勾子&#xff08;hooks&#xff09;来在测试的不同阶段执行一些额外的操作。 使用pytest的勾子&#xff0c;可以在测试运行过程中插入自定义代码。下面是一些…

springSecurity学习之springSecurity注解使用

springSecurity注解使用 在使用springboot的时候&#xff0c;大家更习惯于使用注解来进行配置&#xff0c;那么springSecurity注解怎么使用呢 首先开启注解 EnableGlobalMethodSecurity(// Spring Security 开启注解securedEnabledtrue, // 开启Secured注解,会创建切点&…

MongoDB教程(十三):MongoDB覆盖索引

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; 文章目录 引言什么是覆盖…

数据结构(栈及其实现)

栈 概念与结构 栈&#xff1a;⼀种特殊的线性表&#xff0c;其只允许在固定的⼀端进⾏插⼊和删除元素操作。 进⾏数据插⼊和删除操作的⼀端称为栈顶&#xff0c;另⼀端称为栈底。栈中的数据元素遵守后进先出 LIFO&#xff08;Last In First Out&#xff09;的原则。 压栈&…

date hwclock

目录 1.查看操作系统时间和bios时间 2.将系统时间同步到硬件时钟 3.将硬件时间同步到系统时间 1.查看操作系统时间和bios时间 date && hwclock Wed Jun 26 23:05:19 CST 2024 Wed 26 Jun 2024 11:05:24 PM CST -0.380328 seconds 2.将系统时间同步到硬件时钟 #…

PyCharm创建一个空的python项目

1.设置项目路径 2.配置python解释器 右下角可以选择always

【Linux】线程——生产者消费者模型、基于阻塞队列的生产消费者模型、基于环形队列的生产消费者模型、POSIX信号量的概念和使用

文章目录 Linux线程6. 生产消费者模型6.1 基于阻塞队列的生产消费者模型6.1.1 阻塞队列模型实现 6.2 基于环形队列的生产消费者模型6.2.1 POSIX信号量的概念6.2.2 POSIX信号量的使用6.2.3 环形队列模型实现 Linux线程 6. 生产消费者模型 生产消费者模型的概念 生产者消费者模…