一些背景:
我正在使用scipy.optimize.minimize
中的Nelder-Mead单纯形优化算法对深度学习模型进行一些超参数优化。对于输入x和函数f,minimize
试图通过改变x来优化函数值f(x)。在我的例子中,x是模型f的超参数,它对一组恒定的训练样本进行预测。
由于f非常大,并且有许多训练示例,当对所有训练示例进行预测的并行问题分布在20个rtx-2080 GPU中时,每次调用f(x)大约需要10分钟。每一步都很昂贵。
由于某种原因(崩溃,GPU上的时间耗尽),脚本将在优化过程中停止。因此,我希望保存优化的状态,这样我就可以从它停止的地方继续它。我能够在每个NM期间保存超参数值x。一步,但这只是到此为止。即使你已经恢复了x(让我们称恢复的版本为x '),Nelder-Mead单纯形也会丢失。如果在x '处重新开始优化f,minimize
必须通过计算f(x' + p)*N次来重建单纯形,其中p是对x的一个维度的扰动,N是dim(x)或dim(x)+ 1。在我的例子中,x是高维的(>20),所以仅仅恢复单纯形就需要大约3个小时。
问:
我需要一种方法来访问单工在每一步的情况下崩溃。其他人建议使用回调来解决在使用scipy.optimize.minimize
(不一定是Nelder-Mead)优化期间恢复参数和函数值的问题。然而,在minimize
的文档中,它指出唯一可以通过回调返回当前参数值(x)* 和 * OptimizeResult
对象(在N.M.情况下可以包含单纯形的对象)的minimize
版本是“trust_constr”方法。换句话说,我很确定在“nelder_mead”版本中使用回调只能让你访问x。
我们提出的最佳解决方案是在minimize
源代码中编辑_minimize_neldermead
函数,以便在每一步之后保存单纯形值。有没有更优雅的方式来实现这一点?难道minimize
已经有这个能力了,只是我们找不到它?
1条答案
按热度按时间dpiehjr41#
我也遇到了同样的问题。对我来说有效的解决方案是以正常的方式定义函数
f(x)
,这样minimize()
就可以用输入数组x调用它。但是你也可以提供额外的参数,比如一个列表或数组,你可以用它来存储你的单纯形,它们的值,以及你的函数在此过程中可能计算的任何其他沿着的东西。所以你的函数看起来像这样:当你调用scipy.opt.minimize时,你的调用现在看起来像这样:
应该根据您的问题适当地设置各种选项值。通过使用
args
参数,minimize
知道传入额外的参数simplex_list
,并且您将其用作记录保存机制。请注意,如果您稍后向
f()
添加其他参数,例如要写入调试信息的目录路径或f()
可能需要计算的其他变量,则还必须以正确的顺序将它们添加到args
参数中。如果你不这样做,minimize()
将悄悄地对你失败。我对自己做过很多次...:)