创建用于预测序列的人工智能模型,用Keras Tuner探索模型的超参数。
上一篇:《创建用于预测序列的人工智能模型(五),调整模型的超参数》
序言:在完成初步的模型研发后,接下来的重点是探索和优化超参数。通过合理调整超参数(如学习率、动量参数、神经元数量等),可以进一步提高模型的性能和准确性。这一过程需要结合工具(如 Keras Tuner)进行自动化测试和优化,从而高效找到最优配置方案。
探索使用 Keras Tuner 调整超参数
在上一节中,你学会了如何粗略地优化随机梯度下降(SGD)损失函数的学习率。这确实是一个非常粗略的尝试:每隔几个 epoch 改变一次学习率并测量损失值变化。然而,这种方式受到损失函数本身在每个 epoch 间波动的影响,因此你可能并没有真正找到最佳值,而只是得到了一个近似值。要真正找到最佳值,你需要在每个潜在值的情况下进行完整的轮次训练,然后比较结果。
而且,这还仅仅是针对一个超参数——学习率。如果你还想优化动量参数(momentum),或者调整其他内容,比如每层的神经元数量、层数等,那么可能需要测试成千上万种选项,而手动实现所有这些训练代码几乎是不可能的。
幸运的是,Keras Tuner 工具让这些变得相对简单。你可以通过以下命令安装 Keras Tuner:
!pip install keras-tuner
安装完成后,你就可以使用它来参数化超参数,并指定需要测试的值范围。Keras Tuner 会为每组参数训练模型,评估其性能,并根据你的目标(例如最小化损失)报告最佳的模型结果。我不会在这里详细介绍所有功能,但会展示如何在这个特定模型中使用它。
假设我们想实验两个方面,首先是调整模型架构中输入层的神经元数量。目前的模型架构是输入层 10 个神经元、隐藏层 10 个神经元,然后是输出层。但如果通过增加输入层的神经元数量,网络的表现可以变得更好呢?比如,你可以尝试将输入层的神经元数量从 10 增加到 30。
回忆一下,输入层的定义如下:
tf.keras.layers.Dense(10, input_shape=[window_size], activation="relu")
如果你想测试比硬编码的 10 更大的值,可以这样写:
tf.keras.layers.Dense(units=hp.Int('units', min_value=10, max_value=30, step=2),
activation='relu', input_shape=[window_size])
这里定义了输入层会用多种值进行测试,从 10 开始,每次增加 2,一直到 30。现在,Keras Tuner 将不再只训练一次模型,而是会训练 11 次!
同时,回忆一下优化器中的动量参数是硬编码为 0.9 的:
optimizer = tf.keras.optimizers.SGD(lr=1e-5, momentum=0.9)
你可以使用 hp.Choice 方法测试多个动量值,例如:
optimizer = tf.keras.optimizers.SGD(hp.Choice('momentum', values=[.9, .7, .5, .3]),
lr=1e-5)
这为动量参数提供了 4 种可能的选择。因此,当与前述输入层神经元数量组合时,总共会有 44 种组合需要测试。Keras Tuner 会自动完成这些训练任务,并报告表现最佳的模型。
为了完成设置,首先需要定义一个函数,用于根据超参数构建模型:
def build_model(hp):
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Dense(
units=hp.Int('units', min_value=10, max_value=30, step=2),
activation='relu', input_shape=[window_size]))
model.add(tf.keras.layers.Dense(10, activation='relu'))
model.add(tf.keras.layers.Dense(1))
model.compile(loss="mse",
optimizer=tf.keras.optimizers.SGD(hp.Choice('momentum',
values=[.9, .7, .5, .3]),
lr=1e-5))
return model
接着,使用安装好的 Keras Tuner 创建一个 RandomSearch 对象来管理所有的迭代:
tuner = RandomSearch(
build_model,
objective='loss', max_trials=150,
executions_per_trial=3, directory='my_dir',
project_name='hello')
注意,你需要通过传递前面定义的函数来指定模型。hp 参数用于控制需要调整的值范围。目标(objective)被设置为 loss,表示我们想要最小化损失值。max_trials 参数限制总实验次数,executions_per_trial 参数可以指定每次实验的训练和评估次数,从而减少随机波动的影响。
开始搜索时,只需调用 tuner.search,就像调用 model.fit 一样:
tuner.search(dataset, epochs=100, verbose=0)
运行本章中所使用的合成序列数据后,Keras Tuner 会根据你定义的选项训练模型并完成所有可能的超参数组合测试。
完成后,你可以调用 tuner.results_summary 查看基于目标的前 10 次实验结果:
tuner.results_summary()
你会看到类似以下的输出:
Results summary
|-Results in my_dir/hello
|-Showing 10 best trials
|-Objective(name='loss', direction='min')
Trial summary
|-Trial ID: dcfd832e62daf4d34b729c546120fb14
|-Score: 33.18723194615371
|-Best step: 0
Hyperparameters:
|-momentum: 0.5
|-units: 28
Trial summary
|-Trial ID: 02ca5958ac043f6be8b2e2b5479d1f09
|-Score: 33.83273440510237
|-Best step: 0
Hyperparameters:
|-momentum: 0.7
|-units: 28
从结果中可以看到,最低损失值是在动量为 0.5 和输入神经元数量为 28 时达到的。你可以通过调用 get_best_models 来检索这些模型以及其他最佳模型。例如,如果你想获取前 4 个最佳模型,可以这样调用:
tuner.get_best_models(num_models=4)
你可以测试这些模型,或者使用找到的最佳超参数从头创建一个新模型,例如:
dataset = windowed_dataset(x_train, window_size, batch_size, shuffle_buffer_size)
model = tf.keras.models.Sequential([
tf.keras.layers.Dense(28, input_shape=[window_size], activation="relu"),
tf.keras.layers.Dense(10, activation="relu"),
tf.keras.layers.Dense(1)
])
optimizer = tf.keras.optimizers.SGD(lr=1e-5, momentum=0.5)
model.compile(loss="mse", optimizer=optimizer)
history = model.fit(dataset, epochs=100, verbose=1)
当我使用这些超参数进行训练,并像之前一样对整个验证集进行预测时,我得到了一个类似于图 10-6 的图表:
图 10-6:优化超参数后的预测图表
对这个模型的 MAE(平均绝对误差)计算结果是 4.47,相比之前的 4.51 有了轻微的改进,相较于上一章统计方法的 5.13 结果更是显著提升。这是在学习率调整为 1e−51e^{-5}1e−5 的情况下完成的,而这个学习率可能还不是最优值。通过 Keras Tuner,你可以进一步调整像这样的超参数,还可以尝试调整中间层的神经元数量,甚至实验不同的损失函数和优化器。尝试一下,看看能否进一步改进这个模型吧!
总结
在本篇中,我们从前几篇的时间序列统计分析出发,尝试将机器学习应用于改进预测。人工智能(机器学习)的核心在于模式匹配,正如预期的那样,我们通过使用深度神经网络(DNN)来发现数据中的模式,成功将平均绝对误差(MAE)降低了近 10%。接着,我们再利用 Keras Tuner 进一步优化超参数,改进了模型的损失值并提升了预测精度。
在接下来的文章中,我们将超越简单的人工智能模型( DNN),探索使用循环神经网络(RNN)来预测序列数据的可能性,并分析其对序列预测的影响。
创建用于预测序列的人工智能模型,用Keras Tuner探索模型的超参数。的更多相关文章
- lecture16-联合模型、分层坐标系、超参数优化及本课未来的探讨
这是HInton的第16课,也是最后一课. 一.学习一个图像和标题的联合模型 在这部分,会介绍一些最近的在学习标题和描述图片的特征向量的联合模型上面的工作.在之前的lecture中,介绍了如何从图像中 ...
- 随机森林RF模型超参数的优化:Python实现
本文介绍基于Python的随机森林(Random Forest,RF)回归代码,以及模型超参数(包括决策树个数与最大深度.最小分离样本数.最小叶子节点样本数.最大分离特征数等)自动优化的代码. ...
- 人工智能中小样本问题相关的系列模型演变及学习笔记(二):生成对抗网络 GAN
[说在前面]本人博客新手一枚,象牙塔的老白,职业场的小白.以下内容仅为个人见解,欢迎批评指正,不喜勿喷![握手][握手] [再啰嗦一下]本文衔接上一个随笔:人工智能中小样本问题相关的系列模型演变及学习 ...
- [DeeplearningAI笔记]序列模型3.7-3.8注意力模型
5.3序列模型与注意力机制 觉得有用的话,欢迎一起讨论相互学习~Follow Me 3.7注意力模型直观理解Attention model intuition 长序列问题 The problem of ...
- R_针对churn数据用id3、cart、C4.5和C5.0创建决策树模型进行判断哪种模型更合适
data(churn)导入自带的训练集churnTrain和测试集churnTest 用id3.cart.C4.5和C5.0创建决策树模型,并用交叉矩阵评估模型,针对churn数据,哪种模型更合适 决 ...
- oracle创建和删除序列
创建序列语法: CREATE SEQUENCE 序列名 [START WITH n] [INCREMENT BY n] [{MINVALUE n}] [{MAXVALUE n|NOMAXVALUE}] ...
- [EULAR文摘] 利用蛋白组学技术开发一项蛋白评分用于预测TNFi疗效
利用蛋白组学技术开发一项蛋白评分与临床参数联用可以增强对TNF拮抗剂对RA疗效的预测效能 Cuppen BV, et al. EULAR 2015. Present ID: OP0130. 背景: 对 ...
- 创建用于编译和运行Java程序的批处理文件
创建用于编译和运行Java程序的批处理文件 每次编译或运行Java程序时,都要在DOS命令行中输入很长的javac或java命令,悟空觉得太麻烦,就编写了一个适用于Windows操作系统的批处理文件b ...
- 成对HMM(Pair HMMs)用于双序列比对--转载
http://blog.163.com/bioinfor_cnu/blog/static/19446223720118205527863/ 所有文章:http://blog.163.com/bioin ...
- python中的enumerate函数用于遍历序列中的元素以及它们的下标
enumerate 函数用于遍历序列中的元素以及它们的下标: >>> for i,j in enumerate(('a','b','c')): print i,j 0 a1 b2 c ...
随机推荐
- 一文彻底弄清Redis的布隆过滤器
布隆过滤器(Bloom Filter)是一种空间效率极高的数据结构,用于快速判断一个元素是否在集合中.它能够节省大量内存,但它有一个特点:可能存在误判,即可能会认为某个元素存在于集合中,但实际上不存在 ...
- Robust Loop Closure by Textual Cues in Challenging Environments
arxiv | 南洋理工大学开源 基于文本线索实现复杂环境中的鲁棒闭环检测 [Robust Loop Closure by Textual Cues in Challenging Environmen ...
- ROS入门21讲(5)
九.服务数据的定义与使用 1.服务模型 2.自定义服务数据 Person.srv string name uint8 sex uint8 age uint8 unknown = 0 uint8 mal ...
- mysql重置id排列重新排序
1.删除表中的原有的主键字段 ALTER TABLE table2 DROP id 2.表中重新创建一个字段 ALTER TABLE table2 ADD id int NOT NULL FIRST; ...
- Java学习十七—反射机制:解锁代码的无限可能
Java学习十七-反射机制:解锁代码的无限可能 一.关于反射 1.1 简介 Java 反射(Reflection)是Java 的特征之一,它允许程序在运行时动态地访问和操作类的信息,包括类的属性.方法 ...
- layui laydate日期时间范围,时间默认设定为23:59:59
在Layui中,如果你想设置日期时间选择器(datetime)的默认结束时间为当天的23:59:59,你可以使用如下代码(红色部分): laydate.render({ elem: '#test10' ...
- .NET Core 反射底层原理浅谈
简介 反射,反射,程序员的快乐. 前期绑定与后期绑定 在.NET中,前期绑定(Early Binding)是指在编译时就确定了对象的类型和方法,而后期绑定(Late Binding)或动态绑定是在运行 ...
- Air201资产定位模组LuatOS:录音&播放录音功能的操作方法
一直有小伙伴们问,迷你小巧的合宙Air201虽然有很多优点,超低功耗.精准定位,那么它是否支持录音.播放录音功能? 那必须能!高集成化设计的Air201自带了ES8311音频解码芯片(Audio ...
- Codeforces Round 988 (Div. 3)
Codeforces Round 988 (Div. 3) 总结 A 没啥好说的,用桶存出现次数. #include <iostream> #include <cstdio> ...
- 开源IDS/IPS Suricata的部署与使用
目录 前言 在Linux上部署Suricata Suricata的基本配置 配置文件 Suricata的规则 Suricata的使用 Suricata检测SQL注入 前言 Suricata 是一个高性 ...