Adversarial network feature decorrelation: passing loss gradient

damar: <p>Hi all! I’m trying to construct an ANN to decorrelate a classifier from a given feature. I think the best way to show is with a little sketch (I hope it renders):<br>
<div class="lightbox-wrapper"><a class="lightbox" href="https://discuss.pytorch.org/uploads/default/original/3X/b/a/ba826971cccbf430703078a50e39bf4b07f94700.png" data-download-href="https://discuss.pytorch.org/uploads/default/ba826971cccbf430703078a50e39bf4b07f94700" title="Screenshot from 2022-05-11 12-41-21"><img src="https://discuss.pytorch.org/uploads/default/optimized/3X/b/a/ba826971cccbf430703078a50e39bf4b07f94700_2_690x191.png" alt="Screenshot from 2022-05-11 12-41-21" data-base62-sha1="qBWdn8ab43MeFWd7Ztnstw1cCac" width="690" height="191" srcset="https://discuss.pytorch.org/uploads/default/optimized/3X/b/a/ba826971cccbf430703078a50e39bf4b07f94700_2_690x191.png, https://discuss.pytorch.org/uploads/default/original/3X/b/a/ba826971cccbf430703078a50e39bf4b07f94700.png 1.5x, https://discuss.pytorch.org/uploads/default/original/3X/b/a/ba826971cccbf430703078a50e39bf4b07f94700.png 2x" data-dominant-color="ECEEF1"><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">Screenshot from 2022-05-11 12-41-21</span><span class="informations">996×277 45.2 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><br>
(the constant can be modified to balance classifying and feature decorellation)</p>
<p>The problem I have is how I pass the ANN loss to the classifier so it can calculate the gradient with respect to the classifier outputs, without modifying the ANN itself. What I have now (clearly still wrong) is something like this:</p>
<pre><code class="lang-auto">        #run number of batches
        for i, data in enumerate(trainloader, 0):
            #regtargets are the x feature values that the regressor tries to find
            inputs, targets, regtargets = data
            inputs, targets, regtargets = inputs.float(), targets.float(), regtargets.float()
            targets = targets.reshape((targets.shape[0], 2))
            #reset optimizers
            optimizer_reg.zero_grad()
            optimizer.zero_grad()

            #get classifier predictions
            outputs = mlp(inputs)
            
            #outputs are fed to ANN (detach, Error:args don't support auto diff, but one requires grad)
            ANN_in = outputs.detach()
            ANN_in.requires_grad = False
            #optimise ANN to new outputs
            ANN = TrainANN_hot(ANN, ANN_in, regtargets)
            ANNoutputs = ANN(ANN_in)
            loss_ANN = loss_function2(ANNoutputs, regtargets)
            loss_ANN.backward()
            optimizer_reg.step()
            optimizer_reg.zero_grad()
            #get new loss after optimization
            ANN_in.requires_grad = True
            ANNoutputs = ANN(ANN_in)
            loss_ANN = loss_function2(ANNoutputs, regtargets)
            
            #loss is calculated and complete model is retrained
            loss = loss_function(outputs, targets) - lda* loss_ANN
            loss.backward()
</code></pre>
<p>I’m new to pytorch so I hoped to get some insight on how to best implement gradient reversal.</p>

damar: <p>I eventually found a much more elegant solution here: <a href="https://discuss.pytorch.org/t/solved-reverse-gradients-in-backward-pass/3589" class="inline-onebox">[Solved] Reverse gradients in backward pass</a></p>