问题描述
我正在通过改变 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,(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,并在调用外部模拟器之前对其进行反标准化。