I want to compute the gradient of a function in several points. However, If I use tensors generated with torch.arange the gradient is not computed (the .grad attributes are None). Instead, using classical tensors it works. Why?
In the following an example
import torch
from torch import tensor
def l(w_1,w_2):
return w_1*w_2
w_1 = tensor(3., requires_grad=True)
w_2 = tensor(5., requires_grad=True)
l_v = l(w_1, w_2)
l_v.backward()
print(l_v.item(), w_1.grad, w_2.grad) # HERE WORKS OK
#############
for w_1_value in torch.arange(+2,+4,0.1, requires_grad=True):
for w_2_value in torch.arange(-2,+4,0.1, requires_grad=True):
print(w_1_value, w_2_value)
l_value = l(w_1_value, w_2_value)
l_value.backward()
print(l_value.item(), w_1_value.grad, w_2_value.grad) # HERE I GET NONE ON GRAD VALUES
UserWarning: The .grad attribute of a Tensor that is not a leaf Tensor is being accessed. Its .grad attribute won't be populated during autograd.backward(). If you indeed want the .grad field to be populated for a non-leaf Tensor, use .retain_grad() on the non-leaf Tensor. If you access the non-leaf Tensor by mistake, make sure you access the leaf Tensor instead. See github.com/pytorch/pytorch/pull/30531 for more informations.
Thank you for your answer, but I still don’t understand. What is UnbindBackward and why is it a problem when connected to my custom function graph?
Thanks again for your help
When you iterate over the items in the torch.arange tensors, you are getting a view of the tensor, which doesn’t have the grad.
Yes, you could also call it a view even if technically it’s an unbind operation. The root cause is still the same: the returned tensors in the for loop are non-leaf variables.