Opacus framework for Multilabel multiclass classification problem

sabeekakhan7: <p>Hello,</p>
<p>I am stuck with something I was hoping to get some help with. I am trying to train a differentially private multilabel multiclass model on the NIH Chest X-Ray dataset using the Opacus framework. I have tried different settings for the hyperparameters, i.e., <em><strong>max_grad_norm</strong></em> and <strong><em><strong>noise_multiplier</strong></em>,</strong> but my model consistently suffers from a considerable accuracy loss irrespective of the hyperparameter settings. As a sanity test, I set the <em><strong>noise_multiplier</strong></em> to 0 and <em><strong>max_grad_norm</strong></em> to high values within the range of 10 to 1000000. With these settings, the model should ideally behave like a regular non-differentially private model, but that’s not the case. The AUROC  score I get with these settings is ~0.5, whereas when I train the model without the privacy_engine() wrapper, like a regular CNN model, the AUROC score is ~0.8.</p>
<p>I am confused as to  why there’s a huge accuracy drop when I set the settings of the differentially private model in a way that the model is not really differentially private ( e.g. noise_multiplier = 0, max_grad_norm = 1000).</p>
<p>I’d greatly appreciate it if anyone who has worked on this could help me with it.</p>
<p>P.S. Here’s the link of the baseline code I am using. To create an instance of a differentially private model, I simply call  the privacy_engine()  wrapper, keeping everything else as it is.</p>
<aside class="onebox githubblob" data-onebox-src="https://github.com/zoogzog/chexnet/blob/master/ChexnetTrainer.py">
  <header class="source">

      <a href="https://github.com/zoogzog/chexnet/blob/master/ChexnetTrainer.py" target="_blank" rel="noopener nofollow ugc">github.com</a>
  </header>

  <article class="onebox-body">
    <h4><a href="https://github.com/zoogzog/chexnet/blob/master/ChexnetTrainer.py" target="_blank" rel="noopener nofollow ugc">zoogzog/chexnet/blob/master/ChexnetTrainer.py</a></h4>


      <pre><code class="lang-py">import os
import numpy as np
import time
import sys

import torch
import torch.nn as nn
import torch.backends.cudnn as cudnn
import torchvision
import torchvision.transforms as transforms
import torch.optim as optim
import torch.nn.functional as tfunc
from torch.utils.data import DataLoader
from torch.optim.lr_scheduler import ReduceLROnPlateau
import torch.nn.functional as func

from sklearn.metrics.ranking import roc_auc_score

from DensenetModels import DenseNet121
from DensenetModels import DenseNet169
</code></pre>



  This file has been truncated. <a href="https://github.com/zoogzog/chexnet/blob/master/ChexnetTrainer.py" target="_blank" rel="noopener nofollow ugc">show original</a>

  </article>

  <div class="onebox-metadata">
    
    
  </div>

  <div style="clear: both"></div>
</aside>


ffuuugor: <p>Hey</p>
<p>I can see that <code>DenseNet*</code> models use <code>BatchNorm2d</code> layers - which means opacus won’t be able to work with them directly.<br>
Presumably, you’re calling <code>ModuleValidator.fix(densenet121)</code> before passing the module to the PrivacyEngine. What this does is it replaces <code>BatchNorm</code> with <code>GroupNorm</code> layers, which might by itself affect the performance - you can in fact check if that’s the case to confirm.<br>
There’s not much one can do here - <code>BatchNorm</code> is not compatible with DP-SGD (see <a href="https://github.com/pytorch/opacus/blob/main/tutorials/intro_to_advanced_features.ipynb" rel="noopener nofollow ugc">here</a> for explanation). One thing you can try is using <code>InstanceNorm</code> as a replacement:</p>
<pre><code class="lang-auto">m = ModuleValidator.fix(densenet121, replace_bn_with_in=True)
</code></pre>