Tensor version mis-match when calling .backward()

Muhammad_Athar_Ganai: <p>I am trying to implement a method which has three sub networks. An encoder, discriminator and a regressor.<br>
The outputs of the encoder are inputs to both the discriminator as well as the regressor.<br>
We also define 3 optimizers. They are as follows.</p>
<pre><code class="lang-auto">optimizer = optim.Adam(list(encoder.parameters()) + list(regressor.parameters()), lr=1e-4)
optimizer_conf = optim.Adam(list(encoder.parameters()), lr=1e-4)
optimizer_dm = optim.Adam(list(domain_predictor.parameters()), lr=1e-4)
</code></pre>
<p>Here’s my code.</p>
<pre><code class="lang-auto"># First update the encoder and regressor
                optimizer.zero_grad()
                features = encoder(data)
                output_pred = regressor(features)
                loss_total = criteron(output_pred, target)
                loss_total.backward(retain_graph=True)
                optimizer.step()

                # Now update just the domain_predictor
                optimizer_dm.zero_grad()
                output_dm = domain_predictor(features.detach())
                loss_dm = domain_criterion(output_dm, domain_target)
                loss_dm.backward(retain_graph=False)
                optimizer_dm.step()

                # Now update just the encoder using the domain loss
                optimizer_conf.zero_grad()
                output_dm_conf = domain_predictor(features)
                loss_conf = beta * conf_criterion(output_dm_conf, domain_target)
                loss_conf.backward(retain_graph=False)
                optimizer_conf.step()
</code></pre>
<p>This is the error I am getting, I have also put anomaly detection:</p>
<pre><code class="lang-auto">***one of the variables needed for gradient computation has been modified by 
an inplace operation: [torch.cuda.FloatTensor [1]] is at version 2; expected version 1 instead. 
Hint: the backtrace further above shows the operation that failed to compute its gradient. 
The variable in question was changed in there or anywhere later. Good luck!***
  File "/home/new_user/DA/Brain-MR-Segmentation-Playground/methods/unlearn.py", line 303, in train_unlearn
    loss_conf.backward(retain_graph=False)
  File "/home/new_user/DA/Brain-MR-Segmentation-Playground/methods/unlearn.py", line 524, in cmd_train
    loss, acc, dm_loss, conf_loss = train_unlearn(ctx, models, train_dataloaders, optimizers, criterions,
  File "/home/new_user/DA/Brain-MR-Segmentation-Playground/methods/runner.py", line 31, in run_main
    selected_method.cmd_train(ctx)
  File "/home/new_user/DA/Brain-MR-Segmentation-Playground/methods/runner.py", line 35, in &lt;module&gt;
    run_main()
</code></pre>
<p>Kindly help!!!</p>

ptrblck: <p>I guess the error is raised since you are using stale forward activations in the <code>encoder</code> during the <code>loss_conf.backward()</code> call.<br>
I.e:</p>
<ul>
<li>
<code>features = encoder(data)</code> will store the intermediate activations (<code>a0</code>)</li>
<li>
<code>loss_total_backward(retain_graph=True)</code> will use these intermediate activations (<code>a0</code>) and <code>optimizer.step()</code> will update the original parameters of <code>eencoder</code> (<code>p0</code>) to a new set (<code>p1</code>)</li>
<li>
<code>output_dm_conf = domain_predictor(features)</code> is not detaching the <code>features</code> tensor so it’s still attached to <code>encoder</code>
</li>
<li>
<code>loss_conf.backward()</code> will try to calculate the gradients for <code>domain_predictor</code> (this should work) as well as for <code>encoder</code> using the stored forwad activations (<code>a0</code>)</li>
<li>since <code>optimizer.step()</code> was performed these <code>a0</code> activations do not match the updated parameters <code>p1</code> which will raise the error as it’s mathematically wrong.</li>
</ul>

Muhammad_Athar_Ganai: <aside class="quote no-group" data-username="Muhammad_Athar_Ganai" data-post="1" data-topic="154930">
<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/muhammad_athar_ganai/48/45534_2.png" class="avatar"> Muhammad_Athar_Ganai:</div>
<blockquote>
<p><code>features.detach())</code></p>
</blockquote>
</aside>
<p>Thankyou for the reply,<br>
I am not sure I entirely understood the reason for the problem or how to solve it.</p>
<p>You mentioned that the features aren’t being detached, however in the second block we have</p>
<pre><code class="lang-auto">optimizer_dm.zero_grad()
output_dm = domain_predictor(features.detach())
loss_dm = domain_criterion(output_dm, domain_target)
loss_dm.backward(retain_graph=False)
optimizer_dm.step()
</code></pre>
<p>we are using <code>features.detach()</code>.<br>
What should we do to get the implementation right???</p>

ptrblck: <p>I don’t think the second block creates the issue (you could run your code and check where it’s failing exactly) and in the third block you are not detaching the <code>features</code> tensor:</p>
<pre><code class="lang-python">output_dm_conf = domain_predictor(features)
</code></pre>
<p>To solve the issue either <code>detach</code> the input (if it fits your use case) or check my previous post and try to explain how your use case should work in this case using stale forward activations.</p>