def data_step(self, adj_transform="normalize_adj", attr_transform=None, K=35, re_decompose=False): graph = self.graph adj_matrix = gf.get(adj_transform)(graph.adj_matrix) node_attr = gf.get(attr_transform)(graph.node_attr) if re_decompose or not "U" in self.cache: V, U = sp.linalg.eigs(adj_matrix.astype('float64'), k=K) U, V = U.real, V.real else: U, V = self.cache.U, self.cache.V 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)
def make_data(self, graph, graph_transform=None, device=None, **kwargs): """This method is used for process your inputs, which accepts only keyword arguments in your defined method 'data_step'. This method will process the inputs, and transform them into tensors. Commonly used keyword arguments: -------------------------------- graph: graphgallery graph classes. graph_transform: string, Callable function, or a tuple with function and dict arguments. transform for the entire graph, it is used first. device: device for preparing data, if None, it defaults to `self.device` adj_transform: string, Callable function, or a tuple with function and dict arguments. transform for adjacency matrix. attr_transform: string, Callable function, or a tuple with function and dict arguments. transform for attribute matrix. other arguments (if have) will be passed into method 'data_step'. """ self.graph = gf.get(graph_transform)(graph) cfg = self.cfg.data if device is not None: self.data_device = gf.device(device, self.backend) else: self.data_device = self.device cfg.device = device _, kwargs = gf.wrapper(self.data_step)(**kwargs) kwargs['graph_transform'] = graph_transform cfg.merge_from_dict(kwargs) for k, v in kwargs.items(): if k.endswith("transform"): setattr(self.transform, k, gf.get(v)) return self
def process_step(self, adj_transform="normalize_adj", attr_transform=None, graph_transform=None, recalculate=True): 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) # ``A`` and ``X`` are cached for later use self.register_cache(X=X, A=A) if recalculate: # Uses this to save time for structure evation attack # NOTE: Please make sure the node attribute matrix remains the same if recalculate=False knn_graph = gf.normalize_adj(gf.knn_graph(node_attr), fill_weight=0.) pseudo_labels, node_pairs = gf.attr_sim(node_attr) knn_graph, pseudo_labels = gf.astensors(knn_graph, pseudo_labels, device=self.device) self.register_cache(knn_graph=knn_graph, pseudo_labels=pseudo_labels, node_pairs=node_pairs)
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) # 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(K=K)([X, A]) with tf.device(self.device): # ``A`` and ``X`` are cached for later use self.register_cache(X=X, A=A)
def data_step(self, adj_transform="add_selfloops", attr_transform=None): graph = self.graph adj_matrix = gf.get(adj_transform)(graph.adj_matrix) node_attr = gf.get(attr_transform)(graph.node_attr) X, G = gf.astensors(node_attr, adj_matrix, device=self.data_device) # ``G`` and ``X`` are cached for later use self.register_cache(X=X, G=G)
def __init__(self, *graph, n_clusters=None, adj_transform="normalize_adj", attr_transform=None, device='cpu:0', seed=None, name=None, **kwargs): r"""Create a Cluster Graph Convolutional Networks (ClusterGCN) model. This can be instantiated in several ways: model = ClusterGCN(graph) with a `graphgallery.data.Graph` instance representing A sparse, attributed, labeled graph. model = ClusterGCN(adj_matrix, node_attr, labels) where `adj_matrix` is a 2D Scipy sparse matrix denoting the graph, `node_attr` is a 2D Numpy array-like matrix denoting the node attributes, `labels` is a 1D Numpy array denoting the node labels. Parameters: ---------- graph: An instance of `graphgallery.data.Graph` or a tuple (list) of inputs. A sparse, attributed, labeled graph. n_clusters: integer. optional The number of clusters that the graph being seperated, if not specified (`None`), it will be set to the number of classes automatically. (default :obj: `None`). adj_transform: string, `transform`, or None. optional How to transform the adjacency matrix. See `graphgallery.functional` (default: :obj:`'normalize_adj'` with normalize rate `-0.5`. i.e., math:: \hat{A} = D^{-\frac{1}{2}} A D^{-\frac{1}{2}}) attr_transform: string, `transform`, or None. optional How to transform the node attribute matrix. See `graphgallery.functional` (default :obj: `None`) device: string. optional The device where the model is running on. You can specified `CPU` or `GPU` for the model. (default: :str: `CPU:0`, i.e., running on the 0-th `CPU`) seed: interger scalar. optional Used in combination with `tf.random.set_seed` & `np.random.seed` & `random.seed` to create a reproducible sequence of tensors across multiple calls. (default :obj: `None`, i.e., using random seed) name: string. optional Specified name for the model. (default: :str: `class.__name__`) kwargs: other custom keyword parameters. """ super().__init__(*graph, device=device, seed=seed, name=name, **kwargs) if not n_clusters: n_clusters = self.graph.num_node_classes self.n_clusters = n_clusters self.adj_transform = gf.get(adj_transform) self.attr_transform = gf.get(attr_transform) self.process()
def __init__(self, *graph, batch_size=256, rank=100, adj_transform="normalize_adj", attr_transform=None, device='cpu:0', seed=None, name=None, **kwargs): r"""Create a Fast Graph Convolutional Networks (FastGCN) model. This can be instantiated in several ways: model = FastGCN(graph) with a `graphgallery.data.Graph` instance representing A sparse, attributed, labeled graph. model = FastGCN(adj_matrix, node_attr, labels) where `adj_matrix` is a 2D Scipy sparse matrix denoting the graph, `node_attr` is a 2D Numpy array-like matrix denoting the node attributes, `labels` is a 1D Numpy array denoting the node labels. Parameters: ---------- graph: An instance of `graphgallery.data.Graph` or a tuple (list) of inputs. A sparse, attributed, labeled graph. batch_size (Positive integer, optional): Batch size for the training nodes. (default :int: `256`) rank (Positive integer, optional): The selected nodes for each batch nodes, `rank` must be smaller than `batch_size`. (default :int: `100`) adj_transform: string, `transform`, or None. optional How to transform the adjacency matrix. See `graphgallery.functional` (default: :obj:`'normalize_adj'` with normalize rate `-0.5`. i.e., math:: \hat{A} = D^{-\frac{1}{2}} A D^{-\frac{1}{2}}) attr_transform: string, `transform`, or None. optional How to transform the node attribute matrix. See `graphgallery.functional` (default :obj: `None`) device: string. optional The device where the model is running on. You can specified `CPU` or `GPU` for the model. (default: :str: `CPU:0`, i.e., running on the 0-th `CPU`) seed: interger scalar. optional Used in combination with `tf.random.set_seed` & `np.random.seed` & `random.seed` to create a reproducible sequence of tensors across multiple calls. (default :obj: `None`, i.e., using random seed) name: string. optional Specified name for the model. (default: :str: `class.__name__`) kwargs: other custom keyword parameters. """ super().__init__(*graph, device=device, seed=seed, name=name, **kwargs) self.rank = rank self.batch_size = batch_size self.adj_transform = gf.get(adj_transform) self.attr_transform = gf.get(attr_transform) self.process()
def __init__(self, *graph, adj_transform="normalize_adj", attr_transform=None, k=35, device='cpu:0', seed=None, name=None, **kwargs): r"""Create a Graph Convolutional Networks (GCN) model using Spetral Adversarial Training (SAT) defense strategy. This can be instantiated in several ways: model = SAT(graph) with a `graphgallery.data.Graph` instance representing A sparse, attributed, labeled graph. model = SAT(adj_matrix, node_attr, labels) where `adj_matrix` is a 2D Scipy sparse matrix denoting the graph, `node_attr` is a 2D Numpy array-like matrix denoting the node attributes, `labels` is a 1D Numpy array denoting the node labels. Parameters: ---------- graph: An instance of `graphgallery.data.Graph` or a tuple (list) of inputs. A sparse, attributed, labeled graph. adj_transform: string, `transform`, or None. optional How to transform the adjacency matrix. See `graphgallery.functional` (default: :obj:`'normalize_adj'` with normalize rate `-0.5`. i.e., math:: \hat{A} = D^{-\frac{1}{2}} A D^{-\frac{1}{2}}) attr_transform: string, `transform`, or None. optional How to transform the node attribute matrix. See `graphgallery.functional` (default :obj: `None`) k: integer. optional. The number of eigenvalues and eigenvectors desired. `k` must be smaller than N-1. It is not possible to compute all eigenvectors of an adjacency matrix. device: string. optional The device where the model is running on. You can specified `CPU` or `GPU` for the model. (default: :str: `CPU:0`, i.e., running on the 0-th `CPU`) seed: interger scalar. optional Used in combination with `tf.random.set_seed` & `np.random.seed` & `random.seed` to create a reproducible sequence of tensors across multiple calls. (default :obj: `None`, i.e., using random seed) name: string. optional Specified name for the model. (default: :str: `class.__name__`) kwargs: other custom keyword parameters. """ super().__init__(*graph, device=device, seed=seed, name=name, **kwargs) self.adj_transform = gf.get(adj_transform) self.attr_transform = gf.get(attr_transform) self.k = k self.process()
def process_step(self, attr_transform=None, graph_transform=None): graph = gf.get(graph_transform)(self.graph) node_attr = gf.get(attr_transform)(graph.node_attr) X = gf.astensors(node_attr, device=self.device) # ``A`` and ``X`` are cached for later use self.register_cache(X=X)
def __init__(self, *graph, n_samples=(15, 5), adj_transform="neighbor_sampler", attr_transform=None, device='cpu:0', seed=None, name=None, **kwargs): r"""Create a SAmple and aggreGatE Graph Convolutional Networks (GraphSAGE) model. This can be instantiated in several ways: model = GraphSAGE(graph) with a `graphgallery.data.Graph` instance representing A sparse, attributed, labeled graph. model = GraphSAGE(adj_matrix, node_attr, labels) where `adj_matrix` is a 2D Scipy sparse matrix denoting the graph, `node_attr` is a 2D Numpy array-like matrix denoting the node attributes, `labels` is a 1D Numpy array denoting the node labels. Parameters: ---------- graph: An instance of `graphgallery.data.Graph` or a tuple (list) of inputs. A sparse, attributed, labeled graph. n_samples: List of positive integer. optional The number of sampled neighbors for each nodes in each layer. (default :obj: `(15, 5)`, i.e., sample `15` first-order neighbors and `5` sencond-order neighbors, and the radius for `GraphSAGE` is `2`) adj_transform: string, `transform`, or None. optional How to transform the adjacency matrix. See `graphgallery.functional` (default: :obj:`'neighbor_sampler'`) attr_transform: string, `transform`, or None. optional How to transform the node attribute matrix. See `graphgallery.functional` (default :obj: `None`) device: string. optional The device where the model is running on. You can specified `CPU` or `GPU` for the model. (default: :str: `CPU:0`, i.e., running on the 0-th `CPU`) seed: interger scalar. optional Used in combination with `tf.random.set_seed` & `np.random.seed` & `random.seed` to create a reproducible sequence of tensors across multiple calls. (default :obj: `None`, i.e., using random seed) name: string. optional Specified name for the model. (default: :str: `class.__name__`) kwargs: other custom keyword parameters. """ super().__init__(*graph, device=device, seed=seed, name=name, **kwargs) self.n_samples = n_samples self.adj_transform = gf.get(adj_transform) self.attr_transform = gf.get(attr_transform) self.process()
def cache_transform(transform_kwargs): graph_transform = gf.get(transform_kwargs.pop("graph_transform", None)) adj_transform = gf.get(transform_kwargs.pop("adj_transform", None)) attr_transform = gf.get(transform_kwargs.pop("attr_transform", None)) label_transform = gf.get(transform_kwargs.pop("label_transform", None)) return gf.BunchDict(graph_transform=graph_transform, adj_transform=adj_transform, attr_transform=attr_transform, label_transform=label_transform)
def data_step(self, adj_transform="add_self_loop", 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, g = gf.astensors(attr_matrix, adj_matrix, device=self.data_device) # ``g`` and ``feat`` are cached for later use self.register_cache(feat=feat, g=g)
def data_step(self, adj_transform="normalize_adj", attr_transform=None): graph = self.graph adj_matrix = gf.get(adj_transform)(graph.adj_matrix).toarray() node_attr = gf.get(attr_transform)(graph.node_attr) # ``A`` and ``X`` are cached for later use self.register_cache(X=node_attr, A=adj_matrix)
def data_step(self, adj_transform=None, 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 = gf.astensor(attr_matrix, device=self.data_device) # ``feat`` is cached for later use self.register_cache(feat=feat, adj=adj_matrix)
def data_step(self, adj_transform="normalize_adj", attr_transform=None): 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) # ``A`` and ``X`` are cached for later use self.register_cache(X=X, A=A, neighbors=gf.find_4o_nbrs(adj_matrix))
def __init__(self, *graph, n_samples=50, adj_transform="normalize_adj", attr_transform=None, device='cpu:0', seed=None, name=None, **kwargs): r"""Create a sample-based Batch Virtual Adversarial Training Graph Convolutional Networks (SBVAT) model. This can be instantiated in several ways: model = SBVAT(graph) with a `graphgallery.data.Graph` instance representing A sparse, attributed, labeled graph. model = SBVAT(adj_matrix, node_attr, labels) where `adj_matrix` is a 2D Scipy sparse matrix denoting the graph, `node_attr` is a 2D Numpy array-like matrix denoting the node attributes, `labels` is a 1D Numpy array denoting the node labels. Parameters: ---------- graph: An instance of `graphgallery.data.Graph` or a tuple (list) of inputs. A sparse, attributed, labeled graph. n_samples (Positive integer, optional): The number of sampled subset nodes in the graph where the length of the shortest path between them is at least `4`. (default :obj: `50`) adj_transform: string, `transform`, or None. optional How to transform the adjacency matrix. See `graphgallery.functional` (default: :obj:`'normalize_adj'` with normalize rate `-0.5`. i.e., math:: \hat{A} = D^{-\frac{1}{2}} A D^{-\frac{1}{2}}) attr_transform: string, `transform`, or None. optional How to transform the node attribute matrix. See `graphgallery.functional` (default :obj: `None`) device: string. optional The device where the model is running on. You can specified `CPU` or `GPU` for the model. (default: :str: `CPU:0`, i.e., running on the 0-th `CPU`) seed: interger scalar. optional Used in combination with `tf.random.set_seed` & `np.random.seed` & `random.seed` to create a reproducible sequence of tensors across multiple calls. (default :obj: `None`, i.e., using random seed) name: string. optional Specified name for the model. (default: :str: `class.__name__`) kwargs: other custom keyword parameters. """ super().__init__(*graph, device=device, seed=seed, name=name, **kwargs) self.adj_transform = gf.get(adj_transform) self.attr_transform = gf.get(attr_transform) self.n_samples = n_samples self.process()
def __init__(self, *graph, adj_transform="normalize_adj", attr_transform=None, device='cpu:0', seed=None, name=None, **kwargs): r"""Create a Edge Convolution version of Graph Convolutional Networks (EdgeGCN) model. This can be instantiated in several ways: model = EdgeGCN(graph) with a `graphgallery.data.Graph` instance representing A sparse, attributed, labeled graph. model = EdgeGCN(adj_matrix, node_attr, labels) where `adj_matrix` is a 2D Scipy sparse matrix denoting the graph, `node_attr` is a 2D Numpy array-like matrix denoting the node attributes, `labels` is a 1D Numpy array denoting the node labels. Parameters: ---------- graph: An instance of `graphgallery.data.Graph` or a tuple (list) of inputs. A sparse, attributed, labeled graph. adj_transform: string, `transform`, or None. optional How to transform the adjacency matrix. See `graphgallery.functional` (default: :obj:`'normalize_adj'` with normalize rate `-0.5`. i.e., math:: \hat{A} = D^{-\frac{1}{2}} A D^{-\frac{1}{2}}) attr_transform: string, `transform`, or None. optional How to transform the node attribute matrix. See `graphgallery.functional` (default :obj: `None`) device: string. optional The device where the model is running on. You can specified `CPU` or `GPU` for the model. (default: :str: `CPU:0`, i.e., running on the 0-th `CPU`) seed: interger scalar. optional Used in combination with `tf.random.set_seed` & `np.random.seed` & `random.seed` to create a reproducible sequence of tensors across multiple calls. (default :obj: `None`, i.e., using random seed) name: string. optional Specified name for the model. (default: :str: `class.__name__`) kwargs: other custom keyword parameters. Note: ---------- The Graph Edge Convolutional implements the operation using message passing framework, i.e., using Tensor `edge index` and `edge weight` of adjacency matrix to aggregate neighbors' message, instead of SparseTensor `adj`. """ super().__init__(*graph, device=device, seed=seed, name=name, **kwargs) self.adj_transform = gf.get(adj_transform) self.attr_transform = gf.get(attr_transform) self.process()
def data_step(self, adj_transform="normalize_adj", attr_transform=None): graph = self.graph adj_matrix = gf.get(adj_transform)(graph.adj_matrix) node_attr = gf.get(attr_transform)(graph.node_attr) edge_index, edge_weight = gf.sparse_adj_to_edge(adj_matrix) X, E = gf.astensors(node_attr, (edge_index.T, edge_weight), device=self.data_device) # ``E`` and ``X`` are cached for later use self.register_cache(E=E, X=X)
def __init__(self, *graph, order=2, adj_transform="add_selfloops", attr_transform=None, device='cpu:0', seed=None, name=None, **kwargs): r"""Create a Simplifying Graph Convolutional Networks (SGC) model. This can be instantiated in several ways: model = SGC(graph) with a `graphgallery.data.Graph` instance representing A sparse, attributed, labeled graph. model = SGC(adj_matrix, node_attr, labels) where `adj_matrix` is a 2D Scipy sparse matrix denoting the graph, `node_attr` is a 2D Numpy array-like matrix denoting the node attributes, `labels` is a 1D Numpy array denoting the node labels. Parameters: ---------- graph: An instance of `graphgallery.data.Graph` or a tuple (list) of inputs. A sparse, attributed, labeled graph. order: positive integer. optional The power (order) of adjacency matrix. (default :obj: `2`, i.e., math:: A^{2}) adj_transform: string, `transform`, or None. optional How to transform the adjacency matrix. See `graphgallery.functional` (default: :obj:`'add_selfloops'`, i.e., A = A + I) attr_transform: string, `transform`, or None. optional How to transform the node attribute matrix. See `graphgallery.functional` (default :obj: `None`) device: string. optional The device where the model is running on. You can specified `CPU` or `GPU` for the model. (default: :str: `CPU:0`, i.e., running on the 0-th `CPU`) seed: interger scalar. optional Used in combination with `tf.random.set_seed` & `np.random.seed` & `random.seed` to create a reproducible sequence of tensors across multiple calls. (default :obj: `None`, i.e., using random seed) name: string. optional Specified name for the model. (default: :str: `class.__name__`) kwargs: other custom keyword parameters. """ super().__init__(*graph, device=device, seed=seed, name=name, **kwargs) self.order = order self.adj_transform = gf.get(adj_transform) self.attr_transform = gf.get(attr_transform) self.process()
def data_step(self, adj_transform="normalize_adj", attr_transform=None): graph = self.graph adj_matrix = gf.get(adj_transform)(graph.adj_matrix) node_attr = gf.get(attr_transform)(graph.node_attr) node_attr = adj_matrix @ node_attr X, A = gf.astensor(node_attr, device=self.data_device), adj_matrix # ``A`` and ``X`` are cached for later use self.register_cache(X=X, A=A)
def data_step(self, adj_transform="add_self_loop", 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 = gf.astensor(attr_matrix, device=self.data_device) # without considering `edge_weight` edges = gf.astensor(adj_matrix, device=self.data_device)[0] # ``edges`` and ``feat`` are cached for later use self.register_cache(feat=feat, edges=edges)
def data_step(self, adj_transform=("normalize_adj", dict(symmetric=False)), 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)
def data_step(self, adj_transform=("cheby_basis", dict(K=2)), 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)
def data_step(self, adj_transform=None, feat_transform=None): graph = self.graph adj_matrix = gf.get(adj_transform)(graph.adj_matrix) attr_matrix = gf.get(feat_transform)(graph.attr_matrix) X, A = gf.astensors(attr_matrix, device=self.data_device), adj_matrix # ``A`` and ``X`` are cached for later use self.register_cache(X=X, A=A)
def data_step(self, adj_transform=("normalize_adj", dict(rate=[-0.5, -1.0])), feat_transform=None): graph = self.graph adj_matrix = gf.get(adj_transform)(graph.adj_matrix) attr_matrix = gf.get(feat_transform)(graph.attr_matrix) X, A = gf.astensors(attr_matrix, adj_matrix, device=self.data_device) # ``A`` and ``X`` are cached for later use self.register_cache(X=X, A=A)
def data_step(self, adj_transform="normalize_adj", 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, edges = gf.astensors(attr_matrix, adj_matrix, device=self.data_device) # ``edges`` and ``feat`` are cached for later use self.register_cache(feat=feat, edges=edges)
def data_step(self, adj_transform=("normalize_adj", dict(symmetric=False)), attr_transform=None): 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) # ``A`` and ``X`` are cached for later use self.register_cache(X=X, A=A)
def process_step(self, adj_transform="add_selfloops", 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, device=self.device) # ``A`` and ``X`` are cached for later use self.register_cache(X=X, A=A)
def process_step(self, adj_transform=("normalize_adj", dict(fill_weight=0.0)), 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, device=self.device) # ``A`` and ``X`` are cached for later use self.register_cache(X=X, A=A)
def data_step(self, adj_transform="normalize_adj", feat_transform=None): graph = self.graph adj_matrix = gf.get(adj_transform)(graph.adj_matrix) attr_matrix = gf.get(feat_transform)(graph.attr_matrix) attr_matrix = adj_matrix @ attr_matrix feat, adj = gf.astensor(attr_matrix, device=self.data_device), adj_matrix # ``adj`` and ``feat`` are cached for later use self.register_cache(feat=feat, adj=adj)