调参不能只靠直觉,也是一门大学问!
虽然算法工程师往往调侃自己是「调参侠」,但调参这件事可能真没想象中那么简单。
比如,你是不是经常会有疑惑到底该选择哪个优化器?一个batch放多少数据?超参数如何设置?难道真要网格搜索全实验一遍吗?
最近,来自谷歌和哈佛大学的研究人员以非官方的名义发布了一本《深度学习调参套路》,把调参这件玄之又玄的事试图用科学的方法来解释,目前已收获超过1万个stars,喜欢记得收藏、关注、点赞。
文档链接:https://github.com/google-research/tuning_playbook
该项目由五名从事深度学习多年的科研人员和工程师合力编写,最早的甚至在2006年就开始写神经网络,涉及的领域也包括从语音识别到天文学的各种问题,并在过程中积累了大量的经验。
技术交流
技术要学会分享、交流,不建议闭门造车。 本文由粉丝群小伙伴推荐。
论文探讨、算法实战交流、求职内推、干货分享、解惑答疑,与2000+来自港大、北大、腾讯、科大讯飞、阿里等开发者互动学习。
目前已开通了技术交流群,群友已超过2000人,添加时最好的备注方式为:来源+兴趣方向,方便找到志同道合的朋友。
方式1、微信搜索公众号:机器学习社区,后台回复:加群;
方式2、可以直接加微信号:mlc2060。加的时候备注一下:研究方向
+学校/公司+CSDN,即可。然后就可以拉你进群了。
目标读者群体
阅读本文的读者可以是对最大化深度学习模型性能感兴趣的工程师和研究人员(包括个人和团队),应当对机器学习和深度学习概念有最基本的知识储备。
文中的重点是超参数调整的过程,同时也涉及了深度学习训练的其他方面,如pipeline的实现和优化,但对这些方面的描述并不完整。
作者假定要解决的机器学习问题是一个监督学习问题或类似的问题(例如自监督),即文中的一些规定也可能适用于其他类型的问题。
调参不能靠直觉
以目前的情况来说,要想让深度神经网络在实际应用场景中取得较高的性能,需要工程师们付出大量的努力与「猜测」性实验。
深度学习的性能不仅与模型架构有关,也与超参数的选择有关,但那些能提高模型性能的参数往往都没有被记录下来。
在论文写作中,为了让自己的叙述更加简介,作者通常不会在正文中提及调参取得sota的过程,而具体的参数对机器学习工程师来说显然更加重要。
而教科书也往往倾向于避免实践类的指导,即使有丰富的工程经验,作者也会优先选择对模型的原理进行介绍。
本文的作者发现,行业内目前还没有一次全面的实验来实际解释如何用深度学习获得更好的结果,只有一些博客文章、社交媒体等有一些零星的尝试结果,或是在论文的附录中简略介绍一下技巧,也有关于某个特定项目或pipeline的实例研究。
总之,关于调参,可参考的内容几乎是一片混乱。
从表面上来看,深度学习专家和一些初学者使用的调参方法都是类似的,但在他们手里,相同模型的性能却有着巨大的差距;不过,这些专家也承认,他们调参的方法可能并不总是可解释的,更多靠的是直觉。
随着深度学习技术的成熟,并对世界产生更大的影响,社区需要更多的资源,涵盖更多有价值的模型recipe,包括所有的工程细节,这对获得好的结果是非常关键的。
在亲身经历训练神经网络、教导新入行的机器学习工程师,以及为同事提供深度学习实践建议的过程中,作者团队积累了大量的经验。
虽然深度学习已经从一个局限于学术实验室的机器学习方法成长为了为数十亿人使用的产品提供底层支持的技术,但作为一门工程学科,深度学习仍然处于起步阶段,作者希望这份文档可以促进行业内对该领域进行系统性的研究。
作者同时表示,这篇文章只是在整理自己在开发深度学习模型时的经验,所以只能代表作者的观点,而非一种客观真理。
虽然本文的主要目的是解决在调整超参数时遇到的难题,但同时也涵盖了在模型开发时遇到的其他重要问题或错误,最好是让这篇文章可以随着技术的进步而不断发展。
最后,文章中还提及了很多作者还没有进行深入研究的内容,并在写作完成后才发现,整个模型构建过程中仍然有大量有趣且容易被忽视的研究问题。
开始新项目
在完成了足够多的问题定义、数据清理等基本工作后,在模型架构和训练设置上花时间才是有意义的。
编写好一个用来训练和评估的pipeline,可以方便地对模型进行训练和预测;选择好合适的评估指标,尽可能地能够指示出在部署环境中的模型性能。
然后,就可以开始调参了。
选择模型架构
当开始新项目时,尽量重用那些已经被证明有效的模型。
选择一个成熟的、常用的模型架构,先让模型跑起来之后再考虑搭建一个自定义的模型。
选择一个合适的模型架构通常意味着需要设置多个超参数来决定模型的大小和其他细节(如层数、层宽、激活函数的类型),在文章中「选择初始配置」和「提高模型性能的科学方法」章节中有详细介绍超参数的选择问题。
在可能的情况下,尽量找一篇解决与手头问题尽可能接近的论文,并将该模型作为起点进行修改。
选择优化器(optimizer)
从手头问题类型中最常见优化器开始。
在所有类型的机器学习问题和模型架构中,没有哪个优化器是「最好」的,即使只是简单地比较各个优化器的性能也是一项困难的任务。
作者建议坚持使用成熟的、常见的优化器,尤其是在开始一个新项目时,理想情况下最好选择用于同一类型问题的最流行的优化器。
要准备好关注所选优化器的「所有」超参数,具有更多超参数的优化器可能需要更多的调参工作来找到最佳配置。
这在项目的开始阶段尤其重要,因为我们正试图找到其他各种超参数的最佳值(例如架构超参数),同时将优化器的超参数视为滋扰参数。
在项目的最初阶段,最好是从一个更简单的优化器开始(例如,具有固定动量的SGD或固定的Adam),并在稳定后切换到一个更通用的优化器。
作者推荐的成熟的优化器包括但不限于:带动量的SGD(Nesterov变体);Adam和NAdam比带动量的SGD更通用,不过需要注意的是,Adam有4个可调整的超参数,并且很重要。
选择batch size
batch size主要控制训练速度,不应该用来直接调整验证集的性能。通常情况下,理想的选择是可用硬件所能支持的最大batch size。
batch size是决定训练时间和计算资源消耗的一个关键因素。
增加batch size通常会减少训练时间,一般来说都是有用的,比如可以在有限的时间内进行更多的实验来调整超参数,从而可能会构建一个性能更好的最终模型;也可以减少开发周期的延迟,更频繁地测试新想法。
但增加批处理量可能减少、增加或不改变资源消耗。
并且batch size不应该被当作验证集性能的可调整超参数,只要所有的超参数都调得很好(尤其是学习率和正则化超参数),并且训练步骤的数量足够多,使用任何batch size都应该可以达到相同的最终性能。
参考资料:
https://github.com/google-research/tuning_playbook