Derivative with respect to the input

username: smu226
cooked: <p>Hello! I want to calculate the derivatives (actually Jacobian) of a NN with respect to its input. Usually I do something like this:</p>
<p><code>torch.autograd.grad(y, x, create_graph=True)[0]</code></p>
<p>But in this case x doesn’t have the “require grad” property (it is the input to the network so it should be fixed). How can I calculate the derivative in this case? Thank you!</p>

username: InnovArul
cooked: <p>you could set the <code>requires_grad</code> property of <code>x</code> to get the gradient w.r.t <code>x</code>?</p>
<p><code>x.requires_grad = True</code></p>

username: smu226
cooked: <p>But if I do this, won’t the x itself be change when I backpropagate through the NN?</p>

username: InnovArul
cooked: <p><code>torch.augograd.grad()</code> just returns the gradient. It doesn’t modify the variables/store grad in <code>.grad</code>, as far as I know. You need to set <code>x.requires_grad</code> to indicate the <code>autograd.grad()</code> function that <code>x</code> is a leaf variable.</p>

username: smu226
cooked: <p>Yes but I want to add this derivative I am calculating (using autograd.grad()) to the final loss function. Won’t x be modified when I call loss.backward(), because x has the requires_grad parameter associated to it?</p>

username: InnovArul
cooked: <p>I am not sure if I follow correctly. I think, adding this grad to loss function will not have any effect. Don’t you think so?</p>

username: smu226
cooked: <p>So what I need is to calculate the derivative the the NN with respect to the input, something like: <code>dx = torch.augograd.grad(NN(x),x)</code> and then add this derivative to the loss and backpropagate. For example <code>loss = (NN(x)-x)**2+abs(dx)</code> and then <code>loss.backward()</code>. Won’t the value of x itself be changed if I have <code>x.requires_grad</code>? For example if x represent the pixels of an image, won’t the value of the pixels themselves be affected i.e. the image will change?</p>

username: InnovArul
cooked: <p>Gradient is calculated when there is a computation graph. For example,</p>
<p><code>x --&gt; linear(w, x) --&gt; softmax()</code>.  Here, <code>x, w</code> could be potentially leaf nodes that require gradient.</p>
<p>In this same paradigm, when you add <code>dx</code> to loss function, it is just like you are adding a constant to the loss function. The weights of the NN doesn’t depend on the gradient and this <code>dx</code> doesn’t have any computation graph associated with it. So, I am not sure if <code>x</code> will be affected by this loss function at all.</p>

username: Yao_Xuan
cooked: <p>Hi, I have exactly the same question. Did you figure out whether adding input x with require “grad True” will influence the backward propagation? Thank you very much.</p>

username: ptrblck
cooked: <p>If your input requires gradient, its <code>.grad</code> attribute will be populated after the backward pass, but besides that it won’t change the gradient calculation.</p>

username: Yao_Xuan
cooked: <p>Thank you very much. It is very helpful.</p>

username: chetan06
cooked: <aside class="quote no-group" data-username="smu226" data-post="7" data-topic="49254">
<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/smu226/48/9063_2.png" class="avatar"> smu226:</div>
<blockquote>
<p>: <code>dx = torch.augograd.grad(NN(x),x)</code></p>
</blockquote>
</aside>
<p>Can this be used for pretrained model present in torchvision.models</p>

username: Ilya_Kamenshchikov
cooked: <p>It seems that you can’t get the gradient through derivative as of pytorch 1.5:</p>
<pre><code class="lang-auto">import torch

x = torch.Tensor([1, 2, 3])
x.requires_grad_(True)
c = x ** 2
print(c.grad_fn)  # c has gradient function
dc_dx = torch.autograd.grad(c.mean(), x)[0]
print(dc_dx)
print(dc_dx.grad_fn)  # derivative of c over x doesn't have gradient function
dc_dx.backward()  # raises RuntimeError
</code></pre>

username: penghao_wu
cooked: <p>You may try this</p>
<pre><code class="lang-auto">dc_dx = torch.autograd.grad(c.mean(), x, create_graph=True, retain_graph=True)[0]
</code></pre>
<p>But you have to call the backward on a scalar like torch.norm(dc_dx).</p>