Set gradients explicitly

username: unofficial-Jona
cooked: <p>I’m using a loss function that returns a tensor (separate loss for each element). I understand that I do have to set the loss.backwards(gradient=???) parameter. What I don’t understand is how to obtain said gradients. Following the answer to <a href="https://discuss.pytorch.org/t/implementing-diou-calculate-grad-explicitly/150261">a previous question</a> I set up the training step as follows. However, this leads to no useful training (which makes sense since gradients are always 1?)</p>
<p>For some context: this is the training step:</p>
<pre><code class="lang-auto">  def training_step(self, batch, batch_idx):
      x, y = batch
      y_hat = self.model(x) 
      loss = self.compute_loss(y_hat, y) # calls torchvision.ops.generalized_box_iou_loss()
      self.log("train_loss", torch.mean(loss))
      return loss.backward(gradient=torch.ones_like(loss))
</code></pre>
<p>Any ideas how to fix this?</p>

username: KFrank
cooked: <p>Hi Jona!</p>
<aside class="quote no-group" data-username="unofficial-Jona" data-post="1" data-topic="151159" data-full="true">
<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/unofficial-jona/48/48227_2.png" class="avatar"> unofficial-Jona:</div>
<blockquote>
<p>I’m using a loss function that returns a tensor (separate loss for each element).</p>
</blockquote>
</aside>
<p>Let me first ask the following question:</p>
<p>Normally we compute a loss function in order to train a network by<br>
minimizing the loss function.  (And we compute the gradient of the<br>
loss so that we can minimize the loss with some version of gradient<br>
descent.)</p>
<p>If your loss function results in a tensor, how do you propose to train<br>
your network?  Minimizing the loss for, say, element 1 will not, in<br>
general, also minimize the loss for element 2.</p>
<p>What we generally do is minimize some weighted combination of<br>
those per-element losses.  But that weighted combination just becomes<br>
our single scalar loss that we minimize by calling <code>loss.backward()</code>,<br>
etc.</p>
<aside class="quote no-group">
<blockquote>
<p>What I don’t understand is how to obtain said gradients.</p>
</blockquote>
</aside>
<p>If you actually need to compute the gradient for each separate per-element<br>
loss, then you need to run multiple backward passes in a loop.</p>
<p>You can use pytorch’s <a href="https://pytorch.org/docs/1.11/generated/torch.autograd.functional.jacobian.html" rel="noopener nofollow ugc">jacobian()</a> function to run this loop for you, or you<br>
can run it by hand.</p>
<p>Some comments about what is going on when you use<br>
<code>gradient = torch.ones_like (loss)</code>  can be found in this post:</p>
<aside class="quote quote-modified" data-post="3" data-topic="150950">
  <div class="title">
    <div class="quote-controls"></div>
    <img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/k/ecb155/48.png" class="avatar">
    <a href="https://discuss.pytorch.org/t/need-help-computing-gradient-of-the-output-with-respect-to-the-input/150950/3">Need help computing gradient of the output with respect to the input</a> <a class="badge-category__wrapper " href="/c/autograd/7"><span data-category-id="7" data-drop-close="true" class="badge-category " title="A category of posts relating to the autograd engine itself."><span class="badge-category__name">autograd</span></span></a>
  </div>
  <blockquote>
    Hi Malfonsoarquimea! 

No, by using grad_outputs = torch.ones_like (output) you end up 
computing the inner product (dot product) of the gradients of output with 
the torch.ones_like() vector.  This does not preserve the gradient of 
each output as a separate entity. 
At issue is the fact that, as currently implemented, autograd computes the 
gradient of a single scalar result (in any individual backward pass).  To get 
the gradients of the elements of output separately, you have to run multiple …
  </blockquote>
</aside>

<p>Best.</p>
<p>K. Frank</p>