diff --git a/test/nn/simplicial/test_snn_layer.py b/test/nn/simplicial/test_snn_layer.py new file mode 100644 index 00000000..3bab1de0 --- /dev/null +++ b/test/nn/simplicial/test_snn_layer.py @@ -0,0 +1,42 @@ +"""Test the SNN layer.""" + +import torch + +from topomodelx.nn.simplicial.snn_layer import SNNLayer + + +class TestSNNLayer: + """Test the SNN layer.""" + + def test_forward(self): + """Test the forward pass of the HSN layer.""" + in_channels = 5 + out_channels = 5 + n_nodes = 10 + K = 5 + lapl_0 = torch.randint(0, 2, (n_nodes, n_nodes)).float() + + x_0 = torch.randn(n_nodes, in_channels) + + snn = SNNLayer(in_channels, out_channels, K) + output = snn.forward(x_0, lapl_0) + + assert output.shape == (n_nodes, out_channels) + + def test_reset_parameters(self): + """Test the reset of the parameters.""" + in_channels = 5 + out_channels = 5 + K = 5 + + snn = SNNLayer(in_channels, out_channels, K) + snn.reset_parameters() + + for module in snn.modules(): + if isinstance(module, torch.nn.Conv2d): + torch.testing.assert_allclose( + module.weight, torch.zeros_like(module.weight) + ) + torch.testing.assert_allclose( + module.bias, torch.zeros_like(module.bias) + ) diff --git a/topomodelx/nn/simplicial/snn_layer.py b/topomodelx/nn/simplicial/snn_layer.py new file mode 100644 index 00000000..28a8278e --- /dev/null +++ b/topomodelx/nn/simplicial/snn_layer.py @@ -0,0 +1,104 @@ +"""Simplicial Neural Network Layer.""" +import torch + +from topomodelx.base.aggregation import Aggregation +from topomodelx.base.conv import Conv + + +class SNNLayer(torch.nn.Module): + """Layer of a Simplicial Neural Network (SNN). + + Implementation of the SNN layer proposed in [SNN20]. + + + References + ---------- + .. [SNN20] Stefania Ebli, Michael Defferrard and Gard Spreemann. + Simplicial Neural Networks. + Topological Data Analysis and Beyond workshop at NeurIPS. + https://arxiv.org/abs/2010.03633 + + Parameters + ---------- + K : int + Maximum polynomial degree for Laplacian. + in_channels : int + Dimension of features on each simplicial cell. + out_channels : int + Dimension of output representation on each simplicial cell. + initialization : string + Initialization method. + """ + + def __init__(self, in_channels, out_channels, K): + super().__init__() + self.in_channels = in_channels + self.out_channels = out_channels + self.K = K + + convs = [ + Conv(in_channels=in_channels, out_channels=out_channels, update_func="relu") + for _ in range(self.K) + ] + + self.convs = torch.nn.ModuleList(convs) + + self.aggr = Aggregation(aggr_func="sum", update_func="relu") + + def reset_parameters(self): + r"""Reset learnable parameters.""" + + for conv in self.convs: + conv.reset_parameters() + + def forward(self, x, laplacian): + r"""Forward pass. + + The forward pass was initially proposed in [SNN20]_. + Its equations are adapted from [TNN23]_, graphically illustrated in [PSHM23]_. + + .. math:: + \begin{align*} + &🟥 \quad m_{y \rightarrow x}^{p, (d \rightarrow d)} = ((H_{d})^p)\_{xy} \cdot h_y^{t,(d)} \cdot \Theta^{t,p}\\ + &🟧 \quad m_{x}^{p, (d \rightarrow d)} = \sum_{y \in (\mathcal{L}\_\uparrow + \mathcal{L}\_\downarrow)(x)} m_{y \rightarrow x}^{p, (d \rightarrow d)}\\ + &🟧 \quad m_x^{(d \rightarrow d)} = \sum_{p=1}^{P_1} (m_{x}^{p,(d \rightarrow d)})^{p}\\ + &🟩 \quad m_x^{(d)} = m_x^{(d \rightarrow d)}\\ + &🟦 \quad h_x^{t+1, (d)} = \sigma (m_{x}^{(d)}) + \end{align*} + + References + ---------- + .. [SNN20] Stefania Ebli, Michael Defferrard and Gard Spreemann. + Simplicial Neural Networks. + Topological Data Analysis and Beyond workshop at NeurIPS. + https://arxiv.org/abs/2010.03633 + .. [TNN23] Equations of Topological Neural Networks. + https://github.com/awesome-tnns/awesome-tnns/ + .. [PSHM23] Papillon, Sanborn, Hajij, Miolane. + Architectures of Topological Deep Learning: A Survey on Topological Neural Networks. + (2023) https://arxiv.org/abs/2304.10031. + + Parameters + ---------- + x: torch.Tensor, shape=[n_simplices, in_channels] + Input features on the simplices of the simplicial complex for the given simplicial degree. + laplacian : torch.sparse, shape=[n_simplices, n_simplices] + Simplicial Laplacian matrix for the given simplicial degree. + + Returns + ------- + _ : torch.Tensor, shape=[n_simplices, out_channels] + Output features on the nodes of the simplicial complex. + """ + + outputs = [] + laplacian_power = torch.eye(laplacian.shape[0]) + outputs.append(self.convs[0](x, laplacian_power)) + + for i in range(1, self.K): + laplacian_power = torch.mm(laplacian_power, laplacian) + + outputs.append(self.convs[i](x, laplacian_power)) + + x = self.aggr(outputs) + return x diff --git a/tutorials/simplicial/snn_train.ipynb b/tutorials/simplicial/snn_train.ipynb new file mode 100644 index 00000000..43260cae --- /dev/null +++ b/tutorials/simplicial/snn_train.ipynb @@ -0,0 +1,495 @@ +{ + "cells": [ + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Train a Simplicial Neural Network (SNN)\n", + "\n", + "In this notebook, we will create and train a Simplicial Neural Network, as proposed in the paper by [Ebli et. al : Simplicial Neural Networks (2020)](https://arxiv.org/abs/2010.03633). \n", + "\n", + "We train the model to perform regression on citation count on a coauthorship dataset \n", + "\n", + "The equations of one layer of this neural network are given by:\n", + "\n", + "\n", + "🟥 $\\quad m_{y \\rightarrow x}^{p, (d \\rightarrow d)} = ((H_{d})^p)\\_{xy} \\cdot h_y^{t,(d)} \\cdot \\Theta^{t,p}$\n", + "\n", + "🟧 $\\quad m_{x}^{p, (d \\rightarrow d)} = \\sum_{y \\in (\\mathcal{L}\\_\\uparrow + \\mathcal{L}\\_\\downarrow)(x)} m_{y \\rightarrow x}^{p, (d \\rightarrow d)}$\n", + "\n", + "🟧 $\\quad m_x^{(d \\rightarrow d)} = \\sum_{p=1}^{P_1} (m_{x}^{p,(d \\rightarrow d)})^{p}$\n", + "\n", + "🟩 $\\quad m_x^{(d)} = m_x^{(d \\rightarrow d)}$\n", + "\n", + "🟦 $\\quad h_x^{t+1, (d)} = \\sigma (m_{x}^{(d)})$\n", + "\n", + "\n", + "Where the notations are defined in [Papillon et al : Architectures of Topological Deep Learning: A Survey of Topological Neural Networks (2023)](https://arxiv.org/abs/2304.10031).\n", + "\n", + "Note that since the forward function is defined separately for each simplicial degree, a layer is created for a particular simplicial degree $d$ as in the equations above. Depending on the problem, multiple layers may be created and combined in a neural network architecture." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import numpy as np\n", + "from matplotlib import pyplot as plt\n", + "from torch_geometric.utils.convert import to_networkx\n", + "from topomodelx.nn.simplicial.snn_layer import SNNLayer\n", + "import toponetx.datasets as datasets" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Load and process the dataset\n", + "\n", + "Load the coauthorship network from [Ebli et. al : Simplicial Neural Networks (2020)](https://arxiv.org/abs/2010.03633) as a simplicial complex.\n", + "\n", + "The coauthorship network is a simplicial complex where a paper with k authors is represented by a (k-1)-simplex.\n", + "\n", + "The dataset is pre-processed as in the original paper. From the Semantic Scholar Open Research Corpus 80 papers with number of citations between 5 and 10 were sampled.\n", + "The papers constitute simplices in the complex, which is completed with subsimplices (seen as collaborations between subsets of authors) to form a simplicial complex.\n", + "\n", + "An attribute named \"citations\" is added to each simplex, corresponding to the sum of citations of all papers on which the authors represented by the simplex collaborated. This will be used as feature and target in our regression problem.\n", + "\n", + "The resulting simplicial complex is of dimension 10 and contains 24552 simplices in total. See the original paper for a more detailed description of the dataset." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "sc = datasets.graph.coauthorship()" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Total number of simplices: 24552\n" + ] + } + ], + "source": [ + "print(\"Total number of simplices:\", sum([len(sc.skeleton(i)) for i in range(sc.dim+1)]))" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Below we mask the features (number of citations for each simplex, for each degree), similar to the way it is done in the original paper.\n", + "\n", + "For each simplicial degree, *ratio_mask* simplices will be masked:\n", + "- At training time they will be replaced by the median value for the feature and will not be included when computing the loss.\n", + "- At test time on the other hand, these are the simplices for which test loss and accuracy are computed." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "ratio_mask = 0.15" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "features_target = {}\n", + "for i in range(sc.dim+1):\n", + " features_target[i] = np.array(list(sc.get_simplex_attributes(name=\"citations\", rank=i).values()))\n", + "\n", + "masks_train = {}\n", + "masks_test = {}\n", + "features_input = {}\n", + "\n", + "for i in range(len(features_target)):\n", + " masks_test[i] = np.random.choice(range(features_target[i].shape[0]), size=int(features_target[i].shape[0]*ratio_mask), replace=False)\n", + " masks_train[i] = list(set(range(features_target[i].shape[0])).difference(set(masks_test[i])))\n", + " features_input[i] = features_target[i].copy()\n", + " features_input[i][masks_test[i]] = np.median(features_target[i])\n", + "\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Define neighborhood structures. ##\n", + "\n", + "For the Simplicial Neural Network we will use the (normalized) Simplician Laplacian matrix.\n", + "\n", + "We can define the simplicial degree (rank) for which we want to run the regression problem below (since we have features on all simplicial degrees). Note that when changing the rank we get different dimension for the Laplacian matrix and the feature vector, which may lead to longer training time, and the network might need to be tuned differently." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "rank = 0" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "lapl = sc.normalized_laplacian_matrix(rank=rank)\n", + "\n", + "lapl = torch.from_numpy(lapl.todense()).to_sparse()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "torch.Size([352, 352])" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "lapl.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "torch.Size([352, 1])\n" + ] + } + ], + "source": [ + "x_nodes = torch.from_numpy(features_input[rank].reshape(-1, 1)).float()\n", + "y_nodes = torch.from_numpy(features_target[rank].reshape(-1, 1)).float()\n", + "print(x_nodes.shape)\n", + "channels_nodes = x_nodes.shape[1]" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Create the Neural Network\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "class SNN(torch.nn.Module):\n", + " \"\"\"Simplicial Neural Network Implementation for binary node classification.\n", + "\n", + " Parameters\n", + " ---------\n", + " channels : int\n", + " Dimension of features\n", + " n_layers : int\n", + " Amount of message passing layers.\n", + "\n", + " \"\"\"\n", + "\n", + " def __init__(self, in_channels, out_channels, hidden_channels, K=5):\n", + " super().__init__()\n", + " layers = torch.nn.ModuleList()\n", + "\n", + " layers.append(SNNLayer(in_channels=in_channels, out_channels=hidden_channels, K=K))\n", + " layers.append(SNNLayer(in_channels=hidden_channels, out_channels=hidden_channels, K=K))\n", + " layers.append(SNNLayer(in_channels=hidden_channels, out_channels=out_channels, K=K))\n", + "\n", + " self.linear = torch.nn.Linear(out_channels, 1)\n", + " self.layers = layers\n", + "\n", + " def forward(self, x, lapl):\n", + " \"\"\"Forward computation.\n", + "\n", + " Parameters\n", + " ---------\n", + " x : tensor\n", + " shape = [n_simplices, channels]\n", + " Node features.\n", + "\n", + " lapl : tensor\n", + " shape = [n_simplices, n_simplices]\n", + " Laplacian for the given rank\n", + "\n", + "\n", + " Returns\n", + " --------\n", + " _ : tensor\n", + " shape = [n_simplices, channels]\n", + " \n", + "\n", + " \"\"\"\n", + " for layer in self.layers:\n", + " x = layer(x, lapl)\n", + " return self.linear(x)" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Train the Neural Network\n", + "\n", + "We specify the model with our pre-made neighborhood structures and specify an optimizer." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "model = SNN(\n", + " in_channels=channels_nodes,\n", + " out_channels=channels_nodes,\n", + " hidden_channels=30,\n", + " K=5\n", + ")\n", + "optimizer = torch.optim.Adam(model.parameters(), lr=0.01)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Parameter counts:\n", + "Total number of parameters: 4802\n" + ] + } + ], + "source": [ + "num_params = 0\n", + "print(\"Parameter counts:\")\n", + "for param in model.parameters():\n", + " p = np.array(param.shape, dtype=int).prod()\n", + " num_params += p\n", + "print(\"Total number of parameters: %d\" %(num_params))" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The following cell performs the training, looping over the network for a low number of epochs." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch: 0 loss: 10.8426\n", + "Epoch: 10 loss: 2.1569\n", + "Epoch: 20 loss: 1.1768\n", + "Epoch: 30 loss: 0.8447\n", + "Epoch: 40 loss: 0.7254\n", + "Epoch: 50 loss: 1.4321\n", + "Epoch: 60 loss: 0.5802\n", + "Epoch: 70 loss: 0.2790\n", + "Epoch: 80 loss: 0.3477\n", + "Epoch: 90 loss: 0.5995\n", + "Epoch: 100 loss: 0.1706\n" + ] + } + ], + "source": [ + "train_losses = []\n", + "test_losses = []\n", + "test_interval = 10\n", + "num_epochs = 100\n", + "for epoch_i in range(0, num_epochs + 1):\n", + " epoch_loss = []\n", + " model.train()\n", + " optimizer.zero_grad()\n", + "\n", + " y_hat = model(x_nodes, lapl)\n", + " loss = torch.nn.functional.l1_loss(\n", + " y_hat[masks_train[rank]], y_nodes[masks_train[rank]], reduction=\"mean\"\n", + " )\n", + " train_losses.append(loss.detach().numpy())\n", + " epoch_loss.append(loss.item())\n", + " loss.backward()\n", + " optimizer.step()\n", + "\n", + " \n", + " if epoch_i % test_interval == 0:\n", + " print(\n", + " f\"Epoch: {epoch_i} loss: {np.mean(epoch_loss):.4f}\",\n", + " flush=True,\n", + " )\n", + " with torch.no_grad():\n", + " loss = torch.nn.functional.l1_loss(y_hat[masks_test[rank]], y_nodes[masks_test[rank]])\n", + " test_losses.append(loss)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "Text(0.5, 1.0, 'Test set loss')" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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oiiKdXV14tNPPy2mpKSIarVaTEpKEhctWuTQ2nPfvn3iTTfdJPbo0UPUarVidHS0OHPmTHHPnj3yNl988YV4xRVXiNHR0aJGoxF79Ogh3nXXXWJeXl6zPw8iou7E2bVKFK2l0CNHjhT9/PzEoKAgMTU1VXzsscfE3NxcURRb9z4siqK4bds2ceTIkaJGo2nxmsTrEZEjQRS74CtuIiIiIiKiTsQ5NkRERERE5PUY2BARERERkddjYENERERERF6PgQ0REREREXk9BjZEREREROT1GNgQEREREZHX87gFOi0WC3JzcxEUFARBENw9HCKibkUURVRUVCA+Ph4KBb/7kvDaRETkHm25LnlcYJObm4ukpCR3D4OIqFvLzs5GYmKiu4fhMXhtIiJyr9ZclzwusAkKCgJgHXxwcLCbR0NE1L3o9XokJSXJ78VkxWsTEZF7tOW65HGBjZTiDw4O5sWDiMhNWG7liNcmIiL3as11iQXURERERETk9RjYEBERERGR12NgQ0REREREXo+BDREREREReT0GNkRERERE5PUY2BARERERkddjYENERERERF6PgQ0REREREXk9BjZEREREROT1GNgQEREREZHX87nA5sWfjmP2W79jw9ECdw+FiIjI5TYdL8DCj/ehvLrO3UMhIvIoPhfYnL1Qhf1ZZcgrr3H3UIiIiFzujU2n8cPBPHx7MNfdQyEi8ig+F9gEaFUAgEqD2c0jISIicr3skmoAwKHzZe4dCBGRh/G5wCZQqwQAVBlMbh4JERGRa1UbTSiqNAIADp4vd/NoiIg8i88FNv5yxoaBDRGRrzGbzXjiiSeQkpICPz8/9O7dG88++yxEUWz2dZs3b8aIESOg1WrRp08frFy5smsG7GLnS+vLrE8WVKDayGsdEZHE5wKbQFtgw4wNEZHvefHFF7F06VL897//xbFjx/Diiy/i3//+N954440mX3P27FnMmDEDU6ZMQXp6Oh588EEsWLAA69at68KRu4ZUhgYAFhE4mqt342iIiDyLyt0DcLUAja0Ujd9iERH5nG3btuGaa67BjBkzAADJycn45JNPsGvXriZfs2zZMqSkpODll18GAAwcOBBbt27Fq6++imnTpnXJuF3FPrABgAPnyzEqOdxNoyEi8iw+l7EJkDM2bB5ARORrxo8fj40bN+LkyZMAgAMHDmDr1q2YPn16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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.figure(figsize=(10,4))\n", + "plt.subplot(121)\n", + "plt.plot(train_losses)\n", + "plt.title(\"Train set loss\")\n", + "plt.subplot(122)\n", + "plt.plot(test_losses)\n", + "plt.title(\"Test set loss\")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can also compute a measure of accuracy for the train and test sets, where a prediction is considered accurate if it deviates at most 10% from the target.\n", + "\n", + "Unfortunately the results are not comparable to those in the original paper. When looking at the implementation for the original paper (https://github.com/stefaniaebli/simplicial_neural_networks) a potential problem with the masking was found which could explain the difference (it seems that two masks are used, one for the imputation of the feature and one for the computation of the loss, where we use the same mask)." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Train accuracy: tensor(100.)\n" + ] + } + ], + "source": [ + "ground_truth = y_nodes[masks_train[rank]]\n", + "preds = y_hat[masks_train[rank]]\n", + "\n", + "print(\"Train accuracy: \", (torch.abs((preds-ground_truth)/ground_truth)<0.1).sum()/preds.shape[0]*100)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test accuracy: tensor(5.7692)\n" + ] + } + ], + "source": [ + "ground_truth = y_nodes[masks_test[rank]]\n", + "preds = y_hat[masks_test[rank]]\n", + "\n", + "print(\"Test accuracy: \", (torch.abs((preds-ground_truth)/ground_truth)<0.1).sum()/preds.shape[0]*100)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}