X_fooling.grad prints float32 values but when used shows NoneType

akt_09: <p>X_fooling = X.clone()<br>
X_fooling = X_fooling.requires_grad_()</p>
<p>learning_rate = 1</p>
<p>l=model(X_fooling).squeeze()[target_y].sum()<br>
l.backward()</p>
<p>g=X_fooling.grad<br>
<span class="hashtag">#print</span>(g.dtype)</p>
<p>dX=learning_rate*X_fooling.grad/X_fooling.grad.norm()<br>
X_fooling=X_fooling+dX</p>
<p><span class="hashtag">#unsupported</span> operand type(s) for *: ‘int’ and ‘NoneType’</p>
<h1>here X_fooling.grad is NoneType. Why?</h1>
<h1>How to solve this?</h1>

albanD: <p>Hi,</p>
<p>I don’t think it is None here.<br>
What is the full stack trace you see?<br>
Also can you split all the computations in the line that fails to different lines so that the stack trace can point to the explicit op that failed.</p>

akt_09: <p>It shows that NoneType can not have dtype, if you run the print line.</p>

albanD: <p>Ok, so it is <code>None</code> from the beginning, it does not actually tell you that it is float32?</p>

akt_09: <p>The problem is X_fooling.grad if printed shows float32 values, but when used it shows as Nonetype and can not do anything with it. Not even .dtype. Shows X_fooling.grad is nonetype and can not do .dtype or any operations with it.</p>

akt_09: <pre><code class="lang-auto">import torch
from torch.autograd import Variable
import torchvision.models

model=torchvision.models.squeezenet1_1(pretrained=True)

x=torch.randn(1,3,100,100)
target_y=6

x_fooling=x.clone()
x_fooling=x_fooling.requires_grad_()

while(torch.argmax(model(x_fooling).squeeze())!=target_y):
    
    l=model(x_fooling)[0][target_y]
    l.backward()

    dx=1*x_fooling.grad/x_fooling.grad.norm()
    
    x_fooling=x_fooling+dx
</code></pre>
<p>How x_fooling.grad is NoneType here? It is not even leaf node, why?</p>

user_123454321: <p>Can you replace the loop by the following and check</p>
<pre><code class="lang-auto">while True:
    x_fooling=x_fooling.requires_grad_()
    l=model(x_fooling)[0][target_y]
    l.backward()
    dx=1*x_fooling.grad/x_fooling.grad.norm()
    with torch.no_grad():
       x_fooling=x_fooling+dx 
       pred = torch.argmax(model(x_fooling).detach().squeeze())
       if pred == target_y: break
</code></pre>

albanD: <p>Hi,</p>
<p>At the first iteration, it works fine.<br>
The problem is that at the end of it, you do <code>    x_fooling=x_fooling+dx</code> which replaces you <code>x_fooling</code> leaf by a Tensor that is not a leaf anymore (it is the result of a differentiable op).</p>
<p>And so as suggested above, you need to make sure that this update is done in a non-differentiable way to make sure <code>x_fooling</code> remains a leaf. You can do so with</p>
<pre><code class="lang-python">with torch.no_grad():
    x_fooling = x_fooling + dx
</code></pre>

akt_09: <p>It works. But where was the problem in my code. Can you please explain a little. I think it is because of detach() . Another thing is it does not work if the prediction check is done as part of while condition. Why is that? Thank you.</p>

user_123454321: <p><a class="mention" href="/u/alband">@albanD</a> has explained it well.</p>

akt_09: <pre><code class="lang-auto">import torch
from torch.autograd import Variable
import torchvision.models

model=torchvision.models.squeezenet1_1(pretrained=True)

x=torch.randn(1,3,100,100)
target_y=6

x_fooling=x
x_fooling=x_fooling.requires_grad_()

while(True):
    
    with torch.no_grad():
        if (torch.argmax(model(x_fooling).squeeze())==target_y):
            break
    
    l=model(x_fooling)[0][target_y]
    l.backward()
    print(i)
    dx=1*x_fooling.grad/x_fooling.grad.norm()
    
    with torch.no_grad():
        x_fooling=x_fooling+dx
    
</code></pre>
<p>This does not work either, what is the issue, here? torch.no_grad is used and the leaf of X_fooling should have remained the same.</p>
<p>This works if</p>
<pre><code class="lang-auto">X_fooling=X_fooling.requires_grad_()
</code></pre>
<p>is added before<br>
<code>While (True)</code></p>
<p>Why is that?</p>

albanD: <p>This is because <code>X_fooling</code> needs to require gradient for you to be able to compute gradients for it.</p>

akt_09: <p>So, the graph is recreated every iteration and if we want to accumulate all the gradients over some number of iterations, we should use another variable to do so. Thank you.</p>