diff --git a/docs/templates/creating-dataset.md b/docs/templates/creating-dataset.md index d2e5c50d..019d0011 100644 --- a/docs/templates/creating-dataset.md +++ b/docs/templates/creating-dataset.md @@ -8,12 +8,10 @@ This is also useful if you want to share you datasets publicly or include them a ## Essential information -There are just a few things to know about datasets before you can create your own. - You create a dataset by subclassing the `spektral.data.Dataset` class. The core of datasets is the `read()` method. This is called at every instantiation of the dataset and must return a list of `spektral.data.Graph`. -It doesn't matter if you read the data from a file or create it on the fly, this is simply where the dataset is loaded in memory. +It doesn't matter if you read the data from a file or create it on the fly, this is where the dataset is loaded in memory. All datasets have a `path` property that represents the directory in which the data is stored. This defaults to `~/.spektral/datasets/[ClassName]`. You can ignore it if you want.
diff --git a/docs/templates/creating-layer.md b/docs/templates/creating-layer.md index 879be72b..5ad15a66 100644 --- a/docs/templates/creating-layer.md +++ b/docs/templates/creating-layer.md @@ -40,7 +40,7 @@ class GCN(MessagePassing): Note that the Keras keyword `activation` was passed to the constructor of the superclass. This can be done with any Keras keyword (like regularizers, constraints, etc) and the layer will process them automatically. -By default, the `call` method of MessagePassing layers will only call `propagate`. We modify it so that it also updates the node features before starting the propagation: +By default, the `call` method of MessagePassing layers will only call `propagate`. We modify it so that it also transforms the node features before starting the propagation: ```py def call(self, inputs): @@ -52,10 +52,10 @@ def call(self, inputs): return self.propagate(x=x, a=a) ``` -Then, we implement the `message` function, which only needs to get the neighbours for each node.
+Then, we implement the `message` function. The `get_i` and `get_j` built-in methods can be used to automatically access either side of the edges \(i \leftarrow j\). For instance, we can use `get_j` to access the node features `x[j]` of all neighbors `j`. -If you need direct access to the edge indices, you can use the `index_i` and `index_j` attributes directly. +If you need direct access to the edge indices, you can use the `index_i` and `index_j` attributes. In this case, we only need to get the neighbors' features and return them: @@ -95,7 +95,7 @@ This is enough to get started with building your own layers in Spektral. ## Notes -An important feature of the MessagePassing class is that any extra keyword argument given to `propagate`, will be matched to the signature of `message`, `aggregate` and `update` and forwarded to those functions if a match is found. +An important feature of the MessagePassing class is that any extra keyword argument given to `propagate`, will be compared to the signatures of `message`, `aggregate` and `update` and forwarded to those functions if a match is found. For example, we can call: diff --git a/docs/templates/examples.md b/docs/templates/examples.md index 265a4e6e..562bdbc1 100644 --- a/docs/templates/examples.md +++ b/docs/templates/examples.md @@ -5,23 +5,25 @@ This is a collection of examples that you can use as template for your projects. ## Node-level prediction - [Citation networks with GCN](https://github.com/danielegrattarola/spektral/blob/master/examples/node_prediction/citation_gcn.py) +- [Citation networks with GCN (custom training loop)](https://github.com/danielegrattarola/spektral/blob/master/examples/node_prediction/citation_gcn_custom.py) - [Citation networks with ChebConv](https://github.com/danielegrattarola/spektral/blob/master/examples/node_prediction/citation_cheby.py) - [Citation networks with GAT](https://github.com/danielegrattarola/spektral/blob/master/examples/node_prediction/citation_gat.py) +- [Citation networks with GAT (custom training loop)](https://github.com/danielegrattarola/spektral/blob/master/examples/node_prediction/citation_gat_custom.py) - [Citation networks with ARMA](https://github.com/danielegrattarola/spektral/blob/master/examples/node_prediction/citation_arma.py) - [Citation networks with SimpleGCN (custom transform)](https://github.com/danielegrattarola/spektral/blob/master/examples/node_prediction/citation_simple_gc.py) -- [Open Graph Benchmark dataset](https://github.com/danielegrattarola/spektral/blob/master/examples/node_prediction/ogbn-proteins_gcn.py) +- [Open Graph Benchmark dataset](https://github.com/danielegrattarola/spektral/blob/master/examples/node_prediction/ogbn-arxiv_gcn.py) ## Graph-level prediction - [General GNN](https://github.com/danielegrattarola/spektral/blob/master/examples/graph_prediction/general_gnn.py) - [Custom dataset](https://github.com/danielegrattarola/spektral/blob/master/examples/graph_prediction/custom_dataset.py) - [OGB mol-esol regression with MinCut pooling](https://github.com/danielegrattarola/spektral/blob/master/examples/graph_prediction/ogbg-mol-esol_batch.py) -- [OGB mol-hiv classification using edge attributes](https://github.com/danielegrattarola/spektral/blob/master/examples/graph_prediction/ogbg-mol-esol_batch.py) -- [Regression on QM9 with ECC](https://github.com/danielegrattarola/spektral/blob/master/examples/graph_prediction/qm9_batch.py) -- [Regression on QM9 with ECC and custom training loop](https://github.com/danielegrattarola/spektral/blob/master/examples/graph_prediction/qm9_disjoint.py) -- [TUDataset classification with GIN](https://github.com/danielegrattarola/spektral/blob/master/examples/graph_prediction/tud_disjoint.py) +- [OGB mol-hiv classification (edge attributes)](https://github.com/danielegrattarola/spektral/blob/master/examples/graph_prediction/ogbg-mol-esol_batch.py) +- [QM9 regression with ECC (custom training loop)](https://github.com/danielegrattarola/spektral/blob/master/examples/graph_prediction/qm9_ecc.py) +- [QM9 regression with ECC (batch mode)](https://github.com/danielegrattarola/spektral/blob/master/examples/graph_prediction/qm9_ecc_batch.py) +- [TUDataset classification with GIN](https://github.com/danielegrattarola/spektral/blob/master/examples/graph_prediction/tud_gin.py) ## Other applications - [Graph signal classification on MNIST (mixed mode)](https://github.com/danielegrattarola/spektral/blob/master/examples/other/graph_signal_classification_mnist.py) -- [Node clustering on citation networks with minCUT pooling (unsupervised)](https://github.com/danielegrattarola/spektral/blob/master/examples/other/node_clustering_mincut.py) +- [Node clustering on citation networks with MinCut pooling (unsupervised)](https://github.com/danielegrattarola/spektral/blob/master/examples/other/node_clustering_mincut.py) diff --git a/docs/templates/getting-started.md b/docs/templates/getting-started.md index 82eec7df..747f170c 100644 --- a/docs/templates/getting-started.md +++ b/docs/templates/getting-started.md @@ -1,6 +1,6 @@ # Getting started -Spektral is designed according to the guiding principles of the Keras API to make things extremely simple for beginners while maintaining flexibility for experts. +Spektral is designed according to the guiding principles of Keras to make things extremely simple for beginners while maintaining flexibility for experts. In this page we will go over the main features of Spektral while creating a graph neural network for graph classification. @@ -17,7 +17,7 @@ In Spektral, graphs are represented with instances of `spektral.data.Graph` whic - `e`: the **edge features** - usually represented in a sparse edge list format, with a `np.array` of shape `(n_edges, n_edge_features)`. - `y`: the **labels** - can represent anything, from graph labels to node labels, or even something else. -A graph can have all of these attributes or none of them. You can even add extra attributes if you want: after all, a `Graph` is just a plain Python object. For instance, see `graph.n_nodes`, `graph.n_node_features`, etc. +A graph can have all of these attributes or none of them. Since Graphs are just plain Python objects, you can also add extra attributes if you want. For instance, see `graph.n_nodes`, `graph.n_node_features`, etc. ## Datasets @@ -90,14 +90,14 @@ Now we are ready to augment our node features with the one-hot-encoded degree. S >>> dataset.apply(Degree(max_degree)) ``` -We can see that it worked because now we have an extra `max_degree + 1` node features, which are our one-hot vectors: +We can see that it worked because now we have an extra `max_degree + 1` node features: ```python >>> dataset[0] Graph(n_nodes=42, n_node_features=17, n_edge_features=None, y=[1. 0.]) ``` -Since we will be using a `GCNConv` layer in our GNN, we also want to follow the [original paper](https://arxiv.org/abs/1609.02907) that introduced this layer, and do some extra pre-processing of the adjacency matrix. +Since we will be using a `GCNConv` layer in our GNN, we also want to follow the [original paper](https://arxiv.org/abs/1609.02907) that introduced this layer and do some extra pre-processing of the adjacency matrix. Since this is a fairly common operation, Spektral has a transform to do it: @@ -196,9 +196,7 @@ and we can finally train our GNN! Since loaders are essentially generators, we need to provide the `steps_per_epoch` keyword to `model.fit()` and we don't need to specify a batch size: ```python -model.fit(loader.load(), - steps_per_epoch=loader.steps_per_epoch, - epochs=10) +model.fit(loader.load(), steps_per_epoch=loader.steps_per_epoch, epochs=10) ``` Done! @@ -218,8 +216,8 @@ loader = BatchLoader(dataset_test, batch_size=32) and feed it to the model by calling `load()`: ```python -loss = model.evaluate(loader.load(), - steps=loader.steps_per_epoch) +loss = model.evaluate(loader.load(), steps=loader.steps_per_epoch) + print('Test loss: {}'.format(loss)) ``` @@ -243,7 +241,6 @@ Make sure to read the documentation, and get in touch [on Github](https://github If you want to cite Spektral in your work, refer to our paper: -> Graph Neural Networks in TensorFlow and Keras with Spektral -> D. Grattarola and C. Alippi -> ICML 2020 - GRL+ Workshop -> [https://arxiv.org/abs/2006.12138](https://arxiv.org/abs/2006.12138) +> [Graph Neural Networks in TensorFlow and Keras with Spektral](https://arxiv.org/abs/2006.12138)
+> Daniele Grattarola and Cesare Alippi + diff --git a/examples/graph_prediction/ogbg-mol-esol_batch.py b/examples/graph_prediction/ogbg-mol-esol_mincut.py similarity index 100% rename from examples/graph_prediction/ogbg-mol-esol_batch.py rename to examples/graph_prediction/ogbg-mol-esol_mincut.py diff --git a/examples/graph_prediction/ogbg-mol-hiv_disjoint.py b/examples/graph_prediction/ogbg-mol-hiv_ecc.py similarity index 100% rename from examples/graph_prediction/ogbg-mol-hiv_disjoint.py rename to examples/graph_prediction/ogbg-mol-hiv_ecc.py diff --git a/examples/graph_prediction/qm9_disjoint.py b/examples/graph_prediction/qm9_ecc.py similarity index 100% rename from examples/graph_prediction/qm9_disjoint.py rename to examples/graph_prediction/qm9_ecc.py diff --git a/examples/graph_prediction/qm9_batch.py b/examples/graph_prediction/qm9_ecc_batch.py similarity index 100% rename from examples/graph_prediction/qm9_batch.py rename to examples/graph_prediction/qm9_ecc_batch.py diff --git a/examples/graph_prediction/tud_disjoint.py b/examples/graph_prediction/tud_gin.py similarity index 100% rename from examples/graph_prediction/tud_disjoint.py rename to examples/graph_prediction/tud_gin.py diff --git a/examples/node_prediction/citation_gat_fast.py b/examples/node_prediction/citation_gat_custom.py similarity index 96% rename from examples/node_prediction/citation_gat_fast.py rename to examples/node_prediction/citation_gat_custom.py index c01fed50..121dcfb4 100644 --- a/examples/node_prediction/citation_gat_fast.py +++ b/examples/node_prediction/citation_gat_custom.py @@ -1,5 +1,5 @@ """ -This script is an extension of the citation_gcn_fast.py script. +This script is an extension of the citation_gcn_custom.py script. It shows how to train GAT (with the same experimental setting of the original paper), using faster training and test functions. """ @@ -98,6 +98,6 @@ def evaluate(): else: current_patience -= 1 if current_patience == 0: - print('Best test acc: {}'.format(best_test_acc)) + print('Test accuracy: {}'.format(best_test_acc)) break toc('GAT ({} epochs)'.format(epoch)) diff --git a/examples/node_prediction/citation_gcn_fast.py b/examples/node_prediction/citation_gcn_custom.py similarity index 100% rename from examples/node_prediction/citation_gcn_fast.py rename to examples/node_prediction/citation_gcn_custom.py