神经网络超参数优化

遗传算法与深度学习实战(16)——神经网络超参数优化

    • 0. 前言
    • 1. 深度学习基础
      • 1.1 传统机器学习
      • 1.2 深度学习
    • 2. 神经网络超参数调整
      • 2.1 超参数调整策略
      • 2.2 超参数调整对神经网络影响
    • 3. 超参数调整规则
    • 小结
    • 系列链接

0. 前言

我们已经学习了多种形式的进化计算,从遗传算法到粒子群优化,以及进化策略和差分进化等高级方法。在之后的学习中,我们将使用这些进化计算 (Evolutionary Computation, EC) 方法来改进深度学习 ( Deep learning, DL),通常称为进化深度学习 (Evolutionary Deep Learning, EDL)。
然而,在构建用于解决 DL 问题的 EDL 解决方案之前,我们必须了解要解决的问题以及如何在没有 EC 的情况下解决它们,毕竟 EC 只是用来改进 DL 的工具。因此,在应用 EC 方法于超参数优化 (Hyperparameter Optimization, HPO) 之前,我们首先介绍超参数优化的重要性和一些手动调整策略。

1. 深度学习基础

1.1 传统机器学习

传统应用程序中,系统是通过使用程序员编写的复杂算法来实现智能化的。例如,假设我们希望识别照片中是否包含狗。在传统的机器学习 (Machine Learning, ML) 中,需要机器学习研究人员首先确定需要从图像中提取的特征,然后提取这些特征并将它们作为输入传递给复杂算法,算法解析给定特征以判断图像中是否包含狗:

传统机器学习

然而,如果要为多种类别图像分类手动提取特征,其数量可能是指数级的,因此,传统方法在受限环境中效果很好(例如,识别证件照片),而在不受限制的环境中效果不佳,因为每张图像之间都有较大差异。
我们可以将相同的思想扩展到其他领域,例如文本或结构化数据。过去,如果希望通过编程来解决现实世界的任务,就必须了解有关输入数据的所有内容并编写尽可能多的规则来涵盖所有场景,并且不能保证所有新场景都会遵循已有规则。
传统机器学习的主要特点是以有限的特征集和显式规则为基础,从大量数据中学习模型,并利用学习到的模型对新数据进行预测或分类;主要方法包括:决策树、朴素贝叶斯分类、支持向量机、最近邻分类、线性回归、逻辑回归等,这些方法通常需要经过数据预处理、特征选择、模型训练和模型评估等一系列步骤,以达到更好的分类或预测效果。
传统机器学习的优点在于它们的理论基础比较成熟,训练和推理速度相对较快,并且可以适用于各种类型的数据,此外,对于一些小规模的数据集,传统机器学习方法的效果也相对不错。然而,传统机器学习方法也有相当明显的局限性,例如,由于传统机器学习方法依赖于手动选择的特征,因此难以捕捉数据中的复杂非线性关系;同时,这些方法通常不具备自适应学习能力,需要人工干预来调整模型。

1.2 深度学习

神经网络内含了特征提取的过程,并将这些特征用于分类/回归,几乎不需要手动特征工程,只需要标记数据(例如,哪些图片是狗,哪些图片不是狗)和神经网络架构,不需要手动提出规则来对图像进行分类,这减轻了传统机器学习技术强加给程序员的大部分负担。
训练神经网络需要提供大量样本数据。例如,在前面的例子中,我们需要为模型提供大量的狗和非狗图片,以便它学习特征。神经网络用于分类任务的流程如下,其训练与测试是端到端 (end-to-end) 的:

神经网络训练
深度学习(Deep Learning, DL)是一类基于神经网络的机器学习算法,其主要特点是使用多层神经元构成的深度神经网络,通过大规模数据训练模型并自动地提取、分析、抽象出高级别的特征,经典的深度神经网络架构示例如下所示:

深度神经网络架构

深度学习的优势在于它可以自动地从大量非结构化或半结构化的数据中学习,同时可以发现数据之间的隐含关系和规律,有效地处理语音、图像、自然语言等复杂的数据。常用的神经网络模型包括多层感知机 (Multilayer Perceptron, MLP)、卷积神经网络 (Convolutional Neural Network, CNN)、循环神经网络 (Recurrent Neural Network, RNN) 等。
深度学习目前已经广泛应用于图像识别、语音识别、自然语言处理等领域,如人脸识别、自动驾驶、智能客服、机器翻译等。虽然深度学习在很多领域取得了出色的成果,但是深度神经网络的训练和优化也存在一些难点和挑战,如梯度消失和梯度爆炸等问题,需要使用一系列优化算法和技巧来解决。

2. 神经网络超参数调整

深度学习模型面临的困难之一是如何调整模型选项和超参数来改进模型。DL 模型中通常都会涉及许多选项和超参数,但通常缺乏详细说明调整的效果,通常研究者仅仅展示最先进模型的效果,经常忽略模型达到最优性能所需的大量调整工作。
通常,学习如何使用不同选项和调整超参数需要大量的建模经验。如果没有进行调整,许多模型可能无法达到最优性能。这不仅是一个经验问题,而且也是 DL 领域本身的一个问题。我们首先学习使用 PyTorch 构建一个基础深度学习模型,用于逼近给定函数。

给定函数

2.1 超参数调整策略

在本节中,我们将介绍一些模型选项和调整 DL 模型超参数的技巧和策略。其中一些技巧是根据大量模型训练经验获得的,但这些策略也是需要不断发展的,随着 DL 的不断发展,模型选项也在不断的扩充。
接下来,我们介绍如何使用超参数和其他选项。添加超参数:batch_sizedata_step。超参数 batch_size 用于确定每次前向传递中输入到网络的数据样本数量;超参数 data_step 用于控制生成的训练数据量:

import torch
import torch.nn as nn
from torch.autograd import Variable
import torch.nn.functional as F
import torch.optim as optim
from torch.utils.data import TensorDataset, DataLoader
#plotting
from matplotlib import pyplot as plt
from IPython.display import clear_output
#for performance timing
import timeresults = []hp_test = "lr = 3.5e-01" #@param {type:"string"}
learning_rate = 3.5e-01
epochs = 500
middle_layer = 16
batch_size = 25
data_step = .5
data_min = -5
data_max = 5def function(x):return (2*x + 3*x**2 + 4*x**3 + 5*x**4 + 6*x**5 + 10) Xi = np.reshape(np.arange(data_min,data_max, data_step), (-1, 1))
yi = function(Xi)
inputs = Xi.shape[1]
yi = yi.reshape(-1, 1)
plt.plot(Xi, yi, 'o', color='black')
plt.plot(Xi,yi, color="red")tensor_x = torch.Tensor(Xi) # transform to torch tensor
tensor_y = torch.Tensor(yi)dataset = TensorDataset(tensor_x,tensor_y) # create your datset
dataloader = DataLoader(dataset, batch_size= batch_size, shuffle=True) # create your dataloaderclass Net(nn.Module):def __init__(self, inputs, middle):super().__init__()self.fc1 = nn.Linear(inputs,middle)    self.fc2 = nn.Linear(middle,middle)    self.out = nn.Linear(middle,1)def forward(self, x):x = F.relu(self.fc1(x))     x = F.relu(self.fc2(x))    x = self.out(x)return xmodel = Net(inputs, middle_layer)
print(model)loss_fn = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=learning_rate)epoch_report = 25
history = []
start = time.time()
for i in range(epochs):        for X, y in iter(dataloader):# wrap the data in variablesx_batch = Variable(torch.Tensor(X))y_batch = Variable(torch.Tensor(y))                   # forward passy_pred = model(x_batch)        # compute and print lossloss = loss_fn(y_pred, y_batch)  history.append(loss.data/batch_size)         # reset gradientsoptimizer.zero_grad()        # backwards passloss.backward()        # step the optimizer - update the weightsoptimizer.step()  if (i+1) % epoch_report == 0:clear_output()y_ = model(tensor_x)plt.plot(Xi, yi, 'o', color='black')plt.plot(Xi,y_.detach().numpy(), 'r')plt.show()print(f"[{i}] Loss = {loss.data}")time.sleep(1)
plt.plot(history)
end = time.time() - startX_a = torch.rand(100,1).clone() * 10 - 5
y_a = model(X_a)
y_a = y_a.detach().numpy()
results.append([hp_test,end, X_a, y_a])fig = plt.figure()
ax1 = fig.add_subplot(111)
for test,t,x,y in results:ax1.scatter(x, y, s=10, marker="s", label=f"{test} in {t:0.1f}s")plt.legend(loc='upper left')
plt.plot(Xi, yi, 'o', color='black')
plt.show()

2.2 超参数调整对神经网络影响

middle_layer 的值由 5 修改为 25,运行代码后,观察两次测试的预测输出,可以看到 middle_layer25 时的模型性能更好。同时可以看到,模型的训练模型的时间略有不同,这是由于更大的模型需要更长的训练时间。

隐藏层数修改

可以修改超参数 batch_sizedata_step,观察不同超参数对模型性能的影响。但需要注意的是,这些值是相互关联的,如果通过将 data_step 减小到 0.1 来增加数据量,则同样需要增加 batch_size
下图展示了在增加数据量时改变和不改变批大小的结果,可以看到,训练 500epoch 所需的训练时间差异明显。

batch_size

继续修改其它超参数,将 learning_rate3.5e-06 修改为 3.5e-01,在调整超参数时,总体目标是创建一个能够快速训练并产生最佳结果的最小(参数量)模型。

学习率

3. 超参数调整规则

即使本节中仅仅只有五个超参数,超参数的调整仍然可能遇到困难,因此一个简单的方法是按照以下步骤进行操作:

  • 设置网络大小 - 在本节中,通过修改 middle_layer 的值实现,通常,首先调整网络大小或层数。但需要注意的是,增加线性层数通常并不如增加层内网络节点数量有效
    超参数训练规则#1:网络大小——增加网络层数能够从数据中提取更多特征,扩展或减小模型宽度(节点数)能够调整模型的拟合程度
  • 控制数据变化性 – 通常认为深度学习模型训练需要大量的数据,虽然深度学习模型可能会从更多的数据中获益,但这更多依赖于数据集中的变化性,在本节中,我们使用 data_step 值来控制数据的变化性,但通常情况下我们无法控制数据的变化性。因此,如果数据集包含较大的变化性,则很可能相应的需要增加模型的层数和宽度。与 MNIST 数据集中的手写数字图片相比,Fashion-MNIST 数据集中服饰图片的变化性要小得多
    超参数训练规则#2:数据变化性——更具变化性的数据集需要更大的模型,以提取更多特征并学习更复杂的解决方案
  • 选择批大小 - 调整模型的批大小可以显著提高训练效率,然而,批大小并不能解决训练性能问题,增加批大小可能对降低最终模型性能,批大小需要基于输入数据的变化性进行调优,输入数据变化性较大时,较小的批大小通常更有益(范围通常在 16-64 之间),而变化性较小的数据可能需要较大的批大小(范围通常在 64-256 之间,甚至更高)
    超参数训练规则#3:批大小——如果输入数据变化性较大,则减小批大小,对于变化较小且更统一的数据集,增加批大小
  • 调整学习率 - 学习率控制模型学习的速度,学习率与模型的复杂性相关,由输入数据的变化性驱动,数据变化性较高时,需要较小的学习率,而更均匀的数据可以采用较高的学习率,调整模型大小可能也可能需要调整学习率,因为模型复杂性发生了变化
    超参数训练规则#4:学习率——调整学习率以适应输入数据的变化性,如果需要增加模型的大小,通常也需要减小学习率
  • 调整训练迭代次数 - 处理较小规模的数据集时,模型通常会快速收敛到某个基准解,因此,可以简单地减少模型的 epochs (训练迭代次数),但是,如果模型较复杂且训练时间较长,则确定总的训练迭代次数可能更为困难。但多数深度学习框架提供了提前停止机制,它通过监视指定损失值,并在损失值不再变化时自动停止训练,因此,通常可以选择可能需要的最大训练迭代次数,另一种策略是定期保存模型的权重,然后在需要时,可以重新加载保存的模型权重并继续训练
    超参数训练规则#5:训练迭代次数——使用可能需要的最大训练迭代次数,使用提前停止等技术来减少训练迭代次数

使用以上五条策略能够更好的调整超参数,但这些技术只是一般规则,可能会有网络配置、数据集和其他因素改变这些一般规则。接下来,我们将进一步讨论构建稳定模型时可能需要决定的各种模型选项。
除了超参数外,模型改进的最大动力源于模型所选用的各种选项。DL 模型提供了多种选项,具体取决于实际问题和网络架构,但通常模型的细微改变就足以从根本上改变模型的拟合方式。
模型选项包括激活函数、优化器函数、以及网络层的类型和数量的选用。网络层的深度通常由模型需要提取和学习的特征数量所决定,网络层的类型(全连接、卷积或循环网络等)通常由需要学习的特征类型决定。例如,使用卷积层来学习特征的聚类,使用循环神经网络来确定特征的出现顺序。
因此,大多数 DL 模型的网络大小和层类型都受数据变化性和需要学习的特征类型的驱动。对于图像分类问题,卷积层用于提取视觉特征,例如眼睛或嘴巴,循环神经网络层用于处理语言或时间序列数据。
大多数情况下,模型选项需要关注的包括激活、优化器和损失函数。激活函数通常由问题类型和数据形式决定,避免在选项调整的最后阶段修改激活函数。通常,优化器和损失函数的选择决定了模型训练的好坏。下图显示了使用四种不同优化器来训练上一节模型得到的结果,其中超参数 middle_layer 值为 25,可以看出,与 AdamRMSprop 相比,随机梯度下降 (Stochastic Gradient Descent, SGD) 和 Adagrad 表现较差。

不同优化器

损失函数同样会对模型训练产生重大影响。在回归问题中,我们可以使用两个不同的损失函数:均方误差 (mean-squared error, MSE) 和平均绝对误差 (mean absolute error, MAE),下图显示了使用的两个不同损失函数的模型性能对比结果。可以看到,MAE 损失函数的效果更好一些。

不同损失函数

超参数训练规则#6:模型修改作为一般规则,更改模型架构或关键模型选项,都需要重新调整所有超参数

事实上,我们可能需要花费数天甚至数月的时间来调整模型的超参数,直到得到更好的损失和优化函数。超参数调整和模型选项选择并非易事,选用不合适的选项甚至得到更差的模型。在构建有效的 DL 模型时,通常会定义模型并选择最适合实际问题的选项。然后,通过调整各种超参数和选项优化模型。

小结

超参数优化的目标是通过调整模型的超参数,如学习率、正则化系数、网络架构、批大小等,来最大化模型的性能和泛化能力。选择合适的方法取决于问题的特性、计算资源和优化目标的复杂性。本节中,我们介绍了一些常见模型选项和调整DL模型超参数的技巧和策略。

系列链接

遗传算法与深度学习实战(1)——进化深度学习
遗传算法与深度学习实战(2)——生命模拟及其应用
遗传算法与深度学习实战(3)——生命模拟与进化论
遗传算法与深度学习实战(4)——遗传算法(Genetic Algorithm)详解与实现
遗传算法与深度学习实战(5)——遗传算法中常用遗传算子
遗传算法与深度学习实战(6)——遗传算法框架DEAP
遗传算法与深度学习实战(7)——DEAP框架初体验
遗传算法与深度学习实战(8)——使用遗传算法解决N皇后问题
遗传算法与深度学习实战(9)——使用遗传算法解决旅行商问题
遗传算法与深度学习实战(10)——使用遗传算法重建图像
遗传算法与深度学习实战(11)——遗传编程详解与实现
遗传算法与深度学习实战(12)——粒子群优化详解与实现
遗传算法与深度学习实战(13)——协同进化详解与实现
遗传算法与深度学习实战(14)——进化策略详解与实现
遗传算法与深度学习实战(15)——差分进化详解与实现

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

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

相关文章

鸿蒙开发实战项目【硅谷租房】--- 项目介绍

目录 一、简述 二、项目资料 2.1 UI设计稿 2.2 服务器 2.3 Apifox接口JSON文件 使用 Apifox 测试接口 一、简述 这是一个基于 鸿蒙 API12 开发的移动端租房 App,用户可以使用该应用搜索租房列表、查看房屋详情、预约租房等。 该项目的tabbar包含五部分&…

网站集群批量管理-Ansible(ad-hoc)

1. 概述 1. 自动化运维: 批量管理,批量分发,批量执行,维护 2. 无客户端,基于ssh进行管理与维护 2. 环境准备 环境主机ansible10.0.0.7(管理节点)nfs01 10.0.0.31(被管理节点)backup10.0.0.41(被管理节点) 2.1 创建密钥认证 安装sshpass yum install -y sshpass #!/bin/bash ##…

Android终端GB28181音视频实时回传设计探讨

技术背景 好多开发者,在调研Android平台GB28181实时回传的时候,对这块整体的流程,没有个整体的了解,本文以大牛直播SDK的SmartGBD设计开发为例,聊下如何在Android终端实现GB28181音视频数据实时回传。 技术实现 Andr…

操作系统导论阅读 - 虚拟化

近期系统性地过一下操作系统导论 第二章 操作系统介绍 冯诺伊曼架构 冯诺依曼架构的核心思想: 使用二进制存储数据像存储数据一样来存储程序计算机由输入设备,输出设备以及控制器,运算器和存储器五部分组成 通常使用的键盘,…

SevenZip++显示当前压缩进度的范例

以前写7z压缩工具,直接调用命令行的话,因为无法提取命令行的压缩进度所以无法在界面上显示当前压缩进度,现在用SevenZip,成功提取到了压缩到7z过程中的压缩进度,先在命令行中展示一下效果吧。 直接上代码,看…

企业架构系列(19)TOGAF企业连续体和构建块

TOGAF 企业连续体(Enterprise Continuum)是一个用于对架构描述进行分类的框架。它有助于突出架构师在哪个抽象层次上工作,并概述了不同目的下应使用的不同层次。而构建块(Building Blocks)是用来描述这些架构和解决方案…

机器学习——自动化机器学习(AutoML)

机器学习——自动化机器学习(AutoML) 自动化机器学习(AutoML)——2024年的新趋势什么是AutoML?AutoML的关键组成部分AutoML的优势AutoML 实例:使用Auto-sklearn进行回归分析AutoML的应用领域2024年值得关注…

高效的读书与笔记管理:打造个人知识体系

01 读书学习的常见问题 1、读书⼯具分散,划线和笔记分散,导致我们的复习、搜索效率低。⽐如不同书籍中,提到了同⼀个问题的观点,很难进行关联。 2、读书,仅限于读,知道别⼈的观点,但是缺乏内…

【Qt】控件概述(3)—— 显示类控件

显示类控件 1. QLabel——标签1.1 setPixmap设置图片1.2 setAlignment设置文本对齐方式1.3 setWordWrap设置自动换行1.4 setIndent设置缩进1.5 setMargin设置边距1.6 body 2. QLCDNumber2.1 使用QTimer实现一个倒计时效果2.2 使用循环的方式实现倒计时 3. QProgressBar——进度…

商贸物流痛点解析

商贸物流痛点解析 在当今全球化的商业环境中,商贸与物流之间的紧密协作已成为业务成功的关键因素。然而,许多组织面临着信息不对称、资源配套不足以及系统间隔离等痛点,这些问题严重阻碍了商贸体系与物流、仓储和园区的有效联动,…

Linux高效查日志命令介绍

说明:之前介绍Linux补充命令时,有介绍使用tail、grep命令查日志; Linux命令补充 今天发现仅凭这两条命令不够,本文扩展介绍一下。 命令一:查看日志开头 head -n 行数 日志路径如下,可以查看程序启动是否…

数据库SQL基础教程(二)

目录 连接(JOIN) 语法: 不同的 SQL JOIN INNER JOIN 关键字 LEFT JOIN 关键字 SQL LEFT JOIN 语法 RIGHT JOIN 关键字 SQL RIGHT JOIN 语法 FULL OUTER JOIN 关键字 SQL FULL OUTER JOIN 语法 UNION 操作符 SQL UNION 语法 SQL UNION ALL 语法 SELECT I…

uniapp引入ThorUI的方法

1、下载文件 2、复制相应的文件除了pages 3、往项目中复制即可 4、引入即可实现 5、添加easycome自动引入

单片机(学习)2024.10.9

目录 汇编整体分类 1.指令 2.伪操作 3.伪指令 汇编代码 汇编初始化 数据搬运指令 算术运算指令 加法 减法 乘法 比较指令 跳转指令 逻辑运算指令 与或,异或 左移右移 内存操作 LOAD/STORE 指令 写 读 CPU的栈机制 栈的概念 栈的种类 1.空栈(…

Java生成Excel_低内存占用_更快

EasyExcel:高效Java Excel工具,解决大文件读写难题 EasyExcel是一个基于Java的、快速简洁且能有效解决大文件内存溢出问题的Excel处理工具。它使得用户可以在无需过多关注性能和内存消耗的情况下,轻松实现Excel文件的读写功能。相较于传统的…

无头浏览器测试:如何使用 Puppeteer 和 Browserless?

什么是无头浏览器测试? 无头浏览器测试通常指没有头的物体或东西,在浏览器的语境中,它指的是没有 UI 的浏览器模拟。无头浏览器自动化使用 Web 浏览器进行端到端测试,而无需加载浏览器的 UI。 无头模式是一个功能,它…

Canvas:AI协作的新维度

在人工智能的浪潮中,OpenAI的最新力作Canvas,不仅是一款新工具,它标志着人工智能协作方式的一次革命性飞跃。Canvas为写作和编程提供了一个全新的交互界面,让用户能够与ChatGPT进行更紧密、更直观的协作。 ​​​​​​​ Canvas的…

Android targetSdkVersion 升级为34 问题处理

原因是发布到GooglePlay遭到拒绝,需要最低API level为34。之前为31,感觉还挺高的,但是GooglePlay需要的更高。 记录下处理问题: 1.升级gradle版本为8.0.2 之前是: classpath com.android.tools.build:gradle:7.1.0-…

sql注入第8关

手工注入麻烦 目录 判断闭合方式 判断注入类型 手工注入 1、获取数据库名 2、爆破数据库的名字(security) 3、爆破表的数量 4、判断表名的长度 5、判断表的列名数量 6、判断表的列名的名字 7、获取表的数据 8、判断数据的长度 9、判断数据的…

Golang | Leetcode Golang题解之第464题我能赢吗

题目&#xff1a; 题解&#xff1a; func canIWin(maxChoosableInteger, desiredTotal int) bool {if (1maxChoosableInteger)*maxChoosableInteger/2 < desiredTotal {return false}dp : make([]int8, 1<<maxChoosableInteger)for i : range dp {dp[i] -1}var dfs …