def train_victim_model(data, model_name='gcn', file_path=None, device='cpu'): """Train the victim model (target classifer) and save the model Note that the attacker can only do black query to this model. """ if file_path is None: file_path = 'results/saved_models/%s/' % data.name adj, features, labels = data.adj, data.features, data.labels idx_train, idx_val, idx_test = data.idx_train, data.idx_val, data.idx_test nfeat = features.shape[1] adj, features, labels = preprocess(adj, features, labels, preprocess_adj=False) # Setup victim model victim_model = GCN(nfeat=features.shape[1], nclass=labels.max().item()+1, nhid=16, dropout=0.5, weight_decay=5e-4, device=device) adj = adj.to(device) features = features.to(device) labels = labels.to(device) victim_model = victim_model.to(device) victim_model.fit(features, adj, labels, idx_train, idx_val) # save the model if not osp.exists(file_path): os.system('mkdir -p %s' % file_path) torch.save(victim_model.state_dict(), osp.join(file_path, model_name + '_checkpoint')) victim_model.eval() return victim_model
def multi_test(): # Setup Surrogate model surrogate = GCN(nfeat=features.shape[1], nclass=labels.max().item()+1, nhid=16, dropout=0, with_relu=False, with_bias=False, device=device) surrogate = surrogate.to(device) surrogate.fit(features, adj, labels, idx_train) attack_cnt = 0 defense_cnt = 0 degrees = adj.sum(0).A1 node_list = select_nodes() num = len(node_list) print('=== Attacking %s nodes one after another ===' % num) for target_node in node_list: #n_perturbations = min(15, int(degrees[target_node])) n_perturbations = int(degrees[target_node]) model = Nettack(surrogate, nnodes=adj.shape[0], attack_structure=True, attack_features=True, device=device) model = model.to(device) model.attack(features, adj, labels, target_node, n_perturbations, verbose=False) modified_adj = model.modified_adj modified_features = model.modified_features attack_acc = test_attack(modified_adj, modified_features, target_node) if attack_acc == 0: attack_cnt += 1 defense_acc = test_defense(modified_adj, modified_features, target_node) if defense_acc == 1: defense_cnt += 1 print("Attacking node :", target_node, "Details :", degrees[target_node], modified_adj.sum(0).A1[target_node], attack_acc, defense_acc) print('Pure attack accuracy rate : %s' % ((num - attack_cnt)/num), flush=True) print('With Jaccard defense accuracy rate : %s' % (defense_cnt/num), flush=True) print("GCNJaccard threshold used :", args.threshold)
def test(adj, features, target_node): ''' test on GCN ''' gcn = GCN(nfeat=features.shape[1], nhid=16, nclass=labels.max().item() + 1, dropout=0.5, device=device) if args.cuda: gcn = gcn.to(device) gcn.fit(features, adj, labels, idx_train) gcn.eval() output = gcn(gcn.features, gcn.adj_norm) probs = torch.exp(output[[target_node]])[0] print(f'probs: {probs.detach().cpu().numpy()}') loss_test = F.nll_loss(output[idx_test], labels[idx_test]) acc_test = accuracy(output[idx_test], labels[idx_test]) print("Test set results:", "loss= {:.4f}".format(loss_test.item()), "accuracy= {:.4f}".format(acc_test.item())) return acc_test.item()
def build_mettack(adj=None, features=None, labels=None, idx_train=None, device=None): lambda_ = 0 # Setup Surrogate Model surrogate = GCN(nfeat=features.shape[1], nclass=labels.max().item() + 1, nhid=16, dropout=0.5, with_relu=False, with_bias=True, weight_decay=5e-4, device=device) surrogate = surrogate.to(device) surrogate.fit(features, adj, labels, idx_train) model = Metattack(model=surrogate, nnodes=adj.shape[0], feature_shape=features.shape, attack_structure=True, attack_features=False, device=device, lambda_=lambda_) model = model.to(device) return model
def multi_test_evasion(): # test on 40 nodes on evasion attack target_gcn = GCN(nfeat=features.shape[1], nhid=16, nclass=labels.max().item() + 1, dropout=0.5, device=device) target_gcn = target_gcn.to(device) target_gcn.fit(features, adj, labels, idx_train, idx_val, patience=30) cnt = 0 degrees = adj.sum(0).A1 node_list = select_nodes(target_gcn) num = len(node_list) print('=== [Evasion] Attacking %s nodes respectively ===' % num) for target_node in tqdm(node_list): n_perturbations = int(degrees[target_node]) model = SGAttack(surrogate, attack_structure=True, attack_features=False, device=device) model = model.to(device) model.attack(features, adj, labels, target_node, n_perturbations, direct=True, verbose=False) modified_adj = model.modified_adj modified_features = model.modified_features acc = single_test(modified_adj, modified_features, target_node, gcn=target_gcn) if acc == 0: cnt += 1 print('misclassification rate : %s' % (cnt / num))
def test(features, adj, target_node): ''' test on GCN ''' gcn = GCN(nfeat=features.shape[1], nhid=16, nclass=labels.max().item() + 1, dropout=0.5) if args.cuda: gcn = gcn.to(device) gcn.fit(features, adj, labels, idx_train) gcn.eval() try: adj = normalize_adj_tensor(adj, sparse=True) except: adj = normalize_adj_tensor(adj) output = gcn(features, adj) probs = torch.exp(output[[target_node]])[0] print('probs: {}'.format(probs)) loss_test = F.nll_loss(output[idx_test], labels[idx_test]) acc_test = accuracy(output[idx_test], labels[idx_test]) print("Test set results:", "loss= {:.4f}".format(loss_test.item()), "accuracy= {:.4f}".format(acc_test.item())) return acc_test.item()
def test_given_adj(p_adj: sp.csr_matrix, p_feat: np.ndarray, p_label: np.ndarray, p_train_idx, p_val_idx, p_test_idx): """ Parameters: p_adj : csr_matrix """ use_gpu = t.cuda.is_available() adj = p_adj.A features = p_feat labels = p_label # surrogate model surrogate = GCN(nfeat=features.shape[1], nclass=labels.max().item() + 1, nhid=16, dropout=0, with_relu=True, with_bias=True, device='cuda:0').cuda() # train model surrogate.fit(features, adj, labels, p_train_idx, p_val_idx, patience=30) # test_model surrogate.test(p_test_idx) return surrogate
def select_nodes(target_gcn=None): ''' selecting nodes as reported in Nettack paper: (i) the 10 nodes with highest margin of classification, i.e. they are clearly correctly classified, (ii) the 10 nodes with lowest margin (but still correctly classified) and (iii) 20 more nodes randomly ''' if target_gcn is None: target_gcn = GCN(nfeat=features.shape[1], nhid=16, nclass=labels.max().item() + 1, dropout=0.5, device=device) target_gcn = target_gcn.to(device) target_gcn.fit(features, adj, labels, idx_train, idx_val, patience=30) target_gcn.eval() output = target_gcn.predict() margin_dict = {} for idx in idx_test: margin = classification_margin(output[idx], labels[idx]) if margin < 0: # only keep the nodes correctly classified continue margin_dict[idx] = margin sorted_margins = sorted(margin_dict.items(), key=lambda x: x[1], reverse=True) high = [x for x, y in sorted_margins[: 10]] low = [x for x, y in sorted_margins[-10:]] other = [x for x, y in sorted_margins[10: -10]] other = np.random.choice(other, 20, replace=False).tolist() return high + low + other
def test(data, adj): ''' test on GCN ''' _, features, labels = data.adj, data.features, data.labels idx_train, idx_val, idx_test = data.idx_train, data.idx_val, data.idx_test idx_unlabeled = np.union1d(idx_val, idx_test) adj, features, labels = preprocess(adj, features, labels, preprocess_adj=False) # adj = normalize_adj_tensor(adj) gcn = GCN(nfeat=features.shape[1], nhid=args.hidden, nclass=labels.max().item() + 1, dropout=args.dropout, device=device) gcn = gcn.to(device) gcn.fit(features, adj, labels, idx_train) # train without model picking # gcn.fit(features, adj, labels, idx_train, idx_val) # train with validation model picking output = gcn.output.cpu() loss_test = F.nll_loss(output[idx_test], labels[idx_test]) acc_test = accuracy(output[idx_test], labels[idx_test]) # print("Test set results:", # "loss= {:.4f}".format(loss_test.item()), # "accuracy= {:.4f}".format(acc_test.item())) return acc_test.item()
def test(adj, gcn=None): ''' test on GCN ''' if gcn is None: # adj = normalize_adj_tensor(adj) gcn = GCN(nfeat=features.shape[1], nhid=args.hidden, nclass=labels.max().item() + 1, dropout=args.dropout, device=device) gcn = gcn.to(device) gcn.fit(features, adj, labels, idx_train) # train without model picking gcn.fit(features, adj, labels, idx_train, idx_val, patience=30) # train with validation model picking gcn.eval() output = gcn.predict().cpu() else: gcn.eval() output = gcn.predict().cpu() loss_test = F.nll_loss(output[idx_test], labels[idx_test]) acc_test = accuracy(output[idx_test], labels[idx_test]) print("Test set results:", "loss= {:.4f}".format(loss_test.item()), "accuracy= {:.4f}".format(acc_test.item())) return acc_test.item()
def main(): target_gcn = GCN(nfeat=features.shape[1], nhid=16, nclass=labels.max().item() + 1, dropout=0.5, device=device) target_gcn = target_gcn.to(device) target_gcn.fit(features, adj, labels, idx_train, idx_val, patience=30) print('=== testing GCN on clean graph ===') test(adj, target_gcn) print('=== testing GCN on Evasion attack ===') model.attack(features, adj, labels, idx_train, perturbations, epochs=args.epochs) modified_adj = model.modified_adj test(modified_adj, target_gcn) # modified_features = model.modified_features print('=== testing GCN on Poisoning attack ===') test(modified_adj)
def build_mettack(adj=None, features=None, labels=None, idx_train=None, device=None): lambda_ = 0 # Setup Surrogate Model surrogate = GCN(nfeat=features.shape[1], nclass=labels.max().item() + 1, nhid=16, dropout=0.5, with_relu=False, with_bias=True, weight_decay=5e-4, device=device) surrogate = surrogate.to(device) surrogate.fit(features, adj, labels, idx_train) # print(torch.cuda.current_device()) print(f'{torch.cuda.device_count()} GPUs available') print('built surrogate') model = Metattack(model=surrogate, nnodes=adj.shape[0], feature_shape=features.shape, attack_structure=True, attack_features=False, device=device, lambda_=lambda_) print('built model') # if adj.shape[0] > 12000: # model = nn.DataParallel(model) model = model.to(device) print('to device') return model
def test_attack(adj, features, target_node): ''' test on GCN after NETTACK poisoning attack''' gcn = GCN(nfeat=features.shape[1], nhid=16, nclass=labels.max().item() + 1, dropout=0.5, device=device) gcn = gcn.to(device) gcn.fit(features, adj, labels, idx_train) gcn.eval() output = gcn.predict() probs = torch.exp(output[[target_node]]) acc_test = accuracy(output[[target_node]], [labels[target_node]]) return acc_test.item()
def main(): target_gcn = GCN(nfeat=features.shape[1], nhid=16, nclass=labels.max().item() + 1, dropout=0.5, device=device, lr=0.01) target_gcn = target_gcn.to(device) target_gcn.fit(features, adj, labels, idx_train, idx_val, patience=30) # target_gcn.fit(features, adj, labels, idx_train) print('=== testing GCN on clean graph ===') test(adj, target_gcn) # Setup Attack Model print('=== setup attack model ===') model = PGDAttack(model=target_gcn, nnodes=adj.shape[0], loss_type='CE', device=device) model = model.to(device) # model.attack(features, adj, labels, idx_train, perturbations, epochs=args.epochs) # Here for the labels we need to replace it with predicted ones fake_labels = target_gcn.predict(features.to(device), adj.to(device)) fake_labels = torch.argmax(fake_labels, 1).cpu() # Besides, we need to add the idx into the whole process idx_fake = np.concatenate([idx_train, idx_test]) idx_others = list(set(np.arange(len(labels))) - set(idx_train)) fake_labels = torch.cat([labels[idx_train], fake_labels[idx_others]]) model.attack(features, adj, fake_labels, idx_fake, perturbations, epochs=args.epochs) print('=== testing GCN on Evasion attack ===') modified_adj = model.modified_adj test(modified_adj, target_gcn) # modified_features = model.modified_features print('=== testing GCN on Poisoning attack ===') test(modified_adj)
def test(adj): ''' test on GCN ''' gcn = GCN(nfeat=features.shape[1], nhid=args.hidden, nclass=labels.max().item() + 1, dropout=args.dropout, device=device) gcn = gcn.to(device) gcn.fit(features, adj, labels, idx_train) # train without model picking output = gcn.output.cpu() loss_test = F.nll_loss(output[idx_test], labels[idx_test]) acc_test = accuracy(output[idx_test], labels[idx_test]) print("Test set results:", "loss= {:.4f}".format(loss_test.item()), "accuracy= {:.4f}".format(acc_test.item())) return acc_test.item()
def single_test(adj, features, target_node): ''' test on GCN (poisoning attack)''' gcn = GCN(nfeat=features.shape[1], nhid=16, nclass=labels.max().item() + 1, dropout=0.5, device=device) gcn = gcn.to(device) gcn.fit(features, adj, labels, idx_train) gcn.eval() output = gcn.predict() probs = torch.exp(output[[target_node]]) acc_test = accuracy(output[[target_node]], labels[target_node]) # print("Test set results:", "accuracy= {:.4f}".format(acc_test.item())) return acc_test.item()
def build_minmax(adj=None, features=None, labels=None, idx_train=None, device=None): # Setup Victim Model victim_model = GCN(nfeat=features.shape[1], nclass=labels.max().item() + 1, nhid=8, dropout=0.5, weight_decay=5e-4, device=device) victim_model = victim_model.to(device) victim_model.fit(features, adj, labels, idx_train) return MinMax(model=victim_model, nnodes=adj.shape[0], loss_type='CE', device=device)
def test_GCN(): ''' test on GCN ''' gcn = GCN(nfeat=features.shape[1], nhid=16, nclass=labels.max().item() + 1, dropout=0.5, device=device) gcn = gcn.to(device) gcn.fit(features, adj, labels, idx_train) gcn.eval() output = gcn.predict() acc_test = accuracy(output[idx_test], labels[idx_test]) print("GCN Test set results:", "accuracy= {:.4f}".format(acc_test.item())) return acc_test.item()
def test(adj, features, target_node): ''' test on GCN ''' gcn = GCN(nfeat=features.shape[1], nhid=16, nclass=labels.max().item() + 1, dropout=0.5, device=device) gcn = gcn.to(device) gcn.fit(features, adj, labels, idx_train, idx_val, patience=30) gcn.eval() output = gcn.predict() probs = torch.exp(output[[target_node]])[0] print('Target node probs: {}'.format(probs.detach().cpu().numpy())) acc_test = accuracy(output[idx_test], labels[idx_test]) print("Overall test set results:", "accuracy= {:.4f}".format(acc_test.item())) return acc_test.item()
def single_test(adj, features, target_node, gcn=None): if gcn is None: # test on GCN (poisoning attack) gcn = GCN(nfeat=features.shape[1], nhid=16, nclass=labels.max().item() + 1, dropout=0.5, device=device) gcn = gcn.to(device) gcn.fit(features, adj, labels, idx_train, idx_val, patience=30) gcn.eval() output = gcn.predict() else: # test on GCN (evasion attack) output = gcn.predict(features, adj) probs = torch.exp(output[[target_node]]) # acc_test = accuracy(output[[target_node]], labels[target_node]) acc_test = (output.argmax(1)[target_node] == labels[target_node]) return acc_test.item()
def test_gcn(adj, data, cuda, data_prep, nhid=16): ''' test on GCN ''' device = torch.device("cuda" if cuda else "cpu") features, labels, idx_train, idx_val, idx_test = data_prep(data, device) gcn = GCN(nfeat=features.shape[1], nhid=nhid, nclass=labels.max().item() + 1, dropout=0.5, device=device) gcn = gcn.to(device) optimizer = optim.Adam(gcn.parameters(), lr=0.01, weight_decay=5e-4) gcn.fit(features, adj, labels, idx_train) # train without model picking # gcn.fit(features, adj, labels, idx_train, idx_val) # train with validation model picking output = gcn.output loss_test = F.nll_loss(output[idx_test], labels[idx_test]) acc_test = accuracy(output[idx_test], labels[idx_test]) return acc_test.item()
def test(adj): ''' test on GCN ''' # adj = normalize_adj_tensor(adj) gcn = GCN(nfeat=features.shape[1], nhid=16, nclass=labels.max().item() + 1, dropout=0.5, device=device) gcn = gcn.to(device) optimizer = optim.Adam(gcn.parameters(), lr=0.01, weight_decay=5e-4) gcn.fit(features, adj, labels, idx_train) # train without model picking # gcn.fit(features, adj, labels, idx_train, idx_val) # train with validation model picking output = gcn.output loss_test = F.nll_loss(output[idx_test], labels[idx_test]) acc_test = accuracy(output[idx_test], labels[idx_test]) print("Test set results:", "loss= {:.4f}".format(loss_test.item()), "accuracy= {:.4f}".format(acc_test.item())) return acc_test.item()
percentile = (1 - perturbed_adj.sum() / adj.shape[0]**2 * sr) * 100 adj_rec = reconstructor.sparse(percentile) adj_rec_norm = utils.preprocess_graph(adj_rec) torch.manual_seed(args.seed) if args.cuda: torch.cuda.manual_seed(args.seed) vgae = GCN(nfeat=features.shape[1], nhid=16, nclass=labels.max() + 1, device=device) vgae = vgae.to(device) vgae.fit(features, adj_rec_norm, labels, idx_train, idx_val, train_iters=200, verbose=False, normalize=False) vgae.eval() output = vgae.test(idx_val) res.append(output.item()) print("retraining") bst = np.argmax(res) + 1 percentile = (1 - perturbed_adj.sum() / adj.shape[0]**2 * bst) * 100 adj_rec = reconstructor.sparse(percentile) adj_rec_norm = utils.preprocess_graph(adj_rec) torch.manual_seed(args.seed) if args.cuda:
direct=direct_attack, n_influencers=n_influencers) print(nettack.structure_perturbations) ########################### # no defense model = GCNTorch(nfeat=features.shape[1], nhid=16, nclass=labels.max() + 1, device=device) model = model.to(device) model.fit(features, nettack.adj_preprocessed, labels, idx_train, idx_val, train_iters=200, verbose=False, normalize=False) model.eval() acc = model.test(idx_test) probs_after_defense = model.predict().detach().cpu().numpy()[u] preds['no'] = np.argmax(probs_after_defense) ########################### # vae settings model = 'arga_vae' #'arga_ae' or 'arga_vae' iterations = 500 if dataname == "polblogs" else 200 train = True # train or load pretrain ###########################
np.random.seed(args.seed) torch.manual_seed(args.seed) if args.cuda: torch.cuda.manual_seed(args.seed) # Setup GCN Model model = GCN(nfeat=features.shape[1], nhid=16, nclass=labels.max() + 1, device=device) model = model.to(device) model.fit(features, perturbed_adj, labels, idx_train, train_iters=200, verbose=True) # # using validation to pick model # model.fit(features, perturbed_adj, labels, idx_train, idx_val, train_iters=200, verbose=True) model.eval() # You can use the inner function of model to test model.test(idx_test) print('==================') print( '=== load graph perturbed by DeepRobust 5% metattack (under seed 15) ===') perturbed_data = PtbDataset(root='/tmp/', name=args.dataset, attack_method='meta') perturbed_adj = perturbed_data.adj
adj, features, labels = data.adj, data.features, data.labels idx_train, idx_val, idx_test = data.idx_train, data.idx_val, data.idx_test idx_unlabeled = np.union1d(idx_val, idx_test) # Setup Surrogate model surrogate = GCN(nfeat=features.shape[1], nclass=labels.max().item() + 1, nhid=16, dropout=0, with_relu=False, with_bias=False, device=device) surrogate = surrogate.to(device) surrogate.fit(features, adj, labels, idx_train) # Setup Attack Model target_node = 0 assert target_node in idx_unlabeled model = IGAttack(surrogate, nnodes=adj.shape[0], attack_structure=True, attack_features=True, device=device) model = model.to(device) def main(): degrees = adj.sum(0).A1
idx_train, idx_val, idx_test = data.idx_train, data.idx_val, data.idx_test # Setup Target Model model = GCN(nfeat=features.shape[1], nclass=labels.max() + 1, nhid=16, dropout=0, with_relu=False, with_bias=True, device=device) model = model.to(device) # test on original adj print('=== test on original adj ===') model.fit(features, adj, labels, idx_train) output = model.output acc_test = accuracy(output[idx_test], labels[idx_test]) print("Test set results:", "accuracy= {:.4f}".format(acc_test.item())) print('=== Adversarial Training for Evasion Attack===') adversary = Random() adv_train_model = GCN(nfeat=features.shape[1], nclass=labels.max() + 1, nhid=16, dropout=0, with_relu=False, with_bias=True, device=device) adv_train_model = adv_train_model.to(device)
20, p_rand_seed=rand_seed) idx_unlabeled = np.union1d(idx_val, idx_test) # Setup Surrogate model surrogate = GCN(nfeat=features.shape[1], nclass=labels.max().item() + 1, nhid=16, dropout=0, with_relu=False, with_bias=False, device='cpu').cpu() surrogate.fit(features, adj, labels, idx_train, idx_val, patience=30, verbose=True) # Setup Attack Model model = Metattack(surrogate, nnodes=adj.shape[0], feature_shape=features.shape, attack_structure=True, attack_features=False, device='cpu', lambda_=0).cpu() # Attack n_perturbations = 1500 model.attack(features, adj,
model = GCN(nfeat=features.shape[1], nhid=args.hidden, nclass=labels.max().item() + 1, dropout=args.dropout, device=device) if args.only_gcn: perturbed_adj, features, labels = preprocess(perturbed_adj, features, labels, preprocess_adj=False, sparse=True, device=device) model.fit(features, perturbed_adj, labels, idx_train, idx_val, verbose=True, train_iters=args.epochs) model.test(idx_test) else: perturbed_adj, features, labels = preprocess(perturbed_adj, features, labels, preprocess_adj=False, device=device) prognn = ProGNN(model, args, device) prognn.fit(features, perturbed_adj, labels, idx_train, idx_val) prognn.test(features, labels, idx_test)
idx_unlabeled = np.union1d(idx_val, idx_test) perturbations = int(args.ptb_rate * (adj.sum() // 2)) adj, features, labels = preprocess(adj, features, labels, preprocess_adj=False) # Setup Victim Model victim_model = GCN(nfeat=features.shape[1], nclass=labels.max().item() + 1, nhid=16, dropout=0.5, weight_decay=5e-4, device=device) victim_model = victim_model.to(device) victim_model.fit(features, adj, labels, idx_train) # Setup Attack Model model = PGDAttack(model=victim_model, nnodes=adj.shape[0], loss_type='CE', device=device) model = model.to(device) def test(adj): ''' test on GCN ''' # adj = normalize_adj_tensor(adj)