From da9a40585d94c8f05af9f5592bd43cead38b9fd9 Mon Sep 17 00:00:00 2001 From: snoop2head Date: Mon, 29 Aug 2022 15:54:08 +0900 Subject: [PATCH] plot ROC curve for CIFAR10 MIA --- README.md | 5 +++-- assets/roc_cifar10.png | Bin 0 -> 45861 bytes config.yaml | 5 ++--- inference_attack.py | 9 +++++---- train_shadow.py | 17 ++++++++--------- train_target.py | 13 ++++++------- 6 files changed, 24 insertions(+), 25 deletions(-) create mode 100644 assets/roc_cifar10.png diff --git a/README.md b/README.md index b006597..40ca643 100644 --- a/README.md +++ b/README.md @@ -24,14 +24,15 @@ Modifications were made on shadow models' training methodology in order to preve ### Result - Replicated the paper's configuration on [config.yaml](./config.yaml) -- Below is an example of ROC Curve plotting `TPR / FPR` according to MIA classification thresholds for CIFAR 100 dataset +- ROC Curve is plotting `TPR / FPR` according to MIA classification thresholds | MIA Attack Metrics | Accuracy | Precision | Recall | F1 Score | | :----------------: | :------: | :-------: | :----: | :------: | | CIFAR10 | 0.8376 | 0.8087 | 0.8834 | 0.8444 | | CIFAR100 | 0.9746 | 0.9627 | 0.9875 | 0.9749 | -![roc_curve](./assets/roc_cifar100.png) +![roc_curve CIFAR10](./assets/roc_cifar10.png) +![roc_curve CIFAR100](./assets/roc_cifar100.png) ### Paper's Methodology in Diagrams diff --git a/assets/roc_cifar10.png b/assets/roc_cifar10.png new file mode 100644 index 0000000000000000000000000000000000000000..d38d527bb29378ad1d20768388c83b449e5910c7 GIT binary patch literal 45861 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 literal 0 HcmV?d00001 diff --git a/config.yaml b/config.yaml index b3b7a5d..d977eaa 100644 --- a/config.yaml +++ b/config.yaml @@ -1,10 +1,9 @@ # config for shadow CFG: dataset_name: CIFAR10 # CIFAR10 vs CIFAR100 selection - model_architecture: resnet18 - DEBUG: false + model_architecture: resnet18 # names available on torchvision.models https://pytorch.org/vision/stable/models.html#classification topk_num_accessible_probs: 10 # topk match with accessible classes logits/probability classes number from the target model. usually top 5 for APIs - # We set the learning rate to 0.001, the learning rate decay to 1e − 07, and the maximum epochs of training to 100. + # "We set the learning rate to 0.001, the learning rate decay to 1e − 07, and the maximum epochs of training to 100." num_epochs: 100 # number of shadow model train epochs learning_rate: 0.001 learning_rate_decay: 0.0000001 # NOT IMPLEMENTED ON THE REPO diff --git a/inference_attack.py b/inference_attack.py index c45b3a6..4079e56 100644 --- a/inference_attack.py +++ b/inference_attack.py @@ -4,6 +4,7 @@ from torch import nn import torchvision import torchvision.transforms as transforms +from torch.utils.data import DataLoader, Subset from utils.seed import seed_everything from utils.load_config import load_config import pandas as pd @@ -59,14 +60,14 @@ list_nonmember_indices = pd.read_csv("./attack/train_indices.csv")["index"].to_list() list_member_indices = np.random.choice(len(testset), len(list_nonmember_indices), replace=False) -subset_nonmember = torch.utils.data.Subset(trainset, list_nonmember_indices) -subset_member = torch.utils.data.Subset(testset, list_member_indices) +subset_nonmember = Subset(trainset, list_nonmember_indices) +subset_member = Subset(testset, list_member_indices) -subset_nonmember_loader = torch.utils.data.DataLoader( +subset_nonmember_loader = DataLoader( subset_nonmember, batch_size=CFG.train_batch_size, shuffle=True, num_workers=2 ) -subset_member_loader = torch.utils.data.DataLoader( +subset_member_loader = DataLoader( subset_member, batch_size=CFG.train_batch_size, shuffle=True, num_workers=2 ) diff --git a/train_shadow.py b/train_shadow.py index 6acab3d..57b5762 100644 --- a/train_shadow.py +++ b/train_shadow.py @@ -8,6 +8,7 @@ import torch.nn as nn import torch.nn.functional as F from torch.optim import Adam, AdamW +from torch.utils.data import DataLoader, Subset import torchvision.transforms as transforms from tqdm import tqdm import pandas as pd @@ -45,9 +46,7 @@ ] ) shadow_set = DSET_CLASS(root="./data", train=True, download=True, transform=transform) -shadow_loader = torch.utils.data.DataLoader( - shadow_set, batch_size=CFG.train_batch_size, shuffle=True, num_workers=2 -) +shadow_loader = DataLoader(shadow_set, batch_size=CFG.train_batch_size, shuffle=True, num_workers=2) # define dataset for attack model that shadow models will generate print("mapped classes to ids:", shadow_set.class_to_idx) @@ -70,19 +69,19 @@ ) test_indices = np.random.choice(test_indices, CFG.shadow_train_size, replace=False) - subset_train = torch.utils.data.Subset(shadow_set, train_indices) - subset_eval = torch.utils.data.Subset(shadow_set, eval_indices) - subset_test = torch.utils.data.Subset(shadow_set, test_indices) + subset_train = Subset(shadow_set, train_indices) + subset_eval = Subset(shadow_set, eval_indices) + subset_test = Subset(shadow_set, test_indices) - subset_train_loader = torch.utils.data.DataLoader( + subset_train_loader = DataLoader( subset_train, batch_size=CFG.train_batch_size, shuffle=True, num_workers=2 ) - subset_eval_loader = torch.utils.data.DataLoader( + subset_eval_loader = DataLoader( subset_eval, batch_size=CFG.val_batch_size, shuffle=False, num_workers=2 ) - subset_test_loader = torch.utils.data.DataLoader( + subset_test_loader = DataLoader( subset_test, batch_size=CFG.val_batch_size, shuffle=False, num_workers=2 ) diff --git a/train_target.py b/train_target.py index 0348779..227db77 100644 --- a/train_target.py +++ b/train_target.py @@ -8,6 +8,7 @@ import torch.nn as nn import torch.nn.functional as F from torch.optim import Adam, AdamW +from torch.utils.data import DataLoader, Subset import torchvision.transforms as transforms from tqdm import tqdm import pandas as pd @@ -43,9 +44,7 @@ ) testset = DSET_CLASS(root="./data", train=False, download=True, transform=transform) -testloader = torch.utils.data.DataLoader( - testset, batch_size=CFG.val_batch_size, shuffle=False, num_workers=2 -) +testloader = DataLoader(testset, batch_size=CFG.val_batch_size, shuffle=False, num_workers=2) # define dataset for attack model that shadow models will generate print("mapped classes to ids:", testset.class_to_idx) @@ -69,13 +68,13 @@ "./attack/train_indices.csv", index=False ) -subset_tgt_train = torch.utils.data.Subset(testset, target_train_indices) -subset_tgt_eval = torch.utils.data.Subset(testset, target_eval_indices) +subset_tgt_train = Subset(testset, target_train_indices) +subset_tgt_eval = Subset(testset, target_eval_indices) -subset_tgt_train_loader = torch.utils.data.DataLoader( +subset_tgt_train_loader = DataLoader( subset_tgt_train, batch_size=CFG.train_batch_size, shuffle=True, num_workers=2 ) -subset_tgt_eval_loader = torch.utils.data.DataLoader( +subset_tgt_eval_loader = DataLoader( subset_tgt_eval, batch_size=CFG.val_batch_size, shuffle=False, num_workers=2 )