Limit backpropagation depth for multiple backward passes

Nerrror: <p>Hey,</p>
<p>so I’m working on a problem where I have multiple losses and I want to stop backpropagation of one of the losses before the end of the computational graph. In more detail:</p>
<p>I have a tensor x (y_0 in my second post) which has already been passed through a couple of pytroch functions, so the grad_fn attribute is not None. This Tensor x is then passed through a subnetwork y = f(x; theta). y is then used in a direct loss L(y) and also passed on to another subnetwork. Now, I want that the direct loss will only affect the parameters theta in f and should not affect any parameters prior to f, ie. backpropagation should be stopped at x for the direct loss L. However, the loss from the second subnetwork should backpropagate the entire computational graph, therefore detaching x is not possible.</p>
<p>I could, ofc, clone x, detach the clone and make a second pass through f but I would like to avoid that for efficiency reasons. Is there a smarter way to do this?</p>
<p>Thank you for your help!</p>

ptrblck: <p>I’m not sure if I fully understand the network structure but would explicitly computing gradients for the subnetwork via e.g. <code>torch.autograd.grad</code> or by providing <code>inputs</code> to <code>backward</code> work?</p>

Nerrror: <p>Hey ptrblck,</p>
<p>thanks for your fast response!<br>
Here is an image of the network layout:<br>
<div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/8/0/80f66ac9491d6e9e072f7d6817737404582eefb8.jpeg" data-download-href="https://discuss.pytorch.org/uploads/default/80f66ac9491d6e9e072f7d6817737404582eefb8" title="WhatsApp Bild 2023-10-09 um 16.30.54_17b2be2b"><img src="https://discuss.pytorch.org/uploads/default/optimized/3X/8/0/80f66ac9491d6e9e072f7d6817737404582eefb8_2_690x388.jpeg" alt="WhatsApp Bild 2023-10-09 um 16.30.54_17b2be2b" data-base62-sha1="ioR3SdzWIcZf4sIjleBF79VXnqU" width="690" height="388" srcset="https://discuss.pytorch.org/uploads/default/optimized/3X/8/0/80f66ac9491d6e9e072f7d6817737404582eefb8_2_690x388.jpeg, https://discuss.pytorch.org/uploads/default/optimized/3X/8/0/80f66ac9491d6e9e072f7d6817737404582eefb8_2_1035x582.jpeg 1.5x, https://discuss.pytorch.org/uploads/default/optimized/3X/8/0/80f66ac9491d6e9e072f7d6817737404582eefb8_2_1380x776.jpeg 2x" data-dominant-color="818180"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">WhatsApp Bild 2023-10-09 um 16.30.54_17b2be2b</span><span class="informations">1920×1080 141 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div></p>
<p>f_0, f_1 and f_2 are all NNs with parameters phi, theta and psi. the second network f_1 has an additional loss L_1 but the gradients should only affect network f_1. Thus, the gradients of L_1 wrt. to f_0 should be 0. If I would just call backward naively on L_1, I would get non-zero contribution to the total gradients of phi. This is what I want to avoid.</p>
<p>If I understand <code>torch.autograd.grad</code> correctly, it would do the same as cloning and detaching y_0 and then using the cloned y_0 for the loss L_1, is that correct?</p>

soulitzer: <blockquote>
<p>If I understand <code>torch.autograd.grad</code> correctly, it would do the same as cloning and detaching y_0 and then using the cloned y_0 for the loss L_1, is that correct?</p>
</blockquote>
<p>yes, but the difference is that now the .grad fields won’t be populated. Instead .grad() returns the gradients.</p>
<p>you can also pass inputs= to .backward(), it does the same thing except it also populates the .grad fields. (as ptrblck mentions)</p>