Call backward () twice

slavavs: <p>I have a network that has two independent neurons at the output.<br>
Each neuron has a function to activate tan.<br>
I consider a mistake for the first neuron and for the second.<br>
If I call backward () twice, I get an error.<br>
How do i do right?<br>
As the Loss function, I use L1Loss.</p>

slavavs: <p>I also can not figure out how to choose the right Loss function.<br>
I have two neurons. They work independently and give values ​​from -1 to 1.<br>
For example, one neuron gives 0.3, and the network gives the correct answer is -0.4. Network error is 0.7. I have to reduce the gradient. But if I call the L1Loss function, then I will get 0.3 - (- 0.4) = 0.7. In this case, my gradients will be increased. How do I specify a network to reduce the gradient?<br>
Although maybe I’m wrong, the network will do everything right …<br>
The first question remains, how do I calculate the gradients for two neurons( loss1.backward(), loss2.backward() )</p>

smth: <p>you can do for example <code>(loss1 + loss2).backward()</code> or use <code>torch.autograd.grad</code> function</p>

KylinA1: <p>every time after <code>loss.backward()</code> is called, the previous computational graph is released.<br>
Thus if you want use the graph again, just add <code>loss1.backward(retain_graph = True)</code> to prevent the graph to be released.<br>
And remember to reset <code>optimizer.zero_grad</code> , before you call <code>optimizer.step()</code>.<br>
<code>loss.backward()</code> will compute the gradient<br>
and  <code>optimizer.step()</code> will apply the gradient and update the tensor.<br>
Since you have  two loss, you might need to be more careful about when to reset the grad and update</p>

god_sp33d: <p>In the example you stated, after applying you get the error 0.7. And when you do a backward pass the network computes the gradients such that your error is reduced. I am not sure how you stated <em>the gradients will increase</em> in your example.</p>
<p>Also like smth said you don’t need to do backward twice, you can basically add those losses and directly compute backward on the total loss.</p>

slavavs: <p>Assume the network issued on the first neuron 0.7, the correct answer is 0.2 error is 0.5. The second neuron produced 0.1, the correct answer is 0.5, the error is -0.4.<br>
If you do (loss1 + loss2) .backward () -&gt; (0.5 - 0.4 = 0.1) .backward (), how does the network know that for the first neuron you need to decrease by 0.5, and for the second to increase by 0.4?</p>

slavavs: <p>At the moment I did like this</p>
<blockquote>
<p>optimizer.zero_grad()<br>
loss1.backward(retain_graph=True)<br>
loss2.backward()<br>
optimizer.step()</p>
</blockquote>
<p>Maybe that’s how it will be right?</p>
<blockquote>
<p>optimizer.zero_grad()<br>
loss1.backward(retain_graph=True)<br>
optimizer.step()<br>
optimizer.zero_grad()<br>
loss2.backward()<br>
optimizer.step()</p>
</blockquote>

god_sp33d: <p>you sum the absolute values of the errors. so your total loss would be 0.5 + 0.4. so, to decrease the total loss it needs to decrease individual losses, thus the gradients are updated such that both the losses decrease simultaneously.</p>
<p>If above is the scenario of your problem, then you can add absolute value of the losses and do backward at once.</p>

slavavs: <p>The weights for the first neuron need to be reduced by 0.5, and the weights for the second one increased by 0.4. If the errors are 0.5 and 0.4, does backward () do the right thing?</p>

god_sp33d: <p>yes. The error would be zero only if the first decreases and the second increases. And the models goal always would be to achieve zero loss.</p>

slavavs: <p>I think you do not understand me correctly.<br>
If the output was one neuron and the error was 0.5, then backward () would do everything correctly.<br>
But I need backward () to change each neuron correctly, first reduce the weight for the first neuron, while the second neuron will not change. Then he changed the weight for the second neuron. Is it possible?</p>

slavavs: <p>I can not understand, is the error 0.4 and -0.4 the same?<br>
Indeed, in the first case, the gradient needs to be reduced, and in the second one, should it be increased?<br>
But if I do</p>
<blockquote>
<p>abs (Loss)</p>
</blockquote>
<p>then the network will not correctly change the gradient …</p>

pinocchio: <p>what does it mean for “the previous computational graph to be released” mean?</p>

xuanyaoming: <p>I just encountered the exactly same problem. <br><br>
In my case, my two networks can both be trained independently with different loss functions. But putting them together by calling <strong>loss1.backward()</strong> and <strong>loss2.backward()</strong> consecutively will result in “inplace operation” errors. And the info provided by pytorch isn’t helpful at all.<br><br>
I fixed the error by making sure the input tensors of the two networks are <em><strong>completely detached</strong></em>. Based on my knowledge, the input tensors will be included in the computation graph by default, and <strong>loss.backward()</strong> function will remove <em><strong>all tensors</strong></em> that are related to the loss from the graph.  That means, if an input tensor is used by both the networks, it will not be <em><strong>visible</strong></em> to <em><strong>loss2’s computation graph</strong></em> after pytorch runs <strong>loss1.backward()</strong>, which may be identified as an “inplace operation” by the debugging tools.<br><br>
To detach the tensor, simply organize your code like:</p>
<pre><code class="lang-auto">x.clone().detach()
loss1 = loss_func(y1, net1(x))
loss2 = loss_func(y2, net2(x))
opti1.zero_grad()
opti2.zero_grad()
loss1.backward()
loss2.backward()
opti1.step()
opti2.step()
</code></pre>
<p>I’m using torch version 1.13. Please let me know if the solution is not useful.</p>