Я пытаюсь понять, как работает PyTorch, реализовав метод Ньютона для решения x = cos (x) .Вот версия, которая работает:
x = Variable(DoubleTensor([1]), requires_grad=True)
for i in range(5):
y = x - torch.cos(x)
y.backward()
x = Variable(x.data - y.data/x.grad.data, requires_grad=True)
print(x.data) # tensor([0.7390851332151607], dtype=torch.float64) (correct)
Этот код кажется мне не элегантным (неэффективным?), Поскольку он воссоздает весь вычислительный граф на каждом этапе цикла for
(верно?).Я пытался избежать этого, просто обновляя данные, хранящиеся в каждой из переменных, вместо того, чтобы воссоздавать их:
x = Variable(DoubleTensor([1]), requires_grad=True)
y = x - torch.cos(x)
y.backward(retain_graph=True)
for i in range(5):
x.data = x.data - y.data/x.grad.data
y.data = x.data - torch.cos(x.data)
y.backward(retain_graph=True)
print(x.data) # tensor([0.7417889255761136], dtype=torch.float64) (wrong)
Похоже, с DoubleTensor
s я несу достаточно цифр точности, чтобы исключитьошибка округления.Так откуда же возникла ошибка?
Возможно, связано: Приведенный выше фрагмент разбивается без флага retain_graph=True
, установленного на каждом шаге, если цикл for
.Я получаю сообщение об ошибке, если опускаю его в цикле - но сохраняю его в строке 3 -: RuntimeError: Попытка выполнить обратный просмотр графика во второй раз, но буферы уже освобождены.Укажите retain_graph = True при обратном вызове в первый раз . Это похоже на доказательство того, что я что-то неправильно понимаю ...