Функция jacobian из torch всегда возвращает нули. Как исправить?

Вообщем, имеется задача: Изначально, есть некоторая функция function, которая на вход принимает один вектор numpy.ndarray, который в последствии разбирается на несколько векторов и матриц.

function внутри использует numpy, поэтому на вход должна принимать строго numpy.ndarray.

Поиск минимума требуется осуществить с помощью scipy.optimize.minimize методом BFGS, для которого требуется якобиан.

Чтобы посчитать якобиан, используется torch.autograd.functional.jacobian.

def jac(x, function):
    def inner(x):
        print(x)
        return tensor(function(x.detach().numpy()))
    return jacobian(inner, from_numpy(x)).numpy()

Но он всегда возвращает нулевой вектор, из-за чего минимум у функции получается везде.

UPD:

function в данном случае, является любой функцией, которая принимает numpy.ndarray и возвращает число. Важно, что эта функция использует внутри код, который работает при подаче на вход numpy.ndarray, но не работает при torch.tensor.

Например (в качестве тестовой функции), function может представлять из себя функцию Розенброка:

def RosenbrockFunction(x):
    print(x.dot(np.eye(2)))
    return (1 - x[0]) ** 2 + 100 * (x[1] - x[0] ** 2) ** 2

Строчка print(x.dot(np.eye(2))) представляет из себя код, который не может быть выполнен на torch.tensor.

Как это исправить?


Ответы (1 шт):

Автор решения: CrazyElf
  1. torch для вычисления Якобиана требуется доступ к функции и её градиентам. Если градиентов нет, то на выходе будут нули. А градиентов у вас не будет, видимо, из-за использования detach(), но может быть не только из-за этого, я не настолько в нём разбираюсь. Вообще использование torch - это отдельное искусство и отдельный способ мышления, лучше не смешивать его с другими библиотеками, а писать всё на только на нём. Либо вообще его не использовать.
  2. В библиотеке SciPy, которую вы уже используете, есть свой Якобиан.
  3. На английском SO есть и другие рецепты, как получить Якобиан в Python.
→ Ссылка