有了比较好的起始点之后,调整超参数后再重新训练模型,再去看看验证集上的结果(精度、损失)
- 一次调一个值,多个值同时调可能会不知道谁在起贡献
- 看看模型对超参数的敏感度是什么样子【没调好一个超参数模型可能会比较差,但是调好了也只是到了还不错的范围】
- 想对超参数没那么敏感的话,可以使用比较好的模型【在优化算法中使用Adam(对有些超参数没那么敏感,调参会简单很多)而不是SGD(在比较小的区域比较好)】
多次调参的管理
- 每次调参一定要做好笔记【任何调过的东西,最好将这些实验管理好】(训练日志、超参数记录下来,这样可以与之前的实验做比较,也好做分享,与自己重复自己的实验)
- 最简单的做法是将log记录到txt上,把超参数和关键性指标(训练误差)放在excel中【适合实验没有那么多的参数】
- Tensorboard,tensorflow开发的一个可视化工具
- weight&kbias:允许在训练的时候用他们的API,然后把实验记录下来后上传到他们的网页上,就可以进行比较
重复一个实验是非常难的
- 开发的环境:用的硬件是什么、新旧GPU可能会有点不一样;用的库的版本(Python本身也要去注意)
- 代码开发要做好版本控制(可以将每个版本的代码放在同一个地方 需求的库也放在这里)
- 要注意随机性(改变了随机种子,模型抖动比较大的话,说明代码的稳定性不是很好)【要避免换了个随机种子后,结果浮动比较大。这样的话,尝试能不能将不稳定的地方修改一下,实在不行就将多个模型做ensemble】
机器调参与人调参的成本比较
- 在小任务上很多时候已经可以用机器来做了(到最后可能都是用机器来调参【人的成本在增加】)
- 训练树模型在CPU上花10min 大概花$0.4
- 训练神经网络在GPU花1h左右 大概花$5
- 跟人比(人大概花十天左右),算法训练1000次调参数,很有可能会打败人类(90%)
自动调参(AutoML)
- AutoML在模型选择这一块做的比较好
- 超参数的优化(HPO)【比较通用】:通过搜索的方法,找到一个集合去调整模型的超参数
- NAS(Neural architecture search)【专注于神经网络】:可以构造一个比较好的神经网络模型,使得能够拟合我们的任务
- 每个年代都有最大的技术痛点,当前AutoML可能是技术瓶颈。
总结
HPO算法
- black-box:每次一个训练任务 当作一个黑盒(每挑一组超参数,然后拿去训练,然后看模型的关键的衡量指标(精度、误差),再去选下一个怎么做)【可以适用于各种机器学习算法】;
- Multi-fidelity(讨论比较多):因为训练一个模型太贵了(数据集很大,完整跑完很耗时间,还要试很多的话,太耗时了),所以可以不用把整个数据集给跑完(不关心最后的精度怎么样,只关心超参数之间的效果怎么样);
以下是做法:
- 对数据集下采样(超参数如果在小数据集上效果比较好的话,在完整数据集上也不差);
- 将模型的变小(SGD的超参数在resnet18上效果差不多的话,在resnet152上也可能是不错的);
- 在训练时会对数据扫很多遍,但是对于不好的超参数来说,它训练一遍就知道它的效果怎么样了,所以不需要等到完全训练完,看到效果不好的,及时停止;
- 上面三点就是说,通过比较比较便宜点的但又跟完整训练有关系的任务来近似一个值,然后对超参数进行排序;
Black-box 虽然会贵一点但是任务计算量比较小或优化算法不知道的话,这个方法会比较好;Multi-fidelity知道一些任务的细节,可以将任务弄小一点,这样每次试验的时候成本没有那么高。
HPO算法有哪些
Black-Box:
- Grid Search:
- Random Search:
- Bayesian Optimization:
- Simulated Annealing
- Genetic Algorithms
Multi-Fidelity:
- Modeling Learning Curve
- Bandit Based(Successive Halving & Hyperband)
Black-Box
Grid search(网格搜索):
- 其实就是一个暴力穷举,对search space中的每一个config(每一组值),拿去训练一次然后去评价一次,把最好的结果返回出来,也就是把所有的组合过了一遍之后,再把最好的值返回出来。
- 只要搜索空间足够好,就能覆盖到比较好的值,并且一定能找出来;
- 特点就是所有都会评价(Evaluate)一遍,并且保证能找到最好值,但是有个很明显的缺点,搜索空间随着超参数的变多会指数级的增加,也就是“维度诅咒”。但是如果算法足够简单,就那几个参数选择不大的话,当然预算足够的话,也是可以的。
Random Search(随机搜索):
- 随机搜索跟前面的有点类似,虽然也是有个search space 但是 我只选择n次,每一次在搜索空间中选出一个config,拿过去训练,再得出最好结果;
- 次数n保证了我们的这个算法一定会停,可以由我们自己选取,n取过大就跟网格搜索差不多,n取过小,可能并不是那么好用,就n要取得合适;
- 一般来说,随机搜索时一个非常有效的办法,再没有更好的想法之前可以尝试随机搜索
- 其实也可以不选n,可以是等到差不多的时候(感觉精度没有什么进展)直接把它停掉
网格搜索可能会出现精度平稳之后,精度还会上升的情况;但是随机搜索很少会出现这样的情况,除非没有随机好。
Bayesian Optimization(贝叶斯优化):
-
在实际中用的不是那么多,因为相对来说比较复杂,但是是比较活跃的研究方向;
-
BO(贝叶斯优化),是会学从一个超参数HP到目标函数(精度、损失)的一个函数【机器学习是数据到我们想要东西之间的一个映射的关系】,这里是说每一个数据点是一个模型;
-
就每做一个实验就会得到一个数据点,然后再拟合一个曲线出来;它在选下一个超参数去试的时候,会根据当前的评估,来的出数据点;
-
Surrogate模型:就是拟合超参数与目标函数之间关系的模型,可以采用概率的一些regression模型,可以使用随机森林或者是高斯过程;
-
具体有张图:
-
随着采样的越来越多,对整个模型的进步会越来越准。
-
在一开始的时候其实跟random search差不多(获取函数还不够好,就只能随机挑值来做),再后期的时候(建模比较准)会比较好一点;
-
随机搜索是并行的算法,贝叶斯优化是顺序的算法(采下一个点需要等上一个完成才行)
-
到底是什么时候会好一点,如果预算不够的话(搜的质量跟随机搜索的差不多),这样是划不来的;如果贝叶斯能在前期就做的比随机搜索好,那这样的划得来的。
-
通常贝叶斯优化比随机搜索好的时候,一般来说是模型比较简单(模型比较简单的话,随机搜索也不差),或者是超参数的那个空间不那么复杂,或者有足够多的样本(需要很多的预算)
Multi-Fidelity
以下这两个算法在现实生活中用的比较多
- 网络的拓扑结构(ResNet、MobileNet(通过特殊的卷积层,把整个计算复杂度降低,使得在手机或其他低功耗设备上算的比较快)、架构的层数等);
- 具体层的参数(卷积层中核窗口的大小、输出的通道数是多少、全连接层或RNN中输出的隐藏单元的个数)。
NAS的作用:尽量的使得整个网络的设计能够自动化
- 甚至可以从零开始设计一个神经网络;
- 给出一些网络的选择,选取最优的出来(有点像HPO);
NAS需要关心的东西:
- 整个搜索的空间是什么样子的(整个神经网络的超参数【SGD的或是其他的超参数不关心】);
- 怎么样在搜索空间中搜索;
- 怎么判断网络的好坏。
基本流程:设计一个搜索空间 -> 设计搜索策略 -> 每次采样一个架构出来,查看其性能 -> 反馈回搜索策略让策略更新。
早期NAS的工作:通过强化学习(Reinforcement Learning)
主要思想:
- 将网络的超参数表示成文本;
- 用一个RNN(可以对一个时序序列建模)来生成不一样的整个网络架构;
- 生成一个之后对这个网络进行训练来算这个网络的验证精度;
- 将结果反馈给RNN网络;
- 然后RNN网络利用反馈回来的信息进行更新;
这个整个环用的就是RL(强化学习)【Agent做了一个行动,每行动一次就看下环境给出的反馈,通过反馈更新Agent】,好处:不管是什么套上RL之后可以在整个框架上显得比较优美的,坏处:十分昂贵。
One-shot 方法
- 学习一个架构,既要学习整个网络的架构,也要学习模型里的超参数(训练一个特别大的模型,里面包含了想要看的模型的架构,然后将这个模型训练一遍,里面的子模型就是我们要考虑的架构,这样既能得到他的性能又可以得到他的参数)。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化资料的朋友,可以戳这里获取
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
-1714456598382)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化资料的朋友,可以戳这里获取