Exemple #1
0
    def process_step(self,
                     adj_transform="normalize_adj",
                     attr_transform=None,
                     graph_transform=None,
                     K=2):
        graph = gf.get(graph_transform)(self.graph)
        adj_matrix = gf.get(adj_transform)(graph.adj_matrix)
        node_attr = gf.get(attr_transform)(graph.node_attr)

        X, A = gf.astensors(node_attr, adj_matrix, device=self.device)

        X = SGConvolution(K=K)(X, A)
        # ``A`` and ``X`` are cached for later use
        self.register_cache(X=X, A=A)
Exemple #2
0
    def data_step(self,
                  adj_transform=("normalize_adj", ("adj_power", dict(power=2)),
                                 "to_dense"),
                  feat_transform=None):

        graph = self.graph
        adj_matrix = gf.get(adj_transform)(graph.adj_matrix)
        attr_matrix = gf.get(feat_transform)(graph.attr_matrix)

        feat, adj = gf.astensors(attr_matrix,
                                 adj_matrix,
                                 device=self.data_device)

        # ``adj`` and ``feat`` are cached for later use
        self.register_cache(feat=feat, adj=adj)
Exemple #3
0
    def process_step(self,
                     adj_transform="normalize_adj",
                     attr_transform=None,
                     graph_transform=None):

        graph = gf.get(graph_transform)(self.graph)
        adj_matrix = gf.get(adj_transform)(graph.adj_matrix)
        node_attr = gf.get(attr_transform)(graph.node_attr)

        X, A = gf.astensors(node_attr,
                            adj_matrix.tolil().rows,
                            device=self.device)

        # ``A`` and ``X`` are cached for later use
        self.register_cache(X=X, A=A)
Exemple #4
0
    def data_step(self,
                  adj_transform="normalize_adj",
                  feat_transform=None,
                  K=2):
        graph = self.graph
        adj_matrix = gf.get(adj_transform)(graph.adj_matrix)
        attr_matrix = gf.get(feat_transform)(graph.attr_matrix)

        feat, adj = gf.astensors(attr_matrix,
                                 adj_matrix,
                                 device=self.data_device)

        feat = SGConv(K=K)(feat, adj)
        # ``adj`` and ``feat`` are cached for later use
        self.register_cache(feat=feat, adj=adj)
Exemple #5
0
    def data_step(self,
                  adj_transform="neighbor_sampler",
                  attr_transform=None):

        graph = self.graph
        adj_matrix = gf.get(adj_transform)(graph.adj_matrix)
        node_attr = gf.get(attr_transform)(graph.node_attr)
        # pad with a dummy zero vector
        node_attr = np.vstack([node_attr, np.zeros(node_attr.shape[1],
                                                   dtype=self.floatx)])

        X, A = gf.astensors(node_attr, device=self.data_device), adj_matrix

        # ``A`` and ``X`` are cached for later use
        self.register_cache(X=X, A=A)
Exemple #6
0
    def data_step(self,
                  edge_transform=None,
                  attr_transform=None,
                  edge_attr_transform=None):

        graph = self.graph
        edge_index, edge_weight = gf.get(edge_transform)(graph.edge_index,
                                                         graph.edge_weight)
        node_attr = gf.get(attr_transform)(graph.node_attr)
        edge_attr = gf.get(edge_attr_transform)(graph.edge_attr)

        X, edge_index, edge_x = gf.astensors(node_attr,
                                             edge_index,
                                             edge_attr,
                                             device=self.data_device)
        self.register_cache(X=X, edge_index=edge_index, edge_x=edge_x)
    def process_step(self):
        graph = self.transform.graph_transform(self.graph)
        graph.node_attr = self.transform.attr_transform(graph.node_attr)

        batch_adj, batch_x, cluster_member = gf.graph_partition(
            graph, n_clusters=self.cache.n_clusters)

        batch_adj = self.transform.adj_transform(*batch_adj)
        batch_adj, batch_x = gf.astensors(batch_adj,
                                          batch_x,
                                          device=self.device)

        # ``A`` and ``X`` and ``cluster_member`` are cached for later use
        self.register_cache("batch_x", batch_x)
        self.register_cache("batch_adj", batch_adj)
        self.register_cache("cluster_member", cluster_member)
Exemple #8
0
    def process_step(self,
                     adj_transform="normalize_adj",
                     attr_transform=None,
                     graph_transform=None,
                     label_transform="onehot"):
        graph = gf.get(graph_transform)(self.graph)
        adj_matrix = gf.get(adj_transform)(graph.adj_matrix)
        node_attr = gf.get(attr_transform)(graph.node_attr)
        label = gf.get(label_transform)(graph.node_label)

        X, A = gf.astensors(node_attr, adj_matrix, device=self.device)

        # ``A`` and ``X`` are cached for later use
        self.register_cache(X=X,
                            A=A,
                            Y=label,
                            idx_all=tf.range(graph.num_nodes, dtype=self.intx))
Exemple #9
0
    def data_step(self,
                  adj_transform="normalize_adj",
                  attr_transform=None,
                  num_clusters=10):

        graph = self.graph
        batch_adj, batch_x, cluster_member = gf.graph_partition(
            graph, num_clusters=num_clusters, metis_partition=True)

        batch_adj = gf.get(adj_transform)(*batch_adj)
        batch_x = gf.get(attr_transform)(*batch_x)

        batch_adj, batch_x = gf.astensors(batch_adj, batch_x, device=self.data_device)

        # ``A`` and ``X`` and ``cluster_member`` are cached for later use
        self.register_cache(batch_x=batch_x, batch_adj=batch_adj,
                            cluster_member=cluster_member)
Exemple #10
0
    def process_step(self, re_decompose=False):
        graph = self.graph
        adj_matrix = self.adj_transform(graph.adj_matrix)
        node_attr = self.attr_transform(graph.node_attr)

        if re_decompose or not hasattr(self, "U"):
            V, U = sp.linalg.eigs(adj_matrix.astype('float64'), k=self.k)
            U, V = U.real, V.real
        else:
            U, V = self.U, self.V

        adj_matrix = (U * V) @ U.T
        adj_matrix = self.adj_transform(adj_matrix)

        with tf.device(self.device):
            self.feature_inputs, self.structure_inputs, self.U, self.V = gf.astensors(
                node_attr, adj_matrix, U, V, device=self.device)
Exemple #11
0
    def attack(self,
               target,
               num_budgets=None,
               direct_attack=True,
               structure_attack=True,
               feature_attack=False,
               disable=False):

        super().attack(target, num_budgets, direct_attack, structure_attack,
                       feature_attack)

        if not direct_attack:
            raise NotImplementedError(
                f'{self.name} does NOT support indirect attack.')

        target_index, target_label = gf.astensors([self.target],
                                                  self.target_label)
        adj_matrix = self.graph.adj_matrix

        for it in tqdm(range(self.num_budgets),
                       desc='Peturbing Graph',
                       disable=disable):
            with tf.device(self.device):
                gradients = self.compute_gradients(self.modified_adj,
                                                   self.adj_changes,
                                                   target_index, target_label)

                modified_row = tf.gather(self.modified_adj, target_index)
                gradients = (gradients *
                             (-2 * modified_row + 1)).numpy().ravel()

            sorted_index = np.argsort(-gradients)
            for index in sorted_index:
                u = target
                v = index % adj_matrix.shape[0]
                exist = adj_matrix[u, v]
                if exist and not self.allow_singleton and (
                        self.modified_degree[u] <= 1
                        or self.modified_degree[v] <= 1):
                    continue
                if not self.is_modified(u, v):
                    self.adj_flips[(u, v)] = it
                    self.flip_edge(u, v, exist)
                    break
        return self
Exemple #12
0
 def __init__(self,
              inputs,
              y=None,
              out_index=None,
              device='cpu',
              escape=None,
              **kwargs):
     dataset = gf.astensors(inputs,
                            y,
                            out_index,
                            device=device,
                            escape=escape)
     super().__init__([dataset],
                      batch_size=None,
                      collate_fn=lambda feat: feat,
                      device=device,
                      escape=escape,
                      **kwargs)
Exemple #13
0
    def data_step(self,
                  adj_transform="normalize_adj",
                  feat_transform=None,
                  num_neighbors=2):

        graph = self.graph
        adj_matrix = gf.get(adj_transform)(graph.adj_matrix)
        attr_matrix = gf.get(feat_transform)(graph.attr_matrix)

        feat, adj = gf.astensors(attr_matrix,
                                 adj_matrix,
                                 device=self.data_device)
        self.sampler = gf.ToNeighborMatrix(num_neighbors,
                                           self_loop=False,
                                           add_dummy=False)

        # ``adj`` and ``feat`` are cached for later use
        self.register_cache(feat=feat, adj=adj, adjacency=adj_matrix)
Exemple #14
0
    def data_step(self,
                  edge_transform=None,
                  feat_transform=None,
                  edge_feat_transform=None):

        graph = self.graph
        edge_index, edge_weight = gf.get(edge_transform)(graph.edge_index,
                                                         graph.edge_weight)
        attr_matrix = gf.get(feat_transform)(graph.attr_matrix)
        edge_attr = gf.get(edge_feat_transform)(graph.edge_attr)

        feat, edge_index, edge_feat = gf.astensors(attr_matrix,
                                                   edge_index,
                                                   edge_attr,
                                                   device=self.data_device)
        self.register_cache(feat=feat,
                            edge_index=edge_index,
                            edge_feat=edge_feat)
Exemple #15
0
 def __init__(self,
              inputs,
              y=None,
              out_index=None,
              block_size=2000,
              device='cpu',
              escape=None,
              **kwargs):
     dataset = gf.astensors(inputs,
                            y,
                            out_index,
                            device=device,
                            escape=escape)
     super().__init__([dataset],
                      batch_size=None,
                      collate_fn=self.collate_fn,
                      device=device,
                      escape=escape,
                      **kwargs)
     self.block_size = block_size
Exemple #16
0
    def data_step(self,
                  adj_transform="normalize_adj",
                  attr_transform=None,
                  k=35):

        graph = self.graph
        adj_matrix = gf.get(adj_transform)(graph.adj_matrix)
        node_attr = gf.get(attr_transform)(graph.node_attr)

        V, U = sp.linalg.eigsh(adj_matrix, k=k)

        adj_matrix = (U * V) @ U.T
        adj_matrix = gf.get(adj_transform)(adj_matrix)

        X, A, U, V = gf.astensors(node_attr,
                                  adj_matrix,
                                  U,
                                  V,
                                  device=self.data_device)
        # ``A`` , ``X`` , U`` and ``V`` are cached for later use
        self.register_cache(X=X, A=A, U=U, V=V)
Exemple #17
0
    def data_step(self,
                  adj_transform="normalize_adj",
                  feat_transform=None,
                  num_clusters=10,
                  partition='louvain'):

        assert partition in {'metis', 'random', 'louvain'}

        graph = self.graph
        batch_adj, batch_feat, cluster_member = gf.graph_partition(
            graph, num_clusters=num_clusters, partition=partition)

        batch_adj = gf.get(adj_transform)(*batch_adj)
        batch_feat = gf.get(feat_transform)(*batch_feat)

        batch_adj, batch_feat = gf.astensors(batch_adj, batch_feat, device=self.data_device)

        self.register_cache(batch_feat=batch_feat, batch_adj=batch_adj,
                            cluster_member=cluster_member)
        # for louvain clustering
        self.num_clusters = len(cluster_member)
Exemple #18
0
    def __init__(self,
                 inputs,
                 neighbors,
                 y=None,
                 out_index=None,
                 sizes=50,
                 device='cpu',
                 escape=None,
                 **kwargs):
        dataset = gf.astensors(inputs,
                               y,
                               out_index,
                               device=device,
                               escape=escape)
        super().__init__([dataset],
                         batch_size=None,
                         collate_fn=self.collate_fn,
                         **kwargs)

        self.neighbors = neighbors
        self.num_nodes = inputs[0].shape[0]
        self.sizes = sizes
Exemple #19
0
    def process_step(self):
        graph = self.graph
        adj_matrix = self.adj_transform(graph.adj_matrix)
        node_attr = self.attr_transform(graph.node_attr)

        feature_inputs, structure_inputs = gf.astensors(node_attr,
                                                        adj_matrix,
                                                        device=self.device)

        # To avoid this tensorflow error in large dataset:
        # InvalidArgumentError: Cannot use GPU when output.shape[1] * nnz(a) > 2^31 [Op:SparseTensorDenseMatMul]
        if self.graph.num_node_attrs * adj_matrix.nnz > 2**31:
            device = "CPU"
        else:
            device = self.device

        with tf.device(device):
            feature_inputs = SGConvolution(order=self.order)(
                [feature_inputs, structure_inputs])

        with tf.device(self.device):
            self.feature_inputs, self.structure_inputs = feature_inputs, structure_inputs
Exemple #20
0
    def process_step(self):

        graph = self.transform.graph_transform(self.graph)
        adj_matrix = self.transform.adj_transform(graph.adj_matrix)
        node_attr = self.transform.attr_transform(graph.node_attr)

        X, A = gf.astensors(node_attr, adj_matrix, device=self.device)

        # To avoid this tensorflow error in large dataset:
        # InvalidArgumentError: Cannot use GPU when output.shape[1] * nnz(a) > 2^31 [Op:SparseTensorDenseMatMul]
        if X.shape[1] * adj_matrix.nnz > 2**31:
            device = "CPU"
        else:
            device = self.device

        with tf.device(device):
            X = SGConvolution(order=self.cache.order)([X, A])

        with tf.device(self.device):
            # ``A`` and ``X`` are cached for later use
            self.register_cache("X", X)
            self.register_cache("A", A)
Exemple #21
0
    def data_step(self,
                  adj_transform="normalize_adj",
                  feat_transform=None,
                  k=35):

        graph = self.graph
        adj_matrix = gf.get(adj_transform)(graph.adj_matrix)
        attr_matrix = gf.get(feat_transform)(graph.attr_matrix)

        V, U = sp.linalg.eigsh(adj_matrix, k=k)

        adj_matrix = (U * V) @ U.T
        adj_matrix[adj_matrix < 0] = 0.
        adj_matrix = gf.get(adj_transform)(adj_matrix)

        feat, adj, U, V = gf.astensors(attr_matrix,
                                       adj_matrix,
                                       U,
                                       V,
                                       device=self.data_device)

        # ``adj`` , ``feat`` , U`` and ``V`` are cached for later use
        self.register_cache(feat=feat, adj=adj, U=U, V=V)
Exemple #22
0
    def data_step(self,
                  adj_transform="normalize_adj",
                  attr_transform=None,
                  K=2):

        graph = self.graph
        adj_matrix = gf.get(adj_transform)(graph.adj_matrix)
        node_attr = gf.get(attr_transform)(graph.node_attr)

        X, A = gf.astensors(node_attr, adj_matrix, device=self.data_device)

        # To avoid this tensorflow error in large dataset:
        # InvalidArgumentError: Cannot use GPU when output.shape[1] * nnz(a) > 2^31 [Op:SparseTensorDenseMatMul]
        if X.shape[1] * adj_matrix.nnz > 2**31:
            device = "CPU"
        else:
            device = self.device

        with tf.device(device):
            X = SGConv(K=K)([X, A])

        with tf.device(self.device):
            # ``A`` and ``X`` are cached for later use
            self.register_cache(X=X, A=A)
Exemple #23
0
    def train(self,
              idx_train,
              idx_val=None,
              pre_train_epochs=100,
              epochs=100,
              early_stopping=None,
              verbose=1,
              save_best=True,
              ckpt_path=None,
              as_model=False,
              monitor='val_accuracy',
              early_stop_metric='val_loss'):

        histories = []
        index_all = tf.range(self.graph.num_nodes, dtype=self.intx)

        # pre train model_q
        self.model = self.model_q
        history = super().train(idx_train,
                                idx_val,
                                epochs=pre_train_epochs,
                                early_stopping=early_stopping,
                                verbose=verbose,
                                save_best=save_best,
                                ckpt_path=ckpt_path,
                                as_model=True,
                                monitor=monitor,
                                early_stop_metric=early_stop_metric)
        histories.append(history)

        label_predict = self.predict(index_all).argmax(1)
        label_predict[idx_train] = self.graph.node_label[idx_train]
        label_predict = tf.one_hot(label_predict,
                                   depth=self.graph.num_node_classes)
        # train model_p fitst
        train_sequence = FullBatchNodeSequence(
            [label_predict, self.structure_inputs, index_all],
            label_predict,
            device=self.device)
        if idx_val is not None:
            val_sequence = FullBatchNodeSequence(
                [label_predict, self.structure_inputs, idx_val],
                self.label_onehot[idx_val],
                device=self.device)
        else:
            val_sequence = None

        self.model = self.model_p
        history = super().train(train_sequence,
                                val_sequence,
                                epochs=epochs,
                                early_stopping=early_stopping,
                                verbose=verbose,
                                save_best=save_best,
                                ckpt_path=ckpt_path,
                                as_model=as_model,
                                monitor=monitor,
                                early_stop_metric=early_stop_metric)
        histories.append(history)

        # then train model_q again
        label_predict = self.model.predict_on_batch(
            gf.astensors(label_predict,
                         self.structure_inputs,
                         index_all,
                         device=self.device))

        label_predict = softmax(label_predict)
        if tf.is_tensor(label_predict):
            label_predict = label_predict.numpy()

        label_predict[idx_train] = self.label_onehot[idx_train]

        self.model = self.model_q
        train_sequence = FullBatchNodeSequence(
            [self.feature_inputs, self.structure_inputs, index_all],
            label_predict,
            device=self.device)
        history = super().train(train_sequence,
                                idx_val,
                                epochs=epochs,
                                early_stopping=early_stopping,
                                verbose=verbose,
                                save_best=save_best,
                                ckpt_path=ckpt_path,
                                as_model=as_model,
                                monitor=monitor,
                                early_stop_metric=early_stop_metric)

        histories.append(history)

        return histories