【发布时间】:2017-07-08 00:17:41
【问题描述】:
我正在构建一个脚本来生成输入数据 [参数] 供另一个程序计算。我想优化结果数据。以前我一直在使用 numpy powell 优化。伪代码看起来像这样。
def value(param):
run_program(param)
#Parse output
return value
scipy.optimize.fmin_powell(value,param)
这很好用;但是,它非常慢,因为程序的每次迭代都可能需要数天才能运行。我想做的是粗粒度并行化这个。因此,它不会一次运行一次迭代,而是一次运行(参数数量)*2。例如:
Initial guess: param=[1,2,3,4,5]
#Modify guess by plus minus another matrix that is changeable at each iteration
jump=[1,1,1,1,1]
#Modify each variable plus/minus jump.
for num,a in enumerate(param):
new_param1=param[:]
new_param1[num]=new_param1[num]+jump[num]
run_program(new_param1)
new_param2=param[:]
new_param2[num]=new_param2[num]-jump[num]
run_program(new_param2)
#Wait until all programs are complete -> Parse Output
Output=[[value,param],...]
#Create new guess
#Repeat
变量的数量可以从 3 到 12 不等,因此这样的事情可能会加速代码从一年缩短到一周。所有变量都相互依赖,我只是从最初的猜测中寻找局部最小值。我已经开始使用 hessian 矩阵实现;但是,这涉及很多。有没有什么可以做到这一点,有没有更简单的方法,或者有什么建议可以开始?
所以主要问题如下: 是否有一种算法可以进行初始猜测,生成多个猜测,然后使用这些多个猜测来创建新的猜测,然后重复直到找到阈值。只有解析导数可用。有什么好的方法可以解决这个问题,是否已经构建了可以做到这一点的东西,还有其他选择吗?
感谢您的宝贵时间。
作为一个小更新,我确实通过计算每个维度的三个点的简单抛物线,然后使用最小值作为下一个猜测来实现这一点。这似乎工作得很好,但不是最佳的。我仍在寻找其他选择。
目前最好的实现是并行化鲍威尔方法的内循环。
感谢大家的 cmets。不幸的是,对于这个特定问题,似乎没有一个简明的答案。如果我开始实施一些可以做到这一点的东西,我会把它贴在这里;但是,由于该项目不是特别重要或需要紧迫的结果,我可能会满足于让它占用一个节点一段时间。
【问题讨论】:
-
这与您的问题没有直接关系;但是由于您的任务是资源密集型的,使用像 C 这样的编译语言来提高性能不是更有意义吗?
-
@Ophion 您可能希望先审查您的代码。还要考虑这些性能提示。 wiki.python.org/moin/PythonSpeed/PerformanceTips
-
主要代码是 C 语言并经过高度优化,不幸的是,跨多个计算节点并行化它的实现并不是特别有效。我需要一些东西来与主要代码交互并优化一组它不是设计用来做的参数。重新编写主要代码以执行此操作是一种选择,但可能更复杂,最终收效甚微。
-
那么你到底想要什么并行? run_program() 有什么作用?如果它没有弄乱任何变量,您可以轻松使用池及其映射函数 (docs.python.org/2/library/…)
-
run_program(param) 使用输入参数执行主代码并返回一个奇异值。基本上我想要做的是拥有鲍威尔算法的并行版本或其他一些最好不需要导数并且可以同时考虑多个猜测的最小化算法。
标签: python numpy mathematical-optimization