Как получить полный якобиан производной в PyTorch?

Давайте рассмотрим простой тензор x и определим другой, который зависит от x и имеет несколько измерений: y = (x, 2x, x^2).

Как получить полный градиент dy/dx = (1,2,x)?

Например, возьмем код:

import torch
from torch.autograd import grad

x = 2 * torch.ones(1)
x.requires_grad = True
y = torch.cat((x, 2*x, x*x))
# dy_dx = ???

Вот что я до сих пор безуспешно пробовал:

>>> dy_dx = grad(y, x, grad_outputs=torch.ones_like(y), create_graph=True)
(tensor([7.], grad_fn=<AddBackward0>),)
>>> dy_dx = grad(y, x, grad_outputs=torch.Tensor([1,0,0]), create_graph=True)
(tensor([1.], grad_fn=<AddBackward0>),)
>>> dy_dx = grad(y, [x,x,x], grad_outputs=torch.eye(3), create_graph=True)
(tensor([7.], grad_fn=<AddBackward0>),)

Каждый раз я получал только часть градиента или накопленную версию ...

Я знаю, что могу использовать цикл for, используя второе выражение вроде

dy_dx = torch.zeros_like(y)
coord = torch.zeros_like(y)
for i in range (y.size(0)):
    coord[i] = 1
    dy_dx[i], = grad(y, x, grad_outputs=coord, create_graph=True)
    coord[i] = 0

Однако, поскольку я имею дело с тензорами большой размерности, этот цикл for может занять слишком много времени для вычисления. Более того, должен быть способ выполнить полный якобиан без вакуумирования градиента ...

Есть у кого-нибудь решение? Или альтернатива?


person Kilian Hersent    schedule 06.08.2019    source источник
comment
Когда вы передаете grad_outputs, вы получаете результат между градиентом и grad_outputs. В вашем случае градиент (1, 2, 2x) с x == 2, поэтому то, что вы получите обратно (если grad_outputs равно [1, 1, 1]), похоже на ([1, 2, 4] * [1, 1, 1]).sum()). Я не знаю, как вернуть отдельные градиенты - действительно ли они вам нужны? Мне всегда удавалось использовать продукт градиентов и какой-то другой тензор, когда мне нужны были градиенты. Что бы вы сделали дальше, если бы у вас были отдельные градиенты?   -  person Nathan    schedule 06.08.2019
comment
Спасибо, @Nathan! В самом деле, мне нужен полный градиент, потому что в настоящее время я пытаюсь решить дифференциальное уравнение с помощью нейронной сети. Я подумал о другом способе сделать это, но похоже, что если бы у меня был полный градиент, мой код был бы очень эффективным!   -  person Kilian Hersent    schedule 06.08.2019
comment
Возможный дубликат обратной функции в PyTorch   -  person Shai    schedule 06.08.2019
comment
Извините, @Shai, но я так не думаю ... Мой вопрос не в том, что означает аргумент grad_outputs функции grad (что эквивалентно аргументу, указанному в функции backward). У меня вопрос, как получить полный якобиан в Pytoch ?. Другими словами, взяв пример с обратной функции в Pytorch, как мне получить 2- by-3-by-2-by-3 вывод функции backward? Изменить: Однако, как вы правильно заметили, мой заголовок был неоднозначным, и я изменил его.   -  person Kilian Hersent    schedule 06.08.2019


Ответы (1)


torch.autograd.grad в PyTorch агрегирован. Чтобы вектор автоматически дифференцировался по входу, используйте torch.autograd.functional.jacobian.

person alxyok    schedule 23.11.2020