Проблемы с autograd.hessian_vector_product и scipy.optimize.NonlinearConstraint - PullRequest
0 голосов
/ 08 марта 2019

Я пытаюсь запустить проблему минимизации, используя scipy.optimize, включая NonlinearConstraint. Я действительно не хочу сам кодировать производные, поэтому я использую autograd для этого. Но даже если я следую точно такой же процедуре для аргументов minimize и NonlinearConstraint, первый, кажется, работает, а второй - нет.

Вот мой MWE:

useconstraint = False

import autograd
import autograd.numpy as np
from scipy import optimize

def function(x): return x[0]**2 + x[1]**2
functionjacobian = autograd.jacobian(function)
functionhvp = autograd.hessian_vector_product(function)

def constraint(x): return np.array([x[0]**2 - x[1]**2])
constraintjacobian = autograd.jacobian(constraint)
constrainthvp = autograd.hessian_vector_product(constraint)

constraint = optimize.NonlinearConstraint(constraint, 1, np.inf, constraintjacobian, constrainthvp)

startpoint = [1, 2]

bounds = optimize.Bounds([-np.inf, -np.inf], [np.inf, np.inf])

print optimize.minimize(
  function,
  startpoint,
  method='trust-constr',
  jac=functionjacobian,
  hessp=functionhvp,
  constraints=[constraint] if useconstraint else [],
  bounds=bounds,
)

Когда я выключаю useconstraint (вверху), он работает нормально и минимизируется на (0, 0), как и ожидалось. Когда я включаю его, я получаю следующую ошибку:

Traceback (most recent call last):
  File "test.py", line 29, in <module>
    bounds=bounds,
  File "/home/heshy/.local/lib/python2.7/site-packages/scipy/optimize/_minimize.py", line 613, in minimize
    callback=callback, **options)
  File "/home/heshy/.local/lib/python2.7/site-packages/scipy/optimize/_trustregion_constr/minimize_trustregion_constr.py", line 336, in _minimize_trustregion_constr
    for c in constraints]
  File "/home/heshy/.local/lib/python2.7/site-packages/scipy/optimize/_constraints.py", line 213, in __init__
    finite_diff_bounds, sparse_jacobian)
  File "/home/heshy/.local/lib/python2.7/site-packages/scipy/optimize/_differentiable_functions.py", line 343, in __init__
    self.H = hess(self.x, self.v)
  File "/home/heshy/.local/lib/python2.7/site-packages/autograd/wrap_util.py", line 20, in nary_f
    return unary_operator(unary_f, x, *nary_op_args, **nary_op_kwargs)
  File "/home/heshy/.local/lib/python2.7/site-packages/autograd/differential_operators.py", line 24, in grad
    vjp, ans = _make_vjp(fun, x)
  File "/home/heshy/.local/lib/python2.7/site-packages/autograd/core.py", line 10, in make_vjp
    end_value, end_node =  trace(start_node, fun, x)
  File "/home/heshy/.local/lib/python2.7/site-packages/autograd/tracer.py", line 10, in trace
    end_box = fun(start_box)
  File "/home/heshy/.local/lib/python2.7/site-packages/autograd/wrap_util.py", line 15, in unary_f
    return fun(*subargs, **kwargs)
  File "/home/heshy/.local/lib/python2.7/site-packages/autograd/differential_operators.py", line 88, in vector_dot_grad
    return np.tensordot(fun_grad(*args, **kwargs), vector, np.ndim(vector))
  File "/home/heshy/.local/lib/python2.7/site-packages/autograd/tracer.py", line 44, in f_wrapped
    ans = f_wrapped(*argvals, **kwargs)
  File "/home/heshy/.local/lib/python2.7/site-packages/autograd/tracer.py", line 48, in f_wrapped
    return f_raw(*args, **kwargs)
  File "/home/heshy/.local/lib/python2.7/site-packages/numpy/core/numeric.py", line 1371, in tensordot
    raise ValueError("shape-mismatch for sum")
ValueError: shape-mismatch for sum

Что я делаю не так? Я думаю, что проблема в hessian_vector_product, потому что я вижу hess в сообщении об ошибке, но я не уверен в этом.

1 Ответ

0 голосов
/ 12 марта 2019

Хорошо, я нашел ответ.Это очень сбивало с толку.

Аргумент hessp для minimize ожидает функцию, которая возвращает "гессиан целевой функции, умноженный на произвольный вектор p" ( source ).Напротив, аргумент hess для NonlinearConstraint предполагает, что «вызываемый [который] должен возвращать матрицу Гессе точки (fun, v)» ( source ).

Если выинтерпретировать первую цитату, как я это сделал, «гессиан из (целевая функция умножается на произвольный вектор p)», это означает почти то же самое, что и «матрица гессенской точки (fun, v)».Поэтому я предположил, что вы можете использовать одну и ту же функцию autograd для обоих.

Тем не менее, правильная интерпретация - это "(гессиан целевой функции) умноженный на произвольный вектор p", что совершенно различно.Функция hessian_vector_product в autograd дает правильный результат для первого, но вам нужна другая функция для второго.

...