Example #1
0
 def retrain_model(self, model, X, A, labels, train_idx):
     print('----------------- retraining -------------------')
     # model.reset_parameters()
     optim = t.optim.Adam(model.parameters(), lr=self.args.lr)
     X = t.from_numpy(X).float().to(self.args.device)
     A = sparse_mx_to_torch_sparse_tensor(A).to(self.args.device)
     labels = t.from_numpy(labels).long().to(self.args.device)
     for i in tqdm(range(self.args.retrain_epoch),
                   total=self.args.retrain_epoch,
                   desc='retraining'):
         logits = model(X, A)
         loss = F.cross_entropy(logits[train_idx], labels[train_idx])
         acc_train = count_acc(logits[train_idx], labels[train_idx])
         optim.zero_grad()
         loss.backward()
         optim.step()
         # print('Epoch: {:04d}'.format(i + 1),
         #       'loss_train: {:.4f}'.format(loss.item()),
         #       'acc_train: {:.4f}'.format(acc_train))
     print('----------------- retraining finished -------------------')
     with t.no_grad():
         logits = model(X, A)
         train_logits = logits[train_idx]
         train_labels = labels[train_idx]
         acc_train = count_acc(train_logits, train_labels)
         print('training acc: %.4f' % acc_train)
         train_labels_onehot = t.zeros_like(train_logits) \
             .to(self.args.device) \
             .scatter_(1, train_labels.view(-1, 1), 1)
         l_val = train_logits.gather(1, train_labels.view(-1, 1)).clone()
         c_val, c_new = t.max(train_logits - 1e6 * train_labels_onehot,
                              dim=1)
         dif = l_val.squeeze() - c_val
         return c_new, dif.cpu().detach().numpy()
Example #2
0
 def eval_model(self, model, X, A, labels, train_idx):
     X = t.from_numpy(X).float().to(self.args.device)
     A = sparse_mx_to_torch_sparse_tensor(A).to(self.args.device)
     labels = t.from_numpy(labels).long().to(self.args.device)
     with t.no_grad():
         logits = model(X, A)
         acc_train = count_acc(logits[train_idx], labels[train_idx])
         print('training acc: %.4f' % acc_train)
Example #3
0
 def eval_real(self, X, A, labels, train_idx):
     edge_index, edge_weight = convert_to_coo(A)
     features = t.from_numpy(X).cuda().float()
     edge_index = t.from_numpy(edge_index).cuda().long()
     edge_weight = t.from_numpy(edge_weight).cuda().float()
     labels = t.from_numpy(labels).cuda().long()
     with t.no_grad():
         logits = self.real_model(features, edge_index, edge_weight)
         acc_train = count_acc(logits[train_idx], labels[train_idx])
         print('real model acc: %.4f' % acc_train)
Example #4
0
    def attack(self, X, edge_index, edge_weight, labels, attack_idx):
        # self.eval_real(X, edge_index, edge_weight, labels, attack_idx)
        # edge_index, edge_weight = convert_to_coo(A)
        adv_per_iter = self.args.adv_per_iter
        print('grad attack with {} per iter and use normalize {}'.format(adv_per_iter, self.normalize))
        num_iter = self.args.num_adv // adv_per_iter
        attack_labels = labels
        attack_labels_onehot = t.zeros((len(attack_labels), 18)) \
            .to(self.args.device) \
            .scatter_(1, attack_labels.view(-1, 1), 1)
        targeted = t.randint_like(labels, high=17).to(self.args.device)
        targeted[targeted >= labels] += 1
        num_attack = len(attack_idx)
        for it in range(num_iter):
            print('iteration {}: adding {} new node'.format(it, adv_per_iter))
            cum_adv = (it + 1) * adv_per_iter
            adv_start = X.shape[0] + it * adv_per_iter
            # adv_weight = t.ones(new).to(self.args.device)
            # opt = optim.Adam((adv_features, adv_weight), lr=1000)
            nums = [ num_attack for i in range(adv_per_iter)]
            cum = [0]
            one = []
            other = []
            for i, n in enumerate(nums):
                cum.append(cum[i] + n)
                one.extend([adv_start + i] * n)
                other.extend(attack_idx)
                # other.extend(list(range(X.shape[0], adv_start + i)))
                # other.extend(list(range(num_attack)))
                assert len(one) == len(other)
            if 'adv_features' in vars():
                cum_feat_tensor = t.cat((adv_features.data, t.randn((adv_per_iter, 100))))
            else:
                if self.args.init_feature is not None:
                    print('loading init feature')
                    init_feature = np.load(self.args.init_feature)
                    cum_feat_tensor = t.from_numpy(init_feature).float()
                else:
                    cum_feat_tensor = t.randn((adv_per_iter, 100))
            adv_features = t.autograd.Variable(cum_feat_tensor).to(self.args.device).requires_grad_(
                False)
            new_edge = t.LongTensor([one, other]).to(self.args.device)
            new_edge2 = t.LongTensor([other, one]).to(self.args.device)
            adv_weight = t.autograd.Variable(t.zeros(cum[-1])).to(self.args.device).requires_grad_(True)
            opt = optim.Adam((adv_weight,), lr=1)
            e_i = t.cat([edge_index, new_edge, new_edge2], dim=1)
            # t.nn.init.normal_(self.adv_features)
            # adv_feat = t.zeros((self.args.num_adv, 100)).to(self.args.device1)
            # features = t.autograd.Variable(t.cat([self.features, adv_feat], dim=0)).to(self.args.device1).requires_grad_(
            #     True)
            # features = normalize(features)
            for ep in range(2):
                print('start adv train on edge %d' % ep)
                if self.normalize:
                    norm_feature = 3 * F.normalize(adv_features, p=float('inf'), dim=0)
                    f = t.cat([X, norm_feature], dim=0)
                else:
                    f = t.cat([X, adv_features], dim=0)
                e_w = t.cat([edge_weight, adv_weight, adv_weight], dim=0)
                logits = self.real_model(f, e_i, e_w)
                train_logits = logits[attack_idx]
                l_val = train_logits.gather(1, attack_labels.view(-1, 1)).squeeze()
                if self.args.targeted:
                    c_val = train_logits.gather(1, targeted.view(-1, 1)).squeeze()
                else:
                    c_val, c_new = t.max(train_logits - 1e6 * attack_labels_onehot, dim=1)
                dif = c_val - l_val
                # loss = - F.cross_entropy(train_logits, attack_labels)
                loss = t.sum(dif)
                opt.zero_grad()
                # t.cuda.empty_cache()
                loss.backward()
                # --------------------- reassign weight -------------------------
                for i in range(adv_per_iter):
                    s = cum[i]
                    e = cum[i + 1]
                    w_current = adv_weight.data[s: e]
                    rel_grad = (1 - 2 * w_current) * adv_weight.grad[s: e]

                    zeros_reward = rel_grad[w_current == 0]
                    zeros_idx = t.arange(e - s)[w_current == 0]
                    zeros_s_val, zeros_s_idx = t.sort(zeros_reward, descending=True)
                    if t.sum((w_current > 0).float()) <= 0:
                        budget = 100
                        for va, id in zip(zeros_s_val, zeros_s_idx):
                            if va < 0 or budget <= 0:
                                break
                            else:
                                w_current[zeros_idx[id]] = 1
                                budget -= 1
                    else:
                        ones_reward = rel_grad[w_current > 0]
                        ones_idx = t.arange(e - s)[w_current > 0]
                        ones_s_val, ones_s_idx = t.sort(ones_reward, descending=True)
                        j = 0
                        for j, (s_id, s_va) in enumerate(zip(ones_s_idx, ones_s_val)):
                            if s_va > 0:
                                w_current[ones_idx[s_id]] = 0
                            else:
                                break

                        budget = 100 - t.sum(w_current)
                        for s_id, s_va in zip(zeros_s_idx, zeros_s_val):
                            if s_va < 0:
                                break
                            if budget <= 0:
                                if j >= len(ones_s_idx):
                                    break
                                rew = s_va + ones_s_val[j]
                                if rew <= 0:
                                    break
                                else:
                                    w_current[zeros_idx[s_id]] = 1
                                    w_current[ones_idx[ones_s_idx[j]]] = 0
                                    j += 1
                            else:
                                w_current[zeros_idx[s_id]] = 1
                                budget -= 1
                    print('total connected edge %d for node %d' % (t.sum(adv_weight.data[s: e]).item(), i))
                    assert t.sum(adv_weight.data[s: e]) <= 100
                # --------------------- reassign weight end -------------------------
                # --------------------- adv train feature ---------------------------
                adv_gt0 = adv_weight.data > 0
                non_zeros = t.sum(adv_gt0.long())
                new_one = t.LongTensor(one)[adv_gt0].tolist()
                new_other = t.LongTensor(other)[adv_gt0].tolist()
                new_edge = t.LongTensor([new_one, new_other]).to(self.args.device)
                new_edge2 = t.LongTensor([new_other, new_one]).to(self.args.device)
                tmp_edge_index = t.cat([edge_index, new_edge, new_edge2], dim=1).to(self.args.device1)
                tmp_edge_weight = t.cat([edge_weight, t.ones(2 * non_zeros)], dim=0).to(self.args.device1)
                self.real_model = self.real_model.to(self.args.device1)
                adv_features = adv_features.to(self.args.device1).requires_grad_(True)
                train_labels_gpu = attack_labels.to(self.args.device1)
                train_labels_onehot_gpu = attack_labels_onehot.to(self.args.device1)
                targeted_gpu = targeted.to(self.args.device1)
                X_gpu = X.to(self.args.device1)
                opt = optim.Adam((adv_features,), lr=0.01)
                print('start adv train on feature %d' % ep)
                for k in range(self.args.adv_feature_epoch):
                    if self.normalize:
                        norm_feature = 3 * F.normalize(adv_features, p=float('inf'), dim=0)
                        f = t.cat([X_gpu, norm_feature], dim=0)
                    else:
                        f = t.cat([X_gpu, adv_features], dim=0)
                    # e_w = t.cat([edge_weight, adv_weight, adv_weight], dim=0)
                    logits = self.real_model(f, tmp_edge_index, tmp_edge_weight)
                    train_logits = logits[attack_idx]
                    adv_acc = count_acc(train_logits, train_labels_gpu)
                    l_val = train_logits.gather(1, train_labels_gpu.view(-1, 1)).squeeze()
                    if self.args.targeted:
                        c_val = train_logits.gather(1, targeted_gpu.view(-1, 1)).squeeze()
                    else:
                        c_val, c_new = t.max(train_logits - 1e6 * train_labels_onehot_gpu, dim=1)
                    dif = l_val - c_val
                    # loss = - F.cross_entropy(train_logits, attack_labels)
                    loss = t.sum(dif)
                    opt.zero_grad()
                    # t.cuda.empty_cache()
                    loss.backward()
                    opt.step()
                    print('Epoch: {:04d} {:04d}'.format(ep + 1, k + 1),
                          'loss: {:.4f}'.format(loss.item()),
                          'acc: {:.4f}'.format(adv_acc))
                self.real_model = self.real_model.to(self.args.device)
                adv_features = t.autograd.Variable(adv_features.data).to(self.args.device).requires_grad_(
                    False)
                # --------------------- adv train feature end ---------------------------

                # adv_features.data.add_(1., adv_features.grad)
                # print('Epoch: {:04d}'.format(ep + 1),
                #       'loss: {:.4f}'.format(loss.item()),
                #       'acc: {:.4f}'.format(adv_acc))
            adv_gt0 = adv_weight.data > 0
            non_zeros = t.sum(adv_gt0.long())
            new_one = t.LongTensor(one)[adv_gt0].tolist()
            new_other = t.LongTensor(other)[adv_gt0].tolist()
            new_edge = t.LongTensor([new_one, new_other]).to(self.args.device)
            new_edge2 = t.LongTensor([new_other, new_one]).to(self.args.device)
            edge_index = t.cat([edge_index, new_edge, new_edge2], dim=1)
            edge_weight = t.cat([edge_weight, t.ones(2 * non_zeros)], dim=0)
        rows = edge_index[0, :].numpy()
        cols = edge_index[1, :].numpy()
        data = np.ones(len(rows))
        features = adv_features.data.numpy()
        total = X.shape[0] + self.args.num_adv
        adj = coo_matrix((data, (rows, cols)), shape=(total, total))
        adj = adj.tocsr()[X.shape[0]:, :]
        np.save('result/%s/feature.npy' % self.dirname, features)
        with open('result/%s/adj.pkl' % self.dirname, 'wb') as f:
            pk.dump(adj, f)
Example #5
0
 def eval_real(self, features, edge_index, edge_weight, labels, train_idx):
     with t.no_grad():
         logits = self.real_model(features, edge_index, edge_weight)
         acc_train = count_acc(logits[train_idx], labels)
         print('real model acc: %.4f' % acc_train)