Метод backward
Метод backward класса Tensor вычисляет градиенты текущего тензора по отношению к листовым узлам вычислительного графа. Для скалярных тензоров вызывается без аргументов. Для тензоров, имеющих более одного элемента, необходимо передать тензор весов gradient.
Синтаксис
t.backward([gradient], [retain_graph], [create_graph])
Метод принимает три необязательных параметра:
gradient - тензор весов, соответствующий форме исходного тензора. Обязателен, если тензор не скалярный.
retain_graph - флаг, указывающий, нужно ли сохранять вычислительный граф после обратного распространения для повторного использования.
create_graph - флаг, указывающий, нужно ли строить граф для вычисления производных более высокого порядка.
Пример вычисления градиента для скалярного тензора
Давайте создадим тензор с включенным отслеживанием градиентов и вызовем метод backward для скалярного результата:
import torch
t = torch.tensor([2.0, 3.0], requires_grad=True)
res = (t * t).sum()
res.backward()
print(t.grad)
Результат выполнения кода:
tensor([4., 6.])
Пример вычисления градиента для нескалярного тензора
Для нескалярного тензора необходимо передать весовой тензор в метод backward:
import torch
t = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
grad_weight = torch.tensor([0.1, 0.2, 0.3])
t.backward(grad_weight)
print(t.grad)
Результат выполнения кода:
tensor([0.1000, 0.2000, 0.3000])
Пример с сохранением графа для повторного использования
Используем параметр retain_graph для повторного вызова метода backward на том же тензоре:
import torch
t = torch.tensor([2.0, 4.0], requires_grad=True)
res = (t * t).sum()
res.backward(retain_graph=True)
print(t.grad)
res.backward()
print(t.grad)
Результат выполнения кода:
tensor([4., 8.])
tensor([8., 16.])
Пример вычисления производных второго порядка
Установим флаг create_graph для построения графа для производных второго порядка:
import torch
t = torch.tensor([1.0, 2.0], requires_grad=True)
res = (t * t).sum()
first_grad = torch.autograd.grad(res, t, create_graph=True)[0]
second_grad = torch.autograd.grad(first_grad.sum(), t, create_graph=True)[0]
print(first_grad)
print(second_grad)
Результат выполнения кода:
tensor([2., 4.], grad_fn=<MulBackward0>)
tensor([2., 2.])
Пример использования в нейронной сети
Рассмотрим использование метода backward для вычисления градиентов параметров простой линейной модели:
import torch
torch.manual_seed(0)
model = torch.nn.Linear(2, 1)
x = torch.tensor([[1.0, 2.0], [3.0, 4.0]])
y = torch.tensor([[0.0], [1.0]])
pred = model(x)
loss = ((pred - y) ** 2).mean()
loss.backward()
for name, param in model.named_parameters():
print(f"{name}.grad: {param.grad}")
Результат выполнения кода:
weight.grad: tensor([[-0.0826],
[-0.1651]])
bias.grad: tensor([-0.0826])
Смотрите также
-
атрибут
grad,
который хранит вычисленные градиенты тензора -
атрибут
requires_grad,
который указывает, нужно ли отслеживать градиенты для тензора -
атрибут
grad_fn,
который хранит функцию, создавшую тензор в вычислительном графе -
метод
retain_grad,
который позволяет сохранить градиенты для нелистовых тензоров