我在 Python 中实现 NLOPT 时遇到问题。我的目标是最小化一个有点复杂的最大似然函数。
我的函数称为 mle,有 6 个参数需要估计。
找到这个 MLE 的梯度并非易事,所以我决定转向数值梯度函数:
def numgrad(f, x, step=1e-6):
"""numgrad(f: function, x: num array, step: num) -> num array
Numerically estimates the gradient of a function f which takes an array as
its argument.
"""
ary = len(x)
curr = x * sp.ones((ary, ary))
next = curr + sp.identity(ary) * step
delta = sp.apply_along_axis(f, 1, next) - sp.apply_along_axis(f, 1, curr)
return delta / step
然后我的 NLOPT 实现是这样的:
def myfunc(x, grad):
if grad.size > 0:
grad = numgrad(mle, [x[0], x[1], x[2], x[3], x[4], x[5]], step=1e-14)
return mle([x[0], x[1], x[2], x[3], x[4], x[5]])
opt = nlopt.opt(nlopt.LD_SLSQP, 6)
opt.set_lower_bounds([mmin, smin, ming, bmin, vmin, pmin]) #min bound for each of the param.
opt.set_upper_bounds([mmax, smax, maxg, bmax, vmax, pmax])
opt.set_min_objective(myfunc)
opt.set_xtol_rel(1e-15)
opt.maxeval=10000
x = opt.optimize([x1, x2, x3, x4, x5, x6])
minf = opt.last_optimum_value()
print "optimum at ", x[0], x[1], x[2], x[3], x[4], x[5]
print "minimum value = ", minf
print "result code = ", opt.last_optimize_result()
现在的问题是......最小化过程太快了。在 matlab 中,大约需要 1 小时,而在 Python 中需要 12 秒……我在使用 fmincon 的 Matlab 中没有得到相同的结果。
我的感觉是代码无法识别opt.set_xtol_rel(1e-15)andopt.maxeval=10000语句,因为即使我增加数字......时间过程没有变化......
或者问题出在其他地方......我做错了什么?