У меня есть некоторая функция z (x, y), и я хотел бы создать график колчана (2D-график градиентов). Что-то вроде этого:
Для этого мне нужно запустить градиент над линейной сеткой и настроить данные в формате, который делает matplotlib.quiver.
Наивный способ состоит в том, чтобы перебирать вперед и назад в цикле:
for i in range(10):
for j in range(10):
x = torch.tensor(1. * i, requires_grad=True)
y = torch.tensor(1. * j, requires_grad=True)
z = x ** 2 + y ** 2
z.backward()
print(x.grad, y.grad)
Это, очевидно, очень неэффективно. Есть несколько примеров того, как создать линейную сетку из x, y, но мне нужно будет позже изменить сетку обратно в формат форвардной формулы, получить векторы градиента и вернуть их обратно и т.д.
Простым примером в numpy будет:
import matplotlib.pyplot as plt
n = 25
x_range = np.linspace(-25, 25, n)
y_range = np.linspace(-25, 25, n)
X, Y = np.meshgrid(x_range, y_range)
Z = X**2 + Y**2
U, V = 2*X, 2*Y
plt.quiver(X, Y, U, V, Z, alpha=.9)
Каким будет стандартный способ сделать это с помощью pytorch? Существуют ли некоторые простые примеры?
Вы можете вычислить градиенты torch.Tensor
путем прохождения torch.Tensor
единиц.
import matplotlib.pyplot as plt
import torch
# create meshgrid
n = 25
a = torch.linspace(-25, 25, n)
b = torch.linspace(-25, 25, n)
x = a.repeat(n)
y = b.repeat(n, 1).t().contiguous().view(-1)
x.requires_grad = True
y.requires_grad=True
z = x**2 + y**2
# this line will compute the gradients
torch.autograd.backward([z], [torch.ones(x.size()), torch.ones(y.size())])
# detach to plot
plt.quiver(x.detach(), y.detach(), x.grad, y.grad, z.detach(), alpha=.9)
plt.show()
Если вам нужно сделать это несколько раз, вам нужно обнулить градиенты (установите x.grad = y.grad = None
).