我通过改变3个参数来运行模拟。对于每个模拟,我计算一个指数,告诉我模拟是否正在改进(较低的指数)。要做到这一点,我使用scipy.optimize.minimize
,但我不确定哪种方法是最好的(我正在努力学习更多)。
def launcher(x0):
#varying parameters#
varying_p(x0[0], x0[1], x0[2])
run_sim(simulation)
results = import_results(simulation)
indexes = index_calc(Data_from,Data_to,simulation,results)
value = indexes['CHI_tot'].iloc[-1]
return value
每个参数在我用"边界"表示的范围内变化。
当我启动模拟时,每个参数都以非常小的步骤变化。有一种方法不仅可以定义变化范围,还可以定义每个参数的步长(例如步长为50
)
这可能有助于更快地获得优化结果?
v_cp = 999.209
v_rho = 1249.94
v_lambda = 0.2815
initialcond = np.array([v_cp, v_rho, v_lambda])
# Bounds: valid only for method L-BFGS-B, TNC, SLSQP, Powell, and trust-constr
bounds = [(400,1600), (400,1600), (0.1, 1.2)]
res = minimize(launcher, initialcond , bounds=bounds, method='L-BFGS-B', options = {'maxiter':10})
print(res.x)
所有基于SciPy梯度的优化器(L-BFGS-B, SLSQP等)显然期望目标函数的梯度。如果您不提供,他们将尝试为您计算一个数字,使用一些可笑的小步长(如10^-6)。这可能就是你所看到的。几个"变通方法":
-
我似乎记得一些优化器允许您设置梯度计算的步长("eps"参数)
-
(更好)在调用优化器时将参数在0和1之间规范化,并在调用外部模拟器之前将它们反规范化。