【问题标题】:scipy minimize 'trust-krylov' doesn't seem to stop when the change reaches 'tol'当更改达到“tol”时,scipy 最小化“trust-krylov”似乎并没有停止
【发布时间】:2017-12-06 23:55:20
【问题描述】:

我在一个非常复杂的最小化问题上使用了 scipy.optimize.minimize 的 trust-krylov 方法(在这里发布实际代码太长了)。我发现,当迭代之间的目标函数的差异变化低于我设置的“tol”关键字时,例程会运行 许多 次迭代。我们称目标函数为 J,从迭代 i 到 i+1 的变化为 dJ。

我理解“tol”是指迭代之间目标值 dJ 可接受的最小变化。因此,如果我将 'tol' 设置为 1.e-4,如

res=minimize(J,X0,method='trust-krylov', tol=1.e-4, jac=Jacobian,hessp=Hessian)

然后我希望代码在 dJ 下降并保持在该值以下后停止运行几次迭代。但是我现在正在运行一个代码并且 dJ 低于 1.e-8 并且在 16 次迭代和计数后它仍然以这种方式运行。可能的错误?

【问题讨论】:

    标签: python scipy


    【解决方案1】:

    您误解了tol 参数。

    这不是关于:|obj_i - obj_i-1|(基于标量的计算),而是关于:||grad_i||_p(基于向量的计算)。

    后一种条件经常被使用,并且是大多数非线性优化器的一部分(尤其是当没有 KKT 条件或二阶信息可用时)。它也直接遵循理论:局部最优点的一阶必要最优性条件

    您可以查看来源:

    here: tol becomes gtol:

    if meth in ('bfgs', 'cg', 'l-bfgs-b', 'tnc', 'dogleg',
                'trust-ncg', 'trust-exact', 'trust-krylov'):
       options.setdefault('gtol', tol)
    

    here: _minimize_trust_krylov is called:

    elif meth == 'trust-krylov':
        return _minimize_trust_krylov(fun, x0, args, jac, hess, hessp,
                                      callback=callback, **options)
    

    _trustregion_krylov talks about the oder conditions 并根据 exact / inexact 调用最终优化器:

    if inexact:
        return _minimize_trust_region(fun, x0, args=args, jac=jac,
                                      hess=hess, hessp=hessp,
                                      subproblem=get_trlib_quadratic_subproblem(
                                          tol_rel_i=-2.0, tol_rel_b=-3.0,
                                          disp=trust_region_options.get('disp', False)
                                          ),
                                      **trust_region_options)
    else:
        return _minimize_trust_region(fun, x0, args=args, jac=jac,
                                      hess=hess, hessp=hessp,
                                      subproblem=get_trlib_quadratic_subproblem(
                                          tol_rel_i=1e-8, tol_rel_b=1e-6,
                                          disp=trust_region_options.get('disp', False)
                                          ),
                                      **trust_region_options)
    

    the optimizer used 包含以下几行:

    gtol : float
        Gradient norm must be less than `gtol`
        before successful termination.
    
    # check if the gradient is small enough to stop
    if m.jac_mag < gtol:
        warnflag = 0
        break
    
    # check if we have looked at enough iterations
    if k >= maxiter:
        warnflag = 1
        break
    

    here jac_mag is found:

    @property
    def jac_mag(self):
        """Magniture of jacobian of objective function at current iteration."""
        if self._g_mag is None:
            self._g_mag = scipy.linalg.norm(self.jac)
        return self._g_mag
    

    在这个答案的开头之后,并且使用了 euclidean-norm (p=2)

    【讨论】:

      猜你喜欢
      • 2014-09-09
      • 1970-01-01
      • 2014-07-12
      • 1970-01-01
      • 2022-01-15
      • 2012-02-29
      • 2018-04-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多