Commit 268e9b5c by Klin
parents e13f1f29 204f7fcb
...@@ -181,7 +181,7 @@ def build_trajectory_membership_dataset(args, ori_model_path, device='cpu'): ...@@ -181,7 +181,7 @@ def build_trajectory_membership_dataset(args, ori_model_path, device='cpu'):
gol.set_value(plist) gol.set_value(plist)
# load这些非distill model只是为了获得最后一个loss # load这些非distill model只是为了获得最后一个loss
# 对于量化后的 这里应该要改吧,需要load量化后的模型来做推理 # 对于量化后的,需要load量化后的模型来做推理
if args.mode == 'target': if args.mode == 'target':
cnn_model, cnn_params = normal.load_model(args, ori_model_path+'/target', model_name, epoch=args.epochs) cnn_model, cnn_params = normal.load_model(args, ori_model_path+'/target', model_name, epoch=args.epochs)
...@@ -206,22 +206,17 @@ def build_trajectory_membership_dataset(args, ori_model_path, device='cpu'): ...@@ -206,22 +206,17 @@ def build_trajectory_membership_dataset(args, ori_model_path, device='cpu'):
# params['task']中记录用什么数据集 # params['task']中记录用什么数据集
# 尝试调小batch size看看resnet50/152是否还会爆显存
# 这里调小了batchsize=128会导致ResNet_18的attack acc相比于batchsize=512时下降2% # 这里调小了batchsize=128会导致ResNet_18的attack acc相比于batchsize=512时下降2%
dataset = mia_utils.get_dataset(cnn_params['task'], mode=args.mode, aug=True, batch_size=512) dataset = mia_utils.get_dataset(cnn_params['task'], mode=args.mode, aug=True, batch_size=256)
if args.mode == 'target': if args.mode == 'target':
print('load target_dataset ... ') print('load target_dataset ... ')
train_loader = dataset.aug_target_train_loader train_loader = dataset.aug_target_train_loader
# test set不再做data augmentation
# test_loader = dataset.aug_target_test_loader
test_loader = dataset.target_test_loader test_loader = dataset.target_test_loader
elif args.mode == 'shadow': elif args.mode == 'shadow':
print('load shadow_dataset ... ') print('load shadow_dataset ... ')
train_loader = dataset.aug_shadow_train_loader train_loader = dataset.aug_shadow_train_loader
# test_loader = dataset.aug_shadow_test_loader
test_loader = dataset.shadow_test_loader test_loader = dataset.shadow_test_loader
model_top1 = None model_top1 = None
...@@ -352,7 +347,6 @@ def trajectory_black_box_membership_inference_attack(args, models_path, device=' ...@@ -352,7 +347,6 @@ def trajectory_black_box_membership_inference_attack(args, models_path, device='
epoch = 0 epoch = 0
# 这里如果要加val set,就直接把trainset按8:2划分 # 这里如果要加val set,就直接把trainset按8:2划分
# AttackModelTrainSet = np.load(models_path + f'/shadow/{model_name}/trajectory_train_data.npy', allow_pickle=True).item()
if args.quant_type is None: if args.quant_type is None:
AttackModelTrainSet = np.load(models_path + f'/shadow/{model_name}/trajectory_train_data.npy', allow_pickle=True).item() AttackModelTrainSet = np.load(models_path + f'/shadow/{model_name}/trajectory_train_data.npy', allow_pickle=True).item()
else: else:
...@@ -377,7 +371,7 @@ def trajectory_black_box_membership_inference_attack(args, models_path, device=' ...@@ -377,7 +371,7 @@ def trajectory_black_box_membership_inference_attack(args, models_path, device='
# train/test i.e. in or out # train/test i.e. in or out
torch.from_numpy(np.array(check_and_transform_label_format(AttackModelTrainSet['predicted_status'], nb_classes=2, return_one_hot=True)[:,:2])).type(torch.long), torch.from_numpy(np.array(check_and_transform_label_format(AttackModelTrainSet['predicted_status'], nb_classes=2, return_one_hot=True)[:,:2])).type(torch.long),
torch.from_numpy(np.array(AttackModelTrainSet['member_status'])).type(torch.long),) torch.from_numpy(np.array(AttackModelTrainSet['member_status'])).type(torch.long),)
attack_train_loader = torch.utils.data.DataLoader(train_set, batch_size=128, shuffle=True) attack_train_loader = torch.utils.data.DataLoader(train_set, batch_size=512, shuffle=True)
test_set = torch.utils.data.TensorDataset( test_set = torch.utils.data.TensorDataset(
torch.from_numpy(np.array(AttackModelTestSet['model_loss_ori'], dtype='f')), torch.from_numpy(np.array(AttackModelTestSet['model_loss_ori'], dtype='f')),
...@@ -387,7 +381,7 @@ def trajectory_black_box_membership_inference_attack(args, models_path, device=' ...@@ -387,7 +381,7 @@ def trajectory_black_box_membership_inference_attack(args, models_path, device='
# train/test i.e. in or out # train/test i.e. in or out
torch.from_numpy(np.array(check_and_transform_label_format(AttackModelTestSet['predicted_status'], nb_classes=2, return_one_hot=True)[:,:2])).type(torch.long), torch.from_numpy(np.array(check_and_transform_label_format(AttackModelTestSet['predicted_status'], nb_classes=2, return_one_hot=True)[:,:2])).type(torch.long),
torch.from_numpy(np.array(AttackModelTestSet['member_status'])).type(torch.long),) torch.from_numpy(np.array(AttackModelTestSet['member_status'])).type(torch.long),)
attack_test_loader = torch.utils.data.DataLoader(test_set, batch_size=128, shuffle=True) attack_test_loader = torch.utils.data.DataLoader(test_set, batch_size=512, shuffle=True)
print(f'-------------------"Loss Trajectory"------------------') print(f'-------------------"Loss Trajectory"------------------')
# 训练Attack Model # 训练Attack Model
...@@ -508,8 +502,6 @@ def get_trajectory(data, target, args, model_path, device='cpu'): ...@@ -508,8 +502,6 @@ def get_trajectory(data, target, args, model_path, device='cpu'):
print(f"MODEL NAME IS :{model_name}") print(f"MODEL NAME IS :{model_name}")
trajectory = None trajectory = None
# 创建一个形状为 (data.shape[0], 1) 的 NumPy 数组 predicted_label,并将其初始化为 -1 data.shape[0]即batch_size # 创建一个形状为 (data.shape[0], 1) 的 NumPy 数组 predicted_label,并将其初始化为 -1 data.shape[0]即batch_size
# predicted_label = np.array([-1]).repeat(data.shape[0],0).reshape(data.shape[0],1)
# TODO 需要适配由PTQ Target Model得到的Distill Target Model # TODO 需要适配由PTQ Target Model得到的Distill Target Model
# 虽然是通过mode == shadow和target来区分,但load的model是ditill model # 虽然是通过mode == shadow和target来区分,但load的model是ditill model
...@@ -518,20 +510,6 @@ def get_trajectory(data, target, args, model_path, device='cpu'): ...@@ -518,20 +510,6 @@ def get_trajectory(data, target, args, model_path, device='cpu'):
model_path_current = 'mia_ckpt/{}'.format(s) model_path_current = 'mia_ckpt/{}'.format(s)
# 对每个distill epoch (是看的distill model对target的loss并记录成为loss_trajectory) # 对每个distill epoch (是看的distill model对target的loss并记录成为loss_trajectory)
for i in range(1, args.epochs_distill+1): for i in range(1, args.epochs_distill+1):
# 通过load存储的distill model在各个epoch时候的权值参数来复现loss
# if args.mode == 'shadow':
# cnn_model_target, cnn_params_target = normal.load_model(args, model_path_current+'/distill_shadow', model_name, epoch=i)
# elif args.mode == 'target':
# if args.quant_type is None:
# cnn_model_target, cnn_params_target = normal.load_model(args, model_path_current+'/distill_target', model_name, epoch=i)
# # TODO 调整load的路径,把(ptq) Distill Target Model的权值参数load进来
# else:
# if args.quant_type == 'FLOAT':
# title = '%s_%d_E%d' % (args.quant_type, args.num_bits, args.e_bits)
# else:
# title = '%s_%d' % (args.quant_type, args.num_bits)
# cnn_model_target, cnn_params_target = normal.load_model(args, model_path_current+'/distill_target', model_name + '_' + title, epoch=i)
if args.quant_type is None: if args.quant_type is None:
cnn_model_target, cnn_params_target = normal.load_model(args, model_path_current+'/distill_'+args.mode, model_name, epoch=i) cnn_model_target, cnn_params_target = normal.load_model(args, model_path_current+'/distill_'+args.mode, model_name, epoch=i)
# TODO 调整load的路径,把(ptq) Distill Target Model的权值参数load进来 # TODO 调整load的路径,把(ptq) Distill Target Model的权值参数load进来
...@@ -553,8 +531,6 @@ def get_trajectory(data, target, args, model_path, device='cpu'): ...@@ -553,8 +531,6 @@ def get_trajectory(data, target, args, model_path, device='cpu'):
# 都是distill model的output,因此不需要quantize_inference # 都是distill model的output,因此不需要quantize_inference
logit_target = MODEL_target(data) logit_target = MODEL_target(data)
# 看target model的output与label的loss (batch list中的各个数据分别算) # 看target model的output与label的loss (batch list中的各个数据分别算)
loss = [F.cross_entropy(logit_target_i.unsqueeze(0), target_i.unsqueeze(0)) for (logit_target_i, target_i) in zip(logit_target, target)] loss = [F.cross_entropy(logit_target_i.unsqueeze(0), target_i.unsqueeze(0)) for (logit_target_i, target_i) in zip(logit_target, target)]
# list -> nparray 一列的 # list -> nparray 一列的
......
...@@ -16,7 +16,7 @@ if __name__ == '__main__': ...@@ -16,7 +16,7 @@ if __name__ == '__main__':
# 统一计算所有的js # 统一计算所有的js
gol._init() gol._init()
quant_type_list = ['INT','POT'] quant_type_list = ['INT','POT','FLOAT']
filename =f'{args.model}_mia_result.xlsx' filename =f'{args.model}_mia_result.xlsx'
workbook = openpyxl.load_workbook(filename) workbook = openpyxl.load_workbook(filename)
......
...@@ -80,126 +80,122 @@ echo "Use GPU ${CUDA_VISIBLE_DEVICES}" # which gpus ...@@ -80,126 +80,122 @@ echo "Use GPU ${CUDA_VISIBLE_DEVICES}" # which gpus
# # TRAIN DISTILL TARGET MODEL # # TRAIN DISTILL TARGET MODEL
# echo "python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 2 --epochs_distill $Distill" echo "python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 2 --epochs_distill $Distill"
# python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 2 --epochs_distill $Distill python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 2 --epochs_distill $Distill
# echo "python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 3 --epochs_distill $Distill" echo "python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 3 --epochs_distill $Distill"
# python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 3 --epochs_distill $Distill python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 3 --epochs_distill $Distill
# echo "python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 4 --epochs_distill $Distill" echo "python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 4 --epochs_distill $Distill"
# python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 4 --epochs_distill $Distill python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 4 --epochs_distill $Distill
# echo "python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 5 --epochs_distill $Distill" echo "python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 5 --epochs_distill $Distill"
# python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 5 --epochs_distill $Distill python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 5 --epochs_distill $Distill
# echo "python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 6 --epochs_distill $Distill" echo "python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 6 --epochs_distill $Distill"
# python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 6 --epochs_distill $Distill python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 6 --epochs_distill $Distill
# echo "python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 7 --epochs_distill $Distill" echo "python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 7 --epochs_distill $Distill"
# python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 7 --epochs_distill $Distill python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 7 --epochs_distill $Distill
# echo "python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 8 --epochs_distill $Distill" echo "python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 8 --epochs_distill $Distill"
# python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 8 --epochs_distill $Distill python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 8 --epochs_distill $Distill
# # TRAIN DISTILL SHADOW MODEL # TRAIN DISTILL SHADOW MODEL
# echo "python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 2 --epochs_distill $Distill" echo "python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 2 --epochs_distill $Distill"
# python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 2 --epochs_distill $Distill python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 2 --epochs_distill $Distill
# echo "python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 3 --epochs_distill $Distill" echo "python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 3 --epochs_distill $Distill"
# python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 3 --epochs_distill $Distill python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 3 --epochs_distill $Distill
# echo "python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 4 --epochs_distill $Distill" echo "python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 4 --epochs_distill $Distill"
# python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 4 --epochs_distill $Distill python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 4 --epochs_distill $Distill
# echo "python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 5 --epochs_distill $Distill" echo "python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 5 --epochs_distill $Distill"
# python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 5 --epochs_distill $Distill python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 5 --epochs_distill $Distill
# echo "python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 6 --epochs_distill $Distill" echo "python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 6 --epochs_distill $Distill"
# python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 6 --epochs_distill $Distill python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 6 --epochs_distill $Distill
# echo "python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 7 --epochs_distill $Distill" echo "python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 7 --epochs_distill $Distill"
# python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 7 --epochs_distill $Distill python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 7 --epochs_distill $Distill
# echo "python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 8 --epochs_distill $Distill" echo "python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 8 --epochs_distill $Distill"
# python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 8 --epochs_distill $Distill python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 8 --epochs_distill $Distill
# # CONSTRUCT TRAIN DATASET # CONSTRUCT TRAIN DATASET
# echo "python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 2 --epochs_distill $Distill" echo "python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 2 --epochs_distill $Distill"
# python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 2 --epochs_distill $Distill python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 2 --epochs_distill $Distill
# echo "python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 3 --epochs_distill $Distill" echo "python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 3 --epochs_distill $Distill"
# python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 3 --epochs_distill $Distill python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 3 --epochs_distill $Distill
# echo "python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 4 --epochs_distill $Distill" echo "python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 4 --epochs_distill $Distill"
# python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 4 --epochs_distill $Distill python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 4 --epochs_distill $Distill
# echo "python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 5 --epochs_distill $Distill" echo "python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 5 --epochs_distill $Distill"
# python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 5 --epochs_distill $Distill python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 5 --epochs_distill $Distill
# echo "python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 6 --epochs_distill $Distill" echo "python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 6 --epochs_distill $Distill"
# python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 6 --epochs_distill $Distill python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 6 --epochs_distill $Distill
# echo "python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 7 --epochs_distill $Distill" echo "python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 7 --epochs_distill $Distill"
# python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 7 --epochs_distill $Distill python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 7 --epochs_distill $Distill
# echo "python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 8 --epochs_distill $Distill" echo "python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 8 --epochs_distill $Distill"
# python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 8 --epochs_distill $Distill python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 8 --epochs_distill $Distill
# # CONSTRUCT TEST DATASET # CONSTRUCT TEST DATASET
# echo "python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 2 --epochs_distill $Distill" echo "python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 2 --epochs_distill $Distill"
# python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 2 --epochs_distill $Distill python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 2 --epochs_distill $Distill
# echo "python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 3 --epochs_distill $Distill" echo "python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 3 --epochs_distill $Distill"
# python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 3 --epochs_distill $Distill python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 3 --epochs_distill $Distill
# echo "python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 4 --epochs_distill $Distill" echo "python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 4 --epochs_distill $Distill"
# python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 4 --epochs_distill $Distill python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 4 --epochs_distill $Distill
# echo "python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 5 --epochs_distill $Distill" echo "python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 5 --epochs_distill $Distill"
# python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 5 --epochs_distill $Distill python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 5 --epochs_distill $Distill
# echo "python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 6 --epochs_distill $Distill" echo "python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 6 --epochs_distill $Distill"
# python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 6 --epochs_distill $Distill python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 6 --epochs_distill $Distill
# echo "python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 7 --epochs_distill $Distill" echo "python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 7 --epochs_distill $Distill"
# python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 7 --epochs_distill $Distill python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 7 --epochs_distill $Distill
# echo "python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 8 --epochs_distill $Distill" echo "python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 8 --epochs_distill $Distill"
# python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 8 --epochs_distill $Distill python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 8 --epochs_distill $Distill
# ATTACK # ATTACK
# # for test full precision mia result # for test full precision mia result
# echo "python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --load_attack --epochs_distill $Distill" echo "python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --load_attack --epochs_distill $Distill"
# python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --load_attack --epochs_distill $Distill python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --load_attack --epochs_distill $Distill
echo "python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 2 --epochs_distill $Distill"
python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 2 --epochs_distill $Distill
echo "python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --epochs_distill $Distill" echo "python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 3 --epochs_distill $Distill"
python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --epochs_distill $Distill python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 3 --epochs_distill $Distill
# echo "python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 2 --epochs_distill $Distill" echo "python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 4 --epochs_distill $Distill"
# python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 2 --epochs_distill $Distill python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 4 --epochs_distill $Distill
# echo "python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 3 --epochs_distill $Distill" echo "python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 5 --epochs_distill $Distill"
# python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 3 --epochs_distill $Distill python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 5 --epochs_distill $Distill
# echo "python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 4 --epochs_distill $Distill" echo "python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 6 --epochs_distill $Distill"
# python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 4 --epochs_distill $Distill python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 6 --epochs_distill $Distill
# echo "python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 5 --epochs_distill $Distill" echo "python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 7 --epochs_distill $Distill"
# python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 5 --epochs_distill $Distill python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 7 --epochs_distill $Distill
# echo "python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 6 --epochs_distill $Distill" echo "python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 8 --epochs_distill $Distill"
# python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 6 --epochs_distill $Distill python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 8 --epochs_distill $Distill
# echo "python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 7 --epochs_distill $Distill"
# python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 7 --epochs_distill $Distill
# echo "python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 8 --epochs_distill $Distill"
# python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 8 --epochs_distill $Distill
#- End #- End
echo "Job end at $(date "+%Y-%m-%d %H:%M:%S")" echo "Job end at $(date "+%Y-%m-%d %H:%M:%S")"
...@@ -184,9 +184,6 @@ python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Mod ...@@ -184,9 +184,6 @@ python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Mod
# ATTACK # ATTACK
# for test full precision mia result
# echo "python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --load_attack --epochs_distill $Distill"
# python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --load_attack --epochs_distill $Distill
echo "python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 9 --epochs_distill $Distill" echo "python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 9 --epochs_distill $Distill"
python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 9 --epochs_distill $Distill python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 9 --epochs_distill $Distill
......
...@@ -166,7 +166,7 @@ echo "python mia_one.py --action 1 --mia_type black-box --model $Model --model_ ...@@ -166,7 +166,7 @@ echo "python mia_one.py --action 1 --mia_type black-box --model $Model --model_
python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type POT --num_bits 5 --epochs_distill $Distill python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type POT --num_bits 5 --epochs_distill $Distill
echo "python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type POT --num_bits 6 --epochs_distill $Distill" echo "python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type POT --num_bits 6 --epochs_distill $Distill"
python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type POT --num_bits 6 --epochs_distill $Distill python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type POT --num_bits 6 --epochs_dist在·ill $Distill
#- End #- End
echo "Job end at $(date "+%Y-%m-%d %H:%M:%S")" echo "Job end at $(date "+%Y-%m-%d %H:%M:%S")"
#!/bin/bash
#- Job parameters
# (TODO)
# Please modify job name
#- Resources
# (TODO)
# Please modify your requirements
#SBATCH -p nv-gpu # Submit to 'nv-gpu' Partitiion
#SBATCH -t 0-01:00:00 # Run for a maximum time of 0 days, 12 hours, 00 mins, 00 secs
#SBATCH --nodes=1 # Request N nodes
#SBATCH --gres=gpu:1 # Request M GPU per node
#SBATCH --gres-flags=enforce-binding # CPU-GPU Affinity
#SBATCH --qos=gpu-trial # Request QOS Type
###
### The system will alloc 8 or 16 cores per gpu by default.
### If you need more or less, use following:
### #SBATCH --cpus-per-task=K # Request K cores
###
###
### Without specifying the constraint, any available nodes that meet the requirement will be allocated
### You can specify the characteristics of the compute nodes, and even the names of the compute nodes
###
### #SBATCH --nodelist=gpu-v00 # Request a specific list of hosts
### #SBATCH --constraint="Volta|RTX8000" # Request GPU Type: Volta(V100 or V100S) or RTX8000
###
# set constraint for RTX8000 to meet my cuda
#SBATCH --constraint="Ampere|RTX8000"
#- Log information
echo "Job start at $(date "+%Y-%m-%d %H:%M:%S")"
echo "Job run at:"
echo "$(hostnamectl)"
#- Load environments
source /tools/module_env.sh
source ~/pyt1.5/bin/activate
module list # list modules loaded
##- Tools
module load cluster-tools/v1.0
module load slurm-tools/v1.0
module load cmake/3.15.7
module load git/2.17.1
module load vim/8.1.2424
##- language
module load python3/3.6.8
##- CUDA
module load cuda-cudnn/10.2-7.6.5
##- virtualenv
# source xxxxx/activate
echo $(module list) # list modules loaded
echo $(which gcc)
echo $(which python)
echo $(which python3)
cluster-quota # nas quota
nvidia-smi --format=csv --query-gpu=name,driver_version,power.limit # gpu info
#- Warning! Please not change your CUDA_VISIBLE_DEVICES
#- in `.bashrc`, `env.sh`, or your job script
echo "Use GPU ${CUDA_VISIBLE_DEVICES}" # which gpus
#- The CUDA_VISIBLE_DEVICES variable is assigned and specified by SLURM
#- Job step
# [EDIT HERE(TODO)]
echo "python property_div.py --model $Model --data $Dataset"
python property_dis.py --model $Model --data $Dataset
#- End
echo "Job end at $(date "+%Y-%m-%d %H:%M:%S")"
...@@ -110,10 +110,14 @@ def quantize_inference(args, model, data, device='cpu'): ...@@ -110,10 +110,14 @@ def quantize_inference(args, model, data, device='cpu'):
# 对 是否distill,有不同的train方法
# 对是否distill,有不同的train方法
# 之前已经创建了model并把params config一起存储到了相应路径,此处先把model和params config load出来再trian # 之前已经创建了model并把params config一起存储到了相应路径,此处先把model和params config load出来再trian
# model_path_tar, model_path_dis = 'mia_ckpt/{}/{}'.format(args.seed, args.mode)
# untrained_model_tar, untrained_model_dis => model_name = '{}_mobilenetv2'.format(args.data)... ''' 参数赋值的示例:
model_path_tar, model_path_dis = 'mia_ckpt/{}/{}'.format(args.seed, args.mode)
untrained_model_tar, untrained_model_dis => model_name = '{}_mobilenetv2'.format(args.data)...
'''
def train(args, model_path_tar, untrained_model_tar, model_path_dis = None, untrained_model_dis = None, device='cpu'): def train(args, model_path_tar, untrained_model_tar, model_path_dis = None, untrained_model_dis = None, device='cpu'):
print('Training models...') print('Training models...')
...@@ -298,7 +302,6 @@ def train(args, model_path_tar, untrained_model_tar, model_path_dis = None, untr ...@@ -298,7 +302,6 @@ def train(args, model_path_tar, untrained_model_tar, model_path_dis = None, untr
print('Training took {} seconds...'.format(total_training_time)) print('Training took {} seconds...'.format(total_training_time))
# 存储训练后的模型权值参数和model_params (区分了用到的target model是否量化/什么量化) # 存储训练后的模型权值参数和model_params (区分了用到的target model是否量化/什么量化)
# model_path_dis = 'mia_ckpt/{}/{}'.format(args.seed, args.mode)
# 在networks/{}/{}'.format(args.seed, args.mode)/trained_model_name + title 下存储 # 在networks/{}/{}'.format(args.seed, args.mode)/trained_model_name + title 下存储
...@@ -307,9 +310,7 @@ def train(args, model_path_tar, untrained_model_tar, model_path_dis = None, untr ...@@ -307,9 +310,7 @@ def train(args, model_path_tar, untrained_model_tar, model_path_dis = None, untr
else: else:
if 'distill' in args.mode: if 'distill' in args.mode:
save_model(trained_model, model_params, model_path_dis, trained_model_name, epoch=args.epochs_distill) save_model(trained_model, model_params, model_path_dis, trained_model_name, epoch=args.epochs_distill)
# 只保存了最后一个epoch的target model和shadow model 是不是不太合理 准备改成存best的试试? (在mia_utils中的cnn_train)
# else:
# save_model(trained_model, model_params, model_path_tar, trained_model_name, epoch=num_epochs)
# 配置模型信息,创建并训练模型 # 配置模型信息,创建并训练模型
def train_models(args, model_path_tar, model_path_dis, device='cpu'): def train_models(args, model_path_tar, model_path_dis, device='cpu'):
...@@ -389,8 +390,6 @@ def create_model(models_path,args): ...@@ -389,8 +390,6 @@ def create_model(models_path,args):
# 实例化model,并调用save_model存储,只在create model的时候用到 # 实例化model,并调用save_model存储,只在create model的时候用到
def save_networks(args, model_name, model_params, model_path): def save_networks(args, model_name, model_params, model_path):
print('Saving model...') print('Saving model...')
# model_params['base_model'] = model_name
# network_type = model_params['network_type']
model = MIA_Model(args,model_params,args.model,args.data) # args.model用部分大写的,args.data用小写的 model = MIA_Model(args,model_params,args.model,args.data) # args.model用部分大写的,args.data用小写的
......
import openpyxl
from mia_utils import *
import module
import gol
import argparse
import numpy as np
import torch
import math
from sklearn.neighbors import KernelDensity
from scipy.stats import pearsonr
from scipy.spatial import distance
def js_divergence_rows(p, q):
jsd = np.zeros(p.shape[0])
for i in range(p.shape[0]):
jsd[i] = module.js_div(p[i], q[i])
return jsd
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='DIV_TrajectoryMIA')
parser.add_argument('--model', type=str, default='resnet18', help=['AlexNet','AlexNet_BN','VGG_16','VGG_19','Inception_BN','ResNet_18','ResNet_50','ResNet_152','MobileNetV2'])
parser.add_argument('--data', type=str, default='cifar10', help=['cinic10', 'cifar10', 'cifar100'])
args = parser.parse_args()
# 打开excel
filename =f'{args.model}_mia_result.xlsx'
workbook = openpyxl.load_workbook(filename)
worksheet = workbook[args.data]
# fp32 js
data_path = f'mia_ckpt/0/target/{args.data}_{args.model}/trajectory_test_data.npy'
dataSet = np.load(data_path, allow_pickle=True).item()
data = torch.from_numpy(np.array(dataSet['model_trajectory'], dtype='f'))
data_i = torch.from_numpy(np.array(dataSet['model_loss_ori'], dtype='f'))
# 根据 member_status 划分成两个 Tensor
# data_0 = data[dataSet['member_status'] == 0].transpose(0, 1)
# data_1 = data[dataSet['member_status'] == 1].transpose(0, 1)
data_0 = data[dataSet['member_status'] == 0]
data_1 = data[dataSet['member_status'] == 1]
data_i0 = data_i[dataSet['member_status'] == 0]
data_i1 = data_i[dataSet['member_status'] == 1]
# c0 = torch.cat((data_0, data_i0.unsqueeze(0)),0)
# c1 = torch.cat((data_1, data_i1.unsqueeze(0)),0)
c0 = torch.cat((data_0, data_i0.unsqueeze(1)),1)
c1 = torch.cat((data_1, data_i1.unsqueeze(1)),1)
# c0 = c0.t()
# c1 = c1.t()
js_distance = distance.jensenshannon(c0.numpy(),c1.numpy())
js_distance = js_distance.sum()
if math.isnan(js_distance):
js_distance = 0
# distance = module.js_div(data_0, data_1)
# distance = distance.item()
# if distance<0:P
# distance = 0
model_name = f'{args.data}_{args.model}'
print(f"js distance of {model_name}: {js_distance}")
worksheet.cell(row=2,column=1,value='js_distance')
worksheet.cell(row=2,column=2,value=js_distance)
# 统一计算所有的ptq后的js
gol._init()
quant_type_list = ['INT','POT','FLOAT']
for quant_type in quant_type_list:
num_bit_list = numbit_list(quant_type)
for num_bits in num_bit_list:
e_bit_list = ebit_list(quant_type,num_bits)
for e_bits in e_bit_list:
if quant_type == 'FLOAT':
title = '%s_%d_E%d' % (quant_type, num_bits, e_bits)
else:
title = '%s_%d' % (quant_type, num_bits)
model_name_ptq = f'{args.data}_{args.model}_{title}'
p_data_path = f'mia_ckpt/0/target/{model_name_ptq}/trajectory_test_data.npy'
p_dataSet = np.load(p_data_path, allow_pickle=True).item()
p_data = torch.from_numpy(np.array(p_dataSet['model_trajectory'], dtype='f'))
i_data = torch.from_numpy(np.array(p_dataSet['model_loss_ori'], dtype='f'))
# 根据 member_status 划分成两个 Tensor
# p_data_0 = p_data[p_dataSet['member_status'] == 0].transpose(0, 1)
# p_data_1 = p_data[p_dataSet['member_status'] == 1].transpose(0, 1)
# 10000 * 120
p_data_0 = p_data[p_dataSet['member_status'] == 0]
p_data_1 = p_data[p_dataSet['member_status'] == 1]
i_data_0 = i_data[p_dataSet['member_status'] == 0]
i_data_1 = i_data[p_dataSet['member_status'] == 1]
print(f"shape of p_data:{p_data_0.shape}")
# c0 = torch.cat((p_data_0, i_data_0.unsqueeze(0)),0)
# c1 = torch.cat((p_data_1, i_data_1.unsqueeze(0)),0)
c0 = torch.cat((p_data_0, i_data_0.unsqueeze(1)),1)
c1 = torch.cat((p_data_1, i_data_1.unsqueeze(1)),1)
print(f"shape of c_data:{c0.shape}")
# c0 = c0.t()
# c1 = c1.t()
js_distance = distance.jensenshannon(c0.numpy(),c1.numpy())
js_distance = js_distance.sum()
if math.isnan(js_distance):
js_distance = 0
print(f"distance_sum:{js_distance}")
idx = GlobalVariables.title_list.index(title)
idx += 4
worksheet.cell(row=idx,column=2,value=js_distance)
workbook.save(filename)
### Update 2023.7.8
# Model-Transfer-Adaptability
---
# 模型迁移安全性
#### MIA回顾
#### 模型迁移隐私安全性的两个思路
#### 具体工作
---
# MIA回顾
**定义:**
成员推理攻击(Membership Inference Attack)是一种揭示模型训练数据信息的攻击方法。这种攻击通过分析模型的输出来推断某个特定输入样本是否被用于训练模型。
**意义:**
1. 数据隐私保护:它揭示了机器学习模型可能存在的隐私泄露风险,可以帮助我们意识到在训练和使用机器学习模型时需要考虑和保护数据隐私。模型窃取、数据重建等隐私攻击建立在成员推理攻击基础上。
2. 安全性评估:成员推理攻击也可以用作评估机器学习模型安全性的一种手段。如果一个模型容易受到成员推理攻击,那么可能就存在过拟合或者其他安全性问题。
**论文:**
`Membership Inference Attacks Against Machine Learning Models` 经典的MIA
`Disparate Vulnerability to Membership Inference Attacks ` 思路2的理论依据
`Membership Inference Attacks by Exploiting Loss Trajectory ` Loss Trajectory MIA
---
# MIA的算法简介
### Naive MIA
**攻击假设:** 黑盒攻击,只知道目标模型的大致结构,能够使用目标模型的输出,但不知道目标模型的具体参数和训练过程。
**攻击模型:** 输入一个数据记录,输出该记录是否属于Target Model的训练数据
**影子模型的意义:** 使用影子模型去模仿目标模型,因为知道影子模型的训练数据和测试数据,可以用影子模型去训练攻击模型。
**训练/测试攻击模型:** 训练攻击模型的数据格式为:(Model Output(data), in/out). 测试攻击模型时则采用目标模型来替换影子模型。
**攻击度量:** 模型的预测acc和auc越高,则模型对MIA越脆弱。
### Loss Trajectory MIA
*思路类似,但比Naive MIA效果更好,过程更复杂。*
**训练/测试攻击模型:**(loss trajectory(data), in/out),loss trajectory是data在训练影子模型/目标模型时的按epoch汇总的损失轨迹
**获取损失轨迹:** 由于**黑盒攻击**,无法知道目标模型训练/测试数据的损失轨迹,因此通过**模型蒸馏**,得到蒸馏目标模型,由此**近似**获得目标模型的训练、测试数据的损失轨迹,为了对齐,对影子模型也采用相同策略,得到蒸馏影子模型。
<img src="public/p1.png" style="display: block; margin: 0 auto; width: 40%; height: 40%;">
---
# 两个思路
- **思路1:仿照模型迁移精度方面的做法,预测量化后的攻击ACC和AUC相对于全精度模型的变化。(../ALL中是对思路1的实现)**
**假设:** 认为攻击者**不知道**要攻击的模型是全精度的还是量化后的。
**做法:** 不改变原有的全精度的影子模型、蒸馏影子模型。且使用原有的攻击模型攻击量化后的目标模型。
**预测:** 以量化后模型与全精度模型的损失轨迹差异度为自变量,以攻击模型的ACC变化量或AUC变化量为因变量进行预测。
- **思路2:直接预测量化后模型和全精度模型的攻击成功率和AUC (./ALL_2中是对思路2的实现)**
**假设:** 认为攻击者**知道**要攻击的模型是全精度的或是量化的。
**做法:** 采用量化后的影子模型、蒸馏影子模型(需重新训练)。使用重新训练的攻击模型攻击量化后的目标模型。
**预测:**``Disparate Vulnerability to Membership Inference Attacks ``中的理论证明为依据:可知``Worst-case Vulnerability = Distributional Generalization``<br>
近似理解为攻击模型的**ACC或AUC**可以用模型的某个**指标对训练集数据和非训练集数据的差异来预测**。这个指标可以是loss,模型输出的向量,也可以是损失轨迹。最终选择了用JS距离来度量差异
### 总结:
- 两个思路的差异在于是否需要为量化后的目标模型进行**定制化的攻击**
- 思路二是定制化的攻击量化模型(重新训练量化后的影子模型、蒸馏影子模型、攻击模型)。
- 思路一中的攻击模型一定不是最适配于量化目标模型的,但思路二中的攻击模型是被重新训练的最适配于目标模型的。**我认为思路二的方式更具有实际意义。**
- 在拟合曲线阶段,我们需要重新训练量化后的影子模型、蒸馏影子模型、攻击模型。但在用户的预测阶段,只需要训练全精度和量化的目标模型、蒸馏目标模型,不再需要影子模型和攻击模型等。
---
# 具体工作
代码整合
思路1,2分别整合到了模型总代码框架中 (在ALL和ALL_2文件夹)
- 对Target Model和Shadow Model的训练进行了适配调整(optimizer,lr_scheduler...)。
- 训练脚本也整合到了scripts文件夹中。
超参数调整 - 对Loss Trajectory MIA的超参数和Attack Model的结构进行了探索实验
- 对攻击模型的acc影响较大的因素包括目标模型,影子模型,蒸馏目标模型,蒸馏影子模型的 训练周期数(distill epoch)、训练批次大小 、测试批次大小
**最终确定的较优超参数为:** *distill epoch = 120,training batch size = 512,test batch size = 256* 能够**平衡攻击模型的acc和显存占用**
| CIFAR10 | AlexNet | AlexNet_BN | VGG_16 | VGG_19 | MobileNetV2 | ResNet_18 | ResNet_50 |
| ------- | ------- | ---------- | ------ | ------ | ----------- | --------- | --------- |
| AUC | 0.6728 | 0.7027 | 0.6453 | 0.6473 | 0.6797 | 0.6581 | 0.6512 |
| ACC | 0.6111 | 0.6380 | 0.5985 | 0.5967 | 0.6355 | 0.6041 | 0.6130 |
在CIFAR100上的数据待后续补充
- 调整了攻击模型的训练周期数,对优化器和学习率调整器都做了一定修改,对结构也做了简单调整,但都效果不显著。后续考虑使用RNN网络,可能更有效的处理损失轨迹这种序列信息。
---
**思路1的结果回顾**
在ResNet18 + CIFAR10上进行了实验 <br>
横轴:量化后模型与全精度模型的损失轨迹差异度 <br>
纵轴:攻击模型的ACC或AUC (统一减去0.5后)
<div style="display: flex;">
<figure class="figure1">
<img src="public/i1_auc_loss_curve.png" alt="idea1_auc"/>
<figcaption style="font-size: 12px;">auc loss-js(R^2 = 0.9553)</figcaption>
</figure>
<figure class="figure2">
<img src="public/i1_acc_loss_curve.png" alt="idea1_acc"/>
<figcaption style="font-size: 12px;">acc loss-js(R^2 = 0.9523)</figcaption>
</figure>
</div>
---
思路2的尝试和效果展示
#### 如何计算损失轨迹差异度:
- 在度量损失轨迹差异度的方式上进行了很多实验,最终采用JS距离而非JS散度来度量损失轨迹,效果最好。
- 读入调整了损失轨迹张量,每行是一个输入图片的各个蒸馏周期的loss,计算出每行的JS距离后进行求和则可以得到数据集数据与非数据集数据之间的损失轨迹差异度。
- 还尝试了分组对loss求和后再算JS距离,但没有改进效果。
---
**思路2结果展示**
下面四张图中对AlexNetBN和ResNet18的曲线拟合还只是针对于单个模型,没有为泛化性做数据处理。后面分析并展示了如何通过数据处理来得到更具有泛化性的预测曲线(对单个模型的拟合效果和下面这4张图基本没有差异,但是对多个模型的数据的统一拟合效果会更好)。
横坐标是目标模型的数据集数据与非数据集数据之间的损失轨迹差异度
纵坐标是攻击模型的auc或acc
AlexNetBN
<div style="display: flex;">
<figure class="figure1">
<img src="public/d_alexbn_acc.png" alt="idea2_alexbn_acc"/>
<figcaption style="font-size: 12px;">acc-js(R^2 = 0.9427)</figcaption>
</figure>
<figure class="figure2">
<img src="public/d_alexbn_auc.png" alt="idea2_alexbn_auc"/>
<figcaption style="font-size: 12px;">auc-js(R^2 = 0.9547)</figcaption>
</figure>
</div>
#
ResNet18
<div style="display: flex;">
<figure class="figure1">
<img src="public/d_res18_acc.png" alt="idea2_res18_acc"/>
<figcaption style="font-size: 12px;">acc-js(R^2 = 0.8778)</figcaption>
</figure>
<figure class="figure2">
<img src="public/d_res18_auc.png" alt="idea2_res18_auc"/>
<figcaption style="font-size: 12px;">auc-js(R^2 = 0.9049)</figcaption>
</figure>
</div>
---
### 泛化性曲线拟合
### 分析
- 攻击模型的训练针对各个特定的目标模型,目标模型自身的架构特点将明显影响攻击模型的ACC和AUC。
- 直接将各个模型得到的数据点尝试在一张图上拟合不合理。需要考虑如何去掉目标模型自身的特性。
### 改进
- 对得到的所有攻击模型acc,auc分别减去0.5,得到${acc}_1$,${auc}_1$
- **量化模型**对应的攻击模型${{acc}_1}'$,${{auc}_1}'$值除以**全精度模型**对应的攻击模型${acc}_1$,${auc}_1$,得到$\hat{acc}$, $\hat{auc}$
- **量化模型**对应的损失轨迹距离除以**全精度模型**的损失轨迹距离得到相对损失轨迹距离$\hat{jsd}$
- 对$\hat{acc}$ - $\hat{jsd}$和$\hat{auc}$ - $\hat{jsd}$分别进行拟合
**ResNet18与AlexNetBN的整体拟合对比**
ACC:
<div style="display: flex;">
<figure class="figure1">
<img src="public/all_0_acc_p3.png" alt="idea2_resalexbn_pre"/>
<figcaption style="font-size: 12px;">改进前acc - jsd(R^2 = 0.7099)</figcaption>
</figure>
<figure class="figure2">
<img src="public/all_1_acc.png" alt="idea2_resalexbn_pro"/>
<figcaption style="font-size: 12px;">改进后acc - jsd (R^2 = 0.8173)</figcaption>
</figure>
</div>
#
ResNet18与AlexNetBN的整体拟合对比
AUC:
<div style="display: flex;">
<figure class="figure1">
<img src="public/all_0_auc_p3.png" alt="params_lstmocr"/>
<figcaption style="font-size: 12px;">改进前auc - jsd(R^2 = 0.7489)</figcaption>
</figure>
<figure class="figure2">
<img src="public/all_1_auc.png" alt="flops_lstmocr"/>
<figcaption style="font-size: 12px;">改进后auc - jsd (R^2 = 0.8475)</figcaption>
</figure>
</div>
---
# 总结
- 仅需要跑部分模型,避开ResNet50, ResNet152, InceptionBN这些较大的模型(开销过大)
- 正在补充各个模型在cifar10和cifar100上的结果
- 对于精度,有一条泛化的、通用于各种模型的拟合曲线使得我们仅仅需要对用户的新模型进行量化,根据参数相似度差异就能预测精度变化;对于隐私安全性(关于MIA),我们也可以在不实际攻击的情况下预测模型的隐私安全性,仅根据量化过程中得到的一些数据进行预测。
- 模型迁移隐私安全性适配性度量的流程:
1. 根据模型架构,配置cfg.py,补充该模型的cfg_table,使其能够被量化。
2. 按照该模型的结构,分别训练全精度的和量化后的目标模型、蒸馏目标模型,记录他们的损失轨迹。
3. 根据量化前后模型的损失轨迹的相对距离$\hat{jsd}$,即可预测MIA攻击的auc和acc的相对变化量$\hat{acc}$, $\hat{auc}$,即预测了模型在迁移后的隐私安全性变化。
# 运行说明
- 模型迁移安全性评估的运行脚本均在scripts文件夹中,每个sh脚本中均会调用相应的slurm脚本,而slurm中则有具体的运行命令和配置参数。sh脚本通过``sh scripts/xxx.sh``运行
**mia_one_fp32.sh: 对全精度模型的完整攻击流程,是首先需要被运行的脚本**
```sh
sbatch --job-name=$1 -o "ret_one/%x/%j.out" -e "ret_one/%x/%j.err" --export=Model=$1,Dataset=$2,Distill=$3 mia_one_fp32.slurm
```
mia_one_int_s1.sh,mia_one_int_s2.sh: 对INT量化模型的完整攻击流程
```sh
sbatch --job-name=$1 -o "ret_one/%x/%j.out" -e "ret_one/%x/%j.err" --export=Model=$1,Dataset=$2,Distill=$3 mia_one_int_s1.slurm
```
mia_one_pot.sh: 对POT量化模型的完整攻击流程
```sh
sbatch --job-name=$1 -o "ret_one/%x/%j.out" -e "ret_one/%x/%j.err" --export=Model=$1,Dataset=$2,Distill=$3 mia_one_pot.slurm
```
mia_one_fp_s1.sh, mia_one_fp_s2.sh, mia_one_fp_s3.sh, mia_one_fp_s4.sh: 对FLOAT量化模型的完整攻击流程
```sh
sbatch --job-name=$1 -o "ret_one/%x/%j.out" -e "ret_one/%x/%j.err" --export=Model=$1,Dataset=$2,Distill=$3 mia_one_fp_s1.slurm
```
mia_one_property_dis.sh: 评估训练集数据和非训练集数据的损失轨迹的js距离**(是最后才能被运行的sh脚本)**
```sh
sbatch --job-name=$1 -o "ret_one/%x/%j.out" -e "ret_one/%x/%j.err" --export=Model=$1,Dataset=$2 mia_one_property_dis.slurm
```
注:`$Model`可选用['AlexNet', 'AlexNet_BN', 'VGG_16', 'VGG_19', 'MobileNetV2', 'ResNet_18'], `$Dataset`可选用['cifar10', 'cifar100'], `$Distill$`建议使用120
- 每个slurm文件中均有一系列的运行命令,下面分别以mia_one_fp32.slurm, mia_one_int_s1.slurm, mia_one_property_dis.slurm为例说明
- mia_one_fp32.slurm
是对全精度模型的完整攻击流程
```sh
# 训练目标模型
python mia_one.py --mode target --model $Model --data $Dataset
# 训练影子模型
python mia_one.py --mode shadow --model $Model --data $Dataset
# 训练蒸馏目标模型
python mia_one.py --mode distill_target --model $Model --data $Dataset --epochs_distill $Distill
# 训练蒸馏影子模型
python mia_one.py --mode distill_shadow --model $Model --data $Dataset --epochs_distill $Distill
# 构造攻击模型训练数据集
python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --epochs_distill $Distill
# 构造攻击模型测试数据集
python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --epochs_distill $Distill
# 训练攻击模型
python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --epochs_distill $Distill
```
- mia_one_int_s1.slurm
分为五个部分,分别是训练蒸馏目标模型,蒸馏影子模型,构建攻击模型训练数据集,构建攻击模型测试数据集,训练攻击模型。每个部分中的指令都是相似的,只是具体量化参数上略有差异。
```sh
# TRAIN DISTILL TARGET MODEL
python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 2 --epochs_distill $Distill
python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 3 --epochs_distill $Distill
python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 4 --epochs_distill $Distill
python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 5 --epochs_distill $Distill
python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 6 --epochs_distill $Distill
python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 7 --epochs_distill $Distill
python mia_one.py --mode distill_target --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 8 --epochs_distill $Distill
# TRAIN DISTILL SHADOW MODEL
python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 2 --epochs_distill $Distill
python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 3 --epochs_distill $Distill
python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 4 --epochs_distill $Distill
python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 5 --epochs_distill $Distill
python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 6 --epochs_distill $Distill
python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 7 --epochs_distill $Distill
python mia_one.py --mode distill_shadow --model $Model --data $Dataset --store_ptq --quant_type INT --num_bits 8 --epochs_distill $Distill
# CONSTRUCT TRAIN DATASET
python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 2 --epochs_distill $Distill
python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 3 --epochs_distill $Distill
python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 4 --epochs_distill $Distill
python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 5 --epochs_distill $Distill
python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 6 --epochs_distill $Distill
python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 7 --epochs_distill $Distill
python mia_one.py --action 1 --mode shadow --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 8 --epochs_distill $Distill
# CONSTRUCT TEST DATASET
python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 2 --epochs_distill $Distill
python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 3 --epochs_distill $Distill
python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 4 --epochs_distill $Distill
python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 5 --epochs_distill $Distill
python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 6 --epochs_distill $Distill
python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 7 --epochs_distill $Distill
python mia_one.py --action 1 --mode target --mia_type build-dataset --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 8 --epochs_distill $Distill
# ATTACK
# for test full precision mia result
python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --load_attack --epochs_distill $Distill
python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 2 --epochs_distill $Distill
python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 3 --epochs_distill $Distill
python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 4 --epochs_distill $Distill
python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 5 --epochs_distill $Distill
python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 6 --epochs_distill $Distill
python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 7 --epochs_distill $Distill
python mia_one.py --action 1 --mia_type black-box --model $Model --model_distill $Model --data $Dataset --quant_type INT --num_bits 8 --epochs_distill $Distill
```
- mia_one_property_dis.slurm
```sh
python property_dis.py --model $Model --data $Dataset
```
最终结果将存储在modelname_mia_result.xlsx中,modelname与`$Model`对应,sheet与`$Dataset`对应,各量化模型的结果分别存储在各行中。
### Update 2023.6.28 ### Update 2023.6.28
ALL_2中是对思路2的实现,后续在代码稳定下来后将补充该readme ALL_2中是对思路2的实现,后续在代码稳定下来后将补充该readme
......
...@@ -3,4 +3,4 @@ if [ ! -d "ret_one" ]; then ...@@ -3,4 +3,4 @@ if [ ! -d "ret_one" ]; then
mkdir -p "ret_one" mkdir -p "ret_one"
fi fi
sbatch --job-name=$1 -o "ret_one/%x/%j.out" -e "ret_one/%x/%j.err" --export=Model=$1,Dataset=$2 mia_one_property_div.slurm sbatch --job-name=$1 -o "ret_one/%x/%j.out" -e "ret_one/%x/%j.err" --export=Model=$1,Dataset=$2 mia_one_property_dis.slurm
\ No newline at end of file \ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment