Понимание питорга, автоград - PullRequest
1 голос
/ 27 января 2020

Я пытаюсь понять, как работает автоград Pytorch. Если у меня есть функции y = 2x и z = y ** 2, если я делаю нормальное дифференцирование, я получаю dz / dx при x = 1 как 8 (dz / dx = dz / dy * dy / dx = 2y * 2 = 2 (2x) * 2 = 8x). Или z = (2x) ** 2 = 4x ^ 2 и dz / dx = 8x, поэтому при x = 1 оно равно 8.

Если я сделаю то же самое с автоградой Pytorch, я получу 4

x = torch.ones(1,requires_grad=True)
y = 2*x
z = y**2
x.backward(z)
print(x.grad)

который печатает

tensor([4.])

где я ошибаюсь?

1 Ответ

2 голосов
/ 27 января 2020

Вы используете Tensor.backward неправильно. Чтобы получить запрошенный результат, вы должны использовать

x = torch.ones(1,requires_grad=True)
y = 2*x
z = y**2
z.backward()  # <-- fixed
print(x.grad)

. Вызов z.backward() вызывает алгоритм обратного распространения, начиная с z и возвращаясь к каждому конечному узлу в графе вычислений. В этом случае x является единственным листовым узлом. После вызова z.backward() граф вычислений сбрасывается, и элемент .grad каждого конечного узла обновляется с градиентом z относительно конечного узла (в данном случае dz / dx).

Что на самом деле происходит в вашем оригинальном коде? Что ж, вы сделали, примените обратное распространение, начиная с x. Без аргументов x.backward() просто приведет к тому, что для x.grad будет установлено значение 1, поскольку dx / dx = 1. Дополнительный аргумент (gradient) фактически является шкалой, применяемой к результирующему градиенту. В этом случае z=4, поэтому вы получите x.grad = z * dx/dx = 4 * 1 = 4. Если вам интересно, вы можете проверить this для получения дополнительной информации о том, что делает аргумент gradient.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...