Manual weight updates: autograd returns none, why?

qm-intel: <p>I am new to pytorch and it may sound a simple question, sorry for that.<br>
I have written a function that updates the parameters of a network manually:</p>
<pre><code class="lang-auto">    def update_params(self, loss, update_lr):
        # parameter update
        updated_params = OrderedDict()
        for name, param in self.graph_model.gnn.named_parameters():
            if param.requires_grad:
                grad = torch.autograd.grad(loss, param, create_graph=True,  allow_unused=True)
                if grad is None:
                    updated_params = param
                else:
                    pdb.set_trace()
                    updated_params = param - update_lr * grad
            updated_params[name] = updated_params
        return updated_params
</code></pre>
<p>the loss is as follows:</p>
<pre><code class="lang-auto">loss
tensor([0.0693], device='cuda:0', grad_fn=&lt;AddBackward0&gt;)
</code></pre>
<p>and the first param of loop is :</p>
<pre><code class="lang-auto">(Pdb) param
Parameter containing:
tensor([[-0.2142, -0.1182, -0.2988,  ...,  0.2933, -0.0804, -0.3286],
        [-0.1250,  0.2673,  0.1617,  ...,  0.2363,  0.2026, -0.2973],
        [ 0.0588,  0.2348, -0.2333,  ...,  0.1882,  0.0286, -0.3238],
        ...,
        [-0.1961,  0.1434,  0.0306,  ...,  0.3135,  0.2239, -0.0953],
        [ 0.1190,  0.2062, -0.2643,  ...,  0.3116,  0.1146, -0.1994],
        [ 0.0340, -0.2294,  0.2095,  ..., -0.2376,  0.0456,  0.3151]],
       device='cuda:0', requires_grad=True)
</code></pre>
<p>the grad is none for the first param (first iteration in the loop)</p>
<pre><code class="lang-auto">(pdb) grad
(None,)
</code></pre>
<p>however, when I check</p>
<pre><code class="lang-auto">(Pdb) grad is None
False
</code></pre>
<p>it returns False (means goes to the <code>else</code>). I am not sure where I am doing the mistake?</p>

soulitzer: <p>torch.autograd.grad returns Tuple[None] which is not the same as None!</p>

qm-intel: <p><a class="mention" href="/u/soulitzer">@soulitzer</a> Sorry I should have asked my question more clearly,<br>
the first question was, why autograd.grad returns None?</p>
<p>the second question that you answered relates to the tuple you mentioned.</p>
<p>So the question is why it returns None? what are the reasons? and how can I resolve this?</p>

soulitzer: <p>Usually autograd would’ve raised an error here, saying that some of the inputs that you are trying to find gradients with respect to aren’t part of the graph that autograd built, but since you explicitly passed allow_unused=True, it would just return None for that input instead.</p>
<aside class="quote no-group" data-username="qm-intel" data-post="1" data-topic="175044">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/qm-intel/48/57996_2.png" class="avatar"> qm-intel:</div>
<blockquote>
<p><code>allow_unused=True</code></p>
</blockquote>
</aside>
<p>This can mean several things: (1) you did not use that input in your computation at all (2) you did use that input in the computation, but the gradient wrt that input is zero. The issue here is that autograd doesn’t actually distinguish between gradient values of zero and gradient of None (3) you are using non-differentiable operations. There are certain operations that can break the autograd graph,  such as constructing a new-tensor, converting to and from numpy (perhaps to use other scientific libraries)</p>

qm-intel: <p><a class="mention" href="/u/soulitzer">@soulitzer</a> Thanks fo the explanation</p>