Backward got grad of none

username: Tony_Lee
cooked: <p>Hello, I use the backward to solve the grad, the demo code is as follows:</p>
<pre><code class="lang-auto">import torch


def angle2matrix(angles, device=torch.device('cpu')):
    angles = angles/180*3.1415926
    x = angles[0]
    y = angles[1]
    z = angles[2]

    # x
    Rx = torch.tensor([[1, 0, 0],
                   [0, torch.cos(x), -torch.sin(x)],
                   [0, torch.sin(x), torch.cos(x)]]).to(device)
    # y
    Ry = torch.tensor([[torch.cos(y), 0, torch.sin(y)],
                   [0, 1, 0],
                   [-torch.sin(y), 0, torch.cos(y)]]).to(device)
    # z
    Rz = torch.tensor([[torch.cos(z), -torch.sin(z), 0],
                   [torch.sin(z), torch.cos(z), 0],
                   [0, 0, 1]]).to(device)

    R = Rz.mm(Ry.mm(Rx))
    return R

x=torch.ones(3,requires_grad=True)
y=torch.pow(angle2matrix(x),2)
y.sum().backward()

print(x.grad)
</code></pre>
<p>then I got the error as follows:</p>
<pre><code class="lang-auto">Traceback (most recent call last):
  File "app/transform.py", line 110, in &lt;module&gt;
    y.sum().backward()
  File "/root/anaconda3/lib/python3.7/site-packages/torch/tensor.py", line 198, in backward
    torch.autograd.backward(self, gradient, retain_graph, create_graph)
  File "/root/anaconda3/lib/python3.7/site-packages/torch/autograd/__init__.py", line 100, in backward
    allow_unreachable=True)  # allow_unreachable flag
RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn
</code></pre>
<p>then I change the <code> angle2matrix</code> as follows:</p>
<pre><code class="lang-auto">def angle2matrix(angles, device=torch.device('cpu')):

    angles = angles/180*3.1415926
    x = angles[0]
    y = angles[1]
    z = angles[2]

    # x
    Rx = torch.tensor([[1, 0, 0],
                   [0, torch.cos(x), -torch.sin(x)],
                   [0, torch.sin(x), torch.cos(x)]]).to(device)
    # y
    Ry = torch.tensor([[torch.cos(y), 0, torch.sin(y)],
                   [0, 1, 0],
                   [-torch.sin(y), 0, torch.cos(y)]]).to(device)
    # z
    Rz = torch.tensor([[torch.cos(z), -torch.sin(z), 0],
                   [torch.sin(z), torch.cos(z), 0],
                   [0, 0, 1]]).to(device)

    Rx.requires_grad=True
    Ry.requires_grad=True
    Rz.requires_grad=True

    R = Rz.mm(Ry.mm(Rx))
    return R

x=torch.ones(3,requires_grad=True)
y=torch.pow(angle2matrix(x),2)
y.sum().backward()

print(x.grad)
</code></pre>
<p>but this time I the grad of <code>x</code> is none.</p>
<p>looking forward to your help !</p>

username: Kushaj
cooked: <p>Your problem is this</p>
<pre><code class="lang-python">x = torch.tensor([1., 2], requires_grad=True)
y = torch.tensor(x, requires_grad=True)
y.sum().backward()
</code></pre>
<p>Now when you backprop through y, y is a leaf (because torch.tensor creates leaf), there is no path to propagate the gradients to x i.e. why <code>x.grad=None</code>.</p>

username: Kushaj
cooked: <p>One way to solve this problem is by doing something as follows</p>
<pre><code class="lang-python">x = torch.tensor([1., 2.], requires_grad=True)
y = [x[0], x[1]]
(y[0]+y[1]).backward()

# Now gradients will be propagated to x
</code></pre>
<p>I don’t know if there is an easier way. But you need to convert Rx, Ry, Rx to lists and then work from there for your code to work.</p>

username: Sagar_Dollin
cooked: <p>I’m facing a similar issue… I’m basically trying to pass two parameters for two matrices each. And then calculate loss using mse of y and predicted output. And backpropagate to the paparmeters. This is my code:</p>
<pre><code class="lang-auto">import torch

def get_device(gpu_no):
    if torch.cuda.is_available():
        return torch.device('cuda', gpu_no)
    else:
        return torch.device('cpu')


device = get_device(0)

params = torch.tensor(([[0.011], [0.012]]), requires_grad=True).to(device).to(torch.cfloat)

x_gate = torch.tensor([[1., 0.], [0., 1.]]).to(device)
y_gate = torch.tensor(([[0, -1j], [1j, 0]])).to(device)


def rx(theta):
    # co = torch.cos(theta / 2)
    # si = torch.sin(theta / 2)
    Rx_gate = torch.exp(-1j * (theta / 2) * x_gate).to(device).to(torch.cfloat).requires_grad_()

    return Rx_gate


def ry(theta):
    # co = torch.cos(theta / 2)
    # si = torch.sin(theta / 2)
    Ry_gate = torch.exp(-1j * (theta / 2) * y_gate).to(device).to(torch.cfloat).requires_grad_()

    return Ry_gate


x = torch.tensor([1., 0.]).to(device).to(torch.cfloat)
y = torch.tensor([0., 1.]).to(device).to(torch.cfloat)


def pred(params):
    out = rx(params[0]) @ x
    out = ry(params[1]) @ out
    return out

print("params        :", params)
print("prediction    :", pred(params))

loss = torch.pow((y - pred(params)), 2).sum()
print("loss          :", loss)

loss.backward()
print("loss grad     :", loss.grad)
print("params grad   :", params.grad)
</code></pre>
<p>The output I get is:</p>
<pre><code class="lang-auto">params        : tensor([[0.0110+0.j],
        [0.0120+0.j]], device='cuda:0', grad_fn=&lt;ToCopyBackward0&gt;)
prediction    : tensor([1.9940-0.0055j, 2.0060-0.0055j], device='cuda:0',
       grad_fn=&lt;MvBackward0&gt;)
loss          : tensor(4.9880-0.0331j, device='cuda:0', grad_fn=&lt;SumBackward0&gt;)
loss grad     : None
params grad   : None
</code></pre>
<p>I tried defining rx() and ry() in different ways like:</p>
<pre><code class="lang-auto">def rx(theta):
    co = torch.cos(theta / 2)
    si = torch.sin(theta / 2)
    Rx_gate = torch.stack([torch.cat([co, -si], dim=-1),
                          torch.cat([-si, co], dim=-1)], dim=-2).squeeze(0).to(device).to(torch.cfloat).requires_grad_()
    # Rx_gate = torch.exp(-1j * (theta / 2) * x_gate).to(device).to(torch.cfloat).requires_grad_()

    return Rx_gate


def ry(theta):
    co = torch.cos(theta / 2)
    si = torch.sin(theta / 2)
    Ry_gate = torch.stack([torch.cat([co, -si]),
                                torch.cat([si, co])], dim=-2).squeeze(0).to(device).to(torch.cfloat).requires_grad_()
    # Ry_gate = torch.exp(-1j * (theta / 2) * y_gate).to(device).to(torch.cfloat).requires_grad_()

    return Ry_gate
</code></pre>
<p>and like this:</p>
<pre><code class="lang-auto">def rx(theta):
    # co = torch.cos(theta / 2)
    # si = torch.sin(theta / 2)
    # Rx_gate = torch.stack([torch.cat([co, -si], dim=-1),
    #                       torch.cat([-si, co], dim=-1)], dim=-2).squeeze(0).to(device).to(torch.cfloat).requires_grad_()
    # Rx_gate = torch.exp(-1j * (theta / 2) * x_gate).to(device).to(torch.cfloat).requires_grad_()
    Rx_gate = torch.tensor(([[torch.cos(theta/2), -torch.sin(theta/2)],
                             [-torch.sin(theta/2), torch.cos(theta/2)]]), requires_grad=True).to(device).to(torch.cfloat)

    return Rx_gate


def ry(theta):
    # co = torch.cos(theta / 2)
    # si = torch.sin(theta / 2)
    # Ry_gate = torch.stack([torch.cat([co, -si]),
    #                             torch.cat([si, co])], dim=-2).squeeze(0).to(device).to(torch.cfloat).requires_grad_()
    # Ry_gate = torch.exp(-1j * (theta / 2) * y_gate).to(device).to(torch.cfloat).requires_grad_()
    Ry_gate = torch.tensor(([[torch.cos(theta / 2), -torch.sin(theta / 2)],
                        [torch.sin(theta / 2), torch.cos(theta / 2)]]), requires_grad=True).to(device).to(torch.cfloat)

    return Ry_gate
</code></pre>
<p>all these give the same result. can someone please explain why I’m not getting the grad of press. Even though in the output it has grad_fn=</p>

username: ptrblck
cooked: <pre><code class="lang-python">params = torch.tensor(([[0.011], [0.012]]), requires_grad=True).to(device).to(torch.cfloat)
</code></pre>
<p>will create a non-leaf tensor, since you are calling <code>to()</code> on it, which is differentiable.<br>
Specify the <code>device</code> and <code>dtype</code> in the tensor constructor or create a new leaf tensor via <code>a = params.detach().requires_grad_()</code>.</p>
<p>I don’t know how you are checking the loss gradient, but by default it won’t be set since you are implicitly (as <code>1.</code>) or explicitly passing the gradient to the loss in the <code>backward()</code> call.</p>