Repository: privacytrustlab/ml_privacy_meter (language: python)

Issue:
Fix issue, modify visualization
Fix issue, modify visualization

Closes: privacytrustlab/ml_privacy_meter#1


Discussion / hints:

Fix patch:
diff --git a/.gitignore b/.gitignore
index 9bc8928..c8c77c4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,7 +11,7 @@ archive/venv/
 archive/*.egg-info/
 archive/.vscode/
 archive/datasets/*.txt*
-archive/tutorials/datasets/*.txt*
+archive/advanced/datasets/*.txt*
 archive/logs/
 archive/.DS_Store
 
@@ -21,4 +21,16 @@ log*/
 *.npy
 events.out*
 *.json
-*.csv
\ No newline at end of file
+*.csv
+*/*.pickle
+*/*/*.pickle
+data/*/*
+advanced/data_batch*
+data/*
+*/*/model*.pkl
+*/*/data_batch*
+*/data/*
+
+*.pkl
+*.log
+*.png
\ No newline at end of file
diff --git a/CITATION.bib b/CITATION.bib
index 1877ed4..49470cf 100644
--- a/CITATION.bib
+++ b/CITATION.bib
@@ -1,3 +1,10 @@
+@misc{privacymeter2023,
+  author = {Chang, Hongyan and Maddi, Aadyaa and Masiak, Victor and Khandekar, Mihir and Ye, Jiayuan and Shokri, Reza},
+  title = {Privacy Meter},
+  year = {2023},
+  howpublished = "\url{https://github.com/privacytrustlab/ml_privacy_meter}",
+}
+
 @inproceedings{ye2022enhanced,
   title={Enhanced Membership Inference Attacks against Machine Learning Models},
   author={Ye, Jiayuan and Maddi, Aadyaa and Murakonda, Sasi Kumar and Bindschaedler, Vincent and Shokri, Reza},
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index aa41e5b..ab0bca5 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,7 +1,7 @@
 # Contributing to Privacy Meter
 
 We are happy to accepet any contributions to this project. Implementing new attack signals, improving documentation, fixing issues, providing feedback, or writing tutorials are all examples of valuable contributions.
-Suppose you publish a new membership inference attack or evaluate the defense's effectiveness. In such a case, we encourage you to add it to the privacy meter so that others can evaluate it fairly for their own projects.
+Suppose you publish a new membership inference attack or evaluate the defense's effectiveness. In such a case, we encourage you to add it to the Privacy Meter so that others can evaluate it fairly for their own projects.
 
 ## Pipeline for contributing
 
diff --git a/README.md b/README.md
index 49958ab..e2884eb 100644
--- a/README.md
+++ b/README.md
@@ -12,27 +12,25 @@
 ![Stargazers](https://img.shields.io/github/stars/privacytrustlab/ml_privacy_meter?style=social)
 ![License](https://img.shields.io/github/license/privacytrustlab/ml_privacy_meter)
 
-## What is privacy meter?
+## What is Privacy Meter?
 
-Privacy Meter is an open-source library to audit data privacy in statistical and machine learning algorithms. The tool can help in data protection impact assessment process by providing a quantitative analysis of fundamental privacy risks of a (machine learning) model. It uses state-of-the-art inference techniques to audit a wide range of machine learning algorithms for classification, regression, computer vision, and natural language processing. Privacy Meter generates extensive reports about the aggregate and individual privacy risks for data records in the training set, at multiple levels of access to the model.
+Privacy Meter is an open-source library to audit data privacy in statistical and machine learning algorithms. The tool can help in the data protection impact assessment process by providing a quantitative analysis of the fundamental privacy risks of a (machine learning) model. It uses state-of-the-art inference techniques to audit a wide range of machine learning algorithms for classification, regression, computer vision, and natural language processing. Privacy Meter generates extensive reports about the aggregate and individual privacy risks for data records in the training set, at multiple levels of access to the model.
 
 ## Why Privacy Meter?
 
-Machine learning is playing a central role in automated decision-making in a wide range of organization and service providers. The data, which is used to train the models, typically contain sensitive information about individuals. Although the data in most cases cannot be released, due to privacy concerns, the models are usually made public or deployed as a service for inference on new test data. For a safe and secure use of machine learning models, it is important to have a quantitative assessment of the privacy risks of these models, and to make sure that they do not reveal sensitive information about their training data. This is of a great importance as there has been a surge in use of machine learning in sensitive domains such as medical and finance applications.
+Machine learning is playing a central role in automated decision-making in a wide range of organizations and service providers. The data, which is used to train the models, typically contain sensitive information about individuals. Although the data in most cases cannot be released, due to privacy concerns, the models are usually made public or deployed as a service for inference on new test data. For a safe and secure use of machine learning models, it is important to have a quantitative assessment of the privacy risks of these models, and to make sure that they do not reveal sensitive information about their training data. This is of great importance as there has been a surge in the use of machine learning in sensitive domains such as medical and finance applications.
 
-Data Protection regulations, such as GDPR, and AI governance frameworks require personal data to be protected when used in AI systems, and that the users have control over their data and awareness about how it is being used. For example, [Article 35 of GDPR](https://gdpr-info.eu/art-35-gdpr/) requires organizations to systematically analyze, identify and minimize the data protection risks of a project, especially when the project involves innovative technologies such as Artificial Intelligence, Machine Learning and Deep Learning. Thus, proper mechanisms need to be in place to quantitatively evaluate and verify the privacy of individuals in every step of the data processing pipeline in AI systems.
+Data Protection regulations, such as GDPR and AI governance frameworks, require personal data to be protected when used in AI systems, and that the users have control over their data and awareness about how it is being used. For example, [Article 35 of GDPR](https://gdpr-info.eu/art-35-gdpr/) requires organizations to systematically analyze, identify and minimize the data protection risks of a project, especially when the project involves innovative technologies such as Artificial Intelligence, Machine Learning, and Deep Learning. Thus, proper mechanisms need to be in place to quantitatively evaluate and verify the privacy of individuals in every step of the data processing pipeline in AI systems.
 
 ML Privacy Meter is a Python library (`privacy_meter`) that enables quantifying the privacy risks of machine learning models. The tool provides privacy risk scores which help in identifying data records among the training data that are at high risk of being leaked through the model parameters or predictions.
 
 ## Overview
 
-The core of the privacy meter consists of three parts: `Information Source`, `Metric` and `Metric Results`.
+The core of the Privacy Meter consists of three parts: `Information Source`, `Metric` and `Metric Results`.
 
-<p align="center" width="100%">
-    <img width="80%" src="source/_static/privacy_meter_architecture.png">
-</p>
+![alt text](https://github.com/privacytrustlab/ml_privacy_meter/blob/master/source/_static/privacy_meter_architecture.png?raw=true)
 
-Kindly refer to the tutorial on the population attack ([here](tutorials/population_metric.ipynb)) to gain familiarity with the utilization of each component.
+<!-- Kindly refer to the tutorial on the population attack ([here](advanced/population_metric.ipynb)) to gain familiarity with the utilization of each component. -->
 
 ## Installation
 
@@ -40,48 +38,28 @@ Privacy Meter supports Python `>=3.6` and works with `tensorflow>=2.4.0` and `to
 
 You can install `privacy-meter` using `pip` for the latest stable version of the tool:
 
-```bash
+<!-- ```bash
 pip install git+https://github.com/privacytrustlab/ml_privacy_meter.git
-```
+``` -->
 
-<!-- ```bash
+```bash
 pip install privacy-meter
-``` -->
+```
 
-<!-- Alternatively, one can install it via conda:
+Alternatively, one can install it via conda:
 
 ```bash
 conda install privacy-meter
-``` -->
-
-## Quickstart
-
-We provide examples of how to run privacy meter on standard datasets and models in the [experiments](experiments/) folder. Run the following code for your first membership inference attack on CIFAR10.
-
-```
-cd experiments
-python main.py --cf config_models.yaml
 ```
-
-Kindly proceed to the experiments folder ([here](experiments/)) to perform privacy audits on various objects, such as models, algorithms, and data points, using the CIFAR10 dataset.
-
 ## User manual
 
-### Basic Usage
-
-We have comprehensive tutorials available in the tutorials folder to aid users in comprehending the privacy meter and also offer a default implementation for automatic privacy auditing in the experiments folder. To maximize the benefits of these resources, we recommend following this suggested order:
+We offer two types of tutorials: basic usage (in the [basic](https://github.com/privacytrustlab/ml_privacy_meter/tree/master/basic/) folder) and advanced usage (in the [advanced](https://github.com/privacytrustlab/ml_privacy_meter/tree/master/advanced/) folder). The goal of the basic tutorials is to provide users with a seamless experience in working with various predefined privacy games, algorithms, and signals. These components represent state-of-the-art membership inference attacks and can be configured easily without requiring users to write code (See instructions [here](https://github.com/privacytrustlab/ml_privacy_meter/tree/master/basic/README.md)). On the other hand, the advanced usage is tailored for professional users who seek to conduct sophisticated auditing. It allows them to utilize both pre-existing and customized algorithms, signals, and models, empowering them to perform advanced auditing tasks at a higher level of complexity and customization. Specifically, we provide the following tutorials for advanced usage:
 
-1. [Acquire a fundamental understanding of the privacy meter by executing a population attack on the CIFAR10 dataset.](tutorials/population_metric.ipynb)
-2. [Enhance your knowledge by conducting a reference attack on the CIFAR10 dataset.](tutorials/reference_metric.ipynb)
-3. [Automate the privacy auditing process on the CIFAR10 dataset.](experiments/)
-
-### Advanced Usage
-
-Users have the capability to extend our privacy meter to fit their specific needs. By utilizing the code in the experiments folder, one can perform privacy audits on customized training algorithms, datasets, and settings based on different privacy games (See instructions [here](experiments/README.md)). Furthermore, our framework can be extended to include white-box attacks and models developed by other libraries. For more information on this, please refer to the tutorials covering the following topics:
-
-1. [Implementing a simple white-box attack using the privacy meter.](tutorials/white_box_attack.ipynb)
-2. [Expanding the privacy meter to encompass OpenVION models.](tutorials/openvino_models.ipynb)
-3. [Integrating the privacy meter with HuggingFace models.](tutorials/hf_causal_language_models.ipynb)
+1. [Understanding low-level APIs: Acquire a fundamental understanding of the Privacy Meter by executing a population attack on the CIFAR10 dataset.](https://github.com/privacytrustlab/ml_privacy_meter/tree/master/advanced/population_metric.ipynb)
+2. [Understanding low-level APIs: Enhance your knowledge by conducting a reference attack on the CIFAR10 dataset.](https://github.com/privacytrustlab/ml_privacy_meter/tree/master/advanced/reference_metric.ipynb)
+3. [Implementing a simple white-box attack using the Privacy Meter.](https://github.com/privacytrustlab/ml_privacy_meter/tree/master/advanced/white_box_attack.ipynb)
+4. [Expanding the Privacy Meter to encompass OpenVINO models.](https://github.com/privacytrustlab/ml_privacy_meter/tree/master/advanced/openvino_models.ipynb)
+5. [Integrating the Privacy Meter with HuggingFace models.](https://github.com/privacytrustlab/ml_privacy_meter/tree/master/advanced/hf_causal_language_models.ipynb)
 
 ## Video (Talks)
 
@@ -101,14 +79,20 @@ Please feel free to join our [Slack Channel](https://join.slack.com/t/privacy-me
 
 To cite this repository, please include the following references (or you can download the [bib file](CITATION.bib)).
 
-1. Jiayuan Ye, Aadyaa Maddi, Sasi Kumar Murakonda, Reza Shokri. [Enhanced Membership Inference Attacks against Machine Learning Models](https://arxiv.org/pdf/2111.09679.pdf) in Proceedings of the 2022 ACM SIGSAC Conference on Computer and Communications Security, 2022.
+1. Chang, Hongyan, Aadyaa Maddi, Victor Masiak, Mihir Khandekar, Jiayuan Ye, and Reza Shokri (2023). Privacy Meter. https://github.com/privacytrustlab/ml_privacy_meter.
 
-2. Sasi Kumar Murakonda, Reza Shokri. [MLPrivacy Meter: Aiding Regulatory Compliance by Quantifying the Privacy Risks of Machine Learning](https://arxiv.org/pdf/2007.09339.pdf) in Workshop on Hot Topics in Privacy Enhancing Technologies (HotPETs), 2020.
+2. Jiayuan Ye, Aadyaa Maddi, Sasi Kumar Murakonda, Reza Shokri. [Enhanced Membership Inference Attacks against Machine Learning Models](https://arxiv.org/pdf/2111.09679.pdf) in Proceedings of the 2022 ACM SIGSAC Conference on Computer and Communications Security, 2022.
 
-3. Milad Nasr, Reza Shokri, and Amir Houmansadr. [Comprehensive Privacy Analysis of Deep Learning: Stand-alone and Federated Learning under Passive and Active White-box Inference Attacks](https://www.comp.nus.edu.sg/~reza/files/Shokri-SP2019.pdf) in IEEE Symposium on Security and Privacy, 2019.
+3. Sasi Kumar Murakonda, Reza Shokri. [MLPrivacy Meter: Aiding Regulatory Compliance by Quantifying the Privacy Risks of Machine Learning](https://arxiv.org/pdf/2007.09339.pdf) in Workshop on Hot Topics in Privacy Enhancing Technologies (HotPETs), 2020.
 
-4. Reza Shokri, Marco Stronati, Congzheng Song, and Vitaly Shmatikov. [Membership Inference Attacks against Machine Learning Models](https://www.comp.nus.edu.sg/~reza/files/Shokri-SP2017.pdf) in IEEE Symposium on Security and Privacy, 2017.
+4. Milad Nasr, Reza Shokri, and Amir Houmansadr. [Comprehensive Privacy Analysis of Deep Learning: Stand-alone and Federated Learning under Passive and Active White-box Inference Attacks](https://www.comp.nus.edu.sg/~reza/files/Shokri-SP2019.pdf) in IEEE Symposium on Security and Privacy, 2019.
+
+5. Reza Shokri, Marco Stronati, Congzheng Song, and Vitaly Shmatikov. [Membership Inference Attacks against Machine Learning Models](https://www.comp.nus.edu.sg/~reza/files/Shokri-SP2017.pdf) in IEEE Symposium on Security and Privacy, 2017.
 
 ## Authors
 
-The tool is designed and developed at NUS Data Privacy and Trustworthy Machine Learning Lab.
+The tool is designed and developed at NUS Data Privacy and Trustworthy Machine Learning Lab. We also welcome contributions from the community.
+
+<a href="https://github.com/privacytrustlab/ml_privacy_meter/graphs/contributors">
+  <img src="https://stg.contrib.rocks/image?repo=privacytrustlab/ml_privacy_meter" />
+</a>
diff --git a/tutorials/README.md b/advanced/README.md
similarity index 71%
rename from tutorials/README.md
rename to advanced/README.md
index bcd0c1e..0447acd 100644
--- a/tutorials/README.md
+++ b/advanced/README.md
@@ -8,22 +8,22 @@ You can access these tutorials on Colab for a seamless experience.
 
 | Tutorial                                                                                     | <img src="https://www.tensorflow.org/images/colab_logo_32px.png" />                                                                    |
 | -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
-| [Running the Population Metric](population_metric.ipynb)                                     | [Run](https://colab.research.google.com/github/privacytrustlab/ml_privacy_meter/blob/master/tutorials/population_metric.ipynb)         |
-| [Running the White-box Attack based on Population Metric](white_box_attack.ipynb)             | [Run](https://colab.research.google.com/github/privacytrustlab/ml_privacy_meter/blob/master/tutorials/white_box_attack.ipynb)           |
-| [Running the Reference Metric](reference_metric.ipynb)                                       | [Run](https://colab.research.google.com/github/privacytrustlab/ml_privacy_meter/blob/master/tutorials/reference_metric.ipynb)          |
-| [Evaluating the Average Privacy Loss of a Training Algorithm](avg_loss_training_algo.ipynb)  | [Run](https://colab.research.google.com/github/privacytrustlab/ml_privacy_meter/blob/master/tutorials/avg_loss_training_algo.ipynb)    |
-| [Running the Shadow Metric ](shadow_metric.ipynb)                                            | [Run](https://colab.research.google.com/github/privacytrustlab/ml_privacy_meter/blob/master/tutorials/shadow_metric.ipynb)             |
-| [Extending the Model class for OpenVINO Models](openvino_models.ipynb)                       | [Run](https://colab.research.google.com/github/privacytrustlab/ml_privacy_meter/blob/master/tutorials/openvino_models.ipynb)           |
-| [Extending the tool for HuggingFace Causal Language Models](hf_causal_language_models.ipynb) | [Run](https://colab.research.google.com/github/privacytrustlab/ml_privacy_meter/blob/master/tutorials/hf_causal_language_models.ipynb) |
+| [Running the Population Metric](population_metric.ipynb)                                     | [Run](https://colab.research.google.com/github/privacytrustlab/ml_privacy_meter/blob/master/advanced/population_metric.ipynb)         |
+| [Running the White-box Attack based on Population Metric](white_box_attack.ipynb)             | [Run](https://colab.research.google.com/github/privacytrustlab/ml_privacy_meter/blob/master/advanced/white_box_attack.ipynb)           |
+| [Running the Reference Metric](reference_metric.ipynb)                                       | [Run](https://colab.research.google.com/github/privacytrustlab/ml_privacy_meter/blob/master/advanced/reference_metric.ipynb)          |
+| [Evaluating the Average Privacy Loss of a Training Algorithm](avg_loss_training_algo.ipynb)  | [Run](https://colab.research.google.com/github/privacytrustlab/ml_privacy_meter/blob/master/advanced/avg_loss_training_algo.ipynb)    |
+| [Running the Shadow Metric ](shadow_metric.ipynb)                                            | [Run](https://colab.research.google.com/github/privacytrustlab/ml_privacy_meter/blob/master/advanced/shadow_metric.ipynb)             |
+| [Extending the Model class for OpenVINO Models](openvino_models.ipynb)                       | [Run](https://colab.research.google.com/github/privacytrustlab/ml_privacy_meter/blob/master/advanced/openvino_models.ipynb)           |
+| [Extending the tool for HuggingFace Causal Language Models](hf_causal_language_models.ipynb) | [Run](https://colab.research.google.com/github/privacytrustlab/ml_privacy_meter/blob/master/advanced/hf_causal_language_models.ipynb) |
 
-If you are running the tutorials on Colab, please add the following code to install the privacy meter.
+If you are running the tutorials on Colab, please add the following code to install the Privacy Meter.
 ```
 # Clone the repo.
 !git clone https://github.com/changhongyan123/ml_privacy_meter.git
 %pip install -r privacy_meter/requirements.txt
 exit()
 ```
-Then, add the following code before you import the privacy meter
+Then, add the following code before you import the Privacy Meter
 ```
 # Add the repo root to the Python path.
 import sys, os
diff --git a/tutorials/avg_loss_training_algo.ipynb b/advanced/avg_loss_training_algo.ipynb
similarity index 99%
rename from tutorials/avg_loss_training_algo.ipynb
rename to advanced/avg_loss_training_algo.ipynb
index 2be3ac6..cfb0474 100644
--- a/tutorials/avg_loss_training_algo.ipynb
+++ b/advanced/avg_loss_training_algo.ipynb
@@ -36,10 +36,10 @@
    "source": [
     "<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
     "<td>\n",
-    "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/privacytrustlab/ml_privacy_meter/blob/master/tutorials/avg_loss_training_algo.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
+    "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/privacytrustlab/ml_privacy_meter/blob/master/advanced/avg_loss_training_algo.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
     "  </td>\n",
     "  <td>\n",
-    "    <a target=\"_blank\" href=\"https://github.com/privacytrustlab/ml_privacy_meter/blob/master/tutorials/avg_loss_training_algo.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View GitHub</a>\n",
+    "    <a target=\"_blank\" href=\"https://github.com/privacytrustlab/ml_privacy_meter/blob/master/advanced/avg_loss_training_algo.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View GitHub</a>\n",
     "  </td>\n",
     "</table>"
    ]
diff --git a/advanced/cifar-10-batches-py/batches.meta b/advanced/cifar-10-batches-py/batches.meta
new file mode 100644
index 0000000..4467a6e
Binary files /dev/null and b/advanced/cifar-10-batches-py/batches.meta differ
diff --git a/advanced/cifar-10-batches-py/readme.html b/advanced/cifar-10-batches-py/readme.html
new file mode 100644
index 0000000..e377ade
--- /dev/null
+++ b/advanced/cifar-10-batches-py/readme.html
@@ -0,0 +1,1 @@
+<meta HTTP-EQUIV="REFRESH" content="0; url=http://www.cs.toronto.edu/~kriz/cifar.html">
diff --git a/tutorials/developer_guide.md b/advanced/developer_guide.md
similarity index 100%
rename from tutorials/developer_guide.md
rename to advanced/developer_guide.md
diff --git a/advanced/evaluation_fair.py b/advanced/evaluation_fair.py
new file mode 100644
index 0000000..c156c01
--- /dev/null
+++ b/advanced/evaluation_fair.py
@@ -0,0 +1,400 @@
+import numpy as np
+from fairlearn.datasets import fetch_acs_income
+from sklearn import preprocessing
+from fairlearn.metrics import MetricFrame
+from fairlearn.metrics import equalized_odds_difference
+import numpy as np
+from privacy_meter.audit import Audit, MetricEnum
+from privacy_meter.dataset import Dataset
+from privacy_meter.information_source import InformationSource
+
+from privacy_meter import audit_report
+from privacy_meter.audit_report import *
+
+import keras as keras
+import tensorflow as tf
+import matplotlib.pyplot as plt
+
+# load dataset
+import pandas as pd
+from fairlearn.reductions import EqualizedOdds
+import warnings
+
+warnings.filterwarnings("ignore")
+
+from fairlearn.metrics import MetricFrame
+from sklearn.metrics import accuracy_score
+from sklearn.tree import DecisionTreeClassifier
+from privacy_meter.audit import Audit, MetricEnum
+from privacy_meter.dataset import Dataset
+from privacy_meter.information_source import InformationSource
+from privacy_meter.model import Fairlearn_Model, Sklearn_Model
+import os
+from torch.utils.data import TensorDataset, DataLoader
+
+from fairtorch import ConstraintLoss, DemographicParityLoss, EqualiedOddsLoss
+import random
+import numpy as np
+import torch
+from torch import nn, optim
+from torch.utils.data import DataLoader, Dataset
+
+
+from privacy_meter.model import PytorchModelTensor
+from privacy_meter.dataset import Dataset
+import scipy
+
+# import copy
+import time
+
+
+def compute_p_value(target_value, observed_distribution):
+    return scipy.stats.percentileofscore(observed_distribution, target_value) / 100
+
+
+def train(
+    input_shape,
+    alpha,
+    coff,
+    device,
+    train_loader,
+    X_train,
+    y_train,
+    X_test,
+    y_test,
+    num_epochs=1000,
+    fair_train_loader=None,
+):
+    model = Model(input_shape, 1024, 1)
+    if coff != 0:
+        dp_loss = EqualiedOddsLoss(sensitive_classes=[1, 2], alpha=alpha)
+    optimizer = optim.AdamW(model.parameters(), lr=0.01)
+    criterion = nn.BCEWithLogitsLoss()
+    model.to(device)
+    for name, param in model.named_parameters():
+        if "weight" in name:
+            nn.init.xavier_normal_(param)
+
+    model.train()
+    for epoch in range(num_epochs):
+        for i, (x, y, s) in enumerate(train_loader):
+            lossfair = 0
+            optimizer.zero_grad()
+            x, y, s = x.to(device), y.to(device), s.to(device)
+            logit = model(x)
+            loss = criterion(logit.view(-1), y)
+            if coff != 0:
+                if fair_train_loader is not None:
+                    for x_f, y_f, s_f in fair_train_loader:
+                        # print(x_f.shape, y_f.shape, s_f.shape)
+                        x_f, y_f, s_f = x_f.to(device), y_f.to(device), s_f.to(device)
+                        logit_f = model(x_f)
+                        lossfair += dp_loss(x_f, logit_f, s_f, y_f)
+                else:
+                    lossfair = dp_loss(x, logit, s, y)
+                if torch.isnan(lossfair):
+                    loss = loss
+                else:
+                    loss = loss + lossfair
+
+            loss.backward()
+            optimizer.step()
+            # Print progress
+            if (i + 1) % 10 == 0:
+                print(
+                    "Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}".format(
+                        epoch + 1, num_epochs, i + 1, len(train_loader), loss.item()
+                    )
+                )
+
+    model.to("cpu")
+    return model
+
+
+def inference(model, X, y, sensi):
+    y_pred = (torch.sigmoid(model(X)).view(-1) > 0.5).float()
+
+    expect_by_a = {}
+
+    # for i in [1, 2]:
+    #     # print(sensi_test.shape, y_pred.shape)
+    #     idx = sensi==i
+    #     expect_by_a[i]=  y_pred[idx].mean().item()
+    # print(expect_by_a)
+    # vanilla_gap_dp = np.abs(expect_by_a[1] - expect_by_a[2])
+    # # print("gap: ",vanilla_gap_dp)
+
+    expect_by_a_y = {}
+    expect_by_a_y_list = []
+    for i in [1, 2]:
+        expect_by_a_y[i] = {}
+        for j in [0, 1]:
+            idx = (sensi == i) & (y == j)
+            expc = y_pred[idx].mean().item()
+            expect_by_a_y[i][j] = expc
+            expect_by_a_y_list.append(expc)
+    print(expect_by_a_y)
+    vanilla_gap_eo = np.max(expect_by_a_y_list) - np.min(expect_by_a_y_list)
+    acc = (
+        ((torch.sigmoid(model(X)).view(-1) > 0.5).float() == y)
+        .float()
+        .mean()
+        .float()
+        .item()
+    )
+    print("acc: ", round(acc, 3))
+
+    print("gap: ", vanilla_gap_eo)
+
+
+def privacy_evaluation(
+    target_model, train_ds, test_ds, population_ds, g_train, g_test, g_population
+):
+    target_model = PytorchModelTensor(
+        target_model, nn.BCEWithLogitsLoss(reduction="none")
+    )
+    target_dataset = Dataset(
+        data_dict={"train": train_ds, "test": test_ds},
+        default_input="x",
+        default_output="y",
+        default_group="g",
+    )
+    reference_dataset = Dataset(
+        data_dict={"train": population_ds},
+        default_input="x",
+        default_output="y",
+        default_group="g",
+    )
+    target_info_source = InformationSource(
+        models=[target_model], datasets=[target_dataset]
+    )
+
+    reference_info_source = InformationSource(
+        models=[target_model], datasets=[reference_dataset]
+    )
+    audit_obj = Audit(
+        metrics=MetricEnum.POPULATION,
+        inference_game_type=InferenceGame.PRIVACY_LOSS_MODEL,
+        target_info_sources=target_info_source,
+        reference_info_sources=reference_info_source,
+        logs_directory_names="log_" + str(time.time()),
+    )
+    audit_obj.prepare()
+
+    train_signal = audit_obj.metric_objects[0].member_signals
+    test_signal = audit_obj.metric_objects[0].non_member_signals
+    pop_signal = audit_obj.metric_objects[0].reference_signals
+
+    p_results = {}
+    for idx, g in enumerate(torch.unique(g_train)):
+        un_pop = pop_signal[g_pop == g]
+        p_train = compute_p_value(train_signal[g_train == g], un_pop)
+        p_test = compute_p_value(test_signal[g_test == g], un_pop)
+        p_results[idx] = {}
+        p_results[idx]["p"] = np.concatenate([p_train, p_test])
+        p_results[idx]["mem"] = np.concatenate(
+            [np.ones(len(p_train)), np.zeros(len(p_test))]
+        )
+
+    return p_results
+
+
+class Model(nn.Module):
+    def __init__(self, input_dim, hidden_dim, output_dim):
+        super(Model, self).__init__()
+        self.fc1 = nn.Linear(input_dim, hidden_dim)
+        self.relu1 = nn.ReLU()
+        self.fc2 = nn.Linear(hidden_dim, hidden_dim)
+        self.relu2 = nn.ReLU()
+        self.fc3 = nn.Linear(hidden_dim, output_dim)
+
+    def forward(self, x):
+        out = self.fc1(x)
+        out = self.relu1(out)
+        out = self.fc2(out)
+        out = self.relu2(out)
+        out = self.fc3(out)
+        return out
+
+
+def get_data(N):
+    p00 = 0.02
+    p10 = 0.4
+    p11 = 0.4
+    p01 = 0.18
+
+    X00 = np.random.multivariate_normal([0, -1], [[7, 1], [1, 7]], int(N * p00))
+    X01 = np.random.multivariate_normal([-5, 0], [[5, 1], [1, 5]], int(N * p01))
+    X10 = np.random.multivariate_normal([1, 2], [[5, 2], [2, 5]], int(N * p10))
+    X11 = np.random.multivariate_normal([2, 3], [[10, 1], [1, 4]], int(N * p11))
+    X = np.concatenate((X00, X01, X10, X11), axis=0)
+    y_true = np.concatenate(
+        (
+            np.zeros(int(N * p00)),
+            np.ones(int(N * p01)),
+            np.zeros(int(N * p10)),
+            np.ones(int(N * p11)),
+        ),
+        axis=0,
+    )
+    sex = np.concatenate(
+        (
+            np.ones(int(N * p00)),
+            np.ones(int(N * p01)),
+            np.full(int(N * p10), 2),
+            np.full(int(N * p11), 2),
+        ),
+        axis=0,
+    )
+    return X, y_true, sex
+
+
+def inference(model, X, y, sensi):
+    y_pred = (torch.sigmoid(model(X)).view(-1) > 0.5).float()
+
+    expect_by_a = {}
+
+    # for i in [1, 2]:
+    #     # print(sensi_test.shape, y_pred.shape)
+    #     idx = sensi==i
+    #     expect_by_a[i]=  y_pred[idx].mean().item()
+    # print(expect_by_a)
+    # vanilla_gap_dp = np.abs(expect_by_a[1] - expect_by_a[2])
+    # # print("gap: ",vanilla_gap_dp)
+
+    expect_by_a_y = {}
+    expect_by_a_y_list = []
+    for i in [1, 2]:
+        expect_by_a_y[i] = {}
+        for j in [0, 1]:
+            idx = (sensi == i) & (y == j)
+            expc = y_pred[idx].mean().item()
+            expect_by_a_y[i][j] = expc
+            expect_by_a_y_list.append(expc)
+    # print(expect_by_a_y)
+    vanilla_gap_eo = np.max(expect_by_a_y_list) - np.min(expect_by_a_y_list)
+    print("gap: ", vanilla_gap_eo)
+
+
+def seed_everything(seed):
+    random.seed(seed)
+    os.environ["PYTHONHASHSEED"] = str(seed)
+    np.random.seed(seed)
+    torch.manual_seed(seed)
+    torch.cuda.manual_seed(seed)
+    torch.backends.cudnn.deterministic = True
+
+
+if __name__ == "__main__":
+    seed_everything(2020)
+    device = "cuda:0"
+    num_train_points = 1000
+    num_test_points = 1000
+    num_fair_train_points = 1000
+    num_population_points = 30000
+    num_epochs = 1000
+
+    X_train, y_train, g_train = get_data(num_train_points)
+    X_test, y_test, g_test = get_data(num_test_points)
+    X_fair_train, y_fair_train, g_fair_train = get_data(num_fair_train_points)
+    X_population, y_population, g_population = get_data(num_population_points)
+
+    X = np.concatenate((X_train, X_test, X_fair_train, X_population), axis=0)
+    y_true = np.concatenate((y_train, y_test, y_fair_train, y_population), axis=0)
+    sex = np.concatenate((g_train, g_test, g_fair_train, g_population), axis=0)
+
+    train_index = np.arange(num_train_points)
+    test_index = np.arange(num_train_points, num_train_points + num_test_points)
+    fair_train_index = np.arange(
+        num_train_points + num_test_points,
+        num_train_points + num_test_points + num_fair_train_points,
+    )
+    population_index = np.arange(
+        num_train_points + num_test_points + num_fair_train_points,
+        num_train_points
+        + num_test_points
+        + num_fair_train_points
+        + num_population_points,
+    )
+
+    # Convert the data to tensors
+    X_train = torch.from_numpy(X[train_index]).float()
+    X_test = torch.from_numpy(X[test_index]).float()
+    y_train = torch.from_numpy(y_true[train_index]).float()
+    y_test = torch.from_numpy(y_true[test_index]).float()
+    sensi_train = torch.from_numpy(sex[train_index]).float()
+    sensi_test = torch.from_numpy(sex[test_index]).float()
+    # create the target model's dataset
+    g_train = y_train + sensi_train * 2
+    g_test = y_test + sensi_test * 2
+
+    X_population = torch.from_numpy(X[population_index]).float()
+    y_population = torch.from_numpy(y_true[population_index]).float()
+    sensi_population = torch.from_numpy(sex[population_index]).float()
+    g_pop = y_population + sensi_population * 2
+
+    X_fair_train = torch.from_numpy(X[fair_train_index]).float()
+    y_fair_train = torch.from_numpy(y_true[fair_train_index]).float()
+    sensi_fair = torch.from_numpy(sex[fair_train_index]).float()
+    g_fair = y_fair_train + sensi_fair * 2
+
+    # Create TensorDatasets
+    train_dataset = TensorDataset(X_train, y_train, sensi_train)
+    test_dataset = TensorDataset(X_test, y_test, sensi_test)
+    fair_train_dataset = TensorDataset(X_fair_train, y_fair_train, sensi_fair)
+
+    # Create DataLoaders
+    train_loader = DataLoader(train_dataset, batch_size=300, shuffle=True)
+    test_loader = DataLoader(test_dataset, batch_size=1000, shuffle=False)
+    fair_train_loader = DataLoader(
+        fair_train_dataset, batch_size=len(fair_train_dataset), shuffle=False
+    )
+
+    model = train(
+        X_train.shape[1],
+        0,
+        0,
+        device,
+        train_loader,
+        X_train,
+        y_train,
+        X_test,
+        y_test,
+        num_epochs=num_epochs,
+        fair_train_loader=None,
+    )
+    fair_model = train(
+        X_train.shape[1],
+        50,
+        1,
+        device,
+        train_loader,
+        X_train,
+        y_train,
+        X_test,
+        y_test,
+        num_epochs=num_epochs,
+        fair_train_loader=None,
+    )
+    fair_model2 = train(
+        X_train.shape[1],
+        50,
+        1,
+        device,
+        train_loader,
+        X_train,
+        y_train,
+        X_test,
+        y_test,
+        num_epochs=num_epochs,
+        fair_train_loader=fair_train_loader,
+    )
+
+    print("Standard model")
+    inference(model, X_test, y_test, sensi_test)
+
+    print("Fair model")
+    inference(fair_model, X_test, y_test, sensi_test)
+    sensi_test
+    print("Our model")
+    inference(fair_model2, X_test, y_test, sensi_test)
diff --git a/advanced/fair_algo.ipynb b/advanced/fair_algo.ipynb
new file mode 100644
index 0000000..4c46b17
--- /dev/null
+++ b/advanced/fair_algo.ipynb
@@ -0,0 +1,577 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import numpy as np\n",
+    "from fairlearn.datasets import fetch_acs_income\n",
+    "from sklearn import preprocessing\n",
+    "from fairlearn.metrics import MetricFrame\n",
+    "from fairlearn.metrics import equalized_odds_difference\n",
+    "import numpy as np\n",
+    "from privacy_meter.audit import Audit, MetricEnum\n",
+    "from privacy_meter.dataset import Dataset\n",
+    "from privacy_meter.information_source import InformationSource\n",
+    "\n",
+    "\n",
+    "import keras as keras\n",
+    "import tensorflow as tf\n",
+    "import matplotlib.pyplot as plt\n",
+    "# load dataset\n",
+    "import pandas as pd\n",
+    "from fairlearn.reductions import EqualizedOdds\n",
+    "import warnings\n",
+    "warnings.filterwarnings('ignore')\n",
+    "\n",
+    "from fairlearn.metrics import MetricFrame\n",
+    "from sklearn.metrics import accuracy_score\n",
+    "from sklearn.tree import DecisionTreeClassifier\n",
+    "from privacy_meter.audit import Audit, MetricEnum\n",
+    "from privacy_meter.dataset import Dataset\n",
+    "from privacy_meter.information_source import InformationSource\n",
+    "from privacy_meter.model import Fairlearn_Model, Sklearn_Model\n"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# load dataset"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 186,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "data = fetch_acs_income(as_frame=False,states=[\"CA\"])\n",
+    "sex = data.data[:,data['feature_names'].index('SEX')]\n",
+    "X = data.data\n",
+    "y_true = (data.target > 50000) * 1\n",
+    "X = preprocessing.normalize(X, norm='l2')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 187,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "((195665, 10), (195665,))"
+      ]
+     },
+     "execution_count": 187,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "X.shape, y_true.shape"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# standard model"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 188,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "0.7455702348401605\n",
+      "sensitive_feature_0\n",
+      "1.0    0.732420\n",
+      "2.0    0.760281\n",
+      "Name: accuracy_score, dtype: float64\n",
+      "0.029908267724111592\n"
+     ]
+    }
+   ],
+   "source": [
+    "\n",
+    "classifier = DecisionTreeClassifier(min_samples_leaf=10, max_depth=4)\n",
+    "classifier.fit(X, y_true)\n",
+    "\n",
+    "y_pred = classifier.predict(X)\n",
+    "gm = MetricFrame(metrics=accuracy_score, y_true=y_true, y_pred=y_pred, sensitive_features=sex)\n",
+    "print(gm.overall)\n",
+    "print(gm.by_group)\n",
+    "print(equalized_odds_difference(y_true,\n",
+    "                                y_pred,\n",
+    "                                sensitive_features=sex))"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# fair models\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 189,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "0.7544016558914471\n",
+      "sensitive_feature_0\n",
+      "1.0    0.744606\n",
+      "2.0    0.765359\n",
+      "Name: accuracy_score, dtype: float64\n"
+     ]
+    }
+   ],
+   "source": [
+    "from fairlearn.reductions import ExponentiatedGradient, DemographicParity\n",
+    "from fairlearn.metrics import equalized_odds_difference\n",
+    "\n",
+    "np.random.seed(0)  # set seed for consistent results with ExponentiatedGradient\n",
+    "constraint = EqualizedOdds(difference_bound=0.0001)\n",
+    "classifier = DecisionTreeClassifier(min_samples_leaf=10, max_depth=4)\n",
+    "mitigator = ExponentiatedGradient(classifier, constraint)\n",
+    "mitigator.fit(X, y_true, sensitive_features=sex)\n",
+    "y_pred_mitigated = mitigator.predict(X)\n",
+    "sr_mitigated = MetricFrame(metrics=accuracy_score, y_true=y_true, y_pred=y_pred_mitigated, sensitive_features=sex)\n",
+    "print(sr_mitigated.overall)\n",
+    "print(sr_mitigated.by_group)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 190,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "0.0006599766260567685\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(equalized_odds_difference(y_true,\n",
+    "                                y_pred_mitigated,\n",
+    "                                sensitive_features=sex))\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Attack models"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 206,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# for the population metric\n",
+    "seed = 1234\n",
+    "np.random.seed(seed)\n",
+    "rng = np.random.default_rng(seed=seed)\n",
+    "# for training the target and reference models\n",
+    "num_train_points = 2000\n",
+    "num_test_points = 2000\n",
+    "num_fair_train_points = 10000\n",
+    "num_population_points = 30000\n",
+    "\n",
+    "train_index = np.random.choice(X.shape[0], num_train_points, replace=False)\n",
+    "test_index = np.random.choice(X.shape[0], num_test_points, replace=False)\n",
+    "fair_train_index = np.random.choice(X.shape[0], num_fair_train_points, replace=False)\n",
+    "population_index = np.random.choice(X.shape[0], num_population_points, replace=False)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 207,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "input_shape= X.shape[-1]\n",
+    "num_classes= 1"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 208,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# create the target model's dataset\n",
+    "g_train  = (y_true[train_index])+ (sex[train_index])*2\n",
+    "g_test  = (y_true[test_index])+ (sex[test_index])*2\n",
+    "g_pop_train = (y_true[population_index])+ (sex[population_index])*2"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 209,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# create the target model's dataset\n",
+    "train_ds = {'x': X[train_index], 'y': y_true[train_index],'g':g_train}\n",
+    "test_ds = {'x': X[test_index], 'y': y_true[test_index], 'g':g_test}\n",
+    "target_dataset = Dataset(\n",
+    "    data_dict={'train': train_ds, 'test': test_ds},\n",
+    "    default_input='x', default_output='y', default_group='g'\n",
+    ")\n",
+    "\n",
+    "# create the reference dataset\n",
+    "population_ds = {'x': X[population_index], 'y': y_true[population_index], 'g': g_pop_train}\n",
+    "reference_dataset = Dataset(\n",
+    "    data_dict={'train': population_ds},\n",
+    "    default_input='x', default_output='y', default_group='g'\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 210,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "DecisionTreeClassifier(max_depth=8, min_samples_leaf=10)\n",
+      "0.7405 sensitive_feature_0\n",
+      "1.0    0.746860\n",
+      "2.0    0.733679\n",
+      "Name: accuracy_score, dtype: float64\n",
+      "0.806 sensitive_feature_0\n",
+      "1.0    0.810732\n",
+      "2.0    0.801026\n",
+      "Name: accuracy_score, dtype: float64\n",
+      "0.22076978939724035\n"
+     ]
+    }
+   ],
+   "source": [
+    "def log(y, pre):\n",
+    "    e = 0.0000001\n",
+    "    pre = np.clip(pre, e, 1 - e)\n",
+    "    return - y * np.log(pre) - (1 - y) * np.log(1 - pre)\n",
+    "\n",
+    "model = DecisionTreeClassifier(min_samples_leaf=10, max_depth=8)\n",
+    "model.fit(X[train_index], y_true[train_index])\n",
+    "target_model = Sklearn_Model(model_obj=model, loss_fn=log)\n",
+    "print(model)\n",
+    "y_pred_test= model.predict(X[test_index])\n",
+    "sr_test = MetricFrame(metrics=accuracy_score, y_true=y_true[test_index], y_pred=y_pred_test, sensitive_features=sex[test_index])\n",
+    "y_pred_train= model.predict(X[train_index])\n",
+    "sr_train = MetricFrame(metrics=accuracy_score, y_true=y_true[train_index], y_pred=y_pred_train, sensitive_features=sex[train_index])\n",
+    "print(sr_test.overall, sr_test.by_group)\n",
+    "print(sr_train.overall, sr_train.by_group)\n",
+    "print(equalized_odds_difference(y_true[test_index],y_pred_test, sensitive_features=sex[test_index]))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 211,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "ExponentiatedGradient(constraints=<fairlearn.reductions._moments.utility_parity.EqualizedOdds object at 0x7f0468ccd370>,\n",
+      "                      estimator=DecisionTreeClassifier(max_depth=8,\n",
+      "                                                       min_samples_leaf=10),\n",
+      "                      nu=0.004422134963885591)\n",
+      "0.742 sensitive_feature_0\n",
+      "1.0    0.743961\n",
+      "2.0    0.739896\n",
+      "Name: accuracy_score, dtype: float64\n",
+      "0.8135 sensitive_feature_0\n",
+      "1.0    0.815610\n",
+      "2.0    0.811282\n",
+      "Name: accuracy_score, dtype: float64\n",
+      "0.05319535221496008\n"
+     ]
+    }
+   ],
+   "source": [
+    "constraint = EqualizedOdds(difference_bound=0.0001)\n",
+    "classifier = DecisionTreeClassifier(min_samples_leaf=10, max_depth=8)\n",
+    "mitigator = ExponentiatedGradient(classifier, constraint)\n",
+    "mitigator.fit(X[train_index], y_true[train_index], sensitive_features=sex[train_index])\n",
+    "fair_target_model = Fairlearn_Model(model_obj=mitigator, loss_fn=log)\n",
+    "print(mitigator)\n",
+    "y_pred_test= mitigator.predict(X[test_index])\n",
+    "sr_test = MetricFrame(metrics=accuracy_score, y_true=y_true[test_index], y_pred=y_pred_test, sensitive_features=sex[test_index])\n",
+    "y_pred_train= mitigator.predict(X[train_index])\n",
+    "sr_train = MetricFrame(metrics=accuracy_score, y_true=y_true[train_index], y_pred=y_pred_train, sensitive_features=sex[train_index])\n",
+    "print(sr_test.overall, sr_test.by_group)\n",
+    "print(sr_train.overall, sr_train.by_group)\n",
+    "print(equalized_odds_difference(y_true[test_index],y_pred_test, sensitive_features=sex[test_index]))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 212,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "un_target_info_source = InformationSource(\n",
+    "    models=[target_model], \n",
+    "    datasets=[target_dataset]\n",
+    ")\n",
+    "\n",
+    "un_reference_info_source = InformationSource(\n",
+    "    models=[target_model],\n",
+    "    datasets=[reference_dataset]\n",
+    ")\n",
+    "\n",
+    "fair_target_info_source = InformationSource(\n",
+    "    models=[fair_target_model], \n",
+    "    datasets=[target_dataset]\n",
+    ")\n",
+    "\n",
+    "fair_reference_info_source = InformationSource(\n",
+    "    models=[fair_target_model],\n",
+    "    datasets=[reference_dataset]\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 221,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from privacy_meter import audit_report\n",
+    "from privacy_meter.audit_report import *\n",
+    "\n",
+    "\n",
+    "un_audit_obj = Audit(\n",
+    "    metrics=MetricEnum.GROUPPOPULATION,\n",
+    "    inference_game_type=InferenceGame.PRIVACY_LOSS_MODEL,\n",
+    "    target_info_sources=un_target_info_source,\n",
+    "    reference_info_sources=un_reference_info_source,\n",
+    "    logs_directory_names='un_log'\n",
+    ")\n",
+    "un_audit_obj.prepare()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 222,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "fair_audit_obj = Audit(\n",
+    "    metrics=MetricEnum.GROUPPOPULATION,\n",
+    "    inference_game_type=InferenceGame.PRIVACY_LOSS_MODEL,\n",
+    "    target_info_sources=fair_target_info_source,\n",
+    "    reference_info_sources=fair_reference_info_source,\n",
+    "    logs_directory_names='fair_log'\n",
+    ")\n",
+    "fair_audit_obj.prepare()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 223,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# un_audit_results = un_audit_obj.run()[0]\n",
+    "# fair_audit_results = fair_audit_obj.run()[0]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 224,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# tpr = un_audit_results[0].tp/(un_audit_results[0].tp+un_audit_results[0].fn)\n",
+    "# fpr = un_audit_results[0].fp/(un_audit_results[0].fp+un_audit_results[0].tn)\n",
+    "# roc = np.trapz(tpr, fpr)\n",
+    "# fair_tpr = fair_audit_results[0].tp/(fair_audit_results[0].tp+fair_audit_results[0].fn)\n",
+    "# fair_fpr = fair_audit_results[0].fp/(fair_audit_results[0].fp+fair_audit_results[0].tn)\n",
+    "# fair_roc = np.trapz(fair_tpr, fair_fpr)\n",
+    "# plt.title('Overall ROC')\n",
+    "# plt.plot([0, 1], [0, 1], 'k--', label='Random Guess')\n",
+    "# plt.plot(fpr, tpr, label=f'Unfair-ROC:{roc:.3f}')\n",
+    "# plt.plot(fair_fpr, fair_tpr, label=f'Fair-ROC:{fair_roc:.3f}')\n",
+    "# plt.legend()\n",
+    "# plt.xlabel('False Positive Rate')\n",
+    "# plt.ylabel('True Positive Rate')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 225,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# show the results in each group \n",
+    "un_train_signal = un_audit_obj.metric_objects[0].member_signals\n",
+    "un_test_signal = un_audit_obj.metric_objects[0].non_member_signals\n",
+    "un_pop_signal = un_audit_obj.metric_objects[0].reference_signals\n",
+    "\n",
+    "fair_train_signal = fair_audit_obj.metric_objects[0].member_signals\n",
+    "fair_test_signal = fair_audit_obj.metric_objects[0].non_member_signals\n",
+    "fair_pop_signal = fair_audit_obj.metric_objects[0].reference_signals"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 226,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import scipy\n",
+    "def compute_p_value( target_value, observed_distribution):\n",
+    "    return scipy.stats.percentileofscore(observed_distribution, target_value)/100\n",
+    "\n",
+    "p_results = {}\n",
+    "p_fair_results = {}\n",
+    "\n",
+    "for g in np.unique(g_train):\n",
+    "    un_pop = un_pop_signal[g_pop_train==g]\n",
+    "    p_train = compute_p_value(un_train_signal[g_train==g], un_pop)\n",
+    "    p_test = compute_p_value(un_test_signal[g_test==g], un_pop)\n",
+    "    p_results[g] = {}\n",
+    "    p_results[g]['p'] = np.concatenate([p_train, p_test])\n",
+    "    p_results[g]['mem'] = np.concatenate([np.ones(len(p_train)), np.zeros(len(p_test))])\n",
+    "    \n",
+    "    \n",
+    "    fair_pop  = fair_pop_signal[g_pop_train==g]\n",
+    "    p_fair_train = compute_p_value(fair_train_signal[g_train==g], fair_pop)\n",
+    "    p_fair_test = compute_p_value(fair_test_signal[g_test==g], fair_pop)\n",
+    "    p_fair_results[g] = {}\n",
+    "    p_fair_results[g]['p'] = np.concatenate([p_fair_train, p_fair_test])\n",
+    "    p_fair_results[g]['mem'] = np.concatenate([np.ones(len(p_fair_train)), np.zeros(len(p_fair_test))])\n",
+    "    "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 227,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(2000,)"
+      ]
+     },
+     "execution_count": 227,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "g_train.shape"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 228,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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",
+      "text/plain": [
+       "<Figure size 1200x300 with 4 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "figs, axes = plt.subplots(1,4, figsize=(12,3), sharey=True, sharex=True)\n",
+    "\n",
+    "# group = np.unique(g_train)\n",
+    "for idx, group in enumerate(np.unique(g_train)):\n",
+    "    tpr = [np.mean(p_results[group]['p'][p_results[group]['mem']==1]<i) for i in np.linspace(0,1,100)]\n",
+    "    fpr = [np.mean(p_results[group]['p'][p_results[group]['mem']==0]<i) for i in np.linspace(0,1,100)]\n",
+    "\n",
+    "    fair_tpr = [np.mean(p_fair_results[group]['p'][p_fair_results[group]['mem']==1]<i) for i in np.linspace(0,1,100)]\n",
+    "    fair_fpr = [np.mean(p_fair_results[group]['p'][p_fair_results[group]['mem']==0]<i) for i in np.linspace(0,1,100)]\n",
+    "\n",
+    "    roc = np.trapz(tpr, fpr)\n",
+    "    fair_roc = np.trapz(fair_tpr, fair_fpr)\n",
+    "\n",
+    "    axes[idx].plot([0, 1], [0, 1], 'k--', label='Random Guess', color='grey')\n",
+    "    axes[idx].plot(fpr, tpr, label=f'Unfair-ROC:{roc:.3f}', color='blue')\n",
+    "    axes[idx].plot(fair_fpr, fair_tpr, label=f'Fair-ROC:{fair_roc:.3f}', ls='--', color='red')\n",
+    "    axes[idx].set_xlabel('False Positive Rate')\n",
+    "    axes[idx].set_title(f'Subgroup {idx}')\n",
+    "    axes[idx].legend()\n",
+    "axes[0].set_ylabel('True Positive Rate')\n",
+    "plt.tight_layout()"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "privacy_meter_test",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.9.16"
+  },
+  "orig_nbformat": 4,
+  "vscode": {
+   "interpreter": {
+    "hash": "af48e0a30d2a0b619bf296aea7d7271ba14c9beb98b0928b3e23c82f12ae949a"
+   }
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/advanced/fair_pytorch.ipynb b/advanced/fair_pytorch.ipynb
new file mode 100644
index 0000000..107a209
--- /dev/null
+++ b/advanced/fair_pytorch.ipynb
@@ -0,0 +1,582 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "2023-04-17 22:30:31.021963: I tensorflow/core/platform/cpu_feature_guard.cc:193] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX2 AVX512F FMA\n",
+      "To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.\n",
+      "2023-04-17 22:30:31.137275: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /usr/lib/x86_64-linux-gnu::/usr/lib/x86_64-linux-gnu:\n",
+      "2023-04-17 22:30:31.137289: I tensorflow/compiler/xla/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.\n",
+      "2023-04-17 22:30:31.681938: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer.so.7'; dlerror: libnvinfer.so.7: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /usr/lib/x86_64-linux-gnu::/usr/lib/x86_64-linux-gnu:\n",
+      "2023-04-17 22:30:31.682025: W tensorflow/compiler/xla/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libnvinfer_plugin.so.7'; dlerror: libnvinfer_plugin.so.7: cannot open shared object file: No such file or directory; LD_LIBRARY_PATH: /usr/lib/x86_64-linux-gnu::/usr/lib/x86_64-linux-gnu:\n",
+      "2023-04-17 22:30:31.682030: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Cannot dlopen some TensorRT libraries. If you would like to use Nvidia GPU with TensorRT, please make sure the missing libraries mentioned above are installed properly.\n",
+      "/home/hongyan/.conda/envs/privacy_meter_test/lib/python3.9/site-packages/tqdm/auto.py:22: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
+      "  from .autonotebook import tqdm as notebook_tqdm\n"
+     ]
+    }
+   ],
+   "source": [
+    "import numpy as np\n",
+    "from fairlearn.datasets import fetch_acs_income\n",
+    "from sklearn import preprocessing\n",
+    "from fairlearn.metrics import MetricFrame\n",
+    "from fairlearn.metrics import equalized_odds_difference\n",
+    "import numpy as np\n",
+    "from privacy_meter.audit import Audit, MetricEnum\n",
+    "from privacy_meter.dataset import Dataset\n",
+    "from privacy_meter.information_source import InformationSource\n",
+    "\n",
+    "from privacy_meter import audit_report\n",
+    "from privacy_meter.audit_report import *\n",
+    "\n",
+    "import keras as keras\n",
+    "import tensorflow as tf\n",
+    "import matplotlib.pyplot as plt\n",
+    "# load dataset\n",
+    "import pandas as pd\n",
+    "from fairlearn.reductions import EqualizedOdds\n",
+    "import warnings\n",
+    "warnings.filterwarnings('ignore')\n",
+    "\n",
+    "from fairlearn.metrics import MetricFrame\n",
+    "from sklearn.metrics import accuracy_score\n",
+    "from sklearn.tree import DecisionTreeClassifier\n",
+    "from privacy_meter.audit import Audit, MetricEnum\n",
+    "from privacy_meter.dataset import Dataset\n",
+    "from privacy_meter.information_source import InformationSource\n",
+    "from privacy_meter.model import Fairlearn_Model, Sklearn_Model\n",
+    "import os\n",
+    "from torch.utils.data import TensorDataset, DataLoader\n",
+    "\n",
+    "from fairtorch import ConstraintLoss, DemographicParityLoss, EqualiedOddsLoss\n",
+    "import random\n",
+    "import numpy as np\n",
+    "import torch\n",
+    "from torch import nn, optim\n",
+    "from torch.utils.data import DataLoader, Dataset"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 155,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from privacy_meter.model import PytorchModelTensor\n",
+    "from privacy_meter.dataset import Dataset\n",
+    "import scipy\n",
+    "def compute_p_value( target_value, observed_distribution):\n",
+    "    return scipy.stats.percentileofscore(observed_distribution, target_value)/100\n",
+    "\n",
+    "# import copy\n",
+    "import time\n",
+    "def privacy_evaluation(target_model, train_ds, test_ds, population_ds, g_train, g_test, g_population):\n",
+    "    target_model = PytorchModelTensor(target_model, nn.BCEWithLogitsLoss(reduction='none'))\n",
+    "    target_dataset = Dataset(\n",
+    "        data_dict={'train': train_ds, 'test': test_ds},\n",
+    "        default_input='x', default_output='y', default_group='g'\n",
+    "    )\n",
+    "    reference_dataset = Dataset(\n",
+    "    data_dict={'train': population_ds},\n",
+    "    default_input='x', default_output='y', default_group='g'\n",
+    "    )\n",
+    "    target_info_source = InformationSource(\n",
+    "    models=[target_model], \n",
+    "        datasets=[target_dataset]\n",
+    "    )\n",
+    "\n",
+    "    reference_info_source = InformationSource(\n",
+    "        models=[target_model],\n",
+    "        datasets=[reference_dataset]\n",
+    "    )\n",
+    "    audit_obj = Audit(\n",
+    "    metrics=MetricEnum.POPULATION,\n",
+    "    inference_game_type=InferenceGame.PRIVACY_LOSS_MODEL,\n",
+    "    target_info_sources=target_info_source,\n",
+    "    reference_info_sources=reference_info_source,\n",
+    "    logs_directory_names='log_'+str(time.time())\n",
+    "    )\n",
+    "    audit_obj.prepare()\n",
+    "\n",
+    "    train_signal = audit_obj.metric_objects[0].member_signals\n",
+    "    test_signal = audit_obj.metric_objects[0].non_member_signals\n",
+    "    pop_signal = audit_obj.metric_objects[0].reference_signals\n",
+    "    \n",
+    "\n",
+    "    p_results = {}\n",
+    "    for idx, g in enumerate(torch.unique(g_train)):\n",
+    "        un_pop = pop_signal[g_pop==g]\n",
+    "        p_train = compute_p_value(train_signal[g_train==g], un_pop)\n",
+    "        p_test = compute_p_value(test_signal[g_test==g], un_pop)\n",
+    "        p_results[idx] = {}\n",
+    "        p_results[idx]['p'] = np.concatenate([p_train, p_test])\n",
+    "        p_results[idx]['mem'] = np.concatenate([np.ones(len(p_train)), np.zeros(len(p_test))])\n",
+    "        \n",
+    "    return p_results\n",
+    "        \n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 156,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def seed_everything(seed):\n",
+    "    random.seed(seed)\n",
+    "    os.environ[\"PYTHONHASHSEED\"] = str(seed)\n",
+    "    np.random.seed(seed)\n",
+    "    torch.manual_seed(seed)\n",
+    "    torch.cuda.manual_seed(seed)\n",
+    "    torch.backends.cudnn.deterministic = True\n",
+    "\n",
+    "\n",
+    "seed_everything(2020)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 157,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "\n",
+    "class Model(nn.Module):\n",
+    "    def __init__(self, input_dim, hidden_dim, output_dim):\n",
+    "        super(Model, self).__init__()\n",
+    "        self.fc1 = nn.Linear(input_dim, hidden_dim)\n",
+    "        self.relu1 = nn.ReLU()\n",
+    "        self.fc2 = nn.Linear(hidden_dim, hidden_dim)\n",
+    "        self.relu2 = nn.ReLU()\n",
+    "        self.fc3 = nn.Linear(hidden_dim, output_dim)\n",
+    "\n",
+    "    def forward(self, x):\n",
+    "        out = self.fc1(x)\n",
+    "        out = self.relu1(out)\n",
+    "        out = self.fc2(out)\n",
+    "        out = self.relu2(out)\n",
+    "        out = self.fc3(out)\n",
+    "        return out\n",
+    "    \n",
+    "def get_data(N):\n",
+    "    p00 = 0.02\n",
+    "    p10 = 0.4\n",
+    "    p11 = 0.4\n",
+    "    p01 = 0.18\n",
+    "\n",
+    "    X00 = np.random.multivariate_normal([0, -1], [[7, 1], [1, 7]], int(N*p00))\n",
+    "    X01 = np.random.multivariate_normal([-5, 0], [[5, 1], [1, 5]], int(N*p01))\n",
+    "    X10 = np.random.multivariate_normal([1, 2], [[5, 2], [2, 5]], int(N*p10))\n",
+    "    X11 = np.random.multivariate_normal([2, 3], [[10, 1], [1, 4]], int(N*p11))\n",
+    "    X = np.concatenate((X00, X01, X10, X11), axis=0)\n",
+    "    y_true = np.concatenate((np.zeros(int(N*p00)), np.ones(int(N*p01)), np.zeros(int(N*p10)), np.ones(int(N*p11))), axis=0)\n",
+    "    sex = np.concatenate((np.ones(int(N*p00)), np.ones(int(N*p01)), np.full(int(N*p10), 2), np.full(int(N*p11), 2)), axis=0)\n",
+    "    return X, y_true, sex\n",
+    "\n",
+    "def inference(model,X,y,sensi):\n",
+    "    y_pred = (torch.sigmoid(model(X)).view(-1) > 0.5 ).float()\n",
+    "\n",
+    "    expect_by_a={}\n",
+    "\n",
+    "    # for i in [1, 2]:\n",
+    "    #     # print(sensi_test.shape, y_pred.shape)\n",
+    "    #     idx = sensi==i\n",
+    "    #     expect_by_a[i]=  y_pred[idx].mean().item()\n",
+    "    # print(expect_by_a)\n",
+    "    # vanilla_gap_dp = np.abs(expect_by_a[1] - expect_by_a[2])\n",
+    "    # # print(\"gap: \",vanilla_gap_dp)\n",
+    "\n",
+    "    expect_by_a_y = {}\n",
+    "    expect_by_a_y_list = []\n",
+    "    for i in [1, 2]:\n",
+    "        expect_by_a_y[i]={}\n",
+    "        for j in [0, 1]:\n",
+    "            idx= (sensi == i) & (y == j)\n",
+    "            expc = y_pred[idx].mean().item()\n",
+    "            expect_by_a_y[i][j] =  expc\n",
+    "            expect_by_a_y_list.append(expc)\n",
+    "    # print(expect_by_a_y)\n",
+    "    vanilla_gap_eo = np.max(expect_by_a_y_list)- np.min(expect_by_a_y_list)\n",
+    "    print(\"gap: \", vanilla_gap_eo)"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Load data"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 158,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# # Load dataset \n",
+    "# data = fetch_acs_income(as_frame=False,states=[\"CA\"])\n",
+    "# sex = data.data[:,data['feature_names'].index('SEX')]\n",
+    "# X = data.data\n",
+    "# y_true = (data.target > 50000) * 1\n",
+    "# X = preprocessing.normalize(X, norm='l2')\n",
+    "\n",
+    "# device = 'cuda:0'\n",
+    "\n",
+    "# num_train_points = 1000\n",
+    "# num_test_points = 1000\n",
+    "\n",
+    "\n",
+    "# num_fair_train_points = 10000\n",
+    "# num_population_points = 30000\n",
+    "\n",
+    "# train_index = np.random.choice(X.shape[0], num_train_points, replace=False)\n",
+    "# test_index = np.random.choice(X.shape[0], num_test_points, replace=False)\n",
+    "# fair_train_index = np.random.choice(X.shape[0], num_fair_train_points, replace=False)\n",
+    "# population_index = np.random.choice(X.shape[0], num_population_points, replace=False)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 205,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "device = 'cuda:0'\n",
+    "num_train_points = 1000\n",
+    "num_test_points = 1000\n",
+    "num_population_points = 30000\n",
+    "X_train,y_train, g_train = get_data(num_train_points)\n",
+    "X_test ,y_test, g_test = get_data(num_test_points)\n",
+    "X_population, y_population, g_population = get_data(num_population_points)\n",
+    "X_train = torch.from_numpy(X_train).float()\n",
+    "X_test = torch.from_numpy(X_test).float()\n",
+    "y_train = torch.from_numpy(y_train).float()\n",
+    "y_test = torch.from_numpy(y_test).float()\n",
+    "sensi_train = torch.from_numpy(g_train).float()\n",
+    "sensi_test = torch.from_numpy(g_test).float()\n",
+    "# create the target model's dataset\n",
+    "g_train  = y_train+ sensi_train*2\n",
+    "g_test  = y_test+ sensi_test*2\n",
+    "\n",
+    "\n",
+    "X_population = torch.from_numpy(X_population).float()\n",
+    "y_population = torch.from_numpy(y_population).float()\n",
+    "sensi_population = torch.from_numpy(g_population).float()\n",
+    "g_population = y_population+ sensi_population*2\n",
+    "\n",
+    "\n",
+    "\n",
+    "# Create TensorDatasets\n",
+    "train_dataset = TensorDataset(X_train, y_train, sensi_train)\n",
+    "test_dataset = TensorDataset(X_test, y_test, sensi_test)\n",
+    "\n",
+    "# Create DataLoaders\n",
+    "train_loader = DataLoader(train_dataset, batch_size=300, shuffle=True)\n",
+    "test_loader = DataLoader(test_dataset, batch_size=1000, shuffle=False)\n",
+    "# X = np.concatenate((X_train, X_test, X_fair_train, X_population), axis=0)\n",
+    "# y_true = np.concatenate((y_train, y_test, y_fair_train, y_population), axis=0)\n",
+    "# sex = np.concatenate((g_train, g_test, g_fair_train, g_population), axis=0)\n",
+    "\n",
+    "# train_index = np.arange(num_train_points)\n",
+    "# test_index = np.arange(num_train_points, num_train_points+num_test_points)\n",
+    "# fair_train_index = np.arange(num_train_points+num_test_points, num_train_points+num_test_points+num_fair_train_points)\n",
+    "# population_index = np.arange(num_train_points+num_test_points+num_fair_train_points, num_train_points+num_test_points+num_fair_train_points+num_population_points)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 235,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Convert the data to tensors\n",
+    "num_fair_train_points = 10000\n",
+    "X_fair_train, y_fair_train, g_fair_train = get_data(num_fair_train_points)\n",
+    "X_fair_train = torch.from_numpy(X_fair_train).float()\n",
+    "y_fair_train = torch.from_numpy(y_fair_train).float()\n",
+    "sensi_fair = torch.from_numpy(g_fair_train).float()\n",
+    "g_fair_train = y_fair_train+ sensi_fair*2\n",
+    "\n",
+    "fair_train_dataset = TensorDataset(X_fair_train, y_fair_train, sensi_fair)\n",
+    "\n",
+    "fair_train_loader =  DataLoader(fair_train_dataset, batch_size=len(fair_train_dataset), shuffle=False)\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 236,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "num_epochs=1000"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 237,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def train(input_shape, alpha, coff, device, train_loader,X_train, y_train, X_test, y_test, num_epochs=1000,fair_train_loader=None):\n",
+    "    model = Model(input_shape, 1024, 1)\n",
+    "    if coff!=0:\n",
+    "        dp_loss = EqualiedOddsLoss(sensitive_classes=[1, 2], alpha=alpha)\n",
+    "    optimizer = optim.AdamW(model.parameters(), lr=0.01)\n",
+    "    criterion = nn.BCEWithLogitsLoss()\n",
+    "    model.to(device)\n",
+    "    for name, param in model.named_parameters():\n",
+    "        if 'weight' in name:\n",
+    "            nn.init.xavier_normal_(param)\n",
+    "    \n",
+    "    model.train()\n",
+    "    for epoch in range(num_epochs):\n",
+    "        for i, (x, y, s) in enumerate(train_loader):\n",
+    "            lossfair = 0\n",
+    "            optimizer.zero_grad()  \n",
+    "            x, y, s = x.to(device), y.to(device), s.to(device)\n",
+    "            logit = model(x)\n",
+    "            loss = criterion(logit.view(-1), y)\n",
+    "            if coff!=0:\n",
+    "                if fair_train_loader is not None:\n",
+    "                    for (x_f, y_f, s_f) in fair_train_loader:\n",
+    "                        # print(x_f.shape, y_f.shape, s_f.shape)\n",
+    "                        x_f, y_f, s_f = x_f.to(device), y_f.to(device), s_f.to(device)\n",
+    "                        logit_f = model(x_f)\n",
+    "                        lossfair += dp_loss(x_f, logit_f, s_f, y_f)\n",
+    "                else:\n",
+    "                    lossfair = dp_loss(x, logit, s, y)\n",
+    "                if torch.isnan(lossfair):\n",
+    "                    loss = loss\n",
+    "                else:\n",
+    "                    loss = loss + lossfair\n",
+    "            \n",
+    "            loss.backward()\n",
+    "            optimizer.step()\n",
+    "            # Print progress\n",
+    "            if (i+1) % 10 == 0:\n",
+    "                print ('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}'\n",
+    "                        .format(epoch+1, num_epochs, i+1, len(train_loader), loss.item()))\n",
+    "\n",
+    "    model.to('cpu')\n",
+    "    return model\n",
+    "\n",
+    "\n",
+    "def inference(model,X,y,sensi):\n",
+    "    y_pred = (torch.sigmoid(model(X)).view(-1) > 0.5 ).float()\n",
+    "\n",
+    "    expect_by_a={}\n",
+    "\n",
+    "    # for i in [1, 2]:\n",
+    "    #     # print(sensi_test.shape, y_pred.shape)\n",
+    "    #     idx = sensi==i\n",
+    "    #     expect_by_a[i]=  y_pred[idx].mean().item()\n",
+    "    # print(expect_by_a)\n",
+    "    # vanilla_gap_dp = np.abs(expect_by_a[1] - expect_by_a[2])\n",
+    "    # # print(\"gap: \",vanilla_gap_dp)\n",
+    "\n",
+    "    expect_by_a_y = {}\n",
+    "    expect_by_a_y_list = []\n",
+    "    for i in [1, 2]:\n",
+    "        expect_by_a_y[i]={}\n",
+    "        for j in [0, 1]:\n",
+    "            idx= (sensi == i) & (y == j)\n",
+    "            expc = y_pred[idx].mean().item()\n",
+    "            expect_by_a_y[i][j] =  expc\n",
+    "            expect_by_a_y_list.append(expc)\n",
+    "    # print(expect_by_a_y)\n",
+    "    vanilla_gap_eo = np.max(expect_by_a_y_list)- np.min(expect_by_a_y_list)\n",
+    "    acc = ((torch.sigmoid(model(X)).view(-1) > 0.5 ).float()  == y ).float().mean().float().item()\n",
+    "    # print(\"acc: \",round(acc,3))\n",
+    "    \n",
+    "    # print(\"gap: \", round(vanilla_gap_eo,3))\n",
+    "    return round(acc,3), round(vanilla_gap_eo,3)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 238,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "fair_model2 = train(X_train.shape[1], 50, 1, device, train_loader, X_train, y_train, X_test, y_test,num_epochs=num_epochs,fair_train_loader=fair_train_loader)\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# model = train(X_train.shape[1], 0, 0, device, train_loader, X_train, y_train, X_test, y_test,num_epochs=num_epochs,fair_train_loader=None)\n",
+    "# fair_model = train(X_train.shape[1], 50, 1, device, train_loader, X_train, y_train, X_test, y_test,num_epochs=num_epochs,fair_train_loader=None)\n",
+    "# fair_model2 = train(X_train.shape[1], 50, 1, device, train_loader, X_train, y_train, X_test, y_test,num_epochs=num_epochs,fair_train_loader=fair_train_loader)\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "un_test_acc, un_test_gap = inference(model,X_test,y_test, sensi_test)\n",
+    "fair_test_acc, fair_test_gap = inference(fair_model,X_test,y_test, sensi_test)\n",
+    "fair_test_acc2, fair_test_gap2 = inference(fair_model2,X_test,y_test, sensi_test)\n",
+    "\n",
+    "un_train_acc, un_train_gap = inference(model,X_train,y_train, sensi_train)\n",
+    "fair_train_acc, fair_train_gap = inference(fair_model,X_train,y_train, sensi_train)\n",
+    "fair_train_acc2, fair_train_gap2 = inference(fair_model2,X_train,y_train, sensi_train)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "0.755 | 0.641 | 0.761 | 0.405 |\n",
+      "0.58 | 0.58 | 0.0 | 0.0 |\n",
+      "0.688 | 0.623 | 0.594 | 0.328 |\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(un_train_acc, '|',un_test_acc, '|',un_train_gap, '|',un_test_gap,'|')\n",
+    "print(fair_train_acc, '|',fair_test_acc, '|',fair_train_gap, '|',fair_test_gap,'|')\n",
+    "print(fair_train_acc2, '|',fair_test_acc2, '|',fair_train_gap2, '|',fair_test_gap2,'|')"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# attack fair models and models\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "0 | 0.75 | 0.55 | 0.7\n",
+      "1 | 0.531 | 0.519 | 0.556\n",
+      "2 | 0.605 | 0.509 | 0.556\n",
+      "3 | 0.562 | 0.512 | 0.541\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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",
+      "text/plain": [
+       "<Figure size 1200x300 with 4 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "# create the target model's dataset\n",
+    "train_ds = {'x': X_train, 'y': y_train.reshape(-1,1),'g':sensi_train}\n",
+    "test_ds = {'x': X_test, 'y': y_test.reshape(-1,1), 'g':sensi_test}\n",
+    "population_ds = {'x': X_population, 'y': y_population.reshape(-1,1), 'g': sensi_population}\n",
+    "\n",
+    "p_results = privacy_evaluation(model,train_ds, test_ds, population_ds, g_train, g_test, g_population)\n",
+    "p_fair_results = privacy_evaluation(fair_model, train_ds, test_ds, population_ds, g_train, g_test, g_population)\n",
+    "p_fair_results_2 = privacy_evaluation(fair_model2, train_ds, test_ds, population_ds, g_train, g_test, g_population)\n",
+    "\n",
+    "\n",
+    "figs, axes = plt.subplots(1,4, figsize=(12,3), sharey=True, sharex=True)\n",
+    "\n",
+    "# group = np.unique(g_train)\n",
+    "for idx, group in enumerate(np.unique(g_train)):\n",
+    "    tpr = [np.mean(p_results[idx]['p'][p_results[idx]['mem']==1]<i) for i in np.linspace(0,1,100)]\n",
+    "    fpr = [np.mean(p_results[idx]['p'][p_results[idx]['mem']==0]<i) for i in np.linspace(0,1,100)]\n",
+    "\n",
+    "    fair_tpr = [np.mean(p_fair_results[idx]['p'][p_fair_results[idx]['mem']==1]<i) for i in np.linspace(0,1,100)]\n",
+    "    fair_fpr = [np.mean(p_fair_results[idx]['p'][p_fair_results[idx]['mem']==0]<i) for i in np.linspace(0,1,100)]\n",
+    "\n",
+    "    fair_tpr2 = [np.mean(p_fair_results_2[idx]['p'][p_fair_results_2[idx]['mem']==1]<i) for i in np.linspace(0,1,100)]\n",
+    "    fair_fpr2 = [np.mean(p_fair_results_2[idx]['p'][p_fair_results_2[idx]['mem']==0]<i) for i in np.linspace(0,1,100)]\n",
+    "\n",
+    "\n",
+    "    roc = np.trapz(tpr, fpr)\n",
+    "    fair_roc = np.trapz(fair_tpr, fair_fpr)\n",
+    "    print(idx, '|', round(max(np.array(tpr) + (1-np.array(fpr)))/2,3), '|',round(max(np.array(fair_tpr) + (1-np.array(fair_fpr)))/2,3), '|',round(max(np.array(fair_tpr2) + (1-np.array(fair_fpr2)))/2,3))\n",
+    "    axes[idx].plot([0, 1], [0, 1], 'k--', label='Random Guess', color='grey')\n",
+    "    axes[idx].plot(fpr, tpr, label=f'Unfair-ROC:{roc:.3f}', color='blue')\n",
+    "    axes[idx].plot(fair_fpr, fair_tpr, label=f'Fair-ROC:{fair_roc:.3f}', ls='--', color='red')\n",
+    "    axes[idx].plot(fair_fpr2, fair_tpr2, label=f'Our Fair-ROC:{fair_roc:.3f}', ls='--', color='green')\n",
+    "    axes[idx].set_xlabel('False Positive Rate')\n",
+    "    axes[idx].set_title(f'Subgroup {idx}')\n",
+    "    axes[idx].legend()\n",
+    "axes[0].set_ylabel('True Positive Rate')\n",
+    "plt.tight_layout()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "privacy_meter_test",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.9.16 | packaged by conda-forge | (main, Feb  1 2023, 21:39:03) \n[GCC 11.3.0]"
+  },
+  "orig_nbformat": 4,
+  "vscode": {
+   "interpreter": {
+    "hash": "af48e0a30d2a0b619bf296aea7d7271ba14c9beb98b0928b3e23c82f12ae949a"
+   }
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/advanced/fair_pytorch_reference.ipynb b/advanced/fair_pytorch_reference.ipynb
new file mode 100644
index 0000000..b5abfb4
--- /dev/null
+++ b/advanced/fair_pytorch_reference.ipynb
@@ -0,0 +1,551 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import numpy as np\n",
+    "from fairlearn.datasets import fetch_acs_income\n",
+    "from sklearn import preprocessing\n",
+    "from fairlearn.metrics import MetricFrame\n",
+    "from fairlearn.metrics import equalized_odds_difference\n",
+    "import numpy as np\n",
+    "from privacy_meter.audit import Audit, MetricEnum\n",
+    "from privacy_meter.dataset import Dataset\n",
+    "from privacy_meter.information_source import InformationSource\n",
+    "\n",
+    "from privacy_meter import audit_report\n",
+    "from privacy_meter.audit_report import *\n",
+    "\n",
+    "import keras as keras\n",
+    "import tensorflow as tf\n",
+    "import matplotlib.pyplot as plt\n",
+    "# load dataset\n",
+    "import pandas as pd\n",
+    "from fairlearn.reductions import EqualizedOdds\n",
+    "import warnings\n",
+    "warnings.filterwarnings('ignore')\n",
+    "\n",
+    "from fairlearn.metrics import MetricFrame\n",
+    "from sklearn.metrics import accuracy_score\n",
+    "from sklearn.tree import DecisionTreeClassifier\n",
+    "from privacy_meter.audit import Audit, MetricEnum\n",
+    "from privacy_meter.dataset import Dataset\n",
+    "from privacy_meter.information_source import InformationSource\n",
+    "from privacy_meter.model import Fairlearn_Model, Sklearn_Model\n",
+    "import os\n",
+    "from torch.utils.data import TensorDataset, DataLoader\n",
+    "\n",
+    "from fairtorch import ConstraintLoss, DemographicParityLoss, EqualiedOddsLoss\n",
+    "import random\n",
+    "import numpy as np\n",
+    "import torch\n",
+    "from torch import nn, optim\n",
+    "from torch.utils.data import DataLoader, Dataset"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 38,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from privacy_meter.model import PytorchModelTensor\n",
+    "from privacy_meter.dataset import Dataset\n",
+    "import scipy\n",
+    "def compute_p_value( target_value, observed_distribution):\n",
+    "    return scipy.stats.percentileofscore(observed_distribution, target_value)/100\n",
+    "\n",
+    "# import copy\n",
+    "import time\n",
+    "def privacy_evaluation(target_model, train_ds, test_ds, population_ds, g_train, g_test, g_population):\n",
+    "    target_model = PytorchModelTensor(target_model, nn.BCEWithLogitsLoss(reduction='none'))\n",
+    "    target_dataset = Dataset(\n",
+    "        data_dict={'train': train_ds, 'test': test_ds},\n",
+    "        default_input='x', default_output='y', default_group='g'\n",
+    "    )\n",
+    "    reference_dataset = Dataset(\n",
+    "    data_dict={'train': population_ds},\n",
+    "    default_input='x', default_output='y', default_group='g'\n",
+    "    )\n",
+    "    target_info_source = InformationSource(\n",
+    "    models=[target_model], \n",
+    "        datasets=[target_dataset]\n",
+    "    )\n",
+    "\n",
+    "    reference_info_source = InformationSource(\n",
+    "        models=[target_model],\n",
+    "        datasets=[reference_dataset]\n",
+    "    )\n",
+    "    audit_obj = Audit(\n",
+    "    metrics=MetricEnum.POPULATION,\n",
+    "    inference_game_type=InferenceGame.PRIVACY_LOSS_MODEL,\n",
+    "    target_info_sources=target_info_source,\n",
+    "    reference_info_sources=reference_info_source,\n",
+    "    logs_directory_names='log_'+str(time.time())\n",
+    "    )\n",
+    "    audit_obj.prepare()\n",
+    "\n",
+    "    train_signal = audit_obj.metric_objects[0].member_signals\n",
+    "    test_signal = audit_obj.metric_objects[0].non_member_signals\n",
+    "    pop_signal = audit_obj.metric_objects[0].reference_signals\n",
+    "    \n",
+    "\n",
+    "    p_results = {}\n",
+    "    for idx, g in enumerate(torch.unique(g_train)):\n",
+    "        un_pop = pop_signal[g_population==g]\n",
+    "        p_train = compute_p_value(train_signal[g_train==g], un_pop)\n",
+    "        p_test = compute_p_value(test_signal[g_test==g], un_pop)\n",
+    "        p_results[idx] = {}\n",
+    "        p_results[idx]['p'] = np.concatenate([p_train, p_test])\n",
+    "        p_results[idx]['mem'] = np.concatenate([np.ones(len(p_train)), np.zeros(len(p_test))])\n",
+    "        \n",
+    "    return p_results\n",
+    "        \n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def seed_everything(seed):\n",
+    "    random.seed(seed)\n",
+    "    os.environ[\"PYTHONHASHSEED\"] = str(seed)\n",
+    "    np.random.seed(seed)\n",
+    "    torch.manual_seed(seed)\n",
+    "    torch.cuda.manual_seed(seed)\n",
+    "    torch.backends.cudnn.deterministic = True\n",
+    "\n",
+    "\n",
+    "seed_everything(2020)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "\n",
+    "class Model(nn.Module):\n",
+    "    def __init__(self, input_dim, hidden_dim, output_dim):\n",
+    "        super(Model, self).__init__()\n",
+    "        self.fc1 = nn.Linear(input_dim, hidden_dim)\n",
+    "        self.relu1 = nn.ReLU()\n",
+    "        self.fc2 = nn.Linear(hidden_dim, hidden_dim)\n",
+    "        self.relu2 = nn.ReLU()\n",
+    "        self.fc3 = nn.Linear(hidden_dim, output_dim)\n",
+    "\n",
+    "    def forward(self, x):\n",
+    "        out = self.fc1(x)\n",
+    "        out = self.relu1(out)\n",
+    "        out = self.fc2(out)\n",
+    "        out = self.relu2(out)\n",
+    "        out = self.fc3(out)\n",
+    "        return out\n",
+    "    \n",
+    "def get_data(N):\n",
+    "    p00 = 0.02\n",
+    "    p10 = 0.4\n",
+    "    p11 = 0.4\n",
+    "    p01 = 0.18\n",
+    "\n",
+    "    X00 = np.random.multivariate_normal([0, -1], [[7, 1], [1, 7]], int(N*p00))\n",
+    "    X01 = np.random.multivariate_normal([-5, 0], [[5, 1], [1, 5]], int(N*p01))\n",
+    "    X10 = np.random.multivariate_normal([1, 2], [[5, 2], [2, 5]], int(N*p10))\n",
+    "    X11 = np.random.multivariate_normal([2, 3], [[10, 1], [1, 4]], int(N*p11))\n",
+    "    X = np.concatenate((X00, X01, X10, X11), axis=0)\n",
+    "    y_true = np.concatenate((np.zeros(int(N*p00)), np.ones(int(N*p01)), np.zeros(int(N*p10)), np.ones(int(N*p11))), axis=0)\n",
+    "    sex = np.concatenate((np.ones(int(N*p00)), np.ones(int(N*p01)), np.full(int(N*p10), 2), np.full(int(N*p11), 2)), axis=0)\n",
+    "    return X, y_true, sex\n",
+    "\n",
+    "def inference(model,X,y,sensi):\n",
+    "    y_pred = (torch.sigmoid(model(X)).view(-1) > 0.5 ).float()\n",
+    "\n",
+    "    expect_by_a={}\n",
+    "\n",
+    "    # for i in [1, 2]:\n",
+    "    #     # print(sensi_test.shape, y_pred.shape)\n",
+    "    #     idx = sensi==i\n",
+    "    #     expect_by_a[i]=  y_pred[idx].mean().item()\n",
+    "    # print(expect_by_a)\n",
+    "    # vanilla_gap_dp = np.abs(expect_by_a[1] - expect_by_a[2])\n",
+    "    # # print(\"gap: \",vanilla_gap_dp)\n",
+    "\n",
+    "    expect_by_a_y = {}\n",
+    "    expect_by_a_y_list = []\n",
+    "    for i in [1, 2]:\n",
+    "        expect_by_a_y[i]={}\n",
+    "        for j in [0, 1]:\n",
+    "            idx= (sensi == i) & (y == j)\n",
+    "            expc = y_pred[idx].mean().item()\n",
+    "            expect_by_a_y[i][j] =  expc\n",
+    "            expect_by_a_y_list.append(expc)\n",
+    "    # print(expect_by_a_y)\n",
+    "    vanilla_gap_eo = np.max(expect_by_a_y_list)- np.min(expect_by_a_y_list)\n",
+    "    print(\"gap: \", vanilla_gap_eo)"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Load data"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# # Load dataset \n",
+    "# data = fetch_acs_income(as_frame=False,states=[\"CA\"])\n",
+    "# sex = data.data[:,data['feature_names'].index('SEX')]\n",
+    "# X = data.data\n",
+    "# y_true = (data.target > 50000) * 1\n",
+    "# X = preprocessing.normalize(X, norm='l2')\n",
+    "\n",
+    "# device = 'cuda:0'\n",
+    "\n",
+    "# num_train_points = 1000\n",
+    "# num_test_points = 1000\n",
+    "\n",
+    "\n",
+    "# num_fair_train_points = 10000\n",
+    "# num_population_points = 30000\n",
+    "\n",
+    "# train_index = np.random.choice(X.shape[0], num_train_points, replace=False)\n",
+    "# test_index = np.random.choice(X.shape[0], num_test_points, replace=False)\n",
+    "# fair_train_index = np.random.choice(X.shape[0], num_fair_train_points, replace=False)\n",
+    "# population_index = np.random.choice(X.shape[0], num_population_points, replace=False)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "device = 'cuda:0'\n",
+    "num_train_points = 1000\n",
+    "num_test_points = 1000\n",
+    "num_population_points = 5000\n",
+    "X_train,y_train, g_train = get_data(num_train_points)\n",
+    "X_test ,y_test, g_test = get_data(num_test_points)\n",
+    "X_population, y_population, g_population = get_data(num_population_points)\n",
+    "X_train = torch.from_numpy(X_train).float()\n",
+    "X_test = torch.from_numpy(X_test).float()\n",
+    "y_train = torch.from_numpy(y_train).float()\n",
+    "y_test = torch.from_numpy(y_test).float()\n",
+    "sensi_train = torch.from_numpy(g_train).float()\n",
+    "sensi_test = torch.from_numpy(g_test).float()\n",
+    "# create the target model's dataset\n",
+    "g_train  = y_train+ sensi_train*2\n",
+    "g_test  = y_test+ sensi_test*2\n",
+    "\n",
+    "\n",
+    "X_population = torch.from_numpy(X_population).float()\n",
+    "y_population = torch.from_numpy(y_population).float()\n",
+    "sensi_population = torch.from_numpy(g_population).float()\n",
+    "g_population = y_population+ sensi_population*2\n",
+    "\n",
+    "\n",
+    "\n",
+    "# Create TensorDatasets\n",
+    "train_dataset = TensorDataset(X_train, y_train, sensi_train)\n",
+    "test_dataset = TensorDataset(X_test, y_test, sensi_test)\n",
+    "\n",
+    "# Create DataLoaders\n",
+    "train_loader = DataLoader(train_dataset, batch_size=300, shuffle=True)\n",
+    "test_loader = DataLoader(test_dataset, batch_size=1000, shuffle=False)\n",
+    "# X = np.concatenate((X_train, X_test, X_fair_train, X_population), axis=0)\n",
+    "# y_true = np.concatenate((y_train, y_test, y_fair_train, y_population), axis=0)\n",
+    "# sex = np.concatenate((g_train, g_test, g_fair_train, g_population), axis=0)\n",
+    "\n",
+    "# train_index = np.arange(num_train_points)\n",
+    "# test_index = np.arange(num_train_points, num_train_points+num_test_points)\n",
+    "# fair_train_index = np.arange(num_train_points+num_test_points, num_train_points+num_test_points+num_fair_train_points)\n",
+    "# population_index = np.arange(num_train_points+num_test_points+num_fair_train_points, num_train_points+num_test_points+num_fair_train_points+num_population_points)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Convert the data to tensors\n",
+    "num_fair_train_points = 1000\n",
+    "X_fair_train, y_fair_train, g_fair_train = get_data(num_fair_train_points)\n",
+    "X_fair_train = torch.from_numpy(X_fair_train).float()\n",
+    "y_fair_train = torch.from_numpy(y_fair_train).float()\n",
+    "sensi_fair = torch.from_numpy(g_fair_train).float()\n",
+    "g_fair_train = y_fair_train+ sensi_fair*2\n",
+    "\n",
+    "fair_train_dataset = TensorDataset(X_fair_train, y_fair_train, sensi_fair)\n",
+    "\n",
+    "fair_train_loader =  DataLoader(fair_train_dataset, batch_size=len(fair_train_dataset), shuffle=False)\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "num_epochs=1000"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 31,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def train(input_shape, alpha, coff, device, train_loader,X_train, y_train, X_test, y_test, num_epochs=1000,fair_train_loader=None):\n",
+    "    model = Model(input_shape, 1024, 1)\n",
+    "    if coff!=0:\n",
+    "        dp_loss = EqualiedOddsLoss(sensitive_classes=[1, 2], alpha=alpha)\n",
+    "    optimizer = optim.AdamW(model.parameters(), lr=0.01)\n",
+    "    criterion = nn.BCEWithLogitsLoss()\n",
+    "    model.to(device)\n",
+    "    for name, param in model.named_parameters():\n",
+    "        if 'weight' in name:\n",
+    "            nn.init.xavier_normal_(param)\n",
+    "    \n",
+    "    model.train()\n",
+    "    for epoch in range(num_epochs):\n",
+    "        for i, (x, y, s) in enumerate(train_loader):\n",
+    "            lossfair = 0\n",
+    "            optimizer.zero_grad()  \n",
+    "            x, y, s = x.to(device), y.to(device), s.to(device)\n",
+    "            logit = model(x)\n",
+    "            loss = criterion(logit.view(-1), y)\n",
+    "            if coff!=0:\n",
+    "                if fair_train_loader is not None:\n",
+    "                    for (x_f, y_f, s_f) in fair_train_loader:\n",
+    "                        # print(x_f.shape, y_f.shape, s_f.shape)\n",
+    "                        x_f, y_f, s_f = x_f.to(device), y_f.to(device), s_f.to(device)\n",
+    "                        logit_f = model(x_f)\n",
+    "                        lossfair += dp_loss(x_f, logit_f, s_f, y_f)\n",
+    "                else:\n",
+    "                    lossfair = dp_loss(x, logit, s, y)\n",
+    "                if torch.isnan(lossfair):\n",
+    "                    loss = loss\n",
+    "                else:\n",
+    "                    loss = loss + lossfair\n",
+    "            \n",
+    "            loss.backward()\n",
+    "            optimizer.step()\n",
+    "            # Print progress\n",
+    "            if (i+1) % 10 == 0:\n",
+    "                print ('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}'\n",
+    "                        .format(epoch+1, num_epochs, i+1, len(train_loader), loss.item()))\n",
+    "\n",
+    "    model.to('cpu')\n",
+    "    return model\n",
+    "\n",
+    "\n",
+    "def inference(model,X,y,sensi):\n",
+    "    y_pred = (torch.sigmoid(model(X)).view(-1) > 0.5 ).float()\n",
+    "\n",
+    "    expect_by_a={}\n",
+    "\n",
+    "    # for i in [1, 2]:\n",
+    "    #     # print(sensi_test.shape, y_pred.shape)\n",
+    "    #     idx = sensi==i\n",
+    "    #     expect_by_a[i]=  y_pred[idx].mean().item()\n",
+    "    # print(expect_by_a)\n",
+    "    # vanilla_gap_dp = np.abs(expect_by_a[1] - expect_by_a[2])\n",
+    "    # # print(\"gap: \",vanilla_gap_dp)\n",
+    "\n",
+    "    expect_by_a_y = {}\n",
+    "    expect_by_a_y_list = []\n",
+    "    for i in [1, 2]:\n",
+    "        expect_by_a_y[i]={}\n",
+    "        for j in [0, 1]:\n",
+    "            idx= (sensi == i) & (y == j)\n",
+    "            expc = y_pred[idx].mean().item()\n",
+    "            expect_by_a_y[i][j] =  expc\n",
+    "            expect_by_a_y_list.append(expc)\n",
+    "    # print(expect_by_a_y)\n",
+    "    vanilla_gap_eo = np.max(expect_by_a_y_list)- np.min(expect_by_a_y_list)\n",
+    "    acc = ((torch.sigmoid(model(X)).view(-1) > 0.5 ).float()  == y ).float().mean().float().item()\n",
+    "    # print(\"acc: \",round(acc,3))\n",
+    "    \n",
+    "    # print(\"gap: \", round(vanilla_gap_eo,3))\n",
+    "    return round(acc,3), round(vanilla_gap_eo,3)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 32,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# fair_model2 = train(X_train.shape[1], 50, 1, device, train_loader, X_train, y_train, X_test, y_test,num_epochs=num_epochs,fair_train_loader=fair_train_loader)\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "model = train(X_train.shape[1], 0, 0, device, train_loader, X_train, y_train, X_test, y_test,num_epochs=num_epochs,fair_train_loader=None)\n",
+    "fair_model = train(X_train.shape[1], 50, 1, device, train_loader, X_train, y_train, X_test, y_test,num_epochs=num_epochs,fair_train_loader=None)\n",
+    "fair_model2 = train(X_train.shape[1], 50, 1, device, train_loader, X_train, y_train, X_test, y_test,num_epochs=num_epochs,fair_train_loader=fair_train_loader)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "un_test_acc, un_test_gap = inference(model,X_test,y_test, sensi_test)\n",
+    "fair_test_acc, fair_test_gap = inference(fair_model,X_test,y_test, sensi_test)\n",
+    "fair_test_acc2, fair_test_gap2 = inference(fair_model2,X_test,y_test, sensi_test)\n",
+    "\n",
+    "un_train_acc, un_train_gap = inference(model,X_train,y_train, sensi_train)\n",
+    "fair_train_acc, fair_train_gap = inference(fair_model,X_train,y_train, sensi_train)\n",
+    "fair_train_acc2, fair_train_gap2 = inference(fair_model2,X_train,y_train, sensi_train)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 36,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "0.8 | 0.649 | 0.632 | 0.489 |\n",
+      "0.58 | 0.58 | 0.0 | 0.0 |\n",
+      "0.702 | 0.62 | 0.433 | 0.452 |\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(un_train_acc, '|',un_test_acc, '|',un_train_gap, '|',un_test_gap,'|')\n",
+    "print(fair_train_acc, '|',fair_test_acc, '|',fair_train_gap, '|',fair_test_gap,'|')\n",
+    "print(fair_train_acc2, '|',fair_test_acc2, '|',fair_train_gap2, '|',fair_test_gap2,'|')"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# attack fair models and models\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 39,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# create the target model's dataset\n",
+    "train_ds = {'x': X_train, 'y': y_train.reshape(-1,1),'g':sensi_train}\n",
+    "test_ds = {'x': X_test, 'y': y_test.reshape(-1,1), 'g':sensi_test}\n",
+    "population_ds = {'x': X_population, 'y': y_population.reshape(-1,1), 'g': sensi_population}\n",
+    "\n",
+    "p_results = privacy_evaluation(model,train_ds, test_ds, population_ds, g_train, g_test, g_population)\n",
+    "p_fair_results = privacy_evaluation(fair_model, train_ds, test_ds, population_ds, g_train, g_test, g_population)\n",
+    "p_fair_results_2 = privacy_evaluation(fair_model2, train_ds, test_ds, population_ds, g_train, g_test, g_population)\n",
+    "\n",
+    "\n",
+    "figs, axes = plt.subplots(1,4, figsize=(12,3), sharey=True, sharex=True)\n",
+    "\n",
+    "# group = np.unique(g_train)\n",
+    "for idx, group in enumerate(np.unique(g_train)):\n",
+    "    tpr = [np.mean(p_results[idx]['p'][p_results[idx]['mem']==1]<i) for i in np.linspace(0,1,100)]\n",
+    "    fpr = [np.mean(p_results[idx]['p'][p_results[idx]['mem']==0]<i) for i in np.linspace(0,1,100)]\n",
+    "\n",
+    "    fair_tpr = [np.mean(p_fair_results[idx]['p'][p_fair_results[idx]['mem']==1]<i) for i in np.linspace(0,1,100)]\n",
+    "    fair_fpr = [np.mean(p_fair_results[idx]['p'][p_fair_results[idx]['mem']==0]<i) for i in np.linspace(0,1,100)]\n",
+    "\n",
+    "    fair_tpr2 = [np.mean(p_fair_results_2[idx]['p'][p_fair_results_2[idx]['mem']==1]<i) for i in np.linspace(0,1,100)]\n",
+    "    fair_fpr2 = [np.mean(p_fair_results_2[idx]['p'][p_fair_results_2[idx]['mem']==0]<i) for i in np.linspace(0,1,100)]\n",
+    "\n",
+    "\n",
+    "    roc = np.trapz(tpr, fpr)\n",
+    "    fair_roc = np.trapz(fair_tpr, fair_fpr)\n",
+    "    print(idx, '|', round(max(np.array(tpr) + (1-np.array(fpr)))/2,3), '|',round(max(np.array(fair_tpr) + (1-np.array(fair_fpr)))/2,3), '|',round(max(np.array(fair_tpr2) + (1-np.array(fair_fpr2)))/2,3))\n",
+    "    axes[idx].plot([0, 1], [0, 1], 'k--', label='Random Guess', color='grey')\n",
+    "    axes[idx].plot(fpr, tpr, label=f'Unfair-ROC:{roc:.3f}', color='blue')\n",
+    "    axes[idx].plot(fair_fpr, fair_tpr, label=f'Fair-ROC:{fair_roc:.3f}', ls='--', color='red')\n",
+    "    axes[idx].plot(fair_fpr2, fair_tpr2, label=f'Our Fair-ROC:{fair_roc:.3f}', ls='--', color='green')\n",
+    "    axes[idx].set_xlabel('False Positive Rate')\n",
+    "    axes[idx].set_title(f'Subgroup {idx}')\n",
+    "    axes[idx].legend()\n",
+    "axes[0].set_ylabel('True Positive Rate')\n",
+    "plt.tight_layout()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "privacy_meter_test",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.9.16 | packaged by conda-forge | (main, Feb  1 2023, 21:39:03) \n[GCC 11.3.0]"
+  },
+  "orig_nbformat": 4,
+  "vscode": {
+   "interpreter": {
+    "hash": "af48e0a30d2a0b619bf296aea7d7271ba14c9beb98b0928b3e23c82f12ae949a"
+   }
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/tutorials/hf_causal_language_models.ipynb b/advanced/hf_causal_language_models.ipynb
similarity index 99%
rename from tutorials/hf_causal_language_models.ipynb
rename to advanced/hf_causal_language_models.ipynb
index 3b29b91..42745c5 100644
--- a/tutorials/hf_causal_language_models.ipynb
+++ b/advanced/hf_causal_language_models.ipynb
@@ -16,10 +16,10 @@
    "source": [
     "<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
     "<td>\n",
-    "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/privacytrustlab/ml_privacy_meter/blob/master/tutorials/hf_causal_language_models.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
+    "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/privacytrustlab/ml_privacy_meter/blob/master/advanced/hf_causal_language_models.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
     "  </td>\n",
     "  <td>\n",
-    "    <a target=\"_blank\" href=\"https://github.com/privacytrustlab/ml_privacy_meter/blob/master/tutorials/hf_causal_language_models.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View GitHub</a>\n",
+    "    <a target=\"_blank\" href=\"https://github.com/privacytrustlab/ml_privacy_meter/blob/master/advanced/hf_causal_language_models.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View GitHub</a>\n",
     "  </td>\n",
     "</table>"
    ]
diff --git a/advanced/load_existing_signals.ipynb b/advanced/load_existing_signals.ipynb
new file mode 100644
index 0000000..a96ad51
--- /dev/null
+++ b/advanced/load_existing_signals.ipynb
@@ -0,0 +1,370 @@
+{
+ "cells": [
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Load Existing Signals\n",
+    "There are cases where you have trained models and already computed the signals. In this tutorial, we will show how Privacy meter can load the existing signals to perform the attacks"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 108,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from privacy_meter.audit_report import ROCCurveReport\n",
+    "from privacy_meter.constants import InferenceGame\n",
+    "from privacy_meter.information_source import InformationSource\n",
+    "from privacy_meter.audit import Audit, MetricEnum\n",
+    "import numpy as np"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Loading the signals for population attacks"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "For the population attack, the adversary needs to compute the signals on the members, non-members, and population data sampled from the same distribution. In this case, you need to provide three `npz` files with the name `PopulationMetric_target_member.npz`, `PopulationMetric_target_non_member.npz` and `PopulationMetric_reference.npz`. In this example, we provide the pre-computed signals in the `existing_signals/population` folder. The size should be `(number of models, number of samples)`, which is `(1, number of samples)` in this case."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 109,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Results are stored in: ['existing_signals/population/']\n"
+     ]
+    }
+   ],
+   "source": [
+    "# First, construct the dummy information source.\n",
+    "target_info_source = InformationSource(\n",
+    "    models=[],\n",
+    "    datasets=[]\n",
+    ")\n",
+    "\n",
+    "reference_info_source = InformationSource(\n",
+    "    models=[],\n",
+    "    datasets=[] \n",
+    ")\n",
+    "\n",
+    "audit_obj = Audit(\n",
+    "    metrics=MetricEnum.POPULATION,\n",
+    "    inference_game_type=InferenceGame.PRIVACY_LOSS_MODEL,\n",
+    "    target_info_sources=target_info_source,\n",
+    "    reference_info_sources=reference_info_source,\n",
+    "    logs_directory_names=\"existing_signals/population/\" # Indicate the folder where the signals are saved.\n",
+    ")\n",
+    "audit_obj.prepare() #Load the signals from the disk\n",
+    "audit_results = audit_obj.run()[0] # Run the attack\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 110,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Plot the results\n",
+    "from privacy_meter import audit_report\n",
+    "audit_report.REPORT_FILES_DIR = '../privacy_meter/report_files'"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 111,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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",
+      "text/plain": [
+       "<Figure size 640x480 with 1 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "AUC = 0.740\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "<Figure size 640x480 with 0 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "ROCCurveReport.generate_report(\n",
+    "    metric_result=audit_results,\n",
+    "    inference_game_type=InferenceGame.PRIVACY_LOSS_MODEL,\n",
+    "    show=True\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Loading the signals for reference attacks\n",
+    "For the reference attacks, the adversary needs to compute the signals for the members and non-members from the target model and compare them with the signals computed for the members and non-members from the reference models. Therefore, we need to have four signal files named `ReferenceMetric_target_member.npz`, `ReferenceMetric_target_non_member.npz`, `ReferenceMetric_reference_member.npz`, and `ReferenceMetric_reference_non_member.npz`. In this example, we provide the pre-computed signals in the `existing_signals/reference` folder. The shape of the array should be `(number of models, number of samples).` \n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 112,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Results are stored in: ['existing_signals/reference/']\n"
+     ]
+    }
+   ],
+   "source": [
+    "# First, construct the dummy information source.\n",
+    "target_info_source = InformationSource(\n",
+    "    models=[],\n",
+    "    datasets=[]\n",
+    ")\n",
+    "\n",
+    "reference_info_source = InformationSource(\n",
+    "    models=[],\n",
+    "    datasets=[] \n",
+    ")\n",
+    "\n",
+    "audit_obj = Audit(\n",
+    "    metrics=MetricEnum.REFERENCE,\n",
+    "    inference_game_type=InferenceGame.PRIVACY_LOSS_MODEL,\n",
+    "    target_info_sources=target_info_source,\n",
+    "    reference_info_sources=reference_info_source,\n",
+    "    logs_directory_names=\"existing_signals/reference/\" # Indicate the folder where the signals are saved.\n",
+    ")\n",
+    "audit_obj.prepare() #Load the signals from the disk\n",
+    "audit_results = audit_obj.run()[0] # Run the attack\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 113,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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",
+      "text/plain": [
+       "<Figure size 640x480 with 1 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "AUC = 0.754\n"
+     ]
+    },
+    {
+     "data": {
+      "text/plain": [
+       "<Figure size 640x480 with 0 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "# Plot the results\n",
+    "from privacy_meter import audit_report\n",
+    "audit_report.REPORT_FILES_DIR = '../privacy_meter/report_files'\n",
+    "ROCCurveReport.generate_report(\n",
+    "    metric_result=audit_results,\n",
+    "    inference_game_type=InferenceGame.PRIVACY_LOSS_MODEL,\n",
+    "    show=True\n",
+    ")"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Load the signals for online attacks\n",
+    "\n",
+    "In the online attacks, the adversary trains a set of models with the target point (In Models) and without the target point (Out Models) and then compute the signals based on the target model. There should be four files: `ReferenceMetric_target_member.npz`, `ReferenceMetric_target_non_member.npz`, `ReferenceMetric_reference_non_member_in.npz`, `ReferenceMetric_reference_non_member_out.npz`, `ReferenceMetric_reference_member_in.npz`, and `ReferenceMetric_reference_member_out.npz`. In this example, we provide the pre-computed signals in the `existing_signals/reference_online` folder.\n",
+    "\n",
+    "In `ReferenceMetric_reference_non_member_in,` the shape of the array should be `(number of samples, number of models, number of arguments).` If the adversary queries the model only based on the original data point, the `number of arguments` will be 1. On the other hand, if the adversary argues the target point and queries the model based on a set of arguments point, the `number of arguments` will reflect how many arguments the adversary computes on the target data."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 130,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from scipy.stats import norm\n",
+    "import matplotlib.pyplot as plt\n",
+    "from sklearn.metrics import auc, roc_curve\n",
+    "import copy\n",
+    "# This implementation is based on the lira attack implememtation: https://github.com/tensorflow/privacy/tree/master/research/mi_lira_2021\n",
+    "\n",
+    "in_member_signals = np.load('existing_signals/reference_online/ReferenceMetric_reference_member_in.npz', allow_pickle=True)['arr_0']\n",
+    "out_member_signals = np.load('existing_signals/reference_online/ReferenceMetric_reference_member_out.npz', allow_pickle=True)['arr_0']\n",
+    "in_non_member_signals = np.load('existing_signals/reference_online/ReferenceMetric_reference_non_member_in.npz', allow_pickle=True)['arr_0']\n",
+    "out_non_member_signals = np.load('existing_signals/reference_online/ReferenceMetric_reference_non_member_out.npz', allow_pickle=True)['arr_0']\n",
+    "\n",
+    "target_member_signals = np.load('existing_signals/reference_online/ReferenceMetric_target_member.npz', allow_pickle=True)['arr_0']\n",
+    "target_non_member_signals = np.load('existing_signals/reference_online/ReferenceMetric_target_non_member.npz', allow_pickle=True)['arr_0']\n",
+    "\n",
+    "in_signals = np.concatenate([in_member_signals, in_non_member_signals],axis=0)\n",
+    "out_signals = np.concatenate([out_member_signals, out_non_member_signals],axis=0)\n",
+    "target_signals = np.array([np.concatenate([target_member_signals, target_non_member_signals],axis=0)])\n",
+    "membership = np.array([np.concatenate([np.ones(len(target_member_signals)), np.zeros(len(target_non_member_signals))], axis=0)])\n",
+    "\n",
+    "# Fit the distributions\n",
+    "mean_in = np.median(in_signals, 1)\n",
+    "mean_out = np.median(out_signals, 1)\n",
+    "fix_variance = True # indicate whether to fix the variance or not\n",
+    "if fix_variance:\n",
+    "    std_in = np.std(in_signals)\n",
+    "    std_out = np.std(in_signals)\n",
+    "else:\n",
+    "    std_in = np.std(in_signals, 1)\n",
+    "    std_out = np.std(out_signals, 1)\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 131,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "prediction = []\n",
+    "answers = []\n",
+    "for ans, sc in zip(membership, target_signals):\n",
+    "    pr_in = -norm.logpdf(sc, mean_in, std_in + 1e-30)\n",
+    "    pr_out = -norm.logpdf(sc, mean_out, std_out + 1e-30)\n",
+    "    score = pr_in - pr_out\n",
+    "    prediction.extend(score.mean(1))\n",
+    "    answers.extend(ans)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 133,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "AUC 0.6843, Accuracy 0.6129, TPR@0.1%FPR of 0.0507\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkIAAAHHCAYAAABTMjf2AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/P9b71AAAACXBIWXMAAA9hAAAPYQGoP6dpAACUkUlEQVR4nOzdd3QU5dvG8e/upnfSQwiETiK9dwgdBMGCNGk/wIqiSBFpgghiAVQQbIioIE0s9CIdBKQjoZfQ0nvbbJn3j8i+RgIkkGQ2yf05h6M7OzN7LUuSKzPPPKNRFEVBCCGEEKIU0qodQAghhBBCLVKEhBBCCFFqSRESQgghRKklRUgIIYQQpZYUISGEEEKUWlKEhBBCCFFqSRESQgghRKklRUgIIYQQpZYUISGEEEKUWlKEhBBCCFFqSRESQjzQkiVL0Gg0lj82NjYEBgYyZMgQbt68mes2iqLw/fff07p1azw8PHBycqJWrVpMnz6dtLS0e77W2rVr6dq1K97e3tjZ2VG2bFmeffZZ/vjjj8J6e0KIUkwj9xoTQjzIkiVLGDp0KNOnT6dixYpkZmby559/smTJEoKDgzl9+jQODg6W9U0mE/3792flypW0atWKp556CicnJ/bs2cOyZcsIDQ1l27Zt+Pn5WbZRFIX//e9/LFmyhHr16vHMM8/g7+/P7du3Wbt2LUeOHGHfvn00b95cjb8CIURJpQghxAN8++23CqAcPnw4x/Lx48crgLJixYocy2fOnKkAypgxY+7a12+//aZotVqlS5cuOZZ/+OGHCqC8/vrritlsvmu7pUuXKgcPHiyAd/PwUlNTVX19IUTBk1NjQoiH1qpVKwAuXbpkWZaRkcGHH35ItWrVmDVr1l3b9OjRg8GDB7Np0yb+/PNPyzazZs2iRo0afPTRR2g0mru2GzhwII0bN75vHrPZzCeffEKtWrVwcHDAx8eHLl268NdffwFw9epVNBoNS5YsuWtbjUbDO++8Y3n8zjvvoNFoOHPmDP3796dMmTK0bNnSku/atWt37WPChAnY2dmRkJBgWXbw4EG6dOmCu7s7Tk5OtGnThn379t33fQghio4UISHEQ7t69SoAZcqUsSzbu3cvCQkJ9O/fHxsbm1y3GzRoEADr1q2zbBMfH0///v3R6XQPnWfYsGG8/vrrBAUFMXv2bN566y0cHBwsheth9O7dm/T0dGbOnMmIESN49tln0Wg0rFy58q51V65cSadOnSx/H3/88QetW7cmOTmZqVOnMnPmTBITE2nXrh2HDh166ExCiIKT+3cpIYTIRVJSErGxsWRmZnLw4EGmTZuGvb093bt3t6xz5swZAOrUqXPP/dx5Ljw8PMd/a9Wq9dDZduzYwZIlS3jttdf45JNPLMvffPNNlEcYClmnTh2WLVuWY1nTpk1ZsWIFY8eOtSw7fPgwly9fthxVUhSFF198kbCwMDZu3Gg5yvXCCy/w2GOPMWnSJLZs2fLQuYQQBUOOCAkh8qxDhw74+PgQFBTEM888g7OzM7/99hvlypWzrJOSkgKAq6vrPfdz57nk5OQc/73fNg+yZs0aNBoNU6dOveu53E615dWLL75417I+ffpw5MiRHKcEV6xYgb29PT179gTg+PHjXLhwgf79+xMXF0dsbCyxsbGkpaXRvn17du/ejdlsfuhcQoiCIUVICJFnCxYsYOvWraxevZpu3boRGxuLvb19jnXulJk7hSg3/y1Lbm5uD9zmQS5dukTZsmXx9PR86H3kpmLFinct6927N1qtlhUrVgDZR39WrVpF165dLe/lwoULAAwePBgfH58cf77++mv0ej1JSUkFmlUIkX9yakwIkWeNGzemYcOGAPTq1YuWLVvSv39/zp07h4uLCwAhISEAnDx5kl69euW6n5MnTwIQGhoKQI0aNQA4derUPbcpCPc6MmQyme65jaOj413LypYtS6tWrVi5ciVvv/02f/75JxEREcyePduyzp2jPR9++CF169bNdd93/s6EEOqRI0JCiIei0+mYNWsWt27dYv78+ZblLVu2xMPDg2XLlt2zYCxduhTAMraoZcuWlClThuXLl9+3lNxP5cqVuXXrFvHx8fdc584g5sTExBzLc7sC7EH69OnDiRMnOHfuHCtWrMDJyYkePXrkyAPZR7s6dOiQ6x9bW9t8v64QomBJERJCPLS2bdvSuHFj5s2bR2ZmJgBOTk6MGTOGc+fOMXHixLu2Wb9+PUuWLKFz5840bdrUss348eMJDw9n/PjxuQ5u/uGHH+57pdXTTz+NoihMmzbtrufu7M/NzQ1vb292796d4/nPP/8872/6X6+n0+lYvnw5q1atonv37jg7O1ueb9CgAZUrV+ajjz4iNTX1ru1jYmLy/ZpCiIInp8aEEI9k7Nix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vvmGYcOGAfDhhx/yySefMG/ePGrVqoWzszOvv/46WVk5j0j997SORqPBbDYXWM77vU5hvLZGo0FRlBzL7swiDpCamkqDBg348ccf79rWx8cHyD5C9Nprr7Fp0yZWrFjBpEmT2Lp1K02bNuWdd96hf//+rF+/no0bNzJ16lR++uknnnzyyUfKLUSpZtTDnjmw630g+xYYet/axLSfh8GzmsrhxB06rYZJj4ew5ugNXmlbBUe74jdjvgyWziMnO5t7/vnv9OAFse6j0mq1vP3220yaNImMjAwA9u3bR8+ePXnuueeoU6cOlSpV4vz58/nab0hICNevX+f27duWZX/++edd65w4cYK0tDTLsn379qHVavN9tOZ+KlWqhK2tLYcPH7YsS0pKuus9+fj45Mh74cIF0tPTLY/r16/PhQsX8PX1pUqVKjn+uLv//12Q69Wrx4QJE9i/fz81a9Zk2bJllueqVavGG2+8wZYtW3jqqaceOMhbCHEPZjOcWg2fNbSUoLTgjtzot4NbvTdICbICRyMS+P3ELcvjit7OjOlUvViWIJAiVKL17t0bnU7HggULgOyxK1u3bmX//v2Eh4fzwgsvEBUVla99dujQgWrVqjF48GBOnDjBnj17mDhxYo51BgwYgIODA4MHD+b06dPs2LGDV199lYEDB1pOixUEV1dXBg8ezNixY9mxYwd///03w4YNQ6vV5jg33a5dO+bPn8+xY8f466+/ePHFF3MceRowYADe3t707NmTPXv2cOXKFXbu3Mlrr73GjRs3uHLlChMmTODAgQNcu3aNLVu2cOHCBUJCQsjIyGDkyJHs3LmTa9eusW/fPg4fPpxjDJEQIg8UBW4dgzk1YM0wSIrAbONATNiHRHX7FoOnjL1Tm8mssGTfVcauOsmnf1zkXGSK2pEKhBShEszGxoaRI0fywQcfkJaWxqRJk6hfvz6dO3embdu2+Pv753smaK1Wy9q1a8nIyKBx48YMHz6c9957L8c6Tk5ObN68mfj4eBo1asQzzzxD+/btcwzcLihz5syhWbNmdO/enQ4dOtCiRQtCQkJyTCL58ccfExQURKtWrejfvz9jxozJMS7KycmJ3bt3U758eZ566ilCQkIYNmwYmZmZuLm54eTkxNmzZ3n66aepVq0azz//PK+88govvPACOp2OuLg4Bg0aRLVq1Xj22Wfp2rUr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",
+      "text/plain": [
+       "<Figure size 640x480 with 1 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "prediction = np.array(prediction)\n",
+    "answers = np.array(answers, dtype=bool)\n",
+    "fpr_list, tpr_list, _ = roc_curve(answers, -prediction)\n",
+    "acc = np.max(1 - (fpr_list + (1 - tpr_list)) / 2)\n",
+    "roc_auc = auc(fpr_list, tpr_list)\n",
+    "\n",
+    "low = tpr_list[np.where(fpr_list < 0.001)[0][-1]]\n",
+    "print(\"AUC %.4f, Accuracy %.4f, TPR@0.1%%FPR of %.4f\" % (roc_auc, acc, low))\n",
+    "range01 = np.linspace(0, 1)\n",
+    "plt.fill_between(fpr_list, tpr_list, alpha=0.15)\n",
+    "plt.plot(range01, range01, \"--\", label=\"Random guess\")\n",
+    "plt.plot(fpr_list, tpr_list, label=\"ROC curve\")\n",
+    "plt.xlim([0, 1])\n",
+    "plt.ylim([0, 1])\n",
+    "plt.grid()\n",
+    "plt.legend()\n",
+    "plt.xlabel(\"False positive rate (FPR)\")\n",
+    "plt.ylabel(\"True positive rate (TPR)\")\n",
+    "plt.title(\"ROC curve\")\n",
+    "plt.text(\n",
+    "    0.7,\n",
+    "    0.3,\n",
+    "    f\"AUC = {roc_auc:.03f}\",\n",
+    "    horizontalalignment=\"center\",\n",
+    "    verticalalignment=\"center\",\n",
+    "    bbox=dict(facecolor=\"white\", alpha=0.5),\n",
+    ")\n",
+    "plt.show()\n"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "privacy_meter_test",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.9.16 | packaged by conda-forge | (main, Feb  1 2023, 21:39:03) \n[GCC 11.3.0]"
+  },
+  "orig_nbformat": 4,
+  "vscode": {
+   "interpreter": {
+    "hash": "af48e0a30d2a0b619bf296aea7d7271ba14c9beb98b0928b3e23c82f12ae949a"
+   }
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/tutorials/openvino_models.ipynb b/advanced/openvino_models.ipynb
similarity index 97%
rename from tutorials/openvino_models.ipynb
rename to advanced/openvino_models.ipynb
index 6b2f46d..2313843 100644
--- a/tutorials/openvino_models.ipynb
+++ b/advanced/openvino_models.ipynb
@@ -25,10 +25,10 @@
    "source": [
     "<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
     "<td>\n",
-    "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/privacytrustlab/ml_privacy_meter/blob/master/tutorials/openvino_models.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
+    "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/privacytrustlab/ml_privacy_meter/blob/master/advanced/openvino_models.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
     "  </td>\n",
     "  <td>\n",
-    "    <a target=\"_blank\" href=\"https://github.com/privacytrustlab/ml_privacy_meter/blob/master/tutorials/openvino_models.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View GitHub</a>\n",
+    "    <a target=\"_blank\" href=\"https://github.com/privacytrustlab/ml_privacy_meter/blob/master/advanced/openvino_models.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View GitHub</a>\n",
     "  </td>\n",
     "</table>"
    ]
diff --git a/tutorials/population_metric.ipynb b/advanced/population_metric.ipynb
similarity index 99%
rename from tutorials/population_metric.ipynb
rename to advanced/population_metric.ipynb
index 21d39e6..1cadbaa 100644
--- a/tutorials/population_metric.ipynb
+++ b/advanced/population_metric.ipynb
@@ -27,10 +27,10 @@
    "source": [
     "<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
     "<td>\n",
-    "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/privacytrustlab/ml_privacy_meter/blob/master/tutorials/population_metric.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
+    "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/privacytrustlab/ml_privacy_meter/blob/master/advanced/population_metric.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
     "  </td>\n",
     "  <td>\n",
-    "    <a target=\"_blank\" href=\"https://github.com/privacytrustlab/ml_privacy_meter/blob/master/tutorials/population_metric.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View GitHub</a>\n",
+    "    <a target=\"_blank\" href=\"https://github.com/privacytrustlab/ml_privacy_meter/blob/master/advanced/population_metric.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View GitHub</a>\n",
     "  </td>\n",
     "</table>"
    ]
diff --git a/tutorials/reference_metric.ipynb b/advanced/reference_metric.ipynb
similarity index 99%
rename from tutorials/reference_metric.ipynb
rename to advanced/reference_metric.ipynb
index 82c377e..e8165ec 100644
--- a/tutorials/reference_metric.ipynb
+++ b/advanced/reference_metric.ipynb
@@ -39,10 +39,10 @@
    "source": [
     "<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
     "<td>\n",
-    "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/privacytrustlab/ml_privacy_meter/blob/master/tutorials/reference_metric.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
+    "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/privacytrustlab/ml_privacy_meter/blob/master/advanced/reference_metric.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
     "  </td>\n",
     "  <td>\n",
-    "    <a target=\"_blank\" href=\"https://github.com/privacytrustlab/ml_privacy_meter/blob/master/tutorials/reference_metric.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View GitHub</a>\n",
+    "    <a target=\"_blank\" href=\"https://github.com/privacytrustlab/ml_privacy_meter/blob/master/advanced/reference_metric.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View GitHub</a>\n",
     "  </td>\n",
     "</table>"
    ]
diff --git a/advanced/roc_curve.jpg b/advanced/roc_curve.jpg
new file mode 100644
index 0000000..e57a537
Binary files /dev/null and b/advanced/roc_curve.jpg differ
diff --git a/tutorials/shadow_metric.ipynb b/advanced/shadow_metric.ipynb
similarity index 99%
rename from tutorials/shadow_metric.ipynb
rename to advanced/shadow_metric.ipynb
index f5c7106..86eaa53 100644
--- a/tutorials/shadow_metric.ipynb
+++ b/advanced/shadow_metric.ipynb
@@ -44,10 +44,10 @@
    "source": [
     "<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
     "<td>\n",
-    "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/privacytrustlab/ml_privacy_meter/blob/master/tutorials/shadow_metric.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
+    "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/privacytrustlab/ml_privacy_meter/blob/master/advanced/shadow_metric.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
     "  </td>\n",
     "  <td>\n",
-    "    <a target=\"_blank\" href=\"https://github.com/privacytrustlab/ml_privacy_meter/blob/master/tutorials/shadow_metric.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View GitHub</a>\n",
+    "    <a target=\"_blank\" href=\"https://github.com/privacytrustlab/ml_privacy_meter/blob/master/advanced/shadow_metric.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View GitHub</a>\n",
     "  </td>\n",
     "</table>"
    ]
diff --git a/tutorials/white_box_attack.ipynb b/advanced/white_box_attack.ipynb
similarity index 99%
rename from tutorials/white_box_attack.ipynb
rename to advanced/white_box_attack.ipynb
index e3c5fe1..94ccfe3 100644
--- a/tutorials/white_box_attack.ipynb
+++ b/advanced/white_box_attack.ipynb
@@ -5,7 +5,7 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
-    "# Whitebox attack using privacy meter"
+    "# Whitebox attack using Privacy Meter"
    ]
   },
   {
@@ -17,7 +17,7 @@
     "\n",
     "In this tutorial we will see:\n",
     "\n",
-    "- How to use the privacy meter to audit model implemented on Pytorch\n",
+    "- How to use the Privacy Meter to audit model implemented on Pytorch\n",
     "- How to extract the white-box signal (i.e., gradient norm)\n",
     "- How to run membership inference attack based on white-box attack based on the population attack"
    ]
@@ -29,10 +29,10 @@
    "source": [
     "<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
     "<td>\n",
-    "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/privacytrustlab/ml_privacy_meter/blob/master/tutorials/white_box_attack.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
+    "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/privacytrustlab/ml_privacy_meter/blob/master/advanced/white_box_attack.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
     "  </td>\n",
     "  <td>\n",
-    "    <a target=\"_blank\" href=\"https://github.com/privacytrustlab/ml_privacy_meter/blob/master/tutorials/white_box_attack.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View GitHub</a>\n",
+    "    <a target=\"_blank\" href=\"https://github.com/privacytrustlab/ml_privacy_meter/blob/master/advanced/white_box_attack.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View GitHub</a>\n",
     "  </td>\n",
     "</table>"
    ]
@@ -551,7 +551,7 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "Results are stored in: ['/home/hongyan/Desktop/ml_privacy_test/ml_privacy_meter/tutorials/log_2023-02-10_13-51-49-000']\n"
+      "Results are stored in: ['/home/hongyan/Desktop/ml_privacy_test/ml_privacy_meter/advanced/log_2023-02-10_13-51-49-000']\n"
      ]
     }
    ],
@@ -589,7 +589,7 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "Results are stored in: ['/home/hongyan/Desktop/ml_privacy_test/ml_privacy_meter/tutorials/log_2023-02-10_13-51-51-000']\n"
+      "Results are stored in: ['/home/hongyan/Desktop/ml_privacy_test/ml_privacy_meter/advanced/log_2023-02-10_13-51-51-000']\n"
      ]
     }
    ],
diff --git a/basic/README.md b/basic/README.md
new file mode 100644
index 0000000..a8b307a
--- /dev/null
+++ b/basic/README.md
@@ -0,0 +1,74 @@
+# Privacy Meter - Basic Usage
+
+This folder contains the implementation of an end-to-end membership inference attack based on various attack games defined by [[Ye et al., 2022](https://arxiv.org/pdf/2111.09679.pdf)] and different attack algorithms. It is recommended that you perform privacy auditing using our automatic pipeline. By default, the audit provides a way to evaluate the privacy risks for models, algorithms, and data points using the CIFAR10 dataset. The training configurations can then be specified in the configuration YAML file. The overall pipeline is illustrated below. For a deeper understanding of various types of attacks or for information on how to extend the Privacy Meter to include other libraries, please refer to our [tutorials for advanced usage](../advanced) for more information.
+
+<p align="center" width="100%">
+    <img width="80%" src="docs/experiment_pipeline.png">
+</p>
+
+
+## Quickstart
+Run the following code for your first membership inference attack on CIFAR10 (we support various datasets, e.g., CIFAR100 and Purchase dataset, but the default example is based on CIFAR10).
+
+```
+python main.py --cf config_models_population.yaml
+```
+
+## Privacy Game
+
+In Ye et al., 2022, four different privacy games widely used in the literature are summarized. Users can specify which privacy game they want to run in the YAML configuration file by setting the `audit.privacy_game` to the following values:
+
+- `avg_privacy_loss_training_algo` - Game 3.1 in Ye et al., 2022
+  This privacy game defines how to audit the privacy risk for a training algorithm. An example configuration is provided in `config_algorithms.yaml`. The privacy risk for a training algorithm is the average privacy risk over records and the models trained by the algorithm, in the sense that the target datasets and the target models are randomly generated. The sample privacy risk report for auditing a training algorithm includes the aggregated ROC of the population attack in attacking 16 models trained on random samples drawn from the population with the same training algorithm (See [here](demo_algorithms/report_population_loss/ROC.png)).
+
+- `privacy_loss_model` - Game 3.2 in Ye et al., 2022
+  This privacy game defines how to audit the privacy risk for a trained model. An example configuration is provided in `config_models_population.yaml`. This game is similar to Game 3.1, except that the target dataset and target models are fixed. The sample privacy risk report for auditing a trained model includes the loss distribution of the target model on the members and non-members (See [here](demo_models/report_population_loss/Histogram.png)) and the ROC of the population attack in attacking a trained model (See [here](demo_models/report_population_loss/ROC.png)).
+
+- `privacy_loss_sample` (uniform) - Game 3.3 in Ye et al., 2022
+  This privacy game defines how to audit the privacy risk for a sample. An example configuration is provided in `config_samples.yaml`. This privacy game captures the privacy risk for a fixed data record where the adversary needs to distinguish models trained with and without the target sample.
+  The privacy risk report includes loss distribution of the target point (data with index 100) for the models trained with it and models trained without it (See [here](demo_samples/report_sample_loss/individual_pr_100_100.png)) and the ROC of the adversary in distinguishing the two types of models (See [here](demo_samples/report_sample_loss/individual_pr_roc_100_100.png)). Note that the rest of the training data points for different models are sampled uniformly from the underlying data distribution.
+
+- `privacy_loss_sample` (leave one out) - Game 3.4 in Ye et al., 2022
+  This privacy game defines how to audit the privacy risk for a sample when the rest of the point is known to the adversary. An example configuration is provided in `config_samples_leave_one_out.yaml`. This game is similar to Game 3.3, except that the training dataset is fixed. In other words, the game quantifies the privacy risk of a target data record with regard to a fixed dataset. The figure in `demo_samples` shows the loss distribution of the target point (data with index 1000) for the models trained with it and models trained without it. The privacy risk report includes loss distribution of the target point (data with index 100) for the models trained with it and models trained without it (See [here](demo_samples_leave_one_out/report_sample_loss/individual_pr_100_100.png)) and the ROC of the adversary in distinguishing the two types of models (See [here](demo_samples_leave_one_out/report_sample_loss/individual_pr_roc_100_100.png)). Note that the rest of the training datasets for all models is the same.
+
+## Auditing Algorithm
+
+In order to audit the privacy risks, we take the role of the adversary who simulates the privacy game above to compute how likely the target point is to be a member. Specifically, there are three ways to simulate the game, which correspond to three different types of algorithms:
+
+- `reference_out`
+  The adversary trains a set of reference models on datasets excluding the target point (OUT models). An example configuration is provided in `config_models_reference_out.yaml`.
+
+- `reference_in_out`
+  The adversary trains a set of reference models on datasets including the target point (IN models) and a set of reference models on datasets excluding the target point (OUT models). An example configuration is provided in `config_models_reference_in_out.yaml`.
+
+- `population`
+  The adversary does not train any models but queries the target model on a dataset disjoint from the target dataset. An example configuration is provided in `config_models_population.yaml`.
+
+For more details about algorithms, please refer to [Ye et al., 2022](https://arxiv.org/pdf/2111.09679.pdf).
+
+## Signal
+
+We support different attack signals, which are defined by `audit.signal` in the configuration file. Currently, we support the following two signals:
+
+- `loss`
+  This is the classification loss that the target model is trained to minimize.
+- `rescaled_logits`
+  This is the rescaled logit, which is $\log (p/1-p)$, where $p$ is the probability of predicting the correct label.
+
+## Others
+
+### Datasets and Models
+
+Privacy Meter supports various datasets widely used in the MIA literature, including CIFAR10 (`cifar10`), CIFAR100 (`cifar100`), Purchase (`purchase100`), and Texas (`texas100`). In terms of models, we provide support for CNN (`cnn`), AlexNet (`alexnet`), WideResNet (`wrn28-1`, `wrn28-2`, `wrn28-10`), and NN (`nn`) models. To specify the dataset and model, you can use the `dataset` and `model_name` parameters in the configuration file. To add dataset, models, or training algorithms for your specific use case, you can add the model structure in `model.py`, the dataset in `dataset.py`, and the training algorithm in `train.py`.
+
+### Efficient Training
+
+We have integrated the fast training library, [hlb-CIFAR10](https://github.com/tysam-code/hlb-CIFAR10), developed by [tysam-code](https://github.com/tysam-code), into Privacy Meter. This library achieves an impressive test accuracy of 94% on CIFAR-10 in approximately 6.84 seconds on a single A100 GPU, setting a new world speed record. This integration allows users to efficiently evaluate the effectiveness of the newly proposed algorithm against existing attack algorithms using the CIFAR-10 dataset. To leverage this fast training library, simply specify the `model_name` as `speedyresnet` in the configuration file. In addition, `speedyresnet` has its own hyper-parameters from `hlb-CIFAR10`, e.g., learning rate, weight decay, etc. The hyper-parameter defined in configuration files will not have an impact on the model training. You can set `optimizer` to `speedyresnet_optimizer`, `learning_rate` to `speedyresnet_learning_rate`, `weight_decay` to `speedyresnet_weight_decay`, `batch_size` to `speedyresnet_batch_size` and `epochs` to `speedyresnet_epochs`. Note that the size of the test dataset used for evaluating the model during training, denoted as `num_test_size`, must be divisible by the batch size `test_batch_size`.
+
+### Argumented queries
+
+When computing the signals from the target model or reference model, we support argument queries. For instance, for each target point, we can query the model loss on the argument target points (e.g., random cropped images from the target image). You can implement your own argumentation queries in `argumented_query.py`.
+
+<!-- ### Video Tutorial
+
+We also provide a video tutorial about Privacy Meter [here](https://drive.google.com/file/d/1wAxzlb8Oy67OCa95JXKPlFiJb0T2e39Y/view?usp=drive_link). -->
diff --git a/basic/augment.py b/basic/augment.py
new file mode 100644
index 0000000..7b2d1b9
--- /dev/null
+++ b/basic/augment.py
@@ -0,0 +1,56 @@
+import numpy as np
+import torch
+
+
+def get_signal_on_augmented_data(model_pm, data, targets, method=None, signal="loss"):
+    if method == "augmented":
+        # implement your own way of using the augmented data for inferring membership
+        reflect = True
+        shift = 0
+        stride = 1
+
+        outs = []
+        for aug in [data, data.flip(dims=[3])][: reflect + 1]:
+            aug_pad = torch.nn.functional.pad(aug, [shift] * 4, mode="reflect")
+            for dx in range(0, 2 * shift + 1, stride):
+                for dy in range(0, 2 * shift + 1, stride):
+                    this_x = aug_pad[:, :, dx : dx + 32, dy : dy + 32]
+                    if signal == "loss":
+                        logits = model_pm.get_loss(this_x, targets)
+                    elif signal == "rescaled_logits":
+                        logits = model_pm.get_rescaled_logits(this_x, targets)
+                    else:
+                        raise ValueError(f"signal {signal} not implemented")
+                    outs.append(logits)
+        return np.transpose(np.array(outs), (1, 0))  # (batch size, number of aug)
+
+    else:
+        if signal == "loss":
+            return model_pm.get_loss(data, targets)
+        elif signal == "rescaled_logits":
+            return model_pm.get_rescaled_logits(data, targets)
+        else:
+            raise ValueError(f"signal {signal} not implemented")
+
+
+def get_augmented_data(data, targets, method=None):
+    if method is None:
+        return data, targets
+    elif method == "augmented":
+        reflect = True
+        shift = 0
+        stride = 1
+
+        targets_list = []
+        data_list = []
+        for aug in [data, data.flip(dims=[3])][: reflect + 1]:
+            aug_pad = torch.nn.functional.pad(aug, [shift] * 4, mode="reflect")
+            for dx in range(0, 2 * shift + 1, stride):
+                for dy in range(0, 2 * shift + 1, stride):
+                    this_x = aug_pad[:, :, dx : dx + 32, dy : dy + 32]
+                    data_list.append(this_x)
+                    targets_list.append(targets)
+        return data, targets
+
+    else:
+        raise NotImplementedError
diff --git a/basic/config_algorithms.yaml b/basic/config_algorithms.yaml
new file mode 100644
index 0000000..5ce165f
--- /dev/null
+++ b/basic/config_algorithms.yaml
@@ -0,0 +1,33 @@
+run: # Configurations for a specific run
+  random_seed: 1234 # Integer number of specifying random seed
+  log_dir: demo_algorithms # String for indicating where to save all the information, including models and computed signals. We can reuse the models saved in the same log_dir.
+  time_log: True # Indicate whether to log the time for each step
+
+audit: # Configurations for auditing
+  privacy_game: avg_privacy_loss_training_algo # Indicate the privacy game from privacy_loss_model, avg_privacy_loss_training_algo, privacy_loss_sample
+  algorithm: population # String for indicating the membership inference attack. We currently support population, reference.
+  report_log: report_population_loss # String that indicates the folder where we save the and auditing report.
+  signal: loss # String for indicating the attack signal. We support loss, rescaled_logits.
+  device: cuda:0 # String for indicating on which device we conduct the membership inference attack and train reference models.
+  audit_batch_size: 1000 # Integer number for indicating the batch size for computing signals in the Privacy Meter.
+
+train: # Configuration for training
+  type: pytorch # Training framework (we only support pytorch now).
+  model_name: speedyresnet # String for indicating the model type. We support CNN, wrn28-1, wrn28-2, wrn28-10, vgg16, nn and speedyresnet (requires cuda). More model types can be added in model.py.
+  num_target_model: 16 #Integer number for indicating how many target models we want to audit for the privacy game
+  device: cuda:0 # String for indicating the device we want to use for training models, e.g., cpu or cuda.
+  epochs: speedyresnet_epochs # Integer number for indicating the epochs for training target model. For speedyresnet, it uses its own number of epochs.
+  batch_size: speedyresnet_batch_size # Integer number for indicating batch size for training the target model. For speedyresnet, it uses its own batch size.
+  optimizer: speedyresnet_optimizer # String which indicates the optimizer. We support Adam and SGD. For speedyresnet, it uses its own optimizer.
+  learning_rate: speedyresnet_learning_rate # Float number for indicating learning rate for training the target model. For speedyresnet, it uses its own learning_rate.
+  weight_decay: speedyresnet_weight_decay # Float number for indicating weight decay for training the target model. For speedyresnet, it uses its own weight_decay.
+  test_batch_size: 250 # Integer number for indicating batch size for evaluating the target model.
+  num_test_size: 1000 # Integer number for indicating the size of the test dataset for evaluating the target model during the training. This should be divisible by test_batch_size.
+
+data: # Configuration for data
+  dataset: cifar10 # String indicates the name of the dataset (i.e., cifar10, cifar100, purchase100, texas1000)
+  f_train: 0.3 # Float number from 0 to 1 indicating the fraction of the train dataset
+  f_test: 0.3 # Float number from 0 to 1 indicating the fraction of the test dataset
+  split_method: no_overlapping # String for indicating the methods of splitting the dataset between train, test, and auditing.
+  f_audit: 0.3 # Float from 0 to 1, indicating the fraction of the auditing dataset
+  data_dir: ../data # String about where to save the data.
diff --git a/basic/config_models_population.yaml b/basic/config_models_population.yaml
new file mode 100644
index 0000000..e12cc2f
--- /dev/null
+++ b/basic/config_models_population.yaml
@@ -0,0 +1,33 @@
+run: # Configurations for a specific run
+  random_seed: 1234 # Integer number of specifying random seed
+  log_dir: demo_models # String for indicating where to save all the information, including models and computed signals. We can reuse the models saved in the same log_dir.
+  time_log: True # Indicate whether to log the time for each step
+
+audit: # Configurations for auditing
+  privacy_game: privacy_loss_model # Indicate the privacy game from privacy_loss_model, avg_privacy_loss_training_algo, privacy_loss_sample
+  algorithm: population # String for indicating the membership inference attack. We currently support population, reference.
+  report_log: report_population_loss # String that indicates the folder where we save the and auditing report.
+  signal: loss # String for indicating the attack signal. We support loss, rescaled_logits.
+  device: cuda:0 # String for indicating on which device we conduct the membership inference attack and train reference models.
+  audit_batch_size: 1000 # Integer number for indicating the batch size for computing signals in the Privacy Meter.
+
+train: # Configuration for training
+  type: pytorch # Training framework (we only support pytorch now).
+  model_name: speedyresnet # String for indicating the model type. We support CNN, wrn28-1, wrn28-2, wrn28-10, vgg16, nn and speedyresnet (requires cuda). More model types can be added in model.py.
+  num_target_model: 1 #Integer number for indicating how many target models we want to audit for the privacy game
+  device: cuda:0 # String for indicating the device we want to use for training models, e.g., cpu or cuda.
+  epochs: speedyresnet_epochs # Integer number for indicating the epochs for training target model. For speedyresnet, it uses its own number of epochs.
+  batch_size: speedyresnet_batch_size # Integer number for indicating batch size for training the target model. For speedyresnet, it uses its own batch size.
+  optimizer: speedyresnet_optimizer # String which indicates the optimizer. We support Adam and SGD. For speedyresnet, it uses its own optimizer.
+  learning_rate: speedyresnet_learning_rate # Float number for indicating learning rate for training the target model. For speedyresnet, it uses its own learning_rate.
+  weight_decay: speedyresnet_weight_decay # Float number for indicating weight decay for training the target model. For speedyresnet, it uses its own weight_decay.
+  test_batch_size: 250 # Integer number for indicating batch size for evaluating the target model.
+  num_test_size: 1000 # Integer number for indicating the size of the test dataset for evaluating the target model during the training. This should be divisible by test_batch_size.
+
+data: # Configuration for data
+  dataset: cifar10 # String indicates the name of the dataset (i.e., cifar10, cifar100, purchase100, texas1000)
+  f_train: 0.3 # Float number from 0 to 1 indicating the fraction of the train dataset
+  f_test: 0.3 # Float number from 0 to 1 indicating the fraction of the test dataset
+  split_method: no_overlapping # String for indicating the methods of splitting the dataset between train, test, and auditing.
+  f_audit: 0.3 # Float from 0 to 1, indicating the fraction of the auditing dataset
+  data_dir: ../data # String about where to save the data.
diff --git a/basic/config_models_reference_in_out.yaml b/basic/config_models_reference_in_out.yaml
new file mode 100644
index 0000000..41f00fb
--- /dev/null
+++ b/basic/config_models_reference_in_out.yaml
@@ -0,0 +1,43 @@
+run: # Configurations for a specific run
+  random_seed: 12345 # Integer number of specifying random seed
+  log_dir: demo_models_reference_in_out # String for indicating where to save all the information, including models and computed signals. We can reuse the models saved in the same log_dir.
+  time_log: True # Indicate whether to log the time for each step
+
+audit: # Configurations for auditing
+  privacy_game: privacy_loss_model # Indicate the privacy game from privacy_loss_model, avg_privacy_loss_training_algo, privacy_loss_sample
+  algorithm: reference_in_out # String for indicating the membership inference attack. We currently support population, reference.
+  report_log: report_in_out_rescaled_logits # String that indicates the folder where we save the and auditing report.
+  signal: rescaled_logits # String for indicating the attack signal. We support loss, rescaled_logits.
+  device: cuda:0 # String for indicating on which device we conduct the membership inference attack and train reference models.
+  audit_batch_size: 1000 # Integer number for indicating the batch size for computing signals in the privacy meter.
+  num_in_models: 8 # Integer number that indicates how many target models trained on idx
+  num_out_models: 8 # Integer number that indicates how many target models not trained on idx
+  augmentation: None # Indicate whether to use augmentation for the query points
+  batch_size: speedyresnet_batch_size # Integer number for indicating the batch size of training the reference models if reference attack is used.
+  optimizer: speedyresnet_optimizer # String which indicates the optimizer for training reference models. We support Adam and SGD.
+  learning_rate: speedyresnet_learning_rate # Float number for indicating learning rate for training the reference model.
+  weight_decay: speedyresnet_weight_decay # Float number for indicating weight decay for training the reference model.
+  model_name: speedyresnet # String for indicating the model type. We support CNN, wrn28-1, wrn28-2, wrn28-10, vgg16, nn and speedyresnet (requires cuda). More model types can be added in model.py.
+  epochs: speedyresnet_epochs # Integer number for indicating the epochs for training target model.
+  test_batch_size: 250 # Integer number for indicating batch size for evaluating the target model.
+  num_test_size: 1000 # Integer number for indicating the size of the test dataset for evaluating the target model during the training. This should be divisible by test_batch_size.
+  fix_variance: True # Indicate hwether to fix the variance of the signals for all data points
+
+train: # Configuration for training
+  type: pytorch # Training framework (we only support pytorch now).
+  model_name: speedyresnet # String for indicating the model type. We support CNN, wrn28-1, wrn28-2, wrn28-10, vgg16, nn and speedyresnet (requires cuda). More model types can be added in model.py.
+  num_target_model: 1 #Integer number for indicating how many target models we want to audit for the privacy game
+  device: cuda:0 # String for indicating the device we want to use for training models, e.g., cpu or cuda.
+  epochs: speedyresnet_epochs # Integer number for indicating the epochs for training target model. For speedyresnet, it uses its own number of epochs.
+  batch_size: speedyresnet_batch_size # Integer number for indicating batch size for training the target model. For speedyresnet, it uses its own batch size.
+  optimizer: speedyresnet_optimizer # String which indicates the optimizer. We support Adam and SGD. For speedyresnet, it uses its own optimizer.
+  learning_rate: speedyresnet_learning_rate # Float number for indicating learning rate for training the target model. For speedyresnet, it uses its own learning_rate.
+  weight_decay: speedyresnet_weight_decay # Float number for indicating weight decay for training the target model. For speedyresnet, it uses its own weight_decay.
+  test_batch_size: 250 # Integer number for indicating batch size for evaluating the target model.
+  num_test_size: 1000 # Integer number for indicating the size of the test dataset for evaluating the target model during the training. This should be divisible by test_batch_size.
+
+data: # Configuration for data
+  dataset: cifar10 # String indicates the name of the dataset
+  data_dir: ../data
+  keep_ratio: 0.5 # the ratio of keeping the point for the training dataset.
+  dataset_size: 50000 # the size of the whole dataset used.
diff --git a/basic/config_models_reference_out.yaml b/basic/config_models_reference_out.yaml
new file mode 100644
index 0000000..6389883
--- /dev/null
+++ b/basic/config_models_reference_out.yaml
@@ -0,0 +1,44 @@
+run: # Configurations for a specific run
+  random_seed: 1234 # Integer number of specifying random seed
+  log_dir: demo_models_reference_out # String for indicating where to save all the information, including models and computed signals. We can reuse the models saved in the same log_dir.
+  time_log: True # Indicate whether to log the time for each step
+
+audit: # Configurations for auditing
+  privacy_game: privacy_loss_model # Indicate the privacy game from privacy_loss_model, avg_privacy_loss_training_algo, privacy_loss_sample
+  algorithm: reference_out # String for indicating the membership inference attack. We currently support population, reference.
+  report_log: report_reference_out_loss # String that indicates the folder where we save the and auditing report.
+  signal: loss # String for indicating the attack signal. We support loss, rescaled_logits.
+  device: cuda:0 # String for indicating on which device we conduct the membership inference attack and train reference models.
+  audit_batch_size: 1000 # Integer number for indicating the batch size for computing signals in the privacy meter.
+  num_reference_models: 16 # Integer number for indicating how many reference models we need to train for auditing, if the reference attack is used.
+  split_method: uniform # String for indicating the splitting methods for reference dataset. We support uniform and leave_one_out.
+  f_reference_dataset: 1 # Float number for indicating the ratio between the reference train dataset and the target train dataset.
+  batch_size: speedyresnet_batch_size # Integer number for indicating the batch size of training the reference models if reference attack is used.
+  optimizer: speedyresnet_optimizer # String which indicates the optimizer for training reference models. We support Adam and SGD.
+  learning_rate: speedyresnet_learning_rate # Float number for indicating learning rate for training the reference model.
+  weight_decay: speedyresnet_weight_decay # Float number for indicating weight decay for training the reference model.
+  model_name: speedyresnet # String for indicating the model type. We support CNN, wrn28-1, wrn28-2, wrn28-10, vgg16, nn and speedyresnet (requires cuda). More model types can be added in model.py.
+  epochs: speedyresnet_epochs # Integer number for indicating the epochs for training target model.
+  test_batch_size: 250 # Integer number for indicating batch size for evaluating the target model.
+  num_test_size: 1000 # Integer number for indicating the size of the test dataset for evaluating the target model during the training. This should be divisible by test_batch_size.
+
+train: # Configuration for training
+  type: pytorch # Training framework (we only support pytorch now).
+  model_name: speedyresnet # String for indicating the model type. We support CNN, wrn28-1, wrn28-2, wrn28-10, vgg16, nn and speedyresnet (requires cuda). More model types can be added in model.py.
+  num_target_model: 1 #Integer number for indicating how many target models we want to audit for the privacy game
+  device: cuda:0 # String for indicating the device we want to use for training models, e.g., cpu or cuda.
+  epochs: speedyresnet_epochs # Integer number for indicating the epochs for training target model. For speedyresnet, it uses its own number of epochs.
+  batch_size: speedyresnet_batch_size # Integer number for indicating batch size for training the target model. For speedyresnet, it uses its own batch size.
+  optimizer: speedyresnet_optimizer # String which indicates the optimizer. We support Adam and SGD. For speedyresnet, it uses its own optimizer.
+  learning_rate: speedyresnet_learning_rate # Float number for indicating learning rate for training the target model. For speedyresnet, it uses its own learning_rate.
+  weight_decay: speedyresnet_weight_decay # Float number for indicating weight decay for training the target model. For speedyresnet, it uses its own weight_decay.
+  test_batch_size: 250 # Integer number for indicating batch size for evaluating the target model.
+  num_test_size: 1000 # Integer number for indicating the size of the test dataset for evaluating the target model during the training. This should be divisible by test_batch_size.
+
+data: # Configuration for data
+  dataset: cifar10 # String indicates the name of the dataset (i.e., cifar10, cifar100, purchase100, texas1000)
+  f_train: 0.3 # Float number from 0 to 1 indicating the fraction of the train dataset
+  f_test: 0.3 # Float number from 0 to 1 indicating the fraction of the test dataset
+  split_method: no_overlapping # String for indicating the methods of splitting the dataset between train, test, and auditing.
+  f_audit: 0.3 # Float from 0 to 1, indicating the fraction of the auditing dataset
+  data_dir: ../data # String about where to save the data.
\ No newline at end of file
diff --git a/basic/config_samples.yaml b/basic/config_samples.yaml
new file mode 100644
index 0000000..deddef2
--- /dev/null
+++ b/basic/config_samples.yaml
@@ -0,0 +1,36 @@
+run: # Configurations for a specific run
+  random_seed: 1234 # Integer number of specifying random seed
+  log_dir: demo_samples # String for indicating where to save all the information, including models and computed signals. We can reuse the models saved in the same log_dir.
+  time_log: True # Indicate whether to log the time for each step
+
+audit: # the configurations for the MIA
+  privacy_game: privacy_loss_sample #privacy_loss_model #avg_privacy_loss_training_algo # the configuarations for the privacy loss game
+  report_log: report_sample_loss # String that indicates the folder where we save the and auditing report.
+  signal: loss # String for indicating the attack signal. We support loss, rescaled_logits.
+  device: cuda:0 # indicate on which device we conduct the MIA
+  model_name: speedyresnet
+  audit_batch_size: 1000 # the batch size for computing signals for inferring membership information
+  data_idx: 100 # Integer number indicating the data index for which we want to show the performance difference
+
+train: # Configuration for training
+  type: pytorch # Training framework (we only support pytorch now).
+  model_name: speedyresnet # String for indicating the model type. We support CNN, wrn28-1, wrn28-2, wrn28-10, vgg16, nn and speedyresnet (requires cuda). More model types can be added in model.py.
+  data_idx: 100 # Integer number for indicating the model index or data index.
+  num_in_models: 50 # Integer number that indicates how many target models trained on data_idx.
+  num_out_models: 50 # Integer number that indicates how many target models not trained on data_idx.
+  device: cuda:0 # String for indicating the device we want to use for training models, e.g., cpu or cuda.
+  epochs: speedyresnet_epochs # Integer number for indicating the epochs for training target model. For speedyresnet, it uses its own number of epochs.
+  batch_size: speedyresnet_batch_size # Integer number for indicating batch size for training the target model. For speedyresnet, it uses its own batch size.
+  optimizer: speedyresnet_optimizer # String which indicates the optimizer. We support Adam and SGD. For speedyresnet, it uses its own optimizer.
+  learning_rate: speedyresnet_learning_rate # Float number for indicating learning rate for training the target model. For speedyresnet, it uses its own learning_rate.
+  weight_decay: speedyresnet_weight_decay # Float number for indicating weight decay for training the target model. For speedyresnet, it uses its own weight_decay.
+  test_batch_size: 250 # Integer number for indicating batch size for evaluating the target model.
+  num_test_size: 1000 # Integer number for indicating the size of the test dataset for evaluating the target model during the training. This should be divisible by test_batch_size.
+
+data: # Configuration for data
+  dataset: cifar10 # String indicates the name of the dataset (i.e., cifar10, cifar100, purchase100, texas1000)
+  f_train: 0.3 # Float number from 0 to 1 indicating the fraction of the train dataset
+  f_test: 0.3 # Float number from 0 to 1 indicating the fraction of the test dataset
+  split_method: uniform # String for indicating the methods of splitting the dataset between train, test, and auditing; Take value from uniform
+  f_audit: 0.3 # Float from 0 to 1, indicating the fraction of the auditing dataset
+  data_dir: ../data # String about where to save the data.
diff --git a/basic/config_samples_leave_one_out.yaml b/basic/config_samples_leave_one_out.yaml
new file mode 100644
index 0000000..4186c4c
--- /dev/null
+++ b/basic/config_samples_leave_one_out.yaml
@@ -0,0 +1,36 @@
+run: # Configurations for a specific run
+  random_seed: 1234 # Integer number of specifying random seed
+  log_dir: demo_samples_leave_one_out # String for indicating where to save all the information, including models and computed signals. We can reuse the models saved in the same log_dir.
+  time_log: True # Indicate whether to log the time for each step
+
+audit: # the configurations for the MIA
+  privacy_game: privacy_loss_sample #privacy_loss_model #avg_privacy_loss_training_algo # the configuarations for the privacy loss game
+  report_log: report_sample_leave_one_out_loss # String that indicates the folder where we save the and auditing report.
+  signal: loss # String for indicating the attack signal. We support loss, rescaled_logits.
+  device: cuda:0 # indicate on which device we conduct the MIA
+  model_name: speedyresnet
+  audit_batch_size: 1000 # the batch size for computing signals for inferring membership information
+  data_idx: 100 # Integer number indicating the data index for which we want to show the performance difference
+
+train: # Configuration for training
+  type: pytorch # Training framework (we only support pytorch now).
+  model_name: speedyresnet # String for indicating the model type. We support CNN, wrn28-1, wrn28-2, wrn28-10, vgg16, nn and speedyresnet (requires cuda). More model types can be added in model.py.
+  data_idx: 100 # Integer number for indicating the model index or data index.
+  num_in_models: 50 # Integer number that indicates how many target models trained on data_idx.
+  num_out_models: 50 # Integer number that indicates how many target models not trained on data_idx.
+  device: cuda:0 # String for indicating the device we want to use for training models, e.g., cpu or cuda.
+  epochs: speedyresnet_epochs # Integer number for indicating the epochs for training target model. For speedyresnet, it uses its own number of epochs.
+  batch_size: speedyresnet_batch_size # Integer number for indicating batch size for training the target model. For speedyresnet, it uses its own batch size.
+  optimizer: speedyresnet_optimizer # String which indicates the optimizer. We support Adam and SGD. For speedyresnet, it uses its own optimizer.
+  learning_rate: speedyresnet_learning_rate # Float number for indicating learning rate for training the target model. For speedyresnet, it uses its own learning_rate.
+  weight_decay: speedyresnet_weight_decay # Float number for indicating weight decay for training the target model. For speedyresnet, it uses its own weight_decay.
+  test_batch_size: 250 # Integer number for indicating batch size for evaluating the target model.
+  num_test_size: 1000 # Integer number for indicating the size of the test dataset for evaluating the target model during the training. This should be divisible by test_batch_size.
+
+data: # Configuration for data
+  dataset: cifar10 # String indicates the name of the dataset (i.e., cifar10, cifar100, purchase100, texas1000)
+  f_train: 0.3 # Float number from 0 to 1 indicating the fraction of the train dataset
+  f_test: 0.3 # Float number from 0 to 1 indicating the fraction of the test dataset
+  split_method: leave_one_out # String for indicating the methods of splitting the dataset between train, test, and auditing; Take value from uniform
+  f_audit: 0.3 # Float from 0 to 1, indicating the fraction of the auditing dataset
+  data_dir: ../data # String about where to save the data.
diff --git a/experiments/core.py b/basic/core.py
similarity index 70%
rename from experiments/core.py
rename to basic/core.py
index 1832c33..d8242de 100644
--- a/experiments/core.py
+++ b/basic/core.py
@@ -8,27 +8,39 @@
 import numpy as np
 import torch
 import torchvision
+from dataset import get_dataloader, get_dataset_subset
+from fast_train import (
+    NetworkEMA,
+    fast_train_fun,
+    get_cifar10_data,
+    logging_columns_list,
+    make_net,
+    print_training_details,
+)
+from models import get_model
 from sklearn.model_selection import train_test_split
 from torch import nn
-
-from dataset import get_dataset_subset
-from models import get_model
-
+from train import inference, train
+from util import get_split, load_models_by_conditions, load_models_by_model_idx
 
 from privacy_meter import audit_report
 from privacy_meter.audit import MetricEnum
 from privacy_meter.audit_report import ROCCurveReport, SignalHistogramReport
 from privacy_meter.constants import InferenceGame
 from privacy_meter.dataset import Dataset
+from privacy_meter.hypothesis_test import linear_itp_threshold_func
 from privacy_meter.information_source import InformationSource
+from privacy_meter.information_source_signal import (
+    ModelLoss,
+    ModelNegativeRescaledLogits,
+)
+from privacy_meter.metric import PopulationMetric, ReferenceMetric
 from privacy_meter.model import PytorchModelTensor
-from train import inference, train
-from util import get_split, load_models_by_conditions, load_models_by_model_idx
 
 
 def load_existing_target_model(
     dataset_size: int, model_metadata_dict: dict, configs: dict
-) -> List(int):
+):
     """Return a list of model's index that matches the configuration.
 
     Args:
@@ -51,10 +63,12 @@ def load_existing_target_model(
         conditions = {
             "optimizer": configs["train"]["optimizer"],
             "batch_size": configs["train"]["batch_size"],
+            "model_name": configs["train"]["model_name"],
             "epochs": configs["train"]["epochs"],
             "learning_rate": configs["train"]["learning_rate"],
             "weight_decay": configs["train"]["weight_decay"],
             "num_train": int(dataset_size * configs["data"]["f_train"]),
+            "dataset": configs["data"]["dataset"],
         }
         matched_idx_list = load_models_by_conditions(
             model_metadata_dict, conditions, num_target_models
@@ -64,7 +78,7 @@ def load_existing_target_model(
 
 def load_existing_reference_models(
     model_metadata_dict: dict, configs: dict, target_idx: int
-) -> List(int):
+):
     """Return a list of reference model's index that matches the configuration.
 
     Args:
@@ -75,7 +89,7 @@ def load_existing_reference_models(
     Returns:
         List(int): List of reference model index which matches the conditions
     """
-    if configs["algorithm"] != "reference":
+    if configs["algorithm"] != "reference_out":
         return []
     number_models = configs.get("num_reference_models", 10)
     num_audit_train_data = int(
@@ -104,7 +118,7 @@ def check_reference_model_dataset(
     target_idx: int,
     splitting_method: str,
     data_idx=None,
-) -> List(int):
+):
     """Filter out the reference models that does not satisfy the splitting method.
 
     Args:
@@ -143,14 +157,22 @@ def check_reference_model_dataset(
 
 
 def load_existing_models(
-    model_metadata_dict: dict, matched_idx: List(int), model_name: str
-) -> List(nn.Module):
+    model_metadata_dict: dict,
+    matched_idx: List(int),
+    model_name: str,
+    dataset: torchvision.datasets,
+    dataset_name: str,
+    device="cuda",
+):
     """Load existing models from dicks for matched_idx.
 
     Args:
         model_metadata_dict (dict): Model metedata dict.
         matched_idx (List): List of model index we want to load.
         model_name (str): Model name.
+        dataset_list (List): Dataset List.
+        dataset (torchvision.datasets): Dataset.
+        dataset_name (str): Dataset name.
     Returns:
         List (nn.Module): List of models.
     """
@@ -158,7 +180,11 @@ def load_existing_models(
     if len(matched_idx) > 0:
         for metadata_idx in matched_idx:
             metadata = model_metadata_dict["model_metadata"][metadata_idx]
-            model = get_model(model_name)
+            if model_name != "speedyresnet":
+                model = get_model(model_name, dataset_name)
+            else:
+                data = get_cifar10_data(dataset, [0], [0], device=device)
+                model = NetworkEMA(make_net(data, device=device))
             with open(f"{metadata['model_path']}", "rb") as file:
                 model_weight = pickle.load(file)
             model.load_state_dict(model_weight)
@@ -170,7 +196,7 @@ def load_existing_models(
 
 def load_dataset_for_existing_models(
     dataset_size: int, model_metadata_dict: dict, matched_idx: List(int), configs: dict
-) -> List(dict):
+):
     """Load the dataset index list for the existing models.
 
     Args:
@@ -241,8 +267,7 @@ def prepare_datasets(dataset_size: int, num_datasets: int, configs: dict):
         selected_index = np.random.choice(
             all_index, train_size + test_size, replace=False
         )
-        train_index, test_index = train_test_split(
-            selected_index, test_size=test_size)
+        train_index, test_index = train_test_split(selected_index, test_size=test_size)
         audit_index = get_split(
             all_index,
             selected_index,
@@ -253,8 +278,7 @@ def prepare_datasets(dataset_size: int, num_datasets: int, configs: dict):
             {"train": train_index, "test": test_index, "audit": audit_index}
         )
 
-    dataset_splits = {"split": index_list,
-                      "split_method": configs["split_method"]}
+    dataset_splits = {"split": index_list, "split_method": configs["split_method"]}
     return dataset_splits
 
 
@@ -267,7 +291,7 @@ def prepare_datasets_for_sample_privacy_risk(
     split_method: str,
     model_metadata_dict: dict,
     matched_in_idx: List(int) = None,
-) -> dict:
+):
     """Prepare the datasets for auditing the priavcy risk for a data point. We prepare the dataset with or without the target point for training a set of models with or without the target point.
 
     Args:
@@ -319,7 +343,22 @@ def prepare_datasets_for_sample_privacy_risk(
                 )
 
     # We generate a list of dataset which is the same as the training dataset of the models indicated by the matched_in_idx but excluding the target point.
-    elif split_method == "leave_one_out":
+    elif split_method == "leave_one_out" and data_type == "include":
+        train_index = np.random.choice(
+            all_index_exclude_z,
+            int((configs["f_train"]) * dataset_size) - 1,
+            replace=False,
+        )
+        for _ in range(num_models):
+            index_list.append(
+                {
+                    "train": np.append(train_index, data_idx),
+                    "test": all_index,
+                    "audit": all_index,
+                }
+            )
+
+    elif split_method == "leave_one_out" and data_type == "exclude":
         assert (
             matched_in_idx is not None
         ), "Please indicate the in-world model metdadata"
@@ -359,12 +398,67 @@ def prepare_datasets_for_sample_privacy_risk(
     return dataset_splits
 
 
+def prepare_datasets_for_reference_in_attack(
+    all_dataset_size: int,
+    dataset_size: int,
+    num_models: int,
+    keep_ratio: float,
+    is_uniform: bool,
+):
+    """Prepare the datasets for reference_in attacks. Each data point will be randomly chosen by half of the models with probability keep_ratio and the rest of the models will be trained on the rest of the dataset.
+    The partioning method is from https://github.com/tensorflow/privacy/blob/master/research/mi_lira_2021/train.py
+    Args:
+        all_dataset_size (int): Size of the whole dataset
+        dataset_size (int): Size of the whole dataset used for training the models
+        num_models (int): Number of additional target models
+        keep_ratio (float): Indicate the probability of keeping the target point for training the model.
+        is_uniform (bool): Indicate whether to perform the splitting in a uniform way.
+    Returns:
+        dict: Data split information.
+        list: List of boolean indicating whether the model is trained on the target point.
+        list: List of target data index on which the adversary wants to infer the membership.
+    """
+    index_list = []
+    all_index = np.random.choice(all_dataset_size, dataset_size, replace=False)
+    left_index = np.setdiff1d(np.arange(all_dataset_size), all_index)
+    if is_uniform:
+        keep = np.random.uniform(0, 1, size=(num_models, dataset_size)) <= keep_ratio
+    else:
+        selected_matrix = np.random.uniform(0, 1, size=(num_models, dataset_size))
+        order = selected_matrix.argsort(0)
+        keep = order < int(keep_ratio * num_models)
+    for i in range(num_models):
+        if np.sum(~keep[i]) % 2 == 0:
+            # This is for speedyresnet
+            index_list.append(
+                {
+                    "train": all_index[keep[i]],
+                    "test": all_index[~keep[i]],
+                    "audit": left_index,
+                }
+            )
+        else:
+            train_index = all_index[keep[i]]
+            test_index = all_index[~keep[i]]
+            index_list.append(
+                {
+                    "train": np.append(train_index, test_index[0]),
+                    "test": test_index[1:],
+                    "audit": left_index,
+                }
+            )
+
+    dataset_splits = {"split": index_list, "split_method": f"random_{keep_ratio}"}
+    return dataset_splits, keep, all_index
+
+
 def prepare_models(
     log_dir: str,
     dataset: torchvision.datasets,
     data_split: dict,
     configs: dict,
     model_metadata_dict: dict,
+    dataset_name: str,
 ):
     """Train models based on the dataset split information.
 
@@ -375,7 +469,7 @@ def prepare_models(
         configs (dict): Indicate the traininig information
         model_metadata_dict (dict): Metadata information about the existing models.
         matched_idx (List, optional): Index list of existing models that matchs configuration. Defaults to None.
-
+        dataset_name (str): Name of the dataset
     Returns:
         nn.Module: List of trained models
         dict: Updated Metadata of the existing models
@@ -388,26 +482,6 @@ def prepare_models(
     for split in range(len(data_split["split"])):
         meta_data = {}
         baseline_time = time.time()
-        train_loader = torch.utils.data.DataLoader(
-            torch.utils.data.Subset(
-                dataset, data_split["split"][split]["train"]),
-            batch_size=configs["batch_size"],
-            shuffle=True,
-            num_workers=4,
-            pin_memory=True,
-            persistent_workers=True,
-            prefetch_factor=16
-        )
-        test_loader = torch.utils.data.DataLoader(
-            torch.utils.data.Subset(
-                dataset, data_split["split"][split]["test"]),
-            batch_size=configs["test_batch_size"],
-            shuffle=False,
-            num_workers=4,
-            pin_memory=True,
-            persistent_workers=True,
-            prefetch_factor=16
-        )
 
         print(50 * "-")
         print(
@@ -415,20 +489,57 @@ def prepare_models(
             f"Train size {len(data_split['split'][split]['train'])}, Test size {len(data_split['split'][split]['test'])}",
         )
 
-        # Train the target model based on the configurations.
-        model = train(get_model(configs["model_name"]), train_loader, configs)
-        # Test performance on the training dataset and test dataset
-        test_loss, test_acc = inference(model, test_loader, configs["device"])
-        train_loss, train_acc = inference(
-            model, train_loader, configs["device"])
+        if configs["model_name"] != "speedyresnet":
+            train_loader = get_dataloader(
+                torch.utils.data.Subset(dataset, data_split["split"][split]["train"]),
+                batch_size=configs["batch_size"],
+                shuffle=True,
+            )
+            test_loader = get_dataloader(
+                torch.utils.data.Subset(dataset, data_split["split"][split]["test"]),
+                batch_size=configs["test_batch_size"],
+            )
+
+            # Train the target model based on the configurations.
+            model = train(
+                get_model(configs["model_name"], dataset_name),
+                train_loader,
+                configs,
+                test_loader,
+            )
+            # Test performance on the training dataset and test dataset
+            test_loss, test_acc = inference(model, test_loader, configs["device"])
+            train_loss, train_acc = inference(model, train_loader, configs["device"])
+            print(f"Train accuracy {train_acc}, Train Loss {train_loss}")
+            print(f"Test accuracy {test_acc}, Test Loss {test_loss}")
+
+        elif configs["model_name"] == "speedyresnet" and dataset_name == "cifar10":
+            data = get_cifar10_data(
+                dataset,
+                data_split["split"][split]["train"],
+                data_split["split"][split]["test"][: configs["num_test_size"]],
+                device=configs["device"],
+            )
+            print_training_details(logging_columns_list, column_heads_only=True)
+            model, train_acc, train_loss, test_acc, test_loss = fast_train_fun(
+                data,
+                make_net(data, device=configs["device"]),
+                eval_batchsize=configs["test_batch_size"],
+                device=configs["device"],
+            )
+
+        else:
+            raise ValueError(
+                f"The {configs['model_name']} is not supported for the {dataset_name}"
+            )
+
         model_list.append(copy.deepcopy(model))
         logging.info(
             "Prepare %s-th target model costs %s seconds ",
             split,
             time.time() - baseline_time,
         )
-        print(f"Train accuracy {train_acc}, Train Loss {train_loss}")
-        print(f"Test accuracy {test_acc}, Test Loss {test_loss}")
+
         print(50 * "-")
 
         # Update the model metadata and save the model
@@ -449,6 +560,12 @@ def prepare_models(
         meta_data["learning_rate"] = configs["learning_rate"]
         meta_data["weight_decay"] = configs["weight_decay"]
         meta_data["model_path"] = f"{log_dir}/model_{model_idx}.pkl"
+        meta_data["train_acc"] = train_acc
+        meta_data["test_acc"] = test_acc
+        meta_data["train_loss"] = train_loss
+        meta_data["test_loss"] = test_loss
+        meta_data["dataset"] = dataset_name
+
         model_metadata_dict["model_metadata"][model_idx] = meta_data
         with open(f"{log_dir}/models_metadata.pkl", "wb") as f:
             pickle.dump(model_metadata_dict, f)
@@ -457,16 +574,20 @@ def prepare_models(
 
 
 def get_info_source_population_attack(
-    dataset: torchvision.datasets, data_split: dict, model: nn.Module, configs: dict
+    dataset: torchvision.datasets,
+    data_split: dict,
+    model: nn.Module,
+    configs: dict,
+    model_name: str,
 ):
-    """Prepare the information source for calling the core of privacy meter for the population attack
+    """Prepare the information source for calling the core of Privacy Meter for the population attack
 
     Args:
         dataset(torchvision.datasets): The whole dataset
         data_split (dict): Data split information. 'split' contains a list of dict, each of which has the train, test and audit information. 'split_method' indicates the how the dataset is generated.
         model (nn.Module): Target Model.
         configs (dict): Auditing configuration
-
+        model_name (str): Target model name
     Returns:
         List(Dataset): List of target dataset on which we want to infer the membership
         List(Dataset):  List of auditing datasets we use for launch the attack
@@ -474,10 +595,14 @@ def get_info_source_population_attack(
         List(nn.Module): List of reference models (which is the target model based on population attack)
     """
     train_data, train_targets = get_dataset_subset(
-        dataset, data_split["train"])
-    test_data, test_targets = get_dataset_subset(dataset, data_split["test"])
+        dataset, data_split["train"], model_name, device=configs["device"]
+    )
+    test_data, test_targets = get_dataset_subset(
+        dataset, data_split["test"], model_name, device=configs["device"]
+    )
     audit_data, audit_targets = get_dataset_subset(
-        dataset, data_split["audit"])
+        dataset, data_split["audit"], model_name, device=configs["device"]
+    )
     target_dataset = Dataset(
         data_dict={
             "train": {"x": train_data, "y": train_targets},
@@ -509,6 +634,8 @@ def get_info_source_reference_attack(
     configs: dict,
     model_metadata_dict: dict,
     target_model_idx: int,
+    model_name: str,
+    dataset_name: str,
 ):
     """Prepare the information source for the reference attacks
 
@@ -520,6 +647,8 @@ def get_info_source_reference_attack(
         configs (dict): Auditing configuration.
         model_metadata_dict (dict): Model metedata dict.
         target_model_idx (int): target model index.
+        model_name (str): target model name.
+        dataset_name (str): name of the dataset.
 
     Returns:
         target_dataset: List of target dataset on which we want to infer the membership.
@@ -531,9 +660,13 @@ def get_info_source_reference_attack(
     """
 
     # Construct the target dataset and target models
+
     train_data, train_targets = get_dataset_subset(
-        dataset, data_split["train"])
-    test_data, test_targets = get_dataset_subset(dataset, data_split["test"])
+        dataset, data_split["train"], model_name, device=configs["device"]
+    )
+    test_data, test_targets = get_dataset_subset(
+        dataset, data_split["test"], model_name, device=configs["device"]
+    )
     target_dataset = Dataset(
         data_dict={
             "train": {"x": train_data, "y": train_targets},
@@ -558,7 +691,11 @@ def get_info_source_reference_attack(
     )
     print(f"Load existing {len(reference_idx)} reference models")
     existing_reference_models = load_existing_models(
-        model_metadata_dict, reference_idx, configs["model_name"]
+        model_metadata_dict,
+        reference_idx,
+        configs["model_name"],
+        dataset,
+        dataset_name,
     )
     reference_models = [
         PytorchModelTensor(
@@ -571,8 +708,7 @@ def get_info_source_reference_attack(
     ]
 
     # Train additional reference models
-    num_reference_models = configs["num_reference_models"] - \
-        len(reference_models)
+    num_reference_models = configs["num_reference_models"] - len(reference_models)
     for reference_idx in range(num_reference_models):
         reference_data_idx = get_split(
             data_split["audit"],
@@ -584,20 +720,35 @@ def get_info_source_reference_attack(
         print(f"Training  {reference_idx}-th reference model")
         start_time = time.time()
 
-        reference_loader = torch.utils.data.DataLoader(
-            torch.utils.data.Subset(dataset, reference_data_idx),
-            batch_size=configs["batch_size"],
-            shuffle=True,
-            num_workers=4,
-            pin_memory=True,
-            persistent_workers=True,
-            prefetch_factor=16
-        )
-        reference_model = get_model(configs["model_name"])
-        reference_model = train(reference_model, reference_loader, configs)
-        # Test performance on the training dataset and test dataset
-        train_loss, train_acc = inference(
-            model, reference_loader, configs["device"])
+        if configs["model_name"] != "speedyresnet":
+            reference_loader = get_dataloader(
+                torch.utils.data.Subset(dataset, reference_data_idx),
+                batch_size=configs["batch_size"],
+                shuffle=True,
+            )
+
+            reference_model = get_model(configs["model_name"], dataset_name)
+            reference_model = train(reference_model, reference_loader, configs)
+            # Test performance on the training dataset and test dataset
+            train_loss, train_acc = inference(
+                model, reference_loader, configs["device"]
+            )
+        else:
+            data = get_cifar10_data(
+                dataset,
+                reference_data_idx,
+                reference_data_idx[: configs["num_test_size"]],
+                device=configs["device"],
+            )
+            print_training_details(
+                logging_columns_list, column_heads_only=True
+            )  ## print out the training column heads before we print the actual content for each run.
+            reference_model, train_acc, train_loss, _, _ = fast_train_fun(
+                data,
+                make_net(data, device=configs["device"]),
+                eval_batchsize=configs["test_batch_size"],
+                device=configs["device"],
+            )
 
         logging.info(
             f"Prepare {reference_idx}-th reference model costs {time.time()-start_time} seconds: Train accuracy (on auditing dataset) {train_acc}, Train Loss {train_loss}"
@@ -620,6 +771,7 @@ def get_info_source_reference_attack(
         meta_data["weight_decay"] = configs["weight_decay"]
         meta_data["model_name"] = configs["model_name"]
         meta_data["model_path"] = f"{log_dir}/model_{model_idx}.pkl"
+        meta_data["dataset"] = dataset_name
         model_metadata_dict["model_metadata"][model_idx] = meta_data
         reference_models.append(
             PytorchModelTensor(
@@ -643,6 +795,27 @@ def get_info_source_reference_attack(
     )
 
 
+def get_signal_and_hypothesis_test_func(configs):
+    """Return the attack and way to find the threshold
+
+    Args:
+        configs (dict): Auditing configuration.
+    """
+    signals = []
+
+    if configs["signal"] == "loss":
+        signals.append(ModelLoss())
+    elif configs["signal"] == "rescaled_logits":
+        signals.append(ModelNegativeRescaledLogits())
+    else:
+        raise ValueError(
+            f"{configs['signal']} is not supported. Please use loss or rescaled_logits as the signal."
+        )
+
+    hypothesis_test_func = linear_itp_threshold_func
+    return signals, hypothesis_test_func
+
+
 def prepare_information_source(
     log_dir: str,
     dataset: torchvision.datasets,
@@ -651,8 +824,10 @@ def prepare_information_source(
     configs: dict,
     model_metadata_dict: dict,
     target_model_idx_list: List(int) = None,
+    model_name: str = None,
+    dataset_name: str = None,
 ):
-    """Prepare the information source for calling the core of the privacy meter
+    """Prepare the information source for calling the core of the Privacy Meter
     Args:
         log_dir (str): Log directory that saved all the information, including the models.
         dataset (torchvision.datasets): The whole dataset
@@ -660,12 +835,14 @@ def prepare_information_source(
         model_list (List): List of target models.
         configs (dict): Auditing configuration.
         model_metadata_dict (dict): Model metedata dict.
+        model_name str: target model name
+        dataset_name (str): name of the dataset
 
     Returns:
         List(InformationSource): target information source list.
         List(InformationSource): reference information source list.
         List: List of metrics used for each target models.
-        List(str): List of directory to save the privacy meter results for each target model.
+        List(str): List of directory to save the Privacy Meter results for each target model.
         dict: Updated metadata for the trained model.
     """
     reference_info_source_list = []
@@ -676,6 +853,8 @@ def prepare_information_source(
     # Prepare the information source for each target model
     for split in range(len(model_list)):
         print(f"preparing information sources for {split}-th target model")
+        log_dir_path = f"{log_dir}/{configs['report_log']}/signal_{split}"
+        signals, hypothesis_test_func = get_signal_and_hypothesis_test_func(configs)
         if configs["algorithm"] == "population":
             (
                 target_dataset,
@@ -683,10 +862,26 @@ def prepare_information_source(
                 target_model,
                 audit_models,
             ) = get_info_source_population_attack(
-                dataset, data_split["split"][split], model_list[split], configs
+                dataset,
+                data_split["split"][split],
+                model_list[split],
+                configs,
+                model_name,
+            )
+            target_info_source = InformationSource(
+                models=target_model, datasets=target_dataset
             )
-            metrics = MetricEnum.POPULATION
-        elif configs["algorithm"] == "reference":
+            reference_info_source = InformationSource(
+                models=audit_models, datasets=audit_dataset
+            )
+            metrics = PopulationMetric(
+                target_info_source=target_info_source,
+                reference_info_source=reference_info_source,
+                signals=signals,
+                hypothesis_test_func=hypothesis_test_func,
+                logs_dirname=log_dir_path,
+            )
+        elif configs["algorithm"] == "reference_out":
             # Check if there are existing reference models
             (
                 target_dataset,
@@ -702,13 +897,24 @@ def prepare_information_source(
                 configs,
                 model_metadata_dict,
                 target_model_idx_list[split],
+                model_name,
+                dataset_name,
+            )
+            target_info_source = InformationSource(
+                models=target_model, datasets=target_dataset
+            )
+            reference_info_source = InformationSource(
+                models=audit_models, datasets=audit_dataset
+            )
+            metrics = ReferenceMetric(
+                target_info_source=target_info_source,
+                reference_info_source=reference_info_source,
+                signals=signals,
+                hypothesis_test_func=hypothesis_test_func,
+                logs_dirname=log_dir_path,
             )
-            metrics = MetricEnum.REFERENCE
         metric_list.append(metrics)
 
-        target_info_source = InformationSource(
-            models=target_model, datasets=target_dataset
-        )
         reference_info_source = InformationSource(
             models=audit_models, datasets=audit_dataset
         )
@@ -716,7 +922,6 @@ def prepare_information_source(
         target_info_source_list.append(target_info_source)
 
         # Save the log_dir for attacking different target model
-        log_dir_path = f"{log_dir}/{configs['report_log']}/signal_{split}"
         Path(log_dir_path).mkdir(parents=True, exist_ok=True)
         log_dir_list.append(log_dir_path)
 
@@ -777,17 +982,9 @@ def prepare_priavcy_risk_report(
                 save=True,
                 filename=f"{save_path}/ROC.png",
             )
-
-            SignalHistogramReport.generate_report(
-                metric_result=audit_results,
-                inference_game_type=InferenceGame.AVG_PRIVACY_LOSS_TRAINING_ALGO,
-                save=True,
-                filename=f"{save_path}/Histogram.png",
-            )
         else:
             raise ValueError(
                 f"{len(audit_results)} results are not enough for {configs['privacy_game']})"
             )
     else:
-        raise NotImplementedError(
-            f"{configs['privacy_game']} is not implemented yet")
+        raise NotImplementedError(f"{configs['privacy_game']} is not implemented yet")
diff --git a/basic/dataset.py b/basic/dataset.py
new file mode 100644
index 0000000..5d869e8
--- /dev/null
+++ b/basic/dataset.py
@@ -0,0 +1,219 @@
+"""This file contains functions for loading the dataset"""
+import math
+import os
+import pickle
+from ast import List
+
+import numpy as np
+import pandas as pd
+import torch
+import torchvision
+import torchvision.transforms as transforms
+from fast_train import get_batches, get_cifar10_data
+from torch.utils.data import Dataset
+
+
+class TabularDataset(Dataset):
+    """Students Performance dataset."""
+
+    def __init__(self, X, y):
+        """Initializes instance of class StudentsPerformanceDataset.
+        Args:
+            csv_file (str): Path to the csv file with the students data.
+        """
+        self.data = X
+        self.targets = y
+
+    def __len__(self):
+        return len(self.targets)
+
+    def __getitem__(self, idx):
+        # Convert idx from tensor to list due to pandas bug (that arises when using pytorch's random_split)
+        if isinstance(idx, torch.Tensor):
+            idx = idx.tolist()
+
+        return [self.data[idx], self.targets[idx]]
+
+
+class InfiniteRepeatDataset(Dataset):
+    def __init__(self, dataset):
+        self.dataset = dataset
+
+    def __len__(self):
+        return len(self.dataset)
+
+    def __getitem__(self, idx):
+        return self.dataset[idx % len(self.dataset)]
+
+
+def get_dataset(dataset_name: str, data_dir: str):
+    """Load the dataset from the pickle file or download it from the internet.
+    Args:
+        dataset_name (str): Dataset name
+        data_dir (str): Indicate the log directory for loading the dataset
+
+    Raises:
+        NotImplementedError: Check if the dataset has been implemented.
+
+    Returns:
+        torchvision.datasets: Whole dataset.
+    """
+    path = f"{data_dir}/{dataset_name}"
+    if os.path.exists(f"{path}.pkl"):
+        with open(f"{path}.pkl", "rb") as file:
+            all_data = pickle.load(file)
+        print(f"Load data from {path}.pkl")
+
+    else:
+        if dataset_name == "cifar10":
+            transform = transforms.Compose(
+                [
+                    transforms.ToTensor(),
+                    transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]),
+                ]
+            )
+            all_data = torchvision.datasets.CIFAR10(
+                root=path, train=True, download=True, transform=transform
+            )
+            test_data = torchvision.datasets.CIFAR10(
+                root=path, train=False, download=True, transform=transform
+            )
+            all_features = np.concatenate([all_data.data, test_data.data], axis=0)
+            all_targets = np.concatenate([all_data.targets, test_data.targets], axis=0)
+            all_data.data = all_features
+            all_data.targets = all_targets
+            with open(f"{path}.pkl", "wb") as file:
+                pickle.dump(all_data, file)
+            print(f"Save data to {path}.pkl")
+        elif dataset_name == "cifar100":
+            transform = transforms.Compose(
+                [
+                    transforms.ToTensor(),
+                    transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]),
+                ]
+            )
+            all_data = torchvision.datasets.CIFAR100(
+                root=path, train=True, download=True, transform=transform
+            )
+            test_data = torchvision.datasets.CIFAR100(
+                root=path, train=False, download=True, transform=transform
+            )
+            all_features = np.concatenate([all_data.data, test_data.data], axis=0)
+            all_targets = np.concatenate([all_data.targets, test_data.targets], axis=0)
+            all_data.data = all_features
+            all_data.targets = all_targets
+            with open(f"{path}.pkl", "wb") as file:
+                pickle.dump(all_data, file)
+            print(f"Save data to {path}.pkl")
+        elif dataset_name == "purchase100":
+            if os.path.exists("../data/purchase/dataset_purchase"):
+                df = pd.read_csv(
+                    "../data/purchase/dataset_purchase", header=None, encoding="utf-8"
+                ).to_numpy()
+                y = df[:, 0] - 1
+                X = df[:, 1:].astype(np.float32)
+                all_data = TabularDataset(X, y)
+                with open(f"{path}.pkl", "wb") as file:
+                    pickle.dump(all_data, file)
+                print(f"Save data to {path}.pkl")
+            else:
+                raise NotImplementedError(
+                    f"{dataset_name} is not installed correctly in ../data/purchase"
+                )
+        elif dataset_name == "texas100":
+            if os.path.exists("../data/texas/texas/100/feats"):
+                X = (
+                    pd.read_csv(
+                        "../data/texas/texas/100/feats", header=None, encoding="utf-8"
+                    )
+                    .to_numpy()
+                    .astype(np.float32)
+                )
+                y = (
+                    pd.read_csv(
+                        "../data/texas/texas/100/labels", header=None, encoding="utf-8"
+                    )
+                    .to_numpy()
+                    .reshape(-1)
+                    - 1
+                )
+
+                all_data = TabularDataset(X, y)
+                with open(f"{path}.pkl", "wb") as file:
+                    pickle.dump(all_data, file)
+                print(f"Save data to {path}.pkl")
+            else:
+                raise NotImplementedError(
+                    f"{dataset_name} is not installed correctly in ../data/texas"
+                )
+        else:
+            raise NotImplementedError(f"{dataset_name} is not implemented")
+
+    print(f"the whole dataset size: {len(all_data)}")
+    return all_data
+
+
+def get_dataset_subset(
+    dataset: torchvision.datasets, index: List(int), model_name="CNN", device="cuda"
+):
+    """Get a subset of the dataset.
+
+    Args:
+        dataset (torchvision.datasets): Whole dataset.
+        index (list): List of index.
+        model_name (str): name of the model.
+    """
+    assert max(index) < len(dataset) and min(index) >= 0, "Index out of range"
+    if model_name != "speedyresnet":  ## check if we need to change
+        data_loader = get_dataloader(
+            torch.utils.data.Subset(dataset, index),
+            batch_size=len(index),
+            shuffle=False,
+        )
+        for data, targets in data_loader:
+            return data, targets
+    else:
+        data = get_cifar10_data(dataset, index[:1], index, device=device)
+        input_list = []
+        targets_list = []
+
+        MAX_BATCH_SIZE = 5000  # to avoid OOM
+        size = len(index)
+        list_divisors = list(
+            set(
+                factor
+                for i in range(1, int(math.sqrt(size)) + 1)
+                if size % i == 0
+                for factor in (i, size // i)
+                if factor < MAX_BATCH_SIZE
+            )
+        )
+        batch_size = max(list_divisors)
+
+        for inputs, targets in get_batches(
+            data, key="eval", batchsize=batch_size, shuffle=False, device=device
+        ):
+            input_list.append(inputs)
+            targets_list.append(targets)
+        inputs = torch.cat(input_list, dim=0)
+        targets = torch.cat(targets_list, dim=0).max(dim=1)[1]
+        return inputs, targets
+
+
+def get_dataloader(
+    dataset: torchvision.datasets,
+    batch_size: int,
+    loader_type="torch",
+    shuffle: bool = True,
+):
+    if loader_type == "torch":
+        repeated_data = InfiniteRepeatDataset(dataset)
+        return torch.utils.data.DataLoader(
+            repeated_data,
+            batch_size=batch_size,
+            shuffle=shuffle,
+            num_workers=4,
+            pin_memory=True,
+            persistent_workers=True,
+            prefetch_factor=16,
+        )
diff --git a/basic/fast_train.py b/basic/fast_train.py
new file mode 100644
index 0000000..86159f6
--- /dev/null
+++ b/basic/fast_train.py
@@ -0,0 +1,885 @@
+# The code is modified from https://github.com/tysam-code/hlb-CIFAR10
+# Note: The one change we need to make if we're in Colab is to uncomment this below block.
+# If we are in an ipython session or a notebook, clear the state to avoid bugs
+"""
+try:
+  _ = get_ipython().__class__.__name__
+  ## we set -f below to avoid prompting the user before clearing the notebook state
+  %reset -f
+except NameError:
+  pass ## we're still good
+"""
+import copy
+import math
+from functools import partial
+
+import torch
+import torch.nn.functional as F
+
+# from dataset import get_dataloader, get_dataset, get_dataset_subset
+from torch import nn
+
+default_conv_kwargs = {"kernel_size": 3, "padding": "same", "bias": False}
+
+batchsize = 1024
+bias_scaler = 56
+hyp = {
+    "opt": {
+        "bias_lr": 1.64
+        * bias_scaler
+        / 512,  # TODO: Is there maybe a better way to express the bias and batchnorm scaling? :'))))
+        "non_bias_lr": 1.64 / 512,
+        "bias_decay": 1.08 * 6.45e-4 * batchsize / bias_scaler,
+        "non_bias_decay": 1.08 * 6.45e-4 * batchsize,
+        "scaling_factor": 1.0 / 9,
+        "percent_start": 0.23,
+        "loss_scale_scaler": 1.0
+        / 128,  # * Regularizer inside the loss summing (range: ~1/512 - 16+). FP8 should help with this somewhat too, whenever it comes out. :)
+    },
+    "net": {
+        "whitening": {
+            "kernel_size": 2,
+            "num_examples": 50000,
+        },
+        "batch_norm_momentum": 0.5,
+        "conv_norm_pow": 2.6,
+        "cutmix_size": 3,
+        "cutmix_epochs": 6,
+        "pad_amount": 2,
+        "base_depth": 64,  ## This should be a factor of 8 in some way to stay tensor core friendly
+    },
+    "misc": {
+        "ema": {
+            "epochs": 10,
+            "decay_base": 0.95,
+            "decay_pow": 3.0,
+            "every_n_steps": 5,
+        },
+        "train_epochs": 12.1,
+        "device": "cuda",
+        "data_location": "data.pt",
+    },
+}
+
+scaler = 2.0
+depths = {
+    "init": round(
+        scaler**-1 * hyp["net"]["base_depth"]
+    ),  # 32  w/ scaler at base value
+    "block1": round(
+        scaler**0 * hyp["net"]["base_depth"]
+    ),  # 64  w/ scaler at base value
+    "block2": round(
+        scaler**2 * hyp["net"]["base_depth"]
+    ),  # 256 w/ scaler at base value
+    "block3": round(
+        scaler**3 * hyp["net"]["base_depth"]
+    ),  # 512 w/ scaler at base value
+    "num_classes": 10,
+}
+logging_columns_list = [
+    "epoch",
+    "train_loss",
+    "val_loss",
+    "train_acc",
+    "val_acc",
+    "ema_val_acc",
+    "total_time_seconds",
+]
+
+
+#############################################
+#                Dataloader                 #
+#############################################
+def get_cifar10_data(dataset, train_index, test_index, device="cuda"):
+    train_dataset_gpu_loader = torch.utils.data.DataLoader(
+        torch.utils.data.Subset(dataset, train_index),
+        batch_size=len(train_index),
+        drop_last=False,
+        shuffle=True,
+        num_workers=2,
+        persistent_workers=False,
+    )
+    eval_dataset_gpu_loader = torch.utils.data.DataLoader(
+        torch.utils.data.Subset(dataset, test_index),
+        batch_size=len(test_index),
+        drop_last=False,
+        shuffle=False,
+        num_workers=1,
+        persistent_workers=False,
+    )
+
+    train_dataset_gpu = {}
+    eval_dataset_gpu = {}
+
+    train_dataset_gpu["images"], train_dataset_gpu["targets"] = [
+        item.to(device=device, non_blocking=True)
+        for item in next(iter(train_dataset_gpu_loader))
+    ]
+    eval_dataset_gpu["images"], eval_dataset_gpu["targets"] = [
+        item.to(device=device, non_blocking=True)
+        for item in next(iter(eval_dataset_gpu_loader))
+    ]
+
+    cifar10_std, cifar10_mean = torch.std_mean(
+        train_dataset_gpu["images"], dim=(0, 2, 3)
+    )  # dynamically calculate the std and mean from the data. this shortens the code and should help us adapt to new datasets!
+
+    def batch_normalize_images(input_images, mean, std):
+        return (input_images - mean.view(1, -1, 1, 1)) / std.view(1, -1, 1, 1)
+
+    # preload with our mean and std
+    batch_normalize_images = partial(
+        batch_normalize_images, mean=cifar10_mean, std=cifar10_std
+    )
+
+    ## Batch normalize datasets, now. Wowie. We did it! We should take a break and make some tea now.
+    train_dataset_gpu["images"] = batch_normalize_images(train_dataset_gpu["images"])
+    eval_dataset_gpu["images"] = batch_normalize_images(eval_dataset_gpu["images"])
+
+    data = {"train": train_dataset_gpu, "eval": eval_dataset_gpu}
+
+    ## Convert dataset to FP16 now for the rest of the process....
+    data["train"]["images"] = data["train"]["images"].half().requires_grad_(False)
+    data["eval"]["images"] = data["eval"]["images"].half().requires_grad_(False)
+
+    # Convert this to one-hot to support the usage of cutmix (or whatever strange label tricks/magic you desire!)
+    data["train"]["targets"] = F.one_hot(data["train"]["targets"]).half()
+    data["eval"]["targets"] = F.one_hot(data["eval"]["targets"]).half()
+
+    if (
+        hyp["net"]["pad_amount"] > 0
+    ):  # Note: if F.pad doesn't work with half(), it means it's on the cpu (only works with cuda)
+        data["train"]["images"] = F.pad(
+            data["train"]["images"], (hyp["net"]["pad_amount"],) * 4, "reflect"
+        )
+    return data
+
+
+#############################################
+#            Network Components             #
+#############################################
+
+
+class BatchNorm(nn.BatchNorm2d):
+    def __init__(
+        self,
+        num_features,
+        eps=1e-12,
+        momentum=hyp["net"]["batch_norm_momentum"],
+        weight=False,
+        bias=True,
+    ):
+        super().__init__(num_features, eps=eps, momentum=momentum)
+        self.weight.data.fill_(1.0)
+        self.bias.data.fill_(0.0)
+        self.weight.requires_grad = weight
+        self.bias.requires_grad = bias
+
+
+# Allows us to set default arguments for the whole convolution itself.
+# Having an outer class like this does add space and complexity but offers us
+# a ton of freedom when it comes to hacking in unique functionality for each layer type
+class Conv(nn.Conv2d):
+    def __init__(self, *args, norm=False, **kwargs):
+        kwargs = {**default_conv_kwargs, **kwargs}
+        super().__init__(*args, **kwargs)
+        self.kwargs = kwargs
+        self.norm = norm
+
+    def forward(self, x):
+        if self.training and self.norm:
+            # TODO: Do/should we always normalize along dimension 1 of the weight vector(s), or the height x width dims too?
+            with torch.no_grad():
+                F.normalize(self.weight.data, p=self.norm)
+        return super().forward(x)
+
+
+class Linear(nn.Linear):
+    def __init__(self, *args, norm=False, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.kwargs = kwargs
+        self.norm = norm
+
+    def forward(self, x):
+        if self.training and self.norm:
+            # TODO: Normalize on dim 1 or dim 0 for this guy?
+            with torch.no_grad():
+                F.normalize(self.weight.data, p=self.norm)
+        return super().forward(x)
+
+
+# can hack any changes to each residual group that you want directly in here
+class ConvGroup(nn.Module):
+    def __init__(self, channels_in, channels_out, norm):
+        super().__init__()
+        self.channels_in = channels_in
+        self.channels_out = channels_out
+
+        self.pool1 = nn.MaxPool2d(2)
+        self.conv1 = Conv(channels_in, channels_out, norm=norm)
+        self.conv2 = Conv(channels_out, channels_out, norm=norm)
+
+        self.norm1 = BatchNorm(channels_out)
+        self.norm2 = BatchNorm(channels_out)
+
+        self.activ = nn.GELU()
+
+    def forward(self, x):
+        x = self.conv1(x)
+        x = self.pool1(x)
+        x = self.norm1(x)
+        x = self.activ(x)
+        residual = x
+        x = self.conv2(x)
+        x = self.norm2(x)
+        x = self.activ(x)
+        x = x + residual  # haiku
+        return x
+
+
+class TemperatureScaler(nn.Module):
+    def __init__(self, init_val):
+        super().__init__()
+        self.scaler = torch.tensor(init_val)
+
+    def forward(self, x):
+        return x.mul(self.scaler)
+
+
+class FastGlobalMaxPooling(nn.Module):
+    def __init__(self):
+        super().__init__()
+
+    def forward(self, x):
+        # Previously was chained torch.max calls.
+        # requires less time than AdaptiveMax2dPooling -- about ~.3s for the entire run, in fact (which is pretty significant! :O :D :O :O <3 <3 <3 <3)
+        return torch.amax(x, dim=(2, 3))  # Global maximum pooling
+
+
+#############################################
+#          Init Helper Functions            #
+#############################################
+
+
+def get_patches(x, patch_shape=(3, 3), dtype=torch.float32):
+    # This uses the unfold operation (https://pytorch.org/docs/stable/generated/torch.nn.functional.unfold.html?highlight=unfold#torch.nn.functional.unfold)
+    # to extract a _view_ (i.e., there's no data copied here) of blocks in the input tensor. We have to do it twice -- once horizontally, once vertically. Then
+    # from that, we get our kernel_size*kernel_size patches to later calculate the statistics for the whitening tensor on :D
+    c, (h, w) = x.shape[1], patch_shape
+    return (
+        x.unfold(2, h, 1).unfold(3, w, 1).transpose(1, 3).reshape(-1, c, h, w).to(dtype)
+    )  # TODO: Annotate?
+
+
+def get_whitening_parameters(patches):
+    # As a high-level summary, we're basically finding the high-dimensional oval that best fits the data here.
+    # We can then later use this information to map the input information to a nicely distributed sphere, where also
+    # the most significant features of the inputs each have their own axis. This significantly cleans things up for the
+    # rest of the neural network and speeds up training.
+    n, c, h, w = patches.shape
+    est_covariance = torch.cov(patches.view(n, c * h * w).t())
+    eigenvalues, eigenvectors = torch.linalg.eigh(
+        est_covariance, UPLO="U"
+    )  # this is the same as saying we want our eigenvectors, with the specification that the matrix be an upper triangular matrix (instead of a lower-triangular matrix)
+    return eigenvalues.flip(0).view(-1, 1, 1, 1), eigenvectors.t().reshape(
+        c * h * w, c, h, w
+    ).flip(0)
+
+
+# Run this over the training set to calculate the patch statistics, then set the initial convolution as a non-learnable 'whitening' layer
+def init_whitening_conv(
+    layer,
+    train_set=None,
+    num_examples=None,
+    previous_block_data=None,
+    pad_amount=None,
+    freeze=True,
+    whiten_splits=None,
+):
+    if train_set is not None and previous_block_data is None:
+        if pad_amount > 0:
+            previous_block_data = train_set[
+                :num_examples, :, pad_amount:-pad_amount, pad_amount:-pad_amount
+            ]  # if it's none, we're at the beginning of our network.
+        else:
+            previous_block_data = train_set[:num_examples, :, :, :]
+
+    # chunking code to save memory for smaller-memory-size (generally consumer) GPUs
+    if whiten_splits is None:
+        previous_block_data_split = [
+            previous_block_data
+        ]  # If we're whitening in one go, then put it in a list for simplicity to reuse the logic below
+    else:
+        previous_block_data_split = previous_block_data.split(
+            whiten_splits, dim=0
+        )  # Otherwise, we split this into different chunks to keep things manageable
+
+    eigenvalue_list, eigenvector_list = [], []
+    for data_split in previous_block_data_split:
+        eigenvalues, eigenvectors = get_whitening_parameters(
+            get_patches(data_split, patch_shape=layer.weight.data.shape[2:])
+        )
+        eigenvalue_list.append(eigenvalues)
+        eigenvector_list.append(eigenvectors)
+
+    eigenvalues = torch.stack(eigenvalue_list, dim=0).mean(0)
+    eigenvectors = torch.stack(eigenvector_list, dim=0).mean(0)
+    # i believe the eigenvalues and eigenvectors come out in float32 for this because we implicitly cast it to float32 in the patches function (for numerical stability)
+    set_whitening_conv(
+        layer,
+        eigenvalues.to(dtype=layer.weight.dtype),
+        eigenvectors.to(dtype=layer.weight.dtype),
+        freeze=freeze,
+    )
+    data = layer(previous_block_data.to(dtype=layer.weight.dtype))
+    return data
+
+
+def set_whitening_conv(conv_layer, eigenvalues, eigenvectors, eps=1e-2, freeze=True):
+    shape = conv_layer.weight.data.shape
+    conv_layer.weight.data[-eigenvectors.shape[0] :, :, :, :] = (
+        eigenvectors / torch.sqrt(eigenvalues + eps)
+    )[
+        -shape[0] :, :, :, :
+    ]  # set the first n filters of the weight data to the top n significant (sorted by importance) filters from the eigenvectors
+    ## We don't want to train this, since this is implicitly whitening over the whole dataset
+    ## For more info, see David Page's original blogposts (link in the README.md as of this commit.)
+    if freeze:
+        conv_layer.weight.requires_grad = False
+
+
+#############################################
+#            Network Definition             #
+#############################################
+
+
+class SpeedyResNet(nn.Module):
+    def __init__(self, network_dict):
+        super().__init__()
+        self.net_dict = network_dict  # flexible, defined in the make_net function
+
+    # This allows you to customize/change the execution order of the network as needed.
+    def forward(self, x):
+        if not self.training:
+            x = torch.cat((x, torch.flip(x, (-1,))))
+        x = self.net_dict["initial_block"]["whiten"](x)
+        x = self.net_dict["initial_block"]["project"](x)
+        x = self.net_dict["initial_block"]["activation"](x)
+        x = self.net_dict["residual1"](x)
+        x = self.net_dict["residual2"](x)
+        x = self.net_dict["residual3"](x)
+        x = self.net_dict["pooling"](x)
+        x = self.net_dict["linear"](x)
+        x = self.net_dict["temperature"](x)
+        if not self.training:
+            # Average the predictions from the lr-flipped inputs during eval
+            orig, flipped = x.split(x.shape[0] // 2, dim=0)
+            x = 0.5 * orig + 0.5 * flipped
+        return x
+
+
+def make_net(data, hyp=hyp, depths=depths, device="cuda"):
+    whiten_conv_depth = 3 * hyp["net"]["whitening"]["kernel_size"] ** 2
+    network_dict = nn.ModuleDict(
+        {
+            "initial_block": nn.ModuleDict(
+                {
+                    "whiten": Conv(
+                        3,
+                        whiten_conv_depth,
+                        kernel_size=hyp["net"]["whitening"]["kernel_size"],
+                        padding=0,
+                    ),
+                    "project": Conv(
+                        whiten_conv_depth, depths["init"], kernel_size=1, norm=2.2
+                    ),  # The norm argument means we renormalize the weights to be length 1 for this as the power for the norm, each step
+                    "activation": nn.GELU(),
+                }
+            ),
+            "residual1": ConvGroup(
+                depths["init"], depths["block1"], hyp["net"]["conv_norm_pow"]
+            ),
+            "residual2": ConvGroup(
+                depths["block1"], depths["block2"], hyp["net"]["conv_norm_pow"]
+            ),
+            "residual3": ConvGroup(
+                depths["block2"], depths["block3"], hyp["net"]["conv_norm_pow"]
+            ),
+            "pooling": FastGlobalMaxPooling(),
+            "linear": Linear(
+                depths["block3"], depths["num_classes"], bias=False, norm=5.0
+            ),
+            "temperature": TemperatureScaler(hyp["opt"]["scaling_factor"]),
+        }
+    )
+
+    net = SpeedyResNet(network_dict)
+    net = net.to(device)
+    net = net.to(
+        memory_format=torch.channels_last
+    )  # to appropriately use tensor cores/avoid thrash while training
+    net.train()
+    net.half()  # Convert network to half before initializing the initial whitening layer.
+
+    ## Initialize the whitening convolution
+    with torch.no_grad():
+        # Initialize the first layer to be fixed weights that whiten the expected input values of the network be on the unit hypersphere. (i.e. their...average vector length is 1.?, IIRC)
+        init_whitening_conv(
+            net.net_dict["initial_block"]["whiten"],
+            data["train"]["images"].index_select(
+                0,
+                torch.randperm(
+                    data["train"]["images"].shape[0],
+                    device=data["train"]["images"].device,
+                ),
+            ),
+            num_examples=hyp["net"]["whitening"]["num_examples"],
+            pad_amount=hyp["net"]["pad_amount"],
+            whiten_splits=5000,
+        )  ## Hardcoded for now while we figure out the optimal whitening number
+        torch.nn.init.dirac_(net.net_dict["initial_block"]["project"].weight)
+
+        for layer_name in net.net_dict.keys():
+            if "residual" in layer_name:
+                torch.nn.init.dirac_(net.net_dict[layer_name].conv2.weight)
+
+    return net
+
+
+#############################################
+#            Data Preprocessing             #
+#############################################
+
+
+## This is actually (I believe) a pretty clean implementation of how to do something like this, since shifted-square masks unique to each depth-channel can actually be rather
+## tricky in practice. That said, if there's a better way, please do feel free to submit it! This can be one of the harder parts of the code to understand (though I personally get
+## stuck on the fold/unfold process for the lower-level convolution calculations.
+def make_random_square_masks(inputs, mask_size):
+    ##### TODO: Double check that this properly covers the whole range of values. :'( :')
+    if mask_size == 0:
+        return None  # no need to cutout or do anything like that since the patch_size is set to 0
+    is_even = int(mask_size % 2 == 0)
+    in_shape = inputs.shape
+
+    # seed centers of squares to cutout boxes from, in one dimension each
+    mask_center_y = torch.empty(
+        in_shape[0], dtype=torch.long, device=inputs.device
+    ).random_(mask_size // 2 - is_even, in_shape[-2] - mask_size // 2 - is_even)
+    mask_center_x = torch.empty(
+        in_shape[0], dtype=torch.long, device=inputs.device
+    ).random_(mask_size // 2 - is_even, in_shape[-1] - mask_size // 2 - is_even)
+
+    # measure distance, using the center as a reference point
+    to_mask_y_dists = torch.arange(in_shape[-2], device=inputs.device).view(
+        1, 1, in_shape[-2], 1
+    ) - mask_center_y.view(-1, 1, 1, 1)
+    to_mask_x_dists = torch.arange(in_shape[-1], device=inputs.device).view(
+        1, 1, 1, in_shape[-1]
+    ) - mask_center_x.view(-1, 1, 1, 1)
+
+    to_mask_y = (to_mask_y_dists >= (-(mask_size // 2) + is_even)) * (
+        to_mask_y_dists <= mask_size // 2
+    )
+    to_mask_x = (to_mask_x_dists >= (-(mask_size // 2) + is_even)) * (
+        to_mask_x_dists <= mask_size // 2
+    )
+
+    final_mask = (
+        to_mask_y * to_mask_x
+    )  ## Turn (y by 1) and (x by 1) boolean masks into (y by x) masks through multiplication. Their intersection is square, hurray! :D
+
+    return final_mask
+
+
+def batch_cutmix(inputs, targets, patch_size, device="cuda"):
+    with torch.no_grad():
+        batch_permuted = torch.randperm(inputs.shape[0], device=device)
+        cutmix_batch_mask = make_random_square_masks(inputs, patch_size)
+        if cutmix_batch_mask is None:
+            return (
+                inputs,
+                targets,
+            )  # if the mask is None, then that's because the patch size was set to 0 and we will not be using cutmix today.
+        # We draw other samples from inside of the same batch
+        cutmix_batch = torch.where(
+            cutmix_batch_mask, torch.index_select(inputs, 0, batch_permuted), inputs
+        )
+        cutmix_targets = torch.index_select(targets, 0, batch_permuted)
+        # Get the percentage of each target to mix for the labels by the % proportion of pixels in the mix
+        portion_mixed = float(patch_size**2) / (inputs.shape[-2] * inputs.shape[-1])
+        cutmix_labels = portion_mixed * cutmix_targets + (1.0 - portion_mixed) * targets
+        return cutmix_batch, cutmix_labels
+
+
+def batch_crop(inputs, crop_size):
+    with torch.no_grad():
+        crop_mask_batch = make_random_square_masks(inputs, crop_size)
+        cropped_batch = torch.masked_select(inputs, crop_mask_batch).view(
+            inputs.shape[0], inputs.shape[1], crop_size, crop_size
+        )
+        return cropped_batch
+
+
+def batch_flip_lr(batch_images, flip_chance=0.5):
+    with torch.no_grad():
+        return torch.where(
+            torch.rand_like(batch_images[:, 0, 0, 0].view(-1, 1, 1, 1)) < flip_chance,
+            torch.flip(batch_images, (-1,)),
+            batch_images,
+        )
+
+
+########################################
+#          Training Helpers            #
+########################################
+
+
+class NetworkEMA(nn.Module):
+    def __init__(self, net):
+        super().__init__()  # init the parent module so this module is registered properly
+        self.net_ema = copy.deepcopy(net).eval().requires_grad_(False)  # copy the model
+
+    def update(self, current_net, decay):
+        with torch.no_grad():
+            for ema_net_parameter, (parameter_name, incoming_net_parameter) in zip(
+                self.net_ema.state_dict().values(), current_net.state_dict().items()
+            ):  # potential bug: assumes that the network architectures don't change during training (!!!!)
+                if incoming_net_parameter.dtype in (torch.half, torch.float):
+                    ema_net_parameter.mul_(decay).add_(
+                        incoming_net_parameter.detach().mul(1.0 - decay)
+                    )  # update the ema values in place, similar to how optimizer momentum is coded
+                    # And then we also copy the parameters back to the network, similarly to the Lookahead optimizer (but with a much more aggressive-at-the-end schedule)
+                    if not (
+                        "norm" in parameter_name and "weight" in parameter_name
+                    ) and not ("whiten" in parameter_name):
+                        incoming_net_parameter.copy_(ema_net_parameter.detach())
+
+    def forward(self, inputs):
+        with torch.no_grad():
+            return self.net_ema(inputs)
+
+
+# TODO: Could we jit this in the (more distant) future? :)
+@torch.no_grad()
+def get_batches(
+    data_dict,
+    key,
+    batchsize,
+    epoch_fraction=1.0,
+    cutmix_size=None,
+    shuffle=True,
+    device="cuda",
+):
+    num_epoch_examples = len(data_dict[key]["images"])
+    if shuffle:
+        shuffled = torch.randperm(num_epoch_examples, device=device)
+    else:
+        shuffled = torch.arange(0, num_epoch_examples, device=device)
+    if epoch_fraction < 1:
+        shuffled = shuffled[
+            : batchsize * round(epoch_fraction * shuffled.shape[0] / batchsize)
+        ]  # TODO: Might be slightly inaccurate, let's fix this later... :) :D :confetti: :fireworks:
+        num_epoch_examples = shuffled.shape[0]
+    crop_size = 32
+    ## Here, we prep the dataset by applying all data augmentations in batches ahead of time before each epoch, then we return an iterator below
+    ## that iterates in chunks over with a random derangement (i.e. shuffled indices) of the individual examples. So we get perfectly-shuffled
+    ## batches (which skip the last batch if it's not a full batch), but everything seems to be (and hopefully is! :D) properly shuffled. :)
+    if key == "train":
+        images = batch_crop(
+            data_dict[key]["images"], crop_size
+        )  # TODO: hardcoded image size for now?
+        images = batch_flip_lr(images)
+        images, targets = batch_cutmix(
+            images, data_dict[key]["targets"], patch_size=cutmix_size, device=device
+        )
+    else:
+        images = data_dict[key]["images"]
+        targets = data_dict[key]["targets"]
+
+    # Send the images to an (in beta) channels_last to help improve tensor core occupancy (and reduce NCHW <-> NHWC thrash) during training
+    images = images.to(memory_format=torch.channels_last)
+    for idx in range(num_epoch_examples // batchsize):
+        if (
+            not (idx + 1) * batchsize > num_epoch_examples
+        ):  ## Use the shuffled randperm to assemble individual items into a minibatch
+            yield images.index_select(
+                0, shuffled[idx * batchsize : (idx + 1) * batchsize]
+            ), targets.index_select(
+                0, shuffled[idx * batchsize : (idx + 1) * batchsize]
+            )  ## Each item is only used/accessed by the network once per epoch. :D
+
+
+def init_split_parameter_dictionaries(network):
+    params_non_bias = {
+        "params": [],
+        "lr": hyp["opt"]["non_bias_lr"],
+        "momentum": 0.85,
+        "nesterov": True,
+        "weight_decay": hyp["opt"]["non_bias_decay"],
+        "foreach": True,
+    }
+    params_bias = {
+        "params": [],
+        "lr": hyp["opt"]["bias_lr"],
+        "momentum": 0.85,
+        "nesterov": True,
+        "weight_decay": hyp["opt"]["bias_decay"],
+        "foreach": True,
+    }
+
+    for name, p in network.named_parameters():
+        if p.requires_grad:
+            if "bias" in name:
+                params_bias["params"].append(p)
+            else:
+                params_non_bias["params"].append(p)
+    return params_non_bias, params_bias
+
+
+# define the printing function and print the column heads
+def print_training_details(
+    columns_list,
+    separator_left="|  ",
+    separator_right="  ",
+    final="|",
+    column_heads_only=False,
+    is_final_entry=False,
+):
+    print_string = ""
+    if column_heads_only:
+        for column_head_name in columns_list:
+            print_string += separator_left + column_head_name + separator_right
+        print_string += final
+        print("-" * (len(print_string)))  # print the top bar
+        print(print_string)
+        print("-" * (len(print_string)))  # print the bottom bar
+    else:
+        for column_value in columns_list:
+            print_string += separator_left + column_value + separator_right
+        print_string += final
+        print(print_string)
+    if is_final_entry:
+        print("-" * (len(print_string)))  # print the final output bar
+
+
+########################################
+#           Train and Eval             #
+########################################
+
+
+def fast_train_fun(
+    data, net, hyp=hyp, batchsize=batchsize, eval_batchsize=2500, device="cuda"
+):
+    # Initializing constants for the whole run.
+    net_ema = None  ## Reset any existing network emas, we want to have _something_ to check for existence so we can initialize the EMA right from where the network is during training
+    ## (as opposed to initializing the network_ema from the randomly-initialized starter network, then forcing it to play catch-up all of a sudden in the last several epochs)
+
+    ## Hey look, it's the soft-targets/label-smoothed loss! Native to PyTorch. Now, _that_ is pretty cool, and simplifies things a lot, to boot! :D :)
+
+    loss_fn = nn.CrossEntropyLoss(label_smoothing=0.2, reduction="none")
+
+    total_time_seconds = 0.0
+    current_steps = 0.0
+
+    # TODO: Doesn't currently account for partial epochs really (since we're not doing "real" epochs across the whole batchsize)....
+    num_steps_per_epoch = len(data["train"]["images"]) // batchsize
+    total_train_steps = math.ceil(num_steps_per_epoch * hyp["misc"]["train_epochs"])
+    ema_epoch_start = (
+        math.floor(hyp["misc"]["train_epochs"]) - hyp["misc"]["ema"]["epochs"]
+    )
+
+    ## I believe this wasn't logged, but the EMA update power is adjusted by being raised to the power of the number of "every n" steps
+    ## to somewhat accomodate for whatever the expected information intake rate is. The tradeoff I believe, though, is that this is to some degree noisier as we
+    ## are intaking fewer samples of our distribution-over-time, with a higher individual weight each. This can be good or bad depending upon what we want.
+    projected_ema_decay_val = (
+        hyp["misc"]["ema"]["decay_base"] ** hyp["misc"]["ema"]["every_n_steps"]
+    )
+
+    # Adjust pct_start based upon how many epochs we need to finetune the ema at a low lr for
+    pct_start = hyp["opt"][
+        "percent_start"
+    ]  # * (total_train_steps/(total_train_steps - num_low_lr_steps_for_ema))
+
+    # # Get network
+    # net = make_net()
+
+    ## Stowing the creation of these into a helper function to make things a bit more readable....
+    non_bias_params, bias_params = init_split_parameter_dictionaries(net)
+    opt = torch.optim.SGD(**non_bias_params)
+    opt_bias = torch.optim.SGD(**bias_params)
+
+    initial_div_factor = 1e16  # basically to make the initial lr ~0 or so :D
+    final_lr_ratio = 0.07  # Actually pretty important, apparently!
+    lr_sched = torch.optim.lr_scheduler.OneCycleLR(
+        opt,
+        max_lr=non_bias_params["lr"],
+        pct_start=pct_start,
+        div_factor=initial_div_factor,
+        final_div_factor=1.0 / (initial_div_factor * final_lr_ratio),
+        total_steps=total_train_steps,
+        anneal_strategy="linear",
+        cycle_momentum=False,
+    )
+    lr_sched_bias = torch.optim.lr_scheduler.OneCycleLR(
+        opt_bias,
+        max_lr=bias_params["lr"],
+        pct_start=pct_start,
+        div_factor=initial_div_factor,
+        final_div_factor=1.0 / (initial_div_factor * final_lr_ratio),
+        total_steps=total_train_steps,
+        anneal_strategy="linear",
+        cycle_momentum=False,
+    )
+
+    ## For accurately timing GPU code
+    starter, ender = torch.cuda.Event(enable_timing=True), torch.cuda.Event(
+        enable_timing=True
+    )
+    torch.cuda.synchronize()  ## clean up any pre-net setup operations
+
+    if (
+        True
+    ):  ## Sometimes we need a conditional/for loop here, this is placed to save the trouble of needing to indent
+        for epoch in range(math.ceil(hyp["misc"]["train_epochs"])):
+            #################
+            # Training Mode #
+            #################
+            torch.cuda.synchronize()
+            starter.record()
+            net.train()
+
+            loss_train = None
+            accuracy_train = None
+
+            cutmix_size = (
+                hyp["net"]["cutmix_size"]
+                if epoch >= hyp["misc"]["train_epochs"] - hyp["net"]["cutmix_epochs"]
+                else 0
+            )
+            epoch_fraction = (
+                1
+                if epoch + 1 < hyp["misc"]["train_epochs"]
+                else hyp["misc"]["train_epochs"] % 1
+            )  # We need to know if we're running a partial epoch or not.
+
+            for epoch_step, (inputs, targets) in enumerate(
+                get_batches(
+                    data,
+                    key="train",
+                    batchsize=batchsize,
+                    epoch_fraction=epoch_fraction,
+                    cutmix_size=cutmix_size,
+                    device=device,
+                )
+            ):
+                ## Run everything through the network
+                outputs = net(inputs)
+
+                loss_batchsize_scaler = (
+                    512 / batchsize
+                )  # to scale to keep things at a relatively similar amount of regularization when we change our batchsize since we're summing over the whole batch
+                ## If you want to add other losses or hack around with the loss, you can do that here.
+                loss = (
+                    loss_fn(outputs, targets)
+                    .mul(hyp["opt"]["loss_scale_scaler"] * loss_batchsize_scaler)
+                    .sum()
+                    .div(hyp["opt"]["loss_scale_scaler"])
+                )  ## Note, as noted in the original blog posts, the summing here does a kind of loss scaling
+                ## (and is thus batchsize dependent as a result). This can be somewhat good or bad, depending...
+
+                # we only take the last-saved accs and losses from train
+                if epoch_step % 50 == 0:
+                    train_acc = (
+                        (outputs.detach().argmax(-1) == targets.argmax(-1))
+                        .float()
+                        .mean()
+                        .item()
+                    )
+                    train_loss = loss.detach().cpu().item() / (
+                        batchsize * loss_batchsize_scaler
+                    )
+
+                loss.backward()
+
+                ## Step for each optimizer, in turn.
+                opt.step()
+                opt_bias.step()
+
+                # We only want to step the lr_schedulers while we have training steps to consume. Otherwise we get a not-so-friendly error from PyTorch
+                lr_sched.step()
+                lr_sched_bias.step()
+
+                ## Using 'set_to_none' I believe is slightly faster (albeit riskier w/ funky gradient update workflows) than under the default 'set to zero' method
+                opt.zero_grad(set_to_none=True)
+                opt_bias.zero_grad(set_to_none=True)
+                current_steps += 1
+
+                if (
+                    epoch >= ema_epoch_start
+                    and current_steps % hyp["misc"]["ema"]["every_n_steps"] == 0
+                ):
+                    ## Initialize the ema from the network at this point in time if it does not already exist.... :D
+                    if net_ema is None:  # don't snapshot the network yet if so!
+                        net_ema = NetworkEMA(net)
+                        continue
+                    # We warm up our ema's decay/momentum value over training exponentially according to the hyp config dictionary (this lets us move fast, then average strongly at the end).
+                    net_ema.update(
+                        net,
+                        decay=projected_ema_decay_val
+                        * (current_steps / total_train_steps)
+                        ** hyp["misc"]["ema"]["decay_pow"],
+                    )
+
+            ender.record()
+            torch.cuda.synchronize()
+            total_time_seconds += 1e-3 * starter.elapsed_time(ender)
+
+            ####################
+            # Evaluation  Mode #
+            ####################
+            net.eval()
+            assert (
+                data["eval"]["images"].shape[0] % eval_batchsize == 0
+            ), "Error: The eval batchsize must evenly divide the eval dataset (for now, we don't have drop_remainder implemented yet)."
+            loss_list_val, acc_list, acc_list_ema = [], [], []
+
+            with torch.no_grad():
+                for inputs, targets in get_batches(
+                    data, key="eval", batchsize=eval_batchsize, device=device
+                ):
+                    if epoch >= ema_epoch_start:
+                        outputs = net_ema(inputs)
+                        acc_list_ema.append(
+                            (outputs.argmax(-1) == targets.argmax(-1)).float().mean()
+                        )
+                    outputs = net(inputs)
+                    loss_list_val.append(loss_fn(outputs, targets).float().mean())
+                    acc_list.append(
+                        (outputs.argmax(-1) == targets.argmax(-1)).float().mean()
+                    )
+
+                val_acc = torch.stack(acc_list).mean().item()
+                ema_val_acc = None
+                # TODO: We can fuse these two operations (just above and below) all-together like :D :))))
+                if epoch >= ema_epoch_start:
+                    ema_val_acc = torch.stack(acc_list_ema).mean().item()
+
+                val_loss = torch.stack(loss_list_val).mean().item()
+            format_for_table = (
+                lambda x, locals: (f"{locals[x]}".rjust(len(x)))
+                if type(locals[x]) == int
+                else "{:0.4f}".format(locals[x]).rjust(len(x))
+                if locals[x] is not None
+                else " " * len(x)
+            )
+            print_training_details(
+                list(
+                    map(
+                        partial(format_for_table, locals=locals()), logging_columns_list
+                    )
+                ),
+                is_final_entry=(epoch >= math.ceil(hyp["misc"]["train_epochs"] - 1)),
+            )
+    net_ema.to("cpu")
+    return net_ema, train_acc, train_loss, ema_val_acc, val_loss
diff --git a/basic/main.py b/basic/main.py
new file mode 100644
index 0000000..9926835
--- /dev/null
+++ b/basic/main.py
@@ -0,0 +1,565 @@
+"""This file is the main entry point for running the priavcy auditing."""
+import argparse
+import logging
+import os
+import pickle
+import random
+import time
+from pathlib import Path
+
+import numpy as np
+import torch
+import yaml
+from augment import get_signal_on_augmented_data
+from core import (
+    load_dataset_for_existing_models,
+    load_existing_models,
+    load_existing_target_model,
+    prepare_datasets,
+    prepare_datasets_for_reference_in_attack,
+    prepare_datasets_for_sample_privacy_risk,
+    prepare_information_source,
+    prepare_models,
+    prepare_priavcy_risk_report,
+)
+from dataset import get_dataset, get_dataset_subset
+from plot import plot_roc, plot_signal_histogram
+from scipy.stats import norm
+from sklearn.metrics import auc, roc_curve
+from torch import nn
+from util import (
+    check_configs,
+    load_leave_one_out_models,
+    load_models_with_data_idx_list,
+    load_models_without_data_idx_list,
+    sweep,
+)
+
+from privacy_meter.audit import Audit
+from privacy_meter.model import PytorchModelTensor
+
+torch.backends.cudnn.benchmark = True
+
+
+def setup_log(name: str, save_file: bool):
+    """Generate the logger for the current run.
+    Args:
+        name (str): Logging file name.
+        save_file (bool): Flag about whether to save to file.
+    Returns:
+        logging.Logger: Logger object for the current run.
+    """
+    my_logger = logging.getLogger(name)
+    my_logger.setLevel(logging.INFO)
+    if save_file:
+        log_format = logging.Formatter("%(asctime)s %(levelname)-8s %(message)s")
+        filename = f"log_{name}.log"
+        log_handler = logging.FileHandler(filename, mode="w")
+        log_handler.setLevel(logging.INFO)
+        log_handler.setFormatter(log_format)
+        my_logger.addHandler(log_handler)
+
+    return my_logger
+
+
+if __name__ == "__main__":
+    parser = argparse.ArgumentParser()
+    parser.add_argument(
+        "--cf",
+        type=str,
+        default="basic/config_models_reference_in_out.yaml",
+        help="Yaml file which contains the configurations",
+    )
+
+    # Load the parameters
+    args = parser.parse_args()
+    with open(args.cf, "rb") as f:
+        configs = yaml.load(f, Loader=yaml.Loader)
+
+    check_configs(configs)
+    # Set the random seed, log_dir and inference_game
+    torch.manual_seed(configs["run"]["random_seed"])
+    np.random.seed(configs["run"]["random_seed"])
+    random.seed(configs["run"]["random_seed"])
+
+    log_dir = configs["run"]["log_dir"]
+    inference_game_type = configs["audit"]["privacy_game"].upper()
+
+    # Set up the logger
+    logger = setup_log("time_analysis", configs["run"]["time_log"])
+
+    # Create folders for saving the logs if they do not exist
+    Path(log_dir).mkdir(parents=True, exist_ok=True)
+    report_dir = f"{log_dir}/{configs['audit']['report_log']}"
+    Path(report_dir).mkdir(parents=True, exist_ok=True)
+
+    start_time = time.time()
+
+    # Load or initialize models based on metadata
+    if os.path.exists((f"{log_dir}/models_metadata.pkl")):
+        with open(f"{log_dir}/models_metadata.pkl", "rb") as f:
+            model_metadata_list = pickle.load(f)
+    else:
+        model_metadata_list = {"model_metadata": {}, "current_idx": 0}
+    # Load the dataset
+    baseline_time = time.time()
+    dataset = get_dataset(configs["data"]["dataset"], configs["data"]["data_dir"])
+
+    privacy_game = configs["audit"]["privacy_game"]
+
+    ############################
+    # Privacy auditing for a model or an algorithm
+    ############################
+    if (
+        privacy_game in ["avg_privacy_loss_training_algo", "privacy_loss_model"]
+        and "reference_in_out" not in configs["audit"]["algorithm"]
+    ):
+        # Load the trained models from disk
+        if model_metadata_list["current_idx"] > 0:
+            target_model_idx_list = load_existing_target_model(
+                len(dataset), model_metadata_list, configs
+            )
+            trained_target_dataset_list = load_dataset_for_existing_models(
+                len(dataset),
+                model_metadata_list,
+                target_model_idx_list,
+                configs["data"],
+            )
+
+            trained_target_models_list = load_existing_models(
+                model_metadata_list,
+                target_model_idx_list,
+                configs["train"]["model_name"],
+                dataset,
+                configs["data"]["dataset"],
+            )
+            num_target_models = configs["train"]["num_target_model"] - len(
+                trained_target_dataset_list
+            )
+        else:
+            target_model_idx_list = []
+            trained_target_models_list = []
+            trained_target_dataset_list = []
+            num_target_models = configs["train"]["num_target_model"]
+
+        # Prepare the datasets
+        print(25 * ">" + "Prepare the the datasets")
+        data_split_info = prepare_datasets(
+            len(dataset), num_target_models, configs["data"]
+        )
+
+        logger.info(
+            "Prepare the datasets costs %0.5f seconds", time.time() - baseline_time
+        )
+
+        # Prepare the target models
+        print(25 * ">" + "Prepare the the target models")
+        baseline_time = time.time()
+
+        new_model_list, model_metadata_list, new_target_model_idx_list = prepare_models(
+            log_dir,
+            dataset,
+            data_split_info,
+            configs["train"],
+            model_metadata_list,
+            configs["data"]["dataset"],
+        )
+
+        # Combine the trained models with the existing models
+        model_list = [*new_model_list, *trained_target_models_list]
+        data_split_info["split"] = [
+            *data_split_info["split"],
+            *trained_target_dataset_list,
+        ]
+        target_model_idx_list = [*new_target_model_idx_list, *target_model_idx_list]
+
+        logger.info(
+            "Prepare the target model costs %0.5f seconds", time.time() - baseline_time
+        )
+
+        # Prepare the information sources
+        print(25 * ">" + "Prepare the information source, including attack models")
+        baseline_time = time.time()
+        (
+            target_info_source,
+            reference_info_source,
+            metrics,
+            log_dir_list,
+            model_metadata_list,
+        ) = prepare_information_source(
+            log_dir,
+            dataset,
+            data_split_info,
+            model_list,
+            configs["audit"],
+            model_metadata_list,
+            target_model_idx_list,
+            configs["train"]["model_name"],
+            configs["data"]["dataset"],
+        )
+        logger.info(
+            "Prepare the information source costs %0.5f seconds",
+            time.time() - baseline_time,
+        )
+
+        # Call core of Privacy Meter
+        print(25 * ">" + "Auditing the privacy risk")
+        baseline_time = time.time()
+        audit_obj = Audit(
+            metrics=metrics,
+            inference_game_type=inference_game_type,
+            target_info_sources=target_info_source,
+            reference_info_sources=reference_info_source,
+            fpr_tolerances=None,
+            logs_directory_names=log_dir_list,
+        )
+        audit_obj.prepare()
+        audit_results = audit_obj.run()
+        logger.info(
+            "Prepare the Privacy Meter result costs %0.5f seconds",
+            time.time() - baseline_time,
+        )
+
+        # Generate the privacy risk report
+        print(25 * ">" + "Generating privacy risk report")
+        baseline_time = time.time()
+        prepare_priavcy_risk_report(
+            log_dir,
+            audit_results,
+            configs["audit"],
+            save_path=f"{log_dir}/{configs['audit']['report_log']}",
+        )
+        print(100 * "#")
+
+        logger.info(
+            "Prepare the plot for the privacy risk report costs %0.5f seconds",
+            time.time() - baseline_time,
+        )
+
+    ############################
+    # Privacy auditing for a sample
+    ############################
+    elif configs["audit"]["privacy_game"] == "privacy_loss_sample":
+        # Load existing models that match the requirement
+        assert (
+            "data_idx" in configs["train"]
+        ), "data_idx in config.train is not specified"
+        assert (
+            "data_idx" in configs["audit"]
+        ), "data_idx in config.audit is not specified"
+
+        in_model_idx_list = load_models_with_data_idx_list(
+            model_metadata_list, [configs["train"]["data_idx"]]
+        )
+        model_in_list = load_existing_models(
+            model_metadata_list,
+            in_model_idx_list,
+            configs["train"]["model_name"],
+            dataset,
+            configs["data"]["dataset"],
+        )
+        # Train additional models if the existing models are not enough
+        if len(in_model_idx_list) < configs["train"]["num_in_models"]:
+            data_split_info_in = prepare_datasets_for_sample_privacy_risk(
+                len(dataset),
+                configs["train"]["num_in_models"] - len(in_model_idx_list),
+                configs["train"]["data_idx"],
+                configs["data"],
+                "include",
+                configs["data"]["split_method"],
+                model_metadata_list,
+            )
+            new_in_model_list, model_metadata_list, new_matched_in_idx = prepare_models(
+                log_dir,
+                dataset,
+                data_split_info_in,
+                configs["train"],
+                model_metadata_list,
+                configs["data"]["dataset"],
+            )
+            model_in_list = [*new_in_model_list, *model_in_list]
+            in_model_idx_list = [*new_matched_in_idx, *in_model_idx_list]
+        in_model_list_pm = [
+            PytorchModelTensor(
+                model_obj=model,
+                loss_fn=nn.CrossEntropyLoss(),
+                batch_size=configs["audit"]["audit_batch_size"],
+                device=configs["audit"]["device"],
+            )
+            for model in model_in_list
+        ]
+        if configs["data"]["split_method"] == "uniform":
+            out_model_idx_list = load_models_without_data_idx_list(
+                model_metadata_list, [configs["train"]["data_idx"]]
+            )
+        elif configs["data"]["split_method"] == "leave_one_out":
+            out_model_idx_list = load_leave_one_out_models(
+                model_metadata_list, [configs["train"]["data_idx"]], in_model_idx_list
+            )
+        else:
+            raise ValueError("The split method is not supported")
+
+        model_out_list = load_existing_models(
+            model_metadata_list,
+            out_model_idx_list,
+            configs["train"]["model_name"],
+            dataset,
+            configs["data"]["dataset"],
+        )
+        # Train additional models if the existing models are not enough
+        if len(out_model_idx_list) < configs["train"]["num_out_models"]:
+            data_split_info_out = prepare_datasets_for_sample_privacy_risk(
+                len(dataset),
+                configs["train"]["num_out_models"] - len(out_model_idx_list),
+                configs["train"]["data_idx"],
+                configs["data"],
+                "exclude",
+                configs["data"]["split_method"],
+                model_metadata_list,
+                in_model_idx_list,
+            )
+            (
+                new_out_model_list,
+                model_metadata_list,
+                new_matched_out_idx,
+            ) = prepare_models(
+                log_dir,
+                dataset,
+                data_split_info_out,
+                configs["train"],
+                model_metadata_list,
+                configs["data"]["dataset"],
+            )
+            model_out_list = [*new_out_model_list, *model_out_list]
+            out_model_idx_list = [*new_matched_out_idx, *out_model_idx_list]
+
+        out_model_list_pm = [
+            PytorchModelTensor(
+                model_obj=model,
+                loss_fn=nn.CrossEntropyLoss(),
+                batch_size=configs["audit"]["audit_batch_size"],
+                device=configs["audit"]["device"],
+            )
+            for model in model_out_list
+        ]
+
+        # Test the models' performance on the data indicated by the audit.idx
+        data, targets = get_dataset_subset(
+            dataset,
+            [configs["audit"]["data_idx"]],
+            configs["audit"]["model_name"],
+            device=configs["audit"]["device"],
+        )
+        if configs["audit"]["signal"] == "loss":
+            in_signal = np.array(
+                [model.get_loss(data, targets).item() for model in in_model_list_pm]
+            )
+            out_signal = np.array(
+                [model.get_loss(data, targets).item() for model in out_model_list_pm]
+            )
+        elif configs["audit"]["signal"] == "rescaled_logits":
+            in_signal = np.array(
+                [
+                    -model.get_rescaled_logits(data, targets).item()
+                    for model in in_model_list_pm
+                ]
+            )
+            out_signal = np.array(
+                [
+                    -model.get_rescaled_logits(data, targets).item()
+                    for model in out_model_list_pm
+                ]
+            )
+
+        # Generate the privacy risk report
+        plot_signal_histogram(
+            in_signal,
+            out_signal,
+            configs["train"]["data_idx"],
+            configs["audit"]["data_idx"],
+            f"{log_dir}/{configs['audit']['report_log']}/individual_pr_{configs['train']['data_idx']}_{configs['audit']['data_idx']}.png",
+        )
+        fpr_list, tpr_list, roc_auc = sweep(in_signal, out_signal)
+        plot_roc(
+            fpr_list,
+            tpr_list,
+            roc_auc,
+            f"{log_dir}/{configs['audit']['report_log']}/individual_pr_roc_{configs['train']['data_idx']}_{configs['audit']['data_idx']}.png",
+        )
+
+    ############################
+    # Privacy Auditing for an model with reference_in_out attack
+    ############################
+    elif "reference_in_out" in configs["audit"]["algorithm"]:
+        # The following code of generating the data is modified from the original code in the repo: https://github.com/tensorflow/privacy/tree/master/research/mi_lira_2021
+        baseline_time = time.time()
+        p_ratio = configs["data"]["keep_ratio"]
+        dataset_size = configs["data"]["dataset_size"]
+        number_of_models_total = (
+            configs["audit"]["num_in_models"]
+            + configs["audit"]["num_out_models"]
+            + configs["train"]["num_target_model"]
+        )
+        (
+            data_split_info,
+            keep_matrix,
+            target_data_index,
+        ) = prepare_datasets_for_reference_in_attack(
+            len(dataset),
+            dataset_size,
+            num_models=(number_of_models_total),
+            keep_ratio=p_ratio,
+            is_uniform=False,
+        )
+        data, targets = get_dataset_subset(
+            dataset,
+            target_data_index,
+            configs["train"]["model_name"],
+            device=configs["train"]["device"],
+        )  # only the train dataset we want to attack
+        logger.info(
+            "Prepare the datasets costs %0.5f seconds",
+            time.time() - baseline_time,
+        )
+        baseline_time = time.time()
+        if model_metadata_list["current_idx"] == 0:
+            # if the models are already trained and saved in the disk
+            (model_list, model_metadata_dict, trained_model_idx_list) = prepare_models(
+                log_dir,
+                dataset,
+                data_split_info,
+                configs["train"],
+                model_metadata_list,
+                configs["data"]["dataset"],
+            )
+            logger.info(
+                "Prepare the models costs %0.5f seconds",
+                time.time() - baseline_time,
+            )
+            baseline_time = time.time()
+            signals = []
+            for model in model_list:
+                model_pm = PytorchModelTensor(
+                    model_obj=model,
+                    loss_fn=nn.CrossEntropyLoss(),
+                    device=configs["audit"]["device"],
+                    batch_size=configs["audit"]["audit_batch_size"],
+                )
+                signals.append(
+                    get_signal_on_augmented_data(
+                        model_pm,
+                        data,
+                        targets,
+                        method=configs["audit"]["augmentation"],
+                        signal=configs["audit"]["signal"],
+                    )
+                )
+            logger.info(
+                "Prepare the signals costs %0.5f seconds",
+                time.time() - baseline_time,
+            )
+        else:
+            baseline_time = time.time()
+            signals = []
+            for idx in range(model_metadata_list["current_idx"]):
+                print("Load the model and compute signals for model %d" % idx)
+                model_pm = PytorchModelTensor(
+                    model_obj=load_existing_models(
+                        model_metadata_list,
+                        [idx],
+                        configs["train"]["model_name"],
+                        dataset,
+                        configs["data"]["dataset"],
+                    )[0],
+                    loss_fn=nn.CrossEntropyLoss(),
+                    device=configs["audit"]["device"],
+                    batch_size=10000,
+                )
+                signals.append(
+                    get_signal_on_augmented_data(
+                        model_pm,
+                        data,
+                        targets,
+                        method=configs["audit"]["augmentation"],
+                        signal=configs["audit"]["signal"],
+                    )
+                )
+            logger.info(
+                "Prepare the signals costs %0.5f seconds",
+                time.time() - baseline_time,
+            )
+        baseline_time = time.time()
+        signals = np.array(signals)
+
+        # number of models we want to consider as test
+        num_target = configs["train"]["num_target_model"]
+        target_signal = signals[:num_target, :]
+        reference_signals = signals[num_target:, :]
+        reference_keep_matrix = keep_matrix[num_target:, :]
+        membership = keep_matrix[:num_target, :]
+        in_signals = []
+        out_signals = []
+
+        for data_idx in range(dataset_size):
+            in_signals.append(
+                reference_signals[reference_keep_matrix[:, data_idx], data_idx]
+            )
+            out_signals.append(
+                reference_signals[~reference_keep_matrix[:, data_idx], data_idx]
+            )
+
+        in_size = min(min(map(len, in_signals)), configs["audit"]["num_in_models"])
+        out_size = min(min(map(len, out_signals)), configs["audit"]["num_out_models"])
+        in_signals = np.array([x[:in_size] for x in in_signals]).astype("float32")
+        out_signals = np.array([x[:out_size] for x in out_signals]).astype("float32")
+        mean_in = np.median(in_signals, 1)
+        mean_out = np.median(out_signals, 1)
+        fix_variance = configs["audit"]["fix_variance"]
+        if fix_variance:
+            std_in = np.std(in_signals)
+            std_out = np.std(in_signals)
+        else:
+            std_in = np.std(in_signals, 1)
+            std_out = np.std(out_signals, 1)
+
+        prediction = []
+        answers = []
+        for ans, sc in zip(membership, target_signal):
+            pr_in = -norm.logpdf(sc, mean_in, std_in + 1e-30)
+            pr_out = -norm.logpdf(sc, mean_out, std_out + 1e-30)
+            score = pr_in - pr_out
+            if len(score.shape) == 2:  # the score is of size (data_size, num_augments)
+                prediction.extend(score.mean(1))
+                fpr_list, tpr_list, _ = roc_curve(ans, -score.mean(1))
+            else:
+                prediction.extend(score)
+                fpr_list, tpr_list, _ = roc_curve(ans, -score)
+            answers.extend(ans)
+            acc = np.max(1 - (fpr_list + (1 - tpr_list)) / 2)
+            roc_auc = auc(fpr_list, tpr_list)
+
+        prediction = np.array(prediction)
+        answers = np.array(answers, dtype=bool)
+        fpr_list, tpr_list, _ = roc_curve(answers.ravel(), -prediction.ravel())
+        acc = np.max(1 - (fpr_list + (1 - tpr_list)) / 2)
+        roc_auc = auc(fpr_list, tpr_list)
+        logger.info(
+            "Prepare the privacy risks results costs %0.5f seconds",
+            time.time() - baseline_time,
+        )
+        low = tpr_list[np.where(fpr_list < 0.001)[0][-1]]
+        print("AUC %.4f, Accuracy %.4f, TPR@0.1%%FPR of %.4f" % (roc_auc, acc, low))
+        plot_roc(
+            fpr_list,
+            tpr_list,
+            roc_auc,
+            f"{log_dir}/{configs['audit']['report_log']}/ROC.png",
+        )
+
+    ############################
+    # END
+    ############################
+    logger.info(
+        "Run the priavcy meter for the all steps costs %0.5f seconds",
+        time.time() - start_time,
+    )
diff --git a/experiments/models.py b/basic/models.py
similarity index 57%
rename from experiments/models.py
rename to basic/models.py
index 16813e5..f599759 100644
--- a/experiments/models.py
+++ b/basic/models.py
@@ -1,19 +1,45 @@
 """This file contains the definition of models"""
+import torch
 import torch.nn.functional as F
+import torchvision
 from torch import nn
+from wide_resnet import WideResNet
 
+INPUT_OUTPUT_SHAPE = {
+    "cifar10": [3, 10],
+    "cifar100": [3, 100],
+    "purchase100": [600, 100],
+    "texas100": [6169, 100],
+}
 
-class Net(nn.Module):
+
+class NN(nn.Module):
+    """Simple CNN for CIFAR10 dataset."""
+
+    def __init__(self, in_shape, num_classes=10):
+        super().__init__()
+        self.fc1 = nn.Linear(in_shape, 128)
+        self.fc2 = nn.Linear(128, num_classes)
+
+    def forward(self, inputs):
+        """Forward pass of the model."""
+        inputs = inputs.flatten(1)
+        inputs = torch.tanh(self.fc1(inputs))
+        outputs = self.fc2(inputs)
+        return outputs
+
+
+class CNN(nn.Module):
     """Simple CNN for CIFAR10 dataset."""
 
-    def __init__(self):
+    def __init__(self, num_classes=10):
         super().__init__()
         self.conv1 = nn.Conv2d(3, 6, 5)
         self.pool = nn.MaxPool2d(2, 2)
         self.conv2 = nn.Conv2d(6, 16, 5)
         self.fc1 = nn.Linear(16 * 5 * 5, 120)
         self.fc2 = nn.Linear(120, 84)
-        self.fc3 = nn.Linear(84, 10)
+        self.fc3 = nn.Linear(84, num_classes)
 
     def forward(self, inputs):
         """Forward pass of the model."""
@@ -65,17 +91,31 @@ def forward(self, inputs):
         return outputs
 
 
-def get_model(model_type: str) -> nn.Module:
+def get_model(model_type: str, dataset_name: str):
     """Instantiate the model based on the model_type
 
     Args:
         model_type (str): Name of the model
-
+        dataset_name (str): Name of the dataset
     Returns:
         torch.nn.Module: A model
     """
+    num_classes = INPUT_OUTPUT_SHAPE[dataset_name][1]
+    in_shape = INPUT_OUTPUT_SHAPE[dataset_name][0]
     if model_type == "CNN":
-        return Net()
-    if model_type == "alexnet":
-        return AlexNet()
-    raise NotImplementedError(f"{model_type} is not implemented")
+        return CNN(num_classes=num_classes)
+    elif model_type == "alexnet":
+        return AlexNet(num_classes=num_classes)
+    elif model_type == "wrn28-1":
+        return WideResNet(nin=in_shape, nclass=num_classes, depth=28, width=1)
+    elif model_type == "wrn28-2":
+        return WideResNet(nin=in_shape, nclass=num_classes, depth=28, width=2)
+    elif model_type == "wrn28-10":
+        return WideResNet(nin=in_shape, nclass=num_classes, depth=28, width=10)
+    elif model_type == "nn":
+        # for purchase dataset
+        return NN(in_shape=in_shape, num_classes=num_classes)
+    elif model_type == "vgg16":
+        return torchvision.models.vgg16(pretrained=False)
+    else:
+        raise NotImplementedError(f"{model_type} is not implemented")
diff --git a/basic/plot.py b/basic/plot.py
new file mode 100644
index 0000000..d34bf41
--- /dev/null
+++ b/basic/plot.py
@@ -0,0 +1,114 @@
+"""This file contains ploting functions."""
+
+import matplotlib.pyplot as plt
+import numpy as np
+import pandas as pd
+import seaborn as sns
+
+
+def plot_roc(fpr_list, tpr_list, roc_auc, path):
+    range01 = np.linspace(0, 1)
+    plt.fill_between(fpr_list, tpr_list, alpha=0.15)
+    plt.plot(fpr_list, tpr_list, label="ROC curve")
+    plt.plot(range01, range01, "--", label="Random guess")
+    plt.xlim([0, 1])
+    plt.ylim([0, 1])
+    plt.grid()
+    plt.legend()
+    plt.xlabel("False positive rate (FPR)")
+    plt.ylabel("True positive rate (TPR)")
+    plt.title("ROC curve")
+    plt.text(
+        0.7,
+        0.3,
+        f"AUC = {roc_auc:.03f}",
+        horizontalalignment="center",
+        verticalalignment="center",
+        bbox=dict(facecolor="white", alpha=0.5),
+    )
+    plt.savefig(
+        fname=path,
+        dpi=1000,
+    )
+    plt.clf()
+
+
+def plot_compare_roc(fpr_lists, tpr_lists, roc_aucs, names, path, log_scale=False):
+    range01 = np.linspace(0, 1)
+    for idx in range(len(fpr_lists)):
+        plt.plot(
+            fpr_lists[idx],
+            tpr_lists[idx],
+            label=f"{names[idx]} (AUC = {roc_aucs[idx]:.03f})",
+        )
+    plt.plot(range01, range01, "--", label="Random guess")
+    plt.grid()
+    plt.legend()
+    plt.xlabel("False positive rate (FPR)")
+    plt.ylabel("True positive rate (TPR)")
+    plt.title("ROC curve")
+    if log_scale:
+        plt.xscale("log")
+        plt.yscale("log")
+    else:
+        plt.xlim([0, 1])
+        plt.ylim([0, 1])
+    plt.savefig(
+        fname=path,
+        dpi=1000,
+    )
+    plt.clf()
+
+
+def plot_signal_histogram(
+    in_signal, out_signal, train_data_idx=None, audit_data_idx=None, path=None
+):
+    labels = np.concatenate(
+        [np.ones(in_signal.shape[0]), np.zeros(out_signal.shape[0])]
+    )
+    if train_data_idx is not None:
+        sns.histplot(
+            data=pd.DataFrame(
+                {
+                    "Signal": np.concatenate([in_signal, out_signal]),
+                    "Membership": [
+                        f"In ({train_data_idx})" if y == 1 else f"Out {train_data_idx}"
+                        for y in labels
+                    ],
+                }
+            ),
+            x="Signal",
+            hue="Membership",
+            element="step",
+            kde=True,
+        )
+        plt.grid()
+        plt.xlabel("Signal value")
+        plt.ylabel("Number of Models")
+        plt.title(f"Signal histogram for data point {audit_data_idx}")
+
+    else:
+        sns.histplot(
+            data=pd.DataFrame(
+                {
+                    "Signal": np.concatenate([in_signal, out_signal]),
+                    "Membership": [
+                        "Member" if y == 1 else "Non-member" for y in labels
+                    ],
+                }
+            ),
+            x="Signal",
+            hue="Membership",
+            element="step",
+            kde=True,
+        )
+        plt.grid()
+        plt.xlabel("Signal value")
+        plt.ylabel("Number of Models")
+        plt.title("Signal histogram")
+
+    if path is not None:
+        plt.savefig(path)
+        plt.clf()
+    else:
+        plt.show()
diff --git a/experiments/train.py b/basic/train.py
similarity index 68%
rename from experiments/train.py
rename to basic/train.py
index a08e471..6f289a8 100644
--- a/experiments/train.py
+++ b/basic/train.py
@@ -1,15 +1,18 @@
 """This file contains functions for training and testing the model."""
+import time
 from ast import Tuple
 
 import torch
 from torch import nn
-
 from util import get_optimizer
 
-# Train Function
-
 
-def train(model: torch.nn.Module, train_loader: torch.utils.data.DataLoader, configs: dict):
+def train(
+    model: torch.nn.Module,
+    train_loader: torch.utils.data.DataLoader,
+    configs: dict,
+    test_loader: torch.utils.data.DataLoader = None,
+):
     """Train the model based on on the train loader
     Args:
         model(nn.Module): Model for evaluation.
@@ -24,21 +27,23 @@ def train(model: torch.nn.Module, train_loader: torch.utils.data.DataLoader, con
     # Set the model to the device
     model.to(device)
     model.train()
-
     # Set the loss function and optimizer
     criterion = nn.CrossEntropyLoss()
     optimizer = get_optimizer(model, configs)
-
     # Get the number of epochs for training
     epochs = configs.get("epochs", 1)
+
     # Loop over each epoch
     for epoch_idx in range(epochs):
-        train_loss = 0
+        start_time = time.time()
+        train_loss, train_acc = 0, 0
         # Loop over the training set
+        model.train()
         for data, target in train_loader:
             # Move data to the device
             data, target = data.to(device, non_blocking=True), target.to(
-                device, non_blocking=True)
+                device, non_blocking=True
+            )
             # Cast target to long tensor
             target = target.long()
 
@@ -47,21 +52,39 @@ def train(model: torch.nn.Module, train_loader: torch.utils.data.DataLoader, con
 
             # Get the model output
             output = model(data)
-
             # Calculate the loss
             loss = criterion(output, target)
-
+            pred = output.data.max(1, keepdim=True)[1]
+            train_acc += pred.eq(target.data.view_as(pred)).sum()
             # Perform the backward pass
             loss.backward()
             # Take a step using optimizer
             optimizer.step()
-
             # Add the loss to the total loss
             train_loss += loss.item()
 
-        # Print the epoch and loss summary
         print(f"Epoch: {epoch_idx+1}/{epochs} |", end=" ")
-        print(f"Loss: {train_loss/len(train_loader):.8f}")
+        print(f"Train Loss: {train_loss/len(train_loader):.8f} ", end=" ")
+        print(f"Train Acc: {float(train_acc)/len(train_loader.dataset):.8f} ", end=" ")
+
+        if test_loader is not None:
+            model.eval()
+            with torch.no_grad():
+                test_loss, test_acc = 0, 0
+                for data, target in test_loader:
+                    data, target = data.to(device), target.to(device)
+                    # Cast target to long tensor
+                    target = target.long()
+                    # Computing output and loss
+                    output = model(data)
+                    test_loss += criterion(output, target).item()
+                    # Computing accuracy
+                    pred = output.data.max(1, keepdim=True)[1]
+                    test_acc += pred.eq(target.data.view_as(pred)).sum()
+
+            print(f"Test Loss: {test_loss/len(test_loader):.8f} ", end=" ")
+            print(f"Test Acc: {float(test_acc)/len(test_loader.dataset):.8f} ", end=" ")
+        print(f"One step uses {time.time() - start_time:.2f} seconds")
 
     # Move the model back to the CPU
     model.to("cpu")
diff --git a/experiments/util.py b/basic/util.py
similarity index 85%
rename from experiments/util.py
rename to basic/util.py
index 12a1982..d8c1f12 100644
--- a/experiments/util.py
+++ b/basic/util.py
@@ -2,6 +2,7 @@
 from ast import List
 
 import numpy as np
+import sklearn.metrics as metrics
 import torch
 
 
@@ -25,8 +26,7 @@ def check_configs(configs: dict):
     if privacy_game in ["privacy_loss_model", "avg_privacy_loss_training_algo"]:
         num_target_model = configs["train"]["num_target_model"]
         if privacy_game == "privacy_loss_model" and num_target_model != 1:
-            raise ValueError(
-                "privacy_loss_model game only supports one target model")
+            raise ValueError("privacy_loss_model game only supports one target model")
         if privacy_game == "avg_privacy_loss_training_algo":
             if num_target_model <= 1:
                 raise ValueError(
@@ -35,7 +35,7 @@ def check_configs(configs: dict):
                 )
 
 
-def get_optimizer(model: torch.nn.Module, configs: dict) -> torch.optim.Optimizer:
+def get_optimizer(model: torch.nn.Module, configs: dict):
     """Get the optimizer for the given model
 
     Args:
@@ -51,21 +51,26 @@ def get_optimizer(model: torch.nn.Module, configs: dict) -> torch.optim.Optimize
     optimizer = configs.get("optimizer", "SGD")
     learning_rate = configs.get("learning_rate", 0.001)
     weight_decay = configs.get("weight_decay", 0)
-
+    momentum = configs.get("momentum", 0)
     print(f"Load the optimizer {optimizer}: ", end=" ")
-    print(f"learning rate {learning_rate}", end=" ")
-    print(f"weight decay {weight_decay} ")
+    print(f"Learning rate {learning_rate}", end=" ")
+    print(f"Weight decay {weight_decay} ")
 
     if optimizer == "SGD":
         return torch.optim.SGD(
             model.parameters(),
             lr=learning_rate,
             weight_decay=weight_decay,
+            momentum=momentum,
         )
-    if optimizer == "Adam":
+    elif optimizer == "Adam":
         return torch.optim.Adam(
             model.parameters(), lr=learning_rate, weight_decay=weight_decay
         )
+    elif optimizer == "AdamW":
+        return torch.optim.AdamW(
+            model.parameters(), lr=learning_rate, weight_decay=weight_decay
+        )
 
     else:
         raise NotImplementedError(
@@ -75,7 +80,7 @@ def get_optimizer(model: torch.nn.Module, configs: dict) -> torch.optim.Optimize
 
 def get_split(
     all_index: List(int), used_index: List(int), size: int, split_method: str
-) -> np.ndarray:
+):
     """Select points based on the splitting methods
 
     Args:
@@ -91,11 +96,9 @@ def get_split(
         np.ndarray: List of index
     """
     if split_method in "no_overlapping":
-        selected_index = np.array(
-            [i for i in all_index if i not in used_index])
+        selected_index = np.setdiff1d(all_index, used_index, assume_unique=True)
         if size <= len(selected_index):
-            selected_index = np.random.choice(
-                selected_index, size, replace=False)
+            selected_index = np.random.choice(selected_index, size, replace=False)
         else:
             raise ValueError("Not enough remaining data points.")
     elif split_method == "uniform":
@@ -116,7 +119,7 @@ def load_models_by_conditions(
     conditions: dict,
     num_models: int,
     exclude_idx: List(int) = [],
-) -> List(int):
+):
     """Load existing models metadata index based on the conditions
 
     Args:
@@ -152,9 +155,7 @@ def load_models_by_conditions(
     return matched_idx
 
 
-def load_models_by_model_idx(
-    model_metadata_dict: dict, model_idx_list: List(int)
-) -> List(int):
+def load_models_by_model_idx(model_metadata_dict: dict, model_idx_list: List(int)):
     """Load existing models metadata index based on the model index.
 
     Args:
@@ -173,9 +174,7 @@ def load_models_by_model_idx(
     return model_idx_list
 
 
-def load_models_with_data_idx_list(
-    model_metadata_dict: dict, data_idx_list: List(int)
-) -> List(int):
+def load_models_with_data_idx_list(model_metadata_dict: dict, data_idx_list: List(int)):
     """Load existing metadata index of models which are trained on the data index list.
 
     Args:
@@ -199,7 +198,7 @@ def load_models_with_data_idx_list(
 
 def load_models_without_data_idx_list(
     model_metadata_dict: dict, data_idx_list: List(int)
-) -> List(int):
+):
     """Load existing metadata index of models which are not trained on the data index list.
 
     Args:
@@ -223,7 +222,7 @@ def load_models_without_data_idx_list(
 
 def load_leave_one_out_models(
     model_metadata_dict: dict, data_idx_list: List(int), reference_model_idx: List(int)
-) -> List(int):
+):
     """Load existing models which has one data point left out.
     Args:
         model_metadata_dict (dict): Model metadata dict.
@@ -251,3 +250,16 @@ def load_leave_one_out_models(
                 if set(diff) == set(data_idx_list) and meta_idx not in matched_idx:
                     matched_idx.append(meta_idx)
     return matched_idx
+
+
+def sweep(in_signal, out_signal):
+    """Calculate the ROC curve and AUC score."""
+    all_t = np.concatenate([in_signal, out_signal])
+    all_t = np.append(all_t, [np.max(all_t) + 0.0001, np.min(all_t) - 0.0001])
+    all_t.sort()
+    tpr = []
+    fpr = []
+    for threshold in all_t:
+        tpr.append(np.sum(in_signal < threshold) / len(in_signal))
+        fpr.append(np.sum(out_signal < threshold) / len(out_signal))
+    return fpr, tpr, metrics.auc(fpr, tpr)
diff --git a/basic/wide_resnet.py b/basic/wide_resnet.py
new file mode 100644
index 0000000..1b45ccb
--- /dev/null
+++ b/basic/wide_resnet.py
@@ -0,0 +1,95 @@
+import functools
+from typing import Callable, List
+
+import torch
+import torch.nn as nn
+
+BN_MOM = 0.9
+BN_EPS = 1e-5
+"""
+Pytorch implentation of Wide Residual Networks based on Jax implementation of widresnet: https://github.com/google/objax/blob/d0aefeeb573fb366f2ee547f6869f2ca1b7ef284/objax/zoo/wide_resnet.py
+
+Reference:
+http://arxiv.org/abs/1605.07146
+https://github.com/szagoruyko/wide-residual-networks
+"""
+
+
+class WRNBlock(nn.Module):
+    def __init__(
+        self,
+        nin: int,
+        nout: int,
+        stride: int = 1,
+        bn: Callable = functools.partial(nn.BatchNorm2d, momentum=BN_MOM, eps=BN_EPS),
+    ):
+        super(WRNBlock, self).__init__()
+        self.proj_conv = None
+
+        if nin != nout or stride > 1:
+            self.proj_conv = nn.Conv2d(
+                nin, nout, 1, stride=stride, padding=0, bias=False
+            )
+
+        self.norm_1 = bn(nin)
+        self.conv_1 = nn.Conv2d(nin, nout, 3, stride=stride, padding=1, bias=False)
+        self.norm_2 = bn(nout)
+        self.conv_2 = nn.Conv2d(nout, nout, 3, stride=1, padding=1, bias=False)
+
+    def forward(self, x):
+        o1 = torch.relu(self.norm_1(x))
+        y = self.conv_1(o1)
+        o2 = torch.relu(self.norm_2(y))
+        z = self.conv_2(o2)
+        return z + self.proj_conv(o1) if self.proj_conv else z + x
+
+
+class WideResNetGeneral(nn.Module):
+    def __init__(
+        self,
+        nin: int,
+        nclass: int,
+        blocks_per_group: List[int],
+        width: int,
+        bn: Callable = functools.partial(nn.BatchNorm2d, momentum=BN_MOM, eps=BN_EPS),
+    ):
+        super(WideResNetGeneral, self).__init__()
+        widths = [
+            int(v * width)
+            for v in [16 * (2**i) for i in range(len(blocks_per_group))]
+        ]
+        n = 16
+        ops = [nn.Conv2d(nin, n, 3, padding=1, bias=False)]
+        for i, (block, width) in enumerate(zip(blocks_per_group, widths)):
+            stride = 2 if i > 0 else 1
+            ops.append(WRNBlock(n, width, stride, bn))
+            for b in range(1, block):
+                ops.append(WRNBlock(width, width, 1, bn))
+            n = width
+        ops += [
+            bn(n),
+            nn.ReLU(inplace=True),
+            nn.AdaptiveAvgPool2d(1),
+            nn.Flatten(),
+            nn.Linear(n, nclass),
+        ]
+        self.layers = nn.Sequential(*ops)
+
+    def forward(self, x):
+        return self.layers(x)
+
+
+class WideResNet(WideResNetGeneral):
+    def __init__(
+        self,
+        nin: int,
+        nclass: int,
+        depth: int = 28,
+        width: int = 2,
+        bn: Callable = functools.partial(nn.BatchNorm2d, momentum=BN_MOM, eps=BN_EPS),
+    ):
+        assert (depth - 4) % 6 == 0, "depth should be 6n+4"
+        n = (depth - 4) // 6
+        blocks_per_group = [n] * 3
+        print("load the correct model")
+        super().__init__(nin, nclass, blocks_per_group, width, bn)
diff --git a/benchmark/README.md b/benchmark/README.md
index 64eda6d..5b9bef9 100644
--- a/benchmark/README.md
+++ b/benchmark/README.md
@@ -1,21 +1,33 @@
-# Reproducing benchmark results
+# Benchmark Experiments
 
-This folder provides configurations (YAML files) for reproducing the results provided in published papers on different datasets. To reproduce the results, please run the `experiments/main.py` with the corresponding configuration files.
+This folder contains a script for running benchmark experiments with different methods under the same settings.
 
-**Example:**
+## Setting
 
+The target model is trained using 30% of the entire CIFAR10 dataset (referred to as "members") and tested with another 30% of the dataset (referred to as "non-members"). The remaining data is considered population data and will be used for population attacks.
+
+## Running the Script
+
+To obtain all the attack results under this setting, please run the following command (GPU needed. The default GPU id is 1.):
+    
 ```
-cd ../experiments
-python main.py --cf ../benchmark/cifar10/config_population_setup1.yaml
+python main.py --cf benchmark.yaml
 ```
 
-# Benchmark results
+The results will be saved in the `benchmark` folder within the current directory. In this setting, we train 8 IN reference models and 8 OUT reference models, and 1 target model for producing this benchmark comparison.  Each target data point (from member and non-member set) is included in half of the reference models (referred to as "IN models") and excluded from the other half (referred to as "OUT models").
+Our code will run 245 seconds on a Single NVIDIA TITAN RTX to get all results for all attacks, including the training target model and reference models.
 
-In the following, we provide the pointer to the configuration files and the expected results, and the results we get based on the privacy meter.
+## Results
+In the following, we present the results for different variants of attacks:
+1. `reference_in_out_logits_pdf_fixed`: This attack uses both the IN and OUT models to compute the likelihood ratio for each target data point. The standard deviation of the OUT signals is the same as the IN signals and is constant for all data points. This is from the online attack in the paper (Carlini et al., 2022).
+2. `reference_in_out_logits_pdf`: This attack also utilizes both the IN and OUT models to compute the likelihood for each target data point. However, the standard deviation is computed individually for each data point. This is from the online attack in the paper (Carlini et al., 2022).
+3. `reference_out_logits_percentile_fixed`: In this attack, only the OUT models are used to compute the signal and compare it with the alpha-percentile of the OUT signal distribution. The standard deviation of the OUT signals is constant for all data points. This is from the reference attack in the paper (Ye et al., 2022).
+4. `reference_out_logits_percentile`: Similar to the previous attack, the OUT models are used to compute the signal and compare it with the alpha-percentile of the OUT signal distribution. However, the standard deviation is computed individually for each data point. This is from the reference attack in the paper (Ye et al., 2022).
+5. `reference_out_logits_pdf_fixed`: This attack employs the OUT models to compute the probability density function (PDF) of the target signal with respect to the OUT signal distribution. The standard deviation of the OUT signals remains constant for all data points. This is from the offline attack in the paper (Carlini et al., 2022).
+6. `reference_out_logits_pdf`: Similar to the previous attack, the OUT models are used to compute the PDF of the target signal with respect to the OUT signal distribution. However, the standard deviation is computed individually for each data point. This is from the offline attack in the paper (Carlini et al., 2022).
+7. `population`: This attack utilizes the target model's performance on population data to construct the OUT signal distribution. Each target point's signal is then compared with the alpha-percentile of the OUT signal distribution. This is from the original population attack paper (Ye et al., 2022).
 
-## On CIFAR10 dataset
+<p align="center" width="100%">
+    <img width="80%" src="default_benchmark/benchmark/Combined_ROC_log_scaled.png">
+</p>
 
-| Paper                                                                                                                       | Attack            | Results in the paper                  | Results produced by privacy meter | Configuration File                      |
-| --------------------------------------------------------------------------------------------------------------------------- | ----------------- | ------------------------------------- | --------------------------------- | --------------------------------------- |
-| [Enhanced Membership Inference Attacks against Machine Learning Models](https://dl.acm.org/doi/abs/10.1145/3548606.3560675) | Population attack | 0.857±0.023 (Table 4 of the appendix) | 0.870                             | `cifar10/config_population_setup1.yaml` |
-| [Enhanced Membership Inference Attacks against Machine Learning Models](https://dl.acm.org/doi/abs/10.1145/3548606.3560675) | Reference attack  | 0.874±0.018 (Table 4 of the appendix) | 0.879                             | `cifar10/config_reference_setup1.yaml`  |
diff --git a/benchmark/config_benchmark.yaml b/benchmark/config_benchmark.yaml
new file mode 100644
index 0000000..76142fc
--- /dev/null
+++ b/benchmark/config_benchmark.yaml
@@ -0,0 +1,33 @@
+run: # Configurations for a specific run
+  random_seed: 0530 # Integer number of specifying random seed
+  log_dir: benchmark # String for indicating where to save all the information, including models and computed signals. We can reuse the models saved in the same log_dir.
+  time_log: True # Indicate whether to log the time for each step
+
+audit: # Configurations for auditing
+  privacy_game: privacy_loss_model # Indicate the privacy game from privacy_loss_model, avg_privacy_loss_training_algo, privacy_loss_sample
+  report_log: benchmark # String that indicates the folder where we save the and auditing report.
+  device: cuda:0
+  augmentation: None # Indicate whether to use augmentation for the query points
+  audit_batch_size: 1000
+
+train: # Configuration for training
+  type: pytorch # Training framework (we only support pytorch now).
+  model_name: speedyresnet # String for indicating the model type. We support CNN. More model types can be added in model.py.
+  device: cuda:0 # String for indicating the device we want to use for training models.
+  num_in_models: 8 # Integer number that indicates how many target models trained on idx
+  num_out_models: 8 # Integer number that indicates how many target models not trained on idx
+  num_target_model: 1 # Number of total models we want to test
+  optimizer: speedyresnet_optimizer
+  learning_rate: speedyresnet_learning_rate
+  weight_decay: speedyresnet_weight_decay
+  batch_size: speedyresnet_batch_size
+  epochs: speedyresnet_epochs
+  test_batch_size: 250
+  num_test_size: 1000
+
+data: # Configuration for data
+  dataset: cifar10 # String indicates the name of the dataset
+  data_dir: ../data
+  keep_ratio: 0.5 # the ratio of keeping the point for the training dataset.
+  dataset_size: 50000 # the size of the target dataset, including the train and test dataset; the rest is considered as the population data.
+
diff --git a/benchmark/default_benchmark/benchmark/Combined_ROC.png b/benchmark/default_benchmark/benchmark/Combined_ROC.png
new file mode 100644
index 0000000..8d81f5a
Binary files /dev/null and b/benchmark/default_benchmark/benchmark/Combined_ROC.png differ
diff --git a/benchmark/default_benchmark/benchmark/Combined_ROC_log_scaled.png b/benchmark/default_benchmark/benchmark/Combined_ROC_log_scaled.png
new file mode 100644
index 0000000..7a30ac9
Binary files /dev/null and b/benchmark/default_benchmark/benchmark/Combined_ROC_log_scaled.png differ
diff --git a/benchmark/main.py b/benchmark/main.py
new file mode 100644
index 0000000..43289dc
--- /dev/null
+++ b/benchmark/main.py
@@ -0,0 +1,336 @@
+"""This file is the main entry point for running the priavcy auditing."""
+import argparse
+import logging
+import os
+import pickle
+import sys
+import time
+from pathlib import Path
+
+sys.path.insert(0, "../basic/")
+
+import random
+
+import numpy as np
+import torch
+import yaml
+from core import (load_existing_models,
+                  prepare_datasets_for_reference_in_attack, prepare_models)
+from dataset import get_dataset, get_dataset_subset
+from plot import plot_compare_roc
+from scipy.stats import norm
+from sklearn.metrics import auc, roc_curve
+from torch import nn
+from util import check_configs
+
+from privacy_meter.model import PytorchModelTensor
+
+torch.backends.cudnn.benchmark = True
+
+
+def setup_log(name: str, save_file: bool):
+    """Generate the logger for the current run.
+    Args:
+        name (str): Logging file name.
+        save_file (bool): Flag about whether to save to file.
+    Returns:
+        logging.Logger: Logger object for the current run.
+    """
+    my_logger = logging.getLogger(name)
+    my_logger.setLevel(logging.INFO)
+    if save_file:
+        log_format = logging.Formatter("%(asctime)s %(levelname)-8s %(message)s")
+        filename = f"log_{name}.log"
+        log_handler = logging.FileHandler(filename, mode="w")
+        log_handler.setLevel(logging.INFO)
+        log_handler.setFormatter(log_format)
+        my_logger.addHandler(log_handler)
+
+    return my_logger
+
+
+if __name__ == "__main__":
+    parser = argparse.ArgumentParser()
+    parser.add_argument(
+        "--cf",
+        type=str,
+        default="config_benchmark.yaml",
+        help="Yaml file which contains the configurations",
+    )
+
+    # Load the parameters
+    args = parser.parse_args()
+    with open(args.cf, "rb") as f:
+        configs = yaml.load(f, Loader=yaml.Loader)
+
+    check_configs(configs)
+    # Set the random seed, log_dir and inference_game
+    torch.manual_seed(configs["run"]["random_seed"])
+    np.random.seed(configs["run"]["random_seed"])
+    random.seed(configs["run"]["random_seed"])
+
+    log_dir = configs["run"]["log_dir"]
+    inference_game_type = configs["audit"]["privacy_game"].upper()
+
+    # Set up the logger
+    logger = setup_log("time_analysis", configs["run"]["time_log"])
+
+    # Create folders for saving the logs if they do not exist
+    Path(log_dir).mkdir(parents=True, exist_ok=True)
+    report_dir = f"{log_dir}/{configs['audit']['report_log']}"
+    Path(report_dir).mkdir(parents=True, exist_ok=True)
+
+    start_time = time.time()
+
+    # Load or initialize models based on metadata
+    if os.path.exists((f"{log_dir}/models_metadata.pkl")):
+        with open(f"{log_dir}/models_metadata.pkl", "rb") as f:
+            model_metadata_list = pickle.load(f)
+    else:
+        model_metadata_list = {"model_metadata": {}, "current_idx": 0}
+    # Load the dataset
+    baseline_time = time.time()
+    dataset = get_dataset(configs["data"]["dataset"], configs["data"]["data_dir"])
+    privacy_game = configs["audit"]["privacy_game"]
+
+    baseline_time = time.time()
+    p_ratio = configs["data"]["keep_ratio"]
+    dataset_size = configs["data"]["dataset_size"]
+
+    number_of_models_total = (
+        configs["train"]["num_in_models"]
+        + configs["train"]["num_out_models"]
+        + configs["train"]["num_target_model"]
+    )
+    (
+        data_split_info,
+        keep_matrix,
+        target_data_index,
+    ) = prepare_datasets_for_reference_in_attack(
+        len(dataset),
+        dataset_size,
+        num_models=(number_of_models_total),
+        keep_ratio=p_ratio,
+        is_uniform=False,
+    )
+    data, targets = get_dataset_subset(
+        dataset,
+        target_data_index,
+        configs["train"]["model_name"],
+        device=configs["train"]["device"],
+    )
+    population_idx = np.setdiff1d(np.arange(len(dataset)), target_data_index)
+    population_data, population_targets = get_dataset_subset(
+        dataset,
+        population_idx,
+        configs["train"]["model_name"],
+        device=configs["train"]["device"],
+    )
+
+    logger.info(
+        "Prepare the datasets costs %0.5f seconds",
+        time.time() - baseline_time,
+    )
+    baseline_time = time.time()
+    signals = []
+    population_signals = []
+    if model_metadata_list["current_idx"] == 0:
+        # check if the models are trained
+        (model_list, model_metadata_dict, trained_model_idx_list) = prepare_models(
+            log_dir,
+            dataset,
+            data_split_info,
+            configs["train"],
+            model_metadata_list,
+            configs["data"]["dataset"],
+        )
+        logger.info(
+            "Prepare the models costs %0.5f seconds",
+            time.time() - baseline_time,
+        )
+        baseline_time = time.time()
+        for model in model_list:
+            model_pm = PytorchModelTensor(
+                model_obj=model,
+                loss_fn=nn.CrossEntropyLoss(),
+                device=configs["audit"]["device"],
+                batch_size=configs["audit"]["audit_batch_size"],
+            )
+            signals.append(
+                model_pm.get_rescaled_logits(data, targets)
+            )
+            population_signals.append(
+                model_pm.get_rescaled_logits(population_data, population_targets)
+            )
+
+        logger.info(
+            "Prepare the signals costs %0.5f seconds",
+            time.time() - baseline_time,
+        )
+    else:
+        for idx in range(number_of_models_total):
+            print("Load the model and compute signals for model %d" % idx)
+            model_pm = PytorchModelTensor(
+                model_obj=load_existing_models(
+                    model_metadata_list,
+                    [idx],
+                    configs["train"]["model_name"],
+                    dataset,
+                    configs["data"]["dataset"],
+                )[0],
+                loss_fn=nn.CrossEntropyLoss(),
+                device=configs["audit"]["device"],
+                batch_size=10000,
+            )
+            signals.append(
+                model_pm.get_rescaled_logits(data, targets)
+            )
+            population_signals.append(
+                model_pm.get_rescaled_logits(population_data, population_targets)
+            )
+        logger.info(
+            "Prepare the signals costs %0.5f seconds",
+            time.time() - baseline_time,
+        )
+    baseline_time = time.time()
+    signals = np.array(signals)
+    population_signals = np.array(population_signals)
+    # number of models we want to consider as test
+    n_test = 1
+    target_signal = signals[:n_test, :]
+    reference_signals = signals[n_test:, :]
+    reference_keep_matrix = keep_matrix[n_test:, :]
+    membership = keep_matrix[:n_test, :]
+    in_signals = []
+    out_signals = []
+    population_signals = population_signals[:n_test, :]
+
+    for data_idx in range(len(target_data_index)):
+        in_signals.append(
+            reference_signals[reference_keep_matrix[:, data_idx], data_idx]
+        )
+        out_signals.append(
+            reference_signals[~reference_keep_matrix[:, data_idx], data_idx]
+        )
+
+    in_size = min(min(map(len, in_signals)), configs["train"]["num_in_models"])
+    out_size = min(min(map(len, out_signals)), configs["train"]["num_out_models"])
+    in_signals = np.array([x[:in_size] for x in in_signals]).astype("float32")
+    out_signals = np.array([x[:out_size] for x in out_signals]).astype("float32")
+
+    all_fpr_list = []
+    all_tpr_list = []
+    all_auc_list = []
+    all_alg_list = [
+        "reference_in_out_logit_pdf_fixed",
+        "reference_in_out_logit_pdf",
+        "reference_out_logits_percentile_fixed",
+        "reference_out_logits_percentile",
+        "reference_out_logits_pdf_fixed",
+        "reference_out_logits_pdf",
+        "population",
+    ]
+
+    print(100 * "#")
+
+    for alg in all_alg_list:
+        prediction = []
+        answers = []
+        for ans, sc in zip(membership, target_signal):
+            if alg == "reference_in_out_logit_pdf_fixed":
+                mean_in = np.median(in_signals, 1)
+                mean_out = np.median(out_signals, 1)
+                std_in = np.std(in_signals)
+                std_out = np.std(in_signals)
+
+                pr_in = -norm.logpdf(sc, mean_in, std_in + 1e-30)
+                pr_out = -norm.logpdf(sc, mean_out, std_out + 1e-30)
+                score = pr_in - pr_out
+            elif alg == "reference_in_out_logit_pdf":
+                mean_in = np.median(in_signals, 1)
+                mean_out = np.median(out_signals, 1)
+                std_in = np.std(in_signals, 1)
+                std_out = np.std(out_signals, 1)
+                pr_in = -norm.logpdf(sc, mean_in, std_in + 1e-30)
+                pr_out = -norm.logpdf(sc, mean_out, std_out + 1e-30)
+                score = pr_in - pr_out
+            elif alg == "reference_out_logits_percentile_fixed":
+                mean_out = np.median(out_signals, 1)
+                std_out = np.std(out_signals)
+                pr_out = norm.cdf(sc, mean_out, std_out + 1e-30)
+                score = -pr_out
+            elif alg == "reference_out_logits_percentile":
+                mean_out = np.median(out_signals, 1)
+                std_out = np.std(out_signals, 1)
+                pr_out = norm.cdf(sc, mean_out, std_out + 1e-30)
+                score = -pr_out
+            elif alg == "population":
+                mean_out = np.median(population_signals)
+                std_out = np.std(population_signals)
+                pr_out = norm.cdf(sc, mean_out, std_out + 1e-30)
+                score = -pr_out
+            elif alg == "reference_out_logits_pdf_fixed":
+                mean_out = np.median(out_signals, 1)
+                std_out = np.std(out_signals)
+                pr_out = -norm.logpdf(sc, mean_out, std_out + 1e-30)
+                score = -pr_out
+            elif alg == "reference_out_logits_pdf":
+                mean_out = np.median(out_signals, 1)
+                std_out = np.std(out_signals, 1)
+                pr_out = -norm.logpdf(sc, mean_out, std_out + 1e-30)
+                score = -pr_out
+            else:
+                raise ValueError("Unknown algorithm")
+
+            if len(score.shape) == 2:  # the score is of size (data_size, num_augments)
+                prediction.extend(score.mean(1))
+                fpr_list, tpr_list, _ = roc_curve(ans, -score.mean(1))
+            else:
+                prediction.extend(score)
+                fpr_list, tpr_list, _ = roc_curve(ans, -score)
+            answers.extend(ans)
+            acc = np.max(1 - (fpr_list + (1 - tpr_list)) / 2)
+            roc_auc = auc(fpr_list, tpr_list)
+
+        prediction = np.array(prediction)
+        answers = np.array(answers, dtype=bool)
+        fpr_list, tpr_list, _ = roc_curve(answers.ravel(), -prediction.ravel())
+        ref_in_acc = np.max(1 - (fpr_list + (1 - tpr_list)) / 2)
+        ref_in_roc_auc = auc(fpr_list, tpr_list)
+        ref_in_low = tpr_list[np.where(fpr_list < 0.001)[0][-1]]
+
+        print(
+            f"{alg}     AUC: %.4f, Accuracy: %.4f, TPR@0.1%%FPR: %.4f"
+            % (ref_in_roc_auc, ref_in_acc, ref_in_low)
+        )
+        all_fpr_list.append(fpr_list)
+        all_tpr_list.append(tpr_list)
+        all_auc_list.append(ref_in_roc_auc)
+
+    print(100 * "#")
+
+    plot_compare_roc(
+        all_fpr_list,
+        all_tpr_list,
+        all_auc_list,
+        all_alg_list,
+        f"{log_dir}/{configs['audit']['report_log']}/Combined_ROC.png",
+        log_scale=False,
+    )
+
+    plot_compare_roc(
+        all_fpr_list,
+        all_tpr_list,
+        all_auc_list,
+        all_alg_list,
+        f"{log_dir}/{configs['audit']['report_log']}/Combined_ROC_log_scaled.png",
+        log_scale=True,
+    )
+
+    ############################
+    # END
+    ############################
+    logger.info(
+        "Run the priavcy meter for the all steps costs %0.5f seconds",
+        time.time() - start_time,
+    )
diff --git a/data/purchase/README.md b/data/purchase/README.md
new file mode 100644
index 0000000..a63b3c4
--- /dev/null
+++ b/data/purchase/README.md
@@ -0,0 +1,6 @@
+Install the data from https://www.comp.nus.edu.sg/~reza/files/datasets.html
+
+```
+wget https://www.comp.nus.edu.sg/~reza/files/dataset_purchase.tgz
+tar -xf dataset_purchase.tgz 
+```
\ No newline at end of file
diff --git a/data/texas/README.md b/data/texas/README.md
new file mode 100644
index 0000000..6ddf880
--- /dev/null
+++ b/data/texas/README.md
@@ -0,0 +1,6 @@
+Install the data from https://www.comp.nus.edu.sg/~reza/files/datasets.html
+
+```
+wget https://www.comp.nus.edu.sg/~reza/files/dataset_texas.tgz
+tar -xf dataset_texas.tgz 
+```
\ No newline at end of file
diff --git a/experiments/README.md b/experiments/README.md
deleted file mode 100644
index 0b3180b..0000000
--- a/experiments/README.md
+++ /dev/null
@@ -1,49 +0,0 @@
-# Privacy Meter Experiments
-
-This folder contains the implementation of an end-to-end membership inference attack, based on various attack games defined by [[Ye et al. 2022](https://arxiv.org/pdf/2111.09679.pdf)]. It is recommended that you perform privacy auditing using our automatical pipline. By default, the audit provides a way to evaluate the privacy risks for models, algorithms, and data points using the CIFAR10 dataset. To adapt it to your specific use case, you can specify the model structure in `model.py`, the dataset in `dataset.py`, and the training algorithm in `train.py`. The training configurations can then be specified in the configuration Yaml file. The overall pipeline is illustrated below. For a deeper understanding of various types of attacks or for information on how to extend the Privacy Meter to include other libraries, please refer to our [tutorials](../tutorials) for more information.
-
-<p align="center" width="100%">
-    <img width="80%" src="docs/experiment_pipeline.png">
-</p>
-
-In the following, we introduce how to run privacy auditing automatelliy using our default configurations.
-
-# Privacy auditing examples
-
-## Auditing the privacy risk for a trained model.
-
-To start, you can run the following commands
-
-```
-python main.py --cf config_models_reference.yaml
-```
-
-The Yaml file allows you to specify the hyperparameters for training the model, the method for splitting the data, and the algorithm for the membership inference attack. By default, the program trains a model on the CIFAR10 dataset and trains ten reference models to perform the reference attack algorithm (refer to [Ye et al. 2022] for a more detailed explanation). If you are interested in conducting a population attack, which does not require the training of reference models, you can run the following commands.
-
-```
-python main.py --cf config_models_population.yaml
-```
-
-For a comprehensive explanation of each parameter, please refer to each Yaml file. Upon completion, you will find the results in the `demo` folder, with the reference attack results saved in `demo/report_reference` and the population attack results saved in `demo/report_population`. Furthermore, we also offer a timing log for each run, which can be found in the file `log_time_analysis.log`.
-
-## Auditing the privacy risk for a training algorithm.
-
-To audit the privacy risk of a training algorithm (training settings), you can run the following commands
-
-```
-python main.py --cf config_algorithms.yaml
-```
-
-The program will repeat the first game for multiple target models that are trained using the same training algorithm and configuration, but with different training and test datasets. The outcome will be the average privacy risk across all the target models. Upon completion, you will find the results in the `demo/report_reference_algorithm` folder.
-
-## Auditing the privacy risk for a data point.
-
-Moreover, we have also included an implementation for auditing the privacy risk of a single data point. To be specific, we compare the loss distribution difference of an auditing data point $z_a$ when another data $z_t$ is present in the training dataset versus not being in the target model's training dataset. If $z_t$ equals $z_a$, then the measurement essentially becomes memorization (refer to [reference](https://arxiv.org/abs/1906.05271)).
-
-By default, we assess the memorization of the data point with index 1 (each dataset assigns an index to each data point based on its order in the dataset). To obtain the results, simply execute the following command:
-
-```
-python main.py --cf config_samples.yaml
-```
-
-After the completion, you can locate the privacy risk report in the `demo/report_sample` folder.
diff --git a/experiments/config_algorithms.yaml b/experiments/config_algorithms.yaml
deleted file mode 100644
index 439c402..0000000
--- a/experiments/config_algorithms.yaml
+++ /dev/null
@@ -1,40 +0,0 @@
-run: # Configurations for a specific run
-  random_seed: 1234 # Integer number of specifying random seed
-  log_dir: demo # String for indicating where to save all the information, including models and computed signals. We can reuse the models saved in the same log_dir.
-  time_log: True # Indicate whether to log the time for each step
-
-audit: # Configurations for auditing
-  privacy_game: avg_privacy_loss_training_algo # Indicate the privacy game from privacy_loss_model, avg_privacy_loss_training_algo, privacy_loss_sample
-  device: cpu # String for indicating on which device we conduct the membership inference attack and train reference models.
-  audit_batch_size: 1000 # Integer number for indicating the batch size for computing signals in the privacy meter.
-  algorithm: reference # String for indicating the membership inference attack. We currently support population, reference.
-  num_reference_models: 10 # Integer number for indicating how many reference models we need to train for auditing, if the reference attack is used.
-  batch_size: 256 # Integer number for indicating the batch size of training the reference models if reference attack is used.
-  f_reference_dataset: 1 # Float number for indicating the ratio between the reference train dataset and the target train dataset.
-  optimizer: Adam # String which indicates the optimizer for training reference models. We support Adam and SGD.
-  learning_rate: 0.001 # Float number for indicating learning rate for training the reference model.
-  weight_decay: 0 # Float number for indicating weight decay for training the reference model.
-  model_name: CNN # String for indicating the model type. We support CNN,alexnet. More model type can be added in model.py.
-  epochs: 1 # Integer number for indicating the epochs for training target model.
-  report_log: report_reference_algorithm # String that indicates the folder where we save the and auditing report.
-  split_method: uniform # String for indicating the splitting methods for reference dataset. We support uniform and leave_one_out.
-
-train: # Configuration for training
-  type: pytorch # Training framework (we only support pytorch now).
-  epochs: 1 # Integer number for indicating the epochs for training target model.
-  batch_size: 256 # Integer number for indicating batch size for training the target model.
-  test_batch_size: 10000 # Integer number for indicating batch size for evaluating the target model.
-  optimizer: Adam # String which indicates the optimizer. We support Adam and SGD.
-  learning_rate: 0.001 # Float number for indicating learning rate for training the target model.
-  weight_decay: 0 # Float number for indicating weight decay for training the target model.
-  model_name: CNN # String for indicating the model type. We support CNN. More model types can be added in model.py.
-  device: cpu # String for indicating the device we want to use for training models.
-  num_target_model: 10 #Integer number for indicating how many target models we want to audit for the privacy game
-
-data: # Configuration for data
-  dataset: cifar10 # String indicates the name of the dataset
-  f_train: 0.3 # Float number from 0 to 1 indicating the fraction of the train dataset
-  f_test: 0.3 # Float number from 0 to 1 indicating the fraction of the test dataset
-  split_method: no_overlapping # String for indicating the methods of splitting the dataset between train, test, and auditing.
-  f_audit: 0.3 # Float from 0 to 1, indicating the fraction of the auditing dataset
-  data_dir: ../data # String about where to save the data.
diff --git a/experiments/config_models_population.yaml b/experiments/config_models_population.yaml
deleted file mode 100644
index 6aba426..0000000
--- a/experiments/config_models_population.yaml
+++ /dev/null
@@ -1,32 +0,0 @@
-run: # Configurations for a specific run
-  random_seed: 1234 # Integer number of specifying random seed
-  log_dir: demo # String for indicating where to save all the information, including models and computed signals. We can reuse the models saved in the same log_dir.
-  time_log: True # Indicate whether to log the time for each step
-
-audit: # Configurations for auditing
-  privacy_game: privacy_loss_model # Indicate the privacy game from privacy_loss_model, avg_privacy_loss_training_algo, privacy_loss_sample
-  device: cpu # String for indicating on which device we conduct the membership inference attack and train reference models.
-  audit_batch_size: 1000 # Integer number for indicating the batch size for computing signals in the privacy meter.
-  algorithm: population # String for indicating the membership inference attack. We currently support population, reference.
-  report_log: report_population # String that indicates the folder where we save the and auditing report.
-
-train: # Configuration for training
-  type: pytorch # Training framework (we only support pytorch now).
-  epochs: 30 # Integer number for indicating the epochs for training target model.
-  batch_size: 64 # Integer number for indicating batch size for training the target model.
-  test_batch_size: 10000 # Integer number for indicating batch size for evaluating the target model.
-  optimizer: Adam # String which indicates the optimizer. We support Adam and SGD.
-  learning_rate: 0.001 # Float number for indicating learning rate for training the target model.
-  weight_decay: 0 # Float number for indicating weight decay for training the target model.
-  model_name: CNN # String for indicating the model type. We support CNN. More model types can be added in model.py.
-  device: cpu # String for indicating the device we want to use for training models.
-  num_target_model: 1 #Integer number for indicating how many target models we want to audit for the privacy game
-  model_idx: 0
-
-data: # Configuration for data
-  dataset: cifar10 # String indicates the name of the dataset
-  f_train: 0.3 # Float number from 0 to 1 indicating the fraction of the train dataset
-  f_test: 0.3 # Float number from 0 to 1 indicating the fraction of the test dataset
-  split_method: no_overlapping # String for indicating the methods of splitting the dataset between train, test, and auditing.
-  f_audit: 0.3 # Float from 0 to 1, indicating the fraction of the auditing dataset
-  data_dir: ../data # String about where to save the data.
diff --git a/experiments/config_models_reference.yaml b/experiments/config_models_reference.yaml
deleted file mode 100644
index e09fb87..0000000
--- a/experiments/config_models_reference.yaml
+++ /dev/null
@@ -1,41 +0,0 @@
-run: # Configurations for a specific run
-  random_seed: 1234 # Integer number of specifying random seed
-  log_dir: demo # String for indicating where to save all the information, including models and computed signals. We can reuse the models saved in the same log_dir.
-  time_log: True # Indicate whether to log the time for each step
-
-audit: # Configurations for auditing
-  privacy_game: privacy_loss_model # Indicate the privacy game from privacy_loss_model, avg_privacy_loss_training_algo, privacy_loss_sample
-  device: cpu # String for indicating on which device we conduct the membership inference attack and train reference models.
-  audit_batch_size: 1000 # Integer number for indicating the batch size for computing signals in the privacy meter.
-  algorithm: reference # String for indicating the membership inference attack. We currently support population, reference.
-  num_reference_models: 10 # Integer number for indicating how many reference models we need to train for auditing, if the reference attack is used.
-  batch_size: 64 # Integer number for indicating the batch size of training the reference models if reference attack is used.
-  f_reference_dataset: 1 # Float number for indicating the ratio between the reference train dataset and the target train dataset.
-  optimizer: Adam # String which indicates the optimizer for training reference models. We support Adam and SGD.
-  learning_rate: 0.001 # Float number for indicating learning rate for training the reference model.
-  weight_decay: 0 # Float number for indicating weight decay for training the reference model.
-  model_name: CNN # String for indicating the model type. We support CNN, alexnet. More model type can be added in model.py.
-  epochs: 30 # Integer number for indicating the epochs for training target model.
-  report_log: report_reference # String that indicates the folder where we save the and auditing report.
-  split_method: uniform # String for indicating the splitting methods for reference dataset. We support uniform and leave_one_out.
-
-train: # Configuration for training
-  type: pytorch # Training framework (we only support pytorch now).
-  epochs: 30 # Integer number for indicating the epochs for training target model.
-  batch_size: 64 # Integer number for indicating batch size for training the target model.
-  test_batch_size: 10000 # Integer number for indicating batch size for evaluating the target model.
-  optimizer: Adam # String which indicates the optimizer. We support Adam and SGD.
-  learning_rate: 0.001 # Float number for indicating learning rate for training the target model.
-  weight_decay: 0 # Float number for indicating weight decay for training the target model.
-  model_name: CNN # String for indicating the model type. We support CNN. More model types can be added in model.py.
-  device: cpu # String for indicating the device we want to use for training models.
-  num_target_model: 1 #Integer number for indicating how many target models we want to audit for the privacy game
-  model_idx: 0
-
-data: # Configuration for data
-  dataset: cifar10 # String indicates the name of the dataset
-  f_train: 0.3 # Float number from 0 to 1 indicating the fraction of the train dataset
-  f_test: 0.3 # Float number from 0 to 1 indicating the fraction of the test dataset
-  split_method: no_overlapping # String for indicating the methods of splitting the dataset between train, test, and auditing.
-  f_audit: 0.3 # Float from 0 to 1, indicating the fraction of the auditing dataset
-  data_dir: ../data # String about where to save the data.
diff --git a/experiments/config_samples.yaml b/experiments/config_samples.yaml
deleted file mode 100644
index 0228673..0000000
--- a/experiments/config_samples.yaml
+++ /dev/null
@@ -1,34 +0,0 @@
-run: # Configurations for a specific run
-  random_seed: 1234 # Integer number of specifying random seed
-  log_dir: demo # String for indicating where to save all the information, including models and computed signals. We can reuse the models saved in the same log_dir.
-  time_log: True # Indicate whether to log the time for each step
-
-audit: # the configurations for the MIA
-  privacy_game: privacy_loss_sample #privacy_loss_model #avg_privacy_loss_training_algo # the configuarations for the privacy loss game
-  device: cpu # indicate on which device we conduct the MIA
-  audit_batch_size: 1000 # the batch size for computing signals for inferring membership information
-  split_method: uniform # spliting methods among reference datasets
-  report_log: report_sample # String that indicates the folder where we save the and auditing report.
-  data_idx: 1 # Integer number indicating the data index for which we want to show the performance difference
-
-train: # Configuration for training
-  type: pytorch # Training framework (we only support pytorch now).
-  epochs: 30 # Integer number for indicating the epochs for training target model.
-  batch_size: 64 # Integer number for indicating batch size for training the target model.
-  test_batch_size: 10000 # Integer number for indicating batch size for evaluating the target model.
-  optimizer: Adam # String which indicates the optimizer. We support Adam and SGD.
-  learning_rate: 0.001 # Float number for indicating learning rate for training the target model.
-  weight_decay: 0 # Float number for indicating weight decay for training the target model.
-  model_name: CNN # String for indicating the model type. We support CNN. More model types can be added in model.py.
-  device: cpu # String for indicating the device we want to use for training models.
-  data_idx: 1 # Integer number for indicating the model index or data index.
-  num_in_models: 10 # Integer number that indicates how many target models trained on idx
-  num_out_models: 10 # Integer number that indicates how many target models not trained on idx
-  model_idx: 1
-data: # Configuration for data
-  dataset: cifar10 # String indicates the name of the dataset
-  f_train: 0.3 # Float number from 0 to 1 indicating the fraction of the train dataset
-  f_test: 0.3 # Float number from 0 to 1 indicating the fraction of the test dataset
-  split_method: uniform # String for indicating the methods of splitting the dataset between train, test, and auditing; Take value from uniform
-  f_audit: 0.3 # Float from 0 to 1, indicating the fraction of the auditing dataset
-  data_dir: ../data # String about where to save the data.
diff --git a/experiments/dataset.py b/experiments/dataset.py
deleted file mode 100644
index 645f021..0000000
--- a/experiments/dataset.py
+++ /dev/null
@@ -1,70 +0,0 @@
-"""This file contains functions for loading the dataset"""
-import os
-import pickle
-from ast import List
-
-import numpy as np
-import torch
-import torchvision
-from torchvision import transforms
-
-
-def get_dataset(dataset_name: str, data_dir: str) -> torchvision.datasets:
-    """Load the dataset from the pickle file or download it from the internet.
-    Args:
-        dataset_name (str): Dataset name
-        data_dir (str): Indicate the log directory for loading the dataset
-
-    Raises:
-        NotImplementedError: Check if the dataset has been implemented.
-
-    Returns:
-        torchvision.datasets: Whole dataset.
-    """
-    path = f"{data_dir}/{dataset_name}"
-
-    if os.path.exists(f"{path}.pkl"):
-        with open(f"{path}.pkl", "rb") as file:
-            all_data = pickle.load(file)
-        print(f"Load data from {path}.pkl")
-
-    else:
-        if dataset_name == "cifar10":
-            transform = transforms.Compose([transforms.ToTensor()])
-            all_data = torchvision.datasets.CIFAR10(
-                root=path, train=True, download=True, transform=transform
-            )
-            test_data = torchvision.datasets.CIFAR10(
-                root=path, train=False, download=True, transform=transform
-            )
-            all_features = np.concatenate(
-                [all_data.data, test_data.data], axis=0)
-            all_targets = np.concatenate(
-                [all_data.targets, test_data.targets], axis=0)
-
-            all_data.data = all_features
-            all_data.targets = all_targets
-            with open(f"{path}.pkl", "wb") as file:
-                pickle.dump(all_data, file)
-            print(f"Save data to {path}.pkl")
-        else:
-            raise NotImplementedError(f"{dataset_name} is not implemented")
-
-    print(f"the whole dataset size: {len(all_data)}")
-    return all_data
-
-
-def get_dataset_subset(dataset: torchvision.datasets, index: List(int)):
-    """Get a subset of the dataset.
-
-    Args:
-        dataset (torchvision.datasets): Whole dataset.
-        index (list): List of index.
-    """
-    assert max(index) < len(dataset) and min(index) >= 0, "Index out of range"
-    data = (
-        torch.from_numpy(dataset.data[index]).float().permute(0, 3, 1, 2) / 255
-    )  # channel first
-    targets = list(np.array(dataset.targets)[index])
-    targets = torch.tensor(targets, dtype=torch.long)
-    return data, targets
diff --git a/experiments/docs/experiment_pipeline.png b/experiments/docs/experiment_pipeline.png
deleted file mode 100644
index 1ed5f4a..0000000
Binary files a/experiments/docs/experiment_pipeline.png and /dev/null differ
diff --git a/experiments/log_time_analysis.log b/experiments/log_time_analysis.log
deleted file mode 100644
index 9709c80..0000000
--- a/experiments/log_time_analysis.log
+++ /dev/null
@@ -1,6 +0,0 @@
-2023-02-03 11:09:41,129 INFO     Prepare the datasets costs 0.09670 seconds
-2023-02-03 11:09:41,130 INFO     Prepare the target model costs 0.00001 seconds
-2023-02-03 11:09:41,236 INFO     Prepare the information source costs 0.10580 seconds
-2023-02-03 11:09:41,336 INFO     Prepare the privacy meter result costs 0.10026 seconds
-2023-02-03 11:09:44,737 INFO     Prepare the plot for the privacy risk report costs 3.40022 seconds
-2023-02-03 11:09:44,737 INFO     Run the priavcy meter for the all steps costs 3.70455 seconds
diff --git a/experiments/main.py b/experiments/main.py
deleted file mode 100644
index 183e749..0000000
--- a/experiments/main.py
+++ /dev/null
@@ -1,407 +0,0 @@
-"""This file is the main entry point for running the priavcy auditing."""
-import argparse
-import logging
-import os
-import pickle
-import time
-from pathlib import Path
-
-import matplotlib.pyplot as plt
-import numpy as np
-import pandas as pd
-import seaborn as sns
-import torch
-import yaml
-from core import (
-    load_dataset_for_existing_models,
-    load_existing_models,
-    load_existing_target_model,
-    prepare_datasets,
-    prepare_datasets_for_sample_privacy_risk,
-    prepare_information_source,
-    prepare_models,
-    prepare_priavcy_risk_report,
-)
-from dataset import get_dataset, get_dataset_subset
-from torch import nn
-from util import (
-    check_configs,
-    load_leave_one_out_models,
-    load_models_with_data_idx_list,
-    load_models_without_data_idx_list,
-)
-
-from privacy_meter.audit import Audit
-from privacy_meter.model import PytorchModelTensor
-
-torch.backends.cudnn.benchmark = True
-
-
-def setup_log(name: str, save_file: bool) -> logging.Logger:
-    """Generate the logger for the current run.
-    Args:
-        name (str): Logging file name.
-        save_file (bool): Flag about whether to save to file.
-    Returns:
-        logging.Logger: Logger object for the current run.
-    """
-    my_logger = logging.getLogger(name)
-    my_logger.setLevel(logging.INFO)
-    if save_file:
-        log_format = logging.Formatter(
-            "%(asctime)s %(levelname)-8s %(message)s")
-        filename = f"log_{name}.log"
-        log_handler = logging.FileHandler(filename, mode="w")
-        log_handler.setLevel(logging.INFO)
-        log_handler.setFormatter(log_format)
-        my_logger.addHandler(log_handler)
-
-    return my_logger
-
-
-if __name__ == "__main__":
-
-    parser = argparse.ArgumentParser()
-    parser.add_argument(
-        "--cf",
-        type=str,
-        default="config_samples.yaml",
-        help="Yaml file which contains the configurations",
-    )
-
-    # Load the parameters
-    args = parser.parse_args()
-    with open(args.cf, "rb") as f:
-        configs = yaml.load(f, Loader=yaml.Loader)
-
-    check_configs(configs)
-    # Set the random seed, log_dir and inference_game
-    torch.manual_seed(configs["run"]["random_seed"])
-    np.random.seed(configs["run"]["random_seed"])
-
-    log_dir = configs["run"]["log_dir"]
-    inference_game_type = configs["audit"]["privacy_game"].upper()
-
-    # Set up the logger
-    logger = setup_log("time_analysis", configs["run"]["time_log"])
-
-    # Create folders for saving the logs if they do not exist
-    Path(log_dir).mkdir(parents=True, exist_ok=True)
-    report_dir = f"{log_dir}/{configs['audit']['report_log']}"
-    Path(report_dir).mkdir(parents=True, exist_ok=True)
-
-    start_time = time.time()
-
-    # Load or initialize models based on metadata
-    if os.path.exists((f"{log_dir}/models_metadata.pkl")):
-        with open(f"{log_dir}/models_metadata.pkl", "rb") as f:
-            model_metadata_list = pickle.load(f)
-    else:
-        model_metadata_list = {"model_metadata": {}, "current_idx": 0}
-    # Load the dataset
-    baseline_time = time.time()
-    dataset = get_dataset(configs["data"]["dataset"],
-                          configs["data"]["data_dir"])
-
-    privacy_game = configs["audit"]["privacy_game"]
-
-    # Check the auditing game.
-    if privacy_game in ["avg_privacy_loss_training_algo", "privacy_loss_model"]:
-        # Load the trained models from disk
-        if model_metadata_list["current_idx"] > 0:
-            target_model_idx_list = load_existing_target_model(
-                len(dataset), model_metadata_list, configs
-            )
-            trained_target_models_list = load_existing_models(
-                model_metadata_list,
-                target_model_idx_list,
-                configs["train"]["model_name"],
-            )
-            trained_target_dataset_list = load_dataset_for_existing_models(
-                len(dataset),
-                model_metadata_list,
-                target_model_idx_list,
-                configs["data"],
-            )
-            num_target_models = configs["train"]["num_target_model"] - len(
-                trained_target_dataset_list
-            )
-        else:
-            target_model_idx_list = []
-            trained_target_models_list = []
-            trained_target_dataset_list = []
-            num_target_models = configs["train"]["num_target_model"]
-
-        # Prepare the datasets
-        print(25 * ">" + "Prepare the the datasets")
-        data_split_info = prepare_datasets(
-            len(dataset), num_target_models, configs["data"]
-        )
-
-        logger.info(
-            "Prepare the datasets costs %0.5f seconds", time.time() - baseline_time
-        )
-
-        # Prepare the target models
-        print(25 * ">" + "Prepare the the target models")
-        baseline_time = time.time()
-
-        new_model_list, model_metadata_list, new_target_model_idx_list = prepare_models(
-            log_dir, dataset, data_split_info, configs["train"], model_metadata_list
-        )
-
-        model_list = [*new_model_list, *trained_target_models_list]
-        data_split_info["split"] = [
-            *data_split_info["split"],
-            *trained_target_dataset_list,
-        ]
-        target_model_idx_list = [
-            *new_target_model_idx_list, *target_model_idx_list]
-
-        logger.info(
-            "Prepare the target model costs %0.5f seconds", time.time() - baseline_time
-        )
-
-        # Prepare the information sources
-        print(25 * ">" + "Prepare the information source, including attack models")
-        baseline_time = time.time()
-        (
-            target_info_source,
-            reference_info_source,
-            metrics,
-            log_dir_list,
-            model_metadata_list,
-        ) = prepare_information_source(
-            log_dir,
-            dataset,
-            data_split_info,
-            model_list,
-            configs["audit"],
-            model_metadata_list,
-            target_model_idx_list,
-        )
-        logger.info(
-            "Prepare the information source costs %0.5f seconds",
-            time.time() - baseline_time,
-        )
-
-        # Call core of privacy meter
-        print(25 * ">" + "Auditing the privacy risk")
-        baseline_time = time.time()
-        audit_obj = Audit(
-            metrics=metrics,
-            inference_game_type=inference_game_type,
-            target_info_sources=target_info_source,
-            reference_info_sources=reference_info_source,
-            fpr_tolerances=None,
-            logs_directory_names=log_dir_list,
-        )
-        audit_obj.prepare()
-        audit_results = audit_obj.run()
-        logger.info(
-            "Prepare the privacy meter result costs %0.5f seconds",
-            time.time() - baseline_time,
-        )
-
-        # Generate the privacy risk report
-        print(25 * ">" + "Generating privacy risk report")
-        baseline_time = time.time()
-        prepare_priavcy_risk_report(
-            log_dir,
-            audit_results,
-            configs["audit"],
-            save_path=f"{log_dir}/{configs['audit']['report_log']}",
-        )
-        print(100 * "#")
-
-        logger.info(
-            "Prepare the plot for the privacy risk report costs %0.5f seconds",
-            time.time() - baseline_time,
-        )
-
-        logger.info(
-            "Run the priavcy meter for the all steps costs %0.5f seconds",
-            time.time() - start_time,
-        )
-
-    # Auditing the priavcy risk for an individual data point
-    elif configs["audit"]["privacy_game"] == "privacy_loss_sample":
-        # Load existing models that match the requirement
-        assert (
-            "data_idx" in configs["train"]
-        ), "data_idx in config.train is not specified"
-        assert (
-            "data_idx" in configs["audit"]
-        ), "data_idx in config.audit is not specified"
-
-        in_model_idx_list = load_models_with_data_idx_list(
-            model_metadata_list, [configs["train"]["data_idx"]]
-        )
-        model_in_list = load_existing_models(
-            model_metadata_list,
-            in_model_idx_list,
-            configs["train"]["model_name"],
-        )
-        # Train additional models if the existing models are not enough
-        if len(in_model_idx_list) < configs["train"]["num_in_models"]:
-            data_split_info_in = prepare_datasets_for_sample_privacy_risk(
-                len(dataset),
-                configs["train"]["num_in_models"] - len(in_model_idx_list),
-                configs["train"]["data_idx"],
-                configs["data"],
-                "include",
-                "uniform",
-                model_metadata_list,
-            )
-            new_in_model_list, model_metadata_list, new_matched_in_idx = prepare_models(
-                log_dir,
-                dataset,
-                data_split_info_in,
-                configs["train"],
-                model_metadata_list,
-            )
-            model_in_list = [*new_in_model_list, *model_in_list]
-            in_model_idx_list = [*new_matched_in_idx, *in_model_idx_list]
-        in_model_list_pm = [
-            PytorchModelTensor(
-                model_obj=model, loss_fn=nn.CrossEntropyLoss(), batch_size=1000
-            )
-            for model in model_in_list
-        ]
-        if configs["data"]["split_method"] == "uniform":
-            out_model_idx_list = load_models_without_data_idx_list(
-                model_metadata_list, [configs["train"]["data_idx"]]
-            )
-        elif configs["data"]["split_method"] == "leave_one_out":
-            out_model_idx_list = load_leave_one_out_models(
-                model_metadata_list, [configs["train"]
-                                      ["data_idx"]], in_model_idx_list
-            )
-        else:
-            raise ValueError("The split method is not supported")
-
-        model_out_list = load_existing_models(
-            model_metadata_list,
-            out_model_idx_list,
-            configs["train"]["model_name"],
-        )
-        # Train additional models if the existing models are not enough
-        if len(out_model_idx_list) < configs["train"]["num_out_models"]:
-            data_split_info_out = prepare_datasets_for_sample_privacy_risk(
-                len(dataset),
-                configs["train"]["num_out_models"] - len(out_model_idx_list),
-                configs["train"]["data_idx"],
-                configs["data"],
-                "exclude",
-                configs["data"]["split_method"],
-                model_metadata_list,
-                in_model_idx_list,
-            )
-            (
-                new_out_model_list,
-                model_metadata_list,
-                new_matched_out_idx,
-            ) = prepare_models(
-                log_dir,
-                dataset,
-                data_split_info_out,
-                configs["train"],
-                model_metadata_list,
-            )
-            model_out_list = [*new_out_model_list, *model_out_list]
-            out_model_idx_list = [*new_matched_out_idx, *out_model_idx_list]
-
-        out_model_list_pm = [
-            PytorchModelTensor(
-                model_obj=model, loss_fn=nn.CrossEntropyLoss(), batch_size=1000
-            )
-            for model in model_out_list
-        ]
-
-        # Test the models' performance on the data indicated by the audit.idx
-        data, targets = get_dataset_subset(
-            dataset, [configs["audit"]["data_idx"]])
-        in_signal = np.array(
-            [model.get_loss(data, targets).item()
-             for model in in_model_list_pm]
-        )
-        out_signal = np.array(
-            [model.get_loss(data, targets).item()
-             for model in out_model_list_pm]
-        )
-
-        # Rescale the loss
-        in_signal = in_signal + 1e-17  # avoid nan
-        in_signal = np.log(
-            np.divide(np.exp(-in_signal), (1 - np.exp(-in_signal))))
-        out_signal = out_signal + 1e-17  # avoid nan
-        out_signal = np.log(
-            np.divide(np.exp(-out_signal), (1 - np.exp(-out_signal))))
-
-        # Generate the privacy risk report
-        labels = np.concatenate(
-            [np.ones(in_signal.shape[0]), np.zeros(out_signal.shape[0])]
-        )
-        histogram = sns.histplot(
-            data=pd.DataFrame(
-                {
-                    "Signal": np.concatenate([in_signal, out_signal]),
-                    "Membership": [
-                        f"In ({configs['train']['data_idx']})"
-                        if y == 1
-                        else f"Out ({configs['train']['data_idx']})"
-                        for y in labels
-                    ],
-                }
-            ),
-            x="Signal",
-            hue="Membership",
-            element="step",
-            kde=True,
-        )
-        plt.grid()
-        plt.xlabel("Signal value")
-        plt.ylabel("Number of Models")
-        plt.title(
-            f"Signal histogram for data point {configs['audit']['data_idx']}")
-        plt.savefig(
-            f"{log_dir}/{configs['audit']['report_log']}/individual_pr_{configs['train']['data_idx']}_{configs['audit']['data_idx']}.png"
-        )
-
-        # Generate the ROC
-        all_signals = np.concatenate([in_signal, out_signal])
-        all_signals.sort()
-        tpr_list = []
-        fpr_list = []
-        for threshold in all_signals:
-            tp = np.sum(in_signal < threshold)
-            fp = np.sum(out_signal < threshold)
-            tn = np.sum(out_signal >= threshold)
-            fn = np.sum(in_signal >= threshold)
-            tpr = tp / (tp + fn)
-            fpr = fp / (fp + tn)
-            tpr_list.append(tpr)
-            fpr_list.append(fpr)
-        roc_auc = np.trapz(x=fpr_list, y=tpr_list)
-        range01 = np.linspace(0, 1)
-        plt.fill_between(fpr_list, tpr_list, alpha=0.15)
-        plt.plot(range01, range01, "--", label="Random guess")
-        plt.plot(fpr_list, tpr_list, label="ROC curve")
-        plt.xlim([0, 1])
-        plt.ylim([0, 1])
-        plt.grid()
-        plt.legend()
-        plt.xlabel("False positive rate (FPR)")
-        plt.ylabel("True positive rate (TPR)")
-        plt.title("ROC curve")
-        plt.text(
-            0.7,
-            0.3,
-            f"AUC = {roc_auc:.03f}",
-            horizontalalignment="center",
-            verticalalignment="center",
-            bbox=dict(facecolor="white", alpha=0.5),
-        )
-        plt.savefig(
-            fname=f"{log_dir}/{configs['audit']['report_log']}/individual_pr_roc_{configs['train']['data_idx']}_{configs['audit']['data_idx']}.png", dpi=1000)
-        plt.clf()
diff --git a/privacy_meter/audit_report.py b/privacy_meter/audit_report.py
index 281f48d..8867ed6 100644
--- a/privacy_meter/audit_report.py
+++ b/privacy_meter/audit_report.py
@@ -1,4 +1,3 @@
-import json
 import os
 import subprocess
 from abc import ABC, abstractmethod
@@ -42,38 +41,38 @@
 
 # Config the name for metric id.
 EXPLANATIONS = {
-  "metric": {
-    "shadow_metric": {
-      "name": "Shadow metric",
-      "details": "The shadow metric is a membership inference metric, that uses the algorithm described in \\cite{https://doi.org/10.48550/arxiv.1610.05820}"
+    "metric": {
+        "shadow_metric": {
+            "name": "Shadow metric",
+            "details": "The shadow metric is a membership inference metric, that uses the algorithm described in \\cite{https://doi.org/10.48550/arxiv.1610.05820}",
+        },
+        "population_metric": {
+            "name": "Population metric",
+            "details": "[TODO] Add details in explanations.json (you can also edit citations.bib).",
+        },
+        "reference_metric": {
+            "name": "Reference metric",
+            "details": "[TODO] Add details in explanations.json (you can also edit citations.bib).",
+        },
     },
-    "population_metric": {
-      "name": "Population metric",
-      "details": "[TODO] Add details in explanations.json (you can also edit citations.bib)."
+    "figure": {
+        "roc_curve": {
+            "name": "ROC curve",
+            "details": "shows the ROC (Receiver Operating Characteristic) curve, a graph illustrating the performance of a classification model at various decision thresholds. The AUC (Area Under the Curve), represented in blue, is a threshold-independant measure of the classifier performance.\n\nA higher AUC is an indicator of a system vulnerable to the chosen metric. For reference, a random classifier yields an AUC of 0.5, while a perfect classifier yields an AUC of 1.0",
+        },
+        "confusion_matrix": {
+            "name": "Confusion matrix",
+            "details": "shows the confusion matrix, a graph illustrating the performance of a classification model for a specific decision threshold.\n\nHigher values on the top-left to bottom-right diagonal is an indicator of a system vulnerable to the chosen metric, while higher values on the top-right to bottom-left diagonal is an indicator of a system less vulnerable to the chosen metric.",
+        },
+        "signal_histogram": {
+            "name": "Signal histogram",
+            "details": "shows the histogram of the signal used by the chosen metric, on both members and non-member samples.\n\nA clear separation between the two groups is an indicator of a system vulnerable to the chosen metric.",
+        },
+        "vulnerable_points": {
+            "name": "Vulnerable points",
+            "details": "shows points that are most vulnerable to the chosen metric.\n\nThe score depends on the chosen metric, but is always between 0 and 1, with 0 meaning low vulnerability and 1 high vulnerability.",
+        },
     },
-    "reference_metric": {
-      "name": "Reference metric",
-      "details": "[TODO] Add details in explanations.json (you can also edit citations.bib)."
-    }
-  },
-  "figure": {
-    "roc_curve": {
-      "name": "ROC curve",
-      "details": "shows the ROC (Receiver Operating Characteristic) curve, a graph illustrating the performance of a classification model at various decision thresholds. The AUC (Area Under the Curve), represented in blue, is a threshold-independant measure of the classifier performance.\n\nA higher AUC is an indicator of a system vulnerable to the chosen metric. For reference, a random classifier yields an AUC of 0.5, while a perfect classifier yields an AUC of 1.0"
-    },
-    "confusion_matrix": {
-      "name": "Confusion matrix",
-      "details": "shows the confusion matrix, a graph illustrating the performance of a classification model for a specific decision threshold.\n\nHigher values on the top-left to bottom-right diagonal is an indicator of a system vulnerable to the chosen metric, while higher values on the top-right to bottom-left diagonal is an indicator of a system less vulnerable to the chosen metric."
-    },
-    "signal_histogram": {
-      "name": "Signal histogram",
-      "details": "shows the histogram of the signal used by the chosen metric, on both members and non-member samples.\n\nA clear separation between the two groups is an indicator of a system vulnerable to the chosen metric."
-    },
-    "vulnerable_points": {
-      "name": "Vulnerable points",
-      "details": "shows points that are most vulnerable to the chosen metric.\n\nThe score depends on the chosen metric, but is always between 0 and 1, with 0 meaning low vulnerability and 1 high vulnerability."
-    }
-  }
 }
 
 ########################################################################################################################
@@ -281,6 +280,7 @@ def generate_report(
             plt.savefig(fname=filename, dpi=1000)
         if show:
             plt.show()
+        print(f"AUC = {roc_auc:.03f}")
         plt.clf()
 
 
@@ -551,7 +551,6 @@ def generate_report(
 
         # If we are creating a LaTex
         if save_tex:
-
             # Load template
             template = latex_jinja_env.get_template(
                 f"{REPORT_FILES_DIR}/vulnerable_points_template.tex"
@@ -716,7 +715,6 @@ def generate_report(
         print(f'LaTex file created:\t{os.path.abspath(f"{filename_no_extension}.tex")}')
 
         if call_pdflatex:
-
             # Compile the .tex file to a .pdf file. Several rounds are required to get the references (to papers, to
             # page numbers, and to figure numbers)
 
diff --git a/privacy_meter/information_source_signal.py b/privacy_meter/information_source_signal.py
index 8054f4e..abd94f0 100644
--- a/privacy_meter/information_source_signal.py
+++ b/privacy_meter/information_source_signal.py
@@ -148,6 +148,64 @@ def __call__(
         return results
 
 
+########################################################################################################################
+# MODEL_RESCALEDLOGIT CLASS
+########################################################################################################################
+
+
+class ModelNegativeRescaledLogits(Signal):
+    """
+    Inherits from the Signal class, used to represent any type of signal that can be obtained from a Model and/or a Dataset.
+    This particular class is used to get the output of a model.
+    """
+
+    def __call__(
+        self,
+        models: List[Model],
+        datasets: List[Dataset],
+        model_to_split_mapping: List[Tuple[int, str, str, str]],
+        extra: dict,
+    ):
+        """Built-in call method.
+
+        Args:
+            models: List of models that can be queried.
+            datasets: List of datasets that can be queried.
+            model_to_split_mapping: List of tuples, indicating how each model should query the dataset.
+                More specifically, for model #i:
+                model_to_split_mapping[i][0] contains the index of the dataset in the list,
+                model_to_split_mapping[i][1] contains the name of the split,
+                model_to_split_mapping[i][2] contains the name of the input feature,
+                model_to_split_mapping[i][3] contains the name of the output feature.
+                This can also be provided once and for all at the instantiation of InformationSource, through the
+                default_model_to_split_mapping argument.
+            extra: Dictionary containing any additional parameter that should be passed to the signal object.
+
+        Returns:
+            The signal value.
+        """
+
+        results = []
+        # Compute the signal for each model
+        for k, model in enumerate(models):
+            # Extract the features to be used
+            (
+                dataset_index,
+                split_name,
+                input_feature,
+                output_feature,
+            ) = model_to_split_mapping[k]
+            x = datasets[dataset_index].get_feature(split_name, input_feature)
+            # Check if output feature has been provided, else pass None
+            if output_feature is not None:
+                y = datasets[dataset_index].get_feature(split_name, output_feature)
+            else:
+                y = None
+
+            results.append(-model.get_rescaled_logits(x, y))
+        return results
+
+
 ########################################################################################################################
 # MODEL_INTERMEDIATE_OUTPUT CLASS
 ########################################################################################################################
@@ -411,9 +469,5 @@ def __call__(
             ) = model_to_split_mapping[k]
             x = datasets[dataset_index].get_feature(split_name, input_feature)
             y = datasets[dataset_index].get_feature(split_name, output_feature)
-            results.append(
-                model.get_gradnorm(
-                    x, y
-                )
-            )
+            results.append(model.get_gradnorm(x, y))
         return results
diff --git a/privacy_meter/model.py b/privacy_meter/model.py
index dff2b5e..0f99a00 100644
--- a/privacy_meter/model.py
+++ b/privacy_meter/model.py
@@ -5,6 +5,7 @@
 import tensorflow as tf
 import torch
 from opacus import GradSampleModule  # For speeding up the gradient computation
+from scipy.special import softmax
 
 ########################################################################################################################
 # MODEL CLASS
@@ -109,9 +110,8 @@ def __init__(self, model_obj, loss_fn):
 
         # Add hooks to the layers (to access their value during a forward pass)
         self.intermediate_outputs = {}
-        for (i, l) in enumerate(list(self.model_obj._modules.keys())):
-            getattr(self.model_obj, l).register_forward_hook(
-                self.__forward_hook(l))
+        for i, l in enumerate(list(self.model_obj._modules.keys())):
+            getattr(self.model_obj, l).register_forward_hook(self.__forward_hook(l))
 
         # Create a second loss function, per point
         self.loss_fn_no_reduction = deepcopy(loss_fn)
@@ -126,7 +126,7 @@ def get_logits(self, batch_samples):
         Returns:
             Model output.
         """
-        return self.model_obj(torch.Tensor(batch_samples)).detach().numpy()
+        return self.model_obj(torch.tensor(batch_samples)).detach().numpy()
 
     def get_loss(self, batch_samples, batch_labels, per_point=True):
         """Function to get the model loss on a given input and an expected output.
@@ -142,16 +142,15 @@ def get_loss(self, batch_samples, batch_labels, per_point=True):
         if per_point:
             return (
                 self.loss_fn_no_reduction(
-                    self.model_obj(torch.Tensor(batch_samples)),
-                    torch.Tensor(batch_labels),
+                    self.model_obj(torch.tensor(batch_samples)),
+                    torch.tensor(batch_labels),
                 )
                 .detach()
                 .numpy()
             )
         else:
             return self.loss_fn(
-                self.model_obj(torch.Tensor(batch_samples)
-                               ), torch.Tensor(batch_labels)
+                self.model_obj(torch.tensor(batch_samples)), torch.tensor(batch_labels)
             ).item()
 
     def get_grad(self, batch_samples, batch_labels):
@@ -166,8 +165,7 @@ def get_grad(self, batch_samples, batch_labels):
             A list of gradients of the model loss (one item per layer) with respect to the model parameters.
         """
         loss = self.loss_fn(
-            self.model_obj(torch.Tensor(batch_samples)
-                           ), torch.Tensor(batch_labels)
+            self.model_obj(torch.tensor(batch_samples)), torch.tensor(batch_labels)
         )
         loss.backward()
         return [p.grad.numpy() for p in self.model_obj.parameters()]
@@ -185,7 +183,7 @@ def get_intermediate_outputs(self, layers, batch_samples, forward_pass=True):
             A list of intermediate outputs of layers.
         """
         if forward_pass:
-            _ = self.get_logits(torch.Tensor(batch_samples))
+            _ = self.get_logits(torch.tensor(batch_samples))
         layer_names = []
         for layer in layers:
             if isinstance(layer, str):
@@ -532,10 +530,17 @@ def get_logits(self, batch_samples):
             Model output.
         """
         self.model_obj.to(self.device)
-        logits = self.model_obj(batch_samples).detach().numpy()
+        self.model_obj.eval()
+        with torch.no_grad():
+            logits_list = []
+            batched_samples = torch.split(batch_samples, self.batch_size)
+            for x in batched_samples:
+                x = x.to(self.device)
+                out = self.model_obj(x)
+                logits_list.append(out.detach())  # to avoid the OOM
+            all_logits = torch.cat(logits_list).detach().cpu().numpy()
         self.model_obj.to("cpu")
-
-        return logits
+        return all_logits
 
     def get_loss(self, batch_samples, batch_labels, per_point=True):
         """Function to get the model loss on a given input and an expected output.
@@ -604,7 +609,9 @@ def get_grad(self, batch_samples, batch_labels):
                     ],
                     axis=1,
                 )
-                .detach().cpu().numpy()
+                .detach()
+                .cpu()
+                .numpy()
             )
             # grad = self.grad_sampler_model.conv1.weight.grad_sample.reshape(len(y),-1)
             grad_list.append(grad)
@@ -639,17 +646,23 @@ def get_gradnorm(self, batch_samples, batch_labels):
             loss = self.loss_fn(self.grad_sampler_model(x), y).sum()
             loss.backward()
             grad_norm.append(
-                torch.norm(torch.cat(
-                    [
-                        p.grad_sample.reshape(len(y), -1)
-                        for p in self.grad_sampler_model.parameters()
-                    ],
-                    axis=1,
-                ), dim=1).detach().cpu().numpy()
+                torch.norm(
+                    torch.cat(
+                        [
+                            p.grad_sample.reshape(len(y), -1)
+                            for p in self.grad_sampler_model.parameters()
+                        ],
+                        axis=1,
+                    ),
+                    dim=1,
+                )
+                .detach()
+                .cpu()
+                .numpy()
             )
 
             self.grad_sampler_model.zero_grad()
-            
+
         grad_norm = np.concatenate(grad_norm)
         self.model_obj.to("cpu")
         self.grad_sampler_model.to("cpu")
@@ -669,7 +682,7 @@ def get_intermediate_outputs(self, layers, batch_samples, forward_pass=True):
             A list of intermediate outputs of layers.
         """
         if forward_pass:
-            _ = self.get_logits(torch.Tensor(batch_samples))
+            _ = self.get_logits(torch.tensor(batch_samples))
         layer_names = []
         for layer in layers:
             if isinstance(layer, str):
@@ -680,3 +693,168 @@ def get_intermediate_outputs(self, layers, batch_samples, forward_pass=True):
             self.intermediate_outputs[layer_name].detach().numpy()
             for layer_name in layer_names
         ]
+
+    def get_rescaled_logits(self, batch_samples, batch_labels):
+        """Function to get the model rescaled logits on a given input and an expected output.
+        The rescaled logits is proposed in https://arxiv.org/abs/2112.03570.
+
+        Args:
+            batch_samples: Model input.
+            batch_labels: Model expected output.
+            per_point: Boolean indicating if loss should be returned per point or reduced.
+
+        Returns:
+            The loss value, as defined by the loss_fn attribute.
+        """
+        self.model_obj.to(self.device)
+        self.model_obj.eval()
+        with torch.no_grad():
+            rescaled_list = []
+            batched_samples = torch.split(batch_samples, self.batch_size)
+            batched_labels = torch.split(batch_labels, self.batch_size)
+            for x, y in zip(batched_samples, batched_labels):
+                COUNT = len(x)
+                x = x.to(self.device)
+                y = y.to(self.device)
+                pred = self.model_obj(x)
+                y = y.to("cpu")
+                confi = softmax(pred.detach().cpu().numpy(), axis=1)
+                confi_corret = confi[np.arange(COUNT), y]
+                confi[np.arange(COUNT), y] = 0
+                confi_wrong = np.sum(confi, axis=1)
+                logit = np.log(confi_corret + 1e-45) - np.log(confi_wrong + 1e-45)
+                rescaled_list.append(logit)
+            all_rescaled_logits = np.concatenate(rescaled_list)
+        self.model_obj.to("cpu")
+        return all_rescaled_logits
+
+
+class Sklearn_Model(Model):
+    """Inherits from the Model class, an interface to query a model without any assumption on how it is implemented.
+    This particular class is to be used with tensorflow models.
+    """
+
+    def __init__(self, model_obj, loss_fn):
+        """Constructor
+
+        Args:
+            model_obj: Model object.
+            loss_fn: Loss function.
+        """
+
+        # Imports tensorflow with global scope
+        globals()["tf"] = __import__("tensorflow")
+
+        # Initializes the parent model
+        super().__init__(model_obj, loss_fn)
+
+    def get_logits(self, batch_samples):
+        """Function to get the model output from a given input.
+
+        Args:
+            batch_samples: Model input.
+
+        Returns:
+            Model output.
+        """
+        return self.model_obj.predict_proba(batch_samples)[:, -1]
+
+    def get_loss(self, batch_samples, batch_labels, per_point=True):
+        """Function to get the model loss on a given input and an expected output.
+
+        Args:
+            batch_samples: Model input.
+            batch_labels: Model expected output.
+            per_point: Boolean indicating if loss should be returned per point or reduced.
+
+        Returns:
+            The loss value, as defined by the loss_fn attribute.
+        """
+        return self.loss_fn(batch_labels, self.get_logits(batch_samples))
+
+    def get_grad(self, batch_samples, batch_labels):
+        return None
+
+    def get_intermediate_outputs(self, layers, batch_samples, forward_pass=True):
+        return None
+
+    def __tf_list_to_np_list(self, x):
+        if isinstance(x, list):
+            return [self.__tf_list_to_np_list(y) for y in x]
+        else:
+            return x.numpy()
+
+
+class Fairlearn_Model(Model):
+    """Inherits from the Model class, an interface to query a model without any assumption on how it is implemented.
+    This particular class is to be used with tensorflow models.
+    """
+
+    def __init__(self, model_obj, loss_fn):
+        """Constructor
+
+        Args:
+            model_obj: Model object.
+            loss_fn: Loss function.
+        """
+
+        # Imports tensorflow with global scope
+        globals()["tf"] = __import__("tensorflow")
+
+        # Initializes the parent model
+        super().__init__(model_obj, loss_fn)
+
+    def get_logits(self, batch_samples):
+        """Function to get the model output from a given input.
+
+        Args:
+            batch_samples: Model input.
+
+        Returns:
+            Model output.
+        """
+        logits = []
+        for i in range(len(self.model_obj.predictors_)):
+            logits.append(
+                self.model_obj.weights_[i]
+                * self.model_obj.predictors_[i].predict_proba(batch_samples)[:, -1]
+            )
+
+        return np.mean(logits, axis=0)
+
+    def get_loss(self, batch_samples, batch_labels, per_point=True):
+        """Function to get the model loss on a given input and an expected output.
+
+        Args:
+            batch_samples: Model input.
+            batch_labels: Model expected output.
+            per_point: Boolean indicating if loss should be returned per point or reduced.
+
+        Returns:
+            The loss value, as defined by the loss_fn attribute.
+        """
+        loss = []
+        for i in range(len(self.model_obj.predictors_)):
+            loss.append(
+                self.model_obj.weights_[i]
+                * self.loss_fn(
+                    batch_labels,
+                    self.model_obj.predictors_[i].predict_proba(batch_samples)[:, -1],
+                )
+            )
+
+        return np.mean(loss, axis=0)
+
+        # return self.loss_fn(batch_labels, self.get_logits(batch_samples))
+
+    def get_grad(self, batch_samples, batch_labels):
+        return None
+
+    def get_intermediate_outputs(self, layers, batch_samples, forward_pass=True):
+        return None
+
+    def __tf_list_to_np_list(self, x):
+        if isinstance(x, list):
+            return [self.__tf_list_to_np_list(y) for y in x]
+        else:
+            return x.numpy()
diff --git a/validation/README.md b/validation/README.md
new file mode 100644
index 0000000..25eaca9
--- /dev/null
+++ b/validation/README.md
@@ -0,0 +1,22 @@
+# Reproducing Existing Results
+
+This folder provides configurations (YAML files) for reproducing the results provided in published papers on different datasets. To reproduce the results, please run the `basic/main.py` with the corresponding configuration files.
+
+**Example:**
+
+```
+cd ../basic
+python main.py --cf ../validation/cifar10/config_population_setup1.yaml
+```
+
+# Benchmark results
+
+In the following, we provide the pointer to the configuration files and the expected results, and the results we get based on the Privacy Meter.
+
+## On CIFAR10 dataset
+
+| Paper                                                                                                                       | Attack            | Target Model Structure | Results in the paper (AUC)                                                                                                                                                                                                      | Results produced by Privacy Meter (AUC)                                        | Configuration File                      |
+| --------------------------------------------------------------------------------------------------------------------------- | ----------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | --------------------------------------- |
+| [Enhanced Membership Inference Attacks against Machine Learning Models](https://dl.acm.org/doi/abs/10.1145/3548606.3560675) | Population attack | AlexNet                | 0.857±0.023 (Table 4 of the appendix)                                                                                                                                                                                           | 0.870                                                                          | `cifar10/config_population_setup1.yaml` |
+| [Enhanced Membership Inference Attacks against Machine Learning Models](https://dl.acm.org/doi/abs/10.1145/3548606.3560675) | Reference attack  | AlexNet                | 0.874±0.018 (Table 4 of the appendix)                                                                                                                                                                                           | 0.879                                                                          | `cifar10/config_reference_setup1.yaml`  |
+| [Membership Inference Attacks From First Principles](https://arxiv.org/pdf/2112.03570.pdf)                                  | Online attack     | WideResNet             | 0.6606 (reproduced without data augmentation using the [official library](https://github.com/tensorflow/privacy/tree/4dd8d0ffde4ddb1575d5c2fc02e0693e08f4f4a1/research/mi_lira_2021); the model achieves 8% generalization gap) | 0.6429 (without data augmentation; the model achieves 7.1% generalization gap) | `cifar10/config_lira_online.yaml`       |
diff --git a/validation/cifar10/config_lira_online.yaml b/validation/cifar10/config_lira_online.yaml
new file mode 100644
index 0000000..1129342
--- /dev/null
+++ b/validation/cifar10/config_lira_online.yaml
@@ -0,0 +1,44 @@
+run: # Configurations for a specific run
+  random_seed: 12345 # Integer number of specifying random seed
+  log_dir: demo_lira_attack # String for indicating where to save all the information, including models and computed signals. We can reuse the models saved in the same log_dir.
+  time_log: True # Indicate whether to log the time for each step
+
+audit: # Configurations for auditing
+  privacy_game: privacy_loss_model # Indicate the privacy game from privacy_loss_model, avg_privacy_loss_training_algo, privacy_loss_sample
+  algorithm: reference_in_out # String for indicating the membership inference attack. We currently support population, reference.
+  report_log: report_in_out_rescaled_logits # String that indicates the folder where we save the and auditing report.
+  signal: rescaled_logits # String for indicating the attack signal. We support loss, rescaled_logits.
+  device: cuda:0 # String for indicating on which device we conduct the membership inference attack and train reference models.
+  audit_batch_size: 1000 # Integer number for indicating the batch size for computing signals in the privacy meter.
+  num_in_models: 8 # Integer number that indicates how many target models trained on idx
+  num_out_models: 8 # Integer number that indicates how many target models not trained on idx
+  augmentation: None # Indicate whether to use augmentation for the query points
+  batch_size: speedyresnet_batch_size # Integer number for indicating the batch size of training the reference models if reference attack is used.
+  optimizer: speedyresnet_optimizer # String which indicates the optimizer for training reference models. We support Adam and SGD.
+  learning_rate: speedyresnet_learning_rate # Float number for indicating learning rate for training the reference model.
+  weight_decay: speedyresnet_weight_decay # Float number for indicating weight decay for training the reference model.
+  model_name: speedyresnet # String for indicating the model type. We support CNN, wrn28-1, wrn28-2, wrn28-10, vgg16, nn and speedyresnet (requires cuda). More model types can be added in model.py.
+  epochs: speedyresnet_epochs # Integer number for indicating the epochs for training target model.
+  test_batch_size: 250 # Integer number for indicating batch size for evaluating the target model.
+  num_test_size: 1000 # Integer number for indicating the size of the test dataset for evaluating the target model during the training. This should be divisible by test_batch_size.
+  fix_variance: True # Indicate hwether to fix the variance of the signals for all data points
+
+train: # Configuration for training
+  type: pytorch # Training framework (we only support pytorch now).
+  model_name: speedyresnet # String for indicating the model type. We support CNN. More model types can be added in model.py.
+  device: cuda:0 # String for indicating the device we want to use for training models.
+  num_in_models: 8 # Integer number that indicates how many target models trained on idx
+  num_out_models: 8 # Integer number that indicates how many target models not trained on idx
+  num_target_model: 1 # Number of total models we want to test
+  optimizer: speedyresnet_optimizer
+  learning_rate: speedyresnet_learning_rate
+  weight_decay: speedyresnet_weight_decay
+  batch_size: speedyresnet_batch_size
+  epochs: speedyresnet_epochs
+  test_batch_size: 5000 # Integer number for indicating batch size for evaluating the target model.
+
+data: # Configuration for data
+  dataset: cifar10 # String indicates the name of the dataset
+  data_dir: ../data
+  keep_ratio: 0.5 # the ratio of keeping the point for the training dataset.
+  dataset_size: 50000 # the size of the whole dataset used.
diff --git a/benchmark/cifar10/config_population_setup1.yaml b/validation/cifar10/config_population_setup1.yaml
similarity index 85%
rename from benchmark/cifar10/config_population_setup1.yaml
rename to validation/cifar10/config_population_setup1.yaml
index 0e2805c..65539c5 100644
--- a/benchmark/cifar10/config_population_setup1.yaml
+++ b/validation/cifar10/config_population_setup1.yaml
@@ -1,14 +1,16 @@
 run: # Configurations for a specific run
   random_seed: 12345 # Integer number of specifying random seed
   log_dir: test_ccs # String for indicating where to save all the information, including models and computed signals. We can reuse the models saved in the same log_dir.
+  time_log: True # Indicate whether to log the time for each step
 
 audit: # Configurations for auditing
   privacy_game: privacy_loss_model # Indicate the privacy game from privacy_loss_model, avg_privacy_loss_training_algo, privacy_loss_sample
   device: cuda:0 # String for indicating on which device we conduct the membership inference attack and train reference models.
-  audit_batch_size: 1000 # Integer number for indicating the batch size for computing signals in the privacy meter.
+  audit_batch_size: 1000 # Integer number for indicating the batch size for computing signals in the Privacy Meter.
   algorithm: population # String for indicating the membership inference attack. We currently support population, reference.
   report_log: report_population # String that indicates the folder where we save the and auditing report.
-  split_method: uniform # String for indicating the splitting methods for reference dataset. We support uniform and leave_one_out.
+  augmentation: None # Indicate whether to use augmentation for the query points
+  signal: loss # String for indicating the attack signal. We support loss, rescaled_logits.
 
 train: # Configuration for training
   type: pytorch # Training framework (we only support pytorch now).
@@ -22,6 +24,7 @@ train: # Configuration for training
   device: cuda:0 # String for indicating the device we want to use for training models.
   key: none # String for indicating the meaning of the idx. We support data_idx, model_idx or none.
   num_target_model: 1 #Integer number for indicating how many target models we want to audit for the privacy game
+  test_batch_size: 5000 # Integer number for indicating batch size for evaluating the target model.
 
 data: # Configuration for data
   dataset: cifar10 # String indicates the name of the dataset
@@ -29,4 +32,4 @@ data: # Configuration for data
   f_test: 0.041666666666666664 # Float number from 0 to 1 indicating the fraction of the test dataset
   split_method: no_overlapping # String for indicating the methods of splitting the dataset between train, test, and auditing. Note that, compare to the baseline, we don't use the class balanced splitting.
   f_audit: 0.06666666666666667 # Float from 0 to 1, indicating the fraction of the auditing dataset
-  data_dir: data # String about where to save the data.
+  data_dir: ../data # String about where to save the data.
\ No newline at end of file
diff --git a/benchmark/cifar10/config_reference_setup1.yaml b/validation/cifar10/config_reference_setup1.yaml
similarity index 79%
rename from benchmark/cifar10/config_reference_setup1.yaml
rename to validation/cifar10/config_reference_setup1.yaml
index 2141f1e..301a383 100644
--- a/benchmark/cifar10/config_reference_setup1.yaml
+++ b/validation/cifar10/config_reference_setup1.yaml
@@ -1,12 +1,13 @@
 run: # Configurations for a specific run
   random_seed: 12345 # Integer number of specifying random seed
   log_dir: test_ccs # String for indicating where to save all the information, including models and computed signals. We can reuse the models saved in the same log_dir.
+  time_log: True # Indicate whether to log the time for each step
 
 audit: # Configurations for auditing
   privacy_game: privacy_loss_model # Indicate the privacy game from privacy_loss_model, avg_privacy_loss_training_algo, privacy_loss_sample
   device: cuda:0 # String for indicating on which device we conduct the membership inference attack and train reference models.
-  audit_batch_size: 1000 # Integer number for indicating the batch size for computing signals in the privacy meter.
-  algorithm: reference # String for indicating the membership inference attack. We currently support population, reference.
+  audit_batch_size: 1000 # Integer number for indicating the batch size for computing signals in the Privacy Meter.
+  algorithm: reference_out # String for indicating the membership inference attack. We currently support population, reference.
   report_log: report_reference # String that indicates the folder where we save the and auditing report.
   num_reference_models: 300 # Integer number for indicating how many reference models we need to train for auditing, if the reference attack is used.
   batch_size: 16 # Integer number for indicating the batch size of training the reference models if reference attack is used.
@@ -17,8 +18,9 @@ audit: # Configurations for auditing
   model_name: alexnet # String for indicating the model type. We support CNN,alexnet. More model type can be added in model.py.
   epochs: 75 # Integer number for indicating the epochs for training target model.
   split_method: uniform # String for indicating the splitting methods for reference dataset. We support uniform and leave_one_out.
-  key: none # String for indicating the meaning of the idx. We support data_idx and none for reusing existing reference models. data_idx search for models which include or exclude the data point indicated using idx. Otherwise, the reference models are the ones that have the same training setting as indicated above.
-  idx: none # Integer number for the model index or data index.
+  augmentation: None # Indicate whether to use augmentation for the query points
+  test_batch_size: 5000 # Integer number for indicating batch size for evaluating the target model.
+  signal: loss # String for indicating the attack signal. We support loss, rescaled_logits.
 
 train: # Configuration for training
   type: pytorch # Training framework (we only support pytorch now).
@@ -26,12 +28,13 @@ train: # Configuration for training
   batch_size: 16 # Integer number for indicating batch size for training the target model.
   test_batch_size: 10000 # Integer number for indicating batch size for evaluating the target model.
   optimizer: Adam # String which indicates the optimizer. We support Adam and SGD.
-  lr: 0.001 # Float number for indicating learning rate for training the target model.
-  wd: 0 # Float number for indicating weight decay for training the target model.
+  learning_rate: 0.001 # Float number for indicating learning rate for training the target model.
+  weight_decay: 0 # Float number for indicating weight decay for training the target model.
   model_name: alexnet # String for indicating the model type. We support CNN. More model types can be added in model.py.
   device: cuda:0 # String for indicating the device we want to use for training models.
   key: none # String for indicating the meaning of the idx. We support data_idx, model_idx or none.
   num_target_model: 1 #Integer number for indicating how many target models we want to audit for the privacy game
+  test_batch_size: 5000 # Integer number for indicating batch size for evaluating the target model.
 
 data: # Configuration for data
   dataset: cifar10 # String indicates the name of the dataset
@@ -39,4 +42,4 @@ data: # Configuration for data
   f_test: 0.041666666666666664 # Float number from 0 to 1 indicating the fraction of the test dataset
   split_method: no_overlapping # String for indicating the methods of splitting the dataset between train, test, and auditing. Note that, compare to the baseline, we don't use the class balanced splitting.
   f_audit: 0.06666666666666667 # Float from 0 to 1, indicating the fraction of the auditing dataset
-  data_dir: data
+  data_dir: ../data
\ No newline at end of file


Test patch:
diff --git a/advanced/cifar-10-batches-py/test_batch b/advanced/cifar-10-batches-py/test_batch
new file mode 100644
index 0000000..3e03f1f
Binary files /dev/null and b/advanced/cifar-10-batches-py/test_batch differ
diff --git a/basic/learning_rate_test.py b/basic/learning_rate_test.py
new file mode 100644
index 0000000..4516e38
--- /dev/null
+++ b/basic/learning_rate_test.py
@@ -0,0 +1,181 @@
+import time
+
+import torch
+import torch.nn.functional as F
+from matplotlib import pyplot as plt
+from models import get_model
+from torch.utils.data import DataLoader
+from torch.utils.data.sampler import SubsetRandomSampler
+from torchvision import datasets, transforms
+
+if torch.cuda.is_available():
+    torch.backends.cudnn.deterministic = True
+import numpy as np
+
+device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
+
+
+def cyclical_learning_rate(
+    batch_step,
+    step_size,
+    base_lr=0.001,
+    max_lr=0.006,
+    mode="triangular",
+    gamma=0.999995,
+):
+    cycle = np.floor(1 + batch_step / (2.0 * step_size))
+    x = np.abs(batch_step / float(step_size) - 2 * cycle + 1)
+
+    lr_delta = (max_lr - base_lr) * np.maximum(0, (1 - x))
+
+    if mode == "triangular":
+        pass
+    elif mode == "triangular2":
+        lr_delta = lr_delta * 1 / (2.0 ** (cycle - 1))
+    elif mode == "exp_range":
+        lr_delta = lr_delta * (gamma ** (batch_step))
+    else:
+        raise ValueError('mode must be "triangular", "triangular2", or "exp_range"')
+
+    lr = base_lr + lr_delta
+
+    return lr
+
+
+def compute_accuracy(model, data_loader):
+    correct_pred, num_examples = 0, 0
+    for features, targets in data_loader:
+        features = features.to(device)
+        targets = targets.to(device)
+        logits = model(features)
+        probas = F.softmax(logits, dim=1)
+        _, predicted_labels = torch.max(probas, 1)
+        num_examples += targets.size(0)
+        correct_pred += (predicted_labels == targets).sum()
+    return correct_pred.float() / num_examples * 100
+
+
+num_epochs = 25
+num_train = 30000
+batch_size = 512
+base_lr = 0.09
+max_lr = 0.5
+
+# Hyperparameters
+random_seed = 1
+num_classes = 100
+np.random.seed(random_seed)
+torch.manual_seed(random_seed)
+
+
+idx = np.arange(50000)  # the size of CIFAR10-train
+np.random.shuffle(idx)
+val_idx, train_idx = idx[:num_train], idx[num_train:]
+train_sampler = SubsetRandomSampler(train_idx)
+val_sampler = SubsetRandomSampler(val_idx)
+
+train_dataset = datasets.CIFAR100(
+    root="data", train=True, transform=transforms.ToTensor(), download=True
+)
+
+test_dataset = datasets.CIFAR100(
+    root="data", train=False, transform=transforms.ToTensor()
+)
+
+
+train_loader = DataLoader(
+    dataset=train_dataset,
+    batch_size=batch_size,
+    # shuffle=True, # Subsetsampler already shuffles
+    sampler=train_sampler,
+)
+
+val_loader = DataLoader(
+    dataset=train_dataset,
+    batch_size=batch_size,
+    # shuffle=True,
+    sampler=val_sampler,
+)
+
+
+num_epochs = 10
+iter_per_ep = len(train_loader)
+model = get_model(model_type="wrn28-2", dataset_name="cifar100")
+model = model.to(device)
+cost_fn = torch.nn.CrossEntropyLoss()
+optimizer = torch.optim.SGD(
+    model.parameters(), lr=base_lr, nesterov=True, momentum=0.9, weight_decay=5e-4
+)
+collect = {"lr": [], "cost": [], "train_batch_acc": [], "val_acc": []}
+
+batch_step = -1
+cur_lr = base_lr
+
+start_time = time.time()
+for epoch in range(num_epochs):
+    for batch_idx, (features, targets) in enumerate(train_loader):
+        batch_step += 1
+        features = features.to(device)
+        targets = targets.to(device)
+
+        ### FORWARD AND BACK PROP
+        logits = model(features)
+        probas = F.softmax(logits, dim=1)
+        cost = cost_fn(logits, targets)
+        optimizer.zero_grad()
+
+        cost.backward()
+
+        ### UPDATE MODEL PARAMETERS
+        optimizer.step()
+
+        #############################################
+        # Logging
+        if not batch_step % 200:
+            print(
+                "Total batch # %5d/%d" % (batch_step, iter_per_ep * num_epochs), end=""
+            )
+            print("   Curr. Batch Cost: %.5f" % cost)
+
+        #############################################
+        # Collect stats
+        model = model.eval()
+        train_acc = compute_accuracy(model, [[features, targets]])
+        val_acc = compute_accuracy(model, val_loader)
+        collect["lr"].append(cur_lr)
+        collect["train_batch_acc"].append(train_acc)
+        collect["val_acc"].append(val_acc)
+        collect["cost"].append(cost)
+        model = model.train()
+        #############################################
+        # update learning rate
+        cur_lr = cyclical_learning_rate(
+            batch_step=batch_step,
+            step_size=num_epochs * iter_per_ep,
+            base_lr=base_lr,
+            max_lr=max_lr,
+        )
+        for g in optimizer.param_groups:
+            g["lr"] = cur_lr
+        ############################################
+
+    print("Time elapsed: %.2f min" % ((time.time() - start_time) / 60))
+
+print("Total Training Time: %.2f min" % ((time.time() - start_time) / 60))
+# torch.stack(collect['train_batch_acc']).cpu().numpy()
+
+plt.plot(
+    collect["lr"],
+    torch.stack(collect["train_batch_acc"]).cpu().numpy(),
+    label="train_batch_acc",
+)
+plt.plot(collect["lr"], torch.stack(collect["val_acc"]).cpu().numpy(), label="val_acc")
+plt.xlabel("Learning Rate")
+plt.ylabel("Accuracy")
+plt.legend()
+plt.savefig("learning_rate_test.png")
+plt.clf()
+plt.plot(collect["lr"], torch.stack(collect["cost"]).detach().cpu().numpy())
+plt.xlabel("Learning Rate")
+plt.ylabel("Current Batch Cost")
+plt.savefig("learning_rate_test_cost.png")
diff --git a/privacy_meter/hypothesis_test.py b/privacy_meter/hypothesis_test.py
index 8f574df..d268b98 100644
--- a/privacy_meter/hypothesis_test.py
+++ b/privacy_meter/hypothesis_test.py
@@ -34,8 +34,6 @@ def threshold_func(distribution: List[float], alpha: List[float], **kwargs) -> f
 def linear_itp_threshold_func(
     distribution: List[float],
     alpha: List[float],
-    signal_min=0,
-    signal_max=1000,
     **kwargs,
 ) -> float:
     """
@@ -46,8 +44,6 @@ def linear_itp_threshold_func(
         the threshold is computed. (Here we only consider positive signal values.)
         alpha: Quantile value that will be used to obtain the threshold from the
             distribution.
-        signal_min: minimum of all possible signal values, default value is zero
-        signal_max: maximum of all possible signal values, default vaule is 1000
     Returns:
         threshold: alpha quantile of the provided distribution.
     """
@@ -58,11 +54,21 @@ def linear_itp_threshold_func(
             distribution, q=alpha[1:-1], method="linear", axis=1, **kwargs
         )
         threshold = np.concatenate(
-            [threshold, np.repeat(signal_max, distribution.shape[0]).reshape(1, -1)],
+            [
+                threshold,
+                np.repeat(distribution.max() + 1e-4, distribution.shape[0]).reshape(
+                    1, -1
+                ),
+            ],
             axis=0,
         )
         threshold = np.concatenate(
-            [np.repeat(signal_min, distribution.shape[0]).reshape(1, -1), threshold],
+            [
+                np.repeat(distribution.min() - 1e-4, distribution.shape[0]).reshape(
+                    1, -1
+                ),
+                threshold,
+            ],
             axis=0,
         )
 
@@ -70,9 +76,9 @@ def linear_itp_threshold_func(
         threshold = np.quantile(distribution, q=alpha[1:-1], method="linear", **kwargs)
         threshold = np.concatenate(
             [
-                np.array(signal_min).reshape(-1),
+                np.array(distribution.min() - 1e-4).reshape(-1),
                 threshold,
-                np.array(signal_max).reshape(-1),
+                np.array(distribution.max() + 1e-4).reshape(-1),
             ],
             axis=0,
         )
@@ -170,8 +176,6 @@ def gaussian_threshold_func(
 def min_linear_logit_threshold_func(
     distribution: List[float],
     alpha: List[float],
-    signal_min=0,
-    signal_max=1000,
     **kwargs,
 ) -> float:
     """
@@ -184,15 +188,11 @@ def min_linear_logit_threshold_func(
         the threshold is computed. (Here we only consider positive signal values.)
         alpha: Quantile value that will be used to obtain the threshold from the
             distribution.
-        signal_min: minimum of all possible signal values, default value is zero
-        signal_max: maximum of all possible signal values, default vaule is 1000
     Returns:
         threshold: alpha quantile of the provided distribution.
     """
 
-    threshold_linear = linear_itp_threshold_func(
-        distribution, alpha, signal_min, signal_max, **kwargs
-    )
+    threshold_linear = linear_itp_threshold_func(distribution, alpha, **kwargs)
     threshold_logit = logit_rescale_threshold_func(distribution, alpha, **kwargs)
 
     threshold = np.minimum(threshold_logit, threshold_linear)
diff --git a/tests/test_train.py b/tests/test_train.py
index 8e148c2..667b736 100644
--- a/tests/test_train.py
+++ b/tests/test_train.py
@@ -78,7 +78,7 @@ def test_inference():
     data_loader = torch.utils.data.DataLoader(
         dataset, batch_size=1000, shuffle=False, num_workers=2
     )
-    loss_b, acc_b = inference(model, data_loader, "cuda:1")
+    loss_b, acc_b = inference(model, data_loader, "cuda:0")
 
     updated_w = model.state_dict()
     # Make sure that the original model is not updated. Inference function does not change the model parameters.
@@ -95,5 +95,5 @@ def test_inference():
     }
 
     updated_model = train(model, data_loader, configs)
-    loss_a, acc_a = inference(updated_model, data_loader, "cuda:1")
+    loss_a, acc_a = inference(updated_model, data_loader, "cuda:0")
     assert loss_a < loss_b, acc_a > acc_b