BB高低游戏怎么玩;如何进行超参数调优优?

有关bb高低怎么判断??? ?????_百度知道
有关bb高低怎么判断??? ?????
我有更好的答案
采纳率:100%
塞下曲·鹫翎金仆姑(卢纶)
为您推荐:
其他类似问题
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。谁能告诉我bb高低怎么组合?? ????_百度知道
谁能告诉我bb高低怎么组合?? ????
我有更好的答案
采纳率:66%
为您推荐:
其他类似问题
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。手机mg游戏浏览器设置;如何对其模型进行参数调优?_百度知道
手机mg游戏浏览器设置;如何对其模型进行参数调优?
福 趾 达 开pk0077.c&shyn。很惋惜那段最清纯最美丽的爱恋。
您的回答被采纳后将获得:
系统奖励15(财富值+成长值)+难题奖励20(财富值+成长值)
为您推荐:
其他类似问题
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。Freshman for me
游戏数据分析的架构及调优
数据处理系统的架构和流程,最基本的框架流程如下图所示:
每天,来自各个项目的数据每时每刻都在打入数据分析系统。这些数据通过数据采集环节,被初步整理成一定的格式,然后录入集中的数据存储系统中。当然,我们系统呈献给用户的是各种统计指标。所谓统计指标,即对原始数据的聚合,形成一定的统计结论。所以,我们需要有查询系统,基于海量的数据进行。在我们的系统中,各个部分的技术选型如下:
紫色的部分即为各个部分的技术实现
客户的应用数据,通过REST API打入数据处理系统中。这部分我们考虑使用PHP来实现,主要考虑其实现简单,便于水平扩展;处理速度也可以接受。
Rest API接收到的原始数据,在进入存储之前,还需要进一步整理,主要有两方面的原因:一是一些不合理的日志需要筛选出去;二是我们在这一步,有时候需要把接收到的数据转换成更基本的数据。一个例子是应用程序可能会打入一个应用加载事件visit。那么,我们收到visit的时候,还需要判断这个用户是不是第一次出现;以及用户加载的时候的一些refer信息,等等。所以,这一步的逻辑比Rest API要复杂,做这些逻辑判断所需要的信息也更多,因此我们选用java开发了这一模块。
我们收集到的大量数据,有两方面的信息:一是事件信息,记录发生过的事件:用户A在某个时刻登录了一次;用户B在另一个时刻进行了一次购买,等等。这种事件信息占了系统所存储信息的大部分,而且绝大部分是不断新增的数据。我们采用HBase来存储这部分信息,一方面,HBase对于批量的写入性能很好;另一方面,在rowkey设计合理的情况下,其索引和查询性能也不错。除事件信息外,还有用户的属性信息,比如用户A所在地区位于中国,用户B首次充值的时间为日,等等。这种信息的访问特点是插入和更新都比较多;在查询的时候,既要按照主键(用户ID)来查询,也要按照属性值(例如前面提到的充值时间)来查询。这就要求同一个表有多列的索引能力,所以,我们目前采用了MySQL来存储用户属性信息。
当数据都导入了以后,我们就需要一种系统,具有从HBase和MySQL这种异构存储之上进行查询计算的能力。基于原始数据的聚合计算是一个相对来说比较耗资源的过程,在去年,我们主要使用MapReduce进行这个计算过程,当计算完成后,把结果保存起来,用于展示。这样做的限制在于,系统所展示的数据只能是预先算好的;用户无法动态地对报告进行修改。基于这个问题,我们很早就开始关注交互式查询技术的进展。今年,分布式环境下的SQL查询系统成为一个发展中的热点技术,有若干个这样的系统陆续浮出水面。目前来看,Drill属于发展较晚的一个项目,但其开放、可扩展的架构能很好的满足我们的需求。所以,我们围绕Drill,构建了我们的SQL查询系统。这样,任何能通过SQL表达的数据报告,都可以通过我们的系统来实现了。现在,用户可以通过界面构建任何他想要看到的报告,然后就能在比较短的时间内得到他想要的结果。
上面提到,聚合计算是一个耗资源的过程,即使是现在我们采用了基于drill的查询系统缩短了响应时间,计算后的结果也需要保存下来,以应对用户的查询。我们使用Redis来保存我们的计算结果,主要考虑Redis优秀的随机查询性能。
作为系统的展示层,我们使用了RoR+backbone+coffeescript的组合。这个层面选择的自由度就比较大了,coffeescript应该说是作为python爱好者的首选,用来配合backbone构建富客户端程序;RoR用来完成各种界面操作的Rest API以支持客户端的运行。总体感觉,这个组合还不错,开发起来也快,同时界面表现也不错。
理论上来说,性能调优是一件永无止境的工作。在大数据的背景下,似乎很多问题都可以通过加机器来解决,调优的重要性看起来更低了。但事实上,调优是我们的重要工作之一,原因有以下几点:首先,作为小公司,资源毕竟有限,在集群环境下,调优的成果也具有集群效应;其次,由于我们的系统基于交互式查询技术,那么系统各个环节性能的提升无论对于数据响应的速度还是数据生效的实时性,都会有直接的影响。
所以,我们在系统的各个环节、各个层面都进行了调优。如果用一句废话来解释的话,数据处理系统的特点是(顾名思义)需要处理的数据有很多,所以调优的核心目标只有一个:在尽量短的时间内,使用尽量少的资源(内存,I/O访问,CPU),处理尽量多的数据。
下面,我们按照模块来做划分,简单介绍一下我们在优化方面所作的努力,囊括数据导入、存储、查询、缓存和前端多个部分。
数据导入部分——主要的优化点在于java程序的优化和对于数据库访问的优化(by刘熊)
关于Thrift连接池的优化
在前文中提到,我们在数据导入的时候需要判断一个用户是否为新出现的用户;同时,我们还需要对字符串类型的ID做一定的映射,转化为整型的内部表示。我们开发了专门的服务(称之为ID Service)来处理这种ID之间的转换和新ID的识别工作。出于性能和开发效率的考虑,我们采用Apache的Thrift RPC框架来快速搭建ID Service。不过,Thrift框架的Java客户端本身存在一个不足,就是不支持连接池。为了减少连接创建销毁的开销,我们自己实现了客户端连接池。
关于内存容器类优化
ID Service的后端存储用的是MySQL。为了减轻对MySQL服务器的压力和提升获取内部整型ID的速度,我们采用本地内存来缓存用户原始字符串ID和内部整型ID的对应关系。用户的原始字符串ID,哈希成整数后作为关键字来查找对应的内部整型ID。显然,一个整型到整型的HashMap能保存这种对应关系。考虑到JDK中HashMap的实现相对来说较占内存,我们使用HPPC中的Primitive Collections来替代。采用这种内存缓存后,经统计,缓存命中率能达到99%. 如果对HPPC中OpenHashMap的操作只用到get/put/remove,那么在每次重新哈希时不用打乱关键字顺序,减少重新哈希的计算时间。
关于MySQL Connector/J的优化
每天,我们需要从MySQL中查询各个项目两个月以来的活跃用户。对于某些项目,活跃用户数上千万。默认情况下,Connector/J一次查询会先缓存满足查询条件的所有数据。如果机器内存使用紧张,而某次查询需要缓存的数据量很大,就有可能导致OOM。Connector/J支持逐行返回数据(通过enableStreamingResults来启用),这样,就能大大减轻短时间内对内存的压力。
我们使用LOAD DATA LOCAL INFILE将用户属性信息批量地导入MySQL。刚开始时,我们把待导入的数据先写到文件中,然后让LOAD DATA LOCAL INFILE语句去读这个文件。后来得知,并不需要写入文件,Connector/J支持从输入流中读取待导入的数据(通过setLocalInfileInputStream方法)。这样,批量导入数据就能从内存中读取了,避免了磁盘IO开销。经粗略估计,速度能提升10倍以上。
关于HBase客户端的优化
至于HBase批量导入数据,我们在客户端这边做的优化主要是关闭WAL、调节写缓冲区大小和手动刷新缓冲区。
存储部分——主要的优化点在于对HBase和HDFS的参数调整,以及访问方式的调整(by刘熊&王宇飞)
我们在HBase参数调优上花了一些时间,主要在如下几个方面作了调整:
GC:影响HBase性能的GC参数主要是堆的大小、新生代的大小和垃圾回收器类型。这方面的资料网上较多,前人的经验较多,但不存在万能的最优参数组合,实践中还是需要根据自己的系统线上的实际表现来不断尝试和优化。数据压缩:HBase支持启用数据压缩,能节省很多存储空间,但是同时会带来一定的读写性能开销。目前我们线上使用的仍然是0.94系列的版本,在0.96以及0.98版本中,HBase的存储引擎有非常大的改进,比如引入了新的prefix tree编码方式,以及更新的文件结构,等等。这些改动对于性能提升的潜力巨大,我们也十分期待。手动major compaction:由于执行major compaction对HBase的响应速度有明显影响,所以我们关闭了自动major compaction,而改在集群较空闲时执行。HDFS的本地读模式可以让HBase的RegionServer进程在合适的时候不与本机的DataNode进程通讯,而直接从文件系统读取数据。我们打开了本地读模式,提升读性能,好在现在本地读模式已经默认启用了。启用bloom filter,提升读性能。调节scan cache大小,提升scan性能。
查询部分——主要的优化点在于如何提高查询的IO性能,以及优化查询过程本身(by王宇飞)
Ad-hoc查询机制
Direct Scanner
对hbase的数据扫描的方式我们做了一些改变,没有使用传统的方式通过hbase原生提供的client去获取数据,而是设计了一个direct scanner的组件来替代hbase client。
采用hbase client的方式会通过region server去扫描hdfs存放的数据文件(hfile),之后和region server本身内存中(memstore)数据做合并,按照row key的顺序按批次传给client。如果数据量小没有明显性能问题,比如扫描一两百万行,但通常我们场景会实时扫描上千万行的数据,这个时候就有明显的性能问题了。主要是hdfs上的数据多经过了一层region server再传给client,多增加了一次序列化和网络传输的开销。
Direct scanner的设计就是为了优化这个问题,我们在client的进程中直接扫描hbase在hdfs上的数据,这个数据占大部分。只从region server中获取少部分存在于内存中的数据。最后在direct scanner中控制两部分数据的合并和更新覆盖,版本控制等逻辑。
对两种方式的扫描我们做了性能测试对比,发现数据量越大direct scanner的优势越明显。当扫描3000w行数据时,采用hbase client的方式要用到60s左右,而direct scanner只用29s。
由于我们本身提供的是一个实时查询的服务,这就要求从查询处理到结果返回给用户的时间要尽可能地短,过长时间的等待对用户的体验会大打折扣。但很多时候用户所需要的统计结果本身涉及到查询的数据量就很大,全部扫描的话光是磁盘io的耗费时间用户可能就不能接受。例如,之前提到扫描3000w行hbase数据direct scanner扫描就需要29s左右,这里还没有算上物理计划的执行时间。在实际查询中,一个统计指标所涉及到的扫描量可能远不止3000w行。
针对这个问题,我们的出发点是想能不能扫描尽量少的数据就能得到相对准确的结果。如果可以,会大大减少不必要的磁盘io和cpu处理。通过对游戏玩家的行为分析,我们发现大部分事件发生次数和玩家本身有一个比较一致的分布。所以我们通过对玩家的抽样扫描,来预估最终的统计结果。抽样所涉及到的玩家越多,结果也就越准确。所以在实际的查询中,我们采取逐步扫描的方式,每轮都是对一部分玩家采样,直到结果满足误差可以控制在一定范围内为止。
给一个实际的测试结果可能更形象一些,下面是我们扫描某个项目一天发生visit事件的人数和事件次数结果,分别用采样和不采样的方式:
不采样: 人数:3187632 次数: 耗时:12.53s
采样(只扫描1/256的用户): 人数:3150336 次数: 耗时:0.49s
可以看到,人数的误差在1.17%,次数的误差在0.1%,而查询耗时从12.52s减少到了0.49s。
合并与物理计划执行方式的改进
logical plan的合并可以说是根据我们的查询业务场景做的一个比较有意思的创新。由于我们前后台交互是异步请求模式,前台提交的查询请求转化为logical plan在后台的队列里排队等待处理。而这些排队的logical plan如果一个一个的执行可能会涉及到大量对磁盘的重复扫描和计算。
于是我们想有没有方法一次性批量的去执行这些logical plan,把相同的io扫描和计算合并掉。基于这个目的,我们采取的方案是对一系列的logical plan做合并,把涉及到重复磁盘扫描的操作符合并到一起。这样多个不同的logical plan经过合并后形成的大logical plan极大地增强了我们系统的吞吐量。
在有了合并后的logical plan后,我们对drill原生的物理执行框架又做了进一步改进。Drill本身的物理执行方式是单线程从DAG的root节点逐步向child节点pull数据,这样对于大plan的执行就利用不到服务器多核的优势,处理起来就很慢。所以我们把每个physical operator节点改造成独立的一个线程worker,它本身处理完后就把结果push给自身的parent节点。每个physical operator节点有一个数据队列来接收child节点所传递过来的数据。通过这种多线程push的方式,充分利用了cpu的多核能力,加快了大plan的处理速度。
缓存部分——主要的优化点是如何考虑缓存的粒度,以提高内存利用率(by武子竞)
对缓存结果的读取和存放主要为Get/Set操作,在低延迟、允许少量数据丢失的情况下,架构上,结果缓存采用Redis shard的集群方式,这样可以保证每个Redis实例占用较小的系统资源。同时对Redis的save进行配置,可以灵活掌控数据保存至硬盘的策略。Redis的硬盘存储文件dump.rdb的结构对外开放,也使得扩展集群规模,迁移数据变得相对简便,另外使用Redis作为结果缓存,而不用memcached的另一个重要原因是Redis提供了丰富的数据结构,如Hash,这对缩减整个结果集的Keys的数量也至关重要。
由于每一个查询结果都有对应的key,因此如果用户定义的查询粒度非常细小,就会导致key的数量暴增,因此在缓存的键的设计上,我们选择了折中的粒度,如果是更细粒度的结果,则存储到Hash结构中,这样确保了在时间上可接受的前提下,占用内存比String更小。使用hash的另一个好处是,redis引入了zipmap(SmallHash),可以比正常的HashMap节省一些元数据的存储开销,在我们的hash中,entry的数量不大而且相对固定,因此调整Redis的hash-max-zipmap-entries和hash-max-zipmap-value配置可以找到性能和空间的平衡点。
前端——主要是如何使用各种工具来达到更好的交互体验(by王长历)
采用web app方式设计:用ror做后台的rest服务,页面交互用了backbone.js这个前端MVC框架,除了报表数据的更新,其他的交互都在浏览器端完成。另外,我们用coffeescript来替代javascript,css方面采用bootstrap框架,部署工具用的是capistrano。我们也用到了一些很不错的ruby gem,如利用resque用来做异步调用服务,用private_pub做消息订阅服务(及时把系统通知推到前端)等等。
工具的进步使得小团队的配合变得更加容易。我们的代码均托管在GitHub( )上,同时使用Basecamp来记录项目中的备忘资源和协调任务。自动化运维方面,开源社区也有非常多的选择,比如我们使用Ansible进行配置管理,使用Fabric来做集群的自动化升级。
数据处理问题三个比较主要的技术环节是:如何整理数据、如何存储数据和如何查询数据。在这三个方面,开源社区目前都处于比较快的进步当中:数据整理方面,各种流式处理框架越来越成熟;存储方面,新的存储格式的探索还在不断进行,老的存储系统比如HBase也有很多新的特性在规划当中;查询方面,包括Drill的各种查询引擎也在快速发展之中。
针对业务场景我们做了大量的优化工作,原因在于目前还没有一个特别适合且易用的开源数据仓库方案,能够让我们很方便的“开箱即用”。有理由相信,随着开源技术的不断进步,数据处理的门槛将会越来越低,更多的人和组织有能力处理更多的数据;同时新的问题和新的解决方案也会不断出现。作为一名技术人员,能够投身于这一技术潮流中,是一件令人激动的事情。
穆黎森,现智明星通CTO。曾就职于搜狗,后参加多次创业公司。关注服务器性能优化,关注分布式存储技术,关注分布式查询技术。
Got master's degree in CS from Tsinghua Univ. Served as engineer in sogou.com after graduation. Participated in multiple startup projects, and now entitled as CTO at elex-tech.com, an international game developing and publishing company. Mainly interested in
distributed computation and distributed storage system.(责编/仲浩)
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!在Keras中如何对超参数进行调优?在Keras中如何对超参数进行调优?科技网百家号更多腾讯海量技术文章,请关注云+社区:https://cloud.tencent.com/developer由于没有一个成熟的理论来解释神经网络,所以配置神经网络通常是困难的,经常被同学们调侃为“炼丹”。对于一个给定的预测建模问题,你必须系统地尝试不同的配置然后从客观和变化的视角来审视不同配置的结果,然后尝试理解在不同的配置下分别发生了什么,从而对模型进行合理的调优。本教程将专注于时间预测问题并讨论如何对LSTM(long-short term memory,长短期记忆,最流行的RNN网络之一)网络进行配置。认真完成本教程后,您将掌握以下技能:如何调整训练的epoch数量并解释调整后的结果。如何调整单次训练中的batch size并解释调整后的结果。如何调整神经元的数量并解释调整后的结果。事不宜迟,我们现在就开始吧。摄影:[David Saddler],保留部分权利教程概述本教程可以分为以下6个部分;:数据集准备设计实验测试套件调整epoch的大小调整Batch Size的大小调整神经元的数量结果汇总环境要求本教程假设您已经安装了Python SciPy环境。Python 2或3皆可。本教程假定您已经安装了Keras v2.0或更高版本(TensorFlow或Theano作为后端皆可)。本教程还假设您已经安装了scikit-learn,pandas,NumPy和Matplotlib。如果你不知道如何配置这些环境,可以参考下面的文章:如何使用Anaconda配置机器学习和深度学习所需的Python环境(http://machinelearningmastery.com/setup-python-environment-machine-learning-deep-learning-anaconda/)数据集准备该数据集描述了3年期间每月洗发剂的销量。这个数据集的基本单元是与时间对应的销量,一共有36个观测值。这个数据集是由Makridakis, Wheelwright, and Hyndman (1998)贡献。下载并了解更多关于数据集的信息。下面的代码演示了如何导入数据集并据此绘制销量随时间的变化情况运行代码导入数据集,数据会被加载为Pandas Series类型并且控制台会输出前五行的数据。绘制销量随时间变化的折线图,可以很清楚地看到销量的增长趋势。接下来,我们来看一下实验中LSTM的配置和实验所需的测试套件。测试套件本节将介绍本教程中使用的测试套件。数据分割我们将销量数据集分为两部分:训练集和测试集。前两年的数据作为训练集,剩余一年的数据作为测试集。训练集将用于模型的训练,训练得到的模型将用于预测测试集中的销量。如果以最后一个月的销量作为恒定的预测值,对测试集中的销量值预测误差为平均每月136.761的。这也是我们对模型在测试集上性能要求的下限。模型评估我们将使用滚动预测方案,也称为前向模型验证。测试数据集上的时间步长每次挪动一个单位.每次挪动后模型对下一个单位时长中的销量进行预测,然后取出真实的销量同时对下一个单位时长中的销量进行预测。这种方案模拟了真实世界当中的场景,每个月都会有新的销量数据,我们会利用过去月份的销量数据对下个月的销量进行预测。这个过程可以通过借助训练集和测试集中的时间标记来完成,在后面我们会一次性预测出测试集中所有的销量数据。我们将会利用测试集中所有的数据对模型的预测性能进行训练并通过误差值来评判模型的性能。在这个例子里我们使用均方根误差(RMSE),因为相比于其他损失函数它可以提供较大的罚值,从而使模型的预测值更趋近于真实的销量值。数据准备在我们在数据集上拟合LSTM模型之前,我们必须先对数据集格式进行转换。下面就是我们在拟合模型进行预测前要先做的三个数据转换:固定时间序列数据。具体到这个问题就是让销量数据严格按照时间顺序排列,下一条的数据就是下一个月的销量数据。将时间序列信息隐含与监督学习当中,可以通过组织数据的输入输出方式来实现,在这个问题中只需将前一段时间的销量作为模型输入来预测当前月份的销量数据即可。对销量数据进行合适的缩放。具体来说,为了让数据的输入范围与LSTM模型的激励函数输出范围相匹配,需要将销量值缩放至-1~1的范围当中。为了让模型仍旧可以输出我们需要的销量预测值,需要对变换后的输出进行逆变换从而输出模型的原始预测值。实验运行每个实验场景需要重现10次以上。这是因为即使给定了模型训练所需的超参数,LSTM模型的随机初始化也可能会引起模型训练结果间的巨大差异。通过审视不同模型超参数下模型性能随迭代次数(epochs)的变化曲线,我们可以得到一些可能提升模型性能的超参数调整区间或方向。在每个批次的数据集训练结束后,测试集和训练集上的得分(即均方根误差)会打印输出出来。每个批次结束后打印输出性能评估指标可以帮助我们更好地了解到模型的现状,比如说是否发生了过拟合。训练集和测试集上的RMSE损失值曲线在运行结束之后通过折线图展现,我们设定测试集曲线为蓝色,测试集为橙色。下面让我们编写代码,然后对模型的结果进行分析。调整epochs的大小我们调整的第一个模型超参数是epochs。为了保持其他超参数的一致,我们固定神经元数量为1,Batch Size为4。下面我们通过调整epochs来观察模型性能参数的变化。epochs = 500下面给出了我们实验使用的代码清单。代码是最好的注释,同时代码也易于复用和变更,这份代码是我们下面所有的实验的基础代码,我们只需要在上面稍作变更就可以完成后续的所有实验。运行实验代码。稍等片刻即可看到十次实验结束时训练集和测试集上的均方根误差。运行结束后,在代码文件所在目录下会保存十次实验中测试集和训练集上的均方根误差随训练批次变化的曲线图。epochs=500时的结果从结果可以清楚地看到,几乎所有的实验中均方根误差都是呈下降趋势的。这是一个令我们满意的标志,这个趋势意味着模型确实从训练集中学习得到了预测能力。事实上从曲线上我们也看到了在epochs=500时最终的预测误差RSME均低于136.761。这个趋势也告诉了我们,继续增大epochs的值还可以使模型的性能进一步提升。下面我们就将模型的epochs提升至1000。1000个时代的诊断要实现将epochs提升至1000只需要改变代码中的epochs设定值即可。具体而言,就是将n_epochs参数设置为1000 再执行run()函数。运行代码后可以看到与下面相似的输出结果:同样的,训练结束后可以得到与下相似的曲线图。epochs=1000的结果从曲线中可以看出虽然误差在进一步减小,但是减小的趋势已经越来越不明显了。虽然训练集和测试集的误差曲线变得越来越平坦,但总体上还是下降趋势,不过在最糟糕的一条测试曲线中我们观察到了测试误差在随训练批次的增大而增大。不过这种曲线只是个例,在大多数的实验中继续增加epochs还是值得的。这次让我们把epochs从1000提升至2000。epochs=2000和之前一样,将 run() 函数中的 n_epochs 参数设置为2000再次运行即可 。运行示例可以看到每次实验中测试集和训练集最终的RMSE误差。下面是最终得到的曲线图。epochs=2000正如上面所说,还有很多的模型在epochs=1000之后仍然保持下降趋势。不过epochs=2000时,大约只有一半的测试样例还能保持下降趋势了,其他的误差都开始上升。增长的趋势是过拟合的迹象。过拟合即对训练集的过度拟合致使在训练集上产生了反作用,表现为模型性能的下降。从测试集上误差曲线的继续下降和测试集上误差曲线从下降到上升的现象也可以印证这一点。一少半的测试样例已经满足了这一要求。尽管如此,在测试集上的最终性能仍然很好,也许进一步加大epochs还可以获得更大的提升,我们不妨再调大epochs一次。这次仍然增大一倍,令epochs=4000。epochs=4000将 run() 函数中的 n_epochs 参数设置为4000 。再次运行代码观察到输出如下。运行结束后看到如下的损失曲线图。epochs=4000变化趋势和epochs=2000时相似。看到即使epochs提到4000,性能也仍然有着提升的趋势,不过这次出现了一个很严重的过拟合情况。大多数的样例再次以良好(能够满足我们设置的下限)的测试结果结束。结果汇总从上面参数的动态调整中我们更好地理解了模型随参数的动态变化,但是我们还没有将结果做客观和严谨的比较。我们可以通过重复实验和列表总结来完成这一步,这里我完成了epochs=500,,时各30次的运行。这个方法是通过大量运行相应的配置并进行统计分析,从而更准确地判断哪些配置更优的。完整的代码示例如下所示。运行代码,可以看到这五个配置下的结果概要信息。需要注意的是,这里不仅有平均的RMSE值,还有标准偏差值。平均值代表了当前配置下的平均预期性能,而标准差代表着当前配置下测试模型间的性能偏差大小。最大值和最小值界定了模型性能预期出现在的范围。如果只看平均的RMSE值,epochs=1000时是最好的,如果要得到更具体的值则需要在的范围内进一步细分。从箱形图也可以看出这种分布而且比较起来更为直观。在我们的箱形图中,绿线代表中位数,上下边代表的是性能中前25%和75%的分界线,黑线代表最优值和最差值。从箱形图我们可以看出,如果从测试角度来看,epochs设置为1000更合理,但是如果想获得最佳的性能,那么可能需要牺牲平均性能选取2000附近的epochs值进行重复。用于总结和比较的箱形图接下来,我们看看Batch Size对模型的影响。调整Batch Size的大小Batch Size的大小决定着网络权重的更新频率。注意:在Keras中,Batch Size也是会影响训练集和测试集大小的。在上一节中我们探究epochs对模型训练的影响时将Batch Size固定为4,此时测试数据集数量不受影响,仍然为12,但是训练数据集的前四个数据的利用率是低于后面的,因此只能划分出20个训练样本。根据上一节的结论,我们在这一节中将epochs固定为1000(忽略参数之间的相互影响)。epochs=1000,Batch Size=4这个配置在上一节的部分已经使用过了,此处不再重复赘述,只做简单总结。结果显示直到训练的最后,大多数模型的错误率都还是呈下降趋势的。Batch Size=4Batch Size=2现在我们将Batch Size做减半处理。修改 run() 函数中的 n_batch 参数即可:运行代码,从输出结果和曲线图对比看出模型训练过程中的趋势大致相同,但是从趋势上看可能Batch Size=2时可以达到更低的RMSE值。在Batch Size=2时,与Batch Size=4相比模型的下降趋势并没有那么明显,更加趋于稳定。下面列出了运行过程中输出的每次重复得到的训练集和测试集上的RMSE值。训练和测试集上的RMSE值变化曲线Batch Size=2让我们进一步缩小Batch Size。Batch Size=1Batch Size=1的情况在术语上又称作在线学习(Online Learning)Batch Size=1时,每个样本训练完后就会更新权值,而批量学习(Batch Learning)不同,只有在每个批次的数据训练结束后才会更新网络权值。在 run() 函数中更改 n_batch 参数:再次运行函数,观察控制台的输出:最后得到RSME的损失值变化曲线图。从曲线变化中可以看出与之前相比RMSE的下降速度更快,在epochs=1000时显得更加稳定。考虑到训练集中很小的变化都可能导致网络权值的较大变化,测试集中RMSE的变化范围可能会更大。从这个图像中还可以看出如果增大epoches,模型很可能可以达到更优的性能。Batch Size=1结果汇总和探究epoches时一样,我们需要通过统计的方法客观严谨地分析Batch Size的不同大小对网络性能的影响。同样,将每个超参数配置重复实验30次,将结果以表格和箱形图的方式展示。下面给出需要改动的代码。如果单独从平均的RSME损失来看,Batch Size=1时的RSME值最小,如果再考虑到上一节的结论,通过调整epochs可以进一步提高模型的性能。箱形图中各个边界与标注线与之前一致。可以看出Batch Size时模型的差异性最大,同时RSME的中间水平(不是平均值)也更优。对神经网络的调优实质上就是模型平均性能和性能稳定性(指重复训练得到的模型间的偏差)的折衷,最理想的结果是得到一个平均误差小同时稳定性又强的模型,这意味着模型是良好且易于重复的。探究Batch Size得到的箱形图调整神经元的数量在本节,我们将探究网络中神经元数量对网络的影响。神经元的数量与网络的学习能力直接相关。通常来说更多的神经元可以从问题中习得更多的结构,不过这伴随着更高的时间成本和过拟合的潜在风险。我们固定Batch Size为4,epochs为1000。神经元数量为1我们从1个神经元开始。这个配置在前两个实验都已经重复过了,不再赘述,直接展示结果。神经元数量为1神经元数量为2我们将神经元的数量从1调整至2,一般来说这会提高网络的学习能力。我们需要改变 run() 函数中的 n_neurons 变量来完成新的实验。运行代码,打印得到每次重复实验得到的RMSE损失值。从结果来看,网络的学习结果满足了我们的最低要求,但是并没有我们想象中那么大的提升,表现一般。再看一下我们得到的RMSE损失折线图。这张图相比打印数据更具有说服力,从图中可以看到在epochs为500-750时,除了一条异常曲线以外,其他模型在测试集上的RMSE曲线也都出现了上升的拐点。与此同时,所有模型在训练集上的损失值都有值持续的下降趋势。这很明显就是模型在训练集上过拟合的体现。神经元数量为2让我们继续增加神经元的数量,看模型会不会更快地达到过拟合。神经元数量为3将神经元的数量增加至3在 run() 函数中设置 n_neurons 变量为3。运行代码,控制台会输出每次运行最后得到的RMSE损失值。结果与将神经元数量调整至2时大致相似,我们没有看到神经元数量为2或3有着什么大的差异。而且以最后的性能来说,3个神经元的网络性能似乎因为更快达到过拟合而显得更差一点。从损失值的变化曲线可以看出模型在训练数据集上更快地达到了上面所说的拐点,大概在epochs位于300-400时。如果此时减小学习率,增加神经元数量可以减小过拟合的速度,从而提供更丰富的模型。除此以外也可以使用一些其他的正则化方法比如说增加Dropout层,减小Batch Size,减小epochs等。测试集与训练集上的RMSE曲线图神经元数量为3结果汇总现在,让我们来通过统计的方法对比观察网络其他超参数固定的情况下,神经元数量的增加对网络的影响。还是和上面一样每个配置重复30次,神经元数量为1-5,下面给出重复实验需要更改的函数和代码。运行代码过程中会打印每个配置中测试集上的损失值。单从性能上看,具有一个神经元的网络在epochs=1000,Batch Size=4时具有最佳的性能,同时模型训练的稳定性也最好。从箱形图可以看到神经元数量的增加导致了损失值的增加,模型性能的下降。探究神经元数量影响的汇总箱形图所有实验的汇总分析在本教程中,我们在Shampoo Sales数据集上完成了一系列LSTM实验。对于本文中的数据集来说,一个神经元,Batch Size为4,epoches为1000对于LSTM来说是一个很好的超参数配置。除此之外,如果希望获得更好的模型,Batch Size设为1,使用更大的epoches也值得一试。从本文的描述也可以看出神经网络超参数的调整是一项困难的经验性工作,LSTM网络自然也不例外。本教程也印证了开头所说的以动态和客观的角度来审视模型的工作情况对于我们的调参是大有裨益的。当然,除了本文的话题之外,还有许多有趣又有意义的工作和研究,下一节我也列出了一些来供读者参考。扩展内容本节列出了一些可以基于本教程继续探究的内容和想法。如果你尝试了其中的任一个,欢迎在评论中分享你的结果~添加Dropout。这是减慢机器学习速度更是避免过拟合的一大利器。使用层级的神经网络。通过多层的神经网络可以为模型带来分级分层学习的能力。正则化。可以通过权重正则化(如L1和L2)来减缓模型的学习同时降低模型的复杂度,防止过拟合。优化算法。探索使用Keras提供的其他优化器,如经典的梯度下降,看看在其他算法下模型参数对模型训练和过拟合的速度有怎样的影响。损失函数。尝试使用Keras其他可用的损失函数,探究选用其他的损失函数是否可以提升模型的性能。特征与时间步长。你可以尝试其他的组合方式或者时间步长,比如说你可以跳过上个月的数据等的。更大的Batch Size。使用更大的Batch Size意味着模型在训练集和测试集上的数据操作规模更大了,看看这会带来什么影响。总结通过本教程,你应当可以了解到在时间序列预测问题中,如何系统地对LSTM网络的参数进行探究并调优。具体来说,通过本文我希望你可以掌握以下技能:如何设计评估模型配置的系统测试套件。如何利用模型的性能评估指标以及指标随epochs的变化曲线对模型的行为进行分析。如何探究和解释epoches,Batch Size和神经元数量对模型的影响。翻译人:ArrayZoneYour,该成员来自云+社区翻译社原文链接:https://machinelearningmastery.com/tune-lstm-hyperparameters-keras-time-series-forecasting/原文作者:Jason Brownlee本文由百家号作者上传并发布,百家号仅提供信息发布平台。文章仅代表作者个人观点,不代表百度立场。未经作者许可,不得转载。科技网百家号最近更新:简介:互联网时代最强的精英作者最新文章相关文章}

我要回帖

更多关于 随机森林参数调优 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信