示例#1
0
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()
示例#2
0
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
示例#3
0
def load_victim_model(data, model_name='gcn', device='cpu', file_path=None):

    assert model_name == 'gcn', 'Currently only support gcn as victim model...'
    if file_path is None:
        # file_path = f'results/saved_models/{data.name}/{model_name}_checkpoint'
        file_path = 'results/saved_models/{0}/{1}_checkpoint'.format(
            data.name, model_name)
    else:
        file_path = osp.join(file_path, '{}_checkpoint'.format(model_name))

    # Setup victim model
    if osp.exists(file_path):
        victim_model = GCN(nfeat=data.features.shape[1],
                           nclass=data.labels.max().item() + 1,
                           nhid=16,
                           dropout=0.5,
                           weight_decay=5e-4,
                           device=device)

        victim_model.load_state_dict(torch.load(file_path,
                                                map_location=device))
        victim_model.to(device)
        victim_model.eval()
        return victim_model

    victim_model = train_victim_model(data=data,
                                      model_name=model_name,
                                      device=device,
                                      file_path=osp.dirname(file_path))
    return victim_model
示例#4
0
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()
示例#5
0
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()
示例#6
0
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 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()
示例#8
0
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()
示例#9
0
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()
示例#10
0
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()
示例#11
0
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()
示例#12
0
def load_victim_model(data, model_name='gcn', device='cpu', file_path=None):
    """load_victim_model.

    Parameters
    ----------
    data : deeprobust.graph.Dataset
        graph data
    model_name : str
        victime model name, e.g. ('gcn', 'deepwalk') But currently it only
        supports gcn as victim model.
    device : str
        'cpu' or 'cuda'
    file_path :
        if given, the victim model will be loaded from this path.
    """

    assert model_name == 'gcn', 'Currently only support gcn as victim model...'
    if file_path is None:
        # file_path = f'results/saved_models/{data.name}/{model_name}_checkpoint'
        file_path = 'results/saved_models/{0}/{1}_checkpoint'.format(data.name, model_name)
    else:
        file_path = osp.join(file_path, '{}_checkpoint'.format(model_name))

    # Setup victim model
    if osp.exists(file_path):
        victim_model = GCN(nfeat=data.features.shape[1], nclass=data.labels.max().item()+1,
                    nhid=16, dropout=0.5, weight_decay=5e-4, device=device)

        victim_model.load_state_dict(torch.load(file_path, map_location=device))
        victim_model.to(device)
        victim_model.eval()
        return victim_model

    victim_model = train_victim_model(data=data, model_name=model_name,
                                        device=device, file_path=osp.dirname(file_path))
    return victim_model
示例#13
0
adv_train_model.initialize()
n_perturbations = int(0.01 * (adj.sum() // 2))
for i in tqdm(range(100)):
    # modified_adj = adversary.attack(features, adj)
    modified_adj = adversary.attack(adj,
                                    n_perturbations=n_perturbations,
                                    type='add')
    adv_train_model.fit(features,
                        modified_adj,
                        labels,
                        idx_train,
                        train_iters=50,
                        initialize=False)

adv_train_model.eval()
# test directly or fine tune
print('=== test on perturbed adj ===')
output = adv_train_model.predict()
acc_test = accuracy(output[idx_test], labels[idx_test])
print("Test set results:", "accuracy= {:.4f}".format(acc_test.item()))

# set up Surrogate & Nettack to attack the graph
import random

target_nodes = random.sample(idx_test.tolist(), 20)
# Setup Surrogate model
surrogate = GCN(nfeat=features.shape[1],
                nclass=labels.max().item() + 1,
                nhid=16,
                dropout=0,
示例#14
0
model.fit(features, perturbed_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()))

# For poisoning attack, the adjacency matrix you have
# is alreay perturbed
print('=== Adversarial Training for Poisoning Attack===')
model.initialize()
n_perturbations = int(0.01 * (adj.sum() // 2))
for i in range(100):
    # modified_adj = adversary.attack(features, adj)
    adversary.attack(perturbed_adj,
                     n_perturbations=n_perturbations,
                     type='remove')
    modified_adj = adversary.modified_adj
    model.fit(features,
              modified_adj,
              labels,
              idx_train,
              train_iters=50,
              initialize=False)

model.eval()

# test directly or fine tune
print('=== test on perturbed adj ===')
output = model.predict(features, perturbed_adj)
acc_test = accuracy(output[idx_test], labels[idx_test])
print("Test set results:", "accuracy= {:.4f}".format(acc_test.item()))
示例#15
0
    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:
    torch.cuda.manual_seed(args.seed)
vgae = GCN(nfeat=features.shape[1],
           nhid=16,
           nclass=labels.max() + 1,