Example #1
0
def positional_encoding(g, pos_enc_dim, DATASET_NAME=None):
    """
        Graph positional encoding v/ Laplacian eigenvectors
    """
    # Laplacian,for the pyg
    try:
        g.pos_enc = torch.load('data/ogbn/laplacian_' + DATASET_NAME[5:] +
                               '.pt',
                               map_location='cpu')
        if g.pos_enc.size(1) != pos_enc_dim:
            os.remove('data/ogbn/laplacian_' + DATASET_NAME[5:] + '.pt')
            L = get_laplacian(g.edge_index,
                              normalization='sym',
                              dtype=torch.float64)
            L = csr_matrix((L[1], (L[0][0], L[0][1])),
                           shape=(g.num_nodes, g.num_nodes))
            # Eigenvectors with scipy
            # EigVal, EigVec = sp.linalg.eigs(L, k=pos_enc_dim+1, which='SR')
            EigVal, EigVec = sp.linalg.eigs(L,
                                            k=pos_enc_dim + 1,
                                            which='SR',
                                            tol=1e-2)  # for 40 PEs
            EigVec = EigVec[:, EigVal.argsort()]  # increasing order
            g.pos_enc = torch.from_numpy(EigVec[:, 1:pos_enc_dim + 1].astype(
                np.float32)).float()
            torch.save(g.pos_enc.cpu(),
                       'data/ogbn/laplacian_' + DATASET_NAME[5:] + '.pt')
    except:
        L = get_laplacian(g.edge_index,
                          normalization='sym',
                          dtype=torch.float64)
        L = csr_matrix((L[1], (L[0][0], L[0][1])),
                       shape=(g.num_nodes, g.num_nodes))
        # Eigenvectors with scipy
        # EigVal, EigVec = sp.linalg.eigs(L, k=pos_enc_dim+1, which='SR')
        EigVal, EigVec = sp.linalg.eigs(L,
                                        k=pos_enc_dim + 1,
                                        which='SR',
                                        tol=1e-2)  # for 40 PEs
        EigVec = EigVec[:, EigVal.argsort()]  # increasing order
        g.pos_enc = torch.from_numpy(EigVec[:, 1:pos_enc_dim + 1].astype(
            np.float32)).float()
        torch.save(g.pos_enc.cpu(),
                   'data/ogbn/laplacian_' + DATASET_NAME[5:] + '.pt')
    # add astype to discards the imaginary part to satisfy the version change pytorch1.5.0

    # # Eigenvectors with numpy
    # EigVal, EigVec = np.linalg.eig(L.toarray())
    # idx = EigVal.argsort() # increasing order
    # EigVal, EigVec = EigVal[idx], np.real(EigVec[:,idx])
    # g.ndata['pos_enc'] = torch.from_numpy(np.abs(EigVec[:,1:pos_enc_dim+1])).float()
    return g
Example #2
0
def test_get_laplacian():
    edge_index = torch.tensor([[0, 1, 1, 2], [1, 0, 2, 1]], dtype=torch.long)
    edge_weight = torch.tensor([1, 2, 2, 4], dtype=torch.float)

    lap = get_laplacian(edge_index, edge_weight)
    assert lap[0].tolist() == [[0, 1, 1, 2, 0, 1, 2], [1, 0, 2, 1, 0, 1, 2]]
    assert lap[1].tolist() == [-1, -2, -2, -4, 1, 4, 4]

    lap_sym = get_laplacian(edge_index, edge_weight, normalization='sym')
    assert lap_sym[0].tolist() == lap[0].tolist()
    assert lap_sym[1].tolist() == [-0.5, -1, -0.5, -1, 1, 1, 1]

    lap_rw = get_laplacian(edge_index, edge_weight, normalization='rw')
    assert lap_rw[0].tolist() == lap[0].tolist()
    assert lap_rw[1].tolist() == [-1, -0.5, -0.5, -1, 1, 1, 1]
Example #3
0
    def forward(self, x, edge_index, batch):
        # computing the graph laplacian and adjacency matrix
        batch_nodes = batch.size(0)
        if edge_index.size(1) != 0:
            L_indices, L_values = get_laplacian(edge_index)
            L = torch.sparse.FloatTensor(
                L_indices, L_values, torch.Size([batch_nodes, batch_nodes]))
            A = torch.diag(torch.diag(L.to_dense())) - L.to_dense()

            # entropy computation
            entropies = self.compute_entropy(x, L, A, batch)  # Eq. (8)
        else:
            A = torch.zeros([batch_nodes, batch_nodes])
            norm = torch.norm(x, dim=1).unsqueeze(-1)
            entropies = norm / norm

        # graph convolution and probability scores
        probabilities = self.gc1(entropies, edge_index)
        probabilities = self.gc2(probabilities, edge_index)
        probabilities = self.gc3(probabilities, edge_index)
        probabilities = torch.sigmoid(probabilities)

        # conditional expectation; Algorithm 1
        gamma = entropies.sum()
        loss = self.loss_fn(entropies, probabilities, A, gamma)  # Eq. (9)

        mewis = self.conditional_expectation(entropies, probabilities, A, loss,
                                             gamma)

        # graph reconstruction; Eq. (10)
        x_pooled, adj_pooled = self.graph_reconstruction(mewis, x, A)
        edge_index_pooled, batch_pooled = self.to_edge_index(
            adj_pooled, mewis, batch)

        return x_pooled, edge_index_pooled, batch_pooled, loss, mewis
Example #4
0
    def __norm__(self,
                 edge_index,
                 num_nodes: Optional[int],
                 edge_weight: OptTensor,
                 normalization: Optional[str],
                 lambda_max,
                 dtype: Optional[int] = None,
                 batch: OptTensor = None):

        edge_index, edge_weight = remove_self_loops(edge_index, edge_weight)

        edge_index, edge_weight = get_laplacian(edge_index, edge_weight,
                                                normalization, dtype,
                                                num_nodes)

        if batch is not None and lambda_max.numel() > 1:
            lambda_max = lambda_max[batch[edge_index[0]]]

        edge_weight = (2.0 * edge_weight) / lambda_max
        edge_weight.masked_fill_(edge_weight == float('inf'), 0)

        edge_index, edge_weight = add_self_loops(edge_index,
                                                 edge_weight,
                                                 fill_value=-1.,
                                                 num_nodes=num_nodes)
        assert edge_weight is not None

        return edge_index, edge_weight
Example #5
0
    def __call__(self, data: Data) -> Data:
        from scipy.sparse.linalg import eigs, eigsh
        eig_fn = eigs if not self.is_undirected else eigsh

        num_nodes = data.num_nodes
        edge_index, edge_weight = get_laplacian(
            data.edge_index,
            normalization='sym',
            num_nodes=num_nodes,
        )

        L = to_scipy_sparse_matrix(edge_index, edge_weight, num_nodes)

        eig_vals, eig_vecs = eig_fn(
            L,
            k=self.k + 1,
            which='SR' if not self.is_undirected else 'SA',
            return_eigenvectors=True,
            **self.kwargs,
        )

        eig_vecs = np.real(eig_vecs[:, eig_vals.argsort()])
        pe = torch.from_numpy(eig_vecs[:, 1:self.k + 1])
        sign = -1 + 2 * torch.randint(0, 2, (self.k, ))
        pe *= sign

        data = add_node_attr(data, pe, attr_name=self.attr_name)
        return data
Example #6
0
    def norm(edge_index,
             num_nodes,
             edge_weight,
             normalization,
             lambda_max,
             dtype=None,
             batch=None):

        edge_index, edge_weight = remove_self_loops(edge_index, edge_weight)

        edge_index, edge_weight = get_laplacian(edge_index, edge_weight,
                                                normalization, dtype,
                                                num_nodes)

        if batch is not None and torch.is_tensor(lambda_max):
            lambda_max = lambda_max[batch[edge_index[0]]]

        edge_weight = (2.0 * edge_weight) / lambda_max
        edge_weight[edge_weight == float('inf')] = 0

        edge_index, edge_weight = add_self_loops(edge_index,
                                                 edge_weight,
                                                 fill_value=-1,
                                                 num_nodes=num_nodes)

        return edge_index, edge_weight
Example #7
0
def positional_encoding(g, pos_enc_dim, framework = 'dgl'):
    """
        Graph positional encoding v/ Laplacian eigenvectors
    """
    # Laplacian,for the pyg
    if framework == 'pyg':
        L = get_laplacian(g.edge_index,normalization='sym',dtype = torch.float64)
        L = csr_matrix((L[1], (L[0][0], L[0][1])), shape=(g.num_nodes, g.num_nodes))
        # Eigenvectors with scipy
        # EigVal, EigVec = sp.linalg.eigs(L, k=pos_enc_dim+1, which='SR')
        EigVal, EigVec = sp.linalg.eigs(L, k=pos_enc_dim + 1, which='SR', tol=1e-2)  # for 40 PEs
        EigVec = EigVec[:, EigVal.argsort()]  # increasing order
        g.pos_enc = torch.from_numpy(EigVec[:, 1:pos_enc_dim + 1].astype(np.float32)).float()
        # add astype to discards the imaginary part to satisfy the version change pytorch1.5.0
    elif framework == 'dgl':
        A = g.adjacency_matrix_scipy(return_edge_ids=False).astype(float)
        N = sp.diags(dgl.backend.asnumpy(g.in_degrees()).clip(1) ** -0.5, dtype=float)
        L = sp.eye(g.number_of_nodes()) - N * A * N
        # Eigenvectors with scipy
        # EigVal, EigVec = sp.linalg.eigs(L, k=pos_enc_dim+1, which='SR')
        EigVal, EigVec = sp.linalg.eigs(L, k=pos_enc_dim + 1, which='SR', tol=1e-2)  # for 40 PEs
        EigVec = EigVec[:, EigVal.argsort()]  # increasing order
        g.ndata['pos_enc'] = torch.from_numpy(EigVec[:, 1:pos_enc_dim + 1].astype(np.float32)).float()
        # add astype to discards the imaginary part to satisfy the version change pytorch1.5.0

    # # Eigenvectors with numpy
    # EigVal, EigVec = np.linalg.eig(L.toarray())
    # idx = EigVal.argsort() # increasing order
    # EigVal, EigVec = EigVal[idx], np.real(EigVec[:,idx])
    # g.ndata['pos_enc'] = torch.from_numpy(np.abs(EigVec[:,1:pos_enc_dim+1])).float()
    return g
Example #8
0
def get_laplacian_mat(edge_index,
                      edge_weight,
                      num_node,
                      normalization='sym'):  # todo: change back
    """ return a laplacian (torch.sparse.tensor)"""
    edge_index, edge_weight = get_laplacian(
        edge_index, edge_weight,
        normalization=normalization)  # see https://bit.ly/3c70FJK for format
    return torch.sparse.FloatTensor(edge_index, edge_weight,
                                    torch.Size([num_node, num_node]))
Example #9
0
    def process(self):

        """
        Prepares the data for PyTorch Geometric.
        """

        unprocessed = self.data_read(self.h, self.subs)
        num_samples, timestamps = unprocessed.shape[0], unprocessed.shape[-1]

        # Turn the data into PyTorch Geometric Graphs
        data_list = list()

        for sample in range(num_samples):
            x = unprocessed[sample, :, :, 0]
            y = unprocessed[sample, :, :, 1]
            y2 = unprocessed[sample, :, :, 2]

            edge_index, edge_attr, rows, cols = create_edge_index_attribute(x)
            y_edge_index, y_edge_attr, _, _ = create_edge_index_attribute(y)
            y2_edge_index, y2_edge_attr, _, _ = create_edge_index_attribute(y2)
            y_distr = normal.Normal(y.mean(dim=1), y.std(dim=1))
            y2_distr = normal.Normal(y2.mean(dim=1), y2.std(dim=1))
            y_lap_ei, y_lap_ea = get_laplacian(y_edge_index, y_edge_attr)
            y2_lap_ei, y2_lap_ea = get_laplacian(y2_edge_index, y2_edge_attr)
            y_lap = to_dense_adj(y_lap_ei, edge_attr=y_lap_ea)
            y2_lap = to_dense_adj(y2_lap_ei, edge_attr=y2_lap_ea)

            data = Data(x=x, edge_index=edge_index, edge_attr=edge_attr,
                        y=y, y_edge_index=y_edge_index, y_edge_attr=y_edge_attr, y_distr=y_distr,
                        y2=y2, y2_edge_index=y2_edge_index, y2_edge_attr=y2_edge_attr, y2_distr=y2_distr,
                        y_lap=y_lap, y2_lap=y2_lap)

            data.num_nodes = rows
            data_list.append(data)

        if self.pre_filter is not None:
            data_list = [data for data in data_list if self.pre_filter(data)]

        if self.pre_transform is not None:
            data_list = [self.pre_transform(data) for data in data_list]

        data, slices = self.collate(data_list)
        torch.save((data, slices), self.processed_paths[0])
Example #10
0
    def calculate_laplacian(edge_index, num_nodes, edge_weight, dtype=None):

        edge_index, edge_weight = remove_self_loops(edge_index, edge_weight)

        edge_index, edge_weight = get_laplacian(edge_index, edge_weight, 'sym',
                                                dtype, num_nodes)

        edge_weight[edge_weight == float('inf')] = 0

        edge_index, edge_weight = add_self_loops(edge_index,
                                                 edge_weight,
                                                 fill_value=-1,
                                                 num_nodes=num_nodes)

        return edge_index, edge_weight
Example #11
0
 def forward(self, x, k, edge_index=None, batch=None):
     r"""
     Calculate graph regularization term
     $R=||X^T L X||_F$
     """
     num_nodes = x.shape[-2]
     xdim = x.shape[-1]
     if edge_index is None:
         edge_index = knn_graph(x, k=k, batch=batch, loop=False)
     lap_index, lap_val = get_laplacian(edge_index,
                                        normalization="rw",
                                        num_nodes=num_nodes)
     res = self.propagate(edge_index=lap_index, x=x, edge_weight=lap_val)
     # print(res.shape)  # [B, F * F]
     # Frobenius Norm (intrinstically same)
     return (torch.norm(res, dim=-1, p="fro")**2).mean()
    def __call__(self, data):
        edge_weight = data.edge_attr
        if edge_weight is not None and edge_weight.numel() != data.num_edges:
            edge_weight = None

        edge_index, edge_weight = get_laplacian(data.edge_index, edge_weight,
                                                self.normalization,
                                                num_nodes=data.num_nodes)

        L = to_scipy_sparse_matrix(edge_index, edge_weight, data.num_nodes)

        eig_fn = eigsh if self.normalization == 'sym' else eigs
        lambda_max = eig_fn(L, k=1, which='LM', return_eigenvectors=False)
        data.lambda_max = float(lambda_max.real)

        return data
Example #13
0
 def get_prec(self, data):
     triangle_mask = data.edge_index[0] < data.edge_index[1]
     edge_index = torch.stack([
         data.edge_index[0][triangle_mask],
         data.edge_index[1][triangle_mask]
     ])
     x_query = F.embedding(edge_index[0], data.x)
     x_key = F.embedding(edge_index[1], data.x)
     x = torch.cat([x_query, x_key], dim=1)
     x = F.dropout(x, p=self.dropout, training=self.training)
     x = self.activation(self.reg_fc1(x))
     x = F.dropout(x, p=self.dropout, training=self.training)
     x = F.softplus(self.reg_fc2(x))
     und_edge_index = torch.stack([
         torch.cat([edge_index[0], edge_index[1]], dim=0),
         torch.cat([edge_index[1], edge_index[0]], dim=0)
     ])
     und_edge_weight = torch.cat([x.view(-1), x.view(-1)], dim=0)
     L_edge_index, L_edge_weight = get_laplacian(
         und_edge_index,
         edge_weight=und_edge_weight,
         num_nodes=data.x.size(0))
     L = to_dense_adj(L_edge_index, edge_attr=L_edge_weight)[0]
     return L + torch.eye(L.size(0), dtype=L.dtype, device=L.device)
Example #14
0
def MyDataset(dataset, Lev, s, n, FrameType='Haar', add_feature=False, QM7=False):
    if FrameType == 'Haar':
        D1 = lambda x: np.cos(x / 2)
        D2 = lambda x: np.sin(x / 2)
        DFilters = [D1, D2]
    elif FrameType == 'Linear':
        D1 = lambda x: np.square(np.cos(x / 2))
        D2 = lambda x: np.sin(x) / np.sqrt(2)
        D3 = lambda x: np.square(np.sin(x / 2))
        DFilters = [D1, D2, D3]
    elif FrameType == 'Quadratic':  # not accurate so far
        D1 = lambda x: np.cos(x / 2) ** 3
        D2 = lambda x: np.multiply((np.sqrt(3) * np.sin(x / 2)), np.cos(x / 2) ** 2)
        D3 = lambda x: np.multiply((np.sqrt(3) * np.sin(x / 2) ** 2), np.cos(x / 2))
        D4 = lambda x: np.sin(x / 2) ** 3
        DFilters = [D1, D2, D3, D4]
    else:
        raise Exception('Invalid FrameType')
    r = len(DFilters)

    dataset1 = list()
    label=list()
    for i in range(len(dataset)):
        if add_feature:
            raise Exception('this function has not been completed')  # will add this function as required
        else:
            if QM7:
                x_qm7 = torch.ones(dataset[i].num_nodes, num_features)
                data1 = Data(x=x_qm7, edge_index=dataset[i].edge_index, y=dataset[i].y)
                data1.y_origin = dataset[i].y_origin
            else:
                data1 = Data(x=dataset[i].x, edge_index=dataset[i].edge_index, y=dataset[i].y)
                
        if QM7:
            label.append(dataset[i].y_origin)
        # get graph Laplacian
        num_nodes = data1.x.shape[0]
        L = get_laplacian(dataset[i].edge_index, num_nodes=num_nodes, normalization='sym')
        L = sparse.coo_matrix((L[1].numpy(), (L[0][0, :].numpy(), L[0][1, :].numpy())), shape=(num_nodes, num_nodes))
        # calculate lambda max
        lobpcg_init = np.random.rand(num_nodes, 1)
        lambda_max, _ = lobpcg(L, lobpcg_init)
        lambda_max = lambda_max[0]
        J = np.log(lambda_max / np.pi) / np.log(s) + Lev - 1  # dilation level to start the decomposition
        # get matrix operators
        d = get_operator(L, DFilters, n, s, J, Lev)
        for m in range(1, r):
            for q in range(Lev):
                if (m == 1) and (q == 0):
                    d_aggre = d[m, q]
                else:
                    d_aggre = sparse.vstack((d_aggre, d[m, q]))
        d_aggre = sparse.vstack((d[0, Lev - 1], d_aggre)) ###stack the n x n matrix
        data1.d = [d_aggre]
        # get d_index
        a = [i for i in range((r - 1) * Lev + 1)]##len=3
        data1.d_index=[[a[i // num_nodes] for i in range(len(a) * num_nodes)]]##3*num [0,1,2;,0,1,2...]
        # append data1 into dataset1
        dataset1.append(data1)    
    if QM7:
        mean = torch.mean(torch.Tensor(label)).item()
        std = torch.sqrt(torch.var(torch.Tensor(label))).item()
        return dataset1, r, mean, std    
    else:
        return dataset1, r
Example #15
0
def main():
    parser = ArgumentParser(description="GraphZoom")
    parser.add_argument("-d", "--dataset", type=str, default="arxiv", \
            help="input dataset")
    parser.add_argument("-o", "--coarse", type=str, default="lamg", \
            help="choose either simple_coarse or lamg_coarse, [simple, lamg]")
    parser.add_argument("-c", "--mcr_dir", type=str, default="/opt/matlab/R2018A/", \
            help="directory of matlab compiler runtime (only required by lamg_coarsen)")
    parser.add_argument("-s", "--search_ratio", type=int, default=12, \
            help="control the search space in graph fusion process (only required by lamg_coarsen)")
    parser.add_argument("-r", "--reduce_ratio", type=int, default=2, \
            help="control graph coarsening levels (only required by lamg_coarsen)")
    parser.add_argument("-v", "--level", type=int, default=1, \
            help="number of coarsening levels (only required by simple_coarsen)")
    parser.add_argument("-n", "--num_neighs", type=int, default=2, \
            help="control k-nearest neighbors in graph fusion process")
    parser.add_argument("-l", "--lda", type=float, default=0.1, \
            help="control self loop in adjacency matrix")
    parser.add_argument("-e", "--embed_path", type=str, default="./embed_results/", \
            help="path of embedding result")
    parser.add_argument("-m", "--embed_method", type=str, default="node2vec", \
            help="graph embedding method")
    parser.add_argument("-f", "--fusion", default=True, action="store_false", \
            help="whether use graph fusion")
    parser.add_argument("-p", "--power", default=False, action="store_true", \
            help="Strong power of graph filter, set True to enhance filter power")
    parser.add_argument("-g", "--sage_model", type=str, default="mean", \
            help="aggregation function in graphsage")
    parser.add_argument("-w", "--sage_weighted", default=True, action="store_false", \
            help="whether consider weighted reduced graph")

    args = parser.parse_args()

    dataset = args.dataset
    feature_path = "dataset/{}/{}-feats.npy".format(dataset, dataset)
    fusion_input_path = "dataset/{}/{}.mtx".format(dataset, dataset)
    reduce_results = "./reduction_results/"
    mapping_path = "{}Mapping.mtx".format(reduce_results)

    d = PygNodePropPredDataset(name=f"ogbn-{dataset}")

    os.makedirs(reduce_results, exist_ok=True)
    os.makedirs(f"dataset/{dataset}", exist_ok=True)

    if args.fusion:
        coarsen_input_path = "dataset/{}/fused_{}.mtx".format(dataset, dataset)
    else:
        coarsen_input_path = "dataset/{}/{}.mtx".format(dataset, dataset)

######Load Data######
    print("%%%%%% Loading Graph Data %%%%%%")
    lp_index, lp_weight = get_laplacian(to_undirected(d[0].edge_index, d[0].num_nodes))
    laplacian = to_scipy_sparse_matrix(lp_index, lp_weight)
    if args.coarse == "lamg":
        if os.path.exists(fusion_input_path):
            print("Laplacian matrix in mtx already exists.")
        else:
            print("Saving laplacian matrix in mtx...")
            file = open(fusion_input_path, "wb")
            mmwrite(fusion_input_path, laplacian)
            file.close()

    ## whether node features are required
    if args.fusion:
        feature = d[0].x.numpy()

######Graph Fusion######
    if args.fusion:
        print("%%%%%% Starting Graph Fusion %%%%%%")
        fusion_start = time.process_time()
        laplacian    = graph_fusion(laplacian, feature, args.num_neighs, args.mcr_dir, args.coarse,\
                       fusion_input_path, args.search_ratio, reduce_results, mapping_path, dataset)
        fusion_time  = time.process_time() - fusion_start

######Graph Reduction######
    print("%%%%%% Starting Graph Reduction %%%%%%")
    reduce_start = time.process_time()

    if args.coarse == "simple":
        G, projections, laplacians, level = sim_coarse(laplacian, args.level)
        reduce_time = time.process_time() - reduce_start

    elif args.coarse == "lamg":
        os.system('./run_coarsening.sh {} {} {} n {}'.format(args.mcr_dir, \
                coarsen_input_path, args.reduce_ratio, reduce_results))
        reduce_time = read_time("{}CPUtime.txt".format(reduce_results))
        G = mtx2graph("{}Gs.mtx".format(reduce_results))
        level = read_levels("{}NumLevels.txt".format(reduce_results))
        projections, laplacians = construct_proj_laplacian(laplacian, level, reduce_results)

    else:
        raise NotImplementedError

    edge_index = torch.tensor(list(G.edges)).t().contiguous().view(2, -1)
    edge_index = to_undirected(edge_index, len(G.nodes()))


######Embed Reduced Graph######
    print("%%%%%% Starting Graph Embedding %%%%%%")
    if args.embed_method == "node2vec":
        embed_start = time.process_time()
        embeddings  = node2vec(edge_index)
    else:
        raise NotImplementedError

    embed_time = time.process_time() - embed_start


######Refinement######
    print("%%%%%% Starting Graph Refinement %%%%%%")
    refine_start = time.process_time()
    embeddings   = refinement(level, projections, laplacians, embeddings, args.lda, args.power)
    refine_time  = time.process_time() - refine_start


######Save Embeddings######
    os.makedirs(args.embed_path, exist_ok=True)
    np.save(args.embed_path + "embeddings.npy", embeddings)

######Report timing information######
    print("%%%%%% CPU time %%%%%%")
    if args.fusion:
        total_time = fusion_time + reduce_time + embed_time + refine_time
        print(f"Graph Fusion     Time: {fusion_time:.3f}")
    else:
        total_time = reduce_time + embed_time + refine_time
        print("Graph Fusion     Time: 0")
    print(f"Graph Reduction  Time: {reduce_time:.3f}")
    print(f"Graph Embedding  Time: {embed_time:.3f}")
    print(f"Graph Refinement Time: {refine_time:.3f}")
    print(f"Total Time = Fusion_time + Reduction_time + Embedding_time + Refinement_time = {total_time:.3f}")
Example #16
0
def mgpool(x, pos, edge_index, batch, mask=None):
    adj_values = torch.ones(edge_index.shape[1]).cuda()
    cluster = graclus(edge_index)
    cluster, perm = consecutive_cluster(cluster)

    index = torch.stack([cluster, torch.arange(0, x.shape[0]).cuda()], dim=0)
    values = torch.ones(cluster.shape[0], dtype=torch.float).cuda()
    uniq, inv, counts = torch.unique(cluster,
                                     return_inverse=True,
                                     return_counts=True)
    newsize = uniq.shape[0]

    origsize = x.shape[0]

    new_batch = pool_batch(perm, batch)
    # Compute random walk graph laplacian:
    laplacian_index, laplacian_weights = get_laplacian(edge_index,
                                                       normalization='rw')
    laplacian_index, laplacian_weights = torch_sparse.coalesce(
        laplacian_index, laplacian_weights, m=origsize, n=origsize)
    index, values = torch_sparse.coalesce(index, values, m=newsize,
                                          n=origsize)  # P^T matrix
    new_feat = torch_sparse.spmm(index,
                                 values,
                                 m=newsize,
                                 n=origsize,
                                 matrix=x)  # P^T X
    new_pos = torch_sparse.spmm(index,
                                values,
                                m=newsize,
                                n=origsize,
                                matrix=pos)  # P^T POS

    new_adj, new_adj_val = torch_sparse.spspmm(index,
                                               values,
                                               edge_index,
                                               adj_values,
                                               m=newsize,
                                               k=origsize,
                                               n=origsize,
                                               coalesced=True)  # P^T A
    index, values = torch_sparse.transpose(index,
                                           values,
                                           m=newsize,
                                           n=origsize,
                                           coalesced=True)  # P
    new_adj, new_adj_val = torch_sparse.spspmm(new_adj,
                                               new_adj_val,
                                               index,
                                               values,
                                               m=newsize,
                                               k=origsize,
                                               n=newsize,
                                               coalesced=True)  # (P^T A) P
    # Precompute QP :
    values = torch.ones(cluster.shape[0], dtype=torch.float).cuda()
    index, values = torch_sparse.spspmm(laplacian_index,
                                        laplacian_weights,
                                        index,
                                        values,
                                        m=origsize,
                                        k=origsize,
                                        n=newsize,
                                        coalesced=True)
    return new_adj, new_feat, new_pos, new_batch, index, values, origsize, newsize
Example #17
0
    np.random.seed(args.seed)
    torch.manual_seed(args.seed)

    # Training on CPU/GPU device
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    print(device)

    # load dataset
    dataname = args.dataset
    rootname = osp.join(osp.abspath(''), 'data', dataname)
    dataset = Planetoid(root=rootname, name=dataname)

    num_nodes = dataset[0].x.shape[0]
    L = get_laplacian(dataset[0].edge_index,
                      num_nodes=num_nodes,
                      normalization='sym')
    L = sparse.coo_matrix(
        (L[1].numpy(), (L[0][0, :].numpy(), L[0][1, :].numpy())),
        shape=(num_nodes, num_nodes))

    lobpcg_init = np.random.rand(num_nodes, 1)
    lambda_max, _ = lobpcg(L, lobpcg_init)
    lambda_max = lambda_max[0]

    # extract decomposition/reconstruction Masks
    FrameType = args.FrameType

    if FrameType == 'Haar':
        D1 = lambda x: np.cos(x / 2)
        D2 = lambda x: np.sin(x / 2)