# Derivative of model outputs w.r.t input features

**URL:** <https://discuss.pytorch.org/t/derivative-of-model-outputs-w-r-t-input-features/95814>\
**Category:** Uncategorized\
**Created:** [September 10, 2020, 4:14pm UTC](https://discuss.pytorch.org/t/derivative-of-model-outputs-w-r-t-input-features/95814 "2020-09-10T16:14:19Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![jarvico](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/jarvico/32/28509_2.png) [@jarvico](https://discuss.pytorch.org/u/jarvico)\
**Post date:** [September 10, 2020, 4:14pm UTC](https://discuss.pytorch.org/t/derivative-of-model-outputs-w-r-t-input-features/95814/1 "2020-09-10T16:14:19Z")

</div>

Hi all,

Assume that we have a pertained NN model like LeNet-5 which successfully predicts handwritten digits. In this case number of features is 784 (assuming 28x28 input images) and number of outputs is 10. Sum of the output values(probs) adds up to 1 and each output shows the probability of that class for the given input image.

Now, assuming that I already have this model. And I can predict the class of any input image using feedforward model prediction.

My question is: For any test input image, I would like to calculate derivative of any model output w.r.t model input features. This way I will be calculating a 784x10 Jacobian matrix J.

For example J[0,0] is the derivative of output 0 w.r.t input feature 0 and J[2,3] is derivative of output 3 w.r.t input feature 2 and so on…

Actually maybe I can calculate each element of this Jacobian via a messy code block but I wonder if there is any easy and elegant way of doing so.

Any comment on how to calculate the J matrix?

---

<div class="post-metadata">

**Author:** ![KFrank](https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/k/ecb155/32.png) [@KFrank](https://discuss.pytorch.org/u/KFrank)\
**Post date:** [September 10, 2020, 7:15pm UTC](https://discuss.pytorch.org/t/derivative-of-model-outputs-w-r-t-input-features/95814/2 "2020-09-10T19:15:53Z")

</div>

Hello Ömer!

> [@jarvico](#):
>
> My question is: For any test input image, I would like to calculate derivative of any model output w.r.t model input features. This way I will be calculating a 784x10 Jacobian matrix J.

Just as you use pytorch’s autograd to calculate the derivatives (gradient)  
of your loss function with respect to your model’s parameters (and then  
use those to update your model with gradient descent), you can use  
autograd to calculate the derivatives of a prediction for a single class  
with respect to the input to your model. This will be a single column of  
your Jacobian matrix.

You can then loop over predictions / columns to build the full Jacobian.

Models work on batches, even if you want to process a single image.  
So, for a single image, you need a batch with batch size of one.

Let’s say you have an `input` tensor, with shape `[1, 784]`. (It could be  
`[1, 28, 28]`, if that is what your model expects.) You say your model  
has ten classes, so you will have:

```python
preds = model (input)

```

where `preds` has shape `[nBatch, nClass] = [1, 10]`.

Tell pytorch to track gradients with respect to your `input`, apply your  
model to input, and call `.backward()` on your `preds[i]`, looping over  
`i`. The `.grad` property of of your `input` tensor will be the `i`th column  
of the Jacobian.

```python
J = torch.zeros ((1, 784, 10)) # loop will fill in Jacobian
input.requires_grad = True
preds = model (input)
for i in range (10):
    grd = torch.zeros ((1, 10)) # same shape as preds
    grd[0, i] = 1 # column of Jacobian to compute
    preds.backward (gradient = grd, retain_graph = True)
    J[:,:,i] = input.grad # fill in one column of Jacobian
    input.grad.zero_() # .backward() accumulates gradients, so reset to zero

```

You could also try pytorch’s **experimental** [jacobian()](https://pytorch.org/docs/stable/autograd.html#torch.autograd.functional.jacobian) function, which  
I _think_ basically wraps the loop I outlined above, but with more bells  
and whistles (but I’ve never used it).

Good luck.

K. Frank

---

<div class="post-metadata">

**Author:** ![jarvico](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/jarvico/32/28509_2.png) [@jarvico](https://discuss.pytorch.org/u/jarvico)\
**Post date:** [September 11, 2020, 9:42am UTC](https://discuss.pytorch.org/t/derivative-of-model-outputs-w-r-t-input-features/95814/3 "2020-09-11T09:42:16Z")

</div>

Hi Frank,

I just did a very minor change and it seems to work. Thanks for your help! Appreciated…

my\_input=test\_data[num][0].view(1,1,28,28)

J = torch.zeros((784, 10)) # loop will fill in Jacobian  
J = J.float()

my\_input.requires\_grad\_()

preds = model(my\_input)  
print("preds shape is: ",preds.shape)

for i in range (10):  
grd = torch.zeros ((1, 10)) # same shape as preds  
grd[0, i] = 1 # column of Jacobian to compute  
preds.backward(gradient = grd, retain\_graph = True)  
J[:,i] = my\_input.grad.view(784).float() # fill in one column of Jacobian  
my\_input.grad.zero\_() # .backward() accumulates gradients, so reset to zero

print(J.shape)  
print(J)

---

<div class="post-metadata">

**Author:** ![nicole\_tein](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/nicole_tein/32/27132_2.png) [@nicole\_tein](https://discuss.pytorch.org/u/nicole_tein)\
**Post date:** [November 6, 2021, 8:14am UTC](https://discuss.pytorch.org/t/derivative-of-model-outputs-w-r-t-input-features/95814/4 "2021-11-06T08:14:18Z")

</div>

Thanks! Really helpful.
