使用`scipy.optimize.minimize`最大限度地减少具有大渐变的函数

时间:2016-02-22 16:53:17

标签: python scipy mathematical-optimization

我需要在高维空间中优化标量函数。函数随着参数的变化而变化很快,因此渐变的(绝对值)很大。 scipy.optimize.minimize中的优化器失败,因为最小化过程采用过大的步骤。以下代码使用简单的二次函数说明了问题。

from scipy.optimize import minimize

def objective(x, scalar=1):
    """
    Quadratic objective function with optional scalar.
    """
    # Report function call for debugging
    print "objective({}, scalar={})".format(x, scalar)
    # Return function value and gradient
    return x ** 2 * scalar, 2 * x * scalar

# This optimisation succeeds
print minimize(objective, 1, jac=True)
# This optimisation fails
print minimize(objective, 1, (1e8, ), jac=True)

当然,我可以手动重新调整感兴趣函数的值和梯度,但我想知道是否有一种推荐的方法来最小化这些函数,例如:指定学习率。

1 个答案:

答案 0 :(得分:3)

对于大型非线性优化问题,通常会注意(至少)四件事:

  1. 缩放
  2. 初始值
  3. Bounds
  4. 精确的渐变和可能的二阶导数(用于复杂问题 使用允许自动区分的建模系统)
  5. 一些更高级的解算器可能会为自动缩放提供一些支持。然而,非线性问题的缩放并不容易,因为雅可比会发生变化(一些通常可用的策略是:仅缩放线性部分,在开始时基于初始值缩放线性+非线性部分,或者在期间重新缩放问题迭代过程)。线性求解器在这方面工作更容易(雅可比矩阵是常数,因此我们可以在开始时缩放一次)。 Scipy.optimize.minimize不是最先进的,所以我鼓励你自己扩展(通常你只能在求解器开始之前执行此操作;在某些情况下,你甚至可以停止求解器重新缩放,然后再次使用求解器最后一点作为初始值 - 这听起来很疯狂,但这个技巧帮了我几次)。良好的初始点和良好的界限在这方面也有帮助(为了使求解器保持在可以可靠地评估函数和梯度的合理区域)。最后,模型重构有时可以帮助提供更好的缩放(通过乘法取代除法,取日志等)。