From a400565d39bc909258408d96f70bf4b5d22d3371 Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Mon, 30 Oct 2023 15:36:45 +0000 Subject: [PATCH 01/39] allsets --- .gitignore | 1 + Dockerfile | 16 + docker-compose.yml | 17 + topomodelx/nn/hypergraph/allset.py | 20 +- .../nn/hypergraph/allset_transformer.py | 12 +- topomodelx/nn/hypergraph/hmpnn.py | 2 + tutorials/hypergraph/allset_train.ipynb | 374 +++++++++++------- .../hypergraph/allset_transformer_train.ipynb | 326 ++++++++------- tutorials/hypergraph/hmpnn_train.ipynb | 288 +++++++------- 9 files changed, 610 insertions(+), 446 deletions(-) create mode 100644 Dockerfile create mode 100644 docker-compose.yml diff --git a/.gitignore b/.gitignore index 1ad4f7c88..4ae7bb540 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ coverage.xml **/__pycache__/** __pycache__/ docs/build/ +data/ venv_*/ TopoNetX/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..d3914df1d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,16 @@ +FROM python:3.11.3 + +WORKDIR /TopoModelX + +COPY . . + +RUN pip install --upgrade pip + +RUN pip install -e '.[all]' + +RUN pip install torch==2.0.1 --extra-index-url https://download.pytorch.org/whl/cu115 +RUN pip install torch-scatter torch-sparse -f https://data.pyg.org/whl/torch-2.0.1+cu115.html +RUN pip install torch-cluster -f https://data.pyg.org/whl/torch-2.0.0+cu115.html +RUN pip install jupyterlab +RUN pip install notebook +RUN pip install ipykernel \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..db9a5110d --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,17 @@ +version: '3' +services: + myapp: + build: . + image: topomodelx:new + stdin_open: true + tty: true + volumes: + - ${PWD}:/TopoModelX + # deploy: + # resources: + # reservations: + # devices: + # - driver: nvidia + # count: 1 + # capabilities: [gpu] + diff --git a/topomodelx/nn/hypergraph/allset.py b/topomodelx/nn/hypergraph/allset.py index 793775aaf..8fb77bde9 100644 --- a/topomodelx/nn/hypergraph/allset.py +++ b/topomodelx/nn/hypergraph/allset.py @@ -48,6 +48,7 @@ def __init__( mlp_activation=None, mlp_dropout=0.0, mlp_norm=None, + task_level="graph", ): super().__init__() layers = [ @@ -65,7 +66,7 @@ def __init__( for _ in range(n_layers - 1): layers.append( AllSetLayer( - in_channels=in_channels, + in_channels=hidden_channels, hidden_channels=hidden_channels, dropout=dropout, mlp_num_layers=mlp_num_layers, @@ -76,6 +77,7 @@ def __init__( ) self.layers = torch.nn.ModuleList(layers) self.linear = torch.nn.Linear(hidden_channels, out_channels) + self.out_pool = True if task_level == "graph" else False def forward(self, x_0, incidence_1): """Forward computation. @@ -92,12 +94,14 @@ def forward(self, x_0, incidence_1): torch.Tensor Output prediction. """ - # cidx = edge_index[1].min() - # edge_index[1] -= cidx - # reversed_edge_index = torch.stack( - # [edge_index[1], edge_index[0]], dim=0) - + for layer in self.layers: x_0 = layer(x_0, incidence_1) - pooled_x = torch.max(x_0, dim=0)[0] - return torch.sigmoid(self.linear(pooled_x))[0] + + # Pool over all nodes in the hypergraph + if self.out_pool is True: + x = torch.max(x_0, dim=0)[0] + else: + x = x_0 + + return self.linear(x) diff --git a/topomodelx/nn/hypergraph/allset_transformer.py b/topomodelx/nn/hypergraph/allset_transformer.py index 2c0e803f2..ad5960c9c 100644 --- a/topomodelx/nn/hypergraph/allset_transformer.py +++ b/topomodelx/nn/hypergraph/allset_transformer.py @@ -47,6 +47,7 @@ def __init__( dropout=0.2, mlp_num_layers=2, mlp_dropout=0.0, + task_level="graph", ): super().__init__() layers = [ @@ -73,6 +74,7 @@ def __init__( ) self.layers = torch.nn.ModuleList(layers) self.linear = torch.nn.Linear(hidden_channels, out_channels) + self.out_pool = True if task_level == "graph" else False def forward(self, x_0, incidence_1): """ @@ -92,5 +94,11 @@ def forward(self, x_0, incidence_1): """ for layer in self.layers: x_0 = layer(x_0, incidence_1) - pooled_x = torch.max(x_0, dim=0)[0] - return torch.sigmoid(self.linear(pooled_x))[0] + + # Pool over all nodes in the hypergraph + if self.out_pool is True: + x = torch.max(x_0, dim=0)[0] + else: + x = x_0 + + return self.linear(x) \ No newline at end of file diff --git a/topomodelx/nn/hypergraph/hmpnn.py b/topomodelx/nn/hypergraph/hmpnn.py index d67213006..9d395398c 100644 --- a/topomodelx/nn/hypergraph/hmpnn.py +++ b/topomodelx/nn/hypergraph/hmpnn.py @@ -44,6 +44,8 @@ def __init__( ): super().__init__() hidden_features = (in_features,) + hidden_features + + self.to_hidden_linear = torch.nn.Sequential( *[ torch.nn.Linear(hidden_features[i], hidden_features[i + 1]) diff --git a/tutorials/hypergraph/allset_train.ipynb b/tutorials/hypergraph/allset_train.ipynb index df56edfb3..b27e1c695 100644 --- a/tutorials/hypergraph/allset_train.ipynb +++ b/tutorials/hypergraph/allset_train.ipynb @@ -36,7 +36,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 4, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:51.222779223Z", @@ -56,11 +56,10 @@ "\n", "import torch\n", "import numpy as np\n", - "from sklearn.model_selection import train_test_split\n", - "import toponetx.datasets as datasets\n", + "from torch_geometric.utils import to_undirected\n", + "import torch_geometric.datasets as geom_datasets\n", "\n", - "from topomodelx.nn.hypergraph.allset import AllSet\n", - "from topomodelx.utils.sparse import from_sparse" + "from topomodelx.nn.hypergraph.allset import AllSet\n" ] }, { @@ -73,7 +72,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 5, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:51.959770754Z", @@ -103,16 +102,12 @@ "\n", "## Import data ##\n", "\n", - "The first step is to import the dataset, shrec 16, a benchmark dataset for 3D mesh classification. We then lift each graph into our domain of choice, a hypergraph.\n", - "\n", - "We will also retrieve:\n", - "- input signal on the edges for each of these hypergraphs, as that will be what we feed the model in input\n", - "- the label associated to the hypergraph" + "The first step is to import the dataset, Cora, a benchmark classification datase. We then lift the graph into our domain of choice, a hypergraph.\n" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 6, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:53.022151550Z", @@ -121,53 +116,26 @@ }, "outputs": [ { - "name": "stdout", + "name": "stderr", "output_type": "stream", "text": [ - "Loading shrec 16 small dataset...\n", - "\n", - "done!\n" + "/usr/local/lib/python3.11/site-packages/torch_geometric/data/in_memory_dataset.py:284: UserWarning: It is not recommended to directly access the internal storage format `data` of an 'InMemoryDataset'. If you are absolutely certain what you are doing, access the internal storage via `InMemoryDataset._data` instead to suppress this warning. Alternatively, you can access stacked individual attributes of every graph via `dataset.{attr_name}`.\n", + " warnings.warn(msg)\n" ] } ], "source": [ - "shrec, _ = datasets.mesh.shrec_16(size=\"small\")\n", "\n", - "shrec = {key: np.array(value) for key, value in shrec.items()}\n", - "x_0s = shrec[\"node_feat\"]\n", - "x_1s = shrec[\"edge_feat\"]\n", - "x_2s = shrec[\"face_feat\"]\n", + "cora = geom_datasets.Planetoid(root=\"/TopoModelX/data/cora\", name=\"Cora\")\n", + "data = cora.data\n", "\n", - "ys = shrec[\"label\"]\n", - "simplexes = shrec[\"complexes\"]" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The 6th simplicial complex has 252 nodes with features of dimension 6.\n", - "The 6th simplicial complex has 750 edges with features of dimension 10.\n", - "The 6th simplicial complex has 500 faces with features of dimension 7.\n" - ] - } - ], - "source": [ - "i_complex = 6\n", - "print(\n", - " f\"The {i_complex}th simplicial complex has {x_0s[i_complex].shape[0]} nodes with features of dimension {x_0s[i_complex].shape[1]}.\"\n", - ")\n", - "print(\n", - " f\"The {i_complex}th simplicial complex has {x_1s[i_complex].shape[0]} edges with features of dimension {x_1s[i_complex].shape[1]}.\"\n", - ")\n", - "print(\n", - " f\"The {i_complex}th simplicial complex has {x_2s[i_complex].shape[0]} faces with features of dimension {x_2s[i_complex].shape[1]}.\"\n", - ")" + "x_0s = data.x\n", + "y = data.y\n", + "edge_index = data.edge_index\n", + "\n", + "train_mask = data.train_mask\n", + "val_mask = data.val_mask\n", + "test_mask = data.test_mask\n" ] }, { @@ -177,14 +145,14 @@ "source": [ "## Define neighborhood structures and lift into hypergraph domain. ##\n", "\n", - "Now we retrieve the neighborhood structures (i.e. their representative matrices) that we will use to send messges on each simplicial complex. In the case of this architecture, we need the boundary matrix (or incidence matrix) $B_1$ with shape $n_\\text{nodes} \\times n_\\text{edges}$.\n", + "Now we retrieve the neighborhood structure (i.e. their representative matrice) that we will use to send messges from node to hyperedges. In the case of this architecture, we need the boundary matrix (or incidence matrix) $B_1$ with shape $n_\\text{nodes} \\times n_\\text{edges}$.\n", "\n", - "Once we have recorded the incidence matrix (note that all incidence amtrices in the hypergraph domain must be unsigned), we lift each simplicial complex into a hypergraph. The pairwise edges will become pairwise hyperedges, and faces in the simplciial complex will become 3-wise hyperedges." + "In citation Cora dataset we lift graph structure to the hypergraph domain by creating hyperedges from 1-hop graph neighbourhood of each node. \n" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 7, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:53.022151550Z", @@ -193,41 +161,100 @@ }, "outputs": [], "source": [ - "hg_list = []\n", - "incidence_1_list = []\n", - "for simplex in simplexes:\n", - " incidence_1 = simplex.incidence_matrix(rank=1, signed=False)\n", - " # incidence_1 = from_sparse(incidence_1)\n", - " # incidence_1_list.append(incidence_1)\n", - " hg = simplex.to_hypergraph()\n", - " hg_list.append(hg)\n", - "\n", - "\n", - "# Extract hypergraphs incident matrices from collected hypergraphs\n", - "for hg in hg_list:\n", - " incidence_1 = hg.incidence_matrix()\n", - " incidence_1 = from_sparse(incidence_1)\n", - " incidence_1_list.append(incidence_1)" + "# Ensure the graph is undirected (optional but often useful for one-hop neighborhoods).\n", + "edge_index = to_undirected(edge_index)\n", + "\n", + "# Create a list of one-hop neighborhoods for each node.\n", + "one_hop_neighborhoods = []\n", + "for node in range(data.num_nodes):\n", + " # Get the one-hop neighbors of the current node.\n", + " neighbors = data.edge_index[1, data.edge_index[0] == node]\n", + "\n", + " # Append the neighbors to the list of one-hop neighborhoods.\n", + " one_hop_neighborhoods.append(neighbors.numpy())\n", + "\n", + "# Detect and eliminate duplicate hyperedges.\n", + "unique_hyperedges = set()\n", + "hyperedges = []\n", + "for neighborhood in one_hop_neighborhoods:\n", + " # Sort the neighborhood to ensure consistent comparison.\n", + " neighborhood = tuple(sorted(neighborhood))\n", + " if neighborhood not in unique_hyperedges:\n", + " hyperedges.append(list(neighborhood))\n", + " unique_hyperedges.add(neighborhood) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Additionally we print the statictis associated with obtained incidence matrix" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "The 6th hypergraph has an incidence matrix of shape torch.Size([252, 1250]).\n" + "Hyperedge statistics: \n", + "Number of hyperedges without duplicated hyperedges 2581\n", + "min = 1, \n", + "max = 168, \n", + "mean = 4.003099573808601, \n", + "median = 3.0, \n", + "std = 5.327622607829558, \n", + "Number of hyperedges with size equal to one = 412\n" ] } ], "source": [ - "i_complex = 6\n", - "print(\n", - " f\"The {i_complex}th hypergraph has an incidence matrix of shape {incidence_1_list[i_complex].shape}.\"\n", - ")" + "\n", + "# Calculate hyperedge statistics.\n", + "hyperedge_sizes = [len(he) for he in hyperedges]\n", + "min_size = min(hyperedge_sizes)\n", + "max_size = max(hyperedge_sizes)\n", + "mean_size = np.mean(hyperedge_sizes)\n", + "median_size = np.median(hyperedge_sizes)\n", + "std_size = np.std(hyperedge_sizes)\n", + "num_single_node_hyperedges = sum(np.array(hyperedge_sizes) == 1)\n", + "\n", + "# Print the hyperedge statistics.\n", + "print(f'Hyperedge statistics: ')\n", + "print('Number of hyperedges without duplicated hyperedges', len(hyperedges))\n", + "print(f'min = {min_size}, ')\n", + "print(f'max = {max_size}, ')\n", + "print(f'mean = {mean_size}, ')\n", + "print(f'median = {median_size}, ')\n", + "print(f'std = {std_size}, ')\n", + "print(f'Number of hyperedges with size equal to one = {num_single_node_hyperedges}')\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Construct incidence matrix" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "max_edges = len(hyperedges)\n", + "incidence_1 = np.zeros((x_0s.shape[0], max_edges))\n", + "for col, neighibourhood in enumerate(hyperedges):\n", + " for row in neighibourhood:\n", + " incidence_1[row, col] = 1\n", + "\n", + "assert all(incidence_1.sum(0)>0) == True, \"Some hyperedges are empty\"\n", + "assert all(incidence_1.sum(1)>0) == True, \"Some nodes are not in any hyperedges\"\n", + "incidence_1 = torch.Tensor(incidence_1).to_sparse_coo()" ] }, { @@ -240,7 +267,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 10, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:55.343005145Z", @@ -249,18 +276,20 @@ }, "outputs": [], "source": [ - "channels_edge = x_1s[0].shape[1]\n", - "channels_node = x_0s[0].shape[1]\n", - "in_channels = channels_node\n", - "hidden_channels, out_channels = 64, 1\n", + "in_channels = x_0s.shape[1]\n", + "hidden_channels = 128\n", + "out_channels = torch.unique(y).shape[0]\n", + "task_level = \"graph\" if out_channels==1 else \"node\"\n", + "n_layers=1\n", "\n", "# Define the model\n", "model = AllSet(\n", - " in_channels=channels_node,\n", + " in_channels=in_channels,\n", " hidden_channels=hidden_channels,\n", " out_channels=out_channels,\n", - " n_layers=1,\n", + " n_layers=n_layers,\n", " mlp_num_layers=1,\n", + " task_level=task_level,\n", ")\n", "model = model.to(device)" ] @@ -277,40 +306,48 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "# Optimizer and loss\n", - "opt = torch.optim.Adam(model.parameters(), lr=0.1)\n", - "loss_fn = torch.nn.MSELoss()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Split the dataset into train and test sets." + "opt = torch.optim.Adam(model.parameters(), lr=0.01)\n", + "\n", + "# Categorial cross-entropy loss\n", + "loss_fn = torch.nn.CrossEntropyLoss()\n", + "\n", + "# Accuracy\n", + "acc_fn = lambda y, y_hat: (y == y_hat).float().mean()" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 12, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:59.046068930Z", "start_time": "2023-06-01T16:14:59.037648626Z" } }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/tmp/ipykernel_132025/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + " x_0s = torch.tensor(x_0s)\n", + "/tmp/ipykernel_132025/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + " torch.tensor(y, dtype=torch.long).to(device),\n" + ] + } + ], "source": [ - "test_size = 0.2\n", - "x_0_train, x_0_test = train_test_split(x_0s, test_size=test_size, shuffle=False)\n", - "incidence_1_train, incidence_1_test = train_test_split(\n", - " incidence_1_list, test_size=test_size, shuffle=False\n", - ")\n", - "y_train, y_test = train_test_split(ys, test_size=test_size, shuffle=False)" + "x_0s = torch.tensor(x_0s)\n", + "x_0s, incidence_1, y = (\n", + " x_0s.float().to(device),\n", + " incidence_1.float().to(device),\n", + " torch.tensor(y, dtype=torch.long).to(device),\n", + " )" ] }, { @@ -323,77 +360,112 @@ }, { "cell_type": "code", - "execution_count": 10, - "metadata": { - "ExecuteTime": { - "end_time": "2023-06-01T16:15:01.683216142Z", - "start_time": "2023-06-01T16:15:00.727075750Z" - } - }, + "execution_count": 13, + "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Epoch: 1 loss: 274.8176\n", - "Test_loss: 529.0000\n", - "Epoch: 2 loss: 274.6125\n", - "Test_loss: 529.0000\n", - "Epoch: 3 loss: 274.6125\n", - "Test_loss: 529.0000\n", - "Epoch: 4 loss: 274.6125\n", - "Test_loss: 529.0000\n", - "Epoch: 5 loss: 274.6125\n", - "Test_loss: 529.0000\n" + "Epoch: 1 loss: 1.9463, acc: 0.1429\n", + "Epoch: 2 loss: 1.9444, acc: 0.2500\n", + "Epoch: 3 loss: 1.9251, acc: 0.1857\n", + "Epoch: 4 loss: 1.8896, acc: 0.1429\n", + "Epoch: 5 loss: 1.8660, acc: 0.4000\n", + "Val_loss: 1.8107, Val_acc: 0.4660\n", + "Test_loss: 1.8106, Test_acc: 0.4580\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch: 6 loss: 1.8350, acc: 0.4071\n", + "Epoch: 7 loss: 1.7756, acc: 0.4429\n", + "Epoch: 8 loss: 1.6999, acc: 0.4429\n", + "Epoch: 9 loss: 1.6292, acc: 0.5214\n", + "Epoch: 10 loss: 1.5617, acc: 0.5643\n", + "Val_loss: 1.6181, Val_acc: 0.5460\n", + "Test_loss: 1.5937, Test_acc: 0.5300\n", + "Epoch: 11 loss: 1.4966, acc: 0.5857\n", + "Epoch: 12 loss: 1.4400, acc: 0.6357\n", + "Epoch: 13 loss: 1.3909, acc: 0.8071\n", + "Epoch: 14 loss: 1.3518, acc: 0.8000\n", + "Epoch: 15 loss: 1.3084, acc: 0.8143\n", + "Val_loss: 2.4014, Val_acc: 0.6240\n", + "Test_loss: 2.4001, Test_acc: 0.6330\n", + "Epoch: 16 loss: 1.2680, acc: 0.7857\n", + "Epoch: 17 loss: 1.2288, acc: 0.7357\n", + "Epoch: 18 loss: 1.1883, acc: 0.8143\n", + "Epoch: 19 loss: 1.1475, acc: 0.8429\n", + "Epoch: 20 loss: 1.1041, acc: 0.8714\n", + "Val_loss: 3.5885, Val_acc: 0.5960\n", + "Test_loss: 3.2893, Test_acc: 0.6270\n", + "Epoch: 21 loss: 1.0625, acc: 0.8857\n", + "Epoch: 22 loss: 1.0231, acc: 0.9286\n", + "Epoch: 23 loss: 0.9872, acc: 0.9000\n", + "Epoch: 24 loss: 0.9507, acc: 0.9429\n", + "Epoch: 25 loss: 0.9152, acc: 0.9786\n", + "Val_loss: 6.1737, Val_acc: 0.6820\n", + "Test_loss: 5.9891, Test_acc: 0.7050\n", + "Epoch: 26 loss: 0.8912, acc: 0.9500\n", + "Epoch: 27 loss: 0.8676, acc: 0.9571\n", + "Epoch: 28 loss: 0.8527, acc: 0.9143\n", + "Epoch: 29 loss: 0.8306, acc: 0.9571\n", + "Epoch: 30 loss: 0.8066, acc: 0.9714\n", + "Val_loss: 6.9474, Val_acc: 0.6940\n", + "Test_loss: 7.5958, Test_acc: 0.7020\n" ] } ], "source": [ - "test_interval = 1\n", - "num_epochs = 5\n", + "torch.manual_seed(0)\n", + "test_interval = 5\n", + "num_epochs = 30\n", + "\n", + "epoch_loss = []\n", "for epoch_i in range(1, num_epochs + 1):\n", - " epoch_loss = []\n", + " \n", " model.train()\n", - " for x_0, incidence_1, y in zip(x_0_train, incidence_1_train, y_train):\n", - " x_0 = torch.tensor(x_0)\n", - " x_0, incidence_1, y = (\n", - " x_0.float().to(device),\n", - " incidence_1.float().to(device),\n", - " torch.tensor(y, dtype=torch.float).to(device),\n", - " )\n", - " opt.zero_grad()\n", - " # Extract edge_index from sparse incidence matrix\n", - " # edge_index, _ = to_edge_index(incidence_1)\n", - " y_hat = model(x_0, incidence_1)\n", - " loss = loss_fn(y_hat, y)\n", - "\n", - " loss.backward()\n", - " opt.step()\n", - " epoch_loss.append(loss.item())\n", + "\n", + " opt.zero_grad()\n", + " \n", + " # Extract edge_index from sparse incidence matrix\n", + " y_hat = model(x_0s, incidence_1)\n", + " loss = loss_fn(y_hat[train_mask], y[train_mask])\n", + "\n", + " loss.backward()\n", + " opt.step()\n", + " epoch_loss.append(loss.item())\n", "\n", " print(\n", - " f\"Epoch: {epoch_i} loss: {np.mean(epoch_loss):.4f}\",\n", + " f\"Epoch: {epoch_i} loss: {np.mean(epoch_loss):.4f}, \\\n", + " acc: {acc_fn(y_hat[train_mask].argmax(1), y[train_mask]):.4f}\",\n", " flush=True,\n", " )\n", + "\n", " if epoch_i % test_interval == 0:\n", - " with torch.no_grad():\n", - " for x_0, incidence_1, y in zip(x_0_test, incidence_1_test, y_test):\n", - " x_0 = torch.tensor(x_0)\n", - " x_0, incidence_1, y = (\n", - " x_0.float().to(device),\n", - " incidence_1.float().to(device),\n", - " torch.tensor(y, dtype=torch.float).to(device),\n", - " )\n", - " y_hat = model(x_0, incidence_1)\n", - " loss = loss_fn(y_hat, y)\n", - "\n", - " print(f\"Test_loss: {loss:.4f}\", flush=True)" + " model.eval()\n", + " y_hat = model(x_0s, incidence_1)\n", + "\n", + " loss = loss_fn(y_hat[val_mask], y[val_mask])\n", + " print(f\"Val_loss: {loss:.4f}, Val_acc: {acc_fn(y_hat[val_mask].argmax(1), y[val_mask]):.4f}\", flush=True)\n", + "\n", + " loss = loss_fn(y_hat[test_mask], y[test_mask])\n", + " print(f\"Test_loss: {loss:.4f}, Test_acc: {acc_fn(y_hat[test_mask].argmax(1), y[test_mask]):.4f}\", flush=True)" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { "kernelspec": { - "display_name": "Python 3.9.6 64-bit", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, diff --git a/tutorials/hypergraph/allset_transformer_train.ipynb b/tutorials/hypergraph/allset_transformer_train.ipynb index 79aa438d5..18d5723c4 100644 --- a/tutorials/hypergraph/allset_transformer_train.ipynb +++ b/tutorials/hypergraph/allset_transformer_train.ipynb @@ -76,7 +76,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 11, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:51.222779223Z", @@ -87,14 +87,10 @@ "source": [ "import torch\n", "import numpy as np\n", - "import toponetx.datasets as datasets\n", - "from sklearn.model_selection import train_test_split\n", + "from torch_geometric.utils import to_undirected\n", + "import torch_geometric.datasets as geom_datasets\n", "\n", - "from topomodelx.nn.hypergraph.allset_transformer import AllSetTransformer\n", - "from topomodelx.utils.sparse import from_sparse\n", - "\n", - "# %load_ext autoreload\n", - "# %autoreload 2" + "from topomodelx.nn.hypergraph.allset_transformer import AllSetTransformer\n" ] }, { @@ -107,7 +103,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 12, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:51.959770754Z", @@ -137,71 +133,30 @@ "\n", "## Import data ##\n", "\n", - "The first step is to import the dataset, shrec 16, a benchmark dataset for 3D mesh classification. We then lift each graph into our domain of choice, a hypergraph.\n", - "\n", - "We will also retrieve:\n", - "- input signal on the edges for each of these hypergraphs, as that will be what we feed the model in input\n", - "- the label associated to the hypergraph" + "The first step is to import the dataset, Cora, a benchmark classification datase. We then lift the graph into our domain of choice, a hypergraph." ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 13, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:53.022151550Z", "start_time": "2023-06-01T16:14:52.949636599Z" } }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Loading shrec 16 small dataset...\n", - "\n", - "done!\n" - ] - } - ], + "outputs": [], "source": [ - "shrec, _ = datasets.mesh.shrec_16(size=\"small\")\n", + "cora = geom_datasets.Planetoid(root=\"/TopoModelX/data/cora\", name=\"Cora\")\n", + "data = cora.data\n", "\n", - "shrec = {key: np.array(value) for key, value in shrec.items()}\n", - "x_0s = shrec[\"node_feat\"]\n", - "x_1s = shrec[\"edge_feat\"]\n", - "x_2s = shrec[\"face_feat\"]\n", + "x_0s = data.x\n", + "y = data.y\n", + "edge_index = data.edge_index\n", "\n", - "ys = shrec[\"label\"]\n", - "simplexes = shrec[\"complexes\"]" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The 6th simplicial complex has 252 nodes with features of dimension 6.\n", - "The 6th simplicial complex has 750 edges with features of dimension 10.\n", - "The 6th simplicial complex has 500 faces with features of dimension 7.\n" - ] - } - ], - "source": [ - "i_complex = 6\n", - "print(\n", - " f\"The {i_complex}th simplicial complex has {x_0s[i_complex].shape[0]} nodes with features of dimension {x_0s[i_complex].shape[1]}.\"\n", - ")\n", - "print(\n", - " f\"The {i_complex}th simplicial complex has {x_1s[i_complex].shape[0]} edges with features of dimension {x_1s[i_complex].shape[1]}.\"\n", - ")\n", - "print(\n", - " f\"The {i_complex}th simplicial complex has {x_2s[i_complex].shape[0]} faces with features of dimension {x_2s[i_complex].shape[1]}.\"\n", - ")" + "train_mask = data.train_mask\n", + "val_mask = data.val_mask\n", + "test_mask = data.test_mask" ] }, { @@ -211,14 +166,14 @@ "source": [ "## Define neighborhood structures and lift into hypergraph domain. ##\n", "\n", - "Now we retrieve the neighborhood structures (i.e. their representative matrices) that we will use to send messges on each simplicial complex. In the case of this architecture, we need the boundary matrix (or incidence matrix) $B_1$ with shape $n_\\text{nodes} \\times n_\\text{edges}$.\n", + "Now we retrieve the neighborhood structure (i.e. their representative matrice) that we will use to send messges from node to hyperedges. In the case of this architecture, we need the boundary matrix (or incidence matrix) $B_1$ with shape $n_\\text{nodes} \\times n_\\text{edges}$.\n", "\n", - "Once we have recorded the incidence matrix (note that all incidence amtrices in the hypergraph domain must be unsigned), we lift each simplicial complex into a hypergraph. The pairwise edges will become pairwise hyperedges, and faces in the simplciial complex will become 3-wise hyperedges." + "In citation Cora dataset we lift graph structure to the hypergraph domain by creating hyperedges from 1-hop graph neighbourhood of each node. \n" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:53.022151550Z", @@ -227,38 +182,100 @@ }, "outputs": [], "source": [ - "hg_list = []\n", - "incidence_1_list = []\n", - "for simplex in simplexes:\n", - " incidence_1 = simplex.incidence_matrix(rank=1, signed=False)\n", - " hg = simplex.to_hypergraph()\n", - " hg_list.append(hg)\n", - "\n", - "# Extract hypergraphs incident matrices from collected hypergraphs\n", - "for hg in hg_list:\n", - " incidence_1 = hg.incidence_matrix()\n", - " incidence_1 = from_sparse(incidence_1)\n", - " incidence_1_list.append(incidence_1)" + "# Ensure the graph is undirected (optional but often useful for one-hop neighborhoods).\n", + "edge_index = to_undirected(edge_index)\n", + "\n", + "# Create a list of one-hop neighborhoods for each node.\n", + "one_hop_neighborhoods = []\n", + "for node in range(data.num_nodes):\n", + " # Get the one-hop neighbors of the current node.\n", + " neighbors = data.edge_index[1, data.edge_index[0] == node]\n", + "\n", + " # Append the neighbors to the list of one-hop neighborhoods.\n", + " one_hop_neighborhoods.append(neighbors.numpy())\n", + "\n", + "# Detect and eliminate duplicate hyperedges.\n", + "unique_hyperedges = set()\n", + "hyperedges = []\n", + "for neighborhood in one_hop_neighborhoods:\n", + " # Sort the neighborhood to ensure consistent comparison.\n", + " neighborhood = tuple(sorted(neighborhood))\n", + " if neighborhood not in unique_hyperedges:\n", + " hyperedges.append(list(neighborhood))\n", + " unique_hyperedges.add(neighborhood) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Additionally we print the statictis associated with obtained incidence matrix" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "The 6th hypergraph has an incidence matrix of shape torch.Size([252, 1250]).\n" + "Hyperedge statistics: \n", + "Number of hyperedges without duplicated hyperedges 2581\n", + "min = 1, \n", + "max = 168, \n", + "mean = 4.003099573808601, \n", + "median = 3.0, \n", + "std = 5.327622607829558, \n", + "Number of hyperedges with size equal to one = 412\n" ] } ], "source": [ - "i_complex = 6\n", - "print(\n", - " f\"The {i_complex}th hypergraph has an incidence matrix of shape {incidence_1_list[i_complex].shape}.\"\n", - ")" + "\n", + "# Calculate hyperedge statistics.\n", + "hyperedge_sizes = [len(he) for he in hyperedges]\n", + "min_size = min(hyperedge_sizes)\n", + "max_size = max(hyperedge_sizes)\n", + "mean_size = np.mean(hyperedge_sizes)\n", + "median_size = np.median(hyperedge_sizes)\n", + "std_size = np.std(hyperedge_sizes)\n", + "num_single_node_hyperedges = sum(np.array(hyperedge_sizes) == 1)\n", + "\n", + "# Print the hyperedge statistics.\n", + "print(f'Hyperedge statistics: ')\n", + "print('Number of hyperedges without duplicated hyperedges', len(hyperedges))\n", + "print(f'min = {min_size}, ')\n", + "print(f'max = {max_size}, ')\n", + "print(f'mean = {mean_size}, ')\n", + "print(f'median = {median_size}, ')\n", + "print(f'std = {std_size}, ')\n", + "print(f'Number of hyperedges with size equal to one = {num_single_node_hyperedges}')\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Construct incidence matrix" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "max_edges = len(hyperedges)\n", + "incidence_1 = np.zeros((x_0s.shape[0], max_edges))\n", + "for col, neighibourhood in enumerate(hyperedges):\n", + " for row in neighibourhood:\n", + " incidence_1[row, col] = 1\n", + "\n", + "assert all(incidence_1.sum(0)>0) == True, \"Some hyperedges are empty\"\n", + "assert all(incidence_1.sum(1)>0) == True, \"Some nodes are not in any hyperedges\"\n", + "incidence_1 = torch.Tensor(incidence_1).to_sparse_coo()" ] }, { @@ -276,23 +293,26 @@ "metadata": {}, "outputs": [], "source": [ - "in_channels = x_0s[0].shape[1]\n", - "hid_dim = 64\n", - "out_dim = 1\n", + "in_channels = x_0s.shape[1]\n", + "hidden_channels = 64\n", + "out_channels = torch.unique(y).shape[0]\n", + "task_level = \"graph\" if out_channels==1 else \"node\"\n", + "\n", "heads = 4\n", "n_layers = 1\n", "mlp_num_layers = 2\n", - "Q_n = 1\n", + "\n", "\n", "\n", "# Define the model\n", "model = AllSetTransformer(\n", " in_channels=in_channels,\n", - " hidden_channels=hid_dim,\n", + " hidden_channels=hidden_channels,\n", + " out_channels=out_channels,\n", " heads=heads,\n", - " out_channels=out_dim,\n", " n_layers=n_layers,\n", " mlp_num_layers=mlp_num_layers,\n", + " task_level=task_level,\n", ")\n", "model = model.to(device)" ] @@ -314,35 +334,38 @@ "outputs": [], "source": [ "# Optimizer and loss\n", - "opt = torch.optim.Adam(model.parameters(), lr=0.1)\n", - "loss_fn = torch.nn.MSELoss()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Split the dataset into train and test sets." + "opt = torch.optim.Adam(model.parameters(), lr=0.01)\n", + "\n", + "# Categorial cross-entropy loss\n", + "loss_fn = torch.nn.CrossEntropyLoss()\n", + "\n", + "# Accuracy\n", + "acc_fn = lambda y, y_hat: (y == y_hat).float().mean()" ] }, { "cell_type": "code", "execution_count": 9, - "metadata": { - "ExecuteTime": { - "end_time": "2023-06-01T16:14:59.046068930Z", - "start_time": "2023-06-01T16:14:59.037648626Z" + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/tmp/ipykernel_137396/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + " x_0s = torch.tensor(x_0s)\n", + "/tmp/ipykernel_137396/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + " torch.tensor(y, dtype=torch.long).to(device),\n" + ] } - }, - "outputs": [], + ], "source": [ - "test_size = 0.2\n", - "x_0_train, x_0_test = train_test_split(x_0s, test_size=test_size, shuffle=False)\n", - "incidence_1_train, incidence_1_test = train_test_split(\n", - " incidence_1_list, test_size=test_size, shuffle=False\n", - ")\n", - "y_train, y_test = train_test_split(ys, test_size=test_size, shuffle=False)" + "x_0s = torch.tensor(x_0s)\n", + "x_0s, incidence_1, y = (\n", + " x_0s.float().to(device),\n", + " incidence_1.float().to(device),\n", + " torch.tensor(y, dtype=torch.long).to(device),\n", + " )" ] }, { @@ -367,65 +390,64 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch: 1 loss: 274.9063\n", - "Test_loss: 529.0000\n", - "Epoch: 2 loss: 274.6125\n", - "Test_loss: 529.0000\n", - "Epoch: 3 loss: 274.6125\n", - "Test_loss: 529.0000\n", - "Epoch: 4 loss: 274.6125\n", - "Test_loss: 529.0000\n", - "Epoch: 5 loss: 274.6125\n", - "Test_loss: 529.0000\n" + "Epoch: 1 loss: 2.0382, acc: 0.1357\n", + "Epoch: 2 loss: 2.0218, acc: 0.1643\n", + "Epoch: 3 loss: 1.9403, acc: 0.3071\n", + "Epoch: 4 loss: 1.8247, acc: 0.6714\n", + "Epoch: 5 loss: 1.6906, acc: 0.8786\n", + "Val_loss: 1.2014, Val_acc: 0.7340\n", + "Test_loss: 1.1616, Test_acc: 0.7620\n" ] } ], "source": [ - "test_interval = 1\n", + "torch.manual_seed(0)\n", + "test_interval = 5\n", "num_epochs = 5\n", + "\n", + "epoch_loss = []\n", "for epoch_i in range(1, num_epochs + 1):\n", - " epoch_loss = []\n", + " \n", " model.train()\n", - " for x_0, incidence_1, y in zip(x_0_train, incidence_1_train, y_train):\n", - " x_0 = torch.tensor(x_0)\n", - " x_0, incidence_1, y = (\n", - " x_0.float().to(device),\n", - " incidence_1.float().to(device),\n", - " torch.tensor(y, dtype=torch.float).to(device),\n", - " )\n", - " opt.zero_grad()\n", - " # Extract edge_index from sparse incidence matrix\n", - " # edge_index, _ = to_edge_index(incidence_1)\n", - " y_hat = model(x_0, incidence_1)\n", - " loss = loss_fn(y_hat, y)\n", - "\n", - " loss.backward()\n", - " opt.step()\n", - " epoch_loss.append(loss.item())\n", + "\n", + " opt.zero_grad()\n", + " \n", + " # Extract edge_index from sparse incidence matrix\n", + " y_hat = model(x_0s, incidence_1)\n", + " loss = loss_fn(y_hat[train_mask], y[train_mask])\n", + "\n", + " loss.backward()\n", + " opt.step()\n", + " epoch_loss.append(loss.item())\n", "\n", " print(\n", - " f\"Epoch: {epoch_i} loss: {np.mean(epoch_loss):.4f}\",\n", + " f\"Epoch: {epoch_i} loss: {np.mean(epoch_loss):.4f}, \\\n", + " acc: {acc_fn(y_hat[train_mask].argmax(1), y[train_mask]):.4f}\",\n", " flush=True,\n", " )\n", + "\n", " if epoch_i % test_interval == 0:\n", - " with torch.no_grad():\n", - " for x_0, incidence_1, y in zip(x_0_test, incidence_1_test, y_test):\n", - " x_0 = torch.tensor(x_0)\n", - " x_0, incidence_1, y = (\n", - " x_0.float().to(device),\n", - " incidence_1.float().to(device),\n", - " torch.tensor(y, dtype=torch.float).to(device),\n", - " )\n", - " y_hat = model(x_0, incidence_1)\n", - " loss = loss_fn(y_hat, y)\n", - "\n", - " print(f\"Test_loss: {loss:.4f}\", flush=True)" + " model.eval()\n", + " y_hat = model(x_0s, incidence_1)\n", + "\n", + " loss = loss_fn(y_hat[val_mask], y[val_mask])\n", + " print(f\"Val_loss: {loss:.4f}, Val_acc: {acc_fn(y_hat[val_mask].argmax(1), y[val_mask]):.4f}\", flush=True)\n", + "\n", + " loss = loss_fn(y_hat[test_mask], y[test_mask])\n", + " print(f\"Test_loss: {loss:.4f}, Test_acc: {acc_fn(y_hat[test_mask].argmax(1), y[test_mask]):.4f}\", flush=True)" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { "kernelspec": { - "display_name": "Python 3.9.6 64-bit", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, diff --git a/tutorials/hypergraph/hmpnn_train.ipynb b/tutorials/hypergraph/hmpnn_train.ipynb index 5c49e5230..39b00d423 100644 --- a/tutorials/hypergraph/hmpnn_train.ipynb +++ b/tutorials/hypergraph/hmpnn_train.ipynb @@ -25,8 +25,9 @@ "outputs": [], "source": [ "import torch\n", - "from torch_geometric.datasets import Planetoid\n", - "from sklearn.metrics import accuracy_score\n", + "import numpy as np\n", + "from torch_geometric.utils import to_undirected\n", + "import torch_geometric.datasets as geom_datasets\n", "\n", "from topomodelx.nn.hypergraph.hmpnn import HMPNN" ] @@ -81,28 +82,33 @@ "name": "stderr", "output_type": "stream", "text": [ - "Downloading https://github.com/kimiyoung/planetoid/raw/master/data/ind.cora.x\n", - "Downloading https://github.com/kimiyoung/planetoid/raw/master/data/ind.cora.tx\n", - "Downloading https://github.com/kimiyoung/planetoid/raw/master/data/ind.cora.allx\n", - "Downloading https://github.com/kimiyoung/planetoid/raw/master/data/ind.cora.y\n", - "Downloading https://github.com/kimiyoung/planetoid/raw/master/data/ind.cora.ty\n", - "Downloading https://github.com/kimiyoung/planetoid/raw/master/data/ind.cora.ally\n", - "Downloading https://github.com/kimiyoung/planetoid/raw/master/data/ind.cora.graph\n", - "Downloading https://github.com/kimiyoung/planetoid/raw/master/data/ind.cora.test.index\n", - "Processing...\n", - "Done!\n" + "/usr/local/lib/python3.11/site-packages/torch_geometric/data/in_memory_dataset.py:284: UserWarning: It is not recommended to directly access the internal storage format `data` of an 'InMemoryDataset'. If you are absolutely certain what you are doing, access the internal storage via `InMemoryDataset._data` instead to suppress this warning. Alternatively, you can access stacked individual attributes of every graph via `dataset.{attr_name}`.\n", + " warnings.warn(msg)\n" ] } ], "source": [ - "dataset = Planetoid(\".\", \"cora\")[0]" + "cora = geom_datasets.Planetoid(root=\"/TopoModelX/data/cora\", name=\"Cora\")\n", + "data = cora.data\n", + "\n", + "x_0s = data.x\n", + "y = data.y\n", + "edge_index = data.edge_index\n", + "\n", + "train_mask = data.train_mask\n", + "val_mask = data.val_mask\n", + "test_mask = data.test_mask" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Below, we construct the incidence matrix ($B_1$) which is of shape $n_\\text{nodes} \\times n_\\text{edges}$." + "## Define neighborhood structures and lift into hypergraph domain. ##\n", + "\n", + "Now we retrieve the neighborhood structure (i.e. their representative matrice) that we will use to send messges from node to hyperedges. In the case of this architecture, we need the boundary matrix (or incidence matrix) $B_1$ with shape $n_\\text{nodes} \\times n_\\text{edges}$.\n", + "\n", + "In citation Cora dataset we lift graph structure to the hypergraph domain by creating hyperedges from 1-hop graph neighbourhood of each node. \n" ] }, { @@ -111,10 +117,100 @@ "metadata": {}, "outputs": [], "source": [ - "dataset[\"incidence_1\"] = torch.sparse_coo_tensor(\n", - " dataset[\"edge_index\"], torch.ones(dataset[\"edge_index\"].shape[1]), dtype=torch.long\n", - ")\n", - "dataset = dataset.to(device)" + "# Ensure the graph is undirected (optional but often useful for one-hop neighborhoods).\n", + "edge_index = to_undirected(edge_index)\n", + "\n", + "# Create a list of one-hop neighborhoods for each node.\n", + "one_hop_neighborhoods = []\n", + "for node in range(data.num_nodes):\n", + " # Get the one-hop neighbors of the current node.\n", + " neighbors = data.edge_index[1, data.edge_index[0] == node]\n", + "\n", + " # Append the neighbors to the list of one-hop neighborhoods.\n", + " one_hop_neighborhoods.append(neighbors.numpy())\n", + "\n", + "# Detect and eliminate duplicate hyperedges.\n", + "unique_hyperedges = set()\n", + "hyperedges = []\n", + "for neighborhood in one_hop_neighborhoods:\n", + " # Sort the neighborhood to ensure consistent comparison.\n", + " neighborhood = tuple(sorted(neighborhood))\n", + " if neighborhood not in unique_hyperedges:\n", + " hyperedges.append(list(neighborhood))\n", + " unique_hyperedges.add(neighborhood) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Additionally we print the statictis associated with obtained incidence matrix" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hyperedge statistics: \n", + "Number of hyperedges without duplicated hyperedges 2581\n", + "min = 1, \n", + "max = 168, \n", + "mean = 4.003099573808601, \n", + "median = 3.0, \n", + "std = 5.327622607829558, \n", + "Number of hyperedges with size equal to one = 412\n" + ] + } + ], + "source": [ + "\n", + "# Calculate hyperedge statistics.\n", + "hyperedge_sizes = [len(he) for he in hyperedges]\n", + "min_size = min(hyperedge_sizes)\n", + "max_size = max(hyperedge_sizes)\n", + "mean_size = np.mean(hyperedge_sizes)\n", + "median_size = np.median(hyperedge_sizes)\n", + "std_size = np.std(hyperedge_sizes)\n", + "num_single_node_hyperedges = sum(np.array(hyperedge_sizes) == 1)\n", + "\n", + "# Print the hyperedge statistics.\n", + "print(f'Hyperedge statistics: ')\n", + "print('Number of hyperedges without duplicated hyperedges', len(hyperedges))\n", + "print(f'min = {min_size}, ')\n", + "print(f'max = {max_size}, ')\n", + "print(f'mean = {mean_size}, ')\n", + "print(f'median = {median_size}, ')\n", + "print(f'std = {std_size}, ')\n", + "print(f'Number of hyperedges with size equal to one = {num_single_node_hyperedges}')\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Construct incidence matrix" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "max_edges = len(hyperedges)\n", + "incidence_1 = np.zeros((x_0s.shape[0], max_edges))\n", + "for col, neighibourhood in enumerate(hyperedges):\n", + " for row in neighibourhood:\n", + " incidence_1[row, col] = 1\n", + "\n", + "assert all(incidence_1.sum(0)>0) == True, \"Some hyperedges are empty\"\n", + "assert all(incidence_1.sum(1)>0) == True, \"Some nodes are not in any hyperedges\"\n", + "incidence_1 = torch.Tensor(incidence_1).to_sparse_coo()" ] }, { @@ -129,7 +225,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 7, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:58.153514385Z", @@ -138,16 +234,29 @@ }, "outputs": [], "source": [ - "torch.manual_seed(41)\n", + "torch.manual_seed(0)\n", + "\n", + "# in_channels = x_0s.shape[1]\n", + "# hidden_channels = 64\n", + "# out_channels = torch.unique(y).shape[0]\n", + "# task_level = \"graph\" if out_channels==1 else \"node\"\n", + "\n", "\n", "in_features = 1433\n", "hidden_features = 8\n", "num_classes = 7\n", "n_layers = 2\n", "\n", - "model = HMPNN(in_features, (256, hidden_features), num_classes, n_layers).to(device)\n", + "model = HMPNN(in_features, \n", + " (256, hidden_features), num_classes, n_layers).to(device)\n", + "\n", "optimizer = torch.optim.Adam(model.parameters(), lr=0.01)\n", - "loss_fn = torch.nn.CrossEntropyLoss()" + "\n", + "# Categorial cross-entropy loss\n", + "loss_fn = torch.nn.CrossEntropyLoss()\n", + "\n", + "# Accuracy\n", + "acc_fn = lambda y, y_hat: (y == y_hat).float().mean()" ] }, { @@ -160,7 +269,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 11, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:15:01.683216142Z", @@ -169,127 +278,40 @@ }, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Epoch: 1 train loss: 2.1079 train acc: 0.14 val loss: 2.1436 val acc: 0.16\n", - "Epoch: 2 train loss: 2.0234 train acc: 0.15 val loss: 2.1016 val acc: 0.16\n", - "Epoch: 3 train loss: 1.9800 train acc: 0.15 val loss: 2.0681 val acc: 0.16\n", - "Epoch: 4 train loss: 1.9504 train acc: 0.18 val loss: 2.0389 val acc: 0.16\n", - "Epoch: 5 train loss: 1.9194 train acc: 0.21 val loss: 2.0137 val acc: 0.16\n", - "Epoch: 6 train loss: 1.9241 train acc: 0.19 val loss: 1.9917 val acc: 0.16\n", - "Epoch: 7 train loss: 1.8917 train acc: 0.19 val loss: 1.9729 val acc: 0.16\n", - "Epoch: 8 train loss: 1.8710 train acc: 0.23 val loss: 1.9556 val acc: 0.16\n", - "Epoch: 9 train loss: 1.8574 train acc: 0.29 val loss: 1.9402 val acc: 0.17\n", - "Epoch: 10 train loss: 1.8646 train acc: 0.29 val loss: 1.9265 val acc: 0.17\n", - "Epoch: 11 train loss: 1.8540 train acc: 0.33 val loss: 1.9137 val acc: 0.19\n", - "Epoch: 12 train loss: 1.8430 train acc: 0.36 val loss: 1.9012 val acc: 0.22\n", - "Epoch: 13 train loss: 1.8336 train acc: 0.38 val loss: 1.8886 val acc: 0.25\n", - "Epoch: 14 train loss: 1.8405 train acc: 0.34 val loss: 1.8775 val acc: 0.30\n", - "Epoch: 15 train loss: 1.8264 train acc: 0.34 val loss: 1.8668 val acc: 0.34\n", - "Epoch: 16 train loss: 1.8065 train acc: 0.38 val loss: 1.8562 val acc: 0.37\n", - "Epoch: 17 train loss: 1.8158 train acc: 0.37 val loss: 1.8456 val acc: 0.38\n", - "Epoch: 18 train loss: 1.7957 train acc: 0.44 val loss: 1.8346 val acc: 0.39\n", - "Epoch: 19 train loss: 1.8028 train acc: 0.40 val loss: 1.8249 val acc: 0.41\n", - "Epoch: 20 train loss: 1.7882 train acc: 0.37 val loss: 1.8156 val acc: 0.42\n", - "Epoch: 21 train loss: 1.7912 train acc: 0.36 val loss: 1.8070 val acc: 0.42\n", - "Epoch: 22 train loss: 1.7610 train acc: 0.46 val loss: 1.7985 val acc: 0.41\n", - "Epoch: 23 train loss: 1.7617 train acc: 0.47 val loss: 1.7903 val acc: 0.42\n", - "Epoch: 24 train loss: 1.7596 train acc: 0.41 val loss: 1.7827 val acc: 0.41\n", - "Epoch: 25 train loss: 1.7391 train acc: 0.38 val loss: 1.7737 val acc: 0.42\n", - "Epoch: 26 train loss: 1.7316 train acc: 0.44 val loss: 1.7650 val acc: 0.42\n", - "Epoch: 27 train loss: 1.7364 train acc: 0.42 val loss: 1.7559 val acc: 0.43\n", - "Epoch: 28 train loss: 1.7184 train acc: 0.48 val loss: 1.7454 val acc: 0.44\n", - "Epoch: 29 train loss: 1.7086 train acc: 0.44 val loss: 1.7362 val acc: 0.45\n", - "Epoch: 30 train loss: 1.6815 train acc: 0.46 val loss: 1.7276 val acc: 0.46\n", - "Epoch: 31 train loss: 1.6673 train acc: 0.50 val loss: 1.7178 val acc: 0.46\n", - "Epoch: 32 train loss: 1.6846 train acc: 0.51 val loss: 1.7080 val acc: 0.45\n", - "Epoch: 33 train loss: 1.6483 train acc: 0.51 val loss: 1.7007 val acc: 0.47\n", - "Epoch: 34 train loss: 1.6435 train acc: 0.54 val loss: 1.6982 val acc: 0.44\n", - "Epoch: 35 train loss: 1.6354 train acc: 0.54 val loss: 1.6998 val acc: 0.43\n", - "Epoch: 36 train loss: 1.6336 train acc: 0.54 val loss: 1.6982 val acc: 0.43\n", - "Epoch: 37 train loss: 1.5937 train acc: 0.60 val loss: 1.6972 val acc: 0.43\n", - "Epoch: 38 train loss: 1.5885 train acc: 0.56 val loss: 1.6962 val acc: 0.42\n", - "Epoch: 39 train loss: 1.5970 train acc: 0.55 val loss: 1.6861 val acc: 0.42\n", - "Epoch: 40 train loss: 1.5597 train acc: 0.52 val loss: 1.6673 val acc: 0.44\n", - "Epoch: 41 train loss: 1.5444 train acc: 0.64 val loss: 1.6510 val acc: 0.45\n", - "Epoch: 42 train loss: 1.5500 train acc: 0.60 val loss: 1.6320 val acc: 0.46\n", - "Epoch: 43 train loss: 1.5396 train acc: 0.54 val loss: 1.6160 val acc: 0.48\n", - "Epoch: 44 train loss: 1.5096 train acc: 0.59 val loss: 1.6032 val acc: 0.48\n", - "Epoch: 45 train loss: 1.4991 train acc: 0.59 val loss: 1.5924 val acc: 0.47\n", - "Epoch: 46 train loss: 1.5020 train acc: 0.58 val loss: 1.5830 val acc: 0.49\n", - "Epoch: 47 train loss: 1.4710 train acc: 0.64 val loss: 1.5741 val acc: 0.49\n", - "Epoch: 48 train loss: 1.4607 train acc: 0.67 val loss: 1.5691 val acc: 0.48\n", - "Epoch: 49 train loss: 1.4339 train acc: 0.62 val loss: 1.5616 val acc: 0.48\n", - "Epoch: 50 train loss: 1.4425 train acc: 0.66 val loss: 1.5615 val acc: 0.49\n", - "Epoch: 51 train loss: 1.4206 train acc: 0.66 val loss: 1.5477 val acc: 0.49\n", - "Epoch: 52 train loss: 1.4142 train acc: 0.64 val loss: 1.5281 val acc: 0.50\n", - "Epoch: 53 train loss: 1.4085 train acc: 0.66 val loss: 1.5042 val acc: 0.50\n", - "Epoch: 54 train loss: 1.4017 train acc: 0.62 val loss: 1.4884 val acc: 0.50\n", - "Epoch: 55 train loss: 1.3852 train acc: 0.65 val loss: 1.4838 val acc: 0.50\n", - "Epoch: 56 train loss: 1.3908 train acc: 0.61 val loss: 1.4847 val acc: 0.50\n", - "Epoch: 57 train loss: 1.3434 train acc: 0.71 val loss: 1.4878 val acc: 0.49\n", - "Epoch: 58 train loss: 1.3259 train acc: 0.69 val loss: 1.4851 val acc: 0.50\n", - "Epoch: 59 train loss: 1.3378 train acc: 0.66 val loss: 1.4907 val acc: 0.50\n", - "Epoch: 60 train loss: 1.2930 train acc: 0.69 val loss: 1.4966 val acc: 0.50\n", - "Epoch: 61 train loss: 1.3125 train acc: 0.69 val loss: 1.5017 val acc: 0.50\n", - "Epoch: 62 train loss: 1.3093 train acc: 0.65 val loss: 1.4984 val acc: 0.50\n", - "Epoch: 63 train loss: 1.2770 train acc: 0.67 val loss: 1.4915 val acc: 0.51\n", - "Epoch: 64 train loss: 1.2753 train acc: 0.65 val loss: 1.4854 val acc: 0.50\n", - "Epoch: 65 train loss: 1.2741 train acc: 0.69 val loss: 1.4831 val acc: 0.50\n", - "Epoch: 66 train loss: 1.2784 train acc: 0.67 val loss: 1.4728 val acc: 0.50\n", - "Epoch: 67 train loss: 1.2445 train acc: 0.67 val loss: 1.4712 val acc: 0.50\n", - "Epoch: 68 train loss: 1.2020 train acc: 0.69 val loss: 1.4743 val acc: 0.48\n", - "Epoch: 69 train loss: 1.1976 train acc: 0.69 val loss: 1.4705 val acc: 0.48\n", - "Epoch: 70 train loss: 1.1895 train acc: 0.71 val loss: 1.4638 val acc: 0.48\n", - "Epoch: 71 train loss: 1.2016 train acc: 0.71 val loss: 1.4672 val acc: 0.48\n", - "Epoch: 72 train loss: 1.1565 train acc: 0.74 val loss: 1.4450 val acc: 0.50\n", - "Epoch: 73 train loss: 1.1744 train acc: 0.69 val loss: 1.4279 val acc: 0.50\n", - "Epoch: 74 train loss: 1.1863 train acc: 0.72 val loss: 1.4286 val acc: 0.49\n", - "Epoch: 75 train loss: 1.1765 train acc: 0.72 val loss: 1.4333 val acc: 0.49\n", - "Epoch: 76 train loss: 1.1773 train acc: 0.66 val loss: 1.4499 val acc: 0.49\n", - "Epoch: 77 train loss: 1.1232 train acc: 0.74 val loss: 1.4701 val acc: 0.50\n", - "Epoch: 78 train loss: 1.0667 train acc: 0.76 val loss: 1.4692 val acc: 0.49\n", - "Epoch: 79 train loss: 1.0716 train acc: 0.76 val loss: 1.4593 val acc: 0.50\n", - "Epoch: 80 train loss: 1.0567 train acc: 0.77 val loss: 1.4450 val acc: 0.50\n", - "Epoch: 81 train loss: 1.0626 train acc: 0.72 val loss: 1.4309 val acc: 0.50\n", - "Epoch: 82 train loss: 1.0453 train acc: 0.73 val loss: 1.4244 val acc: 0.50\n", - "Epoch: 83 train loss: 1.0300 train acc: 0.78 val loss: 1.4135 val acc: 0.50\n", - "Epoch: 84 train loss: 1.0505 train acc: 0.74 val loss: 1.4152 val acc: 0.51\n", - "Epoch: 85 train loss: 1.0212 train acc: 0.74 val loss: 1.4340 val acc: 0.52\n", - "Epoch: 86 train loss: 1.0401 train acc: 0.76 val loss: 1.4580 val acc: 0.50\n", - "Epoch: 87 train loss: 0.9888 train acc: 0.81 val loss: 1.4668 val acc: 0.50\n", - "Epoch: 88 train loss: 1.0185 train acc: 0.74 val loss: 1.4771 val acc: 0.50\n", - "Epoch: 89 train loss: 0.9739 train acc: 0.78 val loss: 1.4710 val acc: 0.49\n", - "Epoch: 90 train loss: 0.9517 train acc: 0.83 val loss: 1.4661 val acc: 0.50\n", - "Epoch: 91 train loss: 0.9341 train acc: 0.79 val loss: 1.4519 val acc: 0.50\n", - "Epoch: 92 train loss: 0.9642 train acc: 0.80 val loss: 1.4457 val acc: 0.50\n", - "Epoch: 93 train loss: 0.9191 train acc: 0.77 val loss: 1.4126 val acc: 0.51\n", - "Epoch: 94 train loss: 0.8985 train acc: 0.79 val loss: 1.4001 val acc: 0.51\n", - "Epoch: 95 train loss: 0.8884 train acc: 0.84 val loss: 1.3864 val acc: 0.51\n", - "Epoch: 96 train loss: 0.9020 train acc: 0.82 val loss: 1.3875 val acc: 0.52\n", - "Epoch: 97 train loss: 0.8673 train acc: 0.84 val loss: 1.3893 val acc: 0.53\n", - "Epoch: 98 train loss: 0.9479 train acc: 0.78 val loss: 1.3814 val acc: 0.52\n", - "Epoch: 99 train loss: 0.8873 train acc: 0.81 val loss: 1.3855 val acc: 0.51\n", - "Epoch: 100 train loss: 0.8565 train acc: 0.86 val loss: 1.3936 val acc: 0.52\n" + "ename": "RuntimeError", + "evalue": "Sizes of tensors must match except in dimension 1. Expected size 2708 but got size 2581 for tensor number 1 in the list.", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m/TopoModelX/tutorials/hypergraph/hmpnn_train.ipynb Cell 16\u001b[0m line \u001b[0;36m7\n\u001b[1;32m 5\u001b[0m model\u001b[39m.\u001b[39mtrain()\n\u001b[1;32m 6\u001b[0m optimizer\u001b[39m.\u001b[39mzero_grad()\n\u001b[0;32m----> 7\u001b[0m y_hat \u001b[39m=\u001b[39m model(x_0s, initial_x_1, incidence_1)\n\u001b[1;32m 8\u001b[0m loss \u001b[39m=\u001b[39m loss_fn(y_pred_logits[train_mask], y[train_mask])\n\u001b[1;32m 9\u001b[0m loss\u001b[39m.\u001b[39mbackward()\n", + "File \u001b[0;32m/usr/local/lib/python3.11/site-packages/torch/nn/modules/module.py:1501\u001b[0m, in \u001b[0;36mModule._call_impl\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1496\u001b[0m \u001b[39m# If we don't have any hooks, we want to skip the rest of the logic in\u001b[39;00m\n\u001b[1;32m 1497\u001b[0m \u001b[39m# this function, and just call forward.\u001b[39;00m\n\u001b[1;32m 1498\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m (\u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_backward_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_backward_pre_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_forward_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_forward_pre_hooks\n\u001b[1;32m 1499\u001b[0m \u001b[39mor\u001b[39;00m _global_backward_pre_hooks \u001b[39mor\u001b[39;00m _global_backward_hooks\n\u001b[1;32m 1500\u001b[0m \u001b[39mor\u001b[39;00m _global_forward_hooks \u001b[39mor\u001b[39;00m _global_forward_pre_hooks):\n\u001b[0;32m-> 1501\u001b[0m \u001b[39mreturn\u001b[39;00m forward_call(\u001b[39m*\u001b[39;49margs, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n\u001b[1;32m 1502\u001b[0m \u001b[39m# Do not call functions when jit is used\u001b[39;00m\n\u001b[1;32m 1503\u001b[0m full_backward_hooks, non_full_backward_hooks \u001b[39m=\u001b[39m [], []\n", + "File \u001b[0;32m/TopoModelX/topomodelx/nn/hypergraph/hmpnn.py:87\u001b[0m, in \u001b[0;36mHMPNN.forward\u001b[0;34m(self, x_0, x_1, incidence_1)\u001b[0m\n\u001b[1;32m 85\u001b[0m x_1 \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mto_hidden_linear(x_1)\n\u001b[1;32m 86\u001b[0m \u001b[39mfor\u001b[39;00m layer \u001b[39min\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mlayers:\n\u001b[0;32m---> 87\u001b[0m x_0, x_1 \u001b[39m=\u001b[39m layer(x_0, x_1, incidence_1)\n\u001b[1;32m 89\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mto_categories_linear(x_0)\n", + "File \u001b[0;32m/usr/local/lib/python3.11/site-packages/torch/nn/modules/module.py:1501\u001b[0m, in \u001b[0;36mModule._call_impl\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1496\u001b[0m \u001b[39m# If we don't have any hooks, we want to skip the rest of the logic in\u001b[39;00m\n\u001b[1;32m 1497\u001b[0m \u001b[39m# this function, and just call forward.\u001b[39;00m\n\u001b[1;32m 1498\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m (\u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_backward_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_backward_pre_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_forward_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_forward_pre_hooks\n\u001b[1;32m 1499\u001b[0m \u001b[39mor\u001b[39;00m _global_backward_pre_hooks \u001b[39mor\u001b[39;00m _global_backward_hooks\n\u001b[1;32m 1500\u001b[0m \u001b[39mor\u001b[39;00m _global_forward_hooks \u001b[39mor\u001b[39;00m _global_forward_pre_hooks):\n\u001b[0;32m-> 1501\u001b[0m \u001b[39mreturn\u001b[39;00m forward_call(\u001b[39m*\u001b[39;49margs, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n\u001b[1;32m 1502\u001b[0m \u001b[39m# Do not call functions when jit is used\u001b[39;00m\n\u001b[1;32m 1503\u001b[0m full_backward_hooks, non_full_backward_hooks \u001b[39m=\u001b[39m [], []\n", + "File \u001b[0;32m/TopoModelX/topomodelx/nn/hypergraph/hmpnn_layer.py:224\u001b[0m, in \u001b[0;36mHMPNNLayer.forward\u001b[0;34m(self, x_0, x_1, incidence_1)\u001b[0m\n\u001b[1;32m 203\u001b[0m \u001b[39m\u001b[39m\u001b[39mr\u001b[39m\u001b[39m\"\"\"Forward computation.\u001b[39;00m\n\u001b[1;32m 204\u001b[0m \n\u001b[1;32m 205\u001b[0m \u001b[39mParameters\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 219\u001b[0m \u001b[39m Output features of the hyperedges.\u001b[39;00m\n\u001b[1;32m 220\u001b[0m \u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m 221\u001b[0m node_messages_aggregated, node_messages \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mnode_to_hyperedge_messenger(\n\u001b[1;32m 222\u001b[0m x_0, incidence_1\n\u001b[1;32m 223\u001b[0m )\n\u001b[0;32m--> 224\u001b[0m hyperedge_messages_aggregated \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mhyperedge_to_node_messenger(\n\u001b[1;32m 225\u001b[0m x_1, incidence_1, node_messages\n\u001b[1;32m 226\u001b[0m )\n\u001b[1;32m 228\u001b[0m x_0 \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mupdating_func(\n\u001b[1;32m 229\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mapply_regular_dropout(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mnode_batchnorm(x_0)),\n\u001b[1;32m 230\u001b[0m hyperedge_messages_aggregated,\n\u001b[1;32m 231\u001b[0m )\n\u001b[1;32m 232\u001b[0m x_1 \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mupdating_func(\n\u001b[1;32m 233\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mapply_regular_dropout(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mhyperedge_batchnorm(x_1)),\n\u001b[1;32m 234\u001b[0m node_messages_aggregated,\n\u001b[1;32m 235\u001b[0m )\n", + "File \u001b[0;32m/usr/local/lib/python3.11/site-packages/torch/nn/modules/module.py:1501\u001b[0m, in \u001b[0;36mModule._call_impl\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1496\u001b[0m \u001b[39m# If we don't have any hooks, we want to skip the rest of the logic in\u001b[39;00m\n\u001b[1;32m 1497\u001b[0m \u001b[39m# this function, and just call forward.\u001b[39;00m\n\u001b[1;32m 1498\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m (\u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_backward_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_backward_pre_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_forward_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_forward_pre_hooks\n\u001b[1;32m 1499\u001b[0m \u001b[39mor\u001b[39;00m _global_backward_pre_hooks \u001b[39mor\u001b[39;00m _global_backward_hooks\n\u001b[1;32m 1500\u001b[0m \u001b[39mor\u001b[39;00m _global_forward_hooks \u001b[39mor\u001b[39;00m _global_forward_pre_hooks):\n\u001b[0;32m-> 1501\u001b[0m \u001b[39mreturn\u001b[39;00m forward_call(\u001b[39m*\u001b[39;49margs, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n\u001b[1;32m 1502\u001b[0m \u001b[39m# Do not call functions when jit is used\u001b[39;00m\n\u001b[1;32m 1503\u001b[0m full_backward_hooks, non_full_backward_hooks \u001b[39m=\u001b[39m [], []\n", + "File \u001b[0;32m/TopoModelX/topomodelx/nn/hypergraph/hmpnn_layer.py:74\u001b[0m, in \u001b[0;36m_HyperedgeToNodeMessenger.forward\u001b[0;34m(self, x_source, neighborhood, node_messages)\u001b[0m\n\u001b[1;32m 73\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mforward\u001b[39m(\u001b[39mself\u001b[39m, x_source, neighborhood, node_messages):\n\u001b[0;32m---> 74\u001b[0m x_message \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mmessage(x_source, neighborhood, node_messages)\n\u001b[1;32m 76\u001b[0m neighborhood \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mapply_dropout(neighborhood, \u001b[39mself\u001b[39m\u001b[39m.\u001b[39madjacency_dropout)\n\u001b[1;32m 77\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mtarget_index_i, source_index_j \u001b[39m=\u001b[39m neighborhood\u001b[39m.\u001b[39mindices()\n", + "File \u001b[0;32m/TopoModelX/topomodelx/nn/hypergraph/hmpnn_layer.py:71\u001b[0m, in \u001b[0;36m_HyperedgeToNodeMessenger.message\u001b[0;34m(self, x_source, neighborhood, node_messages)\u001b[0m\n\u001b[1;32m 66\u001b[0m source_index_j, target_index_i \u001b[39m=\u001b[39m hyperedge_neighborhood\u001b[39m.\u001b[39mindices()\n\u001b[1;32m 67\u001b[0m node_messages_aggregated \u001b[39m=\u001b[39m scatter(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39maggr_func)(\n\u001b[1;32m 68\u001b[0m node_messages\u001b[39m.\u001b[39mindex_select(\u001b[39m-\u001b[39m\u001b[39m2\u001b[39m, source_index_j), target_index_i, \u001b[39m0\u001b[39m\n\u001b[1;32m 69\u001b[0m )\n\u001b[0;32m---> 71\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mmessaging_func(x_source, node_messages_aggregated)\n", + "File \u001b[0;32m/usr/local/lib/python3.11/site-packages/torch/nn/modules/module.py:1501\u001b[0m, in \u001b[0;36mModule._call_impl\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1496\u001b[0m \u001b[39m# If we don't have any hooks, we want to skip the rest of the logic in\u001b[39;00m\n\u001b[1;32m 1497\u001b[0m \u001b[39m# this function, and just call forward.\u001b[39;00m\n\u001b[1;32m 1498\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m (\u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_backward_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_backward_pre_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_forward_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_forward_pre_hooks\n\u001b[1;32m 1499\u001b[0m \u001b[39mor\u001b[39;00m _global_backward_pre_hooks \u001b[39mor\u001b[39;00m _global_backward_hooks\n\u001b[1;32m 1500\u001b[0m \u001b[39mor\u001b[39;00m _global_forward_hooks \u001b[39mor\u001b[39;00m _global_forward_pre_hooks):\n\u001b[0;32m-> 1501\u001b[0m \u001b[39mreturn\u001b[39;00m forward_call(\u001b[39m*\u001b[39;49margs, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n\u001b[1;32m 1502\u001b[0m \u001b[39m# Do not call functions when jit is used\u001b[39;00m\n\u001b[1;32m 1503\u001b[0m full_backward_hooks, non_full_backward_hooks \u001b[39m=\u001b[39m [], []\n", + "File \u001b[0;32m/TopoModelX/topomodelx/nn/hypergraph/hmpnn_layer.py:91\u001b[0m, in \u001b[0;36m_DefaultHyperedgeToNodeMessagingFunc.forward\u001b[0;34m(self, x_1, m_0)\u001b[0m\n\u001b[1;32m 90\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mforward\u001b[39m(\u001b[39mself\u001b[39m, x_1, m_0):\n\u001b[0;32m---> 91\u001b[0m \u001b[39mreturn\u001b[39;00m F\u001b[39m.\u001b[39msigmoid(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mlinear(torch\u001b[39m.\u001b[39;49mcat((x_1, m_0), dim\u001b[39m=\u001b[39;49m\u001b[39m1\u001b[39;49m)))\n", + "\u001b[0;31mRuntimeError\u001b[0m: Sizes of tensors must match except in dimension 1. Expected size 2708 but got size 2581 for tensor number 1 in the list." ] } ], "source": [ - "train_y_true = dataset[\"y\"][dataset[\"train_mask\"]]\n", - "val_y_true = dataset[\"y\"][dataset[\"val_mask\"]]\n", - "initial_x_1 = torch.zeros_like(dataset[\"x\"])\n", + "\n", + "initial_x_1 = torch.zeros_like(x_0s)\n", + "\n", "for epoch in range(100):\n", " model.train()\n", " optimizer.zero_grad()\n", - " y_pred_logits = model(dataset[\"x\"], initial_x_1, dataset[\"incidence_1\"])\n", - " loss = loss_fn(y_pred_logits[dataset[\"train_mask\"]], train_y_true)\n", + " y_hat = model(x_0s, initial_x_1, incidence_1)\n", + " loss = loss_fn(y_pred_logits[train_mask], y[train_mask])\n", " loss.backward()\n", " optimizer.step()\n", "\n", " train_loss = loss.item()\n", - " y_pred = y_pred_logits.argmax(dim=-1)\n", - " train_acc = accuracy_score(train_y_true, y_pred[dataset[\"train_mask\"]])\n", + " train_acc = acc_fn(y_hat[train_mask].argmax(1), y[train_mask])\n", "\n", " model.eval()\n", " with torch.no_grad():\n", From 2077aae863dfb5b72ea88f8e51fd1a8e2c6e509c Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Mon, 30 Oct 2023 16:49:46 +0000 Subject: [PATCH 02/39] teamplate --- tutorials/hypergraph/hmpnn_train.ipynb | 279 ++++++---------------- tutorials/simplicial/hsn_train.ipynb | 8 +- tutorials/simplicial/sca_cmps_train.ipynb | 29 ++- 3 files changed, 99 insertions(+), 217 deletions(-) diff --git a/tutorials/hypergraph/hmpnn_train.ipynb b/tutorials/hypergraph/hmpnn_train.ipynb index 39b00d423..16adca19b 100644 --- a/tutorials/hypergraph/hmpnn_train.ipynb +++ b/tutorials/hypergraph/hmpnn_train.ipynb @@ -25,9 +25,8 @@ "outputs": [], "source": [ "import torch\n", - "import numpy as np\n", - "from torch_geometric.utils import to_undirected\n", "import torch_geometric.datasets as geom_datasets\n", + "from sklearn.metrics import accuracy_score\n", "\n", "from topomodelx.nn.hypergraph.hmpnn import HMPNN" ] @@ -77,140 +76,28 @@ "cell_type": "code", "execution_count": 3, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/usr/local/lib/python3.11/site-packages/torch_geometric/data/in_memory_dataset.py:284: UserWarning: It is not recommended to directly access the internal storage format `data` of an 'InMemoryDataset'. If you are absolutely certain what you are doing, access the internal storage via `InMemoryDataset._data` instead to suppress this warning. Alternatively, you can access stacked individual attributes of every graph via `dataset.{attr_name}`.\n", - " warnings.warn(msg)\n" - ] - } - ], - "source": [ - "cora = geom_datasets.Planetoid(root=\"/TopoModelX/data/cora\", name=\"Cora\")\n", - "data = cora.data\n", - "\n", - "x_0s = data.x\n", - "y = data.y\n", - "edge_index = data.edge_index\n", - "\n", - "train_mask = data.train_mask\n", - "val_mask = data.val_mask\n", - "test_mask = data.test_mask" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Define neighborhood structures and lift into hypergraph domain. ##\n", - "\n", - "Now we retrieve the neighborhood structure (i.e. their representative matrice) that we will use to send messges from node to hyperedges. In the case of this architecture, we need the boundary matrix (or incidence matrix) $B_1$ with shape $n_\\text{nodes} \\times n_\\text{edges}$.\n", - "\n", - "In citation Cora dataset we lift graph structure to the hypergraph domain by creating hyperedges from 1-hop graph neighbourhood of each node. \n" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, "outputs": [], "source": [ - "# Ensure the graph is undirected (optional but often useful for one-hop neighborhoods).\n", - "edge_index = to_undirected(edge_index)\n", - "\n", - "# Create a list of one-hop neighborhoods for each node.\n", - "one_hop_neighborhoods = []\n", - "for node in range(data.num_nodes):\n", - " # Get the one-hop neighbors of the current node.\n", - " neighbors = data.edge_index[1, data.edge_index[0] == node]\n", - "\n", - " # Append the neighbors to the list of one-hop neighborhoods.\n", - " one_hop_neighborhoods.append(neighbors.numpy())\n", - "\n", - "# Detect and eliminate duplicate hyperedges.\n", - "unique_hyperedges = set()\n", - "hyperedges = []\n", - "for neighborhood in one_hop_neighborhoods:\n", - " # Sort the neighborhood to ensure consistent comparison.\n", - " neighborhood = tuple(sorted(neighborhood))\n", - " if neighborhood not in unique_hyperedges:\n", - " hyperedges.append(list(neighborhood))\n", - " unique_hyperedges.add(neighborhood) " + "dataset = geom_datasets.Planetoid(root=\"/TopoModelX/data/cora\", name=\"Cora\")[0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Additionally we print the statictis associated with obtained incidence matrix" + "Below, we construct the incidence matrix ($B_1$) which is of shape $n_\\text{nodes} \\times n_\\text{edges}$." ] }, { "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Hyperedge statistics: \n", - "Number of hyperedges without duplicated hyperedges 2581\n", - "min = 1, \n", - "max = 168, \n", - "mean = 4.003099573808601, \n", - "median = 3.0, \n", - "std = 5.327622607829558, \n", - "Number of hyperedges with size equal to one = 412\n" - ] - } - ], - "source": [ - "\n", - "# Calculate hyperedge statistics.\n", - "hyperedge_sizes = [len(he) for he in hyperedges]\n", - "min_size = min(hyperedge_sizes)\n", - "max_size = max(hyperedge_sizes)\n", - "mean_size = np.mean(hyperedge_sizes)\n", - "median_size = np.median(hyperedge_sizes)\n", - "std_size = np.std(hyperedge_sizes)\n", - "num_single_node_hyperedges = sum(np.array(hyperedge_sizes) == 1)\n", - "\n", - "# Print the hyperedge statistics.\n", - "print(f'Hyperedge statistics: ')\n", - "print('Number of hyperedges without duplicated hyperedges', len(hyperedges))\n", - "print(f'min = {min_size}, ')\n", - "print(f'max = {max_size}, ')\n", - "print(f'mean = {mean_size}, ')\n", - "print(f'median = {median_size}, ')\n", - "print(f'std = {std_size}, ')\n", - "print(f'Number of hyperedges with size equal to one = {num_single_node_hyperedges}')\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Construct incidence matrix" - ] - }, - { - "cell_type": "code", - "execution_count": 6, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ - "max_edges = len(hyperedges)\n", - "incidence_1 = np.zeros((x_0s.shape[0], max_edges))\n", - "for col, neighibourhood in enumerate(hyperedges):\n", - " for row in neighibourhood:\n", - " incidence_1[row, col] = 1\n", - "\n", - "assert all(incidence_1.sum(0)>0) == True, \"Some hyperedges are empty\"\n", - "assert all(incidence_1.sum(1)>0) == True, \"Some nodes are not in any hyperedges\"\n", - "incidence_1 = torch.Tensor(incidence_1).to_sparse_coo()" + "dataset[\"incidence_1\"] = torch.sparse_coo_tensor(\n", + " dataset[\"edge_index\"], torch.ones(dataset[\"edge_index\"].shape[1]), dtype=torch.long\n", + ")\n", + "dataset = dataset.to(device)" ] }, { @@ -225,7 +112,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 5, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:58.153514385Z", @@ -234,29 +121,27 @@ }, "outputs": [], "source": [ - "torch.manual_seed(0)\n", - "\n", - "# in_channels = x_0s.shape[1]\n", - "# hidden_channels = 64\n", - "# out_channels = torch.unique(y).shape[0]\n", - "# task_level = \"graph\" if out_channels==1 else \"node\"\n", - "\n", + "torch.manual_seed(41)\n", "\n", "in_features = 1433\n", "hidden_features = 8\n", "num_classes = 7\n", - "n_layers = 2\n", - "\n", - "model = HMPNN(in_features, \n", - " (256, hidden_features), num_classes, n_layers).to(device)\n", + "n_layers = 1\n", "\n", + "model = HMPNN(in_features, (256, hidden_features), num_classes, n_layers).to(device)\n", "optimizer = torch.optim.Adam(model.parameters(), lr=0.01)\n", - "\n", - "# Categorial cross-entropy loss\n", "loss_fn = torch.nn.CrossEntropyLoss()\n", "\n", - "# Accuracy\n", - "acc_fn = lambda y, y_hat: (y == y_hat).float().mean()" + "\n", + "\n", + "train_mask = dataset[\"train_mask\"]\n", + "val_mask = dataset[\"val_mask\"]\n", + "test_mask = dataset[\"test_mask\"]\n", + "\n", + "\n", + "x = dataset[\"x\"]\n", + "y = dataset[\"y\"]\n", + "incidence_1 = dataset[\"incidence_1\"]" ] }, { @@ -269,7 +154,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 6, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:15:01.683216142Z", @@ -278,83 +163,73 @@ }, "outputs": [ { - "ename": "RuntimeError", - "evalue": "Sizes of tensors must match except in dimension 1. Expected size 2708 but got size 2581 for tensor number 1 in the list.", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)", - "\u001b[1;32m/TopoModelX/tutorials/hypergraph/hmpnn_train.ipynb Cell 16\u001b[0m line \u001b[0;36m7\n\u001b[1;32m 5\u001b[0m model\u001b[39m.\u001b[39mtrain()\n\u001b[1;32m 6\u001b[0m optimizer\u001b[39m.\u001b[39mzero_grad()\n\u001b[0;32m----> 7\u001b[0m y_hat \u001b[39m=\u001b[39m model(x_0s, initial_x_1, incidence_1)\n\u001b[1;32m 8\u001b[0m loss \u001b[39m=\u001b[39m loss_fn(y_pred_logits[train_mask], y[train_mask])\n\u001b[1;32m 9\u001b[0m loss\u001b[39m.\u001b[39mbackward()\n", - "File \u001b[0;32m/usr/local/lib/python3.11/site-packages/torch/nn/modules/module.py:1501\u001b[0m, in \u001b[0;36mModule._call_impl\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1496\u001b[0m \u001b[39m# If we don't have any hooks, we want to skip the rest of the logic in\u001b[39;00m\n\u001b[1;32m 1497\u001b[0m \u001b[39m# this function, and just call forward.\u001b[39;00m\n\u001b[1;32m 1498\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m (\u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_backward_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_backward_pre_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_forward_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_forward_pre_hooks\n\u001b[1;32m 1499\u001b[0m \u001b[39mor\u001b[39;00m _global_backward_pre_hooks \u001b[39mor\u001b[39;00m _global_backward_hooks\n\u001b[1;32m 1500\u001b[0m \u001b[39mor\u001b[39;00m _global_forward_hooks \u001b[39mor\u001b[39;00m _global_forward_pre_hooks):\n\u001b[0;32m-> 1501\u001b[0m \u001b[39mreturn\u001b[39;00m forward_call(\u001b[39m*\u001b[39;49margs, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n\u001b[1;32m 1502\u001b[0m \u001b[39m# Do not call functions when jit is used\u001b[39;00m\n\u001b[1;32m 1503\u001b[0m full_backward_hooks, non_full_backward_hooks \u001b[39m=\u001b[39m [], []\n", - "File \u001b[0;32m/TopoModelX/topomodelx/nn/hypergraph/hmpnn.py:87\u001b[0m, in \u001b[0;36mHMPNN.forward\u001b[0;34m(self, x_0, x_1, incidence_1)\u001b[0m\n\u001b[1;32m 85\u001b[0m x_1 \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mto_hidden_linear(x_1)\n\u001b[1;32m 86\u001b[0m \u001b[39mfor\u001b[39;00m layer \u001b[39min\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mlayers:\n\u001b[0;32m---> 87\u001b[0m x_0, x_1 \u001b[39m=\u001b[39m layer(x_0, x_1, incidence_1)\n\u001b[1;32m 89\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mto_categories_linear(x_0)\n", - "File \u001b[0;32m/usr/local/lib/python3.11/site-packages/torch/nn/modules/module.py:1501\u001b[0m, in \u001b[0;36mModule._call_impl\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1496\u001b[0m \u001b[39m# If we don't have any hooks, we want to skip the rest of the logic in\u001b[39;00m\n\u001b[1;32m 1497\u001b[0m \u001b[39m# this function, and just call forward.\u001b[39;00m\n\u001b[1;32m 1498\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m (\u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_backward_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_backward_pre_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_forward_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_forward_pre_hooks\n\u001b[1;32m 1499\u001b[0m \u001b[39mor\u001b[39;00m _global_backward_pre_hooks \u001b[39mor\u001b[39;00m _global_backward_hooks\n\u001b[1;32m 1500\u001b[0m \u001b[39mor\u001b[39;00m _global_forward_hooks \u001b[39mor\u001b[39;00m _global_forward_pre_hooks):\n\u001b[0;32m-> 1501\u001b[0m \u001b[39mreturn\u001b[39;00m forward_call(\u001b[39m*\u001b[39;49margs, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n\u001b[1;32m 1502\u001b[0m \u001b[39m# Do not call functions when jit is used\u001b[39;00m\n\u001b[1;32m 1503\u001b[0m full_backward_hooks, non_full_backward_hooks \u001b[39m=\u001b[39m [], []\n", - "File \u001b[0;32m/TopoModelX/topomodelx/nn/hypergraph/hmpnn_layer.py:224\u001b[0m, in \u001b[0;36mHMPNNLayer.forward\u001b[0;34m(self, x_0, x_1, incidence_1)\u001b[0m\n\u001b[1;32m 203\u001b[0m \u001b[39m\u001b[39m\u001b[39mr\u001b[39m\u001b[39m\"\"\"Forward computation.\u001b[39;00m\n\u001b[1;32m 204\u001b[0m \n\u001b[1;32m 205\u001b[0m \u001b[39mParameters\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 219\u001b[0m \u001b[39m Output features of the hyperedges.\u001b[39;00m\n\u001b[1;32m 220\u001b[0m \u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m 221\u001b[0m node_messages_aggregated, node_messages \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mnode_to_hyperedge_messenger(\n\u001b[1;32m 222\u001b[0m x_0, incidence_1\n\u001b[1;32m 223\u001b[0m )\n\u001b[0;32m--> 224\u001b[0m hyperedge_messages_aggregated \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mhyperedge_to_node_messenger(\n\u001b[1;32m 225\u001b[0m x_1, incidence_1, node_messages\n\u001b[1;32m 226\u001b[0m )\n\u001b[1;32m 228\u001b[0m x_0 \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mupdating_func(\n\u001b[1;32m 229\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mapply_regular_dropout(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mnode_batchnorm(x_0)),\n\u001b[1;32m 230\u001b[0m hyperedge_messages_aggregated,\n\u001b[1;32m 231\u001b[0m )\n\u001b[1;32m 232\u001b[0m x_1 \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mupdating_func(\n\u001b[1;32m 233\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mapply_regular_dropout(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mhyperedge_batchnorm(x_1)),\n\u001b[1;32m 234\u001b[0m node_messages_aggregated,\n\u001b[1;32m 235\u001b[0m )\n", - "File \u001b[0;32m/usr/local/lib/python3.11/site-packages/torch/nn/modules/module.py:1501\u001b[0m, in \u001b[0;36mModule._call_impl\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1496\u001b[0m \u001b[39m# If we don't have any hooks, we want to skip the rest of the logic in\u001b[39;00m\n\u001b[1;32m 1497\u001b[0m \u001b[39m# this function, and just call forward.\u001b[39;00m\n\u001b[1;32m 1498\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m (\u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_backward_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_backward_pre_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_forward_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_forward_pre_hooks\n\u001b[1;32m 1499\u001b[0m \u001b[39mor\u001b[39;00m _global_backward_pre_hooks \u001b[39mor\u001b[39;00m _global_backward_hooks\n\u001b[1;32m 1500\u001b[0m \u001b[39mor\u001b[39;00m _global_forward_hooks \u001b[39mor\u001b[39;00m _global_forward_pre_hooks):\n\u001b[0;32m-> 1501\u001b[0m \u001b[39mreturn\u001b[39;00m forward_call(\u001b[39m*\u001b[39;49margs, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n\u001b[1;32m 1502\u001b[0m \u001b[39m# Do not call functions when jit is used\u001b[39;00m\n\u001b[1;32m 1503\u001b[0m full_backward_hooks, non_full_backward_hooks \u001b[39m=\u001b[39m [], []\n", - "File \u001b[0;32m/TopoModelX/topomodelx/nn/hypergraph/hmpnn_layer.py:74\u001b[0m, in \u001b[0;36m_HyperedgeToNodeMessenger.forward\u001b[0;34m(self, x_source, neighborhood, node_messages)\u001b[0m\n\u001b[1;32m 73\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mforward\u001b[39m(\u001b[39mself\u001b[39m, x_source, neighborhood, node_messages):\n\u001b[0;32m---> 74\u001b[0m x_message \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mmessage(x_source, neighborhood, node_messages)\n\u001b[1;32m 76\u001b[0m neighborhood \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mapply_dropout(neighborhood, \u001b[39mself\u001b[39m\u001b[39m.\u001b[39madjacency_dropout)\n\u001b[1;32m 77\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mtarget_index_i, source_index_j \u001b[39m=\u001b[39m neighborhood\u001b[39m.\u001b[39mindices()\n", - "File \u001b[0;32m/TopoModelX/topomodelx/nn/hypergraph/hmpnn_layer.py:71\u001b[0m, in \u001b[0;36m_HyperedgeToNodeMessenger.message\u001b[0;34m(self, x_source, neighborhood, node_messages)\u001b[0m\n\u001b[1;32m 66\u001b[0m source_index_j, target_index_i \u001b[39m=\u001b[39m hyperedge_neighborhood\u001b[39m.\u001b[39mindices()\n\u001b[1;32m 67\u001b[0m node_messages_aggregated \u001b[39m=\u001b[39m scatter(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39maggr_func)(\n\u001b[1;32m 68\u001b[0m node_messages\u001b[39m.\u001b[39mindex_select(\u001b[39m-\u001b[39m\u001b[39m2\u001b[39m, source_index_j), target_index_i, \u001b[39m0\u001b[39m\n\u001b[1;32m 69\u001b[0m )\n\u001b[0;32m---> 71\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mmessaging_func(x_source, node_messages_aggregated)\n", - "File \u001b[0;32m/usr/local/lib/python3.11/site-packages/torch/nn/modules/module.py:1501\u001b[0m, in \u001b[0;36mModule._call_impl\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1496\u001b[0m \u001b[39m# If we don't have any hooks, we want to skip the rest of the logic in\u001b[39;00m\n\u001b[1;32m 1497\u001b[0m \u001b[39m# this function, and just call forward.\u001b[39;00m\n\u001b[1;32m 1498\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m (\u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_backward_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_backward_pre_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_forward_hooks \u001b[39mor\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_forward_pre_hooks\n\u001b[1;32m 1499\u001b[0m \u001b[39mor\u001b[39;00m _global_backward_pre_hooks \u001b[39mor\u001b[39;00m _global_backward_hooks\n\u001b[1;32m 1500\u001b[0m \u001b[39mor\u001b[39;00m _global_forward_hooks \u001b[39mor\u001b[39;00m _global_forward_pre_hooks):\n\u001b[0;32m-> 1501\u001b[0m \u001b[39mreturn\u001b[39;00m forward_call(\u001b[39m*\u001b[39;49margs, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n\u001b[1;32m 1502\u001b[0m \u001b[39m# Do not call functions when jit is used\u001b[39;00m\n\u001b[1;32m 1503\u001b[0m full_backward_hooks, non_full_backward_hooks \u001b[39m=\u001b[39m [], []\n", - "File \u001b[0;32m/TopoModelX/topomodelx/nn/hypergraph/hmpnn_layer.py:91\u001b[0m, in \u001b[0;36m_DefaultHyperedgeToNodeMessagingFunc.forward\u001b[0;34m(self, x_1, m_0)\u001b[0m\n\u001b[1;32m 90\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mforward\u001b[39m(\u001b[39mself\u001b[39m, x_1, m_0):\n\u001b[0;32m---> 91\u001b[0m \u001b[39mreturn\u001b[39;00m F\u001b[39m.\u001b[39msigmoid(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mlinear(torch\u001b[39m.\u001b[39;49mcat((x_1, m_0), dim\u001b[39m=\u001b[39;49m\u001b[39m1\u001b[39;49m)))\n", - "\u001b[0;31mRuntimeError\u001b[0m: Sizes of tensors must match except in dimension 1. Expected size 2708 but got size 2581 for tensor number 1 in the list." + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch: 6 train loss: 1.7054 train acc: 0.63 val loss: 1.8855 val acc: 0.34test loss: 0.3410 val acc: 0.34\n", + "Epoch: 11 train loss: 1.6260 train acc: 0.69 val loss: 1.8205 val acc: 0.32test loss: 0.3380 val acc: 0.34\n", + "Epoch: 16 train loss: 1.5252 train acc: 0.79 val loss: 1.7742 val acc: 0.35test loss: 0.3920 val acc: 0.39\n", + "Epoch: 21 train loss: 1.4274 train acc: 0.85 val loss: 1.7526 val acc: 0.35test loss: 0.3850 val acc: 0.39\n", + "Epoch: 26 train loss: 1.3159 train acc: 0.83 val loss: 1.7416 val acc: 0.36test loss: 0.3850 val acc: 0.39\n", + "Epoch: 31 train loss: 1.2421 train acc: 0.84 val loss: 1.6929 val acc: 0.39test loss: 0.4150 val acc: 0.41\n", + "Epoch: 36 train loss: 1.1510 train acc: 0.91 val loss: 1.6686 val acc: 0.41test loss: 0.4340 val acc: 0.43\n", + "Epoch: 41 train loss: 1.0704 train acc: 0.91 val loss: 1.5701 val acc: 0.49test loss: 0.4900 val acc: 0.49\n", + "Epoch: 46 train loss: 0.9775 train acc: 0.90 val loss: 1.5366 val acc: 0.50test loss: 0.5130 val acc: 0.51\n", + "Epoch: 51 train loss: 0.9132 train acc: 0.90 val loss: 1.4844 val acc: 0.53test loss: 0.5420 val acc: 0.54\n", + "Epoch: 56 train loss: 0.8477 train acc: 0.96 val loss: 1.4231 val acc: 0.55test loss: 0.5600 val acc: 0.56\n", + "Epoch: 61 train loss: 0.7438 train acc: 0.97 val loss: 1.3804 val acc: 0.56test loss: 0.5830 val acc: 0.58\n", + "Epoch: 66 train loss: 0.7040 train acc: 0.98 val loss: 1.3221 val acc: 0.59test loss: 0.6090 val acc: 0.61\n", + "Epoch: 71 train loss: 0.6370 train acc: 0.98 val loss: 1.3007 val acc: 0.59test loss: 0.6100 val acc: 0.61\n", + "Epoch: 76 train loss: 0.5892 train acc: 0.98 val loss: 1.2758 val acc: 0.62test loss: 0.6180 val acc: 0.62\n", + "Epoch: 81 train loss: 0.5556 train acc: 0.99 val loss: 1.2795 val acc: 0.59test loss: 0.6190 val acc: 0.62\n", + "Epoch: 86 train loss: 0.5107 train acc: 0.98 val loss: 1.2930 val acc: 0.59test loss: 0.6100 val acc: 0.61\n", + "Epoch: 91 train loss: 0.4772 train acc: 0.99 val loss: 1.2791 val acc: 0.59test loss: 0.6110 val acc: 0.61\n", + "Epoch: 96 train loss: 0.4572 train acc: 1.00 val loss: 1.2993 val acc: 0.59test loss: 0.6060 val acc: 0.61\n", + "Epoch: 101 train loss: 0.3808 train acc: 1.00 val loss: 1.3041 val acc: 0.59test loss: 0.6120 val acc: 0.61\n" ] } ], "source": [ + "torch.manual_seed(0)\n", + "test_interval = 5\n", + "num_epochs=100\n", "\n", - "initial_x_1 = torch.zeros_like(x_0s)\n", "\n", - "for epoch in range(100):\n", + "initial_x_1 = torch.zeros_like(x)\n", + "for epoch in range(1, num_epochs + 1):\n", " model.train()\n", " optimizer.zero_grad()\n", - " y_hat = model(x_0s, initial_x_1, incidence_1)\n", - " loss = loss_fn(y_pred_logits[train_mask], y[train_mask])\n", + " y_hat = model(x, initial_x_1, incidence_1)\n", + " loss = loss_fn(y_hat[train_mask], y[train_mask])\n", " loss.backward()\n", " optimizer.step()\n", "\n", " train_loss = loss.item()\n", - " train_acc = acc_fn(y_hat[train_mask].argmax(1), y[train_mask])\n", + " y_pred = y_hat.argmax(dim=-1)\n", + " train_acc = accuracy_score(y[train_mask], y_pred[train_mask])\n", + " \n", + " if epoch % test_interval == 0:\n", + " model.eval()\n", + " \n", + " y_hat = model(x, initial_x_1, incidence_1)\n", + " val_loss = loss_fn(y_hat[val_mask], y[val_mask]).item()\n", + " y_pred = y_hat.argmax(dim=-1)\n", + " val_acc = accuracy_score(y[val_mask], y_pred[val_mask])\n", "\n", - " model.eval()\n", - " with torch.no_grad():\n", - " y_pred_logits = model(dataset[\"x\"], initial_x_1, dataset[\"incidence_1\"])\n", - " val_loss = loss_fn(y_pred_logits[dataset[\"val_mask\"]], val_y_true).item()\n", - " y_pred = y_pred_logits.argmax(dim=-1)\n", - " val_acc = accuracy_score(val_y_true, y_pred[dataset[\"val_mask\"]])\n", - " print(\n", - " f\"Epoch: {epoch + 1} train loss: {train_loss:.4f} train acc: {train_acc:.2f} \"\n", - " f\"val loss: {val_loss:.4f} val acc: {val_acc:.2f}\"\n", - " )" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Finally, we evaluate the model against the test data." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Test loss: 1.3152 test acc: 0.55 \n" - ] - } - ], - "source": [ - "test_y_true = dataset[\"y\"][dataset[\"test_mask\"]]\n", - "initial_x_1 = torch.zeros_like(dataset[\"x\"])\n", - "model.eval()\n", - "with torch.no_grad():\n", - " y_pred_logits = model(dataset[\"x\"], initial_x_1, dataset[\"incidence_1\"])\n", - "test_loss = loss_fn(y_pred_logits[dataset[\"test_mask\"]], test_y_true).item()\n", - "y_pred = y_pred_logits.argmax(dim=-1)\n", - "test_acc = accuracy_score(test_y_true, y_pred[dataset[\"test_mask\"]])\n", - "print(f\"Test loss: {test_loss:.4f} test acc: {test_acc:.2f} \")" + "\n", + " test_loss = loss_fn(y_hat[test_mask], y[test_mask]).item()\n", + " y_pred = y_hat.argmax(dim=-1)\n", + " test_acc = accuracy_score(y[test_mask], y_pred[test_mask])\n", + " print(\n", + " f\"Epoch: {epoch + 1} train loss: {train_loss:.4f} train acc: {train_acc:.2f} \"\n", + " f\"val loss: {val_loss:.4f} val acc: {val_acc:.2f}\"\n", + " f\"test loss: {test_acc:.4f} val acc: {test_acc:.2f}\"\n", + " )\n", + "\n", + " \n", + "\n", + " \n", + " " ] } ], diff --git a/tutorials/simplicial/hsn_train.ipynb b/tutorials/simplicial/hsn_train.ipynb index 1beb10d32..d355ea08d 100644 --- a/tutorials/simplicial/hsn_train.ipynb +++ b/tutorials/simplicial/hsn_train.ipynb @@ -33,7 +33,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -61,7 +61,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 2, "metadata": {}, "outputs": [ { @@ -88,7 +88,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 3, "metadata": {}, "outputs": [ { @@ -122,7 +122,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ diff --git a/tutorials/simplicial/sca_cmps_train.ipynb b/tutorials/simplicial/sca_cmps_train.ipynb index b9df4cba8..3c19b5fd5 100644 --- a/tutorials/simplicial/sca_cmps_train.ipynb +++ b/tutorials/simplicial/sca_cmps_train.ipynb @@ -24,7 +24,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -47,7 +47,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 2, "metadata": {}, "outputs": [ { @@ -80,7 +80,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 3, "metadata": {}, "outputs": [ { @@ -107,7 +107,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -145,7 +145,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -182,7 +182,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -193,7 +193,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -202,7 +202,7 @@ "(100,)" ] }, - "execution_count": 19, + "execution_count": 7, "metadata": {}, "output_type": "execute_result" } @@ -220,7 +220,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -229,7 +229,7 @@ "(80,)" ] }, - "execution_count": 20, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -267,7 +267,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -282,6 +282,13 @@ "opt = torch.optim.Adam(model.parameters(), lr=0.1)\n", "loss_fn = torch.nn.MSELoss()" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { From eb524d97c03d1afa5c1a07c34172d4907db24c39 Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Mon, 30 Oct 2023 16:50:35 +0000 Subject: [PATCH 03/39] template --- tutorials/hypergraph/allset_train.ipynb | 1 + 1 file changed, 1 insertion(+) diff --git a/tutorials/hypergraph/allset_train.ipynb b/tutorials/hypergraph/allset_train.ipynb index b27e1c695..db32dc1ec 100644 --- a/tutorials/hypergraph/allset_train.ipynb +++ b/tutorials/hypergraph/allset_train.ipynb @@ -52,6 +52,7 @@ "used for solving certain types of problems.\n", "\n", "Author: Your Name\n", + "\n", "\"\"\"\n", "\n", "import torch\n", From 81e8f747d9bbe19f12807fc09df91d85def09221 Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Tue, 31 Oct 2023 14:22:56 +0000 Subject: [PATCH 04/39] 7/10 --- test/nn/hypergraph/test_dhgcn.py | 2 +- topomodelx/nn/hypergraph/allset.py | 9 +- topomodelx/nn/hypergraph/allset_layer.py | 1 + .../nn/hypergraph/allset_transformer.py | 3 + topomodelx/nn/hypergraph/dhgcn.py | 42 +- topomodelx/nn/hypergraph/unigcn.py | 43 +- topomodelx/nn/hypergraph/unigcn_layer.py | 24 +- topomodelx/nn/hypergraph/unigcnii.py | 78 +- topomodelx/nn/hypergraph/unigcnii_layer.py | 15 +- topomodelx/nn/hypergraph/unigin.py | 59 +- topomodelx/nn/hypergraph/unigin_layer.py | 13 +- topomodelx/nn/hypergraph/unisage.py | 71 +- tutorials/hypergraph/allset_train.ipynb | 102 +- .../hypergraph/allset_transformer_train.ipynb | 66 +- tutorials/hypergraph/dhgcn_train.ipynb | 45 +- tutorials/hypergraph/hmpnn_train.ipynb | 109 +- tutorials/hypergraph/unigcn_train.ipynb | 1059 +---------------- tutorials/hypergraph/unigcnii_train.ipynb | 166 +-- tutorials/hypergraph/unigin_train.ipynb | 169 +-- tutorials/hypergraph/unisage_train.ipynb | 433 ++++--- 20 files changed, 918 insertions(+), 1591 deletions(-) diff --git a/test/nn/hypergraph/test_dhgcn.py b/test/nn/hypergraph/test_dhgcn.py index 0e22d1b73..ccf1aa158 100644 --- a/test/nn/hypergraph/test_dhgcn.py +++ b/test/nn/hypergraph/test_dhgcn.py @@ -11,7 +11,7 @@ class TestDHGCNL: def test_forward(self): """Test forward method.""" # device = torch.device("cuda" if torch.cuda.is_available() else "cpu") - model = DHGCN(channels_node=8, n_layers=2) + model = DHGCN(channels_node=8, hidden_channels=8, n_layers=2) x_0 = torch.rand(8, 8) diff --git a/topomodelx/nn/hypergraph/allset.py b/topomodelx/nn/hypergraph/allset.py index 8fb77bde9..a277282e4 100644 --- a/topomodelx/nn/hypergraph/allset.py +++ b/topomodelx/nn/hypergraph/allset.py @@ -12,11 +12,11 @@ class AllSet(torch.nn.Module): Parameters ---------- - in_dim : int + in_channels : int Dimension of the input features. - hid_dim : int + hidden_channels : int Dimension of the hidden features. - out_dim : int + out_channels : int Dimension of the output features. dropout : float Dropout probability. @@ -28,6 +28,9 @@ class AllSet(torch.nn.Module): Number of layers in the MLP. mlp_norm : bool, default: False Whether to apply input normalization in the MLP. + task_level: str, default="graph" + Level of the task. Either "graph" or "node". + If "graph", the output is pooled over all nodes in the hypergraph. References ---------- diff --git a/topomodelx/nn/hypergraph/allset_layer.py b/topomodelx/nn/hypergraph/allset_layer.py index 32eb2e9ed..c83f14038 100644 --- a/topomodelx/nn/hypergraph/allset_layer.py +++ b/topomodelx/nn/hypergraph/allset_layer.py @@ -26,6 +26,7 @@ class AllSetLayer(nn.Module): Dropout probability in the MLP. mlp_norm : str or None, optional Type of layer normalization in the MLP. + References ---------- diff --git a/topomodelx/nn/hypergraph/allset_transformer.py b/topomodelx/nn/hypergraph/allset_transformer.py index ad5960c9c..d6dbeda8b 100644 --- a/topomodelx/nn/hypergraph/allset_transformer.py +++ b/topomodelx/nn/hypergraph/allset_transformer.py @@ -28,6 +28,9 @@ class AllSetTransformer(torch.nn.Module): Number of layers in the MLP. mlp_norm : bool, optional. default: False Whether to apply input normalization in the MLP. + task_level: str, default="graph" + Level of the task. Either "graph" or "node". + If "graph", the output is pooled over all nodes in the hypergraph. References ---------- diff --git a/topomodelx/nn/hypergraph/dhgcn.py b/topomodelx/nn/hypergraph/dhgcn.py index 44ae63646..6652de8af 100644 --- a/topomodelx/nn/hypergraph/dhgcn.py +++ b/topomodelx/nn/hypergraph/dhgcn.py @@ -18,6 +18,9 @@ class DHGCN(torch.nn.Module): Dimension of node features n_layer : int, default = 2 Amount of message passing layers. + task_level: str, default="graph" + Level of the task. Either "graph" or "node". + If "graph", the output is pooled over all nodes in the hypergraph. References ---------- @@ -26,19 +29,35 @@ class DHGCN(torch.nn.Module): https://ieeexplore.ieee.org/abstract/document/9835240 """ - def __init__(self, channels_node, n_layers=2): + def __init__( + self, + in_channels, + hidden_channels, + out_channels, + n_layers=1, + task_level="graph" + ): super().__init__() layers = [] - for _ in range(n_layers): + layers.append( + DHGCNLayer( + in_channels=in_channels, + intermediate_channels=hidden_channels, + out_channels=hidden_channels, + ) + ) + for _ in range(n_layers - 1): layers.append( DHGCNLayer( - in_channels=channels_node, - intermediate_channels=channels_node, - out_channels=channels_node, + in_channels=hidden_channels, + intermediate_channels=hidden_channels, + out_channels=hidden_channels, ) ) self.layers = torch.nn.ModuleList(layers) - self.linear = torch.nn.Linear(channels_node, 1) + self.linear = torch.nn.Linear(hidden_channels, out_channels) + self.out_pool = True if task_level == "graph" else False + def forward(self, x_0): """Forward computation through layers, then global average pooling, then linear layer. @@ -55,6 +74,11 @@ def forward(self, x_0): """ for layer in self.layers: x_0 = layer(x_0) - pooled_x = torch.mean(x_0, dim=0) - output = self.linear(pooled_x) - return output[0] + + # Pool over all nodes in the hypergraph + if self.out_pool is True: + x = torch.max(x_0, dim=0)[0] + else: + x = x_0 + + return self.linear(x) diff --git a/topomodelx/nn/hypergraph/unigcn.py b/topomodelx/nn/hypergraph/unigcn.py index 600bd5dc9..a76a79427 100644 --- a/topomodelx/nn/hypergraph/unigcn.py +++ b/topomodelx/nn/hypergraph/unigcn.py @@ -10,10 +10,12 @@ class UniGCN(torch.nn.Module): Parameters ---------- - channels_edge : int - Dimension of edge features - channels_node : int - Dimension of node features + in_channels : int + Dimension of the input features. + hidden_channels : int + Dimension of the hidden features. + out_channels : int + Dimension of the output features. n_layer : int, default = 2 Amount of message passing layers. @@ -25,18 +27,31 @@ class UniGCN(torch.nn.Module): https://arxiv.org/pdf/2105.00956.pdf """ - def __init__(self, channels_edge, channels_node, n_layers=2): + def __init__(self, + in_channels, + hidden_channels, + out_channels, + n_layers=2, + task_level="graph", + ): super().__init__() layers = [] - for _ in range(n_layers): + layers.append( + UniGCNLayer( + in_channels=in_channels, + hidden_channels=hidden_channels, + ) + ) + for _ in range(n_layers - 1): layers.append( UniGCNLayer( - in_channels=channels_edge, - out_channels=channels_edge, + in_channels=hidden_channels, + hidden_channels=hidden_channels, ) ) self.layers = torch.nn.ModuleList(layers) - self.linear = torch.nn.Linear(channels_edge, 1) + self.linear = torch.nn.Linear(hidden_channels, out_channels) + self.out_pool = True if task_level == "graph" else False def forward(self, x_1, incidence_1): """Forward computation through layers, then linear layer, then global max pooling. @@ -56,5 +71,11 @@ def forward(self, x_1, incidence_1): """ for layer in self.layers: x_1 = layer(x_1, incidence_1) - pooled_x = torch.max(x_1, dim=0)[0] - return torch.sigmoid(self.linear(pooled_x)) + + # Pool over all nodes in the hypergraph + if self.out_pool is True: + x = torch.max(x_1, dim=0)[0] + else: + x = x_1 + + return self.linear(x) diff --git a/topomodelx/nn/hypergraph/unigcn_layer.py b/topomodelx/nn/hypergraph/unigcn_layer.py index ad45bc6f1..fd254768b 100644 --- a/topomodelx/nn/hypergraph/unigcn_layer.py +++ b/topomodelx/nn/hypergraph/unigcn_layer.py @@ -14,9 +14,9 @@ class UniGCNLayer(torch.nn.Module): Parameters ---------- in_channels : int - Dimension of input features. - out_channels : int - Dimension of output features. + Dimension of the input features. + hidden_channels : int + Dimension of the hidden features. use_bn : boolean Whether to use bathnorm after the linear transformation. aggr_norm: boolean @@ -37,21 +37,25 @@ class UniGCNLayer(torch.nn.Module): """ def __init__( - self, in_channels, out_channels, aggr_norm: bool = False, use_bn: bool = False + self, + in_channels, + hidden_channels, + aggr_norm: bool = False, + use_bn: bool = False ) -> None: super().__init__() - self.in_channels = in_channels - self.out_channels = out_channels + + with_linear_transform = False if in_channels == hidden_channels else True self.conv_level1_0_to_1 = Conv( in_channels=in_channels, - out_channels=in_channels, + out_channels=hidden_channels, aggr_norm=aggr_norm, update_func=None, - with_linear_transform=False, + with_linear_transform=with_linear_transform, ) self.conv_level2_1_to_0 = Conv( - in_channels=in_channels, - out_channels=out_channels, + in_channels=hidden_channels, + out_channels=hidden_channels, aggr_norm=aggr_norm, update_func=None, ) diff --git a/topomodelx/nn/hypergraph/unigcnii.py b/topomodelx/nn/hypergraph/unigcnii.py index 0dea89266..3f088eecc 100644 --- a/topomodelx/nn/hypergraph/unigcnii.py +++ b/topomodelx/nn/hypergraph/unigcnii.py @@ -1,7 +1,7 @@ """UniGCNII class.""" import torch - +import math from topomodelx.nn.hypergraph.unigcnii_layer import UniGCNIILayer @@ -10,16 +10,26 @@ class UniGCNII(torch.nn.Module): Parameters ---------- - num_classes: int, default=2 - Number of classes used for node classification. - in_features: int, default=1 - Number of input features on the nodes. + in_channels : int + Dimension of the input features. + hidden_channels : int + Dimension of the hidden features. + out_channels : int + Dimension of the output features. n_layers: int, default=2 Number of UniGCNII message passing layers. alpha: float, default=0.5 Parameter of the UniGCNII layer. beta: float, default=0.5 Parameter of the UniGCNII layer. + input_drop: float, default=0.2 + Dropout rate for the input features. + layer_drop: float, default=0.2 + Dropout rate for the hidden features. + task_level: str, default="graph" + Level of the task. Either "graph" or "node". + If "graph", the output is pooled over all nodes in the hypergraph. + References ---------- @@ -29,19 +39,41 @@ class UniGCNII(torch.nn.Module): https://arxiv.org/pdf/2105.00956.pdf """ - def __init__(self, num_classes=2, in_features=1, num_layers=2, alpha=0.5, beta=0.5): + def __init__( + self, + in_channels, + hidden_channels, + out_channels, + n_layers=2, + alpha=0.5, + beta=0.5, + input_drop=0.2, + layer_drop=0.2, + task_level="graph", + ): super().__init__() layers = [] - self.num_features = in_features - self.num_classes = num_classes - - for _ in range(num_layers): + + self.input_drop = torch.nn.Dropout(input_drop) + self.layer_drop = torch.nn.Dropout(layer_drop) + # Define initial linear layer + self.linear_init = torch.nn.Linear(in_channels, hidden_channels) + + + # Define convolutional layers + for i in range(n_layers): + beta = math.log(alpha/(i+1)+1) layers.append( - UniGCNIILayer(in_channels=in_features, alpha=alpha, beta=beta) - ) + UniGCNIILayer( + in_channels=hidden_channels, + hidden_channels=hidden_channels, + alpha=alpha, + beta=beta) + ) self.layers = torch.nn.ModuleList(layers) - self.linear = torch.nn.Linear(self.num_features, self.num_classes) + self.linear = torch.nn.Linear(hidden_channels, out_channels) + self.out_pool = True if task_level == "graph" else False def forward(self, x_0, incidence_1): """Forward pass through the model. @@ -59,12 +91,22 @@ def forward(self, x_0, incidence_1): y_hat : torch.Tensor, shape = (num_nodes, num_classes) Contains the logits for classification for every node. """ - # Copy the original features to use as skip connections - x_0_skip = x_0.clone() + + x_0 = self.input_drop(x_0) + x_0 = self.linear_init(x_0) + x_0 = torch.nn.functional.relu(x_0) + x_0_skip = x_0 for layer in self.layers: x_0 = layer(x_0, incidence_1, x_0_skip) + x_0 = self.layer_drop(x_0) + x_0 = torch.nn.functional.relu(x_0) + + # Pool over all nodes in the hypergraph + if self.out_pool is True: + x = torch.max(x_0, dim=0)[0] + else: + x = x_0 - # linear layer for node classification output - # softmax ommited for use of cross-entropy loss - return self.linear(x_0) + + return self.linear(x) diff --git a/topomodelx/nn/hypergraph/unigcnii_layer.py b/topomodelx/nn/hypergraph/unigcnii_layer.py index 8f5a7a3ef..ad9a23930 100644 --- a/topomodelx/nn/hypergraph/unigcnii_layer.py +++ b/topomodelx/nn/hypergraph/unigcnii_layer.py @@ -8,7 +8,9 @@ class UniGCNIILayer(torch.nn.Module): Parameters ---------- in_channels : int - Number of input channels of the node (rank-0) features. + Dimension of the input features. + hidden_channels : int + Dimension of the hidden features. alpha : float The alpha parameter determining the importance of the self-loop (\theta_2). beta : float @@ -22,13 +24,18 @@ class UniGCNIILayer(torch.nn.Module): https://arxiv.org/pdf/2105.00956.pdf """ - def __init__(self, in_channels, alpha: float, beta: float) -> None: + def __init__( + self, + in_channels, + hidden_channels, + alpha: float, + beta: float + ) -> None: super().__init__() - self.in_channels = in_channels self.alpha = alpha self.beta = beta - self.linear = torch.nn.Linear(in_channels, in_channels, bias=False) + self.linear = torch.nn.Linear(in_channels, hidden_channels, bias=False) def reset_parameters(self) -> None: """Reset the parameters of the layer.""" diff --git a/topomodelx/nn/hypergraph/unigin.py b/topomodelx/nn/hypergraph/unigin.py index 6f084eaad..705da2a29 100644 --- a/topomodelx/nn/hypergraph/unigin.py +++ b/topomodelx/nn/hypergraph/unigin.py @@ -10,10 +10,21 @@ class UniGIN(torch.nn.Module): Parameters ---------- - in_channels_node : int - Dimension of node features + in_channels : int + Dimension of the input features. + hidden_channels : int + Dimension of the hidden features. + out_channels : int + Dimension of the output features. n_layer : int, default = 2 Amount of message passing layers. + input_drop: float, default=0.2 + Dropout rate for the input features. + layer_drop: float, default=0.2 + Dropout rate for the hidden features. + task_level: str, default="graph" + Level of the task. Either "graph" or "node". + If "graph", the output is pooled over all nodes in the hypergraph. References ---------- @@ -24,26 +35,36 @@ class UniGIN(torch.nn.Module): """ def __init__( - self, in_channels_node, intermediate_channels, out_channels, n_layers=2 + self, + in_channels, + hidden_channels, + out_channels, + input_drop=0.2, + layer_drop=0.2, + n_layers=2, + task_level="graph", ): super().__init__() layers = [] + + self.input_drop = torch.nn.Dropout(input_drop) + self.layer_drop = torch.nn.Dropout(layer_drop) + + # Define initial linear layer + self.linear_init = torch.nn.Linear(in_channels, hidden_channels) + for _ in range(n_layers): - mlp = torch.nn.Sequential( - torch.nn.Linear(intermediate_channels, 2 * intermediate_channels), - torch.nn.ReLU(), - torch.nn.Linear(2 * intermediate_channels, intermediate_channels), - ) + layers.append( UniGINLayer( - nn=mlp, - in_channels=intermediate_channels, + in_channels=hidden_channels, ) ) - self.inp_embed = torch.nn.Linear(in_channels_node, intermediate_channels) self.layers = torch.nn.ModuleList(layers) - self.out_decoder = torch.nn.Linear(intermediate_channels, out_channels) + + self.linear_out = torch.nn.Linear(hidden_channels, out_channels) + self.out_pool = True if task_level == "graph" else False def forward(self, x_0, incidence_1): """Forward computation through layers, then linear layer, then global max pooling. @@ -61,8 +82,16 @@ def forward(self, x_0, incidence_1): torch.Tensor, shape = (1) Label assigned to whole complex. """ - x_0 = self.inp_embed(x_0) + x_0 = self.linear_init(x_0) for layer in self.layers: x_0 = layer(x_0, incidence_1) - pooled_x_0 = torch.mean(x_0, dim=0) - return torch.sigmoid(self.out_decoder(pooled_x_0)) + x_0 = self.layer_drop(x_0) + x_0 = torch.nn.functional.relu(x_0) + + # Pool over all nodes in the hypergraph + if self.out_pool is True: + x = torch.max(x_0, dim=0)[0] + else: + x = x_0 + + return self.linear_out(x) diff --git a/topomodelx/nn/hypergraph/unigin_layer.py b/topomodelx/nn/hypergraph/unigin_layer.py index 7bba5b0fa..30fc8f551 100644 --- a/topomodelx/nn/hypergraph/unigin_layer.py +++ b/topomodelx/nn/hypergraph/unigin_layer.py @@ -10,9 +10,6 @@ class UniGINLayer(torch.nn.Module): Parameters ---------- - nn : torch.nn.Module - A neural network that maps node features :obj:`x` of shape :obj:`[-1, in_channels]` to - shape :obj:`[-1, out_channels]`, *e.g.*, defined by :class:`torch.nn.Sequential`. in_channels : int Dimension of input features. eps : float @@ -36,19 +33,19 @@ class UniGINLayer(torch.nn.Module): def __init__( self, - nn, in_channels, - eps: float = 0.0, + eps: float = 0., train_eps: bool = False, ) -> None: super().__init__() - self.in_channels = in_channels + self.initial_eps = eps if train_eps: self.eps = torch.nn.Parameter(torch.Tensor([eps])) else: self.register_buffer("eps", torch.Tensor([eps])) - self.nn = nn + + self.linear = torch.nn.Linear(in_channels, in_channels) def forward(self, x_0, incidence_1): r"""[1]_ initially proposed the forward pass. @@ -99,4 +96,4 @@ def forward(self, x_0, incidence_1): # Second pass fills in features of nodes by adding features of the incident edges m_1_0 = torch.sparse.mm(incidence_1.float(), m_0_1) # Update node features using GIN update equation - return self.nn((1 + self.eps) * x_0 + m_1_0) + return self.linear((1 + self.eps) * x_0 + m_1_0) diff --git a/topomodelx/nn/hypergraph/unisage.py b/topomodelx/nn/hypergraph/unisage.py index 380e89b25..cfbacc797 100644 --- a/topomodelx/nn/hypergraph/unisage.py +++ b/topomodelx/nn/hypergraph/unisage.py @@ -10,12 +10,21 @@ class UniSAGE(torch.nn.Module): Parameters ---------- - channels_edge : int - Dimension of edge features - channels_node : int - Dimension of node features + in_channels : int + Dimension of the input features. + hidden_channels : int + Dimension of the hidden features. + out_channels : int + Dimension of the output features. n_layer : int, default = 2 Amount of message passing layers. + input_drop: float, default=0.2 + Dropout rate for the input features. + layer_drop: float, default=0.2 + Dropout rate for the hidden features. + task_level: str, default="graph" + Level of the task. Either "graph" or "node". + If "graph", the output is pooled over all nodes in the hypergraph. References ---------- @@ -25,25 +34,47 @@ class UniSAGE(torch.nn.Module): https://arxiv.org/pdf/2105.00956.pdf """ - def __init__(self, channels_edge, channels_node, n_layers=2): + def __init__( + self, + in_channels, + hidden_channels, + out_channels, + input_drop=0.2, + layer_drop=0.2, + n_layers=2, + task_level="graph", + ): super().__init__() + + self.input_drop = torch.nn.Dropout(input_drop) + self.layer_drop = torch.nn.Dropout(layer_drop) + + layers = [] - for _ in range(n_layers): + layers.append( + UniSAGELayer( + in_channels=in_channels, + out_channels=hidden_channels, + ) + ) + for _ in range(n_layers - 1): layers.append( UniSAGELayer( - in_channels=channels_edge, - out_channels=channels_edge, + in_channels=hidden_channels, + out_channels=hidden_channels, ) ) self.layers = torch.nn.ModuleList(layers) - self.linear = torch.nn.Linear(channels_edge, 1) + + self.linear_out = torch.nn.Linear(hidden_channels, out_channels) + self.out_pool = True if task_level == "graph" else False - def forward(self, x_1, incidence_1): + def forward(self, x_0, incidence_1): """Forward computation through layers, then linear layer, then global max pooling. Parameters ---------- - x_1 : torch.Tensor, shape = (n_edges, channels_edge) + x : torch.Tensor, shape = (n_edges, channels_edge) Edge features. incidence_1 : torch.Tensor, shape = (n_nodes, n_edges) @@ -54,7 +85,19 @@ def forward(self, x_1, incidence_1): torch.Tensor, shape = (1) Label assigned to whole complex. """ + + x_0 = self.input_drop(x_0) + + # Iterate over layers for layer in self.layers: - x_1 = layer(x_1, incidence_1) - pooled_x = torch.max(x_1, dim=0)[0] - return torch.sigmoid(self.linear(pooled_x)) + x_0 = layer(x_0, incidence_1) + x_0 = self.layer_drop(x_0) + x_0 = torch.nn.functional.relu(x_0) + # Pool over all nodes in the hypergraph + if self.out_pool is True: + x = torch.max(x_0, dim=0)[0] + else: + x = x_0 + + return self.linear_out(x) + diff --git a/tutorials/hypergraph/allset_train.ipynb b/tutorials/hypergraph/allset_train.ipynb index db32dc1ec..4a4548497 100644 --- a/tutorials/hypergraph/allset_train.ipynb +++ b/tutorials/hypergraph/allset_train.ipynb @@ -36,7 +36,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 1, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:51.222779223Z", @@ -73,7 +73,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 2, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:51.959770754Z", @@ -108,7 +108,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 3, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:53.022151550Z", @@ -153,7 +153,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 4, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:53.022151550Z", @@ -194,7 +194,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -243,7 +243,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -268,7 +268,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 7, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:55.343005145Z", @@ -307,7 +307,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ @@ -323,7 +323,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 9, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:59.046068930Z", @@ -335,9 +335,9 @@ "name": "stderr", "output_type": "stream", "text": [ - "/tmp/ipykernel_132025/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_120782/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " x_0s = torch.tensor(x_0s)\n", - "/tmp/ipykernel_132025/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_120782/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " torch.tensor(y, dtype=torch.long).to(device),\n" ] } @@ -361,61 +361,43 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Epoch: 1 loss: 1.9463, acc: 0.1429\n", - "Epoch: 2 loss: 1.9444, acc: 0.2500\n", - "Epoch: 3 loss: 1.9251, acc: 0.1857\n", - "Epoch: 4 loss: 1.8896, acc: 0.1429\n", - "Epoch: 5 loss: 1.8660, acc: 0.4000\n", - "Val_loss: 1.8107, Val_acc: 0.4660\n", - "Test_loss: 1.8106, Test_acc: 0.4580\n" + "Epoch: 5 \n", + "Train_loss: 1.8347, acc: 0.4429\n", + "Val_loss: 1.6878, Val_acc: 0.3280\n", + "Test_loss: 1.6449, Test_acc: 0.3400\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Epoch: 6 loss: 1.8350, acc: 0.4071\n", - "Epoch: 7 loss: 1.7756, acc: 0.4429\n", - "Epoch: 8 loss: 1.6999, acc: 0.4429\n", - "Epoch: 9 loss: 1.6292, acc: 0.5214\n", - "Epoch: 10 loss: 1.5617, acc: 0.5643\n", - "Val_loss: 1.6181, Val_acc: 0.5460\n", - "Test_loss: 1.5937, Test_acc: 0.5300\n", - "Epoch: 11 loss: 1.4966, acc: 0.5857\n", - "Epoch: 12 loss: 1.4400, acc: 0.6357\n", - "Epoch: 13 loss: 1.3909, acc: 0.8071\n", - "Epoch: 14 loss: 1.3518, acc: 0.8000\n", - "Epoch: 15 loss: 1.3084, acc: 0.8143\n", - "Val_loss: 2.4014, Val_acc: 0.6240\n", - "Test_loss: 2.4001, Test_acc: 0.6330\n", - "Epoch: 16 loss: 1.2680, acc: 0.7857\n", - "Epoch: 17 loss: 1.2288, acc: 0.7357\n", - "Epoch: 18 loss: 1.1883, acc: 0.8143\n", - "Epoch: 19 loss: 1.1475, acc: 0.8429\n", - "Epoch: 20 loss: 1.1041, acc: 0.8714\n", - "Val_loss: 3.5885, Val_acc: 0.5960\n", - "Test_loss: 3.2893, Test_acc: 0.6270\n", - "Epoch: 21 loss: 1.0625, acc: 0.8857\n", - "Epoch: 22 loss: 1.0231, acc: 0.9286\n", - "Epoch: 23 loss: 0.9872, acc: 0.9000\n", - "Epoch: 24 loss: 0.9507, acc: 0.9429\n", - "Epoch: 25 loss: 0.9152, acc: 0.9786\n", - "Val_loss: 6.1737, Val_acc: 0.6820\n", - "Test_loss: 5.9891, Test_acc: 0.7050\n", - "Epoch: 26 loss: 0.8912, acc: 0.9500\n", - "Epoch: 27 loss: 0.8676, acc: 0.9571\n", - "Epoch: 28 loss: 0.8527, acc: 0.9143\n", - "Epoch: 29 loss: 0.8306, acc: 0.9571\n", - "Epoch: 30 loss: 0.8066, acc: 0.9714\n", - "Val_loss: 6.9474, Val_acc: 0.6940\n", - "Test_loss: 7.5958, Test_acc: 0.7020\n" + "Epoch: 10 \n", + "Train_loss: 1.4583, acc: 0.8929\n", + "Val_loss: 1.4314, Val_acc: 0.6020\n", + "Test_loss: 1.3842, Test_acc: 0.6520\n", + "Epoch: 15 \n", + "Train_loss: 1.0890, acc: 1.0000\n", + "Val_loss: 3.2297, Val_acc: 0.6440\n", + "Test_loss: 3.1065, Test_acc: 0.6560\n", + "Epoch: 20 \n", + "Train_loss: 0.8794, acc: 1.0000\n", + "Val_loss: 3.7749, Val_acc: 0.6920\n", + "Test_loss: 3.7500, Test_acc: 0.6880\n", + "Epoch: 25 \n", + "Train_loss: 0.8158, acc: 0.9929\n", + "Val_loss: 3.0896, Val_acc: 0.6660\n", + "Test_loss: 3.1467, Test_acc: 0.6770\n", + "Epoch: 30 \n", + "Train_loss: 0.7237, acc: 0.9714\n", + "Val_loss: 3.8173, Val_acc: 0.6260\n", + "Test_loss: 3.7671, Test_acc: 0.6210\n" ] } ], @@ -439,17 +421,19 @@ " opt.step()\n", " epoch_loss.append(loss.item())\n", "\n", - " print(\n", - " f\"Epoch: {epoch_i} loss: {np.mean(epoch_loss):.4f}, \\\n", - " acc: {acc_fn(y_hat[train_mask].argmax(1), y[train_mask]):.4f}\",\n", - " flush=True,\n", - " )\n", + " \n", "\n", " if epoch_i % test_interval == 0:\n", + " \n", " model.eval()\n", " y_hat = model(x_0s, incidence_1)\n", "\n", + " loss = loss_fn(y_hat[train_mask], y[train_mask])\n", + " print(f\"Epoch: {epoch_i} \")\n", + " print(f\"Train_loss: {np.mean(epoch_loss):.4f}, acc: {acc_fn(y_hat[train_mask].argmax(1), y[train_mask]):.4f}\",flush=True)\n", + "\n", " loss = loss_fn(y_hat[val_mask], y[val_mask])\n", + " \n", " print(f\"Val_loss: {loss:.4f}, Val_acc: {acc_fn(y_hat[val_mask].argmax(1), y[val_mask]):.4f}\", flush=True)\n", "\n", " loss = loss_fn(y_hat[test_mask], y[test_mask])\n", diff --git a/tutorials/hypergraph/allset_transformer_train.ipynb b/tutorials/hypergraph/allset_transformer_train.ipynb index 18d5723c4..f8942a99d 100644 --- a/tutorials/hypergraph/allset_transformer_train.ipynb +++ b/tutorials/hypergraph/allset_transformer_train.ipynb @@ -76,7 +76,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 1, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:51.222779223Z", @@ -103,7 +103,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 2, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:51.959770754Z", @@ -138,14 +138,23 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 3, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:53.022151550Z", "start_time": "2023-06-01T16:14:52.949636599Z" } }, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/usr/local/lib/python3.11/site-packages/torch_geometric/data/in_memory_dataset.py:284: UserWarning: It is not recommended to directly access the internal storage format `data` of an 'InMemoryDataset'. If you are absolutely certain what you are doing, access the internal storage via `InMemoryDataset._data` instead to suppress this warning. Alternatively, you can access stacked individual attributes of every graph via `dataset.{attr_name}`.\n", + " warnings.warn(msg)\n" + ] + } + ], "source": [ "cora = geom_datasets.Planetoid(root=\"/TopoModelX/data/cora\", name=\"Cora\")\n", "data = cora.data\n", @@ -352,9 +361,9 @@ "name": "stderr", "output_type": "stream", "text": [ - "/tmp/ipykernel_137396/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_122619/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " x_0s = torch.tensor(x_0s)\n", - "/tmp/ipykernel_137396/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_122619/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " torch.tensor(y, dtype=torch.long).to(device),\n" ] } @@ -390,20 +399,37 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch: 1 loss: 2.0382, acc: 0.1357\n", - "Epoch: 2 loss: 2.0218, acc: 0.1643\n", - "Epoch: 3 loss: 1.9403, acc: 0.3071\n", - "Epoch: 4 loss: 1.8247, acc: 0.6714\n", - "Epoch: 5 loss: 1.6906, acc: 0.8786\n", - "Val_loss: 1.2014, Val_acc: 0.7340\n", - "Test_loss: 1.1616, Test_acc: 0.7620\n" + "Epoch: 5 \n", + "Train_loss: 1.6089, acc: 0.9643\n", + "Val_loss: 1.0637, Val_acc: 0.7500\n", + "Test_loss: 1.0321, Test_acc: 0.7570\n", + "Epoch: 10 \n", + "Train_loss: 1.0163, acc: 1.0000\n", + "Val_loss: 0.9332, Val_acc: 0.7480\n", + "Test_loss: 0.8356, Test_acc: 0.7710\n", + "Epoch: 15 \n", + "Train_loss: 0.7071, acc: 1.0000\n", + "Val_loss: 1.2129, Val_acc: 0.7180\n", + "Test_loss: 1.0261, Test_acc: 0.7510\n", + "Epoch: 20 \n", + "Train_loss: 0.5365, acc: 1.0000\n", + "Val_loss: 1.5998, Val_acc: 0.6940\n", + "Test_loss: 1.3869, Test_acc: 0.7240\n", + "Epoch: 25 \n", + "Train_loss: 0.4309, acc: 1.0000\n", + "Val_loss: 1.9149, Val_acc: 0.6920\n", + "Test_loss: 1.7064, Test_acc: 0.7110\n", + "Epoch: 30 \n", + "Train_loss: 0.3599, acc: 1.0000\n", + "Val_loss: 2.0770, Val_acc: 0.6880\n", + "Test_loss: 1.8370, Test_acc: 0.7070\n" ] } ], "source": [ "torch.manual_seed(0)\n", "test_interval = 5\n", - "num_epochs = 5\n", + "num_epochs = 30\n", "\n", "epoch_loss = []\n", "for epoch_i in range(1, num_epochs + 1):\n", @@ -420,17 +446,19 @@ " opt.step()\n", " epoch_loss.append(loss.item())\n", "\n", - " print(\n", - " f\"Epoch: {epoch_i} loss: {np.mean(epoch_loss):.4f}, \\\n", - " acc: {acc_fn(y_hat[train_mask].argmax(1), y[train_mask]):.4f}\",\n", - " flush=True,\n", - " )\n", + " \n", "\n", " if epoch_i % test_interval == 0:\n", + " \n", " model.eval()\n", " y_hat = model(x_0s, incidence_1)\n", "\n", + " loss = loss_fn(y_hat[train_mask], y[train_mask])\n", + " print(f\"Epoch: {epoch_i} \")\n", + " print(f\"Train_loss: {np.mean(epoch_loss):.4f}, acc: {acc_fn(y_hat[train_mask].argmax(1), y[train_mask]):.4f}\",flush=True)\n", + "\n", " loss = loss_fn(y_hat[val_mask], y[val_mask])\n", + " \n", " print(f\"Val_loss: {loss:.4f}, Val_acc: {acc_fn(y_hat[val_mask].argmax(1), y[val_mask]):.4f}\", flush=True)\n", "\n", " loss = loss_fn(y_hat[test_mask], y[test_mask])\n", diff --git a/tutorials/hypergraph/dhgcn_train.ipynb b/tutorials/hypergraph/dhgcn_train.ipynb index 30dcff67f..8af681150 100644 --- a/tutorials/hypergraph/dhgcn_train.ipynb +++ b/tutorials/hypergraph/dhgcn_train.ipynb @@ -243,7 +243,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 20, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:55.343005145Z", @@ -254,7 +254,15 @@ "source": [ "channels_edge = x_1s[0].shape[1]\n", "channels_node = x_0s[0].shape[1]\n", - "model = DHGCN(channels_node, n_layers=2)\n", + "hidden_channels = 6\n", + "out_channels = 1\n", + "task_level = \"graph\" if out_channels==1 else \"node\"\n", + "\n", + "model = DHGCN(in_channels=channels_node,\n", + " hidden_channels=hidden_channels, \n", + " out_channels=out_channels,\n", + " n_layers=2,\n", + " task_level=task_level)\n", "model = model.to(device)" ] }, @@ -270,7 +278,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 21, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:58.153514385Z", @@ -293,7 +301,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 22, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:59.046068930Z", @@ -317,7 +325,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 23, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:15:01.683216142Z", @@ -329,16 +337,16 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch: 1 loss: 4791557.1252\n", - "Test_loss: 3105.2295\n", - "Epoch: 2 loss: 2015.3119\n", - "Test_loss: 85.2987\n", - "Epoch: 3 loss: 2244.4548\n", - "Test_loss: 263.3355\n", - "Epoch: 4 loss: 280.4737\n", - "Test_loss: 110.2089\n", - "Epoch: 5 loss: 183.3875\n", - "Test_loss: 26.0619\n" + "Epoch: 1 loss: 5970948.3681\n", + "Test_loss: 113531.4844\n", + "Epoch: 2 loss: 6257.3332\n", + "Test_loss: 283.5760\n", + "Epoch: 3 loss: 2764.6070\n", + "Test_loss: 290.4227\n", + "Epoch: 4 loss: 1391.9918\n", + "Test_loss: 685.2422\n", + "Epoch: 5 loss: 835.5999\n", + "Test_loss: 284.1080\n" ] } ], @@ -379,6 +387,13 @@ "\n", " print(f\"Test_loss: {loss:.4f}\", flush=True)" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { diff --git a/tutorials/hypergraph/hmpnn_train.ipynb b/tutorials/hypergraph/hmpnn_train.ipynb index 16adca19b..5b3cebd65 100644 --- a/tutorials/hypergraph/hmpnn_train.ipynb +++ b/tutorials/hypergraph/hmpnn_train.ipynb @@ -15,7 +15,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:51.222779223Z", @@ -41,7 +41,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:51.959770754Z", @@ -74,30 +74,119 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "dataset = geom_datasets.Planetoid(root=\"/TopoModelX/data/cora\", name=\"Cora\")[0]" + "\n", + "cora = geom_datasets.Planetoid(root=\"/TopoModelX/data/cora\", name=\"Cora\")\n", + "data = cora.data\n", + "\n", + "x_0s = data.x\n", + "y = data.y\n", + "edge_index = data.edge_index\n", + "\n", + "train_mask = data.train_mask\n", + "val_mask = data.val_mask\n", + "test_mask = data.test_mask" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Below, we construct the incidence matrix ($B_1$) which is of shape $n_\\text{nodes} \\times n_\\text{edges}$." + "## Define neighborhood structures and lift into hypergraph domain. ##\n", + "\n", + "Now we retrieve the neighborhood structure (i.e. their representative matrice) that we will use to send messges from node to hyperedges. In the case of this architecture, we need the boundary matrix (or incidence matrix) $B_1$ with shape $n_\\text{nodes} \\times n_\\text{edges}$.\n", + "\n", + "In citation Cora dataset we lift graph structure to the hypergraph domain by creating hyperedges from 1-hop graph neighbourhood of each node. \n" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "dataset[\"incidence_1\"] = torch.sparse_coo_tensor(\n", - " dataset[\"edge_index\"], torch.ones(dataset[\"edge_index\"].shape[1]), dtype=torch.long\n", - ")\n", - "dataset = dataset.to(device)" + "# Ensure the graph is undirected (optional but often useful for one-hop neighborhoods).\n", + "edge_index = to_undirected(edge_index)\n", + "\n", + "# Create a list of one-hop neighborhoods for each node.\n", + "one_hop_neighborhoods = []\n", + "for node in range(data.num_nodes):\n", + " # Get the one-hop neighbors of the current node.\n", + " neighbors = data.edge_index[1, data.edge_index[0] == node]\n", + "\n", + " # Append the neighbors to the list of one-hop neighborhoods.\n", + " one_hop_neighborhoods.append(neighbors.numpy())\n", + "\n", + "# Detect and eliminate duplicate hyperedges.\n", + "unique_hyperedges = set()\n", + "hyperedges = []\n", + "for neighborhood in one_hop_neighborhoods:\n", + " # Sort the neighborhood to ensure consistent comparison.\n", + " neighborhood = tuple(sorted(neighborhood))\n", + " if neighborhood not in unique_hyperedges:\n", + " hyperedges.append(list(neighborhood))\n", + " unique_hyperedges.add(neighborhood) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Additionally we print the statictis associated with obtained incidence matrix" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "# Calculate hyperedge statistics.\n", + "hyperedge_sizes = [len(he) for he in hyperedges]\n", + "min_size = min(hyperedge_sizes)\n", + "max_size = max(hyperedge_sizes)\n", + "mean_size = np.mean(hyperedge_sizes)\n", + "median_size = np.median(hyperedge_sizes)\n", + "std_size = np.std(hyperedge_sizes)\n", + "num_single_node_hyperedges = sum(np.array(hyperedge_sizes) == 1)\n", + "\n", + "# Print the hyperedge statistics.\n", + "print(f'Hyperedge statistics: ')\n", + "print('Number of hyperedges without duplicated hyperedges', len(hyperedges))\n", + "print(f'min = {min_size}, ')\n", + "print(f'max = {max_size}, ')\n", + "print(f'mean = {mean_size}, ')\n", + "print(f'median = {median_size}, ')\n", + "print(f'std = {std_size}, ')\n", + "print(f'Number of hyperedges with size equal to one = {num_single_node_hyperedges}')\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Construct incidence matrix" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "max_edges = len(hyperedges)\n", + "incidence_1 = np.zeros((x_0s.shape[0], max_edges))\n", + "for col, neighibourhood in enumerate(hyperedges):\n", + " for row in neighibourhood:\n", + " incidence_1[row, col] = 1\n", + "\n", + "assert all(incidence_1.sum(0)>0) == True, \"Some hyperedges are empty\"\n", + "assert all(incidence_1.sum(1)>0) == True, \"Some nodes are not in any hyperedges\"\n", + "incidence_1 = torch.Tensor(incidence_1).to_sparse_coo()" ] }, { diff --git a/tutorials/hypergraph/unigcn_train.ipynb b/tutorials/hypergraph/unigcn_train.ipynb index 5b209fbc1..c5362e555 100644 --- a/tutorials/hypergraph/unigcn_train.ipynb +++ b/tutorials/hypergraph/unigcn_train.ipynb @@ -7,9 +7,6 @@ "metadata": {}, "outputs": [], "source": [ - "%load_ext autoreload\n", - "%autoreload 2\n", - "\n", "import torch\n", "import numpy as np\n", "from sklearn.model_selection import train_test_split\n", @@ -20,7 +17,9 @@ "from topomodelx.nn.hypergraph.unigcn import UniGCN\n", "import warnings\n", "\n", - "warnings.filterwarnings(\"ignore\")" + "warnings.filterwarnings(\"ignore\")\n", + "# %load_ext autoreload\n", + "# %autoreload 2" ] }, { @@ -90,8 +89,17 @@ "outputs": [], "source": [ "channels_edge = x_1_list[0].shape[1]\n", - "channels_node = dataset[0].x.shape[1]\n", - "model = UniGCN(channels_edge, channels_node, n_layers=2)" + "hidden_channels = 32\n", + "out_channels = 1\n", + "n_layers = 2\n", + "task_level = \"graph\" if out_channels==1 else \"node\"\n", + "\n", + "model = UniGCN(\n", + " in_channels=channels_edge,\n", + " hidden_channels=hidden_channels,\n", + " out_channels=out_channels,\n", + " n_layers=n_layers,\n", + " task_level=task_level,)" ] }, { @@ -161,1037 +169,50 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch 0 loss: 902.4901733398438\n", - "Epoch 0 Validation accuracy: 0.4375\n", - "Epoch 1 loss: 742.79052734375\n", - "Epoch 1 Validation accuracy: 0.4375\n", - "Epoch 2 loss: 585.759521484375\n", - "Epoch 2 Validation accuracy: 0.4375\n", - "Epoch 3 loss: 432.1170654296875\n", - "Epoch 3 Validation accuracy: 0.4375\n", - "Epoch 4 loss: 282.8601379394531\n", - "Epoch 4 Validation accuracy: 0.4375\n", - "Epoch 5 loss: 143.66136169433594\n", - "Epoch 5 Validation accuracy: 0.75\n", - "Epoch 6 loss: 55.54958724975586\n", - "Epoch 6 Validation accuracy: 0.5625\n", - "Epoch 7 loss: 50.33615493774414\n", - "Epoch 7 Validation accuracy: 0.5625\n", - "Epoch 8 loss: 72.13643646240234\n", - "Epoch 8 Validation accuracy: 0.5625\n", - "Epoch 9 loss: 92.25325775146484\n", - "Epoch 9 Validation accuracy: 0.5625\n", - "Epoch 10 loss: 108.162841796875\n", - "Epoch 10 Validation accuracy: 0.5625\n", - "Epoch 11 loss: 119.53228759765625\n", - "Epoch 11 Validation accuracy: 0.5625\n", - "Epoch 12 loss: 126.69290924072266\n", - "Epoch 12 Validation accuracy: 0.5625\n", - "Epoch 13 loss: 129.98519897460938\n", - "Epoch 13 Validation accuracy: 0.5625\n", - "Epoch 14 loss: 130.16600036621094\n", - "Epoch 14 Validation accuracy: 0.5625\n", - "Epoch 15 loss: 127.80245208740234\n", - "Epoch 15 Validation accuracy: 0.5625\n", - "Epoch 16 loss: 122.98604583740234\n", - "Epoch 16 Validation accuracy: 0.5625\n", - "Epoch 17 loss: 116.02069854736328\n", - "Epoch 17 Validation accuracy: 0.5625\n", - "Epoch 18 loss: 107.27203369140625\n", - "Epoch 18 Validation accuracy: 0.5625\n", - "Epoch 19 loss: 97.05550384521484\n", - "Epoch 19 Validation accuracy: 0.5625\n", - "Epoch 20 loss: 85.7593765258789\n", - "Epoch 20 Validation accuracy: 0.5625\n", - "Epoch 21 loss: 74.24275970458984\n", - "Epoch 21 Validation accuracy: 0.5625\n", - "Epoch 22 loss: 63.24573516845703\n", - "Epoch 22 Validation accuracy: 0.625\n", - "Epoch 23 loss: 52.25870132446289\n", - "Epoch 23 Validation accuracy: 0.625\n", - "Epoch 24 loss: 42.992156982421875\n", - "Epoch 24 Validation accuracy: 0.625\n", - "Epoch 25 loss: 37.94447326660156\n", - "Epoch 25 Validation accuracy: 0.625\n", - "Epoch 26 loss: 39.74713897705078\n", - "Epoch 26 Validation accuracy: 0.625\n", - "Epoch 27 loss: 47.584598541259766\n", - "Epoch 27 Validation accuracy: 0.6875\n", - "Epoch 28 loss: 55.302337646484375\n", - "Epoch 28 Validation accuracy: 0.6875\n", - "Epoch 29 loss: 57.985782623291016\n", - "Epoch 29 Validation accuracy: 0.6875\n", - "Epoch 30 loss: 54.713340759277344\n", - "Epoch 30 Validation accuracy: 0.625\n", - "Epoch 31 loss: 47.53618240356445\n", - "Epoch 31 Validation accuracy: 0.5625\n", - "Epoch 32 loss: 39.84739303588867\n", - "Epoch 32 Validation accuracy: 0.625\n", - "Epoch 33 loss: 34.595306396484375\n", - "Epoch 33 Validation accuracy: 0.625\n", - "Epoch 34 loss: 32.71818161010742\n", - "Epoch 34 Validation accuracy: 0.625\n", - "Epoch 35 loss: 33.3809814453125\n", - "Epoch 35 Validation accuracy: 0.625\n", - "Epoch 36 loss: 35.186588287353516\n", - "Epoch 36 Validation accuracy: 0.625\n", - "Epoch 37 loss: 37.00263214111328\n", - "Epoch 37 Validation accuracy: 0.625\n", - "Epoch 38 loss: 38.166587829589844\n", - "Epoch 38 Validation accuracy: 0.625\n", - "Epoch 39 loss: 38.39109420776367\n", - "Epoch 39 Validation accuracy: 0.625\n", - "Epoch 40 loss: 37.600830078125\n", - "Epoch 40 Validation accuracy: 0.625\n", - "Epoch 41 loss: 35.973331451416016\n", - "Epoch 41 Validation accuracy: 0.625\n", - "Epoch 42 loss: 33.825225830078125\n", - "Epoch 42 Validation accuracy: 0.625\n", - "Epoch 43 loss: 31.596601486206055\n", - "Epoch 43 Validation accuracy: 0.625\n", - "Epoch 44 loss: 29.79454231262207\n", - "Epoch 44 Validation accuracy: 0.625\n", - "Epoch 45 loss: 28.8666934967041\n", - "Epoch 45 Validation accuracy: 0.625\n", - "Epoch 46 loss: 28.986522674560547\n", - "Epoch 46 Validation accuracy: 0.625\n", - "Epoch 47 loss: 29.880859375\n", - "Epoch 47 Validation accuracy: 0.625\n", - "Epoch 48 loss: 30.91712188720703\n", - "Epoch 48 Validation accuracy: 0.625\n", - "Epoch 49 loss: 31.44558334350586\n", - "Epoch 49 Validation accuracy: 0.625\n", - "Epoch 50 loss: 31.152557373046875\n", - "Epoch 50 Validation accuracy: 0.625\n", - "Epoch 51 loss: 30.227420806884766\n", - "Epoch 51 Validation accuracy: 0.625\n", - "Epoch 52 loss: 29.160226821899414\n", - "Epoch 52 Validation accuracy: 0.625\n", - "Epoch 53 loss: 28.39475440979004\n", - "Epoch 53 Validation accuracy: 0.625\n", - "Epoch 54 loss: 28.113832473754883\n", - "Epoch 54 Validation accuracy: 0.625\n", - "Epoch 55 loss: 28.215381622314453\n", - "Epoch 55 Validation accuracy: 0.625\n", - "Epoch 56 loss: 28.52114486694336\n", - "Epoch 56 Validation accuracy: 0.625\n", - "Epoch 57 loss: 28.805360794067383\n", - "Epoch 57 Validation accuracy: 0.625\n", - "Epoch 58 loss: 28.915090560913086\n", - "Epoch 58 Validation accuracy: 0.625\n", - "Epoch 59 loss: 28.797382354736328\n", - "Epoch 59 Validation accuracy: 0.625\n", - "Epoch 60 loss: 28.480539321899414\n", - "Epoch 60 Validation accuracy: 0.625\n", - "Epoch 61 loss: 28.068044662475586\n", - "Epoch 61 Validation accuracy: 0.625\n", - "Epoch 62 loss: 27.685386657714844\n", - "Epoch 62 Validation accuracy: 0.625\n", - "Epoch 63 loss: 27.43670654296875\n", - "Epoch 63 Validation accuracy: 0.625\n", - "Epoch 64 loss: 27.364776611328125\n", - "Epoch 64 Validation accuracy: 0.625\n", - "Epoch 65 loss: 27.432109832763672\n", - "Epoch 65 Validation accuracy: 0.625\n", - "Epoch 66 loss: 27.538002014160156\n", - "Epoch 66 Validation accuracy: 0.625\n", - "Epoch 67 loss: 27.5771427154541\n", - "Epoch 67 Validation accuracy: 0.625\n", - "Epoch 68 loss: 27.4938907623291\n", - "Epoch 68 Validation accuracy: 0.625\n", - "Epoch 69 loss: 27.30146026611328\n", - "Epoch 69 Validation accuracy: 0.625\n", - "Epoch 70 loss: 27.066486358642578\n", - "Epoch 70 Validation accuracy: 0.625\n", - "Epoch 71 loss: 26.864112854003906\n", - "Epoch 71 Validation accuracy: 0.625\n", - "Epoch 72 loss: 26.738616943359375\n", - "Epoch 72 Validation accuracy: 0.625\n", - "Epoch 73 loss: 26.689714431762695\n", - "Epoch 73 Validation accuracy: 0.625\n", - "Epoch 74 loss: 26.684139251708984\n", - "Epoch 74 Validation accuracy: 0.625\n", - "Epoch 75 loss: 26.6783390045166\n", - "Epoch 75 Validation accuracy: 0.625\n", - "Epoch 76 loss: 26.640270233154297\n", - "Epoch 76 Validation accuracy: 0.625\n", - "Epoch 77 loss: 26.568225860595703\n", - "Epoch 77 Validation accuracy: 0.625\n", - "Epoch 78 loss: 26.463821411132812\n", - "Epoch 78 Validation accuracy: 0.625\n", - "Epoch 79 loss: 26.352237701416016\n", - "Epoch 79 Validation accuracy: 0.625\n", - "Epoch 80 loss: 26.259632110595703\n", - "Epoch 80 Validation accuracy: 0.625\n", - "Epoch 81 loss: 26.200979232788086\n", - "Epoch 81 Validation accuracy: 0.625\n", - "Epoch 82 loss: 26.173927307128906\n", - "Epoch 82 Validation accuracy: 0.625\n", - "Epoch 83 loss: 26.162473678588867\n", - "Epoch 83 Validation accuracy: 0.625\n", - "Epoch 84 loss: 26.145278930664062\n", - "Epoch 84 Validation accuracy: 0.625\n", - "Epoch 85 loss: 26.108654022216797\n", - "Epoch 85 Validation accuracy: 0.625\n", - "Epoch 86 loss: 26.052175521850586\n", - "Epoch 86 Validation accuracy: 0.625\n", - "Epoch 87 loss: 25.986543655395508\n", - "Epoch 87 Validation accuracy: 0.625\n", - "Epoch 88 loss: 25.926197052001953\n", - "Epoch 88 Validation accuracy: 0.625\n", - "Epoch 89 loss: 25.880918502807617\n", - "Epoch 89 Validation accuracy: 0.625\n", - "Epoch 90 loss: 25.85179901123047\n", - "Epoch 90 Validation accuracy: 0.625\n", - "Epoch 91 loss: 25.83198356628418\n", - "Epoch 91 Validation accuracy: 0.625\n", - "Epoch 92 loss: 25.812116622924805\n", - "Epoch 92 Validation accuracy: 0.625\n", - "Epoch 93 loss: 25.78550148010254\n", - "Epoch 93 Validation accuracy: 0.625\n", - "Epoch 94 loss: 25.751976013183594\n", - "Epoch 94 Validation accuracy: 0.625\n", - "Epoch 95 loss: 25.7146053314209\n", - "Epoch 95 Validation accuracy: 0.625\n", - "Epoch 96 loss: 25.67841148376465\n", - "Epoch 96 Validation accuracy: 0.625\n", - "Epoch 97 loss: 25.64767074584961\n", - "Epoch 97 Validation accuracy: 0.625\n", - "Epoch 98 loss: 25.623760223388672\n", - "Epoch 98 Validation accuracy: 0.625\n", - "Epoch 99 loss: 25.604145050048828\n", - "Epoch 99 Validation accuracy: 0.625\n", - "Epoch 100 loss: 25.58517074584961\n", - "Epoch 100 Validation accuracy: 0.625\n", - "Epoch 101 loss: 25.56340789794922\n", - "Epoch 101 Validation accuracy: 0.625\n", - "Epoch 102 loss: 25.537738800048828\n", - "Epoch 102 Validation accuracy: 0.625\n", - "Epoch 103 loss: 25.5096435546875\n", - "Epoch 103 Validation accuracy: 0.625\n", - "Epoch 104 loss: 25.481836318969727\n", - "Epoch 104 Validation accuracy: 0.625\n", - "Epoch 105 loss: 25.456588745117188\n", - "Epoch 105 Validation accuracy: 0.625\n", - "Epoch 106 loss: 25.435287475585938\n", - "Epoch 106 Validation accuracy: 0.625\n", - "Epoch 107 loss: 25.416616439819336\n", - "Epoch 107 Validation accuracy: 0.625\n", - "Epoch 108 loss: 25.397968292236328\n", - "Epoch 108 Validation accuracy: 0.625\n", - "Epoch 109 loss: 25.377914428710938\n", - "Epoch 109 Validation accuracy: 0.625\n", - "Epoch 110 loss: 25.355894088745117\n", - "Epoch 110 Validation accuracy: 0.625\n", - "Epoch 111 loss: 25.332746505737305\n", - "Epoch 111 Validation accuracy: 0.625\n", - "Epoch 112 loss: 25.310028076171875\n", - "Epoch 112 Validation accuracy: 0.625\n", - "Epoch 113 loss: 25.288677215576172\n", - "Epoch 113 Validation accuracy: 0.625\n", - "Epoch 114 loss: 25.26887321472168\n", - "Epoch 114 Validation accuracy: 0.625\n", - "Epoch 115 loss: 25.249961853027344\n", - "Epoch 115 Validation accuracy: 0.625\n", - "Epoch 116 loss: 25.23108673095703\n", - "Epoch 116 Validation accuracy: 0.625\n", - "Epoch 117 loss: 25.212047576904297\n", - "Epoch 117 Validation accuracy: 0.625\n", - "Epoch 118 loss: 25.192527770996094\n", - "Epoch 118 Validation accuracy: 0.625\n", - "Epoch 119 loss: 25.173789978027344\n", - "Epoch 119 Validation accuracy: 0.625\n", - "Epoch 120 loss: 25.15878677368164\n", - "Epoch 120 Validation accuracy: 0.625\n", - "Epoch 121 loss: 25.14487648010254\n", - "Epoch 121 Validation accuracy: 0.625\n", - "Epoch 122 loss: 25.13152313232422\n", - "Epoch 122 Validation accuracy: 0.625\n", - "Epoch 123 loss: 25.117942810058594\n", - "Epoch 123 Validation accuracy: 0.625\n", - "Epoch 124 loss: 25.103792190551758\n", - "Epoch 124 Validation accuracy: 0.625\n", - "Epoch 125 loss: 25.088790893554688\n", - "Epoch 125 Validation accuracy: 0.625\n", - "Epoch 126 loss: 25.0731201171875\n", - "Epoch 126 Validation accuracy: 0.625\n", - "Epoch 127 loss: 25.057111740112305\n", - "Epoch 127 Validation accuracy: 0.625\n", - "Epoch 128 loss: 25.041547775268555\n", - "Epoch 128 Validation accuracy: 0.625\n", - "Epoch 129 loss: 25.026466369628906\n", - "Epoch 129 Validation accuracy: 0.625\n", - "Epoch 130 loss: 25.011743545532227\n", - "Epoch 130 Validation accuracy: 0.625\n", - "Epoch 131 loss: 24.996620178222656\n", - "Epoch 131 Validation accuracy: 0.625\n", - "Epoch 132 loss: 24.98100471496582\n", - "Epoch 132 Validation accuracy: 0.625\n", - "Epoch 133 loss: 24.965646743774414\n", - "Epoch 133 Validation accuracy: 0.625\n", - "Epoch 134 loss: 24.950223922729492\n", - "Epoch 134 Validation accuracy: 0.625\n", - "Epoch 135 loss: 24.93490982055664\n", - "Epoch 135 Validation accuracy: 0.625\n", - "Epoch 136 loss: 24.919763565063477\n", - "Epoch 136 Validation accuracy: 0.625\n", - "Epoch 137 loss: 24.90479850769043\n", - "Epoch 137 Validation accuracy: 0.625\n", - "Epoch 138 loss: 24.890039443969727\n", - "Epoch 138 Validation accuracy: 0.625\n", - "Epoch 139 loss: 24.875774383544922\n", - "Epoch 139 Validation accuracy: 0.625\n", - "Epoch 140 loss: 24.861370086669922\n", - "Epoch 140 Validation accuracy: 0.625\n", - "Epoch 141 loss: 24.847206115722656\n", - "Epoch 141 Validation accuracy: 0.625\n", - "Epoch 142 loss: 24.833080291748047\n", - "Epoch 142 Validation accuracy: 0.625\n", - "Epoch 143 loss: 24.819049835205078\n", - "Epoch 143 Validation accuracy: 0.625\n", - "Epoch 144 loss: 24.805124282836914\n", - "Epoch 144 Validation accuracy: 0.625\n", - "Epoch 145 loss: 24.79128074645996\n", - "Epoch 145 Validation accuracy: 0.625\n", - "Epoch 146 loss: 24.777509689331055\n", - "Epoch 146 Validation accuracy: 0.625\n", - "Epoch 147 loss: 24.76376724243164\n", - "Epoch 147 Validation accuracy: 0.625\n", - "Epoch 148 loss: 24.74854278564453\n", - "Epoch 148 Validation accuracy: 0.625\n", - "Epoch 149 loss: 24.73321533203125\n", - "Epoch 149 Validation accuracy: 0.625\n", - "Epoch 150 loss: 24.717744827270508\n", - "Epoch 150 Validation accuracy: 0.625\n", - "Epoch 151 loss: 24.702198028564453\n", - "Epoch 151 Validation accuracy: 0.625\n", - "Epoch 152 loss: 24.686790466308594\n", - "Epoch 152 Validation accuracy: 0.625\n", - "Epoch 153 loss: 24.671096801757812\n", - "Epoch 153 Validation accuracy: 0.625\n", - "Epoch 154 loss: 24.655136108398438\n", - "Epoch 154 Validation accuracy: 0.625\n", - "Epoch 155 loss: 24.63947296142578\n", - "Epoch 155 Validation accuracy: 0.625\n", - "Epoch 156 loss: 24.623905181884766\n", - "Epoch 156 Validation accuracy: 0.625\n", - "Epoch 157 loss: 24.608251571655273\n", - "Epoch 157 Validation accuracy: 0.625\n", - "Epoch 158 loss: 24.592540740966797\n", - "Epoch 158 Validation accuracy: 0.625\n", - "Epoch 159 loss: 24.576845169067383\n", - "Epoch 159 Validation accuracy: 0.625\n", - "Epoch 160 loss: 24.56026840209961\n", - "Epoch 160 Validation accuracy: 0.625\n", - "Epoch 161 loss: 24.543073654174805\n", - "Epoch 161 Validation accuracy: 0.625\n", - "Epoch 162 loss: 24.525781631469727\n", - "Epoch 162 Validation accuracy: 0.625\n", - "Epoch 163 loss: 24.50815773010254\n", - "Epoch 163 Validation accuracy: 0.625\n", - "Epoch 164 loss: 24.49064064025879\n", - "Epoch 164 Validation accuracy: 0.625\n", - "Epoch 165 loss: 24.472421646118164\n", - "Epoch 165 Validation accuracy: 0.625\n", - "Epoch 166 loss: 24.450693130493164\n", - "Epoch 166 Validation accuracy: 0.625\n", - "Epoch 167 loss: 24.427898406982422\n", - "Epoch 167 Validation accuracy: 0.625\n", - "Epoch 168 loss: 24.402362823486328\n", - "Epoch 168 Validation accuracy: 0.625\n", - "Epoch 169 loss: 24.37494659423828\n", - "Epoch 169 Validation accuracy: 0.625\n", - "Epoch 170 loss: 24.34657859802246\n", - "Epoch 170 Validation accuracy: 0.625\n", - "Epoch 171 loss: 24.317203521728516\n", - "Epoch 171 Validation accuracy: 0.625\n", - "Epoch 172 loss: 24.286909103393555\n", - "Epoch 172 Validation accuracy: 0.625\n", - "Epoch 173 loss: 24.2688045501709\n", - "Epoch 173 Validation accuracy: 0.625\n", - "Epoch 174 loss: 24.2530574798584\n", - "Epoch 174 Validation accuracy: 0.625\n", - "Epoch 175 loss: 24.237436294555664\n", - "Epoch 175 Validation accuracy: 0.625\n", - "Epoch 176 loss: 24.222070693969727\n", - "Epoch 176 Validation accuracy: 0.625\n", - "Epoch 177 loss: 24.206933975219727\n", - "Epoch 177 Validation accuracy: 0.625\n", - "Epoch 178 loss: 24.19208335876465\n", - "Epoch 178 Validation accuracy: 0.625\n", - "Epoch 179 loss: 24.177217483520508\n", - "Epoch 179 Validation accuracy: 0.625\n", - "Epoch 180 loss: 24.16236114501953\n", - "Epoch 180 Validation accuracy: 0.625\n", - "Epoch 181 loss: 24.147443771362305\n", - "Epoch 181 Validation accuracy: 0.625\n", - "Epoch 182 loss: 24.132776260375977\n", - "Epoch 182 Validation accuracy: 0.625\n", - "Epoch 183 loss: 24.118249893188477\n", - "Epoch 183 Validation accuracy: 0.625\n", - "Epoch 184 loss: 24.103797912597656\n", - "Epoch 184 Validation accuracy: 0.625\n", - "Epoch 185 loss: 24.089706420898438\n", - "Epoch 185 Validation accuracy: 0.625\n", - "Epoch 186 loss: 24.075761795043945\n", - "Epoch 186 Validation accuracy: 0.625\n", - "Epoch 187 loss: 24.06186294555664\n", - "Epoch 187 Validation accuracy: 0.625\n", - "Epoch 188 loss: 24.048063278198242\n", - "Epoch 188 Validation accuracy: 0.625\n", - "Epoch 189 loss: 24.034448623657227\n", - "Epoch 189 Validation accuracy: 0.625\n", - "Epoch 190 loss: 24.020954132080078\n", - "Epoch 190 Validation accuracy: 0.625\n", - "Epoch 191 loss: 24.006834030151367\n", - "Epoch 191 Validation accuracy: 0.625\n", - "Epoch 192 loss: 23.993017196655273\n", - "Epoch 192 Validation accuracy: 0.625\n", - "Epoch 193 loss: 23.979351043701172\n", - "Epoch 193 Validation accuracy: 0.625\n", - "Epoch 194 loss: 23.965789794921875\n", - "Epoch 194 Validation accuracy: 0.625\n", - "Epoch 195 loss: 23.952112197875977\n", - "Epoch 195 Validation accuracy: 0.625\n", - "Epoch 196 loss: 23.938526153564453\n", - "Epoch 196 Validation accuracy: 0.625\n", - "Epoch 197 loss: 23.924880981445312\n", - "Epoch 197 Validation accuracy: 0.625\n", - "Epoch 198 loss: 23.911245346069336\n", - "Epoch 198 Validation accuracy: 0.625\n", - "Epoch 199 loss: 23.897811889648438\n", - "Epoch 199 Validation accuracy: 0.625\n", - "Epoch 200 loss: 23.88424301147461\n", - "Epoch 200 Validation accuracy: 0.625\n", - "Epoch 201 loss: 23.870620727539062\n", - "Epoch 201 Validation accuracy: 0.625\n", - "Epoch 202 loss: 23.856914520263672\n", - "Epoch 202 Validation accuracy: 0.625\n", - "Epoch 203 loss: 23.843372344970703\n", - "Epoch 203 Validation accuracy: 0.625\n", - "Epoch 204 loss: 23.82991600036621\n", - "Epoch 204 Validation accuracy: 0.625\n", - "Epoch 205 loss: 23.81630516052246\n", - "Epoch 205 Validation accuracy: 0.625\n", - "Epoch 206 loss: 23.802886962890625\n", - "Epoch 206 Validation accuracy: 0.625\n", - "Epoch 207 loss: 23.78949737548828\n", - "Epoch 207 Validation accuracy: 0.625\n", - "Epoch 208 loss: 23.776121139526367\n", - "Epoch 208 Validation accuracy: 0.625\n", - "Epoch 209 loss: 23.76279640197754\n", - "Epoch 209 Validation accuracy: 0.625\n", - "Epoch 210 loss: 23.74949836730957\n", - "Epoch 210 Validation accuracy: 0.625\n", - "Epoch 211 loss: 23.737751007080078\n", - "Epoch 211 Validation accuracy: 0.625\n", - "Epoch 212 loss: 23.729055404663086\n", - "Epoch 212 Validation accuracy: 0.625\n", - "Epoch 213 loss: 23.715679168701172\n", - "Epoch 213 Validation accuracy: 0.625\n", - "Epoch 214 loss: 23.70354461669922\n", - "Epoch 214 Validation accuracy: 0.625\n", - "Epoch 215 loss: 23.692848205566406\n", - "Epoch 215 Validation accuracy: 0.625\n", - "Epoch 216 loss: 23.682186126708984\n", - "Epoch 216 Validation accuracy: 0.625\n", - "Epoch 217 loss: 23.671817779541016\n", - "Epoch 217 Validation accuracy: 0.625\n", - "Epoch 218 loss: 23.66116714477539\n", - "Epoch 218 Validation accuracy: 0.625\n", - "Epoch 219 loss: 23.65018081665039\n", - "Epoch 219 Validation accuracy: 0.625\n", - "Epoch 220 loss: 23.638872146606445\n", - "Epoch 220 Validation accuracy: 0.625\n", - "Epoch 221 loss: 23.627206802368164\n", - "Epoch 221 Validation accuracy: 0.625\n", - "Epoch 222 loss: 23.615779876708984\n", - "Epoch 222 Validation accuracy: 0.625\n", - "Epoch 223 loss: 23.6042423248291\n", - "Epoch 223 Validation accuracy: 0.625\n", - "Epoch 224 loss: 23.59211540222168\n", - "Epoch 224 Validation accuracy: 0.625\n", - "Epoch 225 loss: 23.58187484741211\n", - "Epoch 225 Validation accuracy: 0.625\n", - "Epoch 226 loss: 23.570674896240234\n", - "Epoch 226 Validation accuracy: 0.625\n", - "Epoch 227 loss: 23.558454513549805\n", - "Epoch 227 Validation accuracy: 0.625\n", - "Epoch 228 loss: 23.547941207885742\n", - "Epoch 228 Validation accuracy: 0.625\n", - "Epoch 229 loss: 23.537683486938477\n", - "Epoch 229 Validation accuracy: 0.625\n", - "Epoch 230 loss: 23.526987075805664\n", - "Epoch 230 Validation accuracy: 0.625\n", - "Epoch 231 loss: 23.515642166137695\n", - "Epoch 231 Validation accuracy: 0.625\n", - "Epoch 232 loss: 23.504106521606445\n", - "Epoch 232 Validation accuracy: 0.625\n", - "Epoch 233 loss: 23.49180030822754\n", - "Epoch 233 Validation accuracy: 0.625\n", - "Epoch 234 loss: 23.479785919189453\n", - "Epoch 234 Validation accuracy: 0.625\n", - "Epoch 235 loss: 23.46455955505371\n", - "Epoch 235 Validation accuracy: 0.625\n", - "Epoch 236 loss: 23.45136070251465\n", - "Epoch 236 Validation accuracy: 0.625\n", - "Epoch 237 loss: 23.43777847290039\n", - "Epoch 237 Validation accuracy: 0.625\n", - "Epoch 238 loss: 23.424055099487305\n", - "Epoch 238 Validation accuracy: 0.625\n", - "Epoch 239 loss: 23.409717559814453\n", - "Epoch 239 Validation accuracy: 0.625\n", - "Epoch 240 loss: 23.400564193725586\n", - "Epoch 240 Validation accuracy: 0.625\n", - "Epoch 241 loss: 23.39628028869629\n", - "Epoch 241 Validation accuracy: 0.625\n", - "Epoch 242 loss: 23.390756607055664\n", - "Epoch 242 Validation accuracy: 0.625\n", - "Epoch 243 loss: 23.38397979736328\n", - "Epoch 243 Validation accuracy: 0.625\n", - "Epoch 244 loss: 23.37428855895996\n", - "Epoch 244 Validation accuracy: 0.625\n", - "Epoch 245 loss: 23.362167358398438\n", - "Epoch 245 Validation accuracy: 0.625\n", - "Epoch 246 loss: 23.34809112548828\n", - "Epoch 246 Validation accuracy: 0.625\n", - "Epoch 247 loss: 23.3326473236084\n", - "Epoch 247 Validation accuracy: 0.625\n", - "Epoch 248 loss: 23.31566047668457\n", - "Epoch 248 Validation accuracy: 0.625\n", - "Epoch 249 loss: 23.30012321472168\n", - "Epoch 249 Validation accuracy: 0.625\n", - "Epoch 250 loss: 23.2796630859375\n", - "Epoch 250 Validation accuracy: 0.625\n", - "Epoch 251 loss: 23.261516571044922\n", - "Epoch 251 Validation accuracy: 0.625\n", - "Epoch 252 loss: 23.250732421875\n", - "Epoch 252 Validation accuracy: 0.625\n", - "Epoch 253 loss: 23.238964080810547\n", - "Epoch 253 Validation accuracy: 0.625\n", - "Epoch 254 loss: 23.224985122680664\n", - "Epoch 254 Validation accuracy: 0.625\n", - "Epoch 255 loss: 23.208303451538086\n", - "Epoch 255 Validation accuracy: 0.625\n", - "Epoch 256 loss: 23.189075469970703\n", - "Epoch 256 Validation accuracy: 0.625\n", - "Epoch 257 loss: 23.167694091796875\n", - "Epoch 257 Validation accuracy: 0.625\n", - "Epoch 258 loss: 23.145658493041992\n", - "Epoch 258 Validation accuracy: 0.625\n", - "Epoch 259 loss: 23.13551902770996\n", - "Epoch 259 Validation accuracy: 0.625\n", - "Epoch 260 loss: 23.12187385559082\n", - "Epoch 260 Validation accuracy: 0.625\n", - "Epoch 261 loss: 23.102636337280273\n", - "Epoch 261 Validation accuracy: 0.625\n", - "Epoch 262 loss: 23.088523864746094\n", - "Epoch 262 Validation accuracy: 0.625\n", - "Epoch 263 loss: 23.074373245239258\n", - "Epoch 263 Validation accuracy: 0.625\n", - "Epoch 264 loss: 23.05896759033203\n", - "Epoch 264 Validation accuracy: 0.625\n", - "Epoch 265 loss: 23.041915893554688\n", - "Epoch 265 Validation accuracy: 0.625\n", - "Epoch 266 loss: 23.023332595825195\n", - "Epoch 266 Validation accuracy: 0.625\n", - "Epoch 267 loss: 23.00411033630371\n", - "Epoch 267 Validation accuracy: 0.625\n", - "Epoch 268 loss: 22.985628128051758\n", - "Epoch 268 Validation accuracy: 0.625\n", - "Epoch 269 loss: 22.970544815063477\n", - "Epoch 269 Validation accuracy: 0.625\n", - "Epoch 270 loss: 22.95485496520996\n", - "Epoch 270 Validation accuracy: 0.625\n", - "Epoch 271 loss: 22.941598892211914\n", - "Epoch 271 Validation accuracy: 0.625\n", - "Epoch 272 loss: 22.92700958251953\n", - "Epoch 272 Validation accuracy: 0.625\n", - "Epoch 273 loss: 22.912050247192383\n", - "Epoch 273 Validation accuracy: 0.625\n", - "Epoch 274 loss: 22.8923282623291\n", - "Epoch 274 Validation accuracy: 0.625\n", - "Epoch 275 loss: 22.879552841186523\n", - "Epoch 275 Validation accuracy: 0.625\n", - "Epoch 276 loss: 22.867490768432617\n", - "Epoch 276 Validation accuracy: 0.625\n", - "Epoch 277 loss: 22.854406356811523\n", - "Epoch 277 Validation accuracy: 0.625\n", - "Epoch 278 loss: 22.84088706970215\n", - "Epoch 278 Validation accuracy: 0.625\n", - "Epoch 279 loss: 22.826339721679688\n", - "Epoch 279 Validation accuracy: 0.625\n", - "Epoch 280 loss: 22.81657600402832\n", - "Epoch 280 Validation accuracy: 0.625\n", - "Epoch 281 loss: 22.806161880493164\n", - "Epoch 281 Validation accuracy: 0.625\n", - "Epoch 282 loss: 22.795644760131836\n", - "Epoch 282 Validation accuracy: 0.625\n", - "Epoch 283 loss: 22.78535270690918\n", - "Epoch 283 Validation accuracy: 0.625\n", - "Epoch 284 loss: 22.775672912597656\n", - "Epoch 284 Validation accuracy: 0.625\n", - "Epoch 285 loss: 22.760944366455078\n", - "Epoch 285 Validation accuracy: 0.625\n", - "Epoch 286 loss: 22.752826690673828\n", - "Epoch 286 Validation accuracy: 0.625\n", - "Epoch 287 loss: 22.74382209777832\n", - "Epoch 287 Validation accuracy: 0.625\n", - "Epoch 288 loss: 22.729705810546875\n", - "Epoch 288 Validation accuracy: 0.625\n", - "Epoch 289 loss: 22.711393356323242\n", - "Epoch 289 Validation accuracy: 0.625\n", - "Epoch 290 loss: 22.697967529296875\n", - "Epoch 290 Validation accuracy: 0.625\n", - "Epoch 291 loss: 22.6846923828125\n", - "Epoch 291 Validation accuracy: 0.625\n", - "Epoch 292 loss: 22.672142028808594\n", - "Epoch 292 Validation accuracy: 0.625\n", - "Epoch 293 loss: 22.657779693603516\n", - "Epoch 293 Validation accuracy: 0.625\n", - "Epoch 294 loss: 22.64270782470703\n", - "Epoch 294 Validation accuracy: 0.625\n", - "Epoch 295 loss: 22.630765914916992\n", - "Epoch 295 Validation accuracy: 0.625\n", - "Epoch 296 loss: 22.6149845123291\n", - "Epoch 296 Validation accuracy: 0.625\n", - "Epoch 297 loss: 22.603057861328125\n", - "Epoch 297 Validation accuracy: 0.625\n", - "Epoch 298 loss: 22.590776443481445\n", - "Epoch 298 Validation accuracy: 0.625\n", - "Epoch 299 loss: 22.57485008239746\n", - "Epoch 299 Validation accuracy: 0.625\n", - "Epoch 300 loss: 22.556278228759766\n", - "Epoch 300 Validation accuracy: 0.625\n", - "Epoch 301 loss: 22.543123245239258\n", - "Epoch 301 Validation accuracy: 0.625\n", - "Epoch 302 loss: 22.52927017211914\n", - "Epoch 302 Validation accuracy: 0.625\n", - "Epoch 303 loss: 22.51650047302246\n", - "Epoch 303 Validation accuracy: 0.625\n", - "Epoch 304 loss: 22.50031280517578\n", - "Epoch 304 Validation accuracy: 0.625\n", - "Epoch 305 loss: 22.48053550720215\n", - "Epoch 305 Validation accuracy: 0.625\n", - "Epoch 306 loss: 22.46886444091797\n", - "Epoch 306 Validation accuracy: 0.625\n", - "Epoch 307 loss: 22.45595359802246\n", - "Epoch 307 Validation accuracy: 0.625\n", - "Epoch 308 loss: 22.437623977661133\n", - "Epoch 308 Validation accuracy: 0.625\n", - "Epoch 309 loss: 22.424482345581055\n", - "Epoch 309 Validation accuracy: 0.625\n", - "Epoch 310 loss: 22.410137176513672\n", - "Epoch 310 Validation accuracy: 0.625\n", - "Epoch 311 loss: 22.396631240844727\n", - "Epoch 311 Validation accuracy: 0.625\n", - "Epoch 312 loss: 22.381338119506836\n", - "Epoch 312 Validation accuracy: 0.625\n", - "Epoch 313 loss: 22.362808227539062\n", - "Epoch 313 Validation accuracy: 0.625\n", - "Epoch 314 loss: 22.34630012512207\n", - "Epoch 314 Validation accuracy: 0.625\n", - "Epoch 315 loss: 22.32933235168457\n", - "Epoch 315 Validation accuracy: 0.625\n", - "Epoch 316 loss: 22.31389808654785\n", - "Epoch 316 Validation accuracy: 0.625\n", - "Epoch 317 loss: 22.300844192504883\n", - "Epoch 317 Validation accuracy: 0.625\n", - "Epoch 318 loss: 22.28453826904297\n", - "Epoch 318 Validation accuracy: 0.625\n", - "Epoch 319 loss: 22.27028465270996\n", - "Epoch 319 Validation accuracy: 0.625\n", - "Epoch 320 loss: 22.258142471313477\n", - "Epoch 320 Validation accuracy: 0.625\n", - "Epoch 321 loss: 22.245216369628906\n", - "Epoch 321 Validation accuracy: 0.625\n", - "Epoch 322 loss: 22.230785369873047\n", - "Epoch 322 Validation accuracy: 0.625\n", - "Epoch 323 loss: 22.215072631835938\n", - "Epoch 323 Validation accuracy: 0.625\n", - "Epoch 324 loss: 22.198575973510742\n", - "Epoch 324 Validation accuracy: 0.625\n", - "Epoch 325 loss: 22.183231353759766\n", - "Epoch 325 Validation accuracy: 0.625\n", - "Epoch 326 loss: 22.1727294921875\n", - "Epoch 326 Validation accuracy: 0.625\n", - "Epoch 327 loss: 22.159303665161133\n", - "Epoch 327 Validation accuracy: 0.625\n", - "Epoch 328 loss: 22.14360237121582\n", - "Epoch 328 Validation accuracy: 0.625\n", - "Epoch 329 loss: 22.128843307495117\n", - "Epoch 329 Validation accuracy: 0.625\n", - "Epoch 330 loss: 22.117029190063477\n", - "Epoch 330 Validation accuracy: 0.625\n", - "Epoch 331 loss: 22.105663299560547\n", - "Epoch 331 Validation accuracy: 0.625\n", - "Epoch 332 loss: 22.09357452392578\n", - "Epoch 332 Validation accuracy: 0.625\n", - "Epoch 333 loss: 22.080169677734375\n", - "Epoch 333 Validation accuracy: 0.625\n", - "Epoch 334 loss: 22.066062927246094\n", - "Epoch 334 Validation accuracy: 0.625\n", - "Epoch 335 loss: 22.051239013671875\n", - "Epoch 335 Validation accuracy: 0.625\n", - "Epoch 336 loss: 22.04073715209961\n", - "Epoch 336 Validation accuracy: 0.625\n", - "Epoch 337 loss: 22.02910804748535\n", - "Epoch 337 Validation accuracy: 0.625\n", - "Epoch 338 loss: 22.01323127746582\n", - "Epoch 338 Validation accuracy: 0.625\n", - "Epoch 339 loss: 22.00203514099121\n", - "Epoch 339 Validation accuracy: 0.625\n", - "Epoch 340 loss: 21.9904842376709\n", - "Epoch 340 Validation accuracy: 0.625\n", - "Epoch 341 loss: 21.977466583251953\n", - "Epoch 341 Validation accuracy: 0.625\n", - "Epoch 342 loss: 21.96651840209961\n", - "Epoch 342 Validation accuracy: 0.625\n", - "Epoch 343 loss: 21.952547073364258\n", - "Epoch 343 Validation accuracy: 0.625\n", - "Epoch 344 loss: 21.943500518798828\n", - "Epoch 344 Validation accuracy: 0.625\n", - "Epoch 345 loss: 21.931215286254883\n", - "Epoch 345 Validation accuracy: 0.625\n", - "Epoch 346 loss: 21.920156478881836\n", - "Epoch 346 Validation accuracy: 0.625\n", - "Epoch 347 loss: 21.90941047668457\n", - "Epoch 347 Validation accuracy: 0.625\n", - "Epoch 348 loss: 21.897315979003906\n", - "Epoch 348 Validation accuracy: 0.625\n", - "Epoch 349 loss: 21.884029388427734\n", - "Epoch 349 Validation accuracy: 0.625\n", - "Epoch 350 loss: 21.870525360107422\n", - "Epoch 350 Validation accuracy: 0.625\n", - "Epoch 351 loss: 21.857534408569336\n", - "Epoch 351 Validation accuracy: 0.625\n", - "Epoch 352 loss: 21.847549438476562\n", - "Epoch 352 Validation accuracy: 0.625\n", - "Epoch 353 loss: 21.83431053161621\n", - "Epoch 353 Validation accuracy: 0.625\n", - "Epoch 354 loss: 21.82513999938965\n", - "Epoch 354 Validation accuracy: 0.625\n", - "Epoch 355 loss: 21.813926696777344\n", - "Epoch 355 Validation accuracy: 0.625\n", - "Epoch 356 loss: 21.80405044555664\n", - "Epoch 356 Validation accuracy: 0.625\n", - "Epoch 357 loss: 21.79069709777832\n", - "Epoch 357 Validation accuracy: 0.625\n", - "Epoch 358 loss: 21.777841567993164\n", - "Epoch 358 Validation accuracy: 0.625\n", - "Epoch 359 loss: 21.76871681213379\n", - "Epoch 359 Validation accuracy: 0.625\n", - "Epoch 360 loss: 21.757659912109375\n", - "Epoch 360 Validation accuracy: 0.625\n", - "Epoch 361 loss: 21.74506950378418\n", - "Epoch 361 Validation accuracy: 0.625\n", - "Epoch 362 loss: 21.73027992248535\n", - "Epoch 362 Validation accuracy: 0.625\n", - "Epoch 363 loss: 21.721105575561523\n", - "Epoch 363 Validation accuracy: 0.625\n", - "Epoch 364 loss: 21.70802116394043\n", - "Epoch 364 Validation accuracy: 0.625\n", - "Epoch 365 loss: 21.69561767578125\n", - "Epoch 365 Validation accuracy: 0.625\n", - "Epoch 366 loss: 21.686477661132812\n", - "Epoch 366 Validation accuracy: 0.625\n", - "Epoch 367 loss: 21.67528533935547\n", - "Epoch 367 Validation accuracy: 0.625\n", - "Epoch 368 loss: 21.6632022857666\n", - "Epoch 368 Validation accuracy: 0.625\n", - "Epoch 369 loss: 21.654359817504883\n", - "Epoch 369 Validation accuracy: 0.625\n", - "Epoch 370 loss: 21.6440486907959\n", - "Epoch 370 Validation accuracy: 0.625\n", - "Epoch 371 loss: 21.63262367248535\n", - "Epoch 371 Validation accuracy: 0.625\n", - "Epoch 372 loss: 21.62179183959961\n", - "Epoch 372 Validation accuracy: 0.625\n", - "Epoch 373 loss: 21.61004066467285\n", - "Epoch 373 Validation accuracy: 0.625\n", - "Epoch 374 loss: 21.599712371826172\n", - "Epoch 374 Validation accuracy: 0.625\n", - "Epoch 375 loss: 21.58791160583496\n", - "Epoch 375 Validation accuracy: 0.625\n", - "Epoch 376 loss: 21.574491500854492\n", - "Epoch 376 Validation accuracy: 0.625\n", - "Epoch 377 loss: 21.56350326538086\n", - "Epoch 377 Validation accuracy: 0.625\n", - "Epoch 378 loss: 21.55362319946289\n", - "Epoch 378 Validation accuracy: 0.625\n", - "Epoch 379 loss: 21.542652130126953\n", - "Epoch 379 Validation accuracy: 0.625\n", - "Epoch 380 loss: 21.531946182250977\n", - "Epoch 380 Validation accuracy: 0.625\n", - "Epoch 381 loss: 21.520584106445312\n", - "Epoch 381 Validation accuracy: 0.625\n", - "Epoch 382 loss: 21.508346557617188\n", - "Epoch 382 Validation accuracy: 0.625\n", - "Epoch 383 loss: 21.49889373779297\n", - "Epoch 383 Validation accuracy: 0.625\n", - "Epoch 384 loss: 21.488155364990234\n", - "Epoch 384 Validation accuracy: 0.625\n", - "Epoch 385 loss: 21.476438522338867\n", - "Epoch 385 Validation accuracy: 0.625\n", - "Epoch 386 loss: 21.46401596069336\n", - "Epoch 386 Validation accuracy: 0.625\n", - "Epoch 387 loss: 21.453584671020508\n", - "Epoch 387 Validation accuracy: 0.625\n", - "Epoch 388 loss: 21.442052841186523\n", - "Epoch 388 Validation accuracy: 0.625\n", - "Epoch 389 loss: 21.431604385375977\n", - "Epoch 389 Validation accuracy: 0.625\n", - "Epoch 390 loss: 21.420881271362305\n", - "Epoch 390 Validation accuracy: 0.625\n", - "Epoch 391 loss: 21.410736083984375\n", - "Epoch 391 Validation accuracy: 0.625\n", - "Epoch 392 loss: 21.401206970214844\n", - "Epoch 392 Validation accuracy: 0.625\n", - "Epoch 393 loss: 21.389665603637695\n", - "Epoch 393 Validation accuracy: 0.625\n", - "Epoch 394 loss: 21.37841796875\n", - "Epoch 394 Validation accuracy: 0.625\n", - "Epoch 395 loss: 21.36739730834961\n", - "Epoch 395 Validation accuracy: 0.625\n", - "Epoch 396 loss: 21.357166290283203\n", - "Epoch 396 Validation accuracy: 0.625\n", - "Epoch 397 loss: 21.347293853759766\n", - "Epoch 397 Validation accuracy: 0.625\n", - "Epoch 398 loss: 21.335630416870117\n", - "Epoch 398 Validation accuracy: 0.625\n", - "Epoch 399 loss: 21.327388763427734\n", - "Epoch 399 Validation accuracy: 0.625\n", - "Epoch 400 loss: 21.315521240234375\n", - "Epoch 400 Validation accuracy: 0.625\n", - "Epoch 401 loss: 21.30586051940918\n", - "Epoch 401 Validation accuracy: 0.625\n", - "Epoch 402 loss: 21.29657745361328\n", - "Epoch 402 Validation accuracy: 0.625\n", - "Epoch 403 loss: 21.28609848022461\n", - "Epoch 403 Validation accuracy: 0.625\n", - "Epoch 404 loss: 21.276351928710938\n", - "Epoch 404 Validation accuracy: 0.625\n", - "Epoch 405 loss: 21.265724182128906\n", - "Epoch 405 Validation accuracy: 0.625\n", - "Epoch 406 loss: 21.25368309020996\n", - "Epoch 406 Validation accuracy: 0.625\n", - "Epoch 407 loss: 21.241600036621094\n", - "Epoch 407 Validation accuracy: 0.625\n", - "Epoch 408 loss: 21.229310989379883\n", - "Epoch 408 Validation accuracy: 0.625\n", - "Epoch 409 loss: 21.2224178314209\n", - "Epoch 409 Validation accuracy: 0.625\n", - "Epoch 410 loss: 21.2132511138916\n", - "Epoch 410 Validation accuracy: 0.625\n", - "Epoch 411 loss: 21.199750900268555\n", - "Epoch 411 Validation accuracy: 0.625\n", - "Epoch 412 loss: 21.18743133544922\n", - "Epoch 412 Validation accuracy: 0.625\n", - "Epoch 413 loss: 21.1822509765625\n", - "Epoch 413 Validation accuracy: 0.625\n", - "Epoch 414 loss: 21.17019271850586\n", - "Epoch 414 Validation accuracy: 0.625\n", - "Epoch 415 loss: 21.155643463134766\n", - "Epoch 415 Validation accuracy: 0.625\n", - "Epoch 416 loss: 21.146547317504883\n", - "Epoch 416 Validation accuracy: 0.625\n", - "Epoch 417 loss: 21.136232376098633\n", - "Epoch 417 Validation accuracy: 0.625\n", - "Epoch 418 loss: 21.123960494995117\n", - "Epoch 418 Validation accuracy: 0.625\n", - "Epoch 419 loss: 21.11368751525879\n", - "Epoch 419 Validation accuracy: 0.625\n", - "Epoch 420 loss: 21.101808547973633\n", - "Epoch 420 Validation accuracy: 0.625\n", - "Epoch 421 loss: 21.09125518798828\n", - "Epoch 421 Validation accuracy: 0.625\n", - "Epoch 422 loss: 21.083723068237305\n", - "Epoch 422 Validation accuracy: 0.625\n", - "Epoch 423 loss: 21.07281494140625\n", - "Epoch 423 Validation accuracy: 0.625\n", - "Epoch 424 loss: 21.058805465698242\n", - "Epoch 424 Validation accuracy: 0.625\n", - "Epoch 425 loss: 21.049646377563477\n", - "Epoch 425 Validation accuracy: 0.625\n", - "Epoch 426 loss: 21.04451560974121\n", - "Epoch 426 Validation accuracy: 0.625\n", - "Epoch 427 loss: 21.0327091217041\n", - "Epoch 427 Validation accuracy: 0.625\n", - "Epoch 428 loss: 21.01663589477539\n", - "Epoch 428 Validation accuracy: 0.625\n", - "Epoch 429 loss: 21.00825309753418\n", - "Epoch 429 Validation accuracy: 0.625\n", - "Epoch 430 loss: 21.000246047973633\n", - "Epoch 430 Validation accuracy: 0.625\n", - "Epoch 431 loss: 20.990230560302734\n", - "Epoch 431 Validation accuracy: 0.625\n", - "Epoch 432 loss: 20.977436065673828\n", - "Epoch 432 Validation accuracy: 0.625\n", - "Epoch 433 loss: 20.96634864807129\n", - "Epoch 433 Validation accuracy: 0.625\n", - "Epoch 434 loss: 20.95425796508789\n", - "Epoch 434 Validation accuracy: 0.625\n", - "Epoch 435 loss: 20.939908981323242\n", - "Epoch 435 Validation accuracy: 0.625\n", - "Epoch 436 loss: 20.92905616760254\n", - "Epoch 436 Validation accuracy: 0.625\n", - "Epoch 437 loss: 20.918004989624023\n", - "Epoch 437 Validation accuracy: 0.625\n", - "Epoch 438 loss: 20.902795791625977\n", - "Epoch 438 Validation accuracy: 0.625\n", - "Epoch 439 loss: 20.884109497070312\n", - "Epoch 439 Validation accuracy: 0.625\n", - "Epoch 440 loss: 20.871601104736328\n", - "Epoch 440 Validation accuracy: 0.625\n", - "Epoch 441 loss: 20.85983657836914\n", - "Epoch 441 Validation accuracy: 0.625\n", - "Epoch 442 loss: 20.84302520751953\n", - "Epoch 442 Validation accuracy: 0.625\n", - "Epoch 443 loss: 20.82725715637207\n", - "Epoch 443 Validation accuracy: 0.625\n", - "Epoch 444 loss: 20.81039047241211\n", - "Epoch 444 Validation accuracy: 0.625\n", - "Epoch 445 loss: 20.79295539855957\n", - "Epoch 445 Validation accuracy: 0.625\n", - "Epoch 446 loss: 20.775209426879883\n", - "Epoch 446 Validation accuracy: 0.625\n", - "Epoch 447 loss: 20.761594772338867\n", - "Epoch 447 Validation accuracy: 0.625\n", - "Epoch 448 loss: 20.746509552001953\n", - "Epoch 448 Validation accuracy: 0.625\n", - "Epoch 449 loss: 20.734050750732422\n", - "Epoch 449 Validation accuracy: 0.625\n", - "Epoch 450 loss: 20.72390365600586\n", - "Epoch 450 Validation accuracy: 0.625\n", - "Epoch 451 loss: 20.70878028869629\n", - "Epoch 451 Validation accuracy: 0.625\n", - "Epoch 452 loss: 20.69400405883789\n", - "Epoch 452 Validation accuracy: 0.625\n", - "Epoch 453 loss: 20.678071975708008\n", - "Epoch 453 Validation accuracy: 0.625\n", - "Epoch 454 loss: 20.666906356811523\n", - "Epoch 454 Validation accuracy: 0.625\n", - "Epoch 455 loss: 20.6538143157959\n", - "Epoch 455 Validation accuracy: 0.625\n", - "Epoch 456 loss: 20.6412410736084\n", - "Epoch 456 Validation accuracy: 0.625\n", - "Epoch 457 loss: 20.629528045654297\n", - "Epoch 457 Validation accuracy: 0.625\n", - "Epoch 458 loss: 20.61863899230957\n", - "Epoch 458 Validation accuracy: 0.625\n", - "Epoch 459 loss: 20.606908798217773\n", - "Epoch 459 Validation accuracy: 0.625\n", - "Epoch 460 loss: 20.595272064208984\n", - "Epoch 460 Validation accuracy: 0.625\n", - "Epoch 461 loss: 20.58217430114746\n", - "Epoch 461 Validation accuracy: 0.625\n", - "Epoch 462 loss: 20.568185806274414\n", - "Epoch 462 Validation accuracy: 0.625\n", - "Epoch 463 loss: 20.558835983276367\n", - "Epoch 463 Validation accuracy: 0.625\n", - "Epoch 464 loss: 20.548227310180664\n", - "Epoch 464 Validation accuracy: 0.625\n", - "Epoch 465 loss: 20.534801483154297\n", - "Epoch 465 Validation accuracy: 0.625\n", - "Epoch 466 loss: 20.52486228942871\n", - "Epoch 466 Validation accuracy: 0.625\n", - "Epoch 467 loss: 20.514476776123047\n", - "Epoch 467 Validation accuracy: 0.625\n", - "Epoch 468 loss: 20.506332397460938\n", - "Epoch 468 Validation accuracy: 0.625\n", - "Epoch 469 loss: 20.492887496948242\n", - "Epoch 469 Validation accuracy: 0.625\n", - "Epoch 470 loss: 20.481121063232422\n", - "Epoch 470 Validation accuracy: 0.625\n", - "Epoch 471 loss: 20.469911575317383\n", - "Epoch 471 Validation accuracy: 0.625\n", - "Epoch 472 loss: 20.46491813659668\n", - "Epoch 472 Validation accuracy: 0.625\n", - "Epoch 473 loss: 20.452470779418945\n", - "Epoch 473 Validation accuracy: 0.625\n", - "Epoch 474 loss: 20.435522079467773\n", - "Epoch 474 Validation accuracy: 0.625\n", - "Epoch 475 loss: 20.428197860717773\n", - "Epoch 475 Validation accuracy: 0.625\n", - "Epoch 476 loss: 20.420866012573242\n", - "Epoch 476 Validation accuracy: 0.625\n", - "Epoch 477 loss: 20.40703773498535\n", - "Epoch 477 Validation accuracy: 0.625\n", - "Epoch 478 loss: 20.395797729492188\n", - "Epoch 478 Validation accuracy: 0.625\n", - "Epoch 479 loss: 20.38579559326172\n", - "Epoch 479 Validation accuracy: 0.625\n", - "Epoch 480 loss: 20.372974395751953\n", - "Epoch 480 Validation accuracy: 0.625\n", - "Epoch 481 loss: 20.36663246154785\n", - "Epoch 481 Validation accuracy: 0.625\n", - "Epoch 482 loss: 20.354814529418945\n", - "Epoch 482 Validation accuracy: 0.625\n", - "Epoch 483 loss: 20.3371524810791\n", - "Epoch 483 Validation accuracy: 0.625\n", - "Epoch 484 loss: 20.334217071533203\n", - "Epoch 484 Validation accuracy: 0.625\n", - "Epoch 485 loss: 20.32594871520996\n", - "Epoch 485 Validation accuracy: 0.625\n", - "Epoch 486 loss: 20.31154441833496\n", - "Epoch 486 Validation accuracy: 0.625\n", - "Epoch 487 loss: 20.300630569458008\n", - "Epoch 487 Validation accuracy: 0.625\n", - "Epoch 488 loss: 20.291522979736328\n", - "Epoch 488 Validation accuracy: 0.625\n", - "Epoch 489 loss: 20.277509689331055\n", - "Epoch 489 Validation accuracy: 0.625\n", - "Epoch 490 loss: 20.264963150024414\n", - "Epoch 490 Validation accuracy: 0.625\n", - "Epoch 491 loss: 20.253454208374023\n", - "Epoch 491 Validation accuracy: 0.625\n", - "Epoch 492 loss: 20.240015029907227\n", - "Epoch 492 Validation accuracy: 0.625\n", - "Epoch 493 loss: 20.22855567932129\n", - "Epoch 493 Validation accuracy: 0.625\n", - "Epoch 494 loss: 20.216880798339844\n", - "Epoch 494 Validation accuracy: 0.625\n", - "Epoch 495 loss: 20.206361770629883\n", - "Epoch 495 Validation accuracy: 0.625\n", - "Epoch 496 loss: 20.196760177612305\n", - "Epoch 496 Validation accuracy: 0.625\n", - "Epoch 497 loss: 20.184263229370117\n", - "Epoch 497 Validation accuracy: 0.625\n", - "Epoch 498 loss: 20.171443939208984\n", - "Epoch 498 Validation accuracy: 0.625\n", - "Epoch 499 loss: 20.160396575927734\n", - "Epoch 499 Validation accuracy: 0.625\n", - "Test accuracy: 0.85\n" + "Epoch 0 train loss: 88.3000259399414\n", + "Epoch 0 Val acc: 0.4375\n", + "Epoch 10 train loss: 49.60942077636719\n", + "Epoch 10 Val acc: 0.5625\n", + "Epoch 20 train loss: 30.046979904174805\n", + "Epoch 20 Val acc: 0.625\n", + "Test accuracy: 0.8\n" ] } ], "source": [ - "num_epochs = 500\n", + "torch.manual_seed(0)\n", + "test_interval = 10\n", + "num_epochs = 30\n", "for epoch in range(num_epochs):\n", " model.train()\n", " optimizer.zero_grad()\n", " loss = 0\n", " for x_1, incidence_1, y in zip(x_1_train, incidence_1_train, y_train):\n", " output = model(x_1.float(), incidence_1.float())\n", + " output = torch.nn.functional.sigmoid(output)\n", " loss += crit(output, torch.tensor([y]).float())\n", " loss.backward()\n", " optimizer.step()\n", - " print(f\"Epoch {epoch} loss: {loss.item()}\")\n", - " model.eval()\n", - " with torch.no_grad():\n", - " correct = 0\n", - " for x_1, incidence_1, y in zip(x_1_val, incidence_1_val, y_val):\n", - " output = model(x_1.float(), incidence_1.float())\n", - " pred = output > 0.5\n", - " if pred == y:\n", - " correct += 1\n", - " print(f\"Epoch {epoch} Validation accuracy: {correct / len(y_val)}\")\n", + " \n", + " if epoch % test_interval == 0:\n", + " print(f\"Epoch {epoch} train loss: {loss.item()}\")\n", + " model.eval()\n", + " with torch.no_grad():\n", + " correct = 0\n", + " for x_1, incidence_1, y in zip(x_1_val, incidence_1_val, y_val):\n", + " output = model(x_1.float(), incidence_1.float())\n", + " output = torch.nn.functional.sigmoid(output)\n", + " pred = output > 0.5\n", + " if pred == y:\n", + " correct += 1\n", + " print(f\"Epoch {epoch} Val acc: {correct / len(y_val)}\")\n", "\n", "model.eval()\n", "with torch.no_grad():\n", " correct = 0\n", " for x_1, incidence_1, y in zip(x_1_test, incidence_1_test, y_test):\n", " output = model(x_1.float(), incidence_1.float())\n", + " output = torch.nn.functional.sigmoid(output)\n", " pred = output > 0.5\n", " if pred == y:\n", " correct += 1\n", @@ -1201,7 +222,7 @@ { "cell_type": "code", "execution_count": null, - "id": "c32a5282", + "id": "efa3bc9b", "metadata": {}, "outputs": [], "source": [] diff --git a/tutorials/hypergraph/unigcnii_train.ipynb b/tutorials/hypergraph/unigcnii_train.ipynb index 046585750..578860874 100644 --- a/tutorials/hypergraph/unigcnii_train.ipynb +++ b/tutorials/hypergraph/unigcnii_train.ipynb @@ -73,59 +73,53 @@ "name": "stdout", "output_type": "stream", "text": [ - "--2023-09-22 07:15:07-- https://github.com/malllabiisc/HyperGCN/raw/master/data/cocitation/cora/features.pickle\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Resolving github.com (github.com)... 192.30.255.113\n", - "Connecting to github.com (github.com)|192.30.255.113|:443... connected.\n", + "--2023-10-31 11:48:45-- https://github.com/malllabiisc/HyperGCN/raw/master/data/cocitation/cora/features.pickle\n", + "Resolving github.com (github.com)... 140.82.121.3\n", + "Connecting to github.com (github.com)|140.82.121.3|:443... connected.\n", "HTTP request sent, awaiting response... 302 Found\n", "Location: https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/features.pickle [following]\n", - "--2023-09-22 07:15:08-- https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/features.pickle\n", - "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.109.133, 185.199.108.133, 185.199.111.133, ...\n", + "--2023-10-31 11:48:46-- https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/features.pickle\n", + "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.109.133, 185.199.110.133, 185.199.111.133, ...\n", "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.109.133|:443... connected.\n", "HTTP request sent, awaiting response... 200 OK\n", "Length: 404937 (395K) [application/octet-stream]\n", - "Saving to: ‘features.pickle’\n", + "Saving to: ‘features.pickle.5’\n", "\n", - "features.pickle 100%[===================>] 395.45K --.-KB/s in 0.01s \n", + "features.pickle.5 100%[===================>] 395.45K --.-KB/s in 0.006s \n", "\n", - "2023-09-22 07:15:08 (31.5 MB/s) - ‘features.pickle’ saved [404937/404937]\n", + "2023-10-31 11:48:46 (64.7 MB/s) - ‘features.pickle.5’ saved [404937/404937]\n", "\n", - "--2023-09-22 07:15:08-- https://github.com/malllabiisc/HyperGCN/raw/master/data/cocitation/cora/hypergraph.pickle\n", - "Resolving github.com (github.com)... 192.30.255.113\n", - "Connecting to github.com (github.com)|192.30.255.113|:443... connected.\n", + "--2023-10-31 11:48:46-- https://github.com/malllabiisc/HyperGCN/raw/master/data/cocitation/cora/hypergraph.pickle\n", + "Resolving github.com (github.com)... 140.82.121.3\n", + "Connecting to github.com (github.com)|140.82.121.3|:443... connected.\n", "HTTP request sent, awaiting response... 302 Found\n", "Location: https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/hypergraph.pickle [following]\n", - "--2023-09-22 07:15:09-- https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/hypergraph.pickle\n", - "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.110.133, 185.199.109.133, ...\n", - "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.\n", + "--2023-10-31 11:48:46-- https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/hypergraph.pickle\n", + "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.109.133, 185.199.110.133, 185.199.111.133, ...\n", + "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.109.133|:443... connected.\n", "HTTP request sent, awaiting response... 200 OK\n", "Length: 101905 (100K) [application/octet-stream]\n", - "Saving to: ‘hypergraph.pickle’\n", + "Saving to: ‘hypergraph.pickle.5’\n", "\n", - "hypergraph.pickle 100%[===================>] 99.52K --.-KB/s in 0.006s \n", + "hypergraph.pickle.5 100%[===================>] 99.52K --.-KB/s in 0.02s \n", "\n", - "2023-09-22 07:15:09 (16.7 MB/s) - ‘hypergraph.pickle’ saved [101905/101905]\n", + "2023-10-31 11:48:46 (4.63 MB/s) - ‘hypergraph.pickle.5’ saved [101905/101905]\n", "\n", - "--2023-09-22 07:15:09-- https://github.com/malllabiisc/HyperGCN/raw/master/data/cocitation/cora/labels.pickle\n", - "Resolving github.com (github.com)... 192.30.255.113\n", - "Connecting to github.com (github.com)|192.30.255.113|:443... connected.\n", + "--2023-10-31 11:48:46-- https://github.com/malllabiisc/HyperGCN/raw/master/data/cocitation/cora/labels.pickle\n", + "Resolving github.com (github.com)... 140.82.121.3\n", + "Connecting to github.com (github.com)|140.82.121.3|:443... connected.\n", "HTTP request sent, awaiting response... 302 Found\n", "Location: https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/labels.pickle [following]\n", - "--2023-09-22 07:15:10-- https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/labels.pickle\n", - "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.111.133, 185.199.108.133, 185.199.109.133, ...\n", - "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.111.133|:443... connected.\n", + "--2023-10-31 11:48:47-- https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/labels.pickle\n", + "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.109.133, 185.199.110.133, 185.199.111.133, ...\n", + "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.109.133|:443... connected.\n", "HTTP request sent, awaiting response... 200 OK\n", "Length: 5436 (5.3K) [application/octet-stream]\n", - "Saving to: ‘labels.pickle’\n", + "Saving to: ‘labels.pickle.5’\n", "\n", - "labels.pickle 100%[===================>] 5.31K --.-KB/s in 0s \n", + "labels.pickle.5 100%[===================>] 5.31K --.-KB/s in 0s \n", "\n", - "2023-09-22 07:15:10 (46.0 MB/s) - ‘labels.pickle’ saved [5436/5436]\n", + "2023-10-31 11:48:47 (57.9 MB/s) - ‘labels.pickle.5’ saved [5436/5436]\n", "\n" ] } @@ -145,27 +139,21 @@ "name": "stdout", "output_type": "stream", "text": [ - "--2023-09-22 07:15:10-- https://github.com/malllabiisc/HyperGCN/raw/master/data/cocitation/cora/splits/1.pickle\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Resolving github.com (github.com)... 192.30.255.113\n", - "Connecting to github.com (github.com)|192.30.255.113|:443... connected.\n", + "--2023-10-31 11:48:47-- https://github.com/malllabiisc/HyperGCN/raw/master/data/cocitation/cora/splits/1.pickle\n", + "Resolving github.com (github.com)... 140.82.121.3\n", + "Connecting to github.com (github.com)|140.82.121.3|:443... connected.\n", "HTTP request sent, awaiting response... 302 Found\n", "Location: https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/splits/1.pickle [following]\n", - "--2023-09-22 07:15:11-- https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/splits/1.pickle\n", - "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.111.133, 185.199.110.133, ...\n", - "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.\n", + "--2023-10-31 11:48:47-- https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/splits/1.pickle\n", + "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.109.133, 185.199.110.133, 185.199.111.133, ...\n", + "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.109.133|:443... connected.\n", "HTTP request sent, awaiting response... 200 OK\n", "Length: 51582 (50K) [application/octet-stream]\n", - "Saving to: ‘1.pickle’\n", + "Saving to: ‘1.pickle.5’\n", "\n", - "1.pickle 100%[===================>] 50.37K --.-KB/s in 0.003s \n", + "1.pickle.5 100%[===================>] 50.37K --.-KB/s in 0.01s \n", "\n", - "2023-09-22 07:15:11 (14.8 MB/s) - ‘1.pickle’ saved [51582/51582]\n", + "2023-10-31 11:48:47 (4.02 MB/s) - ‘1.pickle.5’ saved [51582/51582]\n", "\n" ] } @@ -190,7 +178,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/tmp/ipykernel_1201318/2369537045.py:2: DeprecationWarning: Please use `csr_matrix` from the `scipy.sparse` namespace, the `scipy.sparse.csr` namespace is deprecated.\n", + "/tmp/ipykernel_42535/2369537045.py:2: DeprecationWarning: Please use `csr_matrix` from the `scipy.sparse` namespace, the `scipy.sparse.csr` namespace is deprecated.\n", " features = pickle.load(handle).todense()\n" ] } @@ -243,7 +231,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/tmp/ipykernel_1201318/2226475299.py:6: UserWarning: Sparse CSR tensor support is in beta state. If you miss a functionality in the sparse tensor support, please submit a feature request to https://github.com/pytorch/pytorch/issues. (Triggered internally at ../aten/src/ATen/SparseCsrTensorImpl.cpp:54.)\n", + "/tmp/ipykernel_42535/2226475299.py:6: UserWarning: Sparse CSR tensor support is in beta state. If you miss a functionality in the sparse tensor support, please submit a feature request to https://github.com/pytorch/pytorch/issues. (Triggered internally at ../aten/src/ATen/SparseCsrTensorImpl.cpp:54.)\n", " incidence = torch.Tensor(incidence).to_sparse_csr()\n" ] } @@ -293,9 +281,21 @@ "metadata": {}, "outputs": [], "source": [ - "channels = x_0.shape[1]\n", - "classes = 7 # current problem has 7 classes\n", - "model = UniGCNII(num_classes=classes, in_features=channels, num_layers=3).to(device)" + "in_channels = x_0.shape[1]\n", + "hidden_channels = 128\n", + "out_channels = torch.unique(y).shape[0]\n", + "task_level = \"graph\" if out_channels==1 else \"node\"\n", + "n_layers=2\n", + "\n", + "model = UniGCNII(\n", + " in_channels=in_channels,\n", + " hidden_channels=hidden_channels,\n", + " out_channels=out_channels,\n", + " n_layers=n_layers,\n", + " input_drop=0.5,\n", + " task_level=task_level,\n", + " \n", + ").to(device)" ] }, { @@ -313,7 +313,7 @@ "metadata": {}, "outputs": [], "source": [ - "num_epochs = 50\n", + "num_epochs = 30\n", "test_interval = 5" ] }, @@ -330,8 +330,14 @@ "metadata": {}, "outputs": [], "source": [ + "# Optimizer and loss\n", "optimizer = torch.optim.Adam(model.parameters(), lr=0.01)\n", - "loss_fn = torch.nn.CrossEntropyLoss()" + "\n", + "# Categorial cross-entropy loss\n", + "loss_fn = torch.nn.CrossEntropyLoss()\n", + "\n", + "# Accuracy\n", + "acc_fn = lambda y, y_hat: (y == y_hat).float().mean()" ] }, { @@ -350,20 +356,17 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch: 5 \t Train accuracy: 0.8357142806053162 \t Test accuracy: 0.47507786750793457\n", - "Epoch: 10 \t Train accuracy: 0.7642857432365417 \t Test accuracy: 0.5183022022247314\n", - "Epoch: 15 \t Train accuracy: 0.9214285612106323 \t Test accuracy: 0.5611370801925659\n", - "Epoch: 20 \t Train accuracy: 0.9428571462631226 \t Test accuracy: 0.597741425037384\n", - "Epoch: 25 \t Train accuracy: 0.9642857313156128 \t Test accuracy: 0.5915108919143677\n", - "Epoch: 30 \t Train accuracy: 0.9857142567634583 \t Test accuracy: 0.5837227702140808\n", - "Epoch: 35 \t Train accuracy: 0.9571428298950195 \t Test accuracy: 0.579828679561615\n", - "Epoch: 40 \t Train accuracy: 0.9857142567634583 \t Test accuracy: 0.5654205679893494\n", - "Epoch: 45 \t Train accuracy: 1.0 \t Test accuracy: 0.5735981464385986\n", - "Epoch: 50 \t Train accuracy: 1.0 \t Test accuracy: 0.5813862681388855\n" + "Epoch: 0 Train_loss: 1.6293, Train_acc: 0.9000 Test_loss: 1.8150, Test_acc: 0.5078\n", + "Epoch: 5 Train_loss: 0.0929, Train_acc: 1.0000 Test_loss: 0.9898, Test_acc: 0.6928\n", + "Epoch: 10 Train_loss: 0.0060, Train_acc: 1.0000 Test_loss: 2.0497, Test_acc: 0.6515\n", + "Epoch: 15 Train_loss: 0.0097, Train_acc: 0.9929 Test_loss: 3.4201, Test_acc: 0.6604\n", + "Epoch: 20 Train_loss: 0.0007, Train_acc: 1.0000 Test_loss: 5.2454, Test_acc: 0.6293\n", + "Epoch: 25 Train_loss: 0.0000, Train_acc: 1.0000 Test_loss: 4.5545, Test_acc: 0.6538\n" ] } ], "source": [ + "torch.manual_seed(0)\n", "for epoch in range(num_epochs):\n", " # set model to training mode\n", " model.train()\n", @@ -375,20 +378,33 @@ " optimizer.step()\n", " optimizer.zero_grad()\n", "\n", - " # Evaluate performance on the validation data\n", - " if (epoch + 1) % test_interval == 0:\n", - " model.eval()\n", - " with torch.no_grad():\n", - " y_hat = model(x_0, incidence)\n", - " y_pred = torch.argmax(y_hat, dim=1)\n", "\n", - " train_acc = (y_pred[train_idx] == y[train_idx]).float().mean()\n", - " test_acc = (y_pred[test_idx] == y[test_idx]).float().mean()\n", + " if epoch % test_interval == 0:\n", + " \n", + " model.eval()\n", + " y_hat = model(x_0, incidence)\n", "\n", - " print(\n", - " f\"Epoch: {epoch + 1} \\t Train accuracy: {train_acc} \\t Test accuracy: {test_acc}\"\n", - " )" + " train_loss = loss_fn(y_hat[train_idx], y[train_idx])\n", + " loss = loss_fn(y_hat[test_idx], y[test_idx])\n", + " print(f\"Epoch: {epoch} \\\n", + " Train_loss: {train_loss:.4f}, Train_acc: {acc_fn(y_hat[train_idx].argmax(1), y[train_idx]):.4f} \\\n", + " Test_loss: {loss:.4f}, Test_acc: {acc_fn(y_hat[test_idx].argmax(1), y[test_idx]):.4f}\",\n", + " flush=True)" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { diff --git a/tutorials/hypergraph/unigin_train.ipynb b/tutorials/hypergraph/unigin_train.ipynb index d9c6e6639..81ac49fb5 100644 --- a/tutorials/hypergraph/unigin_train.ipynb +++ b/tutorials/hypergraph/unigin_train.ipynb @@ -79,14 +79,20 @@ "metadata": {}, "outputs": [], "source": [ - "node_dim = x_1_list[0].shape[1]\n", - "intermediate_channels = 32\n", - "out_dim = 2\n", + "in_channels = x_1_list[0].shape[1]\n", + "hidden_channels = 32\n", + "out_channels = 2\n", + "n_layers= 3\n", + "task_level = \"graph\"\n", + "\n", "model = UniGIN(\n", - " in_channels_node=node_dim,\n", - " intermediate_channels=intermediate_channels,\n", - " out_channels=out_dim,\n", - " n_layers=2,\n", + " in_channels=in_channels,\n", + " hidden_channels=hidden_channels,\n", + " out_channels=out_channels, \n", + " input_drop=0.2,\n", + " layer_drop=0.2,\n", + " n_layers=n_layers,\n", + " task_level=task_level,\n", ")" ] }, @@ -106,7 +112,7 @@ "metadata": {}, "outputs": [], "source": [ - "optimizer = torch.optim.Adam(model.parameters(), lr=0.001)\n", + "optimizer = torch.optim.Adam(model.parameters(), lr=0.01)\n", "crit = torch.nn.CrossEntropyLoss()" ] }, @@ -142,7 +148,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "The below cell trains the model for 50 epochs printing the train loss, and validation accuracy after every epoch. The model is then evaluated on a seperate test-set after training." + "The below cell trains the model for 70 epochs printing the train loss, and validation accuracy after every epoch. The model is then evaluated on a seperate test-set after training." ] }, { @@ -154,112 +160,28 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch 0 loss: 43.388511657714844\n", + "Epoch 0 loss: 264.6469421386719\n", "Epoch 0 Validation accuracy: 0.5625\n", - "Epoch 1 loss: 41.726402282714844\n", - "Epoch 1 Validation accuracy: 0.5625\n", - "Epoch 2 loss: 40.228939056396484\n", - "Epoch 2 Validation accuracy: 0.5625\n", - "Epoch 3 loss: 38.930335998535156\n", - "Epoch 3 Validation accuracy: 0.5625\n", - "Epoch 4 loss: 37.89554214477539\n", - "Epoch 4 Validation accuracy: 0.5625\n", - "Epoch 5 loss: 37.096839904785156\n", - "Epoch 5 Validation accuracy: 0.5625\n", - "Epoch 6 loss: 36.53312301635742\n", - "Epoch 6 Validation accuracy: 0.5625\n", - "Epoch 7 loss: 36.17842483520508\n", - "Epoch 7 Validation accuracy: 0.5625\n", - "Epoch 8 loss: 35.982330322265625\n", - "Epoch 8 Validation accuracy: 0.5625\n", - "Epoch 9 loss: 35.8914680480957\n", - "Epoch 9 Validation accuracy: 0.5625\n", - "Epoch 10 loss: 35.861602783203125\n", + "Epoch 10 loss: 41.20396041870117\n", "Epoch 10 Validation accuracy: 0.5625\n", - "Epoch 11 loss: 35.86212921142578\n", - "Epoch 11 Validation accuracy: 0.5625\n", - "Epoch 12 loss: 35.87543869018555\n", - "Epoch 12 Validation accuracy: 0.5625\n", - "Epoch 13 loss: 35.89324951171875\n", - "Epoch 13 Validation accuracy: 0.5625\n", - "Epoch 14 loss: 35.91067886352539\n", - "Epoch 14 Validation accuracy: 0.5625\n", - "Epoch 15 loss: 35.92604446411133\n", - "Epoch 15 Validation accuracy: 0.5625\n", - "Epoch 16 loss: 35.93891525268555\n", - "Epoch 16 Validation accuracy: 0.5625\n", - "Epoch 17 loss: 35.949344635009766\n", - "Epoch 17 Validation accuracy: 0.5625\n", - "Epoch 18 loss: 35.9575080871582\n", - "Epoch 18 Validation accuracy: 0.5625\n", - "Epoch 19 loss: 35.963714599609375\n", - "Epoch 19 Validation accuracy: 0.5625\n", - "Epoch 20 loss: 35.96826934814453\n", + "Epoch 20 loss: 35.169708251953125\n", "Epoch 20 Validation accuracy: 0.5625\n", - "Epoch 21 loss: 35.97142791748047\n", - "Epoch 21 Validation accuracy: 0.5625\n", - "Epoch 22 loss: 35.97331619262695\n", - "Epoch 22 Validation accuracy: 0.5625\n", - "Epoch 23 loss: 35.974063873291016\n", - "Epoch 23 Validation accuracy: 0.5625\n", - "Epoch 24 loss: 35.97380828857422\n", - "Epoch 24 Validation accuracy: 0.5625\n", - "Epoch 25 loss: 35.97255325317383\n", - "Epoch 25 Validation accuracy: 0.5625\n", - "Epoch 26 loss: 35.97031784057617\n", - "Epoch 26 Validation accuracy: 0.5625\n", - "Epoch 27 loss: 35.96706008911133\n", - "Epoch 27 Validation accuracy: 0.5625\n", - "Epoch 28 loss: 35.96271896362305\n", - "Epoch 28 Validation accuracy: 0.5625\n", - "Epoch 29 loss: 35.957176208496094\n", - "Epoch 29 Validation accuracy: 0.5625\n", - "Epoch 30 loss: 35.95022964477539\n", + "Epoch 30 loss: 30.082611083984375\n", "Epoch 30 Validation accuracy: 0.5625\n", - "Epoch 31 loss: 35.941707611083984\n", - "Epoch 31 Validation accuracy: 0.5625\n", - "Epoch 32 loss: 35.93131637573242\n", - "Epoch 32 Validation accuracy: 0.5625\n", - "Epoch 33 loss: 35.918678283691406\n", - "Epoch 33 Validation accuracy: 0.5625\n", - "Epoch 34 loss: 35.90337371826172\n", - "Epoch 34 Validation accuracy: 0.5625\n", - "Epoch 35 loss: 35.884979248046875\n", - "Epoch 35 Validation accuracy: 0.5625\n", - "Epoch 36 loss: 35.863189697265625\n", - "Epoch 36 Validation accuracy: 0.5625\n", - "Epoch 37 loss: 35.837684631347656\n", - "Epoch 37 Validation accuracy: 0.5625\n", - "Epoch 38 loss: 35.808353424072266\n", - "Epoch 38 Validation accuracy: 0.5625\n", - "Epoch 39 loss: 35.776126861572266\n", - "Epoch 39 Validation accuracy: 0.5625\n", - "Epoch 40 loss: 35.743309020996094\n", + "Epoch 40 loss: 26.874971389770508\n", "Epoch 40 Validation accuracy: 0.5625\n", - "Epoch 41 loss: 35.71380615234375\n", - "Epoch 41 Validation accuracy: 0.5625\n", - "Epoch 42 loss: 35.691314697265625\n", - "Epoch 42 Validation accuracy: 0.5625\n", - "Epoch 43 loss: 35.67386245727539\n", - "Epoch 43 Validation accuracy: 0.5625\n", - "Epoch 44 loss: 35.649879455566406\n", - "Epoch 44 Validation accuracy: 0.5625\n", - "Epoch 45 loss: 35.607601165771484\n", - "Epoch 45 Validation accuracy: 0.5625\n", - "Epoch 46 loss: 35.54794692993164\n", - "Epoch 46 Validation accuracy: 0.5625\n", - "Epoch 47 loss: 35.47976303100586\n", - "Epoch 47 Validation accuracy: 0.5625\n", - "Epoch 48 loss: 35.408973693847656\n", - "Epoch 48 Validation accuracy: 0.5625\n", - "Epoch 49 loss: 35.33806228637695\n", - "Epoch 49 Validation accuracy: 0.5625\n", - "Test accuracy: 0.75\n" + "Epoch 50 loss: 21.022449493408203\n", + "Epoch 50 Validation accuracy: 0.5625\n", + "Epoch 60 loss: 26.520870208740234\n", + "Epoch 60 Validation accuracy: 0.625\n", + "Test accuracy: 0.7\n" ] } ], "source": [ - "num_epochs = 50\n", + "torch.manual_seed(0)\n", + "test_interval = 10\n", + "num_epochs = 70\n", "for epoch in range(num_epochs):\n", " model.train()\n", " optimizer.zero_grad()\n", @@ -269,16 +191,17 @@ " loss += crit(output.unsqueeze(0), torch.tensor([y]))\n", " loss.backward()\n", " optimizer.step()\n", - " print(f\"Epoch {epoch} loss: {loss.item()}\")\n", - " model.eval()\n", - " with torch.no_grad():\n", - " correct = 0\n", - " for x_1, incidence_1, y in zip(x_1_val, incidence_1_val, y_val):\n", - " output = model(x_1, incidence_1)\n", - " pred = torch.argmax(output)\n", - " if pred == y:\n", - " correct += 1\n", - " print(f\"Epoch {epoch} Validation accuracy: {correct / len(y_val)}\")\n", + " if epoch % test_interval == 0:\n", + " print(f\"Epoch {epoch} loss: {loss.item()}\")\n", + " model.eval()\n", + " with torch.no_grad():\n", + " correct = 0\n", + " for x_1, incidence_1, y in zip(x_1_val, incidence_1_val, y_val):\n", + " output = model(x_1, incidence_1)\n", + " pred = torch.argmax(output)\n", + " if pred == y:\n", + " correct += 1\n", + " print(f\"Epoch {epoch} Validation accuracy: {correct / len(y_val)}\")\n", "\n", "model.eval()\n", "with torch.no_grad():\n", @@ -290,6 +213,20 @@ " correct += 1\n", " print(f\"Test accuracy: {correct / len(y_test)}\")" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { diff --git a/tutorials/hypergraph/unisage_train.ipynb b/tutorials/hypergraph/unisage_train.ipynb index a9ab4348d..f6acea943 100644 --- a/tutorials/hypergraph/unisage_train.ipynb +++ b/tutorials/hypergraph/unisage_train.ipynb @@ -7,15 +7,12 @@ "metadata": {}, "outputs": [], "source": [ - "%load_ext autoreload\n", - "%autoreload 2\n", "\n", "import torch\n", "import numpy as np\n", "from sklearn.model_selection import train_test_split\n", - "from torch_geometric.datasets import TUDataset\n", - "from torch_geometric.utils.convert import to_networkx\n", - "from toponetx.classes.simplicial_complex import SimplicialComplex\n", + "from torch_geometric.utils import to_undirected\n", + "import torch_geometric.datasets as geom_datasets\n", "\n", "from topomodelx.nn.hypergraph.unisage import UniSAGE\n", "import warnings\n", @@ -23,6 +20,25 @@ "warnings.filterwarnings(\"ignore\")" ] }, + { + "cell_type": "code", + "execution_count": 2, + "id": "9edb4db4", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "cpu\n" + ] + } + ], + "source": [ + "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n", + "print(device)" + ] + }, { "cell_type": "markdown", "id": "b7251cc4", @@ -40,36 +56,144 @@ "\n", "## Import data ##\n", "\n", - "The first step is to import the dataset, MUTAG, a benchmark dataset for graph classification. We then lift each graph into our domain of choice, a hypergraph.\n", - "\n", - "We will also retrieve:\n", - "- input signal on the edges for each of these hypergraphs, as that will be what we feed the model in input\n", - "- the binary label associated to the hypergraph" + "The first step is to import the dataset, Cora, a benchmark classification datase. We then lift the graph into our domain of choice, a hypergraph.\n" ] }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "id": "b9e6b0d0", "metadata": {}, "outputs": [], "source": [ - "dataset = TUDataset(root=\"/tmp/MUTAG\", name=\"MUTAG\", use_edge_attr=True)\n", - "dataset = dataset[:100]\n", - "hg_list = []\n", - "x_1_list = []\n", - "y_list = []\n", - "for graph in dataset:\n", - " hg = SimplicialComplex(to_networkx(graph)).to_hypergraph()\n", - " hg_list.append(hg)\n", - " x_1_list.append(graph.x)\n", - " y_list.append(int(graph.y))\n", + "cora = geom_datasets.Planetoid(root=\"/TopoModelX/data/cora\", name=\"Cora\")\n", + "data = cora.data\n", + "\n", + "x_0s = data.x\n", + "y = data.y\n", + "edge_index = data.edge_index\n", + "\n", + "train_mask = data.train_mask\n", + "val_mask = data.val_mask\n", + "test_mask = data.test_mask" + ] + }, + { + "cell_type": "markdown", + "id": "c04619c6", + "metadata": {}, + "source": [ + "## Define neighborhood structures and lift into hypergraph domain. ##\n", + "\n", + "Now we retrieve the neighborhood structure (i.e. their representative matrice) that we will use to send messges from node to hyperedges. In the case of this architecture, we need the boundary matrix (or incidence matrix) $B_1$ with shape $n_\\text{nodes} \\times n_\\text{edges}$.\n", + "\n", + "In citation Cora dataset we lift graph structure to the hypergraph domain by creating hyperedges from 1-hop graph neighbourhood of each node. \n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "971f9cd1", + "metadata": {}, + "outputs": [], + "source": [ + "# Ensure the graph is undirected (optional but often useful for one-hop neighborhoods).\n", + "edge_index = to_undirected(edge_index)\n", + "\n", + "# Create a list of one-hop neighborhoods for each node.\n", + "one_hop_neighborhoods = []\n", + "for node in range(data.num_nodes):\n", + " # Get the one-hop neighbors of the current node.\n", + " neighbors = data.edge_index[1, data.edge_index[0] == node]\n", + "\n", + " # Append the neighbors to the list of one-hop neighborhoods.\n", + " one_hop_neighborhoods.append(neighbors.numpy())\n", + "\n", + "# Detect and eliminate duplicate hyperedges.\n", + "unique_hyperedges = set()\n", + "hyperedges = []\n", + "for neighborhood in one_hop_neighborhoods:\n", + " # Sort the neighborhood to ensure consistent comparison.\n", + " neighborhood = tuple(sorted(neighborhood))\n", + " if neighborhood not in unique_hyperedges:\n", + " hyperedges.append(list(neighborhood))\n", + " unique_hyperedges.add(neighborhood) " + ] + }, + { + "cell_type": "markdown", + "id": "ac5e12b4", + "metadata": {}, + "source": [ + "Additionally we print the statictis associated with obtained incidence matrix" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "49d18ae1", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hyperedge statistics: \n", + "Number of hyperedges without duplicated hyperedges 2581\n", + "min = 1, \n", + "max = 168, \n", + "mean = 4.003099573808601, \n", + "median = 3.0, \n", + "std = 5.327622607829558, \n", + "Number of hyperedges with size equal to one = 412\n" + ] + } + ], + "source": [ + "# Calculate hyperedge statistics.\n", + "hyperedge_sizes = [len(he) for he in hyperedges]\n", + "min_size = min(hyperedge_sizes)\n", + "max_size = max(hyperedge_sizes)\n", + "mean_size = np.mean(hyperedge_sizes)\n", + "median_size = np.median(hyperedge_sizes)\n", + "std_size = np.std(hyperedge_sizes)\n", + "num_single_node_hyperedges = sum(np.array(hyperedge_sizes) == 1)\n", + "\n", + "# Print the hyperedge statistics.\n", + "print(f'Hyperedge statistics: ')\n", + "print('Number of hyperedges without duplicated hyperedges', len(hyperedges))\n", + "print(f'min = {min_size}, ')\n", + "print(f'max = {max_size}, ')\n", + "print(f'mean = {mean_size}, ')\n", + "print(f'median = {median_size}, ')\n", + "print(f'std = {std_size}, ')\n", + "print(f'Number of hyperedges with size equal to one = {num_single_node_hyperedges}')\n" + ] + }, + { + "cell_type": "markdown", + "id": "2d8350a0", + "metadata": {}, + "source": [ + "Construct incidence matrix" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "cdaa476d", + "metadata": {}, + "outputs": [], + "source": [ + "max_edges = len(hyperedges)\n", + "incidence_1 = np.zeros((x_0s.shape[0], max_edges))\n", + "for col, neighibourhood in enumerate(hyperedges):\n", + " for row in neighibourhood:\n", + " incidence_1[row, col] = 1\n", "\n", - "incidence_1_list = []\n", - "for hg in hg_list:\n", - " incidence_1 = hg.incidence_matrix()\n", - " incidence_1 = torch.from_numpy(incidence_1.todense()).to_sparse_csr()\n", - " incidence_1_list.append(incidence_1)" + "assert all(incidence_1.sum(0)>0) == True, \"Some hyperedges are empty\"\n", + "assert all(incidence_1.sum(1)>0) == True, \"Some nodes are not in any hyperedges\"\n", + "incidence_1 = torch.Tensor(incidence_1).to_sparse_coo()" ] }, { @@ -84,14 +208,25 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 7, "id": "4e133a18", "metadata": {}, "outputs": [], "source": [ - "channels_edge = x_1_list[0].shape[1]\n", - "channels_node = dataset[0].x.shape[1]\n", - "model = UniSAGE(channels_edge, channels_node, n_layers=2)" + "in_channels = x_0s.shape[1]\n", + "hidden_channels = 128\n", + "out_channels = torch.unique(y).shape[0]\n", + "task_level = \"graph\" if out_channels==1 else \"node\"\n", + "n_layers=1\n", + "model = UniSAGE(\n", + " in_channels=in_channels,\n", + " hidden_channels=hidden_channels,\n", + " out_channels=out_channels, \n", + " input_drop=0.2,\n", + " layer_drop=0.2,\n", + " n_layers=n_layers,\n", + " task_level=task_level,\n", + ").to(device)" ] }, { @@ -106,46 +241,39 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 8, "id": "89ae1cce", "metadata": {}, "outputs": [], "source": [ - "optimizer = torch.optim.Adam(model.parameters(), lr=1e-2)\n", - "crit = torch.nn.BCELoss()" - ] - }, - { - "cell_type": "markdown", - "id": "d8b51d10", - "metadata": {}, - "source": [ - "Split the dataset into train, val, and test sets." + "# Optimizer and loss\n", + "opt = torch.optim.Adam(model.parameters(), lr=0.01)\n", + "\n", + "# Categorial cross-entropy loss\n", + "loss_fn = torch.nn.CrossEntropyLoss()\n", + "\n", + "# Accuracy\n", + "acc_fn = lambda y, y_hat: (y == y_hat).float().mean()" ] }, { "cell_type": "code", - "execution_count": 5, - "id": "1973b46e", + "execution_count": 9, + "id": "078a11cd", "metadata": {}, "outputs": [], "source": [ - "x_1_train, x_1_test = train_test_split(x_1_list, test_size=0.2, shuffle=False)\n", - "incidence_1_train, incidence_1_test = train_test_split(\n", - " incidence_1_list, test_size=0.2, shuffle=False\n", - ")\n", - "y_train, y_test = train_test_split(y_list, test_size=0.2, shuffle=False)\n", - "\n", - "x_1_train, x_1_val = train_test_split(x_1_train, test_size=0.2, shuffle=False)\n", - "incidence_1_train, incidence_1_val = train_test_split(\n", - " incidence_1_train, test_size=0.2, shuffle=False\n", - ")\n", - "y_train, y_val = train_test_split(y_train, test_size=0.2, shuffle=False)" + "x_0s = torch.tensor(x_0s)\n", + "x_0s, incidence_1, y = (\n", + " x_0s.float().to(device),\n", + " incidence_1.float().to(device),\n", + " torch.tensor(y, dtype=torch.long).to(device),\n", + " )" ] }, { "cell_type": "markdown", - "id": "de215a24", + "id": "f13020bc", "metadata": {}, "source": [ "The following cell performs the training, looping over the network for a low amount of epochs. We keep training minimal for the purpose of rapid testing." @@ -153,149 +281,84 @@ }, { "cell_type": "code", - "execution_count": 6, - "id": "3b1397b5", + "execution_count": 10, + "id": "491ebe34", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Epoch 0 loss: 46.11848068237305\n", - "Epoch 0 Validation accuracy: 0.5625\n", - "Epoch 1 loss: 38.48760986328125\n", - "Epoch 1 Validation accuracy: 0.5625\n", - "Epoch 2 loss: 35.41103744506836\n", - "Epoch 2 Validation accuracy: 0.5625\n", - "Epoch 3 loss: 35.46265411376953\n", - "Epoch 3 Validation accuracy: 0.5625\n", - "Epoch 4 loss: 36.654991149902344\n", - "Epoch 4 Validation accuracy: 0.5625\n", - "Epoch 5 loss: 37.48741149902344\n", - "Epoch 5 Validation accuracy: 0.5625\n", - "Epoch 6 loss: 37.493499755859375\n", - "Epoch 6 Validation accuracy: 0.5625\n", - "Epoch 7 loss: 36.90041732788086\n", - "Epoch 7 Validation accuracy: 0.5625\n", - "Epoch 8 loss: 36.03223419189453\n", - "Epoch 8 Validation accuracy: 0.5625\n", - "Epoch 9 loss: 35.20775604248047\n", - "Epoch 9 Validation accuracy: 0.5625\n", - "Epoch 10 loss: 34.63990020751953\n", - "Epoch 10 Validation accuracy: 0.5625\n", - "Epoch 11 loss: 34.34232711791992\n", - "Epoch 11 Validation accuracy: 0.5625\n", - "Epoch 12 loss: 34.30369567871094\n", - "Epoch 12 Validation accuracy: 0.5625\n", - "Epoch 13 loss: 34.4339485168457\n", - "Epoch 13 Validation accuracy: 0.5625\n", - "Epoch 14 loss: 34.60327911376953\n", - "Epoch 14 Validation accuracy: 0.5625\n", - "Epoch 15 loss: 34.69844055175781\n", - "Epoch 15 Validation accuracy: 0.5625\n", - "Epoch 16 loss: 34.66060256958008\n", - "Epoch 16 Validation accuracy: 0.5625\n", - "Epoch 17 loss: 34.48517990112305\n", - "Epoch 17 Validation accuracy: 0.5625\n", - "Epoch 18 loss: 34.20755386352539\n", - "Epoch 18 Validation accuracy: 0.5625\n", - "Epoch 19 loss: 33.90876007080078\n", - "Epoch 19 Validation accuracy: 0.5625\n", - "Epoch 20 loss: 33.64041519165039\n", - "Epoch 20 Validation accuracy: 0.5625\n", - "Epoch 21 loss: 33.4536018371582\n", - "Epoch 21 Validation accuracy: 0.5625\n", - "Epoch 22 loss: 33.356746673583984\n", - "Epoch 22 Validation accuracy: 0.5625\n", - "Epoch 23 loss: 33.32301712036133\n", - "Epoch 23 Validation accuracy: 0.5625\n", - "Epoch 24 loss: 33.31113052368164\n", - "Epoch 24 Validation accuracy: 0.5625\n", - "Epoch 25 loss: 33.28101348876953\n", - "Epoch 25 Validation accuracy: 0.5625\n", - "Epoch 26 loss: 33.19704818725586\n", - "Epoch 26 Validation accuracy: 0.5625\n", - "Epoch 27 loss: 33.05533218383789\n", - "Epoch 27 Validation accuracy: 0.5625\n", - "Epoch 28 loss: 32.8785400390625\n", - "Epoch 28 Validation accuracy: 0.5625\n", - "Epoch 29 loss: 32.683712005615234\n", - "Epoch 29 Validation accuracy: 0.5625\n", - "Epoch 30 loss: 32.50434875488281\n", - "Epoch 30 Validation accuracy: 0.5625\n", - "Epoch 31 loss: 32.371429443359375\n", - "Epoch 31 Validation accuracy: 0.5625\n", - "Epoch 32 loss: 32.28118133544922\n", - "Epoch 32 Validation accuracy: 0.5625\n", - "Epoch 33 loss: 32.21925735473633\n", - "Epoch 33 Validation accuracy: 0.5625\n", - "Epoch 34 loss: 32.157997131347656\n", - "Epoch 34 Validation accuracy: 0.5625\n", - "Epoch 35 loss: 32.07044219970703\n", - "Epoch 35 Validation accuracy: 0.5625\n", - "Epoch 36 loss: 31.944950103759766\n", - "Epoch 36 Validation accuracy: 0.5625\n", - "Epoch 37 loss: 31.793039321899414\n", - "Epoch 37 Validation accuracy: 0.5625\n", - "Epoch 38 loss: 31.64575958251953\n", - "Epoch 38 Validation accuracy: 0.5625\n", - "Epoch 39 loss: 31.5272216796875\n", - "Epoch 39 Validation accuracy: 0.5625\n", - "Epoch 40 loss: 31.440631866455078\n", - "Epoch 40 Validation accuracy: 0.5625\n", - "Epoch 41 loss: 31.375879287719727\n", - "Epoch 41 Validation accuracy: 0.5625\n", - "Epoch 42 loss: 31.311176300048828\n", - "Epoch 42 Validation accuracy: 0.5625\n", - "Epoch 43 loss: 31.22810173034668\n", - "Epoch 43 Validation accuracy: 0.5625\n", - "Epoch 44 loss: 31.12361717224121\n", - "Epoch 44 Validation accuracy: 0.5625\n", - "Epoch 45 loss: 31.010883331298828\n", - "Epoch 45 Validation accuracy: 0.5625\n", - "Epoch 46 loss: 30.924745559692383\n", - "Epoch 46 Validation accuracy: 0.5625\n", - "Epoch 47 loss: 30.86925506591797\n", - "Epoch 47 Validation accuracy: 0.5625\n", - "Epoch 48 loss: 30.828832626342773\n", - "Epoch 48 Validation accuracy: 0.5625\n", - "Epoch 49 loss: 30.78775405883789\n", - "Epoch 49 Validation accuracy: 0.5625\n", - "Test accuracy: 0.8\n" + "Epoch: 5 \n", + "Train_loss: 1.1164, acc: 0.9714\n", + "Val_loss: 0.9324, Val_acc: 0.7820\n", + "Test_loss: 1.0056, Test_acc: 0.7930\n", + "Epoch: 10 \n", + "Train_loss: 0.6460, acc: 0.9929\n", + "Val_loss: 1.4363, Val_acc: 0.7640\n", + "Test_loss: 1.7823, Test_acc: 0.7450\n", + "Epoch: 15 \n", + "Train_loss: 0.4511, acc: 1.0000\n", + "Val_loss: 1.6066, Val_acc: 0.7520\n", + "Test_loss: 1.7711, Test_acc: 0.7620\n", + "Epoch: 20 \n", + "Train_loss: 0.3402, acc: 1.0000\n", + "Val_loss: 2.0556, Val_acc: 0.7520\n", + "Test_loss: 2.4377, Test_acc: 0.7490\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch: 25 \n", + "Train_loss: 0.2747, acc: 1.0000\n", + "Val_loss: 2.1278, Val_acc: 0.7460\n", + "Test_loss: 2.4358, Test_acc: 0.7490\n", + "Epoch: 30 \n", + "Train_loss: 0.2295, acc: 1.0000\n", + "Val_loss: 2.2190, Val_acc: 0.7500\n", + "Test_loss: 2.5519, Test_acc: 0.7460\n" ] } ], "source": [ - "num_epochs = 50\n", - "for epoch in range(num_epochs):\n", + "torch.manual_seed(0)\n", + "test_interval = 5\n", + "num_epochs = 30\n", + "\n", + "epoch_loss = []\n", + "for epoch_i in range(1, num_epochs + 1):\n", + " \n", " model.train()\n", - " optimizer.zero_grad()\n", - " loss = 0\n", - " for x_1, incidence_1, y in zip(x_1_train, incidence_1_train, y_train):\n", - " output = model(x_1, incidence_1)\n", - " loss += crit(output, torch.tensor([y]).float())\n", + "\n", + " opt.zero_grad()\n", + " \n", + " # Extract edge_index from sparse incidence matrix\n", + " y_hat = model(x_0s, incidence_1)\n", + " loss = loss_fn(y_hat[train_mask], y[train_mask])\n", + "\n", " loss.backward()\n", - " optimizer.step()\n", - " print(f\"Epoch {epoch} loss: {loss.item()}\")\n", - " model.eval()\n", - " with torch.no_grad():\n", - " correct = 0\n", - " for x_1, incidence_1, y in zip(x_1_val, incidence_1_val, y_val):\n", - " output = model(x_1, incidence_1)\n", - " pred = output > 0.5\n", - " if pred == y:\n", - " correct += 1\n", - " print(f\"Epoch {epoch} Validation accuracy: {correct / len(y_val)}\")\n", + " opt.step()\n", + " epoch_loss.append(loss.item())\n", + "\n", + " \n", + "\n", + " if epoch_i % test_interval == 0:\n", + " \n", + " model.eval()\n", + " y_hat = model(x_0s, incidence_1)\n", + "\n", + " loss = loss_fn(y_hat[train_mask], y[train_mask])\n", + " print(f\"Epoch: {epoch_i} \")\n", + " print(f\"Train_loss: {np.mean(epoch_loss):.4f}, acc: {acc_fn(y_hat[train_mask].argmax(1), y[train_mask]):.4f}\",flush=True)\n", + "\n", + " loss = loss_fn(y_hat[val_mask], y[val_mask])\n", + " \n", + " print(f\"Val_loss: {loss:.4f}, Val_acc: {acc_fn(y_hat[val_mask].argmax(1), y[val_mask]):.4f}\", flush=True)\n", "\n", - "model.eval()\n", - "with torch.no_grad():\n", - " correct = 0\n", - " for x_1, incidence_1, y in zip(x_1_test, incidence_1_test, y_test):\n", - " output = model(x_1, incidence_1)\n", - " pred = output > 0.5\n", - " if pred == y:\n", - " correct += 1\n", - " print(f\"Test accuracy: {correct / len(y_test)}\")" + " loss = loss_fn(y_hat[test_mask], y[test_mask])\n", + " print(f\"Test_loss: {loss:.4f}, Test_acc: {acc_fn(y_hat[test_mask].argmax(1), y[test_mask]):.4f}\", flush=True)" ] } ], From fbbb5ab3f55a3ba94588ad3581204e55b524e525 Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Thu, 2 Nov 2023 15:18:42 +0000 Subject: [PATCH 05/39] hypersage left --- test/nn/hypergraph/test_hnhn_layer_bis.py | 44 --- topomodelx/nn/hypergraph/hnhn_layer_bis.py | 97 ----- topomodelx/nn/hypergraph/hypergat.py | 44 ++- tutorials/hypergraph/allset_train.ipynb | 60 +-- tutorials/hypergraph/hmpnn_train.ipynb | 165 ++------- tutorials/hypergraph/hnhn_train_bis.ipynb | 401 --------------------- tutorials/hypergraph/hypergat_train.ipynb | 57 ++- 7 files changed, 128 insertions(+), 740 deletions(-) delete mode 100644 test/nn/hypergraph/test_hnhn_layer_bis.py delete mode 100644 topomodelx/nn/hypergraph/hnhn_layer_bis.py delete mode 100644 tutorials/hypergraph/hnhn_train_bis.ipynb diff --git a/test/nn/hypergraph/test_hnhn_layer_bis.py b/test/nn/hypergraph/test_hnhn_layer_bis.py deleted file mode 100644 index aab8f12f9..000000000 --- a/test/nn/hypergraph/test_hnhn_layer_bis.py +++ /dev/null @@ -1,44 +0,0 @@ -"""Test the HNHN layer.""" -import pytest -import torch - -from topomodelx.nn.hypergraph.hnhn_layer_bis import HNHNLayer - -torch.manual_seed(41) - - -class TestHNHNLayer: - """Test the HNHN layer.""" - - @pytest.fixture - def incidence_1(self): - """Provide a random incidence matrix of 100 nodes and 20 hyperedges.""" - in_features = 2 - incidence_1 = torch.randint(0, in_features, (100, 20)) - return incidence_1.to_sparse_coo() - - def test_constructor(self, incidence_1): - """Test the layer constructor in which the weight matrices are computed.""" - in_features = 2 - layer = HNHNLayer(in_features, incidence_1) - assert layer.weighted_node_to_hyperedge_incidence.shape == (20, 100) - assert torch.allclose( - layer.weighted_node_to_hyperedge_incidence.sum(dim=1).to_dense(), - torch.tensor(1.0), - ) - - assert layer.weighted_hyperedge_to_node_incidence.shape == (100, 20) - assert torch.allclose( - layer.weighted_hyperedge_to_node_incidence.sum(dim=1).to_dense(), - torch.tensor(1.0), - ) - - def test_forward(self, incidence_1): - """Test the forward pass of the HNHN layer.""" - in_features = 2 - hnhn_layer = HNHNLayer(in_features, incidence_1) - x_0 = torch.randn(100, in_features) - - x_0, x_1 = hnhn_layer(x_0) - assert x_0.shape == (100, in_features) - assert x_1.shape == (20, in_features) diff --git a/topomodelx/nn/hypergraph/hnhn_layer_bis.py b/topomodelx/nn/hypergraph/hnhn_layer_bis.py deleted file mode 100644 index 0f17c690f..000000000 --- a/topomodelx/nn/hypergraph/hnhn_layer_bis.py +++ /dev/null @@ -1,97 +0,0 @@ -"""HNHN (Hypergraph Network with Hyperedge Neurons) Layer introduced in Dong et al. 2020.""" - -import torch -from torch.nn import functional as F - - -class HNHNLayer(torch.nn.Module): - """HNHN Layer [1]_. - - Given the input representation of nodes, this layer returns a new representation using hyperedges - as a relay. In other words it makes a intermediary representation for hyperedges with those of the nodes - and then makes the final representation of the nodes using the representation of the hyperedges. - During building the representation for a hyperedge/node, this layer multiplies a normalized weight to the - features of the neighboring nodes/hyperedges, reflecting different levels of importance across the neighbors. - - Parameters - ---------- - in_features : int - The input dimension of node features. - incidence_1 : torch.sparse.Tensor, shape = (n_nodes, n_edges) - Incidence matrix mapping hyperedges to nodes (B_1). - activation_func: Callable - Called on the new representations. - normalization_param_alpha: float - The param that weights multiplied into hyperedge representations are powered to beforehand. - normalization_param_beta: float - The param that weights multiplied into node representations are powered to beforehand. - - References - ---------- - .. [1] Dong, Sawin, Bengio. - HNHN: hypergraph networks with hyperedge neurons. - Graph Representation Learning and Beyond Workshop at ICML 2020. - https://grlplus.github.io/papers/40.pdf - """ - - def __init__( - self, - in_features, - incidence_1, - activation_func=F.relu, - normalization_param_alpha: float = 0.0, - normalization_param_beta: float = 0.0, - ) -> None: - super().__init__() - - incidence_1 = incidence_1.to(torch.float) - - d_E = incidence_1.sum(dim=0).to_dense() - d_E_powered = d_E**normalization_param_alpha - # In HNHN layer, it is assumed that a node is attached to at least one hyperedge, so the - # division below is valid. - normalizing_factor = 1 / torch.sparse.mm(incidence_1, d_E_powered.view(-1, 1)) - self.weighted_hyperedge_to_node_incidence = ( - normalizing_factor * incidence_1 * d_E_powered - ) - - d_V = incidence_1.sum(dim=1).to_dense() - d_V_powered = d_V**normalization_param_beta - incidence_1_T = incidence_1.transpose(1, 0) - normalizing_factor = 1 / torch.sparse.mm(incidence_1_T, d_V_powered.view(-1, 1)) - self.weighted_node_to_hyperedge_incidence = ( - normalizing_factor * incidence_1_T * d_V_powered - ) - - self.node_linear_transform = torch.nn.Linear(in_features, in_features) - self.hyperedge_linear_transform = torch.nn.Linear(in_features, in_features) - - self.activation = activation_func - - def forward(self, x_0): - r"""Forward computation. - - Parameters - ---------- - x_0 : torch.Tensor, shape = (n_nodes, in_features) - Input features of the nodes. - - Returns - ------- - x_0 : torch.Tensor, shape = (n_nodes, in_features) - Output features of the nodes. - x_1 : torch.Tensor, shape = (n_hyperedges, in_features) - Output features of the hyperedges. - """ - x_1_prime = self.activation( - self.hyperedge_linear_transform( - self.weighted_node_to_hyperedge_incidence @ x_0 - ) - ) - x_0_prime = self.activation( - self.node_linear_transform( - self.weighted_hyperedge_to_node_incidence @ x_1_prime - ) - ) - - return x_0_prime, x_1_prime diff --git a/topomodelx/nn/hypergraph/hypergat.py b/topomodelx/nn/hypergraph/hypergat.py index f1d95cf44..4ed0123ec 100644 --- a/topomodelx/nn/hypergraph/hypergat.py +++ b/topomodelx/nn/hypergraph/hypergat.py @@ -10,12 +10,18 @@ class HyperGAT(torch.nn.Module): Parameters ---------- - channels_edge : int - Dimension of edge features - channels_node : int - Dimension of node features + in_channels : int + Dimension of the input features. + hidden_channels : int + Dimension of the hidden features. + out_channels : int + Dimension of the output features. n_layer : int, default = 2 Amount of message passing layers. + task_level: str, default="graph" + Level of the task. Either "graph" or "node". + If "graph", the output is pooled over all nodes in the hypergraph. + References ---------- @@ -24,18 +30,26 @@ class HyperGAT(torch.nn.Module): https://aclanthology.org/2020.emnlp-main.399.pdf """ - def __init__(self, in_channels, out_channels, n_layers=2): + def __init__( + self, + in_channels, + hidden_channels, + out_channels, + n_layers=2, + task_level="graph", + ): super().__init__() layers = [] - layers.append(HyperGATLayer(in_channels=in_channels, out_channels=out_channels)) + layers.append(HyperGATLayer(in_channels=in_channels, out_channels=hidden_channels)) for _ in range(1, n_layers): layers.append( - HyperGATLayer(in_channels=out_channels, out_channels=out_channels) + HyperGATLayer(in_channels=hidden_channels, out_channels=hidden_channels) ) self.layers = torch.nn.ModuleList(layers) - self.linear = torch.nn.Linear(out_channels, 1) + self.linear = torch.nn.Linear(hidden_channels, out_channels) + self.out_pool = True if task_level == "graph" else False - def forward(self, x_1, incidence_1): + def forward(self, x_0, incidence_1): """Forward computation through layers, then linear layer, then global max pooling. Parameters @@ -53,6 +67,12 @@ def forward(self, x_1, incidence_1): Label assigned to whole complex. """ for layer in self.layers: - x_1 = layer.forward(x_1, incidence_1) - pooled_x = torch.max(x_1, dim=0)[0] - return torch.sigmoid(self.linear(pooled_x))[0] + x_0 = layer.forward(x_0, incidence_1) + + # Pool over all nodes in the hypergraph + if self.out_pool is True: + x = torch.max(x_0, dim=0)[0] + else: + x = x_0 + + return self.linear(x) diff --git a/tutorials/hypergraph/allset_train.ipynb b/tutorials/hypergraph/allset_train.ipynb index 4a4548497..537532738 100644 --- a/tutorials/hypergraph/allset_train.ipynb +++ b/tutorials/hypergraph/allset_train.ipynb @@ -36,7 +36,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:51.222779223Z", @@ -73,7 +73,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:51.959770754Z", @@ -108,7 +108,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:53.022151550Z", @@ -153,7 +153,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:53.022151550Z", @@ -194,7 +194,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, "outputs": [ { @@ -243,7 +243,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -268,7 +268,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:55.343005145Z", @@ -307,7 +307,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -323,7 +323,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:59.046068930Z", @@ -335,9 +335,9 @@ "name": "stderr", "output_type": "stream", "text": [ - "/tmp/ipykernel_120782/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_316993/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " x_0s = torch.tensor(x_0s)\n", - "/tmp/ipykernel_120782/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_316993/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " torch.tensor(y, dtype=torch.long).to(device),\n" ] } @@ -361,7 +361,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -369,9 +369,9 @@ "output_type": "stream", "text": [ "Epoch: 5 \n", - "Train_loss: 1.8347, acc: 0.4429\n", - "Val_loss: 1.6878, Val_acc: 0.3280\n", - "Test_loss: 1.6449, Test_acc: 0.3400\n" + "Train_loss: 1.8375, acc: 0.6286\n", + "Val_loss: 1.6964, Val_acc: 0.3480\n", + "Test_loss: 1.6553, Test_acc: 0.3760\n" ] }, { @@ -379,25 +379,25 @@ "output_type": "stream", "text": [ "Epoch: 10 \n", - "Train_loss: 1.4583, acc: 0.8929\n", - "Val_loss: 1.4314, Val_acc: 0.6020\n", - "Test_loss: 1.3842, Test_acc: 0.6520\n", + "Train_loss: 1.5705, acc: 0.7429\n", + "Val_loss: 1.5425, Val_acc: 0.5160\n", + "Test_loss: 1.5357, Test_acc: 0.5240\n", "Epoch: 15 \n", - "Train_loss: 1.0890, acc: 1.0000\n", - "Val_loss: 3.2297, Val_acc: 0.6440\n", - "Test_loss: 3.1065, Test_acc: 0.6560\n", + "Train_loss: 1.2492, acc: 0.8786\n", + "Val_loss: 1.5955, Val_acc: 0.5420\n", + "Test_loss: 1.6364, Test_acc: 0.5360\n", "Epoch: 20 \n", - "Train_loss: 0.8794, acc: 1.0000\n", - "Val_loss: 3.7749, Val_acc: 0.6920\n", - "Test_loss: 3.7500, Test_acc: 0.6880\n", + "Train_loss: 0.9905, acc: 1.0000\n", + "Val_loss: 2.3123, Val_acc: 0.6780\n", + "Test_loss: 2.5038, Test_acc: 0.6860\n", "Epoch: 25 \n", - "Train_loss: 0.8158, acc: 0.9929\n", - "Val_loss: 3.0896, Val_acc: 0.6660\n", - "Test_loss: 3.1467, Test_acc: 0.6770\n", + "Train_loss: 0.7995, acc: 1.0000\n", + "Val_loss: 3.6426, Val_acc: 0.6440\n", + "Test_loss: 3.7969, Test_acc: 0.6800\n", "Epoch: 30 \n", - "Train_loss: 0.7237, acc: 0.9714\n", - "Val_loss: 3.8173, Val_acc: 0.6260\n", - "Test_loss: 3.7671, Test_acc: 0.6210\n" + "Train_loss: 0.6813, acc: 1.0000\n", + "Val_loss: 4.1802, Val_acc: 0.6800\n", + "Test_loss: 4.1946, Test_acc: 0.7110\n" ] } ], diff --git a/tutorials/hypergraph/hmpnn_train.ipynb b/tutorials/hypergraph/hmpnn_train.ipynb index 5b3cebd65..c3c4f6e67 100644 --- a/tutorials/hypergraph/hmpnn_train.ipynb +++ b/tutorials/hypergraph/hmpnn_train.ipynb @@ -15,7 +15,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:51.222779223Z", @@ -41,7 +41,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:51.959770754Z", @@ -74,119 +74,30 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "\n", - "cora = geom_datasets.Planetoid(root=\"/TopoModelX/data/cora\", name=\"Cora\")\n", - "data = cora.data\n", - "\n", - "x_0s = data.x\n", - "y = data.y\n", - "edge_index = data.edge_index\n", - "\n", - "train_mask = data.train_mask\n", - "val_mask = data.val_mask\n", - "test_mask = data.test_mask" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Define neighborhood structures and lift into hypergraph domain. ##\n", - "\n", - "Now we retrieve the neighborhood structure (i.e. their representative matrice) that we will use to send messges from node to hyperedges. In the case of this architecture, we need the boundary matrix (or incidence matrix) $B_1$ with shape $n_\\text{nodes} \\times n_\\text{edges}$.\n", - "\n", - "In citation Cora dataset we lift graph structure to the hypergraph domain by creating hyperedges from 1-hop graph neighbourhood of each node. \n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# Ensure the graph is undirected (optional but often useful for one-hop neighborhoods).\n", - "edge_index = to_undirected(edge_index)\n", - "\n", - "# Create a list of one-hop neighborhoods for each node.\n", - "one_hop_neighborhoods = []\n", - "for node in range(data.num_nodes):\n", - " # Get the one-hop neighbors of the current node.\n", - " neighbors = data.edge_index[1, data.edge_index[0] == node]\n", - "\n", - " # Append the neighbors to the list of one-hop neighborhoods.\n", - " one_hop_neighborhoods.append(neighbors.numpy())\n", - "\n", - "# Detect and eliminate duplicate hyperedges.\n", - "unique_hyperedges = set()\n", - "hyperedges = []\n", - "for neighborhood in one_hop_neighborhoods:\n", - " # Sort the neighborhood to ensure consistent comparison.\n", - " neighborhood = tuple(sorted(neighborhood))\n", - " if neighborhood not in unique_hyperedges:\n", - " hyperedges.append(list(neighborhood))\n", - " unique_hyperedges.add(neighborhood) " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Additionally we print the statictis associated with obtained incidence matrix" - ] - }, - { - "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ - "\n", - "# Calculate hyperedge statistics.\n", - "hyperedge_sizes = [len(he) for he in hyperedges]\n", - "min_size = min(hyperedge_sizes)\n", - "max_size = max(hyperedge_sizes)\n", - "mean_size = np.mean(hyperedge_sizes)\n", - "median_size = np.median(hyperedge_sizes)\n", - "std_size = np.std(hyperedge_sizes)\n", - "num_single_node_hyperedges = sum(np.array(hyperedge_sizes) == 1)\n", - "\n", - "# Print the hyperedge statistics.\n", - "print(f'Hyperedge statistics: ')\n", - "print('Number of hyperedges without duplicated hyperedges', len(hyperedges))\n", - "print(f'min = {min_size}, ')\n", - "print(f'max = {max_size}, ')\n", - "print(f'mean = {mean_size}, ')\n", - "print(f'median = {median_size}, ')\n", - "print(f'std = {std_size}, ')\n", - "print(f'Number of hyperedges with size equal to one = {num_single_node_hyperedges}')\n" + "dataset = geom_datasets.Planetoid(root=\"/TopoModelX/data/cora\", name=\"Cora\")[0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Construct incidence matrix" + "Below, we construct the incidence matrix ($B_1$) which is of shape $n_\\text{nodes} \\times n_\\text{edges}$." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ - "max_edges = len(hyperedges)\n", - "incidence_1 = np.zeros((x_0s.shape[0], max_edges))\n", - "for col, neighibourhood in enumerate(hyperedges):\n", - " for row in neighibourhood:\n", - " incidence_1[row, col] = 1\n", - "\n", - "assert all(incidence_1.sum(0)>0) == True, \"Some hyperedges are empty\"\n", - "assert all(incidence_1.sum(1)>0) == True, \"Some nodes are not in any hyperedges\"\n", - "incidence_1 = torch.Tensor(incidence_1).to_sparse_coo()" + "dataset[\"incidence_1\"] = torch.sparse_coo_tensor(\n", + " dataset[\"edge_index\"], torch.ones(dataset[\"edge_index\"].shape[1]), dtype=torch.long\n", + ")\n", + "dataset = dataset.to(device)" ] }, { @@ -255,26 +166,26 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch: 6 train loss: 1.7054 train acc: 0.63 val loss: 1.8855 val acc: 0.34test loss: 0.3410 val acc: 0.34\n", - "Epoch: 11 train loss: 1.6260 train acc: 0.69 val loss: 1.8205 val acc: 0.32test loss: 0.3380 val acc: 0.34\n", - "Epoch: 16 train loss: 1.5252 train acc: 0.79 val loss: 1.7742 val acc: 0.35test loss: 0.3920 val acc: 0.39\n", - "Epoch: 21 train loss: 1.4274 train acc: 0.85 val loss: 1.7526 val acc: 0.35test loss: 0.3850 val acc: 0.39\n", - "Epoch: 26 train loss: 1.3159 train acc: 0.83 val loss: 1.7416 val acc: 0.36test loss: 0.3850 val acc: 0.39\n", - "Epoch: 31 train loss: 1.2421 train acc: 0.84 val loss: 1.6929 val acc: 0.39test loss: 0.4150 val acc: 0.41\n", - "Epoch: 36 train loss: 1.1510 train acc: 0.91 val loss: 1.6686 val acc: 0.41test loss: 0.4340 val acc: 0.43\n", - "Epoch: 41 train loss: 1.0704 train acc: 0.91 val loss: 1.5701 val acc: 0.49test loss: 0.4900 val acc: 0.49\n", - "Epoch: 46 train loss: 0.9775 train acc: 0.90 val loss: 1.5366 val acc: 0.50test loss: 0.5130 val acc: 0.51\n", - "Epoch: 51 train loss: 0.9132 train acc: 0.90 val loss: 1.4844 val acc: 0.53test loss: 0.5420 val acc: 0.54\n", - "Epoch: 56 train loss: 0.8477 train acc: 0.96 val loss: 1.4231 val acc: 0.55test loss: 0.5600 val acc: 0.56\n", - "Epoch: 61 train loss: 0.7438 train acc: 0.97 val loss: 1.3804 val acc: 0.56test loss: 0.5830 val acc: 0.58\n", - "Epoch: 66 train loss: 0.7040 train acc: 0.98 val loss: 1.3221 val acc: 0.59test loss: 0.6090 val acc: 0.61\n", - "Epoch: 71 train loss: 0.6370 train acc: 0.98 val loss: 1.3007 val acc: 0.59test loss: 0.6100 val acc: 0.61\n", - "Epoch: 76 train loss: 0.5892 train acc: 0.98 val loss: 1.2758 val acc: 0.62test loss: 0.6180 val acc: 0.62\n", - "Epoch: 81 train loss: 0.5556 train acc: 0.99 val loss: 1.2795 val acc: 0.59test loss: 0.6190 val acc: 0.62\n", - "Epoch: 86 train loss: 0.5107 train acc: 0.98 val loss: 1.2930 val acc: 0.59test loss: 0.6100 val acc: 0.61\n", - "Epoch: 91 train loss: 0.4772 train acc: 0.99 val loss: 1.2791 val acc: 0.59test loss: 0.6110 val acc: 0.61\n", - "Epoch: 96 train loss: 0.4572 train acc: 1.00 val loss: 1.2993 val acc: 0.59test loss: 0.6060 val acc: 0.61\n", - "Epoch: 101 train loss: 0.3808 train acc: 1.00 val loss: 1.3041 val acc: 0.59test loss: 0.6120 val acc: 0.61\n" + "Epoch: 6 train loss: 1.7054 train acc: 0.63 val loss: 1.8855 val acc: 0.34 test loss: 0.3410 val acc: 0.34\n", + "Epoch: 11 train loss: 1.6260 train acc: 0.69 val loss: 1.8205 val acc: 0.32 test loss: 0.3380 val acc: 0.34\n", + "Epoch: 16 train loss: 1.5252 train acc: 0.79 val loss: 1.7742 val acc: 0.35 test loss: 0.3920 val acc: 0.39\n", + "Epoch: 21 train loss: 1.4274 train acc: 0.85 val loss: 1.7526 val acc: 0.35 test loss: 0.3850 val acc: 0.39\n", + "Epoch: 26 train loss: 1.3159 train acc: 0.83 val loss: 1.7416 val acc: 0.36 test loss: 0.3850 val acc: 0.39\n", + "Epoch: 31 train loss: 1.2421 train acc: 0.84 val loss: 1.6929 val acc: 0.39 test loss: 0.4150 val acc: 0.41\n", + "Epoch: 36 train loss: 1.1510 train acc: 0.91 val loss: 1.6686 val acc: 0.41 test loss: 0.4340 val acc: 0.43\n", + "Epoch: 41 train loss: 1.0704 train acc: 0.91 val loss: 1.5701 val acc: 0.49 test loss: 0.4900 val acc: 0.49\n", + "Epoch: 46 train loss: 0.9775 train acc: 0.90 val loss: 1.5366 val acc: 0.50 test loss: 0.5130 val acc: 0.51\n", + "Epoch: 51 train loss: 0.9132 train acc: 0.90 val loss: 1.4844 val acc: 0.53 test loss: 0.5420 val acc: 0.54\n", + "Epoch: 56 train loss: 0.8477 train acc: 0.96 val loss: 1.4231 val acc: 0.55 test loss: 0.5600 val acc: 0.56\n", + "Epoch: 61 train loss: 0.7438 train acc: 0.97 val loss: 1.3804 val acc: 0.56 test loss: 0.5830 val acc: 0.58\n", + "Epoch: 66 train loss: 0.7040 train acc: 0.98 val loss: 1.3221 val acc: 0.59 test loss: 0.6090 val acc: 0.61\n", + "Epoch: 71 train loss: 0.6370 train acc: 0.98 val loss: 1.3007 val acc: 0.59 test loss: 0.6100 val acc: 0.61\n", + "Epoch: 76 train loss: 0.5892 train acc: 0.98 val loss: 1.2758 val acc: 0.62 test loss: 0.6180 val acc: 0.62\n", + "Epoch: 81 train loss: 0.5556 train acc: 0.99 val loss: 1.2795 val acc: 0.59 test loss: 0.6190 val acc: 0.62\n", + "Epoch: 86 train loss: 0.5107 train acc: 0.98 val loss: 1.2930 val acc: 0.59 test loss: 0.6100 val acc: 0.61\n", + "Epoch: 91 train loss: 0.4772 train acc: 0.99 val loss: 1.2791 val acc: 0.59 test loss: 0.6110 val acc: 0.61\n", + "Epoch: 96 train loss: 0.4572 train acc: 1.00 val loss: 1.2993 val acc: 0.59 test loss: 0.6060 val acc: 0.61\n", + "Epoch: 101 train loss: 0.3808 train acc: 1.00 val loss: 1.3041 val acc: 0.59 test loss: 0.6120 val acc: 0.61\n" ] } ], @@ -311,15 +222,19 @@ " test_acc = accuracy_score(y[test_mask], y_pred[test_mask])\n", " print(\n", " f\"Epoch: {epoch + 1} train loss: {train_loss:.4f} train acc: {train_acc:.2f} \"\n", - " f\"val loss: {val_loss:.4f} val acc: {val_acc:.2f}\"\n", - " f\"test loss: {test_acc:.4f} val acc: {test_acc:.2f}\"\n", + " f\" val loss: {val_loss:.4f} val acc: {val_acc:.2f}\"\n", + " f\" test loss: {test_acc:.4f} val acc: {test_acc:.2f}\"\n", " )\n", "\n", - " \n", - "\n", - " \n", - " " + " \n" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { diff --git a/tutorials/hypergraph/hnhn_train_bis.ipynb b/tutorials/hypergraph/hnhn_train_bis.ipynb deleted file mode 100644 index d7f2f05ff..000000000 --- a/tutorials/hypergraph/hnhn_train_bis.ipynb +++ /dev/null @@ -1,401 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Train a Hypergraph Network with Hyperedge Neurons (HNHN)\n", - "\n", - "In this notebook, we will create and train a Hypergraph Network with Hyperedge Neurons in the hypergraph domain. This method is introduced in the paper [HNHN: Hypergraph Networks with Hyperedge Neurons](https://arxiv.org/abs/2006.12278) by Dong et al. We will use a benchmark dataset, CiteSeer, a collection of 1498 academic papers and 1107 authors, to do the task of node classification. There are 6 categories into which the papers are classified.\n", - "\n", - "Each document is initially represented as a binary vector of length 3703, standing for a unique subset of the words within the papers, in which a value of 1 means the presence of its corresponding word in the paper." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "import torch\n", - "import matplotlib.pyplot as plt\n", - "from sklearn.metrics import accuracy_score\n", - "from sklearn.manifold import TSNE\n", - "from topomodelx.nn.hypergraph.hnhn_layer_bis import HNHNLayer\n", - "from torch_geometric.data import Data\n", - "from torch_geometric.transforms import RandomNodeSplit\n", - "from topomodelx.nn.hypergraph.hnhn import HNHN" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If GPU's are available, we will make use of them. Otherwise, this will run on CPU." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "cpu\n" - ] - } - ], - "source": [ - "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n", - "print(device)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Pre-processing\n", - "\n", - "Here we download the dataset from the official repo of the paper. It contains initial representation of nodes, the incidence matrix and the category labels. The incidence matrix or $B_1$ is of shape $n_\\text{nodes} \\times n_\\text{edges}$.\n", - "\n", - "We also split the data into train and test splits according to the paper." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "! wget https://github.com/twistedcubic/HNHN/raw/master/data/citeseer6cls3703.pt" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "data = torch.load(\"citeseer6cls3703.pt\")\n", - "dataset = Data(\n", - " x=torch.from_numpy(data[\"paper_X\"]).to(torch.float),\n", - " incidence_1=torch.sparse_coo_tensor(\n", - " indices=torch.LongTensor(data[\"paper_author\"]).T,\n", - " values=torch.ones(len(data[\"paper_author\"]), dtype=torch.long),\n", - " ),\n", - " y=torch.LongTensor(data[\"classes\"]),\n", - ")\n", - "train_test_splitter = RandomNodeSplit(num_test=0.85, num_val=0)\n", - "dataset = train_test_splitter(dataset).to(device)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Create the Neural Network\n", - "\n", - "Using the `HNHNLayer` class, we create a neural network with stacked layers." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "class HNHN(torch.nn.Module):\n", - " \"\"\"Neural network implementation of HNHN\n", - "\n", - " Parameters\n", - " ---------\n", - " in_features : int\n", - " Dimension of input features\n", - " hidden_features : int\n", - " Dimension of hidden features\n", - " incidence_1: torch.sparse.Tensor, shape = (n_nodes, n_hyperedges)\n", - " Incidence matrix.\n", - " num_classes: int\n", - " Number of classes.\n", - " n_layer : int, default = 2\n", - " Number of HNHNLayer layers.\n", - " dropout_rate: float, default = 0.3\n", - " \"\"\"\n", - "\n", - " def __init__(\n", - " self,\n", - " in_features,\n", - " hidden_features,\n", - " incidence_1,\n", - " num_classes,\n", - " n_layer=2,\n", - " dropout_rate=0.3,\n", - " ):\n", - " super().__init__()\n", - " self.to_hidden_linear = torch.nn.Linear(in_features, hidden_features)\n", - " self.layers = torch.nn.Sequential(\n", - " *[\n", - " HNHNLayer(\n", - " hidden_features,\n", - " incidence_1,\n", - " normalization_param_alpha=-1.5,\n", - " normalization_param_beta=-0.5,\n", - " )\n", - " for _ in range(n_layer)\n", - " ]\n", - " )\n", - " self.dropout = torch.nn.Dropout(dropout_rate)\n", - " self.to_categories_linear = torch.nn.Linear(hidden_features, num_classes)\n", - "\n", - " def forward(self, x_0):\n", - " \"\"\"Forward computation through layers.\n", - "\n", - " Parameters\n", - " ---------\n", - " x_0 : torch.Tensor, shape = (n_nodes, in_features)\n", - " Node features.\n", - "\n", - " Returns\n", - " --------\n", - " y_pred : torch.Tensor, shape = (n_nodes, num_classes)\n", - " Predicted logits.\n", - " x_1: torch.Tensor, shape = (n_hyperedges, hidden_features)\n", - " Final hidden representation of hyperedges.\n", - " \"\"\"\n", - " x_1 = 0\n", - " x_0 = self.to_hidden_linear(x_0)\n", - " for i, layer in enumerate(self.layers):\n", - " x_0, x_1 = layer(x_0)\n", - " if i != len(self.layers) - 1:\n", - " x_0, x_1 = self.dropout(x_0), self.dropout(x_1)\n", - "\n", - " return self.to_categories_linear(x_0), x_1" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Train the Neural Network\n", - "\n", - "We then specify the hyperparameters and construct the model, the loss, optimizer and a LR scheduler according to the paper." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [], - "source": [ - "in_features = 3703\n", - "hidden_features = 400\n", - "num_classes = 6\n", - "n_layers = 1\n", - "dropout_rate = 0.3\n", - "initial_lr = 0.04\n", - "\n", - "model = HNHN(\n", - " in_features,\n", - " hidden_features,\n", - " dataset[\"incidence_1\"],\n", - " num_classes,\n", - " n_layers,\n", - " dropout_rate,\n", - ").to(device)\n", - "optimizer = torch.optim.Adam(model.parameters(), lr=initial_lr)\n", - "loss_fn = torch.nn.CrossEntropyLoss()\n", - "lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer, 100, gamma=0.51)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now it's time to train the model, looping over the network for a low amount of epochs. We keep training minimal for the purpose of rapid testing." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Epoch: 1 loss: 1.7841 acc: 0.21\n", - "Epoch: 2 loss: 10.6729 acc: 0.22\n", - "Epoch: 3 loss: 21.2133 acc: 0.21\n", - "Epoch: 4 loss: 35.0127 acc: 0.21\n", - "Epoch: 5 loss: 23.5536 acc: 0.23\n", - "Epoch: 6 loss: 17.4931 acc: 0.43\n", - "Epoch: 7 loss: 20.3316 acc: 0.22\n", - "Epoch: 8 loss: 12.5507 acc: 0.32\n", - "Epoch: 9 loss: 2.6564 acc: 0.49\n", - "Epoch: 10 loss: 6.0825 acc: 0.40\n", - "Epoch: 11 loss: 0.6441 acc: 0.80\n", - "Epoch: 12 loss: 1.2435 acc: 0.68\n", - "Epoch: 13 loss: 0.5326 acc: 0.84\n", - "Epoch: 14 loss: 0.3037 acc: 0.91\n", - "Epoch: 15 loss: 0.5990 acc: 0.83\n", - "Epoch: 16 loss: 0.3052 acc: 0.92\n", - "Epoch: 17 loss: 0.2278 acc: 0.93\n", - "Epoch: 18 loss: 0.2426 acc: 0.93\n", - "Epoch: 19 loss: 0.2163 acc: 0.93\n", - "Epoch: 20 loss: 0.1739 acc: 0.94\n", - "Epoch: 21 loss: 0.1618 acc: 0.93\n", - "Epoch: 22 loss: 0.1194 acc: 0.96\n", - "Epoch: 23 loss: 0.1085 acc: 0.97\n", - "Epoch: 24 loss: 0.1179 acc: 0.96\n", - "Epoch: 25 loss: 0.0925 acc: 0.97\n", - "Epoch: 26 loss: 0.0996 acc: 0.96\n", - "Epoch: 27 loss: 0.0797 acc: 0.97\n", - "Epoch: 28 loss: 0.0554 acc: 0.98\n", - "Epoch: 29 loss: 0.0584 acc: 0.98\n", - "Epoch: 30 loss: 0.0565 acc: 0.98\n", - "Epoch: 31 loss: 0.0636 acc: 0.98\n", - "Epoch: 32 loss: 0.0597 acc: 0.98\n", - "Epoch: 33 loss: 0.0604 acc: 0.97\n", - "Epoch: 34 loss: 0.0623 acc: 0.97\n", - "Epoch: 35 loss: 0.0582 acc: 0.97\n", - "Epoch: 36 loss: 0.0543 acc: 0.98\n", - "Epoch: 37 loss: 0.0607 acc: 0.98\n", - "Epoch: 38 loss: 0.0585 acc: 0.97\n", - "Epoch: 39 loss: 0.0603 acc: 0.97\n", - "Epoch: 40 loss: 0.0511 acc: 0.97\n", - "Epoch: 41 loss: 0.0536 acc: 0.97\n", - "Epoch: 42 loss: 0.0482 acc: 0.98\n", - "Epoch: 43 loss: 0.0442 acc: 0.98\n", - "Epoch: 44 loss: 0.0478 acc: 0.98\n", - "Epoch: 45 loss: 0.0411 acc: 0.98\n", - "Epoch: 46 loss: 0.0418 acc: 0.97\n", - "Epoch: 47 loss: 0.0406 acc: 0.97\n", - "Epoch: 48 loss: 0.0379 acc: 0.98\n", - "Epoch: 49 loss: 0.0400 acc: 0.98\n", - "Epoch: 50 loss: 0.0375 acc: 0.98\n" - ] - } - ], - "source": [ - "train_y_true = dataset[\"y\"][dataset[\"train_mask\"]]\n", - "model.train()\n", - "for epoch in range(50):\n", - " optimizer.zero_grad()\n", - " y_pred_logits, _ = model(dataset[\"x\"])\n", - " loss = loss_fn(y_pred_logits[dataset[\"train_mask\"]], train_y_true)\n", - " loss.backward()\n", - " optimizer.step()\n", - " y_pred = y_pred_logits.argmax(dim=-1)\n", - " print(\n", - " f\"Epoch: {epoch + 1} loss: {loss.item():.4f} acc: {accuracy_score(train_y_true, y_pred[dataset['train_mask']]):.2f}\"\n", - " )\n", - " lr_scheduler.step()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "We then evaluate the model against the test data." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Test loss: 12.1901\n", - "Test accuracy: 0.62\n" - ] - } - ], - "source": [ - "model.eval()\n", - "with torch.no_grad():\n", - " y_pred_logits, _ = model(dataset[\"x\"])\n", - "test_y_true = dataset[\"y\"][dataset[\"test_mask\"]]\n", - "loss = loss_fn(y_pred_logits[dataset[\"test_mask\"]], test_y_true)\n", - "print(f\"Test loss: {loss.item():.4f}\")\n", - "y_pred = y_pred_logits.argmax(dim=-1)\n", - "print(f\"Test accuracy: {accuracy_score(test_y_true, y_pred[dataset['test_mask']]):.2f}\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Finally, it's worth it to visualize the learned hidden representations after training the model." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Text(0.5, 1.0, 'Test data')" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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E3jkkUdQFIX58+eX2szftWtXvvvuO6ZOnUr37t3x9vbmmmuuKfV4b775JiNHjqR3797cfffd5OXl8cEHH+Dn58eLL75YqdgBXnrpJdauXcvo0aOJiooiMTGRWbNm0bBhQ6666qoy9+vYsSMTJkxgzpw5zttcmzdv5ssvv2Ts2LEuLSLuMhqNvPjiizz88MMMHjyYm266iRMnTjB37lxiYmLcbnkaM2YML730EnfddRd9+vRhz549fP3112X+vQcGBnLVVVdx1113kZCQwLvvvkuzZs249957K/0aquvll192zmvz4IMPotfr+eSTT7BYLC5zttT0+eLw4cMMGTKEm266iTZt2qDX6/npp59ISEjglltuuejvQ713kUcZXfGKhtSW9XX69GkhhGOeismTJ4tGjRoJg8EgwsPDxZAhQ8ScOXOcdWmaJl599VURFRUlTCaT6Ny5s1iyZImYMGGCy/DLomGXpQ2FKxpWeeFwydLmKBFCiB9//FFcddVVwsvLS3h5eYlWrVqJyZMni0OHDrmUmzVrlnM+gm7duom1a9eKAQMGuD08efLkySW2R0VFuQwxLi1Gu90upk+fLiIiIoTZbBYDBw4Ue/fuLbGvEELs3r1bDBgwQHh4eIgGDRqIGTNmiM8//7zU171q1SoxfPhw4efnJzw8PERMTIyYOHGi2Lp1q7NMWcNCi97jikRFRYnRo0eX+lxWVpZ4+umnRbNmzYTRaBTBwcGiT58+4r///a9zPpLiP+e33npLNGrUSJhMJtGvXz+xa9cul/oqGsI6Z84c0bVrV2E2m4WPj49o3769mDZtmoiLixNCCLF9+3Zx6623isaNGwuTySRCQ0PFmDFjXN4Pd+sq77WX9jvz6aefiqZNmwqdTucyVHn9+vWiV69ewmw2i8jISDFt2jSxfPnyEsOZs7OzxW233Sb8/f0F4PxbKW14shBC/PXXX6Jv377CbDYLX19fcc0114j9+/e7lHH372jFihXiuuuuE5GRkcJoNIrIyEhx6623lhh6XpqCggIxffp0ER0dLQwGg2jUqJF4+umnXYZeC+H+8OQi77//vvMc0qNHD7F+/XrRtWtXMWLECGeZoqHFCxcuLLF/fn6+ePzxx51/c3379hUbNmwo8bMrquObb74RTz/9tAgNDRVms1mMHj1anDx50qXOAQMGiLZt25Y41oXntrK4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HnigWcepbu++ffuIiIgISts7wpH0N6bOpfNpy/OQUlJSUkJSUpLfcl0+j8qR6s+Q40Gd45Ghq55jV2334Y6U8wB1Lp1RZzgPNetHURRFUZROSwUqiqIoiqJ0WipQ6aQsFgv33nvvET2dUp3jkaGrnmNXbffhjpTzAHUunVFnOA81RkVRFEVRlE5L9agoiqIoitJpqUBFURRFUZROSwUqiqIoiqJ0WipQURRFURSl01KBSif00EMPcfTRR2O324mMjGywzL59+zjxxBOx2+3Ex8dzyy234PF42rehrfTcc8/Rp08frFYrKSkp9Raa60p+/vlnTjrpJJKSkhBC8Mknn9R5XUrJPffcQ7du3bDZbMyePZudO3d2TGNb4JFHHmHChAmEhYURHx/Pqaeeyvbt2+uUqaysZP78+cTExBAaGsoZZ5xRs1hgZ9OnT596qzc/+uijdcps2rSJqVOnYrVa6dmzJ4899lgHtbZh6enpXHbZZfTt2xebzUa/fv249957cblcdco0tFL1ypUrO7Dljetq14RA3hczZsyo9/u/+uqrO6jFDbvvvvvqtXHw4ME1r3f0e1sFKp2Qy+XirLPO4pprrmnwda/Xy4knnojL5WL58uW8/vrrLFq0iHvuuaedW9py7777LjfffDP33nsv69atY9SoUcydO5fc3NyOblqLlJWVMWrUKJ577rkGX3/sscf417/+xQsvvMCqVasICQlh7ty5VFZWtnNLW2bZsmXMnz+flStXsnTpUtxuN3PmzKGsrKymzE033cTnn3/O+++/z7Jly8jMzOT000/vwFb798ADD5CVlVXz+Nvf/lbzmsPhYM6cOfTu3Zu1a9fy+OOPc9999/HSSy91YIvr2rZtG7qu8+KLL7JlyxaefvppXnjhBe644456Zb/77rs65zpu3LgOaLF/XfGaEMj7AuCKK66o8/vvbEEvwLBhw+q08ddff615rcPf2y1YM0xpJ6+99pqMiIiot/2rr76SmqbJ7Ozsmm3PP/+8DA8Pl06nsx1b2HITJ06U8+fPr3nu9XplUlKSfOSRRzqwVcEByI8//rjmua7rMjExUT7++OM124qKiqTFYpH/+9//OqCFrZebmysBuWzZMiml73xMJpN8//33a8qkpqZKQK5YsaKjmtmow4Uc4wAAB2dJREFU3r17y6effrrR1//zn//IqKioOu+n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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "tsne = TSNE(n_components=2)\n", - "model.eval()\n", - "with torch.no_grad():\n", - " x_0, _ = model.layers(model.to_hidden_linear(dataset[\"x\"]))\n", - "x_0_train = tsne.fit_transform(x_0[dataset[\"train_mask\"]])\n", - "x_0_test = tsne.fit_transform(x_0[dataset[\"test_mask\"]])\n", - "f, (ax1, ax2) = plt.subplots(1, 2)\n", - "f.suptitle(\"Learned hidden representations of graph nodes\")\n", - "ax1.scatter(x_0_train[:, 0], x_0_train[:, 1], c=dataset[\"y\"][dataset[\"train_mask\"]])\n", - "ax1.set_title(\"Train data\")\n", - "\n", - "ax2.scatter(x_0_test[:, 0], x_0_test[:, 1], c=dataset[\"y\"][dataset[\"test_mask\"]])\n", - "ax2.set_title(\"Test data\")" - ] - } - ], - "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" - }, - "orig_nbformat": 4 - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/tutorials/hypergraph/hypergat_train.ipynb b/tutorials/hypergraph/hypergat_train.ipynb index 3d7fae2ec..86fa18856 100644 --- a/tutorials/hypergraph/hypergat_train.ipynb +++ b/tutorials/hypergraph/hypergat_train.ipynb @@ -213,26 +213,27 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "in_channels = x_0s[0].shape[1]\n", - "out_dim = 32\n", + "hidden_channels = 32\n", + "out_dim = 1\n", "n_layers = 3\n", "\n", "# Define the model\n", - "model = HyperGAT(in_channels=in_channels, out_channels=out_dim, n_layers=n_layers)\n", + "model = HyperGAT(in_channels=in_channels, hidden_channels=hidden_channels, out_channels=out_dim, n_layers=n_layers)\n", "model = model.to(device)\n", "\n", "# Optimizer and loss\n", - "opt = torch.optim.Adam(model.parameters(), lr=0.1)\n", + "opt = torch.optim.Adam(model.parameters(), lr=0.01)\n", "loss_fn = torch.nn.MSELoss()" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -246,29 +247,24 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Epoch: 1 loss: 274.6125\n", - "Test_loss: 529.0000\n", - "Epoch: 2 loss: 274.6125\n", - "Test_loss: 529.0000\n", - "Epoch: 3 loss: 274.6125\n", - "Test_loss: 529.0000\n", - "Epoch: 4 loss: 274.6125\n", - "Test_loss: 529.0000\n", - "Epoch: 5 loss: 274.6125\n", - "Test_loss: 529.0000\n" + "Epoch: 5 train_loss 2793.0022 test_loss: 3603.5338\n", + "Epoch: 10 train_loss 850.0561 test_loss: 973.0185\n", + "Epoch: 15 train_loss 214.8615 test_loss: 419.0050\n", + "Epoch: 20 train_loss 131.6955 test_loss: 234.3142\n" ] } ], "source": [ - "test_interval = 1\n", - "num_epochs = 5\n", + "\n", + "test_interval = 5\n", + "num_epochs = 20\n", "for epoch_i in range(1, num_epochs + 1):\n", " epoch_loss = []\n", " model.train()\n", @@ -289,12 +285,13 @@ " opt.step()\n", " epoch_loss.append(loss.item())\n", "\n", - " print(\n", - " f\"Epoch: {epoch_i} loss: {np.mean(epoch_loss):.4f}\",\n", - " flush=True,\n", - " )\n", + " \n", " if epoch_i % test_interval == 0:\n", " with torch.no_grad():\n", + " \n", + " train_loss = np.mean(epoch_loss)\n", + " \n", + " test_epoch_loss = []\n", " for x_0, incidence_1, y in zip(x_0_test, incidence_1_test, y_test):\n", " x_0 = torch.tensor(x_0)\n", " x_0, incidence_1, y = (\n", @@ -304,16 +301,14 @@ " )\n", " y_hat = model(x_0, incidence_1)\n", " loss = loss_fn(y_hat, y)\n", - "\n", - " print(f\"Test_loss: {loss:.4f}\", flush=True)" + " test_epoch_loss.append(loss.item())\n", + " \n", + " print(\n", + " f\"Epoch: {epoch_i} train_loss {train_loss:.4f} test_loss: {np.mean(test_epoch_loss):.4f}\",\n", + " flush=True,\n", + " )\n", + " " ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { From 77ab206d5b65f457cc484031dceab37e09448297 Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Thu, 2 Nov 2023 15:50:19 +0000 Subject: [PATCH 06/39] hypersage --- topomodelx/nn/hypergraph/hypersage.py | 31 +- tutorials/hypergraph/hypersage_train.ipynb | 437 +++++++++++++-------- 2 files changed, 293 insertions(+), 175 deletions(-) diff --git a/topomodelx/nn/hypergraph/hypersage.py b/topomodelx/nn/hypergraph/hypersage.py index fdbdad8c2..d5501ddc5 100644 --- a/topomodelx/nn/hypergraph/hypersage.py +++ b/topomodelx/nn/hypergraph/hypersage.py @@ -24,22 +24,31 @@ class HyperSAGE(torch.nn.Module): https://arxiv.org/abs/2010.04558 """ - def __init__(self, in_channels, out_channels, n_layers=2, **kwargs): + def __init__( + self, + in_channels, + hidden_channels, + out_channels, + n_layers=2, + task_level="graph", + **kwargs + ): super().__init__() layers = [] layers.append( - HyperSAGELayer(in_channels=in_channels, out_channels=out_channels, **kwargs) + HyperSAGELayer(in_channels=in_channels, out_channels=hidden_channels, **kwargs) ) for _ in range(1, n_layers): layers.append( HyperSAGELayer( - in_channels=out_channels, out_channels=out_channels, **kwargs + in_channels=hidden_channels, out_channels=hidden_channels, **kwargs ) ) self.layers = torch.nn.ModuleList(layers) - self.linear = torch.nn.Linear(out_channels, 1) + self.linear = torch.nn.Linear(hidden_channels, out_channels) + self.out_pool = True if task_level == "graph" else False - def forward(self, x, incidence): + def forward(self, x_0, incidence): """Forward computation through layers, then linear layer, then global max pooling. Parameters @@ -56,6 +65,12 @@ def forward(self, x, incidence): Label assigned to whole complex. """ for layer in self.layers: - x = layer.forward(x, incidence) - pooled_x = torch.max(x, dim=0)[0] - return torch.sigmoid(self.linear(pooled_x))[0] + x_0 = layer.forward(x_0, incidence) + + # Pool over all nodes in the hypergraph + if self.out_pool is True: + x = torch.max(x_0, dim=0)[0] + else: + x = x_0 + + return self.linear(x) diff --git a/tutorials/hypergraph/hypersage_train.ipynb b/tutorials/hypergraph/hypersage_train.ipynb index b22cba339..4f9f2eef7 100644 --- a/tutorials/hypergraph/hypersage_train.ipynb +++ b/tutorials/hypergraph/hypersage_train.ipynb @@ -1,59 +1,86 @@ { "cells": [ { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ - "# Train a Hypersage TNN\n", + "# Train an All-Set TNN\n", "\n", - "In this notebook, we will create and train HyperSAGE layer (Arya et al., [2020](https://arxiv.org/abs/2010.04558)) - two-levels message passing strategy for hypergraphs learning. We will use a benchmark dataset, shrec16, a collection of 3D meshes, to train the model to perform classification at the level of the hypergraph.\n", + "In this notebook, we will create and train a two-step message passing network named AllSet (Chien et al., [2021](https://arxiv.org/abs/2106.13264)) in the hypergraph domain. We will use a benchmark dataset, shrec16, a collection of 3D meshes, to train the model to perform classification at the level of the hypergraph. \n", "\n", - "Following the \"awesome-tnns\" [github repo.](https://github.com/awesome-tnns/awesome-tnns/blob/main/Hypergraphs.md)\n", + "🟧 $\\quad m_{\\rightarrow z}^{(\\rightarrow 1)} = AGG_{y \\in \\mathcal{B}(z)} (h_y^{t, (0)}, h_z^{t,(1)})$ \n", "\n", - "🟥 $\\quad m_{y \\rightarrow z}^{(0 \\rightarrow 1)} = (B_1)^T_{zy} \\cdot w_y \\cdot (h_y^{(0)})^p$ \n", + "🟦 $\\quad h_z^{t+1,(1)} = \\sigma(m_{\\rightarrow z}^{(\\rightarrow 1)})$ \n", "\n", - "🟥 $\\quad m_z^{(0 \\rightarrow 1)} = \\left(\\frac{1}{\\vert \\mathcal{B}(z)\\vert}\\sum_{y \\in \\mathcal{B}(z)} m_{y \\rightarrow z}^{(0 \\rightarrow 1)}\\right)^{\\frac{1}{p}}$\n", + "Edge to vertex: \n", "\n", - "🟥 $\\quad m_{z \\rightarrow x}^{(1 \\rightarrow 0)} = (B_1)_{xz} \\cdot w_z \\cdot (m_z^{(0 \\rightarrow 1)})^p$\n", + "🟧 $\\quad m_{\\rightarrow x}^{(\\rightarrow 0)} = AGG_{z \\in \\mathcal{C}(x)} (h_z^{t+1,(1)}, h_x^{t,(0)})$ \n", "\n", - "🟧 $\\quad m_x^{(1 \\rightarrow 0)} = \\left(\\frac{1}{\\vert \\mathcal{C}(x) \\vert}\\sum_{z \\in \\mathcal{C}(x)} m_{z \\rightarrow x}^{(1 \\rightarrow 0)}\\right)^{\\frac{1}{p}}$\n", - "\n", - "🟩 $\\quad m_x^{(0)} = m_x^{(1 \\rightarrow 0)}$ \n", - "\n", - "🟦 $\\quad h_x^{t+1, (0)} = \\sigma \\left(\\frac{m_x^{(0)} + h_x^{t,(0)}}{\\lvert m_x^{(0)} + h_x^{t,(0)}\\rvert} \\cdot \\Theta^t\\right)$ \n", + "🟦 $\\quad h_x^{t+1,(0)} = \\sigma(m_{\\rightarrow x}^{(\\rightarrow 0)})$\n", "\n", "### Additional theoretical clarifications\n", + "Given a hypergraph $G=(\\mathcal{V}, \\mathcal{E})$, let $\\textbf{X} \\in \\mathbb{R}^{|\\mathcal{V}| \\times F}$ and $\\textbf{Z} \\in \\mathbb{R}^{|\\mathcal{E}| \\times F'}$ denote the hidden node and hyperedge representations, respectively. Additionally, define $V_{e, \\textbf{X}} = \\{\\textbf{X}_{u,:}: u \\in e\\}$ as the multiset of hidden node representations in the hyperedge $e$ and $E_{v, \\textbf{Z}} = \\{\\textbf{Z}_{e,:}: v \\in e\\}$ as the multiset of hidden representations of hyperedges containing $v$.\n", "\n", - "Arya et al propose to interpret the propagation of information in a given hypergraph as a two-level aggregation problem, where the neighborhood of any node is divided into intra-edge neighbors and inter-edge neighbors. Given a hypergraph $H=(\\mathcal{V}, \\mathcal{E})$, let $\\textbf{X}$ denote the feature matrix, such that $\\textbf{x}_{i} \\in \\textbf{X}$ is the feature set for node $\\textbf{v}_{i} \\in \\textbf{V}$ . For two-level aggregation, \n", - "let $\\mathcal{F}_{1}(·)$ and $\\mathcal{F}_{2}(·)$ denote the intra-edge and inter-edge aggregation functions, respectively. Message passing at node vi for aggregation of information at the $\\mathcal{l}^{th}$ layer can then be stated as\n", + "\\\n", + "In this setting, the two general update rules that AllSet's framework puts in place in each layer are:\n", "\n", - "$ \\mathcal{x}_{i,l}^{(e)} \\leftarrow \\mathcal{F}_{1}(\\{ \\mathcal{x}_{j,l-1} | \\mathcal{v}_{j} \\in \\mathcal{N}( \\mathcal{v}_{i},\n", - "\\textbf{e},\\alpha) \\}), $\n", + "🔷 $\\textbf{Z}_{e,:}^{(t+1)} = f_{\\mathcal{V} \\rightarrow \\mathcal{E}}(V_{e, \\textbf{X}^{(t)}}; \\textbf{Z}_{e,:}^{(t)})$\n", "\n", - "$ \\mathcal{x}_{i,l} \\leftarrow \\mathcal{x}_{i,l-1} + \\mathcal{F}_{2}(\\{ \\mathcal{x}_{i,l}^{(e)} | \\mathcal{v}_{i} \\in {E}( \\mathcal{v}_{i}) \\}), $\n", + "🔷 $\\textbf{X}_{v,:}^{(t+1)} = f_{\\mathcal{E} \\rightarrow \\mathcal{V}}(E_{v, \\textbf{Z}^{(t+1)}}; \\textbf{X}_{v,:}^{(t)})$\n", "\n", - "where, $ \\mathcal{x}_{i,l}^{(e)}$ refers to the aggregated feature set at $\\mathcal{v}_{i}$ obtained with intra-edge aggregation for edge $\\textbf{e}$." + "in which $f_{\\mathcal{V} \\rightarrow \\mathcal{E}}$ and $f_{\\mathcal{E} \\rightarrow \\mathcal{V}}$ are two permutation invariant functions with respect to their first input. The matrices $\\textbf{Z}_{e,:}^{(0)}$ and $\\textbf{X}_{v,:}^{(0)}$ are initialized with the hyperedge and node features respectively, if available, otherwise they are set to be all-zero matrices.\n", + "\n", + "In the practical implementation of the model, $f_{\\mathcal{V} \\rightarrow \\mathcal{E}}$ and $f_{\\mathcal{E} \\rightarrow \\mathcal{V}}$ are parametrized and $learnt$ for each dataset and task, and the information of their second argument is not utilized. \n" ] }, { "cell_type": "code", "execution_count": 1, - "metadata": {}, + "metadata": { + "ExecuteTime": { + "end_time": "2023-06-01T16:14:51.222779223Z", + "start_time": "2023-06-01T16:14:49.575421023Z" + } + }, "outputs": [], "source": [ + "\"\"\"\n", + "This module contains the AllSet class for hypergraph-based neural networks.\n", + "\n", + "The AllSet class implements a specific hypergraph-based neural network architecture\n", + "used for solving certain types of problems.\n", + "\n", + "Author: Your Name\n", + "\n", + "\"\"\"\n", + "\n", "import torch\n", "import numpy as np\n", - "import toponetx.datasets as datasets\n", - "from sklearn.model_selection import train_test_split\n", + "from torch_geometric.utils import to_undirected\n", + "import torch_geometric.datasets as geom_datasets\n", "\n", "from topomodelx.nn.hypergraph.hypersage import HyperSAGE\n", - "from topomodelx.utils.sparse import from_sparse" + "from topomodelx.utils.sparse import from_sparse\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If GPU's are available, we will make use of them. Otherwise, this will run on CPU." ] }, { "cell_type": "code", "execution_count": 2, - "metadata": {}, + "metadata": { + "ExecuteTime": { + "end_time": "2023-06-01T16:14:51.959770754Z", + "start_time": "2023-06-01T16:14:51.956096841Z" + } + }, "outputs": [ { "name": "stdout", @@ -69,6 +96,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -76,149 +104,199 @@ "\n", "## Import data ##\n", "\n", - "The first step is to import the dataset, shrec 16, a benchmark dataset for 3D mesh classification. We then lift each graph into our domain of choice, a hypergraph.\n", - "\n", - "We will also retrieve:\n", - "- input signal on the edges for each of these hypergraphs, as that will be what we feed the model in input\n", - "- the label associated to the hypergraph" + "The first step is to import the dataset, Cora, a benchmark classification datase. We then lift the graph into our domain of choice, a hypergraph.\n" ] }, { "cell_type": "code", "execution_count": 3, - "metadata": {}, + "metadata": { + "ExecuteTime": { + "end_time": "2023-06-01T16:14:53.022151550Z", + "start_time": "2023-06-01T16:14:52.949636599Z" + } + }, "outputs": [ { - "name": "stdout", + "name": "stderr", "output_type": "stream", "text": [ - "Loading shrec 16 small dataset...\n", - "\n", - "done!\n" + "/usr/local/lib/python3.11/site-packages/torch_geometric/data/in_memory_dataset.py:284: UserWarning: It is not recommended to directly access the internal storage format `data` of an 'InMemoryDataset'. If you are absolutely certain what you are doing, access the internal storage via `InMemoryDataset._data` instead to suppress this warning. Alternatively, you can access stacked individual attributes of every graph via `dataset.{attr_name}`.\n", + " warnings.warn(msg)\n" ] } ], "source": [ - "shrec, _ = datasets.mesh.shrec_16(size=\"small\")\n", "\n", - "shrec = {key: np.array(value) for key, value in shrec.items()}\n", - "x_0s = shrec[\"node_feat\"]\n", - "x_1s = shrec[\"edge_feat\"]\n", - "x_2s = shrec[\"face_feat\"]\n", + "cora = geom_datasets.Planetoid(root=\"/TopoModelX/data/cora\", name=\"Cora\")\n", + "data = cora.data\n", + "\n", + "x_0s = data.x\n", + "y = data.y\n", + "edge_index = data.edge_index\n", "\n", - "ys = shrec[\"label\"]\n", - "simplexes = shrec[\"complexes\"]" + "train_mask = data.train_mask\n", + "val_mask = data.val_mask\n", + "test_mask = data.test_mask\n" ] }, { - "cell_type": "code", - "execution_count": 4, + "attachments": {}, + "cell_type": "markdown", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The 6th simplicial complex has 252 nodes with features of dimension 6.\n", - "The 6th simplicial complex has 750 edges with features of dimension 10.\n", - "The 6th simplicial complex has 500 faces with features of dimension 7.\n" - ] - } - ], "source": [ - "i_complex = 6\n", - "print(\n", - " f\"The {i_complex}th simplicial complex has {x_0s[i_complex].shape[0]} nodes with features of dimension {x_0s[i_complex].shape[1]}.\"\n", - ")\n", - "print(\n", - " f\"The {i_complex}th simplicial complex has {x_1s[i_complex].shape[0]} edges with features of dimension {x_1s[i_complex].shape[1]}.\"\n", - ")\n", - "print(\n", - " f\"The {i_complex}th simplicial complex has {x_2s[i_complex].shape[0]} faces with features of dimension {x_2s[i_complex].shape[1]}.\"\n", - ")" + "## Define neighborhood structures and lift into hypergraph domain. ##\n", + "\n", + "Now we retrieve the neighborhood structure (i.e. their representative matrice) that we will use to send messges from node to hyperedges. In the case of this architecture, we need the boundary matrix (or incidence matrix) $B_1$ with shape $n_\\text{nodes} \\times n_\\text{edges}$.\n", + "\n", + "In citation Cora dataset we lift graph structure to the hypergraph domain by creating hyperedges from 1-hop graph neighbourhood of each node. \n" ] }, { - "cell_type": "markdown", - "metadata": {}, + "cell_type": "code", + "execution_count": 4, + "metadata": { + "ExecuteTime": { + "end_time": "2023-06-01T16:14:53.022151550Z", + "start_time": "2023-06-01T16:14:52.949636599Z" + } + }, + "outputs": [], "source": [ - "## Define neighborhood structures and lift into hypergraph domain. ##\n", + "# Ensure the graph is undirected (optional but often useful for one-hop neighborhoods).\n", + "edge_index = to_undirected(edge_index)\n", "\n", - "Now we retrieve the neighborhood structures (i.e. their representative matrices) that we will use to send messges on each simplicial complex. In the case of this architecture, we need the boundary matrix (or incidence matrix) $B_1$ with shape $n_\\text{nodes} \\times n_\\text{edges}$.\n", + "# Create a list of one-hop neighborhoods for each node.\n", + "one_hop_neighborhoods = []\n", + "for node in range(data.num_nodes):\n", + " # Get the one-hop neighbors of the current node.\n", + " neighbors = data.edge_index[1, data.edge_index[0] == node]\n", "\n", - "Once we have recorded the incidence matrix (note that all incidence amtrices in the hypergraph domain must be unsigned), we lift each simplicial complex into a hypergraph. The pairwise edges will become pairwise hyperedges, and faces in the simplciial complex will become 3-wise hyperedges." + " # Append the neighbors to the list of one-hop neighborhoods.\n", + " one_hop_neighborhoods.append(neighbors.numpy())\n", + "\n", + "# Detect and eliminate duplicate hyperedges.\n", + "unique_hyperedges = set()\n", + "hyperedges = []\n", + "for neighborhood in one_hop_neighborhoods:\n", + " # Sort the neighborhood to ensure consistent comparison.\n", + " neighborhood = tuple(sorted(neighborhood))\n", + " if neighborhood not in unique_hyperedges:\n", + " hyperedges.append(list(neighborhood))\n", + " unique_hyperedges.add(neighborhood) " ] }, { - "cell_type": "code", - "execution_count": 5, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "hg_list = []\n", - "incidence_1_list = []\n", - "for simplex in simplexes:\n", - " incidence_1 = simplex.incidence_matrix(rank=1, signed=False)\n", - " hg = simplex.to_hypergraph()\n", - " hg_list.append(hg)\n", - "\n", - "# Extract hypergraphs incident matrices from collected hypergraphs\n", - "for hg in hg_list:\n", - " incidence_1 = hg.incidence_matrix()\n", - " incidence_1 = from_sparse(incidence_1)\n", - " incidence_1_list.append(incidence_1)" + "Additionally we print the statictis associated with obtained incidence matrix" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "The 6th hypergraph has an incidence matrix of shape torch.Size([252, 1250]).\n" + "Hyperedge statistics: \n", + "Number of hyperedges without duplicated hyperedges 2581\n", + "min = 1, \n", + "max = 168, \n", + "mean = 4.003099573808601, \n", + "median = 3.0, \n", + "std = 5.327622607829558, \n", + "Number of hyperedges with size equal to one = 412\n" ] } ], "source": [ - "i_complex = 6\n", - "print(\n", - " f\"The {i_complex}th hypergraph has an incidence matrix of shape {incidence_1_list[i_complex].shape}.\"\n", - ")" + "\n", + "# Calculate hyperedge statistics.\n", + "hyperedge_sizes = [len(he) for he in hyperedges]\n", + "min_size = min(hyperedge_sizes)\n", + "max_size = max(hyperedge_sizes)\n", + "mean_size = np.mean(hyperedge_sizes)\n", + "median_size = np.median(hyperedge_sizes)\n", + "std_size = np.std(hyperedge_sizes)\n", + "num_single_node_hyperedges = sum(np.array(hyperedge_sizes) == 1)\n", + "\n", + "# Print the hyperedge statistics.\n", + "print(f'Hyperedge statistics: ')\n", + "print('Number of hyperedges without duplicated hyperedges', len(hyperedges))\n", + "print(f'min = {min_size}, ')\n", + "print(f'max = {max_size}, ')\n", + "print(f'mean = {mean_size}, ')\n", + "print(f'median = {median_size}, ')\n", + "print(f'std = {std_size}, ')\n", + "print(f'Number of hyperedges with size equal to one = {num_single_node_hyperedges}')\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "# Define the Neural Network\n", - "\n" + "Construct incidence matrix" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "max_edges = len(hyperedges)\n", + "incidence_1 = np.zeros((x_0s.shape[0], max_edges))\n", + "for col, neighibourhood in enumerate(hyperedges):\n", + " for row in neighibourhood:\n", + " incidence_1[row, col] = 1\n", + "\n", + "assert all(incidence_1.sum(0)>0) == True, \"Some hyperedges are empty\"\n", + "assert all(incidence_1.sum(1)>0) == True, \"Some nodes are not in any hyperedges\"\n", + "incidence_1 = torch.Tensor(incidence_1).to_sparse_coo()" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", "metadata": {}, + "source": [ + "# Create the Neural Network" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "ExecuteTime": { + "end_time": "2023-06-01T16:14:55.343005145Z", + "start_time": "2023-06-01T16:14:55.339481459Z" + } + }, "outputs": [], "source": [ - "# Define the model\n", - "in_channels = x_0s[0].shape[1]\n", - "out_channels = 10\n", - "p = 2\n", - "initialization = \"xavier_uniform\"\n", - "n_layers = 2\n", + "in_channels = x_0s.shape[1]\n", + "hidden_channels = 128\n", + "out_channels = torch.unique(y).shape[0]\n", + "task_level = \"graph\" if out_channels==1 else \"node\"\n", + "n_layers=1\n", + "\n", "model = HyperSAGE(\n", " in_channels=in_channels,\n", + " hidden_channels=hidden_channels,\n", " out_channels=out_channels,\n", " n_layers=n_layers,\n", " device=\"cpu\",\n", - " initialization=initialization,\n", - ")" + " \n", + ")\n", + "model = model.to(device)" ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -229,37 +307,52 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "# Optimizer and loss\n", - "opt = torch.optim.Adam(model.parameters(), lr=0.1)\n", - "loss_fn = torch.nn.MSELoss()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Split the dataset into train and test sets." + "opt = torch.optim.Adam(model.parameters(), lr=0.01)\n", + "\n", + "# Categorial cross-entropy loss\n", + "loss_fn = torch.nn.CrossEntropyLoss()\n", + "\n", + "# Accuracy\n", + "acc_fn = lambda y, y_hat: (y == y_hat).float().mean()" ] }, { "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [], + "execution_count": 9, + "metadata": { + "ExecuteTime": { + "end_time": "2023-06-01T16:14:59.046068930Z", + "start_time": "2023-06-01T16:14:59.037648626Z" + } + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/tmp/ipykernel_452380/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + " x_0s = torch.tensor(x_0s)\n", + "/tmp/ipykernel_452380/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + " torch.tensor(y, dtype=torch.long).to(device),\n" + ] + } + ], "source": [ - "test_size = 0.2\n", - "x_0_train, x_0_test = train_test_split(x_0s, test_size=test_size, shuffle=False)\n", - "incidence_1_train, incidence_1_test = train_test_split(\n", - " incidence_1_list, test_size=test_size, shuffle=False\n", - ")\n", - "y_train, y_test = train_test_split(ys, test_size=test_size, shuffle=False)" + "x_0s = torch.tensor(x_0s)\n", + "x_0s, incidence_1, y = (\n", + " x_0s.float().to(device),\n", + " incidence_1.float().to(device),\n", + " torch.tensor(y, dtype=torch.long).to(device),\n", + " )" ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -268,72 +361,83 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Epoch: 1 loss: 275.2170\n", - "Test_loss: 529.0000\n", - "Epoch: 2 loss: 274.6125\n", - "Test_loss: 529.0000\n", - "Epoch: 3 loss: 274.6125\n", - "Test_loss: 529.0000\n", - "Epoch: 4 loss: 274.6125\n", - "Test_loss: 529.0000\n", - "Epoch: 5 loss: 274.6125\n", - "Test_loss: 529.0000\n" + "Epoch: 5 \n", + "Train_loss: 1.9424, acc: 0.1571\n", + "Val_loss: 1.9429, Val_acc: 0.1220\n", + "Test_loss: 1.9424, Test_acc: 0.1300\n", + "Epoch: 10 \n", + "Train_loss: 1.9310, acc: 0.9286\n", + "Val_loss: 1.9259, Val_acc: 0.4980\n", + "Test_loss: 1.9261, Test_acc: 0.4960\n", + "Epoch: 15 \n", + "Train_loss: 1.9116, acc: 0.9857\n", + "Val_loss: 1.8915, Val_acc: 0.6960\n", + "Test_loss: 1.8925, Test_acc: 0.6970\n", + "Epoch: 20 \n", + "Train_loss: 1.8826, acc: 1.0000\n", + "Val_loss: 1.8473, Val_acc: 0.7140\n", + "Test_loss: 1.8488, Test_acc: 0.7150\n", + "Epoch: 25 \n", + "Train_loss: 1.8432, acc: 0.9929\n", + "Val_loss: 1.7892, Val_acc: 0.7360\n", + "Test_loss: 1.7912, Test_acc: 0.7180\n", + "Epoch: 30 \n", + "Train_loss: 1.7929, acc: 0.9857\n", + "Val_loss: 1.7125, Val_acc: 0.7460\n", + "Test_loss: 1.7151, Test_acc: 0.7180\n" ] } ], "source": [ - "test_interval = 1\n", - "num_epochs = 5\n", + "torch.manual_seed(0)\n", + "test_interval = 5\n", + "num_epochs = 30\n", + "\n", + "epoch_loss = []\n", "for epoch_i in range(1, num_epochs + 1):\n", - " epoch_loss = []\n", + " \n", " model.train()\n", - " for x_0, incidence_1, y in zip(x_0_train, incidence_1_train, y_train):\n", - " x_0 = torch.tensor(x_0)\n", - " x_0, incidence_1, y = (\n", - " x_0.float().to(device),\n", - " incidence_1.float().to(device),\n", - " torch.tensor(y, dtype=torch.float).to(device),\n", - " )\n", - " opt.zero_grad()\n", - " # Extract edge_index from sparse incidence matrix\n", - " # edge_index, _ = to_edge_index(incidence_1)\n", - " y_hat = model(x_0, incidence_1)\n", - " loss = loss_fn(y_hat, y)\n", - "\n", - " loss.backward()\n", - " opt.step()\n", - " epoch_loss.append(loss.item())\n", - "\n", - " print(\n", - " f\"Epoch: {epoch_i} loss: {np.mean(epoch_loss):.4f}\",\n", - " flush=True,\n", - " )\n", + "\n", + " opt.zero_grad()\n", + " \n", + " # Extract edge_index from sparse incidence matrix\n", + " y_hat = model(x_0s, incidence_1)\n", + " loss = loss_fn(y_hat[train_mask], y[train_mask])\n", + "\n", + " loss.backward()\n", + " opt.step()\n", + " epoch_loss.append(loss.item())\n", + "\n", + " \n", + "\n", " if epoch_i % test_interval == 0:\n", - " with torch.no_grad():\n", - " for x_0, incidence_1, y in zip(x_0_test, incidence_1_test, y_test):\n", - " x_0 = torch.tensor(x_0)\n", - " x_0, incidence_1, y = (\n", - " x_0.float().to(device),\n", - " incidence_1.float().to(device),\n", - " torch.tensor(y, dtype=torch.float).to(device),\n", - " )\n", - " y_hat = model(x_0, incidence_1)\n", - " loss = loss_fn(y_hat, y)\n", - "\n", - " print(f\"Test_loss: {loss:.4f}\", flush=True)" + " \n", + " model.eval()\n", + " y_hat = model(x_0s, incidence_1)\n", + "\n", + " loss = loss_fn(y_hat[train_mask], y[train_mask])\n", + " print(f\"Epoch: {epoch_i} \")\n", + " print(f\"Train_loss: {np.mean(epoch_loss):.4f}, acc: {acc_fn(y_hat[train_mask].argmax(1), y[train_mask]):.4f}\",flush=True)\n", + "\n", + " loss = loss_fn(y_hat[val_mask], y[val_mask])\n", + " \n", + " print(f\"Val_loss: {loss:.4f}, Val_acc: {acc_fn(y_hat[val_mask].argmax(1), y[val_mask]):.4f}\", flush=True)\n", + "\n", + " loss = loss_fn(y_hat[test_mask], y[test_mask])\n", + " print(f\"Test_loss: {loss:.4f}, Test_acc: {acc_fn(y_hat[test_mask].argmax(1), y[test_mask]):.4f}\", flush=True)" ] } ], "metadata": { "kernelspec": { - "display_name": "Python 3.9.6 64-bit", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -349,7 +453,6 @@ "pygments_lexer": "ipython3", "version": "3.11.3" }, - "orig_nbformat": 4, "vscode": { "interpreter": { "hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6" From f39174bdc5199ed15aadef00d4357a409b84887c Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Sun, 5 Nov 2023 10:43:07 +0000 Subject: [PATCH 07/39] tutorials --- topomodelx/nn/hypergraph/allset.py | 47 +- topomodelx/nn/hypergraph/allset_layer.py | 28 +- .../nn/hypergraph/allset_transformer.py | 40 +- .../nn/hypergraph/allset_transformer_layer.py | 24 +- topomodelx/nn/hypergraph/hmpnn.py | 45 +- topomodelx/nn/hypergraph/hmpnn_layer.py | 32 +- topomodelx/nn/hypergraph/hnhn.py | 183 +- topomodelx/nn/hypergraph/hnhn_layer.py | 34 +- topomodelx/nn/hypergraph/hypergat.py | 26 +- topomodelx/nn/hypergraph/hypergat_layer.py | 9 +- topomodelx/nn/hypergraph/hypersage.py | 28 +- topomodelx/nn/hypergraph/hypersage_layer.py | 4 +- topomodelx/nn/hypergraph/unigcn.py | 27 +- topomodelx/nn/hypergraph/unigcn_layer.py | 15 +- topomodelx/nn/hypergraph/unigcnii.py | 30 +- topomodelx/nn/hypergraph/unigcnii_layer.py | 13 +- topomodelx/nn/hypergraph/unigin.py | 32 +- topomodelx/nn/hypergraph/unigin_layer.py | 13 +- topomodelx/nn/hypergraph/unisage.py | 37 +- topomodelx/nn/hypergraph/unisage_layer.py | 16 +- tutorials/hypergraph/allset_train.ipynb | 168 +- .../hypergraph/allset_transformer_train.ipynb | 164 +- tutorials/hypergraph/hmpnn_train.ipynb | 173 +- tutorials/hypergraph/hnhn_train.ipynb | 6636 +---------------- tutorials/hypergraph/hypergat_train.ipynb | 140 +- tutorials/hypergraph/hypersage_train.ipynb | 189 +- tutorials/hypergraph/unigcn_train.ipynb | 215 +- tutorials/hypergraph/unigcnii_train.ipynb | 207 +- tutorials/hypergraph/unigin_train.ipynb | 177 +- tutorials/hypergraph/unisage_train.ipynb | 176 +- 30 files changed, 1846 insertions(+), 7082 deletions(-) diff --git a/topomodelx/nn/hypergraph/allset.py b/topomodelx/nn/hypergraph/allset.py index a277282e4..7125fe0a9 100644 --- a/topomodelx/nn/hypergraph/allset.py +++ b/topomodelx/nn/hypergraph/allset.py @@ -16,22 +16,19 @@ class AllSet(torch.nn.Module): Dimension of the input features. hidden_channels : int Dimension of the hidden features. - out_channels : int - Dimension of the output features. dropout : float Dropout probability. n_layers : int, default: 2 Number of AllSet layers in the network. - input_dropout : float, default: 0.2 - Dropout probability for the layer input. mlp_num_layers : int, default: 2 Number of layers in the MLP. mlp_norm : bool, default: False Whether to apply input normalization in the MLP. - task_level: str, default="graph" - Level of the task. Either "graph" or "node". - If "graph", the output is pooled over all nodes in the hypergraph. - + mlp_dropout: + Dropout probability in the MLP. + mlp_activation: + Activation function in the MLP. + References ---------- .. [1] Chien, Pan, Peng and Milenkovic. @@ -44,21 +41,19 @@ def __init__( self, in_channels, hidden_channels, - out_channels, n_layers=2, - dropout=0.2, + layer_dropout=0.2, mlp_num_layers=2, mlp_activation=None, mlp_dropout=0.0, mlp_norm=None, - task_level="graph", ): super().__init__() layers = [ AllSetLayer( in_channels=in_channels, hidden_channels=hidden_channels, - dropout=dropout, + dropout=layer_dropout, mlp_num_layers=mlp_num_layers, mlp_activation=mlp_activation, mlp_dropout=mlp_dropout, @@ -71,7 +66,7 @@ def __init__( AllSetLayer( in_channels=hidden_channels, hidden_channels=hidden_channels, - dropout=dropout, + dropout=layer_dropout, mlp_num_layers=mlp_num_layers, mlp_activation=mlp_activation, mlp_dropout=mlp_dropout, @@ -79,32 +74,30 @@ def __init__( ) ) self.layers = torch.nn.ModuleList(layers) - self.linear = torch.nn.Linear(hidden_channels, out_channels) - self.out_pool = True if task_level == "graph" else False + def forward(self, x_0, incidence_1): """Forward computation. Parameters ---------- - x : torch.Tensor + x_0 : torch.Tensor Input features. - edge_index : torch.Tensor + incidence_1 : torch.Tensor Edge list (of size (2, |E|)). Returns ------- - torch.Tensor - Output prediction. + x_0 : torch.Tensor + Output node features. + x_1 : torch.Tensor + Output hyperedge features. """ for layer in self.layers: - x_0 = layer(x_0, incidence_1) - - # Pool over all nodes in the hypergraph - if self.out_pool is True: - x = torch.max(x_0, dim=0)[0] - else: - x = x_0 + x_0, x_1 = layer(x_0, incidence_1) + + return (x_0, x_1) + + - return self.linear(x) diff --git a/topomodelx/nn/hypergraph/allset_layer.py b/topomodelx/nn/hypergraph/allset_layer.py index c83f14038..377083fa3 100644 --- a/topomodelx/nn/hypergraph/allset_layer.py +++ b/topomodelx/nn/hypergraph/allset_layer.py @@ -26,8 +26,6 @@ class AllSetLayer(nn.Module): Dropout probability in the MLP. mlp_norm : str or None, optional Type of layer normalization in the MLP. - - References ---------- .. [1] Chien, Pan, Peng and Milenkovic. @@ -77,7 +75,7 @@ def reset_parameters(self) -> None: self.vertex2edge.reset_parameters() self.edge2vertex.reset_parameters() - def forward(self, x, incidence_1): + def forward(self, x_0, incidence_1): r""" Forward computation. @@ -110,21 +108,23 @@ def forward(self, x, incidence_1): Returns ------- - x : torch.Tensor - Output features. + x_0 : torch.Tensor + Output node features. + x_1 : torch.Tensor + Output hyperedge features. """ - if x.shape[-2] != incidence_1.shape[-2]: + if x_0.shape[-2] != incidence_1.shape[-2]: raise ValueError( - f"Shape of incidence matrix ({incidence_1.shape}) does not have the correct number of nodes ({x.shape[0]})." + f"Shape of incidence matrix ({incidence_1.shape}) does not have the correct number of nodes ({x_0.shape[0]})." ) - x = self.vertex2edge(x, incidence_1.transpose(1, 0)) - x = F.dropout(x, p=self.dropout, training=self.training) + x_1 = self.vertex2edge(x_0, incidence_1.transpose(1, 0)) + x_1 = F.dropout(x_1, p=self.dropout, training=self.training) - x = self.edge2vertex(x, incidence_1) - x = F.dropout(x, p=self.dropout, training=self.training) + x_0 = self.edge2vertex(x_1, incidence_1) + x_0 = F.dropout(x_0, p=self.dropout, training=self.training) - return x + return (x_0, x_1) class MLP(nn.Sequential): @@ -259,8 +259,8 @@ def forward(self, x, incidence): Parameters ---------- - x : torch.Tensor - Input features. + x_0 : torch.Tensor + Input node features. incidence : torch.sparse Incidence matrix between node/hyperedges. diff --git a/topomodelx/nn/hypergraph/allset_transformer.py b/topomodelx/nn/hypergraph/allset_transformer.py index d6dbeda8b..a10fe8985 100644 --- a/topomodelx/nn/hypergraph/allset_transformer.py +++ b/topomodelx/nn/hypergraph/allset_transformer.py @@ -12,25 +12,19 @@ class AllSetTransformer(torch.nn.Module): Parameters ---------- - in_dim : int + in_channels : int Dimension of the input features. - hid_dim : int + hidden_channels : int Dimension of the hidden features. - out_dim : int - Dimension of the output features. - dropout : float - Dropout probability. n_layers : int, default: 2 Number of AllSet layers in the network. - input_dropout : float, default: 0.2 - Dropout probability for the layer input. + dropout : float + Dropout probability. mlp_num_layers : int, default: 2 Number of layers in the MLP. - mlp_norm : bool, optional. default: False - Whether to apply input normalization in the MLP. - task_level: str, default="graph" - Level of the task. Either "graph" or "node". - If "graph", the output is pooled over all nodes in the hypergraph. + mlp_dropout: + Dropout probability in the MLP. + References ---------- @@ -44,13 +38,11 @@ def __init__( self, in_channels, hidden_channels, - out_channels, n_layers=1, heads=4, dropout=0.2, mlp_num_layers=2, mlp_dropout=0.0, - task_level="graph", ): super().__init__() layers = [ @@ -76,8 +68,7 @@ def __init__( ) ) self.layers = torch.nn.ModuleList(layers) - self.linear = torch.nn.Linear(hidden_channels, out_channels) - self.out_pool = True if task_level == "graph" else False + def forward(self, x_0, incidence_1): """ @@ -87,7 +78,7 @@ def forward(self, x_0, incidence_1): ---------- x : torch.Tensor Input features. - edge_index : torch.Tensor + incidence_1 : torch.Tensor Edge list (of size (2, |E|)). Returns @@ -96,12 +87,7 @@ def forward(self, x_0, incidence_1): Output prediction. """ for layer in self.layers: - x_0 = layer(x_0, incidence_1) - - # Pool over all nodes in the hypergraph - if self.out_pool is True: - x = torch.max(x_0, dim=0)[0] - else: - x = x_0 - - return self.linear(x) \ No newline at end of file + x_0, x_1 = layer(x_0, incidence_1) + + return (x_0, x_1) + \ No newline at end of file diff --git a/topomodelx/nn/hypergraph/allset_transformer_layer.py b/topomodelx/nn/hypergraph/allset_transformer_layer.py index 154d15ef2..0c1a53c69 100644 --- a/topomodelx/nn/hypergraph/allset_transformer_layer.py +++ b/topomodelx/nn/hypergraph/allset_transformer_layer.py @@ -95,7 +95,7 @@ def reset_parameters(self) -> None: self.vertex2edge.reset_parameters() self.edge2vertex.reset_parameters() - def forward(self, x, incidence_1): + def forward(self, x_0, incidence_1): r"""Forward computation. Vertex to edge: @@ -120,28 +120,30 @@ def forward(self, x, incidence_1): Parameters ---------- - x : torch.Tensor, shape = (n_nodes, channels) + x_0 : torch.Tensor, shape = (n_nodes, channels) Node input features. incidence_1 : torch.sparse, shape = (n_nodes, n_hyperedges) Incidence matrix :math:`B_1` mapping hyperedges to nodes. Returns ------- - x : torch.Tensor - Output features. + x_0 : torch.Tensor + Output node features. + x_1 : torch.Tensor + Output hyperedge features. """ - if x.shape[-2] != incidence_1.shape[-2]: + if x_0.shape[-2] != incidence_1.shape[-2]: raise ValueError( - f"Shape of incidence matrix ({incidence_1.shape}) does not have the correct number of nodes ({x.shape[0]})." + f"Shape of incidence matrix ({incidence_1.shape}) does not have the correct number of nodes ({x_0.shape[0]})." ) - x = F.relu(self.vertex2edge(x, incidence_1.transpose(1, 0))) - x = F.dropout(x, p=self.dropout, training=self.training) + x_1 = F.relu(self.vertex2edge(x_0, incidence_1.transpose(1, 0))) + x_1 = F.dropout(x_1, p=self.dropout, training=self.training) - x = F.relu(self.edge2vertex(x, incidence_1)) - x = F.dropout(x, p=self.dropout, training=self.training) + x_0 = F.relu(self.edge2vertex(x_1, incidence_1)) + x_0 = F.dropout(x_0, p=self.dropout, training=self.training) - return x + return x_0, x_1 class AllSetTransformerBlock(nn.Module): diff --git a/topomodelx/nn/hypergraph/hmpnn.py b/topomodelx/nn/hypergraph/hmpnn.py index 9d395398c..230050006 100644 --- a/topomodelx/nn/hypergraph/hmpnn.py +++ b/topomodelx/nn/hypergraph/hmpnn.py @@ -18,7 +18,7 @@ class HMPNN(torch.nn.Module): dimension from in_features to the last item in the tuple. num_classes: int Number of classes - n_layer : int, default = 2 + n_layers : int, default = 2 Number of HMPNNLayer layers. adjacency_dropout_rate: int, default = 0.7 Adjacency dropout rate. @@ -35,34 +35,34 @@ class HMPNN(torch.nn.Module): def __init__( self, - in_features, - hidden_features, - num_classes, - n_layer=2, + in_channels, + hidden_channels, + n_layers=2, adjacency_dropout_rate=0.7, regular_dropout_rate=0.5, ): super().__init__() - hidden_features = (in_features,) + hidden_features - - self.to_hidden_linear = torch.nn.Sequential( - *[ - torch.nn.Linear(hidden_features[i], hidden_features[i + 1]) - for i in range(len(hidden_features) - 1) - ] - ) + self.linear_node = torch.nn.Linear(in_channels, hidden_channels) + self.linear_edge = torch.nn.Linear(in_channels, hidden_channels) + # self.to_hidden_linear = torch.nn.Sequential( + # *[ + # torch.nn.Linear(hidden_features[i], hidden_features[i + 1]) + # for i in range(len(hidden_features) - 1) + # ] + # ) + self.layers = torch.nn.ModuleList( [ HMPNNLayer( - hidden_features[-1], + hidden_channels, adjacency_dropout=adjacency_dropout_rate, updating_dropout=regular_dropout_rate, ) - for _ in range(n_layer) + for _ in range(n_layers) ] ) - self.to_categories_linear = torch.nn.Linear(hidden_features[-1], num_classes) + #self.to_categories_linear = torch.nn.Linear(hidden_features[-1], num_classes) def forward(self, x_0, x_1, incidence_1): """Forward computation through layers. @@ -78,12 +78,15 @@ def forward(self, x_0, x_1, incidence_1): Returns ------- - y_pred : torch.Tensor, shape = (n_nodes, num_classes) - Predicted logits. + x_0 : torch.Tensor + Output node features. + x_1 : torch.Tensor + Output hyperedge features. """ - x_0 = self.to_hidden_linear(x_0) - x_1 = self.to_hidden_linear(x_1) + x_0 = self.linear_node(x_0) + x_1 = self.linear_edge(x_1) + for layer in self.layers: x_0, x_1 = layer(x_0, x_1, incidence_1) - return self.to_categories_linear(x_0) + return (x_0, x_1) diff --git a/topomodelx/nn/hypergraph/hmpnn_layer.py b/topomodelx/nn/hypergraph/hmpnn_layer.py index 985566338..2b181e041 100644 --- a/topomodelx/nn/hypergraph/hmpnn_layer.py +++ b/topomodelx/nn/hypergraph/hmpnn_layer.py @@ -83,18 +83,18 @@ def forward(self, x_source, neighborhood, node_messages): class _DefaultHyperedgeToNodeMessagingFunc(nn.Module): - def __init__(self, in_features) -> None: + def __init__(self, in_channels) -> None: super().__init__() - self.linear = nn.Linear(2 * in_features, in_features) + self.linear = nn.Linear(2 * in_channels, in_channels) def forward(self, x_1, m_0): return F.sigmoid(self.linear(torch.cat((x_1, m_0), dim=1))) class _DefaultUpdatingFunc(nn.Module): - def __init__(self, in_features) -> None: + def __init__(self, in_channels) -> None: super().__init__() - # self.linear = nn.Linear(in_features, in_features) + # self.linear = nn.Linear(in_channels, in_channels) def forward(self, x, m): return F.sigmoid(x + m) @@ -124,7 +124,7 @@ class HMPNNLayer(nn.Module): Parameters ---------- - in_features : int + in_channels : int Dimension of input features. node_to_hyperedge_messaging_func: None Node messaging function as a callable or nn.Module object. If not given, a linear plus sigmoid @@ -132,7 +132,7 @@ class HMPNNLayer(nn.Module): hyperedge_to_node_messaging_func: None Hyperedge messaging function as a callable or nn.Module object. It gets hyperedge input features and aggregated messages of nodes as input and returns hyperedge messages. If not given, two inputs - are concatenated and a linear layer reducing back to in_features plus sigmoid is applied, according + are concatenated and a linear layer reducing back to in_channels plus sigmoid is applied, according to the paper. adjacency_dropout: int, default = 0.7 Adjacency dropout rate. @@ -155,7 +155,7 @@ class HMPNNLayer(nn.Module): def __init__( self, - in_features, + in_channels, node_to_hyperedge_messaging_func=None, hyperedge_to_node_messaging_func=None, adjacency_dropout: float = 0.7, @@ -167,24 +167,24 @@ def __init__( if node_to_hyperedge_messaging_func is None: node_to_hyperedge_messaging_func = nn.Sequential( - nn.Linear(in_features, in_features), nn.Sigmoid() + nn.Linear(in_channels, in_channels), nn.Sigmoid() ) self.node_to_hyperedge_messenger = _NodeToHyperedgeMessenger( node_to_hyperedge_messaging_func, adjacency_dropout, aggr_func ) if hyperedge_to_node_messaging_func is None: hyperedge_to_node_messaging_func = _DefaultHyperedgeToNodeMessagingFunc( - in_features + in_channels ) self.hyperedge_to_node_messenger = _HyperedgeToNodeMessenger( hyperedge_to_node_messaging_func, adjacency_dropout, aggr_func ) - self.node_batchnorm = nn.BatchNorm1d(in_features) - self.hyperedge_batchnorm = nn.BatchNorm1d(in_features) + self.node_batchnorm = nn.BatchNorm1d(in_channels) + self.hyperedge_batchnorm = nn.BatchNorm1d(in_channels) self.dropout = torch.distributions.Bernoulli(updating_dropout) if updating_func is None: - updating_func = _DefaultUpdatingFunc(in_features) + updating_func = _DefaultUpdatingFunc(in_channels) self.updating_func = updating_func def apply_regular_dropout(self, x): @@ -204,18 +204,18 @@ def forward(self, x_0, x_1, incidence_1): Parameters ---------- - x_0 : torch.Tensor, shape = (n_nodes, node_in_features) + x_0 : torch.Tensor, shape = (n_nodes, node_in_channels) Input features of the nodes. - x_1 : torch.Tensor, shape = (n_edges, hyperedge_in_features) + x_1 : torch.Tensor, shape = (n_edges, hyperedge_in_channels) Input features of the hyperedges. incidence_1 : torch.sparse.Tensor, shape = (n_nodes, n_edges) Incidence matrix mapping hyperedges to nodes (B_1). Returns ------- - x_0 : torch.Tensor, shape = (n_nodes, node_in_features) + x_0 : torch.Tensor, shape = (n_nodes, node_in_channels) Output features of the nodes. - x_1 : torch.Tensor, shape = (n_edges, hyperedge_in_features) + x_1 : torch.Tensor, shape = (n_edges, hyperedge_in_channels) Output features of the hyperedges. """ node_messages_aggregated, node_messages = self.node_to_hyperedge_messenger( diff --git a/topomodelx/nn/hypergraph/hnhn.py b/topomodelx/nn/hypergraph/hnhn.py index 0ac50340e..19df7d5c0 100644 --- a/topomodelx/nn/hypergraph/hnhn.py +++ b/topomodelx/nn/hypergraph/hnhn.py @@ -10,14 +10,12 @@ class HNHN(torch.nn.Module): Parameters ---------- - channels_node : int - Dimension of node features. - channels_edge : int - Dimension of edge features. + in_channels : int + Dimension of the input features. + hidden_channels : int + Dimension of the hidden features. incidence_1 : torch.sparse, shape = (n_nodes, n_edges) Incidence matrix mapping edges to nodes (B_1). - n_classes: int - Number of classes. n_layers : int Number of HNHN message passing layers. @@ -30,20 +28,32 @@ class HNHN(torch.nn.Module): """ def __init__( - self, channels_node, channels_edge, incidence_1, n_classes, n_layers=2 + self, + in_channels, + hidden_channels, + incidence_1, + n_layers=2 ): super().__init__() - self.layers = torch.nn.ModuleList( - [ + + layers = [] + layers.append( HNHNLayer( - channels_node=channels_node, - channels_edge=channels_edge, + in_channels=in_channels, + hidden_channels=hidden_channels, incidence_1=incidence_1, ) - for _ in range(n_layers) - ] - ) - self.linear = torch.nn.Linear(channels_node, n_classes) + ) + for _ in range(n_layers - 1): + layers.append( + HNHNLayer( + in_channels=hidden_channels, + hidden_channels=hidden_channels, + incidence_1=incidence_1, + ) + ) + self.layers = torch.nn.ModuleList(layers) + def forward(self, x_0, x_1): """Forward computation. @@ -61,80 +71,79 @@ def forward(self, x_0, x_1): Returns ------- - logits : torch.Tensor, shape = (n_nodes, n_classes) - The predicted node logits - classes : torch.Tensor, shape = (n_nodes) - The predicted node class - """ - for layer in self.layers: - x_0, x_1 = layer(x_0, x_1) - logits = self.linear(x_0) - classes = torch.softmax(logits, -1).argmax(-1) - return logits, classes - - -class HNHNNetwork(torch.nn.Module): - """Hypergraph Networks with Hyperedge Neurons. Implementation for multiclass node classification. - - Parameters - ---------- - channels_node : int - Dimension of node features. - channels_edge : int - Dimension of edge features. - incidence_1 : torch.sparse - Incidence matrix mapping edges to nodes (B_1). - shape=[n_nodes, n_edges] - n_classes: int - Number of classes - n_layers : int - Number of HNHN message passing layers. - """ - - def __init__( - self, channels_node, channels_edge, incidence_1, n_classes, n_layers=2 - ): - super().__init__() - self.layers = torch.nn.ModuleList( - [ - HNHNLayer( - channels_node=channels_node, - channels_edge=channels_edge, - incidence_1=incidence_1, - ) - for _ in range(n_layers) - ] - ) - self.linear = torch.nn.Linear(channels_node, n_classes) - - def forward(self, x_0, x_1): - """Forward computation. - - Parameters - ---------- x_0 : torch.Tensor - shape = [n_nodes, channels_node] - Hypernode features. - + Output node features. x_1 : torch.Tensor - shape = [n_nodes, channels_edge] - Hyperedge features. - - incidence_1 : torch.Tensor - shape = [n_nodes, n_edges] - Boundary matrix of rank 1. - - Returns - ------- - logits : torch.Tensor - The predicted node logits - shape = [n_nodes, n_classes] - classes : torch.Tensor - The predicted node class - shape = [n_nodes] + Output hyperedge features. """ + for layer in self.layers: x_0, x_1 = layer(x_0, x_1) - logits = self.linear(x_0) - classes = torch.softmax(logits, -1).argmax(-1) - return logits, classes + + return x_0, x_1 + + + +# class HNHNNetwork(torch.nn.Module): +# """Hypergraph Networks with Hyperedge Neurons. Implementation for multiclass node classification. + +# Parameters +# ---------- +# channels_node : int +# Dimension of node features. +# channels_edge : int +# Dimension of edge features. +# incidence_1 : torch.sparse +# Incidence matrix mapping edges to nodes (B_1). +# shape=[n_nodes, n_edges] +# n_classes: int +# Number of classes +# n_layers : int +# Number of HNHN message passing layers. +# """ + +# def __init__( +# self, channels_node, channels_edge, incidence_1, n_classes, n_layers=2 +# ): +# super().__init__() +# self.layers = torch.nn.ModuleList( +# [ +# HNHNLayer( +# channels_node=channels_node, +# channels_edge=channels_edge, +# incidence_1=incidence_1, +# ) +# for _ in range(n_layers) +# ] +# ) +# self.linear = torch.nn.Linear(channels_node, n_classes) + +# def forward(self, x_0, x_1): +# """Forward computation. + +# Parameters +# ---------- +# x_0 : torch.Tensor +# shape = [n_nodes, channels_node] +# Hypernode features. + +# x_1 : torch.Tensor +# shape = [n_nodes, channels_edge] +# Hyperedge features. + +# incidence_1 : torch.Tensor +# shape = [n_nodes, n_edges] +# Boundary matrix of rank 1. + +# Returns +# ------- +# x_0 : torch.Tensor +# Output node features. +# x_1 : torch.Tensor +# Output hyperedge features. +# """ + +# for layer in self.layers: +# x_0, x_1 = layer(x_0, x_1) + +# return x_0, x_1 diff --git a/topomodelx/nn/hypergraph/hnhn_layer.py b/topomodelx/nn/hypergraph/hnhn_layer.py index 7ab6a7300..75c0006f0 100644 --- a/topomodelx/nn/hypergraph/hnhn_layer.py +++ b/topomodelx/nn/hypergraph/hnhn_layer.py @@ -60,8 +60,8 @@ class HNHNLayer(torch.nn.Module): def __init__( self, - channels_node, - channels_edge, + in_channels, + hidden_channels, incidence_1, use_bias: bool = True, use_normalized_incidence: bool = True, @@ -77,23 +77,23 @@ def __init__( self.use_normalized_incidence = use_normalized_incidence self.incidence_1 = incidence_1 self.incidence_1_transpose = incidence_1.transpose(1, 0) - self.channels_edge = channels_edge - self.channels_node = channels_node - self.conv_1_to_0 = Conv( - in_channels=channels_edge, - out_channels=channels_node, + + self.conv_0_to_1 = Conv( + in_channels=in_channels, + out_channels=hidden_channels, aggr_norm=False, update_func=None, ) - self.conv_0_to_1 = Conv( - in_channels=channels_node, - out_channels=channels_edge, + + self.conv_1_to_0 = Conv( + in_channels=hidden_channels, + out_channels=hidden_channels, aggr_norm=False, update_func=None, ) if self.use_bias: - self.bias_1_to_0 = Parameter(torch.Tensor(1, channels_node)) - self.bias_0_to_1 = Parameter(torch.Tensor(1, channels_edge)) + self.bias_1_to_0 = Parameter(torch.Tensor(1, hidden_channels)) + self.bias_0_to_1 = Parameter(torch.Tensor(1, hidden_channels)) self.init_biases() if self.use_normalized_incidence: self.alpha = alpha @@ -196,11 +196,11 @@ def forward(self, x_0, x_1): self.incidence_1 = self.incidence_1.to(x_0.device) self.incidence_1_transpose = self.incidence_1_transpose.to(x_0.device) # Compute output hyperedge features - x_1_tp1 = self.conv_0_to_1(x_0, self.incidence_1_transpose) # nodes to edges + x_1 = self.conv_0_to_1(x_0, self.incidence_1_transpose) # nodes to edges if self.use_bias: - x_1_tp1 += self.bias_0_to_1 + x_1 += self.bias_0_to_1 # Compute output hypernode features - x_0_tp1 = self.conv_1_to_0(x_1, self.incidence_1) # edges to nodes + x_0 = self.conv_1_to_0(x_1, self.incidence_1) # edges to nodes if self.use_bias: - x_0_tp1 += self.bias_1_to_0 - return torch.sigmoid(x_0_tp1), torch.sigmoid(x_1_tp1) + x_0 += self.bias_1_to_0 + return (torch.relu(x_0), torch.relu(x_1)) diff --git a/topomodelx/nn/hypergraph/hypergat.py b/topomodelx/nn/hypergraph/hypergat.py index 4ed0123ec..8084bfecc 100644 --- a/topomodelx/nn/hypergraph/hypergat.py +++ b/topomodelx/nn/hypergraph/hypergat.py @@ -14,14 +14,8 @@ class HyperGAT(torch.nn.Module): Dimension of the input features. hidden_channels : int Dimension of the hidden features. - out_channels : int - Dimension of the output features. n_layer : int, default = 2 Amount of message passing layers. - task_level: str, default="graph" - Level of the task. Either "graph" or "node". - If "graph", the output is pooled over all nodes in the hypergraph. - References ---------- @@ -34,9 +28,7 @@ def __init__( self, in_channels, hidden_channels, - out_channels, n_layers=2, - task_level="graph", ): super().__init__() layers = [] @@ -46,8 +38,6 @@ def __init__( HyperGATLayer(in_channels=hidden_channels, out_channels=hidden_channels) ) self.layers = torch.nn.ModuleList(layers) - self.linear = torch.nn.Linear(hidden_channels, out_channels) - self.out_pool = True if task_level == "graph" else False def forward(self, x_0, incidence_1): """Forward computation through layers, then linear layer, then global max pooling. @@ -63,16 +53,12 @@ def forward(self, x_0, incidence_1): Returns ------- - torch.Tensor, shape = (1) - Label assigned to whole complex. + x_0 : torch.Tensor + Output node features. + x_1 : torch.Tensor + Output hyperedge features. """ for layer in self.layers: - x_0 = layer.forward(x_0, incidence_1) + x_0, x_1 = layer.forward(x_0, incidence_1) - # Pool over all nodes in the hypergraph - if self.out_pool is True: - x = torch.max(x_0, dim=0)[0] - else: - x = x_0 - - return self.linear(x) + return x_0, x_1 \ No newline at end of file diff --git a/topomodelx/nn/hypergraph/hypergat_layer.py b/topomodelx/nn/hypergraph/hypergat_layer.py index 96f4f5893..cef2dbc82 100644 --- a/topomodelx/nn/hypergraph/hypergat_layer.py +++ b/topomodelx/nn/hypergraph/hypergat_layer.py @@ -169,8 +169,10 @@ def forward(self, x_source, incidence): Returns ------- - x : torch.Tensor - Output features. + x_0 : torch.Tensor + Output node features. + x_1 : torch.Tensor + Output hyperedge features. """ intra_aggregation = incidence.t() @ (x_source @ self.weight1) @@ -200,4 +202,5 @@ def forward(self, x_source, incidence): inter_aggregation_with_attention = incidence_with_attention @ ( messages_on_edges @ self.weight2 ) - return self.update(inter_aggregation_with_attention) + + return self.update(inter_aggregation_with_attention), messages_on_edges diff --git a/topomodelx/nn/hypergraph/hypersage.py b/topomodelx/nn/hypergraph/hypersage.py index d5501ddc5..5c7f44346 100644 --- a/topomodelx/nn/hypergraph/hypersage.py +++ b/topomodelx/nn/hypergraph/hypersage.py @@ -10,10 +10,10 @@ class HyperSAGE(torch.nn.Module): Parameters ---------- - channels_edge : int - Dimension of edge features - channels_node : int - Dimension of node features + in_channels : int + Dimension of the input features. + hidden_channels : int + Dimension of the hidden features. n_layer : int, default = 2 Amount of message passing layers. @@ -27,11 +27,9 @@ class HyperSAGE(torch.nn.Module): def __init__( self, in_channels, - hidden_channels, - out_channels, - n_layers=2, - task_level="graph", - **kwargs + hidden_channels, + n_layers=2, + **kwargs ): super().__init__() layers = [] @@ -45,9 +43,7 @@ def __init__( ) ) self.layers = torch.nn.ModuleList(layers) - self.linear = torch.nn.Linear(hidden_channels, out_channels) - self.out_pool = True if task_level == "graph" else False - + def forward(self, x_0, incidence): """Forward computation through layers, then linear layer, then global max pooling. @@ -67,10 +63,4 @@ def forward(self, x_0, incidence): for layer in self.layers: x_0 = layer.forward(x_0, incidence) - # Pool over all nodes in the hypergraph - if self.out_pool is True: - x = torch.max(x_0, dim=0)[0] - else: - x = x_0 - - return self.linear(x) + return x_0 \ No newline at end of file diff --git a/topomodelx/nn/hypergraph/hypersage_layer.py b/topomodelx/nn/hypergraph/hypersage_layer.py index fd552abbb..2e4ab4d95 100644 --- a/topomodelx/nn/hypergraph/hypersage_layer.py +++ b/topomodelx/nn/hypergraph/hypersage_layer.py @@ -215,5 +215,5 @@ def edges_per_node(v): ) x_message = x + inter_edge_aggregation - - return self.update(x_message / x_message.norm(p=2) @ self.weight) + x_0 = self.update(x_message / x_message.norm(p=2) @ self.weight) + return x_0 diff --git a/topomodelx/nn/hypergraph/unigcn.py b/topomodelx/nn/hypergraph/unigcn.py index a76a79427..824744d07 100644 --- a/topomodelx/nn/hypergraph/unigcn.py +++ b/topomodelx/nn/hypergraph/unigcn.py @@ -14,8 +14,6 @@ class UniGCN(torch.nn.Module): Dimension of the input features. hidden_channels : int Dimension of the hidden features. - out_channels : int - Dimension of the output features. n_layer : int, default = 2 Amount of message passing layers. @@ -30,9 +28,7 @@ class UniGCN(torch.nn.Module): def __init__(self, in_channels, hidden_channels, - out_channels, n_layers=2, - task_level="graph", ): super().__init__() layers = [] @@ -50,15 +46,14 @@ def __init__(self, ) ) self.layers = torch.nn.ModuleList(layers) - self.linear = torch.nn.Linear(hidden_channels, out_channels) - self.out_pool = True if task_level == "graph" else False - def forward(self, x_1, incidence_1): + + def forward(self, x_0, incidence_1): """Forward computation through layers, then linear layer, then global max pooling. Parameters ---------- - x_1 : torch.Tensor, shape = (n_edges, channels_edge) + x_0 : torch.Tensor, shape = (n_edges, channels_edge) Edge features. incidence_1 : torch.Tensor, shape = (n_nodes, n_edges) @@ -66,16 +61,12 @@ def forward(self, x_1, incidence_1): Returns ------- - torch.Tensor, shape = (1) - Label assigned to whole complex. + x_0 : torch.Tensor + Output node features. + x_1 : torch.Tensor + Output hyperedge features. """ for layer in self.layers: - x_1 = layer(x_1, incidence_1) - - # Pool over all nodes in the hypergraph - if self.out_pool is True: - x = torch.max(x_1, dim=0)[0] - else: - x = x_1 + x_0, x_1 = layer(x_0, incidence_1) - return self.linear(x) + return (x_0, x_1) \ No newline at end of file diff --git a/topomodelx/nn/hypergraph/unigcn_layer.py b/topomodelx/nn/hypergraph/unigcn_layer.py index fd254768b..4a0935d6e 100644 --- a/topomodelx/nn/hypergraph/unigcn_layer.py +++ b/topomodelx/nn/hypergraph/unigcn_layer.py @@ -108,17 +108,20 @@ def forward(self, x_0, incidence_1): Returns ------- - x_0 : torch.Tensor, shape = (n_nodes, out_channels) - Output features on the nodes of the hypergraph. + x_0 : torch.Tensor + Output node features. + x_1 : torch.Tensor + Output hyperedge features. """ + if x_0.shape[-2] != incidence_1.shape[-2]: raise ValueError( f"Mismatch in number of nodes in features and nodes: {x_0.shape[-2]} and {incidence_1.shape[-2]}." ) incidence_1_transpose = incidence_1.transpose(1, 0) - m_0_1 = self.conv_level1_0_to_1(x_0, incidence_1_transpose) + x_1 = self.conv_level1_0_to_1(x_0, incidence_1_transpose) if self.bn is not None: - m_0_1 = self.bn(m_0_1) - m_1_0 = self.conv_level2_1_to_0(m_0_1, incidence_1) - return m_1_0 + x_1 = self.bn(x_1) + x_0 = self.conv_level2_1_to_0(x_1, incidence_1) + return (x_0, x_1) diff --git a/topomodelx/nn/hypergraph/unigcnii.py b/topomodelx/nn/hypergraph/unigcnii.py index 3f088eecc..aa32079a5 100644 --- a/topomodelx/nn/hypergraph/unigcnii.py +++ b/topomodelx/nn/hypergraph/unigcnii.py @@ -14,8 +14,6 @@ class UniGCNII(torch.nn.Module): Dimension of the input features. hidden_channels : int Dimension of the hidden features. - out_channels : int - Dimension of the output features. n_layers: int, default=2 Number of UniGCNII message passing layers. alpha: float, default=0.5 @@ -26,10 +24,6 @@ class UniGCNII(torch.nn.Module): Dropout rate for the input features. layer_drop: float, default=0.2 Dropout rate for the hidden features. - task_level: str, default="graph" - Level of the task. Either "graph" or "node". - If "graph", the output is pooled over all nodes in the hypergraph. - References ---------- @@ -43,13 +37,11 @@ def __init__( self, in_channels, hidden_channels, - out_channels, n_layers=2, alpha=0.5, beta=0.5, input_drop=0.2, layer_drop=0.2, - task_level="graph", ): super().__init__() layers = [] @@ -58,8 +50,7 @@ def __init__( self.layer_drop = torch.nn.Dropout(layer_drop) # Define initial linear layer self.linear_init = torch.nn.Linear(in_channels, hidden_channels) - - + # Define convolutional layers for i in range(n_layers): beta = math.log(alpha/(i+1)+1) @@ -72,8 +63,6 @@ def __init__( ) self.layers = torch.nn.ModuleList(layers) - self.linear = torch.nn.Linear(hidden_channels, out_channels) - self.out_pool = True if task_level == "graph" else False def forward(self, x_0, incidence_1): """Forward pass through the model. @@ -88,8 +77,10 @@ def forward(self, x_0, incidence_1): Returns ------- - y_hat : torch.Tensor, shape = (num_nodes, num_classes) - Contains the logits for classification for every node. + x_0 : torch.Tensor + Output node features. + x_1 : torch.Tensor + Output hyperedge features. """ x_0 = self.input_drop(x_0) @@ -98,15 +89,8 @@ def forward(self, x_0, incidence_1): x_0_skip = x_0 for layer in self.layers: - x_0 = layer(x_0, incidence_1, x_0_skip) + x_0, x_1 = layer(x_0, incidence_1, x_0_skip) x_0 = self.layer_drop(x_0) x_0 = torch.nn.functional.relu(x_0) - # Pool over all nodes in the hypergraph - if self.out_pool is True: - x = torch.max(x_0, dim=0)[0] - else: - x = x_0 - - - return self.linear(x) + return (x_0, x_1) \ No newline at end of file diff --git a/topomodelx/nn/hypergraph/unigcnii_layer.py b/topomodelx/nn/hypergraph/unigcnii_layer.py index ad9a23930..587715e18 100644 --- a/topomodelx/nn/hypergraph/unigcnii_layer.py +++ b/topomodelx/nn/hypergraph/unigcnii_layer.py @@ -85,8 +85,10 @@ def forward(self, x_0, incidence_1, x_skip=None): Returns ------- - x_0 : torch.Tensor, shape = (num_nodes, in_channels) - Output features of the nodes of the hypergraph. + x_0 : torch.Tensor + Output node features. + x_1 : torch.Tensor + Output hyperedge features. """ x_skip = x_0 if x_skip is None else x_skip @@ -111,10 +113,11 @@ def forward(self, x_0, incidence_1, x_skip=None): edge_degree = edge_degree / torch.sum(incidence_1.to_dense(), dim=0) # Second message normalized with node and edge degrees (using broadcasting) - m_1_0 = (1 / torch.sqrt(node_degree).unsqueeze(-1)) * torch.sparse.mm( + x_1 = (1 / torch.sqrt(node_degree).unsqueeze(-1)) * torch.sparse.mm( incidence_1 @ torch.diag(1 / torch.sqrt(edge_degree)), m_0_1 ) # Introduce skip connections with hyperparameter alpha and beta - x_combined = ((1 - self.alpha) * m_1_0) + (self.alpha * x_skip) - return ((1 - self.beta) * x_combined) + self.beta * self.linear(x_combined) + x_combined = ((1 - self.alpha) * x_1) + (self.alpha * x_skip) + x_0 = ((1 - self.beta) * x_combined) + self.beta * self.linear(x_combined) + return x_0, x_1 diff --git a/topomodelx/nn/hypergraph/unigin.py b/topomodelx/nn/hypergraph/unigin.py index 705da2a29..41344201a 100644 --- a/topomodelx/nn/hypergraph/unigin.py +++ b/topomodelx/nn/hypergraph/unigin.py @@ -14,17 +14,13 @@ class UniGIN(torch.nn.Module): Dimension of the input features. hidden_channels : int Dimension of the hidden features. - out_channels : int - Dimension of the output features. - n_layer : int, default = 2 + n_layers : int, default = 2 Amount of message passing layers. input_drop: float, default=0.2 Dropout rate for the input features. layer_drop: float, default=0.2 Dropout rate for the hidden features. - task_level: str, default="graph" - Level of the task. Either "graph" or "node". - If "graph", the output is pooled over all nodes in the hypergraph. + References ---------- @@ -38,11 +34,10 @@ def __init__( self, in_channels, hidden_channels, - out_channels, + n_layers=2, input_drop=0.2, layer_drop=0.2, - n_layers=2, - task_level="graph", + ): super().__init__() layers = [] @@ -63,9 +58,6 @@ def __init__( self.layers = torch.nn.ModuleList(layers) - self.linear_out = torch.nn.Linear(hidden_channels, out_channels) - self.out_pool = True if task_level == "graph" else False - def forward(self, x_0, incidence_1): """Forward computation through layers, then linear layer, then global max pooling. @@ -79,19 +71,15 @@ def forward(self, x_0, incidence_1): Returns ------- - torch.Tensor, shape = (1) - Label assigned to whole complex. + x_0 : torch.Tensor + Output node features. + x_1 : torch.Tensor + Output hyperedge features. """ x_0 = self.linear_init(x_0) for layer in self.layers: - x_0 = layer(x_0, incidence_1) + x_0, x_1 = layer(x_0, incidence_1) x_0 = self.layer_drop(x_0) x_0 = torch.nn.functional.relu(x_0) - # Pool over all nodes in the hypergraph - if self.out_pool is True: - x = torch.max(x_0, dim=0)[0] - else: - x = x_0 - - return self.linear_out(x) + return (x_0, x_1) \ No newline at end of file diff --git a/topomodelx/nn/hypergraph/unigin_layer.py b/topomodelx/nn/hypergraph/unigin_layer.py index 30fc8f551..16eeacad0 100644 --- a/topomodelx/nn/hypergraph/unigin_layer.py +++ b/topomodelx/nn/hypergraph/unigin_layer.py @@ -87,13 +87,16 @@ def forward(self, x_0, incidence_1): Returns ------- - x_0 : torch.Tensor, shape = (n_nodes, out_channels) - Output features on the nodes of the hypergraph. + x_0 : torch.Tensor + Output node features. + x_1 : torch.Tensor + Output hyperedge features. """ incidence_1_transpose = incidence_1.to_dense().T.to_sparse() # First pass fills in features of edges by adding features of constituent nodes - m_0_1 = torch.sparse.mm(incidence_1_transpose.float(), x_0) + x_1 = torch.sparse.mm(incidence_1_transpose.float(), x_0) # Second pass fills in features of nodes by adding features of the incident edges - m_1_0 = torch.sparse.mm(incidence_1.float(), m_0_1) + m_1_0 = torch.sparse.mm(incidence_1.float(), x_1) # Update node features using GIN update equation - return self.linear((1 + self.eps) * x_0 + m_1_0) + x_0 = self.linear((1 + self.eps) * x_0 + m_1_0) + return (x_0, x_1) diff --git a/topomodelx/nn/hypergraph/unisage.py b/topomodelx/nn/hypergraph/unisage.py index cfbacc797..8a8403474 100644 --- a/topomodelx/nn/hypergraph/unisage.py +++ b/topomodelx/nn/hypergraph/unisage.py @@ -14,18 +14,13 @@ class UniSAGE(torch.nn.Module): Dimension of the input features. hidden_channels : int Dimension of the hidden features. - out_channels : int - Dimension of the output features. - n_layer : int, default = 2 - Amount of message passing layers. input_drop: float, default=0.2 Dropout rate for the input features. layer_drop: float, default=0.2 Dropout rate for the hidden features. - task_level: str, default="graph" - Level of the task. Either "graph" or "node". - If "graph", the output is pooled over all nodes in the hypergraph. - + n_layer : int, default = 2 + Amount of message passing layers. + References ---------- .. [1] Huang and Yang. @@ -38,18 +33,15 @@ def __init__( self, in_channels, hidden_channels, - out_channels, input_drop=0.2, layer_drop=0.2, n_layers=2, - task_level="graph", ): super().__init__() self.input_drop = torch.nn.Dropout(input_drop) self.layer_drop = torch.nn.Dropout(layer_drop) - layers = [] layers.append( UniSAGELayer( @@ -66,15 +58,13 @@ def __init__( ) self.layers = torch.nn.ModuleList(layers) - self.linear_out = torch.nn.Linear(hidden_channels, out_channels) - self.out_pool = True if task_level == "graph" else False - + def forward(self, x_0, incidence_1): """Forward computation through layers, then linear layer, then global max pooling. Parameters ---------- - x : torch.Tensor, shape = (n_edges, channels_edge) + x_0 : torch.Tensor, shape = (n_edges, channels_edge) Edge features. incidence_1 : torch.Tensor, shape = (n_nodes, n_edges) @@ -82,22 +72,19 @@ def forward(self, x_0, incidence_1): Returns ------- - torch.Tensor, shape = (1) - Label assigned to whole complex. + x_0 : torch.Tensor + Output node features. + x_1 : torch.Tensor + Output hyperedge features. """ x_0 = self.input_drop(x_0) # Iterate over layers for layer in self.layers: - x_0 = layer(x_0, incidence_1) + x_0, x_1 = layer(x_0, incidence_1) x_0 = self.layer_drop(x_0) x_0 = torch.nn.functional.relu(x_0) - # Pool over all nodes in the hypergraph - if self.out_pool is True: - x = torch.max(x_0, dim=0)[0] - else: - x = x_0 - - return self.linear_out(x) + + return (x_0, x_1) diff --git a/topomodelx/nn/hypergraph/unisage_layer.py b/topomodelx/nn/hypergraph/unisage_layer.py index 873df4263..8142013af 100644 --- a/topomodelx/nn/hypergraph/unisage_layer.py +++ b/topomodelx/nn/hypergraph/unisage_layer.py @@ -106,8 +106,10 @@ def forward(self, x_0, incidence_1): Returns ------- - x_0 : torch.Tensor, shape = (n_nodes, out_channels) - Output features on the nodes of the hypergraph. + x_0 : torch.Tensor + Output node features. + x_1 : torch.Tensor + Output hyperedge features. """ x_0 = self.linear(x_0) if self.bn is not None: @@ -120,8 +122,12 @@ def forward(self, x_0, incidence_1): else: # Transpose generates CSC tensor, thus we have to convert to csr incidence_1_transpose = incidence_1.transpose(1, 0).to_sparse_csr() + # First pass fills in features of edges by adding features of constituent nodes - m_0_1 = torch.sparse.mm(incidence_1_transpose.float(), x_0, reduce=self.e_aggr) + x_1 = torch.sparse.mm(incidence_1_transpose.float(), x_0, reduce=self.e_aggr) + # Second pass fills in features of nodes by adding features of the incident edges - m_1_0 = torch.sparse.mm(incidence_1.float(), m_0_1, reduce=self.v_aggr) - return x_0 + m_1_0 + m_1_0 = torch.sparse.mm(incidence_1.float(), x_1, reduce=self.v_aggr) + x_0 = x_0 + m_1_0 + + return (x_0, x_1) diff --git a/tutorials/hypergraph/allset_train.ipynb b/tutorials/hypergraph/allset_train.ipynb index 537532738..70370fb83 100644 --- a/tutorials/hypergraph/allset_train.ipynb +++ b/tutorials/hypergraph/allset_train.ipynb @@ -36,7 +36,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:51.222779223Z", @@ -60,7 +60,10 @@ "from torch_geometric.utils import to_undirected\n", "import torch_geometric.datasets as geom_datasets\n", "\n", - "from topomodelx.nn.hypergraph.allset import AllSet\n" + "from topomodelx.nn.hypergraph.allset import AllSet\n", + "\n", + "torch.manual_seed(0)\n", + "np.random.seed(0)\n" ] }, { @@ -73,7 +76,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 13, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:51.959770754Z", @@ -108,7 +111,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 3, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:53.022151550Z", @@ -153,7 +156,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:53.022151550Z", @@ -194,7 +197,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -243,7 +246,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -266,33 +269,109 @@ "# Create the Neural Network" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Define the network that initializes the base model and sets up the readout operation.\n", + "Different downstream tasks might require different pooling procedures.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "class Network(torch.nn.Module):\n", + " \"\"\" Network class that initializes the AllSet model and readout layer.\n", + "\n", + " Base model parameters:\n", + " ----------\n", + " Reqired:\n", + " in_channels : int\n", + " Dimension of the input features.\n", + " hidden_channels : int\n", + " Dimension of the hidden features.\n", + "\n", + " Optitional:\n", + " **kwargs : dict\n", + " Additional arguments for the base model.\n", + " \n", + " Readout layer parameters:\n", + " ----------\n", + " out_channels : int\n", + " Dimension of the output features.\n", + " task_level : str\n", + " Level of the task. Either \"graph\" or \"node\". \n", + " \"\"\"\n", + " def __init__(\n", + " self, \n", + " in_channels, \n", + " hidden_channels,\n", + " out_channels, \n", + " \n", + " task_level=\"graph\",\n", + " **kwargs):\n", + " super().__init__()\n", + " \n", + " # Define the model\n", + " self.base_model = AllSet(\n", + " in_channels=in_channels,\n", + " hidden_channels=hidden_channels,\n", + " **kwargs\n", + " )\n", + "\n", + "\n", + " # Readout\n", + " self.linear = torch.nn.Linear(hidden_channels, out_channels)\n", + " self.out_pool = True if task_level == \"graph\" else False\n", + " \n", + " def forward(self, x_0, incidence_1):\n", + " # Base model\n", + " x_0, x_1 = self.base_model(x_0, incidence_1)\n", + "\n", + " # Pool over all nodes in the hypergraph \n", + " if self.out_pool is True:\n", + " x = torch.max(x_0, dim=0)[0]\n", + " else:\n", + " x = x_0\n", + "\n", + " return self.linear(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Initialize the model" + ] + }, { "cell_type": "code", "execution_count": 8, - "metadata": { - "ExecuteTime": { - "end_time": "2023-06-01T16:14:55.343005145Z", - "start_time": "2023-06-01T16:14:55.339481459Z" - } - }, + "metadata": {}, "outputs": [], "source": [ + "# Base model hyperparameters\n", "in_channels = x_0s.shape[1]\n", "hidden_channels = 128\n", + "n_layers=1\n", + "mlp_num_layers=1\n", + "\n", + "# Readout hyperparameters\n", "out_channels = torch.unique(y).shape[0]\n", "task_level = \"graph\" if out_channels==1 else \"node\"\n", - "n_layers=1\n", "\n", - "# Define the model\n", - "model = AllSet(\n", + "\n", + "model = Network(\n", " in_channels=in_channels,\n", " hidden_channels=hidden_channels,\n", - " out_channels=out_channels,\n", + " out_channels=out_channels, \n", " n_layers=n_layers,\n", - " mlp_num_layers=1,\n", + " mlp_num_layers=mlp_num_layers,\n", " task_level=task_level,\n", - ")\n", - "model = model.to(device)" + " ).to(device)" ] }, { @@ -335,9 +414,9 @@ "name": "stderr", "output_type": "stream", "text": [ - "/tmp/ipykernel_316993/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_645923/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " x_0s = torch.tensor(x_0s)\n", - "/tmp/ipykernel_316993/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_645923/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " torch.tensor(y, dtype=torch.long).to(device),\n" ] } @@ -369,9 +448,9 @@ "output_type": "stream", "text": [ "Epoch: 5 \n", - "Train_loss: 1.8375, acc: 0.6286\n", - "Val_loss: 1.6964, Val_acc: 0.3480\n", - "Test_loss: 1.6553, Test_acc: 0.3760\n" + "Train_loss: 1.8073, acc: 0.5143\n", + "Val_loss: 1.6731, Val_acc: 0.4200\n", + "Test_loss: 1.6482, Test_acc: 0.4550\n" ] }, { @@ -379,30 +458,30 @@ "output_type": "stream", "text": [ "Epoch: 10 \n", - "Train_loss: 1.5705, acc: 0.7429\n", - "Val_loss: 1.5425, Val_acc: 0.5160\n", - "Test_loss: 1.5357, Test_acc: 0.5240\n", + "Train_loss: 1.5072, acc: 0.7714\n", + "Val_loss: 1.2418, Val_acc: 0.5940\n", + "Test_loss: 1.2165, Test_acc: 0.6140\n", "Epoch: 15 \n", - "Train_loss: 1.2492, acc: 0.8786\n", - "Val_loss: 1.5955, Val_acc: 0.5420\n", - "Test_loss: 1.6364, Test_acc: 0.5360\n", + "Train_loss: 1.1989, acc: 0.9714\n", + "Val_loss: 1.9284, Val_acc: 0.6380\n", + "Test_loss: 1.9215, Test_acc: 0.6280\n", "Epoch: 20 \n", - "Train_loss: 0.9905, acc: 1.0000\n", - "Val_loss: 2.3123, Val_acc: 0.6780\n", - "Test_loss: 2.5038, Test_acc: 0.6860\n", + "Train_loss: 0.9625, acc: 0.9429\n", + "Val_loss: 2.6081, Val_acc: 0.6860\n", + "Test_loss: 2.4626, Test_acc: 0.6990\n", "Epoch: 25 \n", - "Train_loss: 0.7995, acc: 1.0000\n", - "Val_loss: 3.6426, Val_acc: 0.6440\n", - "Test_loss: 3.7969, Test_acc: 0.6800\n", + "Train_loss: 0.7969, acc: 1.0000\n", + "Val_loss: 3.6042, Val_acc: 0.6840\n", + "Test_loss: 3.5520, Test_acc: 0.6730\n", "Epoch: 30 \n", - "Train_loss: 0.6813, acc: 1.0000\n", - "Val_loss: 4.1802, Val_acc: 0.6800\n", - "Test_loss: 4.1946, Test_acc: 0.7110\n" + "Train_loss: 0.6704, acc: 1.0000\n", + "Val_loss: 3.7970, Val_acc: 0.7140\n", + "Test_loss: 3.6409, Test_acc: 0.7040\n" ] } ], "source": [ - "torch.manual_seed(0)\n", + "\n", "test_interval = 5\n", "num_epochs = 30\n", "\n", @@ -439,13 +518,6 @@ " loss = loss_fn(y_hat[test_mask], y[test_mask])\n", " print(f\"Test_loss: {loss:.4f}, Test_acc: {acc_fn(y_hat[test_mask].argmax(1), y[test_mask]):.4f}\", flush=True)" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/tutorials/hypergraph/allset_transformer_train.ipynb b/tutorials/hypergraph/allset_transformer_train.ipynb index f8942a99d..800272fe4 100644 --- a/tutorials/hypergraph/allset_transformer_train.ipynb +++ b/tutorials/hypergraph/allset_transformer_train.ipynb @@ -90,7 +90,10 @@ "from torch_geometric.utils import to_undirected\n", "import torch_geometric.datasets as geom_datasets\n", "\n", - "from topomodelx.nn.hypergraph.allset_transformer import AllSetTransformer\n" + "from topomodelx.nn.hypergraph.allset_transformer import AllSetTransformer\n", + "\n", + "torch.manual_seed(0)\n", + "np.random.seed(0)\n" ] }, { @@ -296,34 +299,112 @@ "\n" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Define the network that initializes the base model and sets up the readout operation.\n", + "Different downstream tasks might require different pooling procedures." + ] + }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ + "class Network(torch.nn.Module):\n", + " \"\"\" Network class that initializes the base model and readout layer.\n", + "\n", + " Base model parameters:\n", + " ----------\n", + " Reqired:\n", + " in_channels : int\n", + " Dimension of the input features.\n", + " hidden_channels : int\n", + " Dimension of the hidden features.\n", + "\n", + " Optitional:\n", + " **kwargs : dict\n", + " Additional arguments for the base model.\n", + " \n", + " Readout layer parameters:\n", + " ----------\n", + " out_channels : int\n", + " Dimension of the output features.\n", + " task_level : str\n", + " Level of the task. Either \"graph\" or \"node\". \n", + " \"\"\"\n", + " def __init__(\n", + " self, \n", + " in_channels, \n", + " hidden_channels,\n", + " out_channels, \n", + " \n", + " task_level=\"graph\",\n", + " **kwargs):\n", + " super().__init__()\n", + " \n", + " # Define the model\n", + " self.base_model = AllSetTransformer(\n", + " in_channels=in_channels,\n", + " hidden_channels=hidden_channels,\n", + " **kwargs\n", + " )\n", + "\n", + "\n", + " # Readout\n", + " self.linear = torch.nn.Linear(hidden_channels, out_channels)\n", + " self.out_pool = True if task_level == \"graph\" else False\n", + " \n", + " def forward(self, x_0, incidence_1):\n", + " # Base model\n", + " x_0, x_1 = self.base_model(x_0, incidence_1)\n", + "\n", + " # Pool over all nodes in the hypergraph \n", + " if self.out_pool is True:\n", + " x = torch.max(x_0, dim=0)[0]\n", + " else:\n", + " x = x_0\n", + "\n", + " return self.linear(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Initialize the model" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# Base model hyperparameters\n", "in_channels = x_0s.shape[1]\n", - "hidden_channels = 64\n", - "out_channels = torch.unique(y).shape[0]\n", - "task_level = \"graph\" if out_channels==1 else \"node\"\n", + "hidden_channels = 128\n", "\n", "heads = 4\n", "n_layers = 1\n", "mlp_num_layers = 2\n", "\n", + "# Readout hyperparameters\n", + "out_channels = torch.unique(y).shape[0]\n", + "task_level = \"graph\" if out_channels==1 else \"node\"\n", "\n", "\n", - "# Define the model\n", - "model = AllSetTransformer(\n", - " in_channels=in_channels,\n", - " hidden_channels=hidden_channels,\n", - " out_channels=out_channels,\n", - " heads=heads,\n", - " n_layers=n_layers,\n", - " mlp_num_layers=mlp_num_layers,\n", - " task_level=task_level,\n", - ")\n", - "model = model.to(device)" + "model = Network(\n", + " in_channels=in_channels,\n", + " hidden_channels=hidden_channels,\n", + " out_channels=out_channels,\n", + " heads=heads,\n", + " n_layers=n_layers,\n", + " mlp_num_layers=mlp_num_layers,\n", + " task_level=task_level,\n", + " ).to(device)" ] }, { @@ -338,7 +419,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -354,16 +435,16 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "/tmp/ipykernel_122619/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_695904/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " x_0s = torch.tensor(x_0s)\n", - "/tmp/ipykernel_122619/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_695904/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " torch.tensor(y, dtype=torch.long).to(device),\n" ] } @@ -387,7 +468,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:15:01.683216142Z", @@ -400,29 +481,29 @@ "output_type": "stream", "text": [ "Epoch: 5 \n", - "Train_loss: 1.6089, acc: 0.9643\n", - "Val_loss: 1.0637, Val_acc: 0.7500\n", - "Test_loss: 1.0321, Test_acc: 0.7570\n", + "Train_loss: 1.5815, acc: 0.9857\n", + "Val_loss: 0.9676, Val_acc: 0.7300\n", + "Test_loss: 0.9331, Test_acc: 0.7400\n", "Epoch: 10 \n", - "Train_loss: 1.0163, acc: 1.0000\n", - "Val_loss: 0.9332, Val_acc: 0.7480\n", - "Test_loss: 0.8356, Test_acc: 0.7710\n", + "Train_loss: 0.8823, acc: 1.0000\n", + "Val_loss: 1.0689, Val_acc: 0.7400\n", + "Test_loss: 1.0016, Test_acc: 0.7490\n", "Epoch: 15 \n", - "Train_loss: 0.7071, acc: 1.0000\n", - "Val_loss: 1.2129, Val_acc: 0.7180\n", - "Test_loss: 1.0261, Test_acc: 0.7510\n", + "Train_loss: 0.5933, acc: 1.0000\n", + "Val_loss: 1.5343, Val_acc: 0.7100\n", + "Test_loss: 1.4664, Test_acc: 0.7310\n", "Epoch: 20 \n", - "Train_loss: 0.5365, acc: 1.0000\n", - "Val_loss: 1.5998, Val_acc: 0.6940\n", - "Test_loss: 1.3869, Test_acc: 0.7240\n", + "Train_loss: 0.4458, acc: 1.0000\n", + "Val_loss: 1.9383, Val_acc: 0.7020\n", + "Test_loss: 1.7923, Test_acc: 0.7170\n", "Epoch: 25 \n", - "Train_loss: 0.4309, acc: 1.0000\n", - "Val_loss: 1.9149, Val_acc: 0.6920\n", - "Test_loss: 1.7064, Test_acc: 0.7110\n", + "Train_loss: 0.3568, acc: 1.0000\n", + "Val_loss: 2.2001, Val_acc: 0.7080\n", + "Test_loss: 2.0025, Test_acc: 0.7140\n", "Epoch: 30 \n", - "Train_loss: 0.3599, acc: 1.0000\n", - "Val_loss: 2.0770, Val_acc: 0.6880\n", - "Test_loss: 1.8370, Test_acc: 0.7070\n" + "Train_loss: 0.2988, acc: 0.9929\n", + "Val_loss: 2.0959, Val_acc: 0.7020\n", + "Test_loss: 1.8342, Test_acc: 0.7450\n" ] } ], @@ -464,13 +545,6 @@ " loss = loss_fn(y_hat[test_mask], y[test_mask])\n", " print(f\"Test_loss: {loss:.4f}, Test_acc: {acc_fn(y_hat[test_mask].argmax(1), y[test_mask]):.4f}\", flush=True)" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/tutorials/hypergraph/hmpnn_train.ipynb b/tutorials/hypergraph/hmpnn_train.ipynb index c3c4f6e67..396d76025 100644 --- a/tutorials/hypergraph/hmpnn_train.ipynb +++ b/tutorials/hypergraph/hmpnn_train.ipynb @@ -28,7 +28,10 @@ "import torch_geometric.datasets as geom_datasets\n", "from sklearn.metrics import accuracy_score\n", "\n", - "from topomodelx.nn.hypergraph.hmpnn import HMPNN" + "from topomodelx.nn.hypergraph.hmpnn import HMPNN\n", + "\n", + "torch.manual_seed(0)\n", + "np.random.seed(0)" ] }, { @@ -100,6 +103,17 @@ "dataset = dataset.to(device)" ] }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "x_0s = dataset[\"x\"]\n", + "y = dataset[\"y\"]\n", + "incidence_1 = dataset[\"incidence_1\"]" + ] + }, { "attachments": {}, "cell_type": "markdown", @@ -112,7 +126,102 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "class Network(torch.nn.Module):\n", + " \"\"\" Network class that initializes the base model and readout layer.\n", + "\n", + " Base model parameters:\n", + " ----------\n", + " Reqired:\n", + " in_channels : int\n", + " Dimension of the input features.\n", + " hidden_channels : int\n", + " Dimension of the hidden features.\n", + "\n", + " Optitional:\n", + " **kwargs : dict\n", + " Additional arguments for the base model.\n", + " \n", + " Readout layer parameters:\n", + " ----------\n", + " out_channels : int\n", + " Dimension of the output features.\n", + " task_level : str\n", + " Level of the task. Either \"graph\" or \"node\". \n", + " \"\"\"\n", + " def __init__(\n", + " self, \n", + " in_channels, \n", + " hidden_channels,\n", + " out_channels, \n", + " \n", + " task_level=\"graph\",\n", + " **kwargs):\n", + " super().__init__()\n", + " \n", + " # Define the model\n", + " self.base_model = HMPNN(\n", + " in_channels=in_channels,\n", + " hidden_channels=hidden_channels,\n", + " **kwargs\n", + " )\n", + "\n", + "\n", + " # Readout\n", + " self.linear = torch.nn.Linear(hidden_channels, out_channels)\n", + " self.out_pool = True if task_level == \"graph\" else False\n", + " \n", + " def forward(self, x_0, x_1, incidence_1):\n", + " # Base model\n", + " x_0, x_1 = self.base_model(x_0, x_1, incidence_1)\n", + "\n", + " # Pool over all nodes in the hypergraph \n", + " if self.out_pool is True:\n", + " x = torch.max(x_0, dim=0)[0]\n", + " else:\n", + " x = x_0\n", + "\n", + " return self.linear(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Initialize the model" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "# Base model hyperparameters\n", + "in_channels = x_0s.shape[1]\n", + "hidden_channels = 128\n", + "n_layers=1\n", + "\n", + "# Readout hyperparameters\n", + "out_channels = torch.unique(y).shape[0]\n", + "task_level = \"graph\" if out_channels==1 else \"node\"\n", + "\n", + "\n", + "model = Network(\n", + " in_channels=in_channels,\n", + " hidden_channels=hidden_channels,\n", + " out_channels=out_channels, \n", + " n_layers=n_layers,\n", + " task_level=task_level,\n", + " ).to(device)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:58.153514385Z", @@ -121,14 +230,7 @@ }, "outputs": [], "source": [ - "torch.manual_seed(41)\n", - "\n", - "in_features = 1433\n", - "hidden_features = 8\n", - "num_classes = 7\n", - "n_layers = 1\n", "\n", - "model = HMPNN(in_features, (256, hidden_features), num_classes, n_layers).to(device)\n", "optimizer = torch.optim.Adam(model.parameters(), lr=0.01)\n", "loss_fn = torch.nn.CrossEntropyLoss()\n", "\n", @@ -138,10 +240,7 @@ "val_mask = dataset[\"val_mask\"]\n", "test_mask = dataset[\"test_mask\"]\n", "\n", - "\n", - "x = dataset[\"x\"]\n", - "y = dataset[\"y\"]\n", - "incidence_1 = dataset[\"incidence_1\"]" + "\n" ] }, { @@ -154,7 +253,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 15, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:15:01.683216142Z", @@ -166,26 +265,26 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch: 6 train loss: 1.7054 train acc: 0.63 val loss: 1.8855 val acc: 0.34 test loss: 0.3410 val acc: 0.34\n", - "Epoch: 11 train loss: 1.6260 train acc: 0.69 val loss: 1.8205 val acc: 0.32 test loss: 0.3380 val acc: 0.34\n", - "Epoch: 16 train loss: 1.5252 train acc: 0.79 val loss: 1.7742 val acc: 0.35 test loss: 0.3920 val acc: 0.39\n", - "Epoch: 21 train loss: 1.4274 train acc: 0.85 val loss: 1.7526 val acc: 0.35 test loss: 0.3850 val acc: 0.39\n", - "Epoch: 26 train loss: 1.3159 train acc: 0.83 val loss: 1.7416 val acc: 0.36 test loss: 0.3850 val acc: 0.39\n", - "Epoch: 31 train loss: 1.2421 train acc: 0.84 val loss: 1.6929 val acc: 0.39 test loss: 0.4150 val acc: 0.41\n", - "Epoch: 36 train loss: 1.1510 train acc: 0.91 val loss: 1.6686 val acc: 0.41 test loss: 0.4340 val acc: 0.43\n", - "Epoch: 41 train loss: 1.0704 train acc: 0.91 val loss: 1.5701 val acc: 0.49 test loss: 0.4900 val acc: 0.49\n", - "Epoch: 46 train loss: 0.9775 train acc: 0.90 val loss: 1.5366 val acc: 0.50 test loss: 0.5130 val acc: 0.51\n", - "Epoch: 51 train loss: 0.9132 train acc: 0.90 val loss: 1.4844 val acc: 0.53 test loss: 0.5420 val acc: 0.54\n", - "Epoch: 56 train loss: 0.8477 train acc: 0.96 val loss: 1.4231 val acc: 0.55 test loss: 0.5600 val acc: 0.56\n", - "Epoch: 61 train loss: 0.7438 train acc: 0.97 val loss: 1.3804 val acc: 0.56 test loss: 0.5830 val acc: 0.58\n", - "Epoch: 66 train loss: 0.7040 train acc: 0.98 val loss: 1.3221 val acc: 0.59 test loss: 0.6090 val acc: 0.61\n", - "Epoch: 71 train loss: 0.6370 train acc: 0.98 val loss: 1.3007 val acc: 0.59 test loss: 0.6100 val acc: 0.61\n", - "Epoch: 76 train loss: 0.5892 train acc: 0.98 val loss: 1.2758 val acc: 0.62 test loss: 0.6180 val acc: 0.62\n", - "Epoch: 81 train loss: 0.5556 train acc: 0.99 val loss: 1.2795 val acc: 0.59 test loss: 0.6190 val acc: 0.62\n", - "Epoch: 86 train loss: 0.5107 train acc: 0.98 val loss: 1.2930 val acc: 0.59 test loss: 0.6100 val acc: 0.61\n", - "Epoch: 91 train loss: 0.4772 train acc: 0.99 val loss: 1.2791 val acc: 0.59 test loss: 0.6110 val acc: 0.61\n", - "Epoch: 96 train loss: 0.4572 train acc: 1.00 val loss: 1.2993 val acc: 0.59 test loss: 0.6060 val acc: 0.61\n", - "Epoch: 101 train loss: 0.3808 train acc: 1.00 val loss: 1.3041 val acc: 0.59 test loss: 0.6120 val acc: 0.61\n" + "Epoch: 6 train loss: 1.2548 train acc: 0.82 val loss: 1.9955 val acc: 0.23 test loss: 0.2190 val acc: 0.22\n", + "Epoch: 11 train loss: 0.8370 train acc: 1.00 val loss: 1.7554 val acc: 0.38 test loss: 0.3870 val acc: 0.39\n", + "Epoch: 16 train loss: 0.4960 train acc: 1.00 val loss: 1.6560 val acc: 0.42 test loss: 0.4450 val acc: 0.45\n", + "Epoch: 21 train loss: 0.2625 train acc: 1.00 val loss: 1.5750 val acc: 0.43 test loss: 0.4490 val acc: 0.45\n", + "Epoch: 26 train loss: 0.1403 train acc: 1.00 val loss: 1.5674 val acc: 0.45 test loss: 0.4420 val acc: 0.44\n", + "Epoch: 31 train loss: 0.0737 train acc: 1.00 val loss: 1.6039 val acc: 0.45 test loss: 0.4540 val acc: 0.45\n", + "Epoch: 36 train loss: 0.0448 train acc: 1.00 val loss: 1.6474 val acc: 0.45 test loss: 0.4700 val acc: 0.47\n", + "Epoch: 41 train loss: 0.0269 train acc: 1.00 val loss: 1.6880 val acc: 0.46 test loss: 0.4710 val acc: 0.47\n", + "Epoch: 46 train loss: 0.0182 train acc: 1.00 val loss: 1.7079 val acc: 0.44 test loss: 0.4700 val acc: 0.47\n", + "Epoch: 51 train loss: 0.0139 train acc: 1.00 val loss: 1.6682 val acc: 0.47 test loss: 0.4790 val acc: 0.48\n", + "Epoch: 56 train loss: 0.0116 train acc: 1.00 val loss: 1.6277 val acc: 0.49 test loss: 0.4970 val acc: 0.50\n", + "Epoch: 61 train loss: 0.0100 train acc: 1.00 val loss: 1.6208 val acc: 0.49 test loss: 0.5000 val acc: 0.50\n", + "Epoch: 66 train loss: 0.0086 train acc: 1.00 val loss: 1.6295 val acc: 0.51 test loss: 0.5020 val acc: 0.50\n", + "Epoch: 71 train loss: 0.0072 train acc: 1.00 val loss: 1.6361 val acc: 0.50 test loss: 0.5040 val acc: 0.50\n", + "Epoch: 76 train loss: 0.0063 train acc: 1.00 val loss: 1.6177 val acc: 0.51 test loss: 0.5060 val acc: 0.51\n", + "Epoch: 81 train loss: 0.0060 train acc: 1.00 val loss: 1.6049 val acc: 0.51 test loss: 0.5090 val acc: 0.51\n", + "Epoch: 86 train loss: 0.0055 train acc: 1.00 val loss: 1.6047 val acc: 0.52 test loss: 0.5180 val acc: 0.52\n", + "Epoch: 91 train loss: 0.0056 train acc: 1.00 val loss: 1.6063 val acc: 0.53 test loss: 0.5200 val acc: 0.52\n", + "Epoch: 96 train loss: 0.0047 train acc: 1.00 val loss: 1.6037 val acc: 0.53 test loss: 0.5170 val acc: 0.52\n", + "Epoch: 101 train loss: 0.0050 train acc: 1.00 val loss: 1.6076 val acc: 0.53 test loss: 0.5160 val acc: 0.52\n" ] } ], @@ -195,11 +294,11 @@ "num_epochs=100\n", "\n", "\n", - "initial_x_1 = torch.zeros_like(x)\n", + "initial_x_1 = torch.zeros_like(x_0s)\n", "for epoch in range(1, num_epochs + 1):\n", " model.train()\n", " optimizer.zero_grad()\n", - " y_hat = model(x, initial_x_1, incidence_1)\n", + " y_hat = model(x_0s, initial_x_1, incidence_1)\n", " loss = loss_fn(y_hat[train_mask], y[train_mask])\n", " loss.backward()\n", " optimizer.step()\n", @@ -211,7 +310,7 @@ " if epoch % test_interval == 0:\n", " model.eval()\n", " \n", - " y_hat = model(x, initial_x_1, incidence_1)\n", + " y_hat = model(x_0s, initial_x_1, incidence_1)\n", " val_loss = loss_fn(y_hat[val_mask], y[val_mask]).item()\n", " y_pred = y_hat.argmax(dim=-1)\n", " val_acc = accuracy_score(y[val_mask], y_pred[val_mask])\n", diff --git a/tutorials/hypergraph/hnhn_train.ipynb b/tutorials/hypergraph/hnhn_train.ipynb index d76f07372..4f956bf35 100644 --- a/tutorials/hypergraph/hnhn_train.ipynb +++ b/tutorials/hypergraph/hnhn_train.ipynb @@ -1,6 +1,7 @@ { "cells": [ { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ @@ -35,30 +36,52 @@ { "cell_type": "code", "execution_count": 1, - "metadata": {}, + "metadata": { + "ExecuteTime": { + "end_time": "2023-06-01T16:14:51.222779223Z", + "start_time": "2023-06-01T16:14:49.575421023Z" + } + }, "outputs": [], "source": [ + "\"\"\"\n", + "This module contains the HNHN class for hypergraph-based neural networks.\n", + "\n", + "The HNHN class implements a specific hypergraph-based neural network architecture\n", + "used for solving certain types of problems.\n", + "\n", + "Author: Your Name\n", + "\n", + "\"\"\"\n", + "\n", "import torch\n", "import numpy as np\n", - "from sklearn.model_selection import train_test_split\n", - "import toponetx.datasets.graph as graph\n", - "from topomodelx.nn.hypergraph.hnhn_layer import HNHNLayer\n", - "import matplotlib.pyplot as plt\n", - "from topomodelx.nn.hypergraph.hnhn import HNHN, HNHNNetwork\n", - "from topomodelx.utils.sparse import from_sparse" + "from torch_geometric.utils import to_undirected\n", + "import torch_geometric.datasets as geom_datasets\n", + "\n", + "from topomodelx.nn.hypergraph.hnhn import HNHN\n", + "\n", + "torch.manual_seed(0)\n", + "np.random.seed(0)\n" ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ - "If there is an available GPU, we will use it. Otherwise, this will run on CPU." + "If GPU's are available, we will make use of them. Otherwise, this will run on CPU." ] }, { "cell_type": "code", "execution_count": 2, - "metadata": {}, + "metadata": { + "ExecuteTime": { + "end_time": "2023-06-01T16:14:51.959770754Z", + "start_time": "2023-06-01T16:14:51.956096841Z" + } + }, "outputs": [ { "name": "stdout", @@ -74,67 +97,101 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "# Pre-processing\n", "\n", - "## Import dataset ##\n", - "\n", - "The first step is to import the Karate Club (https://www.jstor.org/stable/3629752) dataset. This is a singular graph with 34 nodes that belong to two different social groups. We will use these groups for the task of node-level binary classification.\n", + "## Import data ##\n", "\n", - "We must first lift our graph dataset into the hypergraph domain." + "The first step is to import the dataset, Cora, a benchmark classification datase. We then lift the graph into our domain of choice, a hypergraph.\n" ] }, { "cell_type": "code", "execution_count": 3, - "metadata": {}, - "outputs": [], + "metadata": { + "ExecuteTime": { + "end_time": "2023-06-01T16:14:53.022151550Z", + "start_time": "2023-06-01T16:14:52.949636599Z" + } + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/usr/local/lib/python3.11/site-packages/torch_geometric/data/in_memory_dataset.py:284: UserWarning: It is not recommended to directly access the internal storage format `data` of an 'InMemoryDataset'. If you are absolutely certain what you are doing, access the internal storage via `InMemoryDataset._data` instead to suppress this warning. Alternatively, you can access stacked individual attributes of every graph via `dataset.{attr_name}`.\n", + " warnings.warn(msg)\n" + ] + } + ], "source": [ - "dataset_sim = graph.karate_club(complex_type=\"simplicial\")\n", - "dataset_hyp = dataset_sim.to_hypergraph()" + "\n", + "cora = geom_datasets.Planetoid(root=\"/TopoModelX/data/cora\", name=\"Cora\")\n", + "data = cora.data\n", + "\n", + "x_0s = data.x\n", + "y = data.y\n", + "edge_index = data.edge_index\n", + "\n", + "train_mask = data.train_mask\n", + "val_mask = data.val_mask\n", + "test_mask = data.test_mask\n" ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ - "## Define neighborhood structures. ##\n", + "## Define neighborhood structures and lift into hypergraph domain. ##\n", "\n", - "Now we retrieve the neighborhood structures (i.e., their representative matrices) that we will use to send messages on the domain. In this case, we need the boundary matrix (or incidence matrix) $B_1$. For a santiy check, we show that the shape of the $B_1 = n_\\text{nodes} \\times n_\\text{edges}$. We also convert the neighborhood structures to sparse torch tensors." + "Now we retrieve the neighborhood structure (i.e. their representative matrice) that we will use to send messges from node to hyperedges. In the case of this architecture, we need the boundary matrix (or incidence matrix) $B_1$ with shape $n_\\text{nodes} \\times n_\\text{edges}$.\n", + "\n", + "In citation Cora dataset we lift graph structure to the hypergraph domain by creating hyperedges from 1-hop graph neighbourhood of each node. \n" ] }, { "cell_type": "code", "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The incidence matrix B1 has shape: torch.Size([34, 78]).\n" - ] + "metadata": { + "ExecuteTime": { + "end_time": "2023-06-01T16:14:53.022151550Z", + "start_time": "2023-06-01T16:14:52.949636599Z" } - ], + }, + "outputs": [], "source": [ - "incidence_1 = dataset_sim.incidence_matrix(rank=1, signed=False)\n", - "incidence_1 = from_sparse(incidence_1)\n", - "print(f\"The incidence matrix B1 has shape: {incidence_1.shape}.\")" + "# Ensure the graph is undirected (optional but often useful for one-hop neighborhoods).\n", + "edge_index = to_undirected(edge_index)\n", + "\n", + "# Create a list of one-hop neighborhoods for each node.\n", + "one_hop_neighborhoods = []\n", + "for node in range(data.num_nodes):\n", + " # Get the one-hop neighbors of the current node.\n", + " neighbors = data.edge_index[1, data.edge_index[0] == node]\n", + "\n", + " # Append the neighbors to the list of one-hop neighborhoods.\n", + " one_hop_neighborhoods.append(neighbors.numpy())\n", + "\n", + "# Detect and eliminate duplicate hyperedges.\n", + "unique_hyperedges = set()\n", + "hyperedges = []\n", + "for neighborhood in one_hop_neighborhoods:\n", + " # Sort the neighborhood to ensure consistent comparison.\n", + " neighborhood = tuple(sorted(neighborhood))\n", + " if neighborhood not in unique_hyperedges:\n", + " hyperedges.append(list(neighborhood))\n", + " unique_hyperedges.add(neighborhood) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Import signal ##\n", - "Our task will be node classification. To classify the nodes, we will use:\n", - "- node features $X_0$; shape: $n_{nodes} \\times channels_{node}$\n", - "- edge features $X_1$; shape: $n_{edges} \\times channels_{edge}$\n", - "\n", - "For the this specific dataset, we have $channels_{node}$ = $channels_{edge}$ = 2.\n", - "Next, we will retrieve node features, edge features, and node labels $y$. The node labels will be one-hot encoded." + "Additionally we print the statictis associated with obtained incidence matrix" ] }, { @@ -146,168 +203,184 @@ "name": "stdout", "output_type": "stream", "text": [ - "There are 34 nodes with features of dimension 2.\n" + "Hyperedge statistics: \n", + "Number of hyperedges without duplicated hyperedges 2581\n", + "min = 1, \n", + "max = 168, \n", + "mean = 4.003099573808601, \n", + "median = 3.0, \n", + "std = 5.327622607829558, \n", + "Number of hyperedges with size equal to one = 412\n" ] } ], "source": [ - "# Node features\n", - "x_0 = []\n", - "for _, v in dataset_sim.get_simplex_attributes(\"node_feat\").items():\n", - " x_0.append(v)\n", - "x_0 = torch.tensor(np.stack(x_0)).to(device)\n", - "n_nodes, channels_node = x_0.shape\n", - "print(f\"There are {n_nodes} nodes with features of dimension {channels_node}.\")" + "\n", + "# Calculate hyperedge statistics.\n", + "hyperedge_sizes = [len(he) for he in hyperedges]\n", + "min_size = min(hyperedge_sizes)\n", + "max_size = max(hyperedge_sizes)\n", + "mean_size = np.mean(hyperedge_sizes)\n", + "median_size = np.median(hyperedge_sizes)\n", + "std_size = np.std(hyperedge_sizes)\n", + "num_single_node_hyperedges = sum(np.array(hyperedge_sizes) == 1)\n", + "\n", + "# Print the hyperedge statistics.\n", + "print(f'Hyperedge statistics: ')\n", + "print('Number of hyperedges without duplicated hyperedges', len(hyperedges))\n", + "print(f'min = {min_size}, ')\n", + "print(f'max = {max_size}, ')\n", + "print(f'mean = {mean_size}, ')\n", + "print(f'median = {median_size}, ')\n", + "print(f'std = {std_size}, ')\n", + "print(f'Number of hyperedges with size equal to one = {num_single_node_hyperedges}')\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Construct incidence matrix" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "There are 78 edges with features of dimension 2.\n" - ] - } - ], + "outputs": [], "source": [ - "# Edge features\n", - "x_1 = []\n", - "for k, v in dataset_sim.get_simplex_attributes(\"edge_feat\").items():\n", - " x_1.append(v)\n", - "x_1 = torch.tensor(np.stack(x_1)).to(device)\n", - "n_edges, channels_edge = x_1.shape\n", - "print(f\"There are {n_edges} edges with features of dimension {channels_edge}.\")" + "max_edges = len(hyperedges)\n", + "incidence_1 = np.zeros((x_0s.shape[0], max_edges))\n", + "for col, neighibourhood in enumerate(hyperedges):\n", + " for row in neighibourhood:\n", + " incidence_1[row, col] = 1\n", + "\n", + "assert all(incidence_1.sum(0)>0) == True, \"Some hyperedges are empty\"\n", + "assert all(incidence_1.sum(1)>0) == True, \"Some nodes are not in any hyperedges\"\n", + "incidence_1 = torch.Tensor(incidence_1).to_sparse_coo()" ] }, { - "cell_type": "code", - "execution_count": 7, + "attachments": {}, + "cell_type": "markdown", "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "There are 34 labels, one for each node.\n" - ] - } - ], "source": [ - "# Node labels\n", - "y = np.array(\n", - " [\n", - " 1,\n", - " 1,\n", - " 1,\n", - " 1,\n", - " 1,\n", - " 1,\n", - " 1,\n", - " 1,\n", - " 1,\n", - " 0,\n", - " 1,\n", - " 1,\n", - " 1,\n", - " 1,\n", - " 0,\n", - " 0,\n", - " 1,\n", - " 1,\n", - " 0,\n", - " 1,\n", - " 0,\n", - " 1,\n", - " 0,\n", - " 0,\n", - " 0,\n", - " 0,\n", - " 0,\n", - " 0,\n", - " 0,\n", - " 0,\n", - " 0,\n", - " 0,\n", - " 0,\n", - " 0,\n", - " ]\n", - ")\n", - "n_classes = len(np.unique(y))\n", - "y_1h = np.eye(n_classes)[y].astype(int) # 1-hot representation\n", - "print(f\"There are {y_1h.shape[0]} labels, one for each node.\")" + "# Create the Neural Network" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "We will now split the dataset into stratified training (85%) and test sets (15%)" + "Define the network that initializes the base model and sets up the readout operation.\n", + "Different downstream tasks might require different pooling procedures.\n" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 7, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Fraction of class-1 samples in the training set: 0.5\n", - "Fraction of class-1 samples in the test set: 0.5\n" - ] - } - ], + "outputs": [], "source": [ - "y_train, y_test, ind_train, ind_test = train_test_split(\n", - " y_1h, np.arange(n_nodes), test_size=0.15, random_state=0, stratify=y\n", - ")\n", - "y_train = torch.tensor(y_train, dtype=torch.float32).to(device)\n", - "y_test = torch.tensor(y_test, dtype=torch.float32).to(device)\n", - "y = torch.tensor(y, dtype=torch.int32).to(device)\n", - "print(\n", - " f\"Fraction of class-1 samples in the training set: {torch.sum(y_train[:,0])/y_train.shape[0]}\"\n", - ")\n", - "print(\n", - " f\"Fraction of class-1 samples in the test set: {torch.sum(y_test[:,0])/y_test.shape[0]}\"\n", - ")" + "class Network(torch.nn.Module):\n", + " \"\"\" Network class that initializes the base model and readout layer.\n", + "\n", + " Base model parameters:\n", + " ----------\n", + " Reqired:\n", + " in_channels : int\n", + " Dimension of the input features.\n", + " hidden_channels : int\n", + " Dimension of the hidden features.\n", + "\n", + " Optitional:\n", + " **kwargs : dict\n", + " Additional arguments for the base model.\n", + " \n", + " Readout layer parameters:\n", + " ----------\n", + " out_channels : int\n", + " Dimension of the output features.\n", + " task_level : str\n", + " Level of the task. Either \"graph\" or \"node\". \n", + " \"\"\"\n", + " def __init__(\n", + " self, \n", + " in_channels, \n", + " hidden_channels,\n", + " out_channels, \n", + " \n", + " task_level=\"graph\",\n", + " **kwargs):\n", + " super().__init__()\n", + " \n", + " # Define the model\n", + " self.base_model = HNHN(\n", + " in_channels=in_channels,\n", + " hidden_channels=hidden_channels,\n", + " **kwargs\n", + " )\n", + "\n", + "\n", + " # Readout\n", + " self.linear = torch.nn.Linear(hidden_channels, out_channels)\n", + " self.out_pool = True if task_level == \"graph\" else False\n", + " \n", + " def forward(self, x_0, incidence_1):\n", + " # Base model\n", + " x_0, x_1 = self.base_model(x_0, incidence_1)\n", + "\n", + " # Pool over all nodes in the hypergraph \n", + " if self.out_pool is True:\n", + " x = torch.max(x_0, dim=0)[0]\n", + " else:\n", + " x = x_0\n", + "\n", + " return self.linear(x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "# Create the Neural Network\n", - "\n", - "Using the HNHNLayer class, we define a neural network for node classification." + "Initialize the model" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ - "model = HNHNNetwork(\n", - " channels_node=channels_node,\n", - " channels_edge=channels_edge,\n", + "# Base model hyperparameters\n", + "in_channels = x_0s.shape[1]\n", + "hidden_channels = 128\n", + "n_layers=1\n", + "mlp_num_layers=1\n", + "\n", + "# Readout hyperparameters\n", + "out_channels = torch.unique(y).shape[0]\n", + "task_level = \"graph\" if out_channels==1 else \"node\"\n", + "\n", + "\n", + "model = Network(\n", + " in_channels=in_channels,\n", + " hidden_channels=hidden_channels,\n", + " out_channels=out_channels, \n", + " n_layers=n_layers,\n", " incidence_1=incidence_1,\n", - " n_classes=n_classes,\n", - " n_layers=2,\n", - ").to(device)" + " task_level=task_level,\n", + " ).to(device)" ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ "# Train the Neural Network\n", "\n", - "We initialize the HNHNNetwork model with our pre-made neighborhood structures and specify an optimizer and a suitable loss." + "We specify the model, the loss, and an optimizer." ] }, { @@ -316,6196 +389,133 @@ "metadata": {}, "outputs": [], "source": [ - "optimizer = torch.optim.Adam(model.parameters(), lr=0.5 * 1e-2)\n", - "criterion = torch.nn.CrossEntropyLoss()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Next, we train the model for 2000 epochs." + "# Optimizer and loss\n", + "opt = torch.optim.Adam(model.parameters(), lr=0.01)\n", + "\n", + "# Categorial cross-entropy loss\n", + "loss_fn = torch.nn.CrossEntropyLoss()\n", + "\n", + "# Accuracy\n", + "acc_fn = lambda y, y_hat: (y == y_hat).float().mean()" ] }, { "cell_type": "code", "execution_count": 11, - "metadata": {}, + "metadata": { + "ExecuteTime": { + "end_time": "2023-06-01T16:14:59.046068930Z", + "start_time": "2023-06-01T16:14:59.037648626Z" + } + }, "outputs": [ { - "name": "stdout", + "name": "stderr", "output_type": "stream", "text": [ - "Epoch: 0-------- \n", - "Loss: 0.7254 \n", - "Train_acc: 0.5000\n", - "Test_acc: 0.5000\n", - "Epoch: 1-------- \n", - "Loss: 0.7232 \n", - "Train_acc: 0.5000\n", - "Epoch: 2-------- \n", - "Loss: 0.7211 \n", - "Train_acc: 0.5000\n", - "Epoch: 3-------- \n", - "Loss: 0.7190 \n", - "Train_acc: 0.5000\n", - "Epoch: 4-------- \n", - "Loss: 0.7170 \n", - "Train_acc: 0.5000\n", - "Epoch: 5-------- \n", - "Loss: 0.7152 \n", - "Train_acc: 0.5000\n", - "Epoch: 6-------- \n", - "Loss: 0.7134 \n", - "Train_acc: 0.5000\n", - "Epoch: 7-------- \n", - "Loss: 0.7117 \n", - "Train_acc: 0.5000\n", - "Epoch: 8-------- \n", - "Loss: 0.7101 \n", - "Train_acc: 0.5000\n", - "Epoch: 9-------- \n", - "Loss: 0.7086 \n", - "Train_acc: 0.5000\n", - "Epoch: 10-------- \n", - "Loss: 0.7072 \n", - "Train_acc: 0.5000\n", - "Epoch: 11-------- \n", - "Loss: 0.7058 \n", - "Train_acc: 0.5000\n", - "Epoch: 12-------- \n", - "Loss: 0.7046 \n", - "Train_acc: 0.5000\n", - "Epoch: 13-------- \n", - "Loss: 0.7034 \n", - "Train_acc: 0.5000\n", - "Epoch: 14-------- \n", - "Loss: 0.7024 \n", - "Train_acc: 0.5000\n", - "Epoch: 15-------- \n", - "Loss: 0.7014 \n", - "Train_acc: 0.5000\n", - "Epoch: 16-------- \n", - "Loss: 0.7005 \n", - "Train_acc: 0.5000\n", - "Epoch: 17-------- \n", - "Loss: 0.6997 \n", - "Train_acc: 0.5000\n", - "Epoch: 18-------- \n", - "Loss: 0.6990 \n", - "Train_acc: 0.5000\n", - "Epoch: 19-------- \n", - "Loss: 0.6983 \n", - "Train_acc: 0.5000\n", - "Epoch: 20-------- \n", - "Loss: 0.6977 \n", - "Train_acc: 0.5000\n", - "Test_acc: 0.5000\n", - "Epoch: 21-------- \n", - "Loss: 0.6972 \n", - "Train_acc: 0.5000\n", - "Epoch: 22-------- \n", - "Loss: 0.6967 \n", - "Train_acc: 0.5000\n", - "Epoch: 23-------- \n", - "Loss: 0.6963 \n", - "Train_acc: 0.5000\n", - "Epoch: 24-------- \n", - "Loss: 0.6960 \n", - "Train_acc: 0.5000\n", - "Epoch: 25-------- \n", - "Loss: 0.6957 \n", - "Train_acc: 0.5000\n", - "Epoch: 26-------- \n", - "Loss: 0.6954 \n", - "Train_acc: 0.5000\n", - "Epoch: 27-------- \n", - "Loss: 0.6952 \n", - "Train_acc: 0.5000\n", - "Epoch: 28-------- \n", - "Loss: 0.6951 \n", - "Train_acc: 0.5000\n", - "Epoch: 29-------- \n", - "Loss: 0.6949 \n", - "Train_acc: 0.5000\n", - "Epoch: 30-------- \n", - "Loss: 0.6948 \n", - "Train_acc: 0.5000\n", - "Epoch: 31-------- \n", - "Loss: 0.6948 \n", - "Train_acc: 0.5000\n", - "Epoch: 32-------- \n", - "Loss: 0.6947 \n", - "Train_acc: 0.5000\n", - "Epoch: 33-------- \n", - "Loss: 0.6947 \n", - "Train_acc: 0.5000\n", - "Epoch: 34-------- \n", - "Loss: 0.6947 \n", - "Train_acc: 0.5000\n", - "Epoch: 35-------- \n", - "Loss: 0.6946 \n", - "Train_acc: 0.5000\n", - "Epoch: 36-------- \n", - "Loss: 0.6946 \n", - "Train_acc: 0.5000\n", - "Epoch: 37-------- \n", - "Loss: 0.6946 \n", - "Train_acc: 0.1429\n", - "Epoch: 38-------- \n", - "Loss: 0.6946 \n", - "Train_acc: 0.3571\n", - "Epoch: 39-------- \n", - "Loss: 0.6946 \n", - "Train_acc: 0.5000\n", - "Epoch: 40-------- \n", - "Loss: 0.6946 \n", - "Train_acc: 0.5000\n", - "Test_acc: 0.5000\n", - "Epoch: 41-------- \n", - "Loss: 0.6946 \n", - "Train_acc: 0.5000\n", - "Epoch: 42-------- \n", - "Loss: 0.6946 \n", - "Train_acc: 0.5000\n", - "Epoch: 43-------- \n", - "Loss: 0.6946 \n", - "Train_acc: 0.5000\n", - "Epoch: 44-------- \n", - "Loss: 0.6946 \n", - "Train_acc: 0.5000\n", - "Epoch: 45-------- \n", - "Loss: 0.6946 \n", - "Train_acc: 0.5000\n", - "Epoch: 46-------- \n", - "Loss: 0.6945 \n", - "Train_acc: 0.5000\n", - "Epoch: 47-------- \n", - "Loss: 0.6945 \n", - "Train_acc: 0.5000\n", - "Epoch: 48-------- \n", - "Loss: 0.6945 \n", - "Train_acc: 0.5000\n", - "Epoch: 49-------- \n", - "Loss: 0.6945 \n", - "Train_acc: 0.5000\n", - "Epoch: 50-------- \n", - "Loss: 0.6944 \n", - "Train_acc: 0.5000\n", - "Epoch: 51-------- \n", - "Loss: 0.6944 \n", - "Train_acc: 0.5000\n", - "Epoch: 52-------- \n", - "Loss: 0.6944 \n", - "Train_acc: 0.5000\n", - "Epoch: 53-------- \n", - "Loss: 0.6943 \n", - "Train_acc: 0.5000\n", - "Epoch: 54-------- \n", - "Loss: 0.6943 \n", - "Train_acc: 0.5000\n", - "Epoch: 55-------- \n", - "Loss: 0.6943 \n", - "Train_acc: 0.5000\n", - "Epoch: 56-------- \n", - "Loss: 0.6943 \n", - "Train_acc: 0.5000\n", - "Epoch: 57-------- \n", - "Loss: 0.6942 \n", - "Train_acc: 0.5000\n", - "Epoch: 58-------- \n", - "Loss: 0.6942 \n", - "Train_acc: 0.5000\n", - "Epoch: 59-------- \n", - "Loss: 0.6942 \n", - "Train_acc: 0.3571\n", - "Epoch: 60-------- \n", - "Loss: 0.6941 \n", - "Train_acc: 0.3214\n", - "Test_acc: 0.0000\n", - "Epoch: 61-------- \n", - "Loss: 0.6941 \n", - "Train_acc: 0.0714\n", - "Epoch: 62-------- \n", - "Loss: 0.6941 \n", - "Train_acc: 0.1071\n", - "Epoch: 63-------- \n", - "Loss: 0.6941 \n", - "Train_acc: 0.5000\n", - "Epoch: 64-------- \n", - "Loss: 0.6940 \n", - "Train_acc: 0.5000\n", - "Epoch: 65-------- \n", - "Loss: 0.6940 \n", - "Train_acc: 0.5000\n", - "Epoch: 66-------- \n", - "Loss: 0.6940 \n", - "Train_acc: 0.5000\n", - "Epoch: 67-------- \n", - "Loss: 0.6940 \n", - "Train_acc: 0.5000\n", - "Epoch: 68-------- \n", - "Loss: 0.6940 \n", - "Train_acc: 0.5000\n", - "Epoch: 69-------- \n", - "Loss: 0.6939 \n", - "Train_acc: 0.5000\n", - "Epoch: 70-------- \n", - "Loss: 0.6939 \n", - "Train_acc: 0.5000\n", - "Epoch: 71-------- \n", - "Loss: 0.6939 \n", - "Train_acc: 0.5000\n", - "Epoch: 72-------- \n", - "Loss: 0.6939 \n", - "Train_acc: 0.5000\n", - "Epoch: 73-------- \n", - "Loss: 0.6939 \n", - "Train_acc: 0.5000\n", - "Epoch: 74-------- \n", - "Loss: 0.6939 \n", - "Train_acc: 0.5000\n", - "Epoch: 75-------- \n", - "Loss: 0.6939 \n", - "Train_acc: 0.5000\n", - "Epoch: 76-------- \n", - "Loss: 0.6938 \n", - "Train_acc: 0.5000\n", - "Epoch: 77-------- \n", - "Loss: 0.6938 \n", - "Train_acc: 0.5000\n", - "Epoch: 78-------- \n", - "Loss: 0.6938 \n", - "Train_acc: 0.5000\n", - "Epoch: 79-------- \n", - "Loss: 0.6938 \n", - "Train_acc: 0.5000\n", - "Epoch: 80-------- \n", - "Loss: 0.6938 \n", - "Train_acc: 0.5000\n", - "Test_acc: 0.5000\n", - "Epoch: 81-------- \n", - "Loss: 0.6938 \n", - "Train_acc: 0.5000\n", - "Epoch: 82-------- \n", - "Loss: 0.6938 \n", - "Train_acc: 0.5000\n", - "Epoch: 83-------- \n", - "Loss: 0.6937 \n", - "Train_acc: 0.5000\n", - "Epoch: 84-------- \n", - "Loss: 0.6937 \n", - "Train_acc: 0.5000\n", - "Epoch: 85-------- \n", - "Loss: 0.6937 \n", - "Train_acc: 0.5000\n", - "Epoch: 86-------- \n", - "Loss: 0.6937 \n", - "Train_acc: 0.5000\n", - "Epoch: 87-------- \n", - "Loss: 0.6937 \n", - "Train_acc: 0.5000\n", - "Epoch: 88-------- \n", - "Loss: 0.6937 \n", - "Train_acc: 0.5000\n", - "Epoch: 89-------- \n", - "Loss: 0.6937 \n", - "Train_acc: 0.5000\n", - "Epoch: 90-------- \n", - "Loss: 0.6937 \n", - "Train_acc: 0.5000\n", - "Epoch: 91-------- \n", - "Loss: 0.6936 \n", - "Train_acc: 0.5000\n", - "Epoch: 92-------- \n", - "Loss: 0.6936 \n", - "Train_acc: 0.5000\n", - "Epoch: 93-------- \n", - "Loss: 0.6936 \n", - "Train_acc: 0.5000\n", - "Epoch: 94-------- \n", - "Loss: 0.6936 \n", - "Train_acc: 0.5000\n", - "Epoch: 95-------- \n", - "Loss: 0.6936 \n", - "Train_acc: 0.5000\n", - "Epoch: 96-------- \n", - "Loss: 0.6936 \n", - "Train_acc: 0.5000\n", - "Epoch: 97-------- \n", - "Loss: 0.6936 \n", - "Train_acc: 0.5000\n", - "Epoch: 98-------- \n", - "Loss: 0.6936 \n", - "Train_acc: 0.5000\n", - "Epoch: 99-------- \n", - "Loss: 0.6935 \n", - "Train_acc: 0.5000\n", - "Epoch: 100-------- \n", - "Loss: 0.6935 \n", - "Train_acc: 0.5000\n", - "Test_acc: 0.5000\n", - "Epoch: 101-------- \n", - "Loss: 0.6935 \n", - "Train_acc: 0.5000\n", - "Epoch: 102-------- \n", - "Loss: 0.6935 \n", - "Train_acc: 0.5000\n", - "Epoch: 103-------- \n", - "Loss: 0.6935 \n", - "Train_acc: 0.5000\n", - "Epoch: 104-------- \n", - "Loss: 0.6935 \n", - "Train_acc: 0.5000\n", - "Epoch: 105-------- \n", - "Loss: 0.6935 \n", - "Train_acc: 0.5000\n", - "Epoch: 106-------- \n", - "Loss: 0.6935 \n", - "Train_acc: 0.5000\n", - "Epoch: 107-------- \n", - "Loss: 0.6935 \n", - "Train_acc: 0.5000\n", - "Epoch: 108-------- \n", - "Loss: 0.6935 \n", - "Train_acc: 0.5000\n", - "Epoch: 109-------- \n", - "Loss: 0.6934 \n", - "Train_acc: 0.5000\n", - "Epoch: 110-------- \n", - "Loss: 0.6934 \n", - "Train_acc: 0.5000\n", - "Epoch: 111-------- \n", - "Loss: 0.6934 \n", - "Train_acc: 0.5000\n", - "Epoch: 112-------- \n", - "Loss: 0.6934 \n", - "Train_acc: 0.5000\n", - "Epoch: 113-------- \n", - "Loss: 0.6934 \n", - "Train_acc: 0.5000\n", - "Epoch: 114-------- \n", - "Loss: 0.6934 \n", - "Train_acc: 0.5000\n", - "Epoch: 115-------- \n", - "Loss: 0.6934 \n", - "Train_acc: 0.5000\n", - "Epoch: 116-------- \n", - "Loss: 0.6934 \n", - "Train_acc: 0.5000\n", - "Epoch: 117-------- \n", - "Loss: 0.6934 \n", - "Train_acc: 0.5000\n", - "Epoch: 118-------- \n", - "Loss: 0.6934 \n", - "Train_acc: 0.5000\n", - "Epoch: 119-------- \n", - "Loss: 0.6933 \n", - "Train_acc: 0.5000\n", - "Epoch: 120-------- \n", - "Loss: 0.6933 \n", - "Train_acc: 0.5000\n", - "Test_acc: 0.5000\n", - "Epoch: 121-------- \n", - "Loss: 0.6933 \n", - "Train_acc: 0.5000\n", - "Epoch: 122-------- \n", - "Loss: 0.6933 \n", - "Train_acc: 0.5000\n", - "Epoch: 123-------- \n", - "Loss: 0.6933 \n", - "Train_acc: 0.5000\n", - "Epoch: 124-------- \n", - "Loss: 0.6933 \n", - "Train_acc: 0.5000\n", - "Epoch: 125-------- \n", - "Loss: 0.6933 \n", - "Train_acc: 0.5000\n", - "Epoch: 126-------- \n", - "Loss: 0.6933 \n", - "Train_acc: 0.5000\n", - "Epoch: 127-------- \n", - "Loss: 0.6933 \n", - "Train_acc: 0.5000\n", - "Epoch: 128-------- \n", - "Loss: 0.6933 \n", - "Train_acc: 0.5000\n", - "Epoch: 129-------- \n", - "Loss: 0.6933 \n", - "Train_acc: 0.5000\n", - "Epoch: 130-------- \n", - "Loss: 0.6932 \n", - "Train_acc: 0.5000\n", - "Epoch: 131-------- \n", - "Loss: 0.6932 \n", - "Train_acc: 0.5000\n", - "Epoch: 132-------- \n", - "Loss: 0.6932 \n", - "Train_acc: 0.5000\n", - "Epoch: 133-------- \n", - "Loss: 0.6932 \n", - "Train_acc: 0.5000\n", - "Epoch: 134-------- \n", - "Loss: 0.6932 \n", - "Train_acc: 0.5000\n", - "Epoch: 135-------- \n", - "Loss: 0.6932 \n", - "Train_acc: 0.5000\n", - "Epoch: 136-------- \n", - "Loss: 0.6932 \n", - "Train_acc: 0.5000\n", - "Epoch: 137-------- \n", - "Loss: 0.6932 \n", - "Train_acc: 0.5000\n", - "Epoch: 138-------- \n", - "Loss: 0.6932 \n", - "Train_acc: 0.5000\n", - "Epoch: 139-------- \n", - "Loss: 0.6932 \n", - "Train_acc: 0.5000\n", - "Epoch: 140-------- \n", - "Loss: 0.6932 \n", - "Train_acc: 0.5000\n", - "Test_acc: 0.5000\n", - "Epoch: 141-------- \n", - "Loss: 0.6931 \n", - "Train_acc: 0.5000\n", - "Epoch: 142-------- \n", - "Loss: 0.6931 \n", - "Train_acc: 0.5000\n", - "Epoch: 143-------- \n", - "Loss: 0.6931 \n", - "Train_acc: 0.5000\n", - "Epoch: 144-------- \n", - "Loss: 0.6931 \n", - "Train_acc: 0.5000\n", - "Epoch: 145-------- \n", - "Loss: 0.6931 \n", - "Train_acc: 0.5000\n", - "Epoch: 146-------- \n", - "Loss: 0.6931 \n", - "Train_acc: 0.5000\n", - "Epoch: 147-------- \n", - "Loss: 0.6931 \n", - "Train_acc: 0.5000\n", - "Epoch: 148-------- \n", - "Loss: 0.6931 \n", - "Train_acc: 0.5000\n", - "Epoch: 149-------- \n", - "Loss: 0.6931 \n", - "Train_acc: 0.5000\n", - "Epoch: 150-------- \n", - "Loss: 0.6931 \n", - "Train_acc: 0.5000\n", - "Epoch: 151-------- \n", - "Loss: 0.6931 \n", - "Train_acc: 0.5000\n", - "Epoch: 152-------- \n", - "Loss: 0.6930 \n", - "Train_acc: 0.5000\n", - "Epoch: 153-------- \n", - "Loss: 0.6930 \n", - "Train_acc: 0.5000\n", - "Epoch: 154-------- \n", - "Loss: 0.6930 \n", - "Train_acc: 0.5000\n", - "Epoch: 155-------- \n", - "Loss: 0.6930 \n", - "Train_acc: 0.5000\n", - "Epoch: 156-------- \n", - "Loss: 0.6930 \n", - "Train_acc: 0.5000\n", - "Epoch: 157-------- \n", - "Loss: 0.6930 \n", - "Train_acc: 0.5000\n", - "Epoch: 158-------- \n", - "Loss: 0.6930 \n", - "Train_acc: 0.5000\n", - "Epoch: 159-------- \n", - "Loss: 0.6930 \n", - "Train_acc: 0.5000\n", - "Epoch: 160-------- \n", - "Loss: 0.6930 \n", - "Train_acc: 0.5000\n", - "Test_acc: 0.5000\n", - "Epoch: 161-------- \n", - "Loss: 0.6930 \n", - "Train_acc: 0.5000\n", - "Epoch: 162-------- \n", - "Loss: 0.6930 \n", - "Train_acc: 0.5000\n", - "Epoch: 163-------- \n", - "Loss: 0.6929 \n", - "Train_acc: 0.5000\n", - "Epoch: 164-------- \n", - "Loss: 0.6929 \n", - "Train_acc: 0.5000\n", - "Epoch: 165-------- \n", - "Loss: 0.6929 \n", - "Train_acc: 0.5000\n", - "Epoch: 166-------- \n", - "Loss: 0.6929 \n", - "Train_acc: 0.5000\n", - "Epoch: 167-------- \n", - "Loss: 0.6929 \n", - "Train_acc: 0.5000\n", - "Epoch: 168-------- \n", - "Loss: 0.6929 \n", - "Train_acc: 0.5000\n", - "Epoch: 169-------- \n", - "Loss: 0.6929 \n", - "Train_acc: 0.5000\n", - "Epoch: 170-------- \n", - "Loss: 0.6929 \n", - "Train_acc: 0.5000\n", - "Epoch: 171-------- \n", - "Loss: 0.6929 \n", - "Train_acc: 0.5000\n", - "Epoch: 172-------- \n", - "Loss: 0.6929 \n", - "Train_acc: 0.5000\n", - "Epoch: 173-------- \n", - "Loss: 0.6928 \n", - "Train_acc: 0.5000\n", - "Epoch: 174-------- \n", - "Loss: 0.6928 \n", - "Train_acc: 0.5000\n", - "Epoch: 175-------- \n", - "Loss: 0.6928 \n", - "Train_acc: 0.5000\n", - "Epoch: 176-------- \n", - "Loss: 0.6928 \n", - "Train_acc: 0.5000\n", - "Epoch: 177-------- \n", - "Loss: 0.6928 \n", - "Train_acc: 0.5000\n", - "Epoch: 178-------- \n", - "Loss: 0.6928 \n", - "Train_acc: 0.5000\n", - "Epoch: 179-------- \n", - "Loss: 0.6928 \n", - "Train_acc: 0.5000\n", - "Epoch: 180-------- \n", - "Loss: 0.6928 \n", - "Train_acc: 0.5000\n", - "Test_acc: 0.5000\n", - "Epoch: 181-------- \n", - "Loss: 0.6928 \n", - "Train_acc: 0.5000\n", - "Epoch: 182-------- \n", - "Loss: 0.6927 \n", - "Train_acc: 0.5000\n", - "Epoch: 183-------- \n", - "Loss: 0.6927 \n", - "Train_acc: 0.5000\n", - "Epoch: 184-------- \n", - "Loss: 0.6927 \n", - "Train_acc: 0.5000\n", - "Epoch: 185-------- \n", - "Loss: 0.6927 \n", - "Train_acc: 0.5000\n", - "Epoch: 186-------- \n", - "Loss: 0.6927 \n", - "Train_acc: 0.5000\n", - "Epoch: 187-------- \n", - "Loss: 0.6927 \n", - "Train_acc: 0.5000\n", - "Epoch: 188-------- \n", - "Loss: 0.6927 \n", - "Train_acc: 0.5000\n", - "Epoch: 189-------- \n", - "Loss: 0.6927 \n", - "Train_acc: 0.5000\n", - "Epoch: 190-------- \n", - "Loss: 0.6926 \n", - "Train_acc: 0.5000\n", - "Epoch: 191-------- \n", - "Loss: 0.6926 \n", - "Train_acc: 0.5000\n", - "Epoch: 192-------- \n", - "Loss: 0.6926 \n", - "Train_acc: 0.5000\n", - "Epoch: 193-------- \n", - "Loss: 0.6926 \n", - "Train_acc: 0.5000\n", - "Epoch: 194-------- \n", - "Loss: 0.6926 \n", - "Train_acc: 0.5000\n", - "Epoch: 195-------- \n", - "Loss: 0.6926 \n", - "Train_acc: 0.5000\n", - "Epoch: 196-------- \n", - "Loss: 0.6926 \n", - "Train_acc: 0.5000\n", - "Epoch: 197-------- \n", - "Loss: 0.6925 \n", - "Train_acc: 0.5000\n", - "Epoch: 198-------- \n", - "Loss: 0.6925 \n", - "Train_acc: 0.5000\n", - "Epoch: 199-------- \n", - "Loss: 0.6925 \n", - "Train_acc: 0.5000\n", - "Epoch: 200-------- \n", - "Loss: 0.6925 \n", - "Train_acc: 0.5000\n", - "Test_acc: 0.5000\n", - "Epoch: 201-------- \n", - "Loss: 0.6925 \n", - "Train_acc: 0.5000\n", - "Epoch: 202-------- \n", - "Loss: 0.6925 \n", - "Train_acc: 0.5000\n", - "Epoch: 203-------- \n", - "Loss: 0.6924 \n", - "Train_acc: 0.5000\n", - "Epoch: 204-------- \n", - "Loss: 0.6924 \n", - "Train_acc: 0.5000\n", - "Epoch: 205-------- \n", - "Loss: 0.6924 \n", - "Train_acc: 0.5000\n", - "Epoch: 206-------- \n", - "Loss: 0.6924 \n", - "Train_acc: 0.5000\n", - "Epoch: 207-------- \n", - "Loss: 0.6924 \n", - "Train_acc: 0.5000\n", - "Epoch: 208-------- \n", - "Loss: 0.6923 \n", - "Train_acc: 0.5000\n", - "Epoch: 209-------- \n", - "Loss: 0.6923 \n", - "Train_acc: 0.5000\n", - "Epoch: 210-------- \n", - "Loss: 0.6923 \n", - "Train_acc: 0.5000\n", - "Epoch: 211-------- \n", - "Loss: 0.6923 \n", - "Train_acc: 0.5000\n", - "Epoch: 212-------- \n", - "Loss: 0.6923 \n", - "Train_acc: 0.5000\n", - "Epoch: 213-------- \n", - "Loss: 0.6922 \n", - "Train_acc: 0.5000\n", - "Epoch: 214-------- \n", - "Loss: 0.6922 \n", - "Train_acc: 0.5000\n", - "Epoch: 215-------- \n", - "Loss: 0.6922 \n", - "Train_acc: 0.5000\n", - "Epoch: 216-------- \n", - "Loss: 0.6922 \n", - "Train_acc: 0.5000\n", - "Epoch: 217-------- \n", - "Loss: 0.6921 \n", - "Train_acc: 0.5000\n", - "Epoch: 218-------- \n", - "Loss: 0.6921 \n", - "Train_acc: 0.5000\n", - "Epoch: 219-------- \n", - "Loss: 0.6921 \n", - "Train_acc: 0.5000\n", - "Epoch: 220-------- \n", - "Loss: 0.6921 \n", - "Train_acc: 0.5000\n", - "Test_acc: 0.5000\n", - "Epoch: 221-------- \n", - "Loss: 0.6920 \n", - "Train_acc: 0.5000\n", - "Epoch: 222-------- \n", - "Loss: 0.6920 \n", - "Train_acc: 0.5000\n", - "Epoch: 223-------- \n", - "Loss: 0.6920 \n", - "Train_acc: 0.5000\n", - "Epoch: 224-------- \n", - "Loss: 0.6920 \n", - "Train_acc: 0.5000\n", - "Epoch: 225-------- \n", - "Loss: 0.6919 \n", - "Train_acc: 0.5000\n", - "Epoch: 226-------- \n", - "Loss: 0.6919 \n", - "Train_acc: 0.5000\n", - "Epoch: 227-------- \n", - "Loss: 0.6919 \n", - "Train_acc: 0.5000\n", - "Epoch: 228-------- \n", - "Loss: 0.6919 \n", - "Train_acc: 0.5000\n", - "Epoch: 229-------- \n", - "Loss: 0.6918 \n", - "Train_acc: 0.5000\n", - "Epoch: 230-------- \n", - "Loss: 0.6918 \n", - "Train_acc: 0.5000\n", - "Epoch: 231-------- \n", - "Loss: 0.6918 \n", - "Train_acc: 0.5000\n", - "Epoch: 232-------- \n", - "Loss: 0.6917 \n", - "Train_acc: 0.5000\n", - "Epoch: 233-------- \n", - "Loss: 0.6917 \n", - "Train_acc: 0.5000\n", - "Epoch: 234-------- \n", - "Loss: 0.6917 \n", - "Train_acc: 0.5000\n", - "Epoch: 235-------- \n", - "Loss: 0.6916 \n", - "Train_acc: 0.5000\n", - "Epoch: 236-------- \n", - "Loss: 0.6916 \n", - "Train_acc: 0.5000\n", - "Epoch: 237-------- \n", - "Loss: 0.6915 \n", - "Train_acc: 0.5000\n", - "Epoch: 238-------- \n", - "Loss: 0.6915 \n", - "Train_acc: 0.5000\n", - "Epoch: 239-------- \n", - "Loss: 0.6915 \n", - "Train_acc: 0.5000\n", - "Epoch: 240-------- \n", - "Loss: 0.6914 \n", - "Train_acc: 0.5000\n", - "Test_acc: 0.5000\n", - "Epoch: 241-------- \n", - "Loss: 0.6914 \n", - "Train_acc: 0.5000\n", - "Epoch: 242-------- \n", - "Loss: 0.6913 \n", - "Train_acc: 0.5000\n", - "Epoch: 243-------- \n", - "Loss: 0.6913 \n", - "Train_acc: 0.5000\n", - "Epoch: 244-------- \n", - "Loss: 0.6913 \n", - "Train_acc: 0.5000\n", - "Epoch: 245-------- \n", - "Loss: 0.6912 \n", - "Train_acc: 0.5000\n", - "Epoch: 246-------- \n", - "Loss: 0.6912 \n", - "Train_acc: 0.5000\n", - "Epoch: 247-------- \n", - "Loss: 0.6911 \n", - "Train_acc: 0.5000\n", - "Epoch: 248-------- \n", - "Loss: 0.6911 \n", - "Train_acc: 0.5000\n", - "Epoch: 249-------- \n", - "Loss: 0.6910 \n", - "Train_acc: 0.5000\n", - "Epoch: 250-------- \n", - "Loss: 0.6910 \n", - "Train_acc: 0.5000\n", - "Epoch: 251-------- \n", - "Loss: 0.6909 \n", - "Train_acc: 0.5000\n", - "Epoch: 252-------- \n", - "Loss: 0.6909 \n", - "Train_acc: 0.5000\n", - "Epoch: 253-------- \n", - "Loss: 0.6908 \n", - "Train_acc: 0.5000\n", - "Epoch: 254-------- \n", - "Loss: 0.6907 \n", - "Train_acc: 0.5000\n", - "Epoch: 255-------- \n", - "Loss: 0.6907 \n", - "Train_acc: 0.5000\n", - "Epoch: 256-------- \n", - "Loss: 0.6906 \n", - "Train_acc: 0.5000\n", - "Epoch: 257-------- \n", - "Loss: 0.6906 \n", - "Train_acc: 0.5000\n", - "Epoch: 258-------- \n", - "Loss: 0.6905 \n", - "Train_acc: 0.5000\n", - "Epoch: 259-------- \n", - "Loss: 0.6904 \n", - "Train_acc: 0.5000\n", - "Epoch: 260-------- \n", - "Loss: 0.6904 \n", - "Train_acc: 0.5000\n", - "Test_acc: 0.5000\n", - "Epoch: 261-------- \n", - "Loss: 0.6903 \n", - "Train_acc: 0.5000\n", - "Epoch: 262-------- \n", - "Loss: 0.6902 \n", - "Train_acc: 0.5000\n", - "Epoch: 263-------- \n", - "Loss: 0.6902 \n", - "Train_acc: 0.5000\n", - "Epoch: 264-------- \n", - "Loss: 0.6901 \n", - "Train_acc: 0.5000\n", - "Epoch: 265-------- \n", - "Loss: 0.6900 \n", - "Train_acc: 0.5000\n", - "Epoch: 266-------- \n", - "Loss: 0.6899 \n", - "Train_acc: 0.5000\n", - "Epoch: 267-------- \n", - "Loss: 0.6899 \n", - "Train_acc: 0.5000\n", - "Epoch: 268-------- \n", - "Loss: 0.6898 \n", - "Train_acc: 0.5000\n", - "Epoch: 269-------- \n", - "Loss: 0.6897 \n", - "Train_acc: 0.5000\n", - "Epoch: 270-------- \n", - "Loss: 0.6896 \n", - "Train_acc: 0.5000\n", - "Epoch: 271-------- \n", - "Loss: 0.6895 \n", - "Train_acc: 0.5000\n", - "Epoch: 272-------- \n", - "Loss: 0.6894 \n", - "Train_acc: 0.5000\n", - "Epoch: 273-------- \n", - "Loss: 0.6893 \n", - "Train_acc: 0.5000\n", - "Epoch: 274-------- \n", - "Loss: 0.6893 \n", - "Train_acc: 0.5000\n", - "Epoch: 275-------- \n", - "Loss: 0.6892 \n", - "Train_acc: 0.5000\n", - "Epoch: 276-------- \n", - "Loss: 0.6891 \n", - "Train_acc: 0.5000\n", - "Epoch: 277-------- \n", - "Loss: 0.6890 \n", - "Train_acc: 0.5000\n", - "Epoch: 278-------- \n", - "Loss: 0.6889 \n", - "Train_acc: 0.5000\n", - "Epoch: 279-------- \n", - "Loss: 0.6888 \n", - "Train_acc: 0.5000\n", - "Epoch: 280-------- \n", - "Loss: 0.6886 \n", - "Train_acc: 0.5000\n", - "Test_acc: 0.5000\n", - "Epoch: 281-------- \n", - "Loss: 0.6885 \n", - "Train_acc: 0.5000\n", - "Epoch: 282-------- \n", - "Loss: 0.6884 \n", - "Train_acc: 0.5000\n", - "Epoch: 283-------- \n", - "Loss: 0.6883 \n", - "Train_acc: 0.5000\n", - "Epoch: 284-------- \n", - "Loss: 0.6882 \n", - "Train_acc: 0.5000\n", - "Epoch: 285-------- \n", - "Loss: 0.6881 \n", - "Train_acc: 0.5000\n", - "Epoch: 286-------- \n", - "Loss: 0.6879 \n", - "Train_acc: 0.5000\n", - "Epoch: 287-------- \n", - "Loss: 0.6878 \n", - "Train_acc: 0.5000\n", - "Epoch: 288-------- \n", - "Loss: 0.6877 \n", - "Train_acc: 0.5000\n", - "Epoch: 289-------- \n", - "Loss: 0.6876 \n", - "Train_acc: 0.5000\n", - "Epoch: 290-------- \n", - "Loss: 0.6874 \n", - "Train_acc: 0.5357\n", - "Epoch: 291-------- \n", - "Loss: 0.6873 \n", - "Train_acc: 0.5357\n", - "Epoch: 292-------- \n", - "Loss: 0.6871 \n", - "Train_acc: 0.5357\n", - "Epoch: 293-------- \n", - "Loss: 0.6870 \n", - "Train_acc: 0.5357\n", - "Epoch: 294-------- \n", - "Loss: 0.6868 \n", - "Train_acc: 0.5357\n", - "Epoch: 295-------- \n", - "Loss: 0.6867 \n", - "Train_acc: 0.5357\n", - "Epoch: 296-------- \n", - "Loss: 0.6865 \n", - "Train_acc: 0.5357\n", - "Epoch: 297-------- \n", - "Loss: 0.6864 \n", - "Train_acc: 0.5357\n", - "Epoch: 298-------- \n", - "Loss: 0.6862 \n", - "Train_acc: 0.5357\n", - "Epoch: 299-------- \n", - "Loss: 0.6861 \n", - "Train_acc: 0.5357\n", - "Epoch: 300-------- \n", - "Loss: 0.6859 \n", - "Train_acc: 0.5714\n", - "Test_acc: 0.6667\n", - "Epoch: 301-------- \n", - "Loss: 0.6857 \n", - "Train_acc: 0.5714\n", - "Epoch: 302-------- \n", - "Loss: 0.6855 \n", - "Train_acc: 0.5714\n", - "Epoch: 303-------- \n", - "Loss: 0.6854 \n", - "Train_acc: 0.5714\n", - "Epoch: 304-------- \n", - "Loss: 0.6852 \n", - "Train_acc: 0.5714\n", - "Epoch: 305-------- \n", - "Loss: 0.6850 \n", - "Train_acc: 0.5714\n", - "Epoch: 306-------- \n", - "Loss: 0.6848 \n", - "Train_acc: 0.5714\n", - "Epoch: 307-------- \n", - "Loss: 0.6846 \n", - "Train_acc: 0.5714\n", - "Epoch: 308-------- \n", - "Loss: 0.6844 \n", - "Train_acc: 0.6429\n", - "Epoch: 309-------- \n", - "Loss: 0.6842 \n", - "Train_acc: 0.6429\n", - "Epoch: 310-------- \n", - "Loss: 0.6840 \n", - "Train_acc: 0.6429\n", - "Epoch: 311-------- \n", - "Loss: 0.6838 \n", - "Train_acc: 0.6429\n", - "Epoch: 312-------- \n", - "Loss: 0.6835 \n", - "Train_acc: 0.6429\n", - "Epoch: 313-------- \n", - "Loss: 0.6833 \n", - "Train_acc: 0.6429\n", - "Epoch: 314-------- \n", - "Loss: 0.6831 \n", - "Train_acc: 0.6429\n", - "Epoch: 315-------- \n", - "Loss: 0.6829 \n", - "Train_acc: 0.6429\n", - "Epoch: 316-------- \n", - "Loss: 0.6826 \n", - "Train_acc: 0.6429\n", - "Epoch: 317-------- \n", - "Loss: 0.6824 \n", - "Train_acc: 0.6429\n", - "Epoch: 318-------- \n", - "Loss: 0.6821 \n", - "Train_acc: 0.6429\n", - "Epoch: 319-------- \n", - "Loss: 0.6819 \n", - "Train_acc: 0.6429\n", - "Epoch: 320-------- \n", - "Loss: 0.6816 \n", - "Train_acc: 0.6429\n", - "Test_acc: 0.6667\n", - "Epoch: 321-------- \n", - "Loss: 0.6814 \n", - "Train_acc: 0.6429\n", - "Epoch: 322-------- \n", - "Loss: 0.6811 \n", - "Train_acc: 0.6429\n", - "Epoch: 323-------- \n", - "Loss: 0.6808 \n", - "Train_acc: 0.6429\n", - "Epoch: 324-------- \n", - "Loss: 0.6806 \n", - "Train_acc: 0.6429\n", - "Epoch: 325-------- \n", - "Loss: 0.6803 \n", - "Train_acc: 0.6429\n", - "Epoch: 326-------- \n", - "Loss: 0.6800 \n", - "Train_acc: 0.6429\n", - "Epoch: 327-------- \n", - "Loss: 0.6797 \n", - "Train_acc: 0.6429\n", - "Epoch: 328-------- \n", - "Loss: 0.6794 \n", - "Train_acc: 0.6429\n", - "Epoch: 329-------- \n", - "Loss: 0.6791 \n", - "Train_acc: 0.6429\n", - "Epoch: 330-------- \n", - "Loss: 0.6788 \n", - "Train_acc: 0.6429\n", - "Epoch: 331-------- \n", - "Loss: 0.6785 \n", - "Train_acc: 0.6429\n", - "Epoch: 332-------- \n", - "Loss: 0.6782 \n", - "Train_acc: 0.6429\n", - "Epoch: 333-------- \n", - "Loss: 0.6778 \n", - "Train_acc: 0.6429\n", - "Epoch: 334-------- \n", - "Loss: 0.6775 \n", - "Train_acc: 0.6429\n", - "Epoch: 335-------- \n", - "Loss: 0.6772 \n", - "Train_acc: 0.6429\n", - "Epoch: 336-------- \n", - "Loss: 0.6768 \n", - "Train_acc: 0.6429\n", - "Epoch: 337-------- \n", - "Loss: 0.6765 \n", - "Train_acc: 0.6429\n", - "Epoch: 338-------- \n", - "Loss: 0.6761 \n", - "Train_acc: 0.6429\n", - "Epoch: 339-------- \n", - "Loss: 0.6758 \n", - "Train_acc: 0.6429\n", - "Epoch: 340-------- \n", - "Loss: 0.6754 \n", - "Train_acc: 0.6429\n", - "Test_acc: 0.6667\n", - "Epoch: 341-------- \n", - "Loss: 0.6750 \n", - "Train_acc: 0.6429\n", - "Epoch: 342-------- \n", - "Loss: 0.6746 \n", - "Train_acc: 0.6429\n", - "Epoch: 343-------- \n", - "Loss: 0.6742 \n", - "Train_acc: 0.6429\n", - "Epoch: 344-------- \n", - "Loss: 0.6738 \n", - "Train_acc: 0.6429\n", - "Epoch: 345-------- \n", - "Loss: 0.6734 \n", - "Train_acc: 0.6429\n", - "Epoch: 346-------- \n", - "Loss: 0.6730 \n", - "Train_acc: 0.6429\n", - "Epoch: 347-------- \n", - "Loss: 0.6726 \n", - "Train_acc: 0.6786\n", - "Epoch: 348-------- \n", - "Loss: 0.6722 \n", - "Train_acc: 0.6786\n", - "Epoch: 349-------- \n", - "Loss: 0.6717 \n", - "Train_acc: 0.6786\n", - "Epoch: 350-------- \n", - "Loss: 0.6713 \n", - "Train_acc: 0.6786\n", - "Epoch: 351-------- \n", - "Loss: 0.6708 \n", - "Train_acc: 0.6786\n", - "Epoch: 352-------- \n", - "Loss: 0.6704 \n", - "Train_acc: 0.6786\n", - "Epoch: 353-------- \n", - "Loss: 0.6699 \n", - "Train_acc: 0.6786\n", - "Epoch: 354-------- \n", - "Loss: 0.6694 \n", - "Train_acc: 0.6786\n", - "Epoch: 355-------- \n", - "Loss: 0.6690 \n", - "Train_acc: 0.6786\n", - "Epoch: 356-------- \n", - "Loss: 0.6685 \n", - "Train_acc: 0.6786\n", - "Epoch: 357-------- \n", - "Loss: 0.6680 \n", - "Train_acc: 0.6786\n", - "Epoch: 358-------- \n", - "Loss: 0.6675 \n", - "Train_acc: 0.6786\n", - "Epoch: 359-------- \n", - "Loss: 0.6670 \n", - "Train_acc: 0.6786\n", - "Epoch: 360-------- \n", - "Loss: 0.6664 \n", - "Train_acc: 0.7143\n", - "Test_acc: 0.6667\n", - "Epoch: 361-------- \n", - "Loss: 0.6659 \n", - "Train_acc: 0.7143\n", - "Epoch: 362-------- \n", - "Loss: 0.6654 \n", - "Train_acc: 0.7500\n", - "Epoch: 363-------- \n", - "Loss: 0.6648 \n", - "Train_acc: 0.7500\n", - "Epoch: 364-------- \n", - "Loss: 0.6642 \n", - "Train_acc: 0.7500\n", - "Epoch: 365-------- \n", - "Loss: 0.6637 \n", - "Train_acc: 0.7500\n", - "Epoch: 366-------- \n", - "Loss: 0.6631 \n", - "Train_acc: 0.7500\n", - "Epoch: 367-------- \n", - "Loss: 0.6625 \n", - "Train_acc: 0.8214\n", - "Epoch: 368-------- \n", - "Loss: 0.6619 \n", - "Train_acc: 0.8214\n", - "Epoch: 369-------- \n", - "Loss: 0.6613 \n", - "Train_acc: 0.8214\n", - "Epoch: 370-------- \n", - "Loss: 0.6607 \n", - "Train_acc: 0.8214\n", - "Epoch: 371-------- \n", - "Loss: 0.6600 \n", - "Train_acc: 0.8214\n", - "Epoch: 372-------- \n", - "Loss: 0.6594 \n", - "Train_acc: 0.8214\n", - "Epoch: 373-------- \n", - "Loss: 0.6588 \n", - "Train_acc: 0.8214\n", - "Epoch: 374-------- \n", - "Loss: 0.6581 \n", - "Train_acc: 0.8214\n", - "Epoch: 375-------- \n", - "Loss: 0.6574 \n", - "Train_acc: 0.8214\n", - "Epoch: 376-------- \n", - "Loss: 0.6568 \n", - "Train_acc: 0.8214\n", - "Epoch: 377-------- \n", - "Loss: 0.6561 \n", - "Train_acc: 0.8214\n", - "Epoch: 378-------- \n", - "Loss: 0.6554 \n", - "Train_acc: 0.8214\n", - "Epoch: 379-------- \n", - "Loss: 0.6547 \n", - "Train_acc: 0.8214\n", - "Epoch: 380-------- \n", - "Loss: 0.6539 \n", - "Train_acc: 0.8214\n", - "Test_acc: 0.6667\n", - "Epoch: 381-------- \n", - "Loss: 0.6532 \n", - "Train_acc: 0.8214\n", - "Epoch: 382-------- \n", - "Loss: 0.6525 \n", - "Train_acc: 0.8214\n", - "Epoch: 383-------- \n", - "Loss: 0.6517 \n", - "Train_acc: 0.8214\n", - "Epoch: 384-------- \n", - "Loss: 0.6509 \n", - "Train_acc: 0.8214\n", - "Epoch: 385-------- \n", - "Loss: 0.6502 \n", - "Train_acc: 0.8214\n", - "Epoch: 386-------- \n", - "Loss: 0.6494 \n", - "Train_acc: 0.8214\n", - "Epoch: 387-------- \n", - "Loss: 0.6486 \n", - "Train_acc: 0.8571\n", - "Epoch: 388-------- \n", - "Loss: 0.6478 \n", - "Train_acc: 0.8571\n", - "Epoch: 389-------- \n", - "Loss: 0.6469 \n", - "Train_acc: 0.8571\n", - "Epoch: 390-------- \n", - "Loss: 0.6461 \n", - "Train_acc: 0.8571\n", - "Epoch: 391-------- \n", - "Loss: 0.6453 \n", - "Train_acc: 0.8571\n", - "Epoch: 392-------- \n", - "Loss: 0.6444 \n", - "Train_acc: 0.8571\n", - "Epoch: 393-------- \n", - "Loss: 0.6435 \n", - "Train_acc: 0.8571\n", - "Epoch: 394-------- \n", - "Loss: 0.6427 \n", - "Train_acc: 0.8571\n", - "Epoch: 395-------- \n", - "Loss: 0.6418 \n", - "Train_acc: 0.8571\n", - "Epoch: 396-------- \n", - "Loss: 0.6409 \n", - "Train_acc: 0.8571\n", - "Epoch: 397-------- \n", - "Loss: 0.6399 \n", - "Train_acc: 0.8571\n", - "Epoch: 398-------- \n", - "Loss: 0.6390 \n", - "Train_acc: 0.8571\n", - "Epoch: 399-------- \n", - "Loss: 0.6381 \n", - "Train_acc: 0.8571\n", - "Epoch: 400-------- \n", - "Loss: 0.6371 \n", - "Train_acc: 0.8571\n", - "Test_acc: 0.8333\n", - "Epoch: 401-------- \n", - "Loss: 0.6361 \n", - "Train_acc: 0.8571\n", - "Epoch: 402-------- \n", - "Loss: 0.6351 \n", - "Train_acc: 0.8571\n", - "Epoch: 403-------- \n", - "Loss: 0.6342 \n", - "Train_acc: 0.8571\n", - "Epoch: 404-------- \n", - "Loss: 0.6331 \n", - "Train_acc: 0.8571\n", - "Epoch: 405-------- \n", - "Loss: 0.6321 \n", - "Train_acc: 0.8571\n", - "Epoch: 406-------- \n", - "Loss: 0.6311 \n", - "Train_acc: 0.8571\n", - "Epoch: 407-------- \n", - "Loss: 0.6300 \n", - "Train_acc: 0.8571\n", - "Epoch: 408-------- \n", - "Loss: 0.6290 \n", - "Train_acc: 0.8571\n", - "Epoch: 409-------- \n", - "Loss: 0.6279 \n", - "Train_acc: 0.8571\n", - "Epoch: 410-------- \n", - "Loss: 0.6268 \n", - "Train_acc: 0.8571\n", - "Epoch: 411-------- \n", - "Loss: 0.6257 \n", - "Train_acc: 0.8571\n", - "Epoch: 412-------- \n", - "Loss: 0.6246 \n", - "Train_acc: 0.8571\n", - "Epoch: 413-------- \n", - "Loss: 0.6235 \n", - "Train_acc: 0.8571\n", - "Epoch: 414-------- \n", - "Loss: 0.6223 \n", - "Train_acc: 0.8571\n", - "Epoch: 415-------- \n", - "Loss: 0.6212 \n", - "Train_acc: 0.8571\n", - "Epoch: 416-------- \n", - "Loss: 0.6200 \n", - "Train_acc: 0.8571\n", - "Epoch: 417-------- \n", - "Loss: 0.6188 \n", - "Train_acc: 0.8571\n", - "Epoch: 418-------- \n", - "Loss: 0.6176 \n", - "Train_acc: 0.8571\n", - "Epoch: 419-------- \n", - "Loss: 0.6164 \n", - "Train_acc: 0.8571\n", - "Epoch: 420-------- \n", - "Loss: 0.6152 \n", - "Train_acc: 0.8571\n", - "Test_acc: 1.0000\n", - "Epoch: 421-------- \n", - "Loss: 0.6139 \n", - "Train_acc: 0.8571\n", - "Epoch: 422-------- \n", - "Loss: 0.6127 \n", - "Train_acc: 0.8571\n", - "Epoch: 423-------- \n", - "Loss: 0.6114 \n", - "Train_acc: 0.8571\n", - "Epoch: 424-------- \n", - "Loss: 0.6101 \n", - "Train_acc: 0.8571\n", - "Epoch: 425-------- \n", - "Loss: 0.6088 \n", - "Train_acc: 0.8571\n", - "Epoch: 426-------- \n", - "Loss: 0.6075 \n", - "Train_acc: 0.8571\n", - "Epoch: 427-------- \n", - "Loss: 0.6061 \n", - "Train_acc: 0.8571\n", - "Epoch: 428-------- \n", - "Loss: 0.6048 \n", - "Train_acc: 0.8571\n", - "Epoch: 429-------- \n", - "Loss: 0.6034 \n", - "Train_acc: 0.8571\n", - "Epoch: 430-------- \n", - "Loss: 0.6020 \n", - "Train_acc: 0.8571\n", - "Epoch: 431-------- \n", - "Loss: 0.6006 \n", - "Train_acc: 0.8571\n", - "Epoch: 432-------- \n", - "Loss: 0.5992 \n", - "Train_acc: 0.8571\n", - "Epoch: 433-------- \n", - "Loss: 0.5978 \n", - "Train_acc: 0.8571\n", - "Epoch: 434-------- \n", - "Loss: 0.5963 \n", - "Train_acc: 0.8571\n", - "Epoch: 435-------- \n", - "Loss: 0.5949 \n", - "Train_acc: 0.8571\n", - "Epoch: 436-------- \n", - "Loss: 0.5934 \n", - "Train_acc: 0.8929\n", - "Epoch: 437-------- \n", - "Loss: 0.5919 \n", - "Train_acc: 0.8929\n", - "Epoch: 438-------- \n", - "Loss: 0.5904 \n", - "Train_acc: 0.8929\n", - "Epoch: 439-------- \n", - "Loss: 0.5888 \n", - "Train_acc: 0.8929\n", - "Epoch: 440-------- \n", - "Loss: 0.5873 \n", - "Train_acc: 0.8929\n", - "Test_acc: 1.0000\n", - "Epoch: 441-------- \n", - "Loss: 0.5857 \n", - "Train_acc: 0.8929\n", - "Epoch: 442-------- \n", - "Loss: 0.5841 \n", - "Train_acc: 0.8929\n", - "Epoch: 443-------- \n", - "Loss: 0.5825 \n", - "Train_acc: 0.9286\n", - "Epoch: 444-------- \n", - "Loss: 0.5809 \n", - "Train_acc: 0.9286\n", - "Epoch: 445-------- \n", - "Loss: 0.5793 \n", - "Train_acc: 0.9286\n", - "Epoch: 446-------- \n", - "Loss: 0.5776 \n", - "Train_acc: 0.9286\n", - "Epoch: 447-------- \n", - "Loss: 0.5759 \n", - "Train_acc: 0.9286\n", - "Epoch: 448-------- \n", - "Loss: 0.5742 \n", - "Train_acc: 0.9286\n", - "Epoch: 449-------- \n", - "Loss: 0.5725 \n", - "Train_acc: 0.9286\n", - "Epoch: 450-------- \n", - "Loss: 0.5708 \n", - "Train_acc: 0.9286\n", - "Epoch: 451-------- \n", - "Loss: 0.5691 \n", - "Train_acc: 0.9286\n", - "Epoch: 452-------- \n", - "Loss: 0.5673 \n", - "Train_acc: 0.9286\n", - "Epoch: 453-------- \n", - "Loss: 0.5655 \n", - "Train_acc: 0.9286\n", - "Epoch: 454-------- \n", - "Loss: 0.5637 \n", - "Train_acc: 0.9286\n", - "Epoch: 455-------- \n", - "Loss: 0.5619 \n", - "Train_acc: 0.9286\n", - "Epoch: 456-------- \n", - "Loss: 0.5600 \n", - "Train_acc: 0.9286\n", - "Epoch: 457-------- \n", - "Loss: 0.5582 \n", - "Train_acc: 0.9286\n", - "Epoch: 458-------- \n", - "Loss: 0.5563 \n", - "Train_acc: 0.9286\n", - "Epoch: 459-------- \n", - "Loss: 0.5544 \n", - "Train_acc: 0.9286\n", - "Epoch: 460-------- \n", - "Loss: 0.5525 \n", - "Train_acc: 0.9286\n", - "Test_acc: 1.0000\n", - "Epoch: 461-------- \n", - "Loss: 0.5506 \n", - "Train_acc: 0.9286\n", - "Epoch: 462-------- \n", - "Loss: 0.5486 \n", - "Train_acc: 0.9286\n", - "Epoch: 463-------- \n", - "Loss: 0.5466 \n", - "Train_acc: 0.9286\n", - "Epoch: 464-------- \n", - "Loss: 0.5447 \n", - "Train_acc: 0.9286\n", - "Epoch: 465-------- \n", - "Loss: 0.5427 \n", - "Train_acc: 0.9286\n", - "Epoch: 466-------- \n", - "Loss: 0.5406 \n", - "Train_acc: 0.9286\n", - "Epoch: 467-------- \n", - "Loss: 0.5386 \n", - "Train_acc: 0.9286\n", - "Epoch: 468-------- \n", - "Loss: 0.5365 \n", - "Train_acc: 0.9286\n", - "Epoch: 469-------- \n", - "Loss: 0.5345 \n", - "Train_acc: 0.9286\n", - "Epoch: 470-------- \n", - "Loss: 0.5324 \n", - "Train_acc: 0.9286\n", - "Epoch: 471-------- \n", - "Loss: 0.5303 \n", - "Train_acc: 0.9286\n", - "Epoch: 472-------- \n", - "Loss: 0.5281 \n", - "Train_acc: 0.9286\n", - "Epoch: 473-------- \n", - "Loss: 0.5260 \n", - "Train_acc: 0.9286\n", - "Epoch: 474-------- \n", - "Loss: 0.5239 \n", - "Train_acc: 0.9286\n", - "Epoch: 475-------- \n", - "Loss: 0.5217 \n", - "Train_acc: 0.9286\n", - "Epoch: 476-------- \n", - "Loss: 0.5195 \n", - "Train_acc: 0.9286\n", - "Epoch: 477-------- \n", - "Loss: 0.5173 \n", - "Train_acc: 0.9286\n", - "Epoch: 478-------- \n", - "Loss: 0.5151 \n", - "Train_acc: 0.9286\n", - "Epoch: 479-------- \n", - "Loss: 0.5129 \n", - "Train_acc: 0.9286\n", - "Epoch: 480-------- \n", - "Loss: 0.5107 \n", - "Train_acc: 0.9286\n", - "Test_acc: 1.0000\n", - "Epoch: 481-------- \n", - "Loss: 0.5084 \n", - "Train_acc: 0.9286\n", - "Epoch: 482-------- \n", - "Loss: 0.5062 \n", - "Train_acc: 0.9286\n", - "Epoch: 483-------- \n", - "Loss: 0.5039 \n", - "Train_acc: 0.9286\n", - "Epoch: 484-------- \n", - "Loss: 0.5016 \n", - "Train_acc: 0.9286\n", - "Epoch: 485-------- \n", - "Loss: 0.4993 \n", - "Train_acc: 0.9286\n", - "Epoch: 486-------- \n", - "Loss: 0.4970 \n", - "Train_acc: 0.9286\n", - "Epoch: 487-------- \n", - "Loss: 0.4947 \n", - "Train_acc: 0.9286\n", - "Epoch: 488-------- \n", - "Loss: 0.4924 \n", - "Train_acc: 0.9286\n", - "Epoch: 489-------- \n", - "Loss: 0.4901 \n", - "Train_acc: 0.9286\n", - "Epoch: 490-------- \n", - "Loss: 0.4878 \n", - "Train_acc: 0.9286\n", - "Epoch: 491-------- \n", - "Loss: 0.4855 \n", - "Train_acc: 0.9286\n", - "Epoch: 492-------- \n", - "Loss: 0.4831 \n", - "Train_acc: 0.9286\n", - "Epoch: 493-------- \n", - "Loss: 0.4808 \n", - "Train_acc: 0.9286\n", - "Epoch: 494-------- \n", - "Loss: 0.4784 \n", - "Train_acc: 0.9286\n", - "Epoch: 495-------- \n", - "Loss: 0.4761 \n", - "Train_acc: 0.9286\n", - "Epoch: 496-------- \n", - "Loss: 0.4737 \n", - "Train_acc: 0.9286\n", - "Epoch: 497-------- \n", - "Loss: 0.4714 \n", - "Train_acc: 0.9286\n", - "Epoch: 498-------- \n", - "Loss: 0.4690 \n", - "Train_acc: 0.9286\n", - "Epoch: 499-------- \n", - "Loss: 0.4667 \n", - "Train_acc: 0.9286\n", - "Epoch: 500-------- \n", - "Loss: 0.4643 \n", - "Train_acc: 0.9286\n", - "Test_acc: 1.0000\n", - "Epoch: 501-------- \n", - "Loss: 0.4619 \n", - "Train_acc: 0.9286\n", - "Epoch: 502-------- \n", - "Loss: 0.4596 \n", - "Train_acc: 0.9286\n", - "Epoch: 503-------- \n", - "Loss: 0.4572 \n", - "Train_acc: 0.9286\n", - "Epoch: 504-------- \n", - "Loss: 0.4549 \n", - "Train_acc: 0.9286\n", - "Epoch: 505-------- \n", - "Loss: 0.4525 \n", - "Train_acc: 0.9286\n", - "Epoch: 506-------- \n", - "Loss: 0.4501 \n", - "Train_acc: 0.9286\n", - "Epoch: 507-------- \n", - "Loss: 0.4478 \n", - "Train_acc: 0.9286\n", - "Epoch: 508-------- \n", - "Loss: 0.4454 \n", - "Train_acc: 0.9286\n", - "Epoch: 509-------- \n", - "Loss: 0.4431 \n", - "Train_acc: 0.9286\n", - "Epoch: 510-------- \n", - "Loss: 0.4407 \n", - "Train_acc: 0.9286\n", - "Epoch: 511-------- \n", - "Loss: 0.4384 \n", - "Train_acc: 0.9286\n", - "Epoch: 512-------- \n", - "Loss: 0.4360 \n", - "Train_acc: 0.9286\n", - "Epoch: 513-------- \n", - "Loss: 0.4337 \n", - "Train_acc: 0.9286\n", - "Epoch: 514-------- \n", - "Loss: 0.4313 \n", - "Train_acc: 0.9286\n", - "Epoch: 515-------- \n", - "Loss: 0.4290 \n", - "Train_acc: 0.9286\n", - "Epoch: 516-------- \n", - "Loss: 0.4267 \n", - "Train_acc: 0.9286\n", - "Epoch: 517-------- \n", - "Loss: 0.4243 \n", - "Train_acc: 0.9286\n", - "Epoch: 518-------- \n", - "Loss: 0.4220 \n", - "Train_acc: 0.9286\n", - "Epoch: 519-------- \n", - "Loss: 0.4197 \n", - "Train_acc: 0.9286\n", - "Epoch: 520-------- \n", - "Loss: 0.4174 \n", - "Train_acc: 0.9286\n", - "Test_acc: 1.0000\n", - "Epoch: 521-------- \n", - "Loss: 0.4151 \n", - "Train_acc: 0.9286\n", - "Epoch: 522-------- \n", - "Loss: 0.4128 \n", - "Train_acc: 0.9286\n", - "Epoch: 523-------- \n", - "Loss: 0.4105 \n", - "Train_acc: 0.9286\n", - "Epoch: 524-------- \n", - "Loss: 0.4082 \n", - "Train_acc: 0.9286\n", - "Epoch: 525-------- \n", - "Loss: 0.4059 \n", - "Train_acc: 0.9286\n", - "Epoch: 526-------- \n", - "Loss: 0.4036 \n", - "Train_acc: 0.9286\n", - "Epoch: 527-------- \n", - "Loss: 0.4014 \n", - "Train_acc: 0.9286\n", - "Epoch: 528-------- \n", - "Loss: 0.3991 \n", - "Train_acc: 0.9286\n", - "Epoch: 529-------- \n", - "Loss: 0.3969 \n", - "Train_acc: 0.9286\n", - "Epoch: 530-------- \n", - "Loss: 0.3946 \n", - "Train_acc: 0.9286\n", - "Epoch: 531-------- \n", - "Loss: 0.3924 \n", - "Train_acc: 0.9286\n", - "Epoch: 532-------- \n", - "Loss: 0.3902 \n", - "Train_acc: 0.9286\n", - "Epoch: 533-------- \n", - "Loss: 0.3880 \n", - "Train_acc: 0.9286\n", - "Epoch: 534-------- \n", - "Loss: 0.3858 \n", - "Train_acc: 0.9286\n", - "Epoch: 535-------- \n", - "Loss: 0.3836 \n", - "Train_acc: 0.9286\n", - "Epoch: 536-------- \n", - "Loss: 0.3814 \n", - "Train_acc: 0.9286\n", - "Epoch: 537-------- \n", - "Loss: 0.3792 \n", - "Train_acc: 0.9286\n", - "Epoch: 538-------- \n", - "Loss: 0.3770 \n", - "Train_acc: 0.9286\n", - "Epoch: 539-------- \n", - "Loss: 0.3749 \n", - "Train_acc: 0.9286\n", - "Epoch: 540-------- \n", - "Loss: 0.3727 \n", - "Train_acc: 0.9286\n", - "Test_acc: 1.0000\n", - "Epoch: 541-------- \n", - "Loss: 0.3706 \n", - "Train_acc: 0.9286\n", - "Epoch: 542-------- \n", - "Loss: 0.3685 \n", - "Train_acc: 0.9286\n", - "Epoch: 543-------- \n", - "Loss: 0.3664 \n", - "Train_acc: 0.9286\n", - "Epoch: 544-------- \n", - "Loss: 0.3643 \n", - "Train_acc: 0.9286\n", - "Epoch: 545-------- \n", - "Loss: 0.3622 \n", - "Train_acc: 0.9286\n", - "Epoch: 546-------- \n", - "Loss: 0.3601 \n", - "Train_acc: 0.9286\n", - "Epoch: 547-------- \n", - "Loss: 0.3580 \n", - "Train_acc: 0.9286\n", - "Epoch: 548-------- \n", - "Loss: 0.3560 \n", - "Train_acc: 0.9286\n", - "Epoch: 549-------- \n", - "Loss: 0.3539 \n", - "Train_acc: 0.9286\n", - "Epoch: 550-------- \n", - "Loss: 0.3519 \n", - "Train_acc: 0.9286\n", - "Epoch: 551-------- \n", - "Loss: 0.3499 \n", - "Train_acc: 0.9286\n", - "Epoch: 552-------- \n", - "Loss: 0.3479 \n", - "Train_acc: 0.9286\n", - "Epoch: 553-------- \n", - "Loss: 0.3459 \n", - "Train_acc: 0.9286\n", - "Epoch: 554-------- \n", - "Loss: 0.3439 \n", - "Train_acc: 0.9286\n", - "Epoch: 555-------- \n", - "Loss: 0.3419 \n", - "Train_acc: 0.9286\n", - "Epoch: 556-------- \n", - "Loss: 0.3400 \n", - "Train_acc: 0.9286\n", - "Epoch: 557-------- \n", - "Loss: 0.3380 \n", - "Train_acc: 0.9286\n", - "Epoch: 558-------- \n", - "Loss: 0.3361 \n", - "Train_acc: 0.9286\n", - "Epoch: 559-------- \n", - "Loss: 0.3342 \n", - "Train_acc: 0.9286\n", - "Epoch: 560-------- \n", - "Loss: 0.3323 \n", - "Train_acc: 0.9286\n", - "Test_acc: 1.0000\n", - "Epoch: 561-------- \n", - "Loss: 0.3304 \n", - "Train_acc: 0.9286\n", - "Epoch: 562-------- \n", - "Loss: 0.3285 \n", - "Train_acc: 0.9286\n", - "Epoch: 563-------- \n", - "Loss: 0.3266 \n", - "Train_acc: 0.9286\n", - "Epoch: 564-------- \n", - "Loss: 0.3248 \n", - "Train_acc: 0.9286\n", - "Epoch: 565-------- \n", - "Loss: 0.3229 \n", - "Train_acc: 0.9643\n", - "Epoch: 566-------- \n", - "Loss: 0.3211 \n", - "Train_acc: 0.9643\n", - "Epoch: 567-------- \n", - "Loss: 0.3193 \n", - "Train_acc: 0.9643\n", - "Epoch: 568-------- \n", - "Loss: 0.3175 \n", - "Train_acc: 0.9643\n", - "Epoch: 569-------- \n", - "Loss: 0.3157 \n", - "Train_acc: 0.9643\n", - "Epoch: 570-------- \n", - "Loss: 0.3139 \n", - "Train_acc: 0.9643\n", - "Epoch: 571-------- \n", - "Loss: 0.3121 \n", - "Train_acc: 0.9643\n", - "Epoch: 572-------- \n", - "Loss: 0.3103 \n", - "Train_acc: 0.9643\n", - "Epoch: 573-------- \n", - "Loss: 0.3086 \n", - "Train_acc: 0.9643\n", - "Epoch: 574-------- \n", - "Loss: 0.3069 \n", - "Train_acc: 0.9643\n", - "Epoch: 575-------- \n", - "Loss: 0.3052 \n", - "Train_acc: 0.9643\n", - "Epoch: 576-------- \n", - "Loss: 0.3034 \n", - "Train_acc: 0.9643\n", - "Epoch: 577-------- \n", - "Loss: 0.3018 \n", - "Train_acc: 0.9643\n", - "Epoch: 578-------- \n", - "Loss: 0.3001 \n", - "Train_acc: 0.9643\n", - "Epoch: 579-------- \n", - "Loss: 0.2984 \n", - "Train_acc: 0.9643\n", - "Epoch: 580-------- \n", - "Loss: 0.2967 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 581-------- \n", - "Loss: 0.2951 \n", - "Train_acc: 0.9643\n", - "Epoch: 582-------- \n", - "Loss: 0.2935 \n", - "Train_acc: 0.9643\n", - "Epoch: 583-------- \n", - "Loss: 0.2919 \n", - "Train_acc: 0.9643\n", - "Epoch: 584-------- \n", - "Loss: 0.2902 \n", - "Train_acc: 0.9643\n", - "Epoch: 585-------- \n", - "Loss: 0.2887 \n", - "Train_acc: 0.9643\n", - "Epoch: 586-------- \n", - "Loss: 0.2871 \n", - "Train_acc: 0.9643\n", - "Epoch: 587-------- \n", - "Loss: 0.2855 \n", - "Train_acc: 0.9643\n", - "Epoch: 588-------- \n", - "Loss: 0.2839 \n", - "Train_acc: 0.9643\n", - "Epoch: 589-------- \n", - "Loss: 0.2824 \n", - "Train_acc: 0.9643\n", - "Epoch: 590-------- \n", - "Loss: 0.2809 \n", - "Train_acc: 0.9643\n", - "Epoch: 591-------- \n", - "Loss: 0.2794 \n", - "Train_acc: 0.9643\n", - "Epoch: 592-------- \n", - "Loss: 0.2778 \n", - "Train_acc: 0.9643\n", - "Epoch: 593-------- \n", - "Loss: 0.2763 \n", - "Train_acc: 0.9643\n", - "Epoch: 594-------- \n", - "Loss: 0.2749 \n", - "Train_acc: 0.9643\n", - "Epoch: 595-------- \n", - "Loss: 0.2734 \n", - "Train_acc: 0.9643\n", - "Epoch: 596-------- \n", - "Loss: 0.2719 \n", - "Train_acc: 0.9643\n", - "Epoch: 597-------- \n", - "Loss: 0.2705 \n", - "Train_acc: 0.9643\n", - "Epoch: 598-------- \n", - "Loss: 0.2690 \n", - "Train_acc: 0.9643\n", - "Epoch: 599-------- \n", - "Loss: 0.2676 \n", - "Train_acc: 0.9643\n", - "Epoch: 600-------- \n", - "Loss: 0.2662 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 601-------- \n", - "Loss: 0.2648 \n", - "Train_acc: 0.9643\n", - "Epoch: 602-------- \n", - "Loss: 0.2634 \n", - "Train_acc: 0.9643\n", - "Epoch: 603-------- \n", - "Loss: 0.2620 \n", - "Train_acc: 0.9643\n", - "Epoch: 604-------- \n", - "Loss: 0.2607 \n", - "Train_acc: 0.9643\n", - "Epoch: 605-------- \n", - "Loss: 0.2593 \n", - "Train_acc: 0.9643\n", - "Epoch: 606-------- \n", - "Loss: 0.2579 \n", - "Train_acc: 0.9643\n", - "Epoch: 607-------- \n", - "Loss: 0.2566 \n", - "Train_acc: 0.9643\n", - "Epoch: 608-------- \n", - "Loss: 0.2553 \n", - "Train_acc: 0.9643\n", - "Epoch: 609-------- \n", - "Loss: 0.2540 \n", - "Train_acc: 0.9643\n", - "Epoch: 610-------- \n", - "Loss: 0.2527 \n", - "Train_acc: 0.9643\n", - "Epoch: 611-------- \n", - "Loss: 0.2514 \n", - "Train_acc: 0.9643\n", - "Epoch: 612-------- \n", - "Loss: 0.2501 \n", - "Train_acc: 0.9643\n", - "Epoch: 613-------- \n", - "Loss: 0.2488 \n", - "Train_acc: 0.9643\n", - "Epoch: 614-------- \n", - "Loss: 0.2476 \n", - "Train_acc: 0.9643\n", - "Epoch: 615-------- \n", - "Loss: 0.2463 \n", - "Train_acc: 0.9643\n", - "Epoch: 616-------- \n", - "Loss: 0.2451 \n", - "Train_acc: 0.9643\n", - "Epoch: 617-------- \n", - "Loss: 0.2438 \n", - "Train_acc: 0.9643\n", - "Epoch: 618-------- \n", - "Loss: 0.2426 \n", - "Train_acc: 0.9643\n", - "Epoch: 619-------- \n", - "Loss: 0.2414 \n", - "Train_acc: 0.9643\n", - "Epoch: 620-------- \n", - "Loss: 0.2402 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 621-------- \n", - "Loss: 0.2390 \n", - "Train_acc: 0.9643\n", - "Epoch: 622-------- \n", - "Loss: 0.2378 \n", - "Train_acc: 0.9643\n", - "Epoch: 623-------- \n", - "Loss: 0.2367 \n", - "Train_acc: 0.9643\n", - "Epoch: 624-------- \n", - "Loss: 0.2355 \n", - "Train_acc: 0.9643\n", - "Epoch: 625-------- \n", - "Loss: 0.2344 \n", - "Train_acc: 0.9643\n", - "Epoch: 626-------- \n", - "Loss: 0.2332 \n", - "Train_acc: 0.9643\n", - "Epoch: 627-------- \n", - "Loss: 0.2321 \n", - "Train_acc: 0.9643\n", - "Epoch: 628-------- \n", - "Loss: 0.2310 \n", - "Train_acc: 0.9643\n", - "Epoch: 629-------- \n", - "Loss: 0.2299 \n", - "Train_acc: 0.9643\n", - "Epoch: 630-------- \n", - "Loss: 0.2287 \n", - "Train_acc: 0.9643\n", - "Epoch: 631-------- \n", - "Loss: 0.2277 \n", - "Train_acc: 0.9643\n", - "Epoch: 632-------- \n", - "Loss: 0.2266 \n", - "Train_acc: 0.9643\n", - "Epoch: 633-------- \n", - "Loss: 0.2255 \n", - "Train_acc: 0.9643\n", - "Epoch: 634-------- \n", - "Loss: 0.2244 \n", - "Train_acc: 0.9643\n", - "Epoch: 635-------- \n", - "Loss: 0.2234 \n", - "Train_acc: 0.9643\n", - "Epoch: 636-------- \n", - "Loss: 0.2223 \n", - "Train_acc: 0.9643\n", - "Epoch: 637-------- \n", - "Loss: 0.2213 \n", - "Train_acc: 0.9643\n", - "Epoch: 638-------- \n", - "Loss: 0.2202 \n", - "Train_acc: 0.9643\n", - "Epoch: 639-------- \n", - "Loss: 0.2192 \n", - "Train_acc: 0.9643\n", - "Epoch: 640-------- \n", - "Loss: 0.2182 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 641-------- \n", - "Loss: 0.2172 \n", - "Train_acc: 0.9643\n", - "Epoch: 642-------- \n", - "Loss: 0.2162 \n", - "Train_acc: 0.9643\n", - "Epoch: 643-------- \n", - "Loss: 0.2152 \n", - "Train_acc: 0.9643\n", - "Epoch: 644-------- \n", - "Loss: 0.2142 \n", - "Train_acc: 0.9643\n", - "Epoch: 645-------- \n", - "Loss: 0.2132 \n", - "Train_acc: 0.9643\n", - "Epoch: 646-------- \n", - "Loss: 0.2123 \n", - "Train_acc: 0.9643\n", - "Epoch: 647-------- \n", - "Loss: 0.2113 \n", - "Train_acc: 0.9643\n", - "Epoch: 648-------- \n", - "Loss: 0.2104 \n", - "Train_acc: 0.9643\n", - "Epoch: 649-------- \n", - "Loss: 0.2094 \n", - "Train_acc: 0.9643\n", - "Epoch: 650-------- \n", - "Loss: 0.2085 \n", - "Train_acc: 0.9643\n", - "Epoch: 651-------- \n", - "Loss: 0.2076 \n", - "Train_acc: 0.9643\n", - "Epoch: 652-------- \n", - "Loss: 0.2066 \n", - "Train_acc: 0.9643\n", - "Epoch: 653-------- \n", - "Loss: 0.2057 \n", - "Train_acc: 0.9643\n", - "Epoch: 654-------- \n", - "Loss: 0.2048 \n", - "Train_acc: 0.9643\n", - "Epoch: 655-------- \n", - "Loss: 0.2039 \n", - "Train_acc: 0.9643\n", - "Epoch: 656-------- \n", - "Loss: 0.2030 \n", - "Train_acc: 0.9643\n", - "Epoch: 657-------- \n", - "Loss: 0.2021 \n", - "Train_acc: 0.9643\n", - "Epoch: 658-------- \n", - "Loss: 0.2013 \n", - "Train_acc: 0.9643\n", - "Epoch: 659-------- \n", - "Loss: 0.2004 \n", - "Train_acc: 0.9643\n", - "Epoch: 660-------- \n", - "Loss: 0.1995 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 661-------- \n", - "Loss: 0.1987 \n", - "Train_acc: 0.9643\n", - "Epoch: 662-------- \n", - "Loss: 0.1978 \n", - "Train_acc: 0.9643\n", - "Epoch: 663-------- \n", - "Loss: 0.1970 \n", - "Train_acc: 0.9643\n", - "Epoch: 664-------- \n", - "Loss: 0.1962 \n", - "Train_acc: 0.9643\n", - "Epoch: 665-------- \n", - "Loss: 0.1953 \n", - "Train_acc: 0.9643\n", - "Epoch: 666-------- \n", - "Loss: 0.1945 \n", - "Train_acc: 0.9643\n", - "Epoch: 667-------- \n", - "Loss: 0.1937 \n", - "Train_acc: 0.9643\n", - "Epoch: 668-------- \n", - "Loss: 0.1929 \n", - "Train_acc: 0.9643\n", - "Epoch: 669-------- \n", - "Loss: 0.1921 \n", - "Train_acc: 0.9643\n", - "Epoch: 670-------- \n", - "Loss: 0.1913 \n", - "Train_acc: 0.9643\n", - "Epoch: 671-------- \n", - "Loss: 0.1905 \n", - "Train_acc: 0.9643\n", - "Epoch: 672-------- \n", - "Loss: 0.1897 \n", - "Train_acc: 0.9643\n", - "Epoch: 673-------- \n", - "Loss: 0.1889 \n", - "Train_acc: 0.9643\n", - "Epoch: 674-------- \n", - "Loss: 0.1882 \n", - "Train_acc: 0.9643\n", - "Epoch: 675-------- \n", - "Loss: 0.1874 \n", - "Train_acc: 0.9643\n", - "Epoch: 676-------- \n", - "Loss: 0.1866 \n", - "Train_acc: 0.9643\n", - "Epoch: 677-------- \n", - "Loss: 0.1859 \n", - "Train_acc: 0.9643\n", - "Epoch: 678-------- \n", - "Loss: 0.1851 \n", - "Train_acc: 0.9643\n", - "Epoch: 679-------- \n", - "Loss: 0.1844 \n", - "Train_acc: 0.9643\n", - "Epoch: 680-------- \n", - "Loss: 0.1837 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 681-------- \n", - "Loss: 0.1829 \n", - "Train_acc: 0.9643\n", - "Epoch: 682-------- \n", - "Loss: 0.1822 \n", - "Train_acc: 0.9643\n", - "Epoch: 683-------- \n", - "Loss: 0.1815 \n", - "Train_acc: 0.9643\n", - "Epoch: 684-------- \n", - "Loss: 0.1808 \n", - "Train_acc: 0.9643\n", - "Epoch: 685-------- \n", - "Loss: 0.1801 \n", - "Train_acc: 0.9643\n", - "Epoch: 686-------- \n", - "Loss: 0.1794 \n", - "Train_acc: 0.9643\n", - "Epoch: 687-------- \n", - "Loss: 0.1787 \n", - "Train_acc: 0.9643\n", - "Epoch: 688-------- \n", - "Loss: 0.1780 \n", - "Train_acc: 0.9643\n", - "Epoch: 689-------- \n", - "Loss: 0.1773 \n", - "Train_acc: 0.9643\n", - "Epoch: 690-------- \n", - "Loss: 0.1766 \n", - "Train_acc: 0.9643\n", - "Epoch: 691-------- \n", - "Loss: 0.1759 \n", - "Train_acc: 0.9643\n", - "Epoch: 692-------- \n", - "Loss: 0.1753 \n", - "Train_acc: 0.9643\n", - "Epoch: 693-------- \n", - "Loss: 0.1746 \n", - "Train_acc: 0.9643\n", - "Epoch: 694-------- \n", - "Loss: 0.1740 \n", - "Train_acc: 0.9643\n", - "Epoch: 695-------- \n", - "Loss: 0.1733 \n", - "Train_acc: 0.9643\n", - "Epoch: 696-------- \n", - "Loss: 0.1726 \n", - "Train_acc: 0.9643\n", - "Epoch: 697-------- \n", - "Loss: 0.1720 \n", - "Train_acc: 0.9643\n", - "Epoch: 698-------- \n", - "Loss: 0.1714 \n", - "Train_acc: 0.9643\n", - "Epoch: 699-------- \n", - "Loss: 0.1707 \n", - "Train_acc: 0.9643\n", - "Epoch: 700-------- \n", - "Loss: 0.1701 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 701-------- \n", - "Loss: 0.1695 \n", - "Train_acc: 0.9643\n", - "Epoch: 702-------- \n", - "Loss: 0.1688 \n", - "Train_acc: 0.9643\n", - "Epoch: 703-------- \n", - "Loss: 0.1682 \n", - "Train_acc: 0.9643\n", - "Epoch: 704-------- \n", - "Loss: 0.1676 \n", - "Train_acc: 0.9643\n", - "Epoch: 705-------- \n", - "Loss: 0.1670 \n", - "Train_acc: 0.9643\n", - "Epoch: 706-------- \n", - "Loss: 0.1664 \n", - "Train_acc: 0.9643\n", - "Epoch: 707-------- \n", - "Loss: 0.1658 \n", - "Train_acc: 0.9643\n", - "Epoch: 708-------- \n", - "Loss: 0.1652 \n", - "Train_acc: 0.9643\n", - "Epoch: 709-------- \n", - "Loss: 0.1646 \n", - "Train_acc: 0.9643\n", - "Epoch: 710-------- \n", - "Loss: 0.1640 \n", - "Train_acc: 0.9643\n", - "Epoch: 711-------- \n", - "Loss: 0.1635 \n", - "Train_acc: 0.9643\n", - "Epoch: 712-------- \n", - "Loss: 0.1629 \n", - "Train_acc: 0.9643\n", - "Epoch: 713-------- \n", - "Loss: 0.1623 \n", - "Train_acc: 0.9643\n", - "Epoch: 714-------- \n", - "Loss: 0.1617 \n", - "Train_acc: 0.9643\n", - "Epoch: 715-------- \n", - "Loss: 0.1612 \n", - "Train_acc: 0.9643\n", - "Epoch: 716-------- \n", - "Loss: 0.1606 \n", - "Train_acc: 0.9643\n", - "Epoch: 717-------- \n", - "Loss: 0.1601 \n", - "Train_acc: 0.9643\n", - "Epoch: 718-------- \n", - "Loss: 0.1595 \n", - "Train_acc: 0.9643\n", - "Epoch: 719-------- \n", - "Loss: 0.1590 \n", - "Train_acc: 0.9643\n", - "Epoch: 720-------- \n", - "Loss: 0.1584 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 721-------- \n", - "Loss: 0.1579 \n", - "Train_acc: 0.9643\n", - "Epoch: 722-------- \n", - "Loss: 0.1573 \n", - "Train_acc: 0.9643\n", - "Epoch: 723-------- \n", - "Loss: 0.1568 \n", - "Train_acc: 0.9643\n", - "Epoch: 724-------- \n", - "Loss: 0.1563 \n", - "Train_acc: 0.9643\n", - "Epoch: 725-------- \n", - "Loss: 0.1557 \n", - "Train_acc: 0.9643\n", - "Epoch: 726-------- \n", - "Loss: 0.1552 \n", - "Train_acc: 0.9643\n", - "Epoch: 727-------- \n", - "Loss: 0.1547 \n", - "Train_acc: 0.9643\n", - "Epoch: 728-------- \n", - "Loss: 0.1542 \n", - "Train_acc: 0.9643\n", - "Epoch: 729-------- \n", - "Loss: 0.1537 \n", - "Train_acc: 0.9643\n", - "Epoch: 730-------- \n", - "Loss: 0.1532 \n", - "Train_acc: 0.9643\n", - "Epoch: 731-------- \n", - "Loss: 0.1527 \n", - "Train_acc: 0.9643\n", - "Epoch: 732-------- \n", - "Loss: 0.1522 \n", - "Train_acc: 0.9643\n", - "Epoch: 733-------- \n", - "Loss: 0.1517 \n", - "Train_acc: 0.9643\n", - "Epoch: 734-------- \n", - "Loss: 0.1512 \n", - "Train_acc: 0.9643\n", - "Epoch: 735-------- \n", - "Loss: 0.1507 \n", - "Train_acc: 0.9643\n", - "Epoch: 736-------- \n", - "Loss: 0.1502 \n", - "Train_acc: 0.9643\n", - "Epoch: 737-------- \n", - "Loss: 0.1497 \n", - "Train_acc: 0.9643\n", - "Epoch: 738-------- \n", - "Loss: 0.1492 \n", - "Train_acc: 0.9643\n", - "Epoch: 739-------- \n", - "Loss: 0.1488 \n", - "Train_acc: 0.9643\n", - "Epoch: 740-------- \n", - "Loss: 0.1483 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 741-------- \n", - "Loss: 0.1478 \n", - "Train_acc: 0.9643\n", - "Epoch: 742-------- \n", - "Loss: 0.1473 \n", - "Train_acc: 0.9643\n", - "Epoch: 743-------- \n", - "Loss: 0.1469 \n", - "Train_acc: 0.9643\n", - "Epoch: 744-------- \n", - "Loss: 0.1464 \n", - "Train_acc: 0.9643\n", - "Epoch: 745-------- \n", - "Loss: 0.1460 \n", - "Train_acc: 0.9643\n", - "Epoch: 746-------- \n", - "Loss: 0.1455 \n", - "Train_acc: 0.9643\n", - "Epoch: 747-------- \n", - "Loss: 0.1451 \n", - "Train_acc: 0.9643\n", - "Epoch: 748-------- \n", - "Loss: 0.1446 \n", - "Train_acc: 0.9643\n", - "Epoch: 749-------- \n", - "Loss: 0.1442 \n", - "Train_acc: 0.9643\n", - "Epoch: 750-------- \n", - "Loss: 0.1437 \n", - "Train_acc: 0.9643\n", - "Epoch: 751-------- \n", - "Loss: 0.1433 \n", - "Train_acc: 0.9643\n", - "Epoch: 752-------- \n", - "Loss: 0.1428 \n", - "Train_acc: 0.9643\n", - "Epoch: 753-------- \n", - "Loss: 0.1424 \n", - "Train_acc: 0.9643\n", - "Epoch: 754-------- \n", - "Loss: 0.1420 \n", - "Train_acc: 0.9643\n", - "Epoch: 755-------- \n", - "Loss: 0.1415 \n", - "Train_acc: 0.9643\n", - "Epoch: 756-------- \n", - "Loss: 0.1411 \n", - "Train_acc: 0.9643\n", - "Epoch: 757-------- \n", - "Loss: 0.1407 \n", - "Train_acc: 0.9643\n", - "Epoch: 758-------- \n", - "Loss: 0.1403 \n", - "Train_acc: 0.9643\n", - "Epoch: 759-------- \n", - "Loss: 0.1399 \n", - "Train_acc: 0.9643\n", - "Epoch: 760-------- \n", - "Loss: 0.1394 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 761-------- \n", - "Loss: 0.1390 \n", - "Train_acc: 0.9643\n", - "Epoch: 762-------- \n", - "Loss: 0.1386 \n", - "Train_acc: 0.9643\n", - "Epoch: 763-------- \n", - "Loss: 0.1382 \n", - "Train_acc: 0.9643\n", - "Epoch: 764-------- \n", - "Loss: 0.1378 \n", - "Train_acc: 0.9643\n", - "Epoch: 765-------- \n", - "Loss: 0.1374 \n", - "Train_acc: 0.9643\n", - "Epoch: 766-------- \n", - "Loss: 0.1370 \n", - "Train_acc: 0.9643\n", - "Epoch: 767-------- \n", - "Loss: 0.1366 \n", - "Train_acc: 0.9643\n", - "Epoch: 768-------- \n", - "Loss: 0.1362 \n", - "Train_acc: 0.9643\n", - "Epoch: 769-------- \n", - "Loss: 0.1358 \n", - "Train_acc: 0.9643\n", - "Epoch: 770-------- \n", - "Loss: 0.1354 \n", - "Train_acc: 0.9643\n", - "Epoch: 771-------- \n", - "Loss: 0.1351 \n", - "Train_acc: 0.9643\n", - "Epoch: 772-------- \n", - "Loss: 0.1347 \n", - "Train_acc: 0.9643\n", - "Epoch: 773-------- \n", - "Loss: 0.1343 \n", - "Train_acc: 0.9643\n", - "Epoch: 774-------- \n", - "Loss: 0.1339 \n", - "Train_acc: 0.9643\n", - "Epoch: 775-------- \n", - "Loss: 0.1335 \n", - "Train_acc: 0.9643\n", - "Epoch: 776-------- \n", - "Loss: 0.1332 \n", - "Train_acc: 0.9643\n", - "Epoch: 777-------- \n", - "Loss: 0.1328 \n", - "Train_acc: 0.9643\n", - "Epoch: 778-------- \n", - "Loss: 0.1324 \n", - "Train_acc: 0.9643\n", - "Epoch: 779-------- \n", - "Loss: 0.1320 \n", - "Train_acc: 0.9643\n", - "Epoch: 780-------- \n", - "Loss: 0.1317 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 781-------- \n", - "Loss: 0.1313 \n", - "Train_acc: 0.9643\n", - "Epoch: 782-------- \n", - "Loss: 0.1310 \n", - "Train_acc: 0.9643\n", - "Epoch: 783-------- \n", - "Loss: 0.1306 \n", - "Train_acc: 0.9643\n", - "Epoch: 784-------- \n", - "Loss: 0.1302 \n", - "Train_acc: 0.9643\n", - "Epoch: 785-------- \n", - "Loss: 0.1299 \n", - "Train_acc: 0.9643\n", - "Epoch: 786-------- \n", - "Loss: 0.1295 \n", - "Train_acc: 0.9643\n", - "Epoch: 787-------- \n", - "Loss: 0.1292 \n", - "Train_acc: 0.9643\n", - "Epoch: 788-------- \n", - "Loss: 0.1288 \n", - "Train_acc: 0.9643\n", - "Epoch: 789-------- \n", - "Loss: 0.1285 \n", - "Train_acc: 0.9643\n", - "Epoch: 790-------- \n", - "Loss: 0.1281 \n", - "Train_acc: 0.9643\n", - "Epoch: 791-------- \n", - "Loss: 0.1278 \n", - "Train_acc: 0.9643\n", - "Epoch: 792-------- \n", - "Loss: 0.1275 \n", - "Train_acc: 0.9643\n", - "Epoch: 793-------- \n", - "Loss: 0.1271 \n", - "Train_acc: 0.9643\n", - "Epoch: 794-------- \n", - "Loss: 0.1268 \n", - "Train_acc: 0.9643\n", - "Epoch: 795-------- \n", - "Loss: 0.1265 \n", - "Train_acc: 0.9643\n", - "Epoch: 796-------- \n", - "Loss: 0.1261 \n", - "Train_acc: 0.9643\n", - "Epoch: 797-------- \n", - "Loss: 0.1258 \n", - "Train_acc: 0.9643\n", - "Epoch: 798-------- \n", - "Loss: 0.1255 \n", - "Train_acc: 0.9643\n", - "Epoch: 799-------- \n", - "Loss: 0.1251 \n", - "Train_acc: 0.9643\n", - "Epoch: 800-------- \n", - "Loss: 0.1248 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 801-------- \n", - "Loss: 0.1245 \n", - "Train_acc: 0.9643\n", - "Epoch: 802-------- \n", - "Loss: 0.1242 \n", - "Train_acc: 0.9643\n", - "Epoch: 803-------- \n", - "Loss: 0.1239 \n", - "Train_acc: 0.9643\n", - "Epoch: 804-------- \n", - "Loss: 0.1235 \n", - "Train_acc: 0.9643\n", - "Epoch: 805-------- \n", - "Loss: 0.1232 \n", - "Train_acc: 0.9643\n", - "Epoch: 806-------- \n", - "Loss: 0.1229 \n", - "Train_acc: 0.9643\n", - "Epoch: 807-------- \n", - "Loss: 0.1226 \n", - "Train_acc: 0.9643\n", - "Epoch: 808-------- \n", - "Loss: 0.1223 \n", - "Train_acc: 0.9643\n", - "Epoch: 809-------- \n", - "Loss: 0.1220 \n", - "Train_acc: 0.9643\n", - "Epoch: 810-------- \n", - "Loss: 0.1217 \n", - "Train_acc: 0.9643\n", - "Epoch: 811-------- \n", - "Loss: 0.1214 \n", - "Train_acc: 0.9643\n", - "Epoch: 812-------- \n", - "Loss: 0.1211 \n", - "Train_acc: 0.9643\n", - "Epoch: 813-------- \n", - "Loss: 0.1208 \n", - "Train_acc: 0.9643\n", - "Epoch: 814-------- \n", - "Loss: 0.1205 \n", - "Train_acc: 0.9643\n", - "Epoch: 815-------- \n", - "Loss: 0.1202 \n", - "Train_acc: 0.9643\n", - "Epoch: 816-------- \n", - "Loss: 0.1199 \n", - "Train_acc: 0.9643\n", - "Epoch: 817-------- \n", - "Loss: 0.1196 \n", - "Train_acc: 0.9643\n", - "Epoch: 818-------- \n", - "Loss: 0.1193 \n", - "Train_acc: 0.9643\n", - "Epoch: 819-------- \n", - "Loss: 0.1190 \n", - "Train_acc: 0.9643\n", - "Epoch: 820-------- \n", - "Loss: 0.1187 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 821-------- \n", - "Loss: 0.1184 \n", - "Train_acc: 0.9643\n", - "Epoch: 822-------- \n", - "Loss: 0.1181 \n", - "Train_acc: 0.9643\n", - "Epoch: 823-------- \n", - "Loss: 0.1178 \n", - "Train_acc: 0.9643\n", - "Epoch: 824-------- \n", - "Loss: 0.1176 \n", - "Train_acc: 0.9643\n", - "Epoch: 825-------- \n", - "Loss: 0.1173 \n", - "Train_acc: 0.9643\n", - "Epoch: 826-------- \n", - "Loss: 0.1170 \n", - "Train_acc: 0.9643\n", - "Epoch: 827-------- \n", - "Loss: 0.1167 \n", - "Train_acc: 0.9643\n", - "Epoch: 828-------- \n", - "Loss: 0.1164 \n", - "Train_acc: 0.9643\n", - "Epoch: 829-------- \n", - "Loss: 0.1162 \n", - "Train_acc: 0.9643\n", - "Epoch: 830-------- \n", - "Loss: 0.1159 \n", - "Train_acc: 0.9643\n", - "Epoch: 831-------- \n", - "Loss: 0.1156 \n", - "Train_acc: 0.9643\n", - "Epoch: 832-------- \n", - "Loss: 0.1153 \n", - "Train_acc: 0.9643\n", - "Epoch: 833-------- \n", - "Loss: 0.1151 \n", - "Train_acc: 0.9643\n", - "Epoch: 834-------- \n", - "Loss: 0.1148 \n", - "Train_acc: 0.9643\n", - "Epoch: 835-------- \n", - "Loss: 0.1145 \n", - "Train_acc: 0.9643\n", - "Epoch: 836-------- \n", - "Loss: 0.1143 \n", - "Train_acc: 0.9643\n", - "Epoch: 837-------- \n", - "Loss: 0.1140 \n", - "Train_acc: 0.9643\n", - "Epoch: 838-------- \n", - "Loss: 0.1137 \n", - "Train_acc: 0.9643\n", - "Epoch: 839-------- \n", - "Loss: 0.1135 \n", - "Train_acc: 0.9643\n", - "Epoch: 840-------- \n", - "Loss: 0.1132 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 841-------- \n", - "Loss: 0.1130 \n", - "Train_acc: 0.9643\n", - "Epoch: 842-------- \n", - "Loss: 0.1127 \n", - "Train_acc: 0.9643\n", - "Epoch: 843-------- \n", - "Loss: 0.1125 \n", - "Train_acc: 0.9643\n", - "Epoch: 844-------- \n", - "Loss: 0.1122 \n", - "Train_acc: 0.9643\n", - "Epoch: 845-------- \n", - "Loss: 0.1119 \n", - "Train_acc: 0.9643\n", - "Epoch: 846-------- \n", - "Loss: 0.1117 \n", - "Train_acc: 0.9643\n", - "Epoch: 847-------- \n", - "Loss: 0.1114 \n", - "Train_acc: 0.9643\n", - "Epoch: 848-------- \n", - "Loss: 0.1112 \n", - "Train_acc: 0.9643\n", - "Epoch: 849-------- \n", - "Loss: 0.1109 \n", - "Train_acc: 0.9643\n", - "Epoch: 850-------- \n", - "Loss: 0.1107 \n", - "Train_acc: 0.9643\n", - "Epoch: 851-------- \n", - "Loss: 0.1105 \n", - "Train_acc: 0.9643\n", - "Epoch: 852-------- \n", - "Loss: 0.1102 \n", - "Train_acc: 0.9643\n", - "Epoch: 853-------- \n", - "Loss: 0.1100 \n", - "Train_acc: 0.9643\n", - "Epoch: 854-------- \n", - "Loss: 0.1097 \n", - "Train_acc: 0.9643\n", - "Epoch: 855-------- \n", - "Loss: 0.1095 \n", - "Train_acc: 0.9643\n", - "Epoch: 856-------- \n", - "Loss: 0.1092 \n", - "Train_acc: 0.9643\n", - "Epoch: 857-------- \n", - "Loss: 0.1090 \n", - "Train_acc: 0.9643\n", - "Epoch: 858-------- \n", - "Loss: 0.1088 \n", - "Train_acc: 0.9643\n", - "Epoch: 859-------- \n", - "Loss: 0.1085 \n", - "Train_acc: 0.9643\n", - "Epoch: 860-------- \n", - "Loss: 0.1083 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 861-------- \n", - "Loss: 0.1081 \n", - "Train_acc: 0.9643\n", - "Epoch: 862-------- \n", - "Loss: 0.1078 \n", - "Train_acc: 0.9643\n", - "Epoch: 863-------- \n", - "Loss: 0.1076 \n", - "Train_acc: 0.9643\n", - "Epoch: 864-------- \n", - "Loss: 0.1074 \n", - "Train_acc: 0.9643\n", - "Epoch: 865-------- \n", - "Loss: 0.1071 \n", - "Train_acc: 0.9643\n", - "Epoch: 866-------- \n", - "Loss: 0.1069 \n", - "Train_acc: 0.9643\n", - "Epoch: 867-------- \n", - "Loss: 0.1067 \n", - "Train_acc: 0.9643\n", - "Epoch: 868-------- \n", - "Loss: 0.1065 \n", - "Train_acc: 0.9643\n", - "Epoch: 869-------- \n", - "Loss: 0.1062 \n", - "Train_acc: 0.9643\n", - "Epoch: 870-------- \n", - "Loss: 0.1060 \n", - "Train_acc: 0.9643\n", - "Epoch: 871-------- \n", - "Loss: 0.1058 \n", - "Train_acc: 0.9643\n", - "Epoch: 872-------- \n", - "Loss: 0.1056 \n", - "Train_acc: 0.9643\n", - "Epoch: 873-------- \n", - "Loss: 0.1054 \n", - "Train_acc: 0.9643\n", - "Epoch: 874-------- \n", - "Loss: 0.1051 \n", - "Train_acc: 0.9643\n", - "Epoch: 875-------- \n", - "Loss: 0.1049 \n", - "Train_acc: 0.9643\n", - "Epoch: 876-------- \n", - "Loss: 0.1047 \n", - "Train_acc: 0.9643\n", - "Epoch: 877-------- \n", - "Loss: 0.1045 \n", - "Train_acc: 0.9643\n", - "Epoch: 878-------- \n", - "Loss: 0.1043 \n", - "Train_acc: 0.9643\n", - "Epoch: 879-------- \n", - "Loss: 0.1041 \n", - "Train_acc: 0.9643\n", - "Epoch: 880-------- \n", - "Loss: 0.1038 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 881-------- \n", - "Loss: 0.1036 \n", - "Train_acc: 0.9643\n", - "Epoch: 882-------- \n", - "Loss: 0.1034 \n", - "Train_acc: 0.9643\n", - "Epoch: 883-------- \n", - "Loss: 0.1032 \n", - "Train_acc: 0.9643\n", - "Epoch: 884-------- \n", - "Loss: 0.1030 \n", - "Train_acc: 0.9643\n", - "Epoch: 885-------- \n", - "Loss: 0.1028 \n", - "Train_acc: 0.9643\n", - "Epoch: 886-------- \n", - "Loss: 0.1026 \n", - "Train_acc: 0.9643\n", - "Epoch: 887-------- \n", - "Loss: 0.1024 \n", - "Train_acc: 0.9643\n", - "Epoch: 888-------- \n", - "Loss: 0.1022 \n", - "Train_acc: 0.9643\n", - "Epoch: 889-------- \n", - "Loss: 0.1020 \n", - "Train_acc: 0.9643\n", - "Epoch: 890-------- \n", - "Loss: 0.1018 \n", - "Train_acc: 0.9643\n", - "Epoch: 891-------- \n", - "Loss: 0.1016 \n", - "Train_acc: 0.9643\n", - "Epoch: 892-------- \n", - "Loss: 0.1014 \n", - "Train_acc: 0.9643\n", - "Epoch: 893-------- \n", - "Loss: 0.1012 \n", - "Train_acc: 0.9643\n", - "Epoch: 894-------- \n", - "Loss: 0.1010 \n", - "Train_acc: 0.9643\n", - "Epoch: 895-------- \n", - "Loss: 0.1008 \n", - "Train_acc: 0.9643\n", - "Epoch: 896-------- \n", - "Loss: 0.1006 \n", - "Train_acc: 0.9643\n", - "Epoch: 897-------- \n", - "Loss: 0.1004 \n", - "Train_acc: 0.9643\n", - "Epoch: 898-------- \n", - "Loss: 0.1002 \n", - "Train_acc: 0.9643\n", - "Epoch: 899-------- \n", - "Loss: 0.1000 \n", - "Train_acc: 0.9643\n", - "Epoch: 900-------- \n", - "Loss: 0.0998 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 901-------- \n", - "Loss: 0.0996 \n", - "Train_acc: 0.9643\n", - "Epoch: 902-------- \n", - "Loss: 0.0994 \n", - "Train_acc: 0.9643\n", - "Epoch: 903-------- \n", - "Loss: 0.0992 \n", - "Train_acc: 0.9643\n", - "Epoch: 904-------- \n", - "Loss: 0.0990 \n", - "Train_acc: 0.9643\n", - "Epoch: 905-------- \n", - "Loss: 0.0988 \n", - "Train_acc: 0.9643\n", - "Epoch: 906-------- \n", - "Loss: 0.0986 \n", - "Train_acc: 0.9643\n", - "Epoch: 907-------- \n", - "Loss: 0.0985 \n", - "Train_acc: 0.9643\n", - "Epoch: 908-------- \n", - "Loss: 0.0983 \n", - "Train_acc: 0.9643\n", - "Epoch: 909-------- \n", - "Loss: 0.0981 \n", - "Train_acc: 0.9643\n", - "Epoch: 910-------- \n", - "Loss: 0.0979 \n", - "Train_acc: 0.9643\n", - "Epoch: 911-------- \n", - "Loss: 0.0977 \n", - "Train_acc: 0.9643\n", - "Epoch: 912-------- \n", - "Loss: 0.0975 \n", - "Train_acc: 0.9643\n", - "Epoch: 913-------- \n", - "Loss: 0.0973 \n", - "Train_acc: 0.9643\n", - "Epoch: 914-------- \n", - "Loss: 0.0972 \n", - "Train_acc: 0.9643\n", - "Epoch: 915-------- \n", - "Loss: 0.0970 \n", - "Train_acc: 0.9643\n", - "Epoch: 916-------- \n", - "Loss: 0.0968 \n", - "Train_acc: 0.9643\n", - "Epoch: 917-------- \n", - "Loss: 0.0966 \n", - "Train_acc: 0.9643\n", - "Epoch: 918-------- \n", - "Loss: 0.0964 \n", - "Train_acc: 0.9643\n", - "Epoch: 919-------- \n", - "Loss: 0.0963 \n", - "Train_acc: 0.9643\n", - "Epoch: 920-------- \n", - "Loss: 0.0961 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 921-------- \n", - "Loss: 0.0959 \n", - "Train_acc: 0.9643\n", - "Epoch: 922-------- \n", - "Loss: 0.0957 \n", - "Train_acc: 0.9643\n", - "Epoch: 923-------- \n", - "Loss: 0.0956 \n", - "Train_acc: 0.9643\n", - "Epoch: 924-------- \n", - "Loss: 0.0954 \n", - "Train_acc: 0.9643\n", - "Epoch: 925-------- \n", - "Loss: 0.0952 \n", - "Train_acc: 0.9643\n", - "Epoch: 926-------- \n", - "Loss: 0.0950 \n", - "Train_acc: 0.9643\n", - "Epoch: 927-------- \n", - "Loss: 0.0949 \n", - "Train_acc: 0.9643\n", - "Epoch: 928-------- \n", - "Loss: 0.0947 \n", - "Train_acc: 0.9643\n", - "Epoch: 929-------- \n", - "Loss: 0.0945 \n", - "Train_acc: 0.9643\n", - "Epoch: 930-------- \n", - "Loss: 0.0944 \n", - "Train_acc: 0.9643\n", - "Epoch: 931-------- \n", - "Loss: 0.0942 \n", - "Train_acc: 0.9643\n", - "Epoch: 932-------- \n", - "Loss: 0.0940 \n", - "Train_acc: 0.9643\n", - "Epoch: 933-------- \n", - "Loss: 0.0939 \n", - "Train_acc: 0.9643\n", - "Epoch: 934-------- \n", - "Loss: 0.0937 \n", - "Train_acc: 0.9643\n", - "Epoch: 935-------- \n", - "Loss: 0.0935 \n", - "Train_acc: 0.9643\n", - "Epoch: 936-------- \n", - "Loss: 0.0934 \n", - "Train_acc: 0.9643\n", - "Epoch: 937-------- \n", - "Loss: 0.0932 \n", - "Train_acc: 0.9643\n", - "Epoch: 938-------- \n", - "Loss: 0.0930 \n", - "Train_acc: 0.9643\n", - "Epoch: 939-------- \n", - "Loss: 0.0929 \n", - "Train_acc: 0.9643\n", - "Epoch: 940-------- \n", - "Loss: 0.0927 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 941-------- \n", - "Loss: 0.0925 \n", - "Train_acc: 0.9643\n", - "Epoch: 942-------- \n", - "Loss: 0.0924 \n", - "Train_acc: 0.9643\n", - "Epoch: 943-------- \n", - "Loss: 0.0922 \n", - "Train_acc: 0.9643\n", - "Epoch: 944-------- \n", - "Loss: 0.0920 \n", - "Train_acc: 0.9643\n", - "Epoch: 945-------- \n", - "Loss: 0.0919 \n", - "Train_acc: 0.9643\n", - "Epoch: 946-------- \n", - "Loss: 0.0917 \n", - "Train_acc: 0.9643\n", - "Epoch: 947-------- \n", - "Loss: 0.0916 \n", - "Train_acc: 0.9643\n", - "Epoch: 948-------- \n", - "Loss: 0.0914 \n", - "Train_acc: 0.9643\n", - "Epoch: 949-------- \n", - "Loss: 0.0913 \n", - "Train_acc: 0.9643\n", - "Epoch: 950-------- \n", - "Loss: 0.0911 \n", - "Train_acc: 0.9643\n", - "Epoch: 951-------- \n", - "Loss: 0.0909 \n", - "Train_acc: 0.9643\n", - "Epoch: 952-------- \n", - "Loss: 0.0908 \n", - "Train_acc: 0.9643\n", - "Epoch: 953-------- \n", - "Loss: 0.0906 \n", - "Train_acc: 0.9643\n", - "Epoch: 954-------- \n", - "Loss: 0.0905 \n", - "Train_acc: 0.9643\n", - "Epoch: 955-------- \n", - "Loss: 0.0903 \n", - "Train_acc: 0.9643\n", - "Epoch: 956-------- \n", - "Loss: 0.0902 \n", - "Train_acc: 0.9643\n", - "Epoch: 957-------- \n", - "Loss: 0.0900 \n", - "Train_acc: 0.9643\n", - "Epoch: 958-------- \n", - "Loss: 0.0899 \n", - "Train_acc: 0.9643\n", - "Epoch: 959-------- \n", - "Loss: 0.0897 \n", - "Train_acc: 0.9643\n", - "Epoch: 960-------- \n", - "Loss: 0.0896 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 961-------- \n", - "Loss: 0.0894 \n", - "Train_acc: 0.9643\n", - "Epoch: 962-------- \n", - "Loss: 0.0893 \n", - "Train_acc: 0.9643\n", - "Epoch: 963-------- \n", - "Loss: 0.0891 \n", - "Train_acc: 0.9643\n", - "Epoch: 964-------- \n", - "Loss: 0.0890 \n", - "Train_acc: 0.9643\n", - "Epoch: 965-------- \n", - "Loss: 0.0888 \n", - "Train_acc: 0.9643\n", - "Epoch: 966-------- \n", - "Loss: 0.0887 \n", - "Train_acc: 0.9643\n", - "Epoch: 967-------- \n", - "Loss: 0.0885 \n", - "Train_acc: 0.9643\n", - "Epoch: 968-------- \n", - "Loss: 0.0884 \n", - "Train_acc: 0.9643\n", - "Epoch: 969-------- \n", - "Loss: 0.0882 \n", - "Train_acc: 0.9643\n", - "Epoch: 970-------- \n", - "Loss: 0.0881 \n", - "Train_acc: 0.9643\n", - "Epoch: 971-------- \n", - "Loss: 0.0880 \n", - "Train_acc: 0.9643\n", - "Epoch: 972-------- \n", - "Loss: 0.0878 \n", - "Train_acc: 0.9643\n", - "Epoch: 973-------- \n", - "Loss: 0.0877 \n", - "Train_acc: 0.9643\n", - "Epoch: 974-------- \n", - "Loss: 0.0875 \n", - "Train_acc: 0.9643\n", - "Epoch: 975-------- \n", - "Loss: 0.0874 \n", - "Train_acc: 0.9643\n", - "Epoch: 976-------- \n", - "Loss: 0.0872 \n", - "Train_acc: 0.9643\n", - "Epoch: 977-------- \n", - "Loss: 0.0871 \n", - "Train_acc: 0.9643\n", - "Epoch: 978-------- \n", - "Loss: 0.0870 \n", - "Train_acc: 0.9643\n", - "Epoch: 979-------- \n", - "Loss: 0.0868 \n", - "Train_acc: 0.9643\n", - "Epoch: 980-------- \n", - "Loss: 0.0867 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 981-------- \n", - "Loss: 0.0865 \n", - "Train_acc: 0.9643\n", - "Epoch: 982-------- \n", - "Loss: 0.0864 \n", - "Train_acc: 0.9643\n", - "Epoch: 983-------- \n", - "Loss: 0.0863 \n", - "Train_acc: 0.9643\n", - "Epoch: 984-------- \n", - "Loss: 0.0861 \n", - "Train_acc: 0.9643\n", - "Epoch: 985-------- \n", - "Loss: 0.0860 \n", - "Train_acc: 0.9643\n", - "Epoch: 986-------- \n", - "Loss: 0.0859 \n", - "Train_acc: 0.9643\n", - "Epoch: 987-------- \n", - "Loss: 0.0857 \n", - "Train_acc: 0.9643\n", - "Epoch: 988-------- \n", - "Loss: 0.0856 \n", - "Train_acc: 0.9643\n", - "Epoch: 989-------- \n", - "Loss: 0.0855 \n", - "Train_acc: 0.9643\n", - "Epoch: 990-------- \n", - "Loss: 0.0853 \n", - "Train_acc: 0.9643\n", - "Epoch: 991-------- \n", - "Loss: 0.0852 \n", - "Train_acc: 0.9643\n", - "Epoch: 992-------- \n", - "Loss: 0.0851 \n", - "Train_acc: 0.9643\n", - "Epoch: 993-------- \n", - "Loss: 0.0849 \n", - "Train_acc: 0.9643\n", - "Epoch: 994-------- \n", - "Loss: 0.0848 \n", - "Train_acc: 0.9643\n", - "Epoch: 995-------- \n", - "Loss: 0.0847 \n", - "Train_acc: 0.9643\n", - "Epoch: 996-------- \n", - "Loss: 0.0845 \n", - "Train_acc: 0.9643\n", - "Epoch: 997-------- \n", - "Loss: 0.0844 \n", - "Train_acc: 0.9643\n", - "Epoch: 998-------- \n", - "Loss: 0.0843 \n", - "Train_acc: 0.9643\n", - "Epoch: 999-------- \n", - "Loss: 0.0841 \n", - "Train_acc: 0.9643\n", - "Epoch: 1000-------- \n", - "Loss: 0.0840 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 1001-------- \n", - "Loss: 0.0839 \n", - "Train_acc: 0.9643\n", - "Epoch: 1002-------- \n", - "Loss: 0.0838 \n", - "Train_acc: 0.9643\n", - "Epoch: 1003-------- \n", - "Loss: 0.0836 \n", - "Train_acc: 0.9643\n", - "Epoch: 1004-------- \n", - "Loss: 0.0835 \n", - "Train_acc: 0.9643\n", - "Epoch: 1005-------- \n", - "Loss: 0.0834 \n", - "Train_acc: 0.9643\n", - "Epoch: 1006-------- \n", - "Loss: 0.0832 \n", - "Train_acc: 0.9643\n", - "Epoch: 1007-------- \n", - "Loss: 0.0831 \n", - "Train_acc: 0.9643\n", - "Epoch: 1008-------- \n", - "Loss: 0.0830 \n", - "Train_acc: 0.9643\n", - "Epoch: 1009-------- \n", - "Loss: 0.0829 \n", - "Train_acc: 0.9643\n", - "Epoch: 1010-------- \n", - "Loss: 0.0827 \n", - "Train_acc: 0.9643\n", - "Epoch: 1011-------- \n", - "Loss: 0.0826 \n", - "Train_acc: 0.9643\n", - "Epoch: 1012-------- \n", - "Loss: 0.0825 \n", - "Train_acc: 0.9643\n", - "Epoch: 1013-------- \n", - "Loss: 0.0824 \n", - "Train_acc: 0.9643\n", - "Epoch: 1014-------- \n", - "Loss: 0.0823 \n", - "Train_acc: 0.9643\n", - "Epoch: 1015-------- \n", - "Loss: 0.0821 \n", - "Train_acc: 0.9643\n", - "Epoch: 1016-------- \n", - "Loss: 0.0820 \n", - "Train_acc: 0.9643\n", - "Epoch: 1017-------- \n", - "Loss: 0.0819 \n", - "Train_acc: 0.9643\n", - "Epoch: 1018-------- \n", - "Loss: 0.0818 \n", - "Train_acc: 0.9643\n", - "Epoch: 1019-------- \n", - "Loss: 0.0816 \n", - "Train_acc: 0.9643\n", - "Epoch: 1020-------- \n", - "Loss: 0.0815 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 1021-------- \n", - "Loss: 0.0814 \n", - "Train_acc: 0.9643\n", - "Epoch: 1022-------- \n", - "Loss: 0.0813 \n", - "Train_acc: 0.9643\n", - "Epoch: 1023-------- \n", - "Loss: 0.0812 \n", - "Train_acc: 0.9643\n", - "Epoch: 1024-------- \n", - "Loss: 0.0810 \n", - "Train_acc: 0.9643\n", - "Epoch: 1025-------- \n", - "Loss: 0.0809 \n", - "Train_acc: 0.9643\n", - "Epoch: 1026-------- \n", - "Loss: 0.0808 \n", - "Train_acc: 0.9643\n", - "Epoch: 1027-------- \n", - "Loss: 0.0807 \n", - "Train_acc: 0.9643\n", - "Epoch: 1028-------- \n", - "Loss: 0.0806 \n", - "Train_acc: 0.9643\n", - "Epoch: 1029-------- \n", - "Loss: 0.0805 \n", - "Train_acc: 0.9643\n", - "Epoch: 1030-------- \n", - "Loss: 0.0803 \n", - "Train_acc: 0.9643\n", - "Epoch: 1031-------- \n", - "Loss: 0.0802 \n", - "Train_acc: 0.9643\n", - "Epoch: 1032-------- \n", - "Loss: 0.0801 \n", - "Train_acc: 0.9643\n", - "Epoch: 1033-------- \n", - "Loss: 0.0800 \n", - "Train_acc: 0.9643\n", - "Epoch: 1034-------- \n", - "Loss: 0.0799 \n", - "Train_acc: 0.9643\n", - "Epoch: 1035-------- \n", - "Loss: 0.0798 \n", - "Train_acc: 0.9643\n", - "Epoch: 1036-------- \n", - "Loss: 0.0797 \n", - "Train_acc: 0.9643\n", - "Epoch: 1037-------- \n", - "Loss: 0.0795 \n", - "Train_acc: 0.9643\n", - "Epoch: 1038-------- \n", - "Loss: 0.0794 \n", - "Train_acc: 0.9643\n", - "Epoch: 1039-------- \n", - "Loss: 0.0793 \n", - "Train_acc: 0.9643\n", - "Epoch: 1040-------- \n", - "Loss: 0.0792 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 1041-------- \n", - "Loss: 0.0791 \n", - "Train_acc: 0.9643\n", - "Epoch: 1042-------- \n", - "Loss: 0.0790 \n", - "Train_acc: 0.9643\n", - "Epoch: 1043-------- \n", - "Loss: 0.0789 \n", - "Train_acc: 0.9643\n", - "Epoch: 1044-------- \n", - "Loss: 0.0788 \n", - "Train_acc: 0.9643\n", - "Epoch: 1045-------- \n", - "Loss: 0.0787 \n", - "Train_acc: 0.9643\n", - "Epoch: 1046-------- \n", - "Loss: 0.0785 \n", - "Train_acc: 0.9643\n", - "Epoch: 1047-------- \n", - "Loss: 0.0784 \n", - "Train_acc: 0.9643\n", - "Epoch: 1048-------- \n", - "Loss: 0.0783 \n", - "Train_acc: 0.9643\n", - "Epoch: 1049-------- \n", - "Loss: 0.0782 \n", - "Train_acc: 0.9643\n", - "Epoch: 1050-------- \n", - "Loss: 0.0781 \n", - "Train_acc: 0.9643\n", - "Epoch: 1051-------- \n", - "Loss: 0.0780 \n", - "Train_acc: 0.9643\n", - "Epoch: 1052-------- \n", - "Loss: 0.0779 \n", - "Train_acc: 0.9643\n", - "Epoch: 1053-------- \n", - "Loss: 0.0778 \n", - "Train_acc: 0.9643\n", - "Epoch: 1054-------- \n", - "Loss: 0.0777 \n", - "Train_acc: 0.9643\n", - "Epoch: 1055-------- \n", - "Loss: 0.0776 \n", - "Train_acc: 0.9643\n", - "Epoch: 1056-------- \n", - "Loss: 0.0775 \n", - "Train_acc: 0.9643\n", - "Epoch: 1057-------- \n", - "Loss: 0.0774 \n", - "Train_acc: 0.9643\n", - "Epoch: 1058-------- \n", - "Loss: 0.0772 \n", - "Train_acc: 0.9643\n", - "Epoch: 1059-------- \n", - "Loss: 0.0771 \n", - "Train_acc: 0.9643\n", - "Epoch: 1060-------- \n", - "Loss: 0.0770 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 1061-------- \n", - "Loss: 0.0769 \n", - "Train_acc: 0.9643\n", - "Epoch: 1062-------- \n", - "Loss: 0.0768 \n", - "Train_acc: 0.9643\n", - "Epoch: 1063-------- \n", - "Loss: 0.0767 \n", - "Train_acc: 0.9643\n", - "Epoch: 1064-------- \n", - "Loss: 0.0766 \n", - "Train_acc: 0.9643\n", - "Epoch: 1065-------- \n", - "Loss: 0.0765 \n", - "Train_acc: 0.9643\n", - "Epoch: 1066-------- \n", - "Loss: 0.0764 \n", - "Train_acc: 0.9643\n", - "Epoch: 1067-------- \n", - "Loss: 0.0763 \n", - "Train_acc: 0.9643\n", - "Epoch: 1068-------- \n", - "Loss: 0.0762 \n", - "Train_acc: 0.9643\n", - "Epoch: 1069-------- \n", - "Loss: 0.0761 \n", - "Train_acc: 0.9643\n", - "Epoch: 1070-------- \n", - "Loss: 0.0760 \n", - "Train_acc: 0.9643\n", - "Epoch: 1071-------- \n", - "Loss: 0.0759 \n", - "Train_acc: 0.9643\n", - "Epoch: 1072-------- \n", - "Loss: 0.0758 \n", - "Train_acc: 0.9643\n", - "Epoch: 1073-------- \n", - "Loss: 0.0757 \n", - "Train_acc: 0.9643\n", - "Epoch: 1074-------- \n", - "Loss: 0.0756 \n", - "Train_acc: 0.9643\n", - "Epoch: 1075-------- \n", - "Loss: 0.0755 \n", - "Train_acc: 0.9643\n", - "Epoch: 1076-------- \n", - "Loss: 0.0754 \n", - "Train_acc: 0.9643\n", - "Epoch: 1077-------- \n", - "Loss: 0.0753 \n", - "Train_acc: 0.9643\n", - "Epoch: 1078-------- \n", - "Loss: 0.0752 \n", - "Train_acc: 0.9643\n", - "Epoch: 1079-------- \n", - "Loss: 0.0751 \n", - "Train_acc: 0.9643\n", - "Epoch: 1080-------- \n", - "Loss: 0.0750 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 1081-------- \n", - "Loss: 0.0749 \n", - "Train_acc: 0.9643\n", - "Epoch: 1082-------- \n", - "Loss: 0.0748 \n", - "Train_acc: 0.9643\n", - "Epoch: 1083-------- \n", - "Loss: 0.0747 \n", - "Train_acc: 0.9643\n", - "Epoch: 1084-------- \n", - "Loss: 0.0746 \n", - "Train_acc: 0.9643\n", - "Epoch: 1085-------- \n", - "Loss: 0.0745 \n", - "Train_acc: 0.9643\n", - "Epoch: 1086-------- \n", - "Loss: 0.0744 \n", - "Train_acc: 0.9643\n", - "Epoch: 1087-------- \n", - "Loss: 0.0743 \n", - "Train_acc: 0.9643\n", - "Epoch: 1088-------- \n", - "Loss: 0.0742 \n", - "Train_acc: 0.9643\n", - "Epoch: 1089-------- \n", - "Loss: 0.0741 \n", - "Train_acc: 0.9643\n", - "Epoch: 1090-------- \n", - "Loss: 0.0740 \n", - "Train_acc: 0.9643\n", - "Epoch: 1091-------- \n", - "Loss: 0.0739 \n", - "Train_acc: 0.9643\n", - "Epoch: 1092-------- \n", - "Loss: 0.0738 \n", - "Train_acc: 0.9643\n", - "Epoch: 1093-------- \n", - "Loss: 0.0737 \n", - "Train_acc: 0.9643\n", - "Epoch: 1094-------- \n", - "Loss: 0.0737 \n", - "Train_acc: 0.9643\n", - "Epoch: 1095-------- \n", - "Loss: 0.0736 \n", - "Train_acc: 0.9643\n", - "Epoch: 1096-------- \n", - "Loss: 0.0735 \n", - "Train_acc: 0.9643\n", - "Epoch: 1097-------- \n", - "Loss: 0.0734 \n", - "Train_acc: 0.9643\n", - "Epoch: 1098-------- \n", - "Loss: 0.0733 \n", - "Train_acc: 0.9643\n", - "Epoch: 1099-------- \n", - "Loss: 0.0732 \n", - "Train_acc: 0.9643\n", - "Epoch: 1100-------- \n", - "Loss: 0.0731 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 1101-------- \n", - "Loss: 0.0730 \n", - "Train_acc: 0.9643\n", - "Epoch: 1102-------- \n", - "Loss: 0.0729 \n", - "Train_acc: 0.9643\n", - "Epoch: 1103-------- \n", - "Loss: 0.0728 \n", - "Train_acc: 0.9643\n", - "Epoch: 1104-------- \n", - "Loss: 0.0727 \n", - "Train_acc: 0.9643\n", - "Epoch: 1105-------- \n", - "Loss: 0.0726 \n", - "Train_acc: 0.9643\n", - "Epoch: 1106-------- \n", - "Loss: 0.0725 \n", - "Train_acc: 0.9643\n", - "Epoch: 1107-------- \n", - "Loss: 0.0724 \n", - "Train_acc: 0.9643\n", - "Epoch: 1108-------- \n", - "Loss: 0.0724 \n", - "Train_acc: 0.9643\n", - "Epoch: 1109-------- \n", - "Loss: 0.0723 \n", - "Train_acc: 0.9643\n", - "Epoch: 1110-------- \n", - "Loss: 0.0722 \n", - "Train_acc: 0.9643\n", - "Epoch: 1111-------- \n", - "Loss: 0.0721 \n", - "Train_acc: 0.9643\n", - "Epoch: 1112-------- \n", - "Loss: 0.0720 \n", - "Train_acc: 0.9643\n", - "Epoch: 1113-------- \n", - "Loss: 0.0719 \n", - "Train_acc: 0.9643\n", - "Epoch: 1114-------- \n", - "Loss: 0.0718 \n", - "Train_acc: 0.9643\n", - "Epoch: 1115-------- \n", - "Loss: 0.0717 \n", - "Train_acc: 0.9643\n", - "Epoch: 1116-------- \n", - "Loss: 0.0716 \n", - "Train_acc: 0.9643\n", - "Epoch: 1117-------- \n", - "Loss: 0.0716 \n", - "Train_acc: 0.9643\n", - "Epoch: 1118-------- \n", - "Loss: 0.0715 \n", - "Train_acc: 0.9643\n", - "Epoch: 1119-------- \n", - "Loss: 0.0714 \n", - "Train_acc: 0.9643\n", - "Epoch: 1120-------- \n", - "Loss: 0.0713 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 1121-------- \n", - "Loss: 0.0712 \n", - "Train_acc: 0.9643\n", - "Epoch: 1122-------- \n", - "Loss: 0.0711 \n", - "Train_acc: 0.9643\n", - "Epoch: 1123-------- \n", - "Loss: 0.0710 \n", - "Train_acc: 0.9643\n", - "Epoch: 1124-------- \n", - "Loss: 0.0709 \n", - "Train_acc: 0.9643\n", - "Epoch: 1125-------- \n", - "Loss: 0.0709 \n", - "Train_acc: 0.9643\n", - "Epoch: 1126-------- \n", - "Loss: 0.0708 \n", - "Train_acc: 0.9643\n", - "Epoch: 1127-------- \n", - "Loss: 0.0707 \n", - "Train_acc: 0.9643\n", - "Epoch: 1128-------- \n", - "Loss: 0.0706 \n", - "Train_acc: 0.9643\n", - "Epoch: 1129-------- \n", - "Loss: 0.0705 \n", - "Train_acc: 0.9643\n", - "Epoch: 1130-------- \n", - "Loss: 0.0704 \n", - "Train_acc: 0.9643\n", - "Epoch: 1131-------- \n", - "Loss: 0.0703 \n", - "Train_acc: 0.9643\n", - "Epoch: 1132-------- \n", - "Loss: 0.0703 \n", - "Train_acc: 0.9643\n", - "Epoch: 1133-------- \n", - "Loss: 0.0702 \n", - "Train_acc: 0.9643\n", - "Epoch: 1134-------- \n", - "Loss: 0.0701 \n", - "Train_acc: 0.9643\n", - "Epoch: 1135-------- \n", - "Loss: 0.0700 \n", - "Train_acc: 0.9643\n", - "Epoch: 1136-------- \n", - "Loss: 0.0699 \n", - "Train_acc: 0.9643\n", - "Epoch: 1137-------- \n", - "Loss: 0.0698 \n", - "Train_acc: 0.9643\n", - "Epoch: 1138-------- \n", - "Loss: 0.0698 \n", - "Train_acc: 0.9643\n", - "Epoch: 1139-------- \n", - "Loss: 0.0697 \n", - "Train_acc: 0.9643\n", - "Epoch: 1140-------- \n", - "Loss: 0.0696 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 1141-------- \n", - "Loss: 0.0695 \n", - "Train_acc: 0.9643\n", - "Epoch: 1142-------- \n", - "Loss: 0.0694 \n", - "Train_acc: 0.9643\n", - "Epoch: 1143-------- \n", - "Loss: 0.0693 \n", - "Train_acc: 0.9643\n", - "Epoch: 1144-------- \n", - "Loss: 0.0693 \n", - "Train_acc: 0.9643\n", - "Epoch: 1145-------- \n", - "Loss: 0.0692 \n", - "Train_acc: 0.9643\n", - "Epoch: 1146-------- \n", - "Loss: 0.0691 \n", - "Train_acc: 0.9643\n", - "Epoch: 1147-------- \n", - "Loss: 0.0690 \n", - "Train_acc: 0.9643\n", - "Epoch: 1148-------- \n", - "Loss: 0.0689 \n", - "Train_acc: 0.9643\n", - "Epoch: 1149-------- \n", - "Loss: 0.0689 \n", - "Train_acc: 0.9643\n", - "Epoch: 1150-------- \n", - "Loss: 0.0688 \n", - "Train_acc: 0.9643\n", - "Epoch: 1151-------- \n", - "Loss: 0.0687 \n", - "Train_acc: 0.9643\n", - "Epoch: 1152-------- \n", - "Loss: 0.0686 \n", - "Train_acc: 0.9643\n", - "Epoch: 1153-------- \n", - "Loss: 0.0685 \n", - "Train_acc: 0.9643\n", - "Epoch: 1154-------- \n", - "Loss: 0.0685 \n", - "Train_acc: 0.9643\n", - "Epoch: 1155-------- \n", - "Loss: 0.0684 \n", - "Train_acc: 0.9643\n", - "Epoch: 1156-------- \n", - "Loss: 0.0683 \n", - "Train_acc: 0.9643\n", - "Epoch: 1157-------- \n", - "Loss: 0.0682 \n", - "Train_acc: 0.9643\n", - "Epoch: 1158-------- \n", - "Loss: 0.0681 \n", - "Train_acc: 0.9643\n", - "Epoch: 1159-------- \n", - "Loss: 0.0681 \n", - "Train_acc: 0.9643\n", - "Epoch: 1160-------- \n", - "Loss: 0.0680 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 1161-------- \n", - "Loss: 0.0679 \n", - "Train_acc: 0.9643\n", - "Epoch: 1162-------- \n", - "Loss: 0.0678 \n", - "Train_acc: 0.9643\n", - "Epoch: 1163-------- \n", - "Loss: 0.0677 \n", - "Train_acc: 0.9643\n", - "Epoch: 1164-------- \n", - "Loss: 0.0677 \n", - "Train_acc: 0.9643\n", - "Epoch: 1165-------- \n", - "Loss: 0.0676 \n", - "Train_acc: 0.9643\n", - "Epoch: 1166-------- \n", - "Loss: 0.0675 \n", - "Train_acc: 0.9643\n", - "Epoch: 1167-------- \n", - "Loss: 0.0674 \n", - "Train_acc: 0.9643\n", - "Epoch: 1168-------- \n", - "Loss: 0.0674 \n", - "Train_acc: 0.9643\n", - "Epoch: 1169-------- \n", - "Loss: 0.0673 \n", - "Train_acc: 0.9643\n", - "Epoch: 1170-------- \n", - "Loss: 0.0672 \n", - "Train_acc: 0.9643\n", - "Epoch: 1171-------- \n", - "Loss: 0.0671 \n", - "Train_acc: 0.9643\n", - "Epoch: 1172-------- \n", - "Loss: 0.0671 \n", - "Train_acc: 0.9643\n", - "Epoch: 1173-------- \n", - "Loss: 0.0670 \n", - "Train_acc: 0.9643\n", - "Epoch: 1174-------- \n", - "Loss: 0.0669 \n", - "Train_acc: 0.9643\n", - "Epoch: 1175-------- \n", - "Loss: 0.0668 \n", - "Train_acc: 0.9643\n", - "Epoch: 1176-------- \n", - "Loss: 0.0667 \n", - "Train_acc: 0.9643\n", - "Epoch: 1177-------- \n", - "Loss: 0.0667 \n", - "Train_acc: 0.9643\n", - "Epoch: 1178-------- \n", - "Loss: 0.0666 \n", - "Train_acc: 0.9643\n", - "Epoch: 1179-------- \n", - "Loss: 0.0665 \n", - "Train_acc: 0.9643\n", - "Epoch: 1180-------- \n", - "Loss: 0.0664 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 1181-------- \n", - "Loss: 0.0664 \n", - "Train_acc: 0.9643\n", - "Epoch: 1182-------- \n", - "Loss: 0.0663 \n", - "Train_acc: 0.9643\n", - "Epoch: 1183-------- \n", - "Loss: 0.0662 \n", - "Train_acc: 0.9643\n", - "Epoch: 1184-------- \n", - "Loss: 0.0662 \n", - "Train_acc: 0.9643\n", - "Epoch: 1185-------- \n", - "Loss: 0.0661 \n", - "Train_acc: 0.9643\n", - "Epoch: 1186-------- \n", - "Loss: 0.0660 \n", - "Train_acc: 0.9643\n", - "Epoch: 1187-------- \n", - "Loss: 0.0659 \n", - "Train_acc: 0.9643\n", - "Epoch: 1188-------- \n", - "Loss: 0.0659 \n", - "Train_acc: 0.9643\n", - "Epoch: 1189-------- \n", - "Loss: 0.0658 \n", - "Train_acc: 0.9643\n", - "Epoch: 1190-------- \n", - "Loss: 0.0657 \n", - "Train_acc: 0.9643\n", - "Epoch: 1191-------- \n", - "Loss: 0.0656 \n", - "Train_acc: 0.9643\n", - "Epoch: 1192-------- \n", - "Loss: 0.0656 \n", - "Train_acc: 0.9643\n", - "Epoch: 1193-------- \n", - "Loss: 0.0655 \n", - "Train_acc: 0.9643\n", - "Epoch: 1194-------- \n", - "Loss: 0.0654 \n", - "Train_acc: 0.9643\n", - "Epoch: 1195-------- \n", - "Loss: 0.0654 \n", - "Train_acc: 0.9643\n", - "Epoch: 1196-------- \n", - "Loss: 0.0653 \n", - "Train_acc: 0.9643\n", - "Epoch: 1197-------- \n", - "Loss: 0.0652 \n", - "Train_acc: 0.9643\n", - "Epoch: 1198-------- \n", - "Loss: 0.0651 \n", - "Train_acc: 0.9643\n", - "Epoch: 1199-------- \n", - "Loss: 0.0651 \n", - "Train_acc: 0.9643\n", - "Epoch: 1200-------- \n", - "Loss: 0.0650 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 1201-------- \n", - "Loss: 0.0649 \n", - "Train_acc: 0.9643\n", - "Epoch: 1202-------- \n", - "Loss: 0.0649 \n", - "Train_acc: 0.9643\n", - "Epoch: 1203-------- \n", - "Loss: 0.0648 \n", - "Train_acc: 0.9643\n", - "Epoch: 1204-------- \n", - "Loss: 0.0647 \n", - "Train_acc: 0.9643\n", - "Epoch: 1205-------- \n", - "Loss: 0.0646 \n", - "Train_acc: 0.9643\n", - "Epoch: 1206-------- \n", - "Loss: 0.0646 \n", - "Train_acc: 0.9643\n", - "Epoch: 1207-------- \n", - "Loss: 0.0645 \n", - "Train_acc: 0.9643\n", - "Epoch: 1208-------- \n", - "Loss: 0.0644 \n", - "Train_acc: 0.9643\n", - "Epoch: 1209-------- \n", - "Loss: 0.0644 \n", - "Train_acc: 0.9643\n", - "Epoch: 1210-------- \n", - "Loss: 0.0643 \n", - "Train_acc: 0.9643\n", - "Epoch: 1211-------- \n", - "Loss: 0.0642 \n", - "Train_acc: 0.9643\n", - "Epoch: 1212-------- \n", - "Loss: 0.0642 \n", - "Train_acc: 0.9643\n", - "Epoch: 1213-------- \n", - "Loss: 0.0641 \n", - "Train_acc: 0.9643\n", - "Epoch: 1214-------- \n", - "Loss: 0.0640 \n", - "Train_acc: 0.9643\n", - "Epoch: 1215-------- \n", - "Loss: 0.0640 \n", - "Train_acc: 0.9643\n", - "Epoch: 1216-------- \n", - "Loss: 0.0639 \n", - "Train_acc: 0.9643\n", - "Epoch: 1217-------- \n", - "Loss: 0.0638 \n", - "Train_acc: 0.9643\n", - "Epoch: 1218-------- \n", - "Loss: 0.0638 \n", - "Train_acc: 0.9643\n", - "Epoch: 1219-------- \n", - "Loss: 0.0637 \n", - "Train_acc: 0.9643\n", - "Epoch: 1220-------- \n", - "Loss: 0.0636 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 1221-------- \n", - "Loss: 0.0635 \n", - "Train_acc: 0.9643\n", - "Epoch: 1222-------- \n", - "Loss: 0.0635 \n", - "Train_acc: 0.9643\n", - "Epoch: 1223-------- \n", - "Loss: 0.0634 \n", - "Train_acc: 0.9643\n", - "Epoch: 1224-------- \n", - "Loss: 0.0633 \n", - "Train_acc: 0.9643\n", - "Epoch: 1225-------- \n", - "Loss: 0.0633 \n", - "Train_acc: 0.9643\n", - "Epoch: 1226-------- \n", - "Loss: 0.0632 \n", - "Train_acc: 0.9643\n", - "Epoch: 1227-------- \n", - "Loss: 0.0631 \n", - "Train_acc: 0.9643\n", - "Epoch: 1228-------- \n", - "Loss: 0.0631 \n", - "Train_acc: 0.9643\n", - "Epoch: 1229-------- \n", - "Loss: 0.0630 \n", - "Train_acc: 0.9643\n", - "Epoch: 1230-------- \n", - "Loss: 0.0629 \n", - "Train_acc: 0.9643\n", - "Epoch: 1231-------- \n", - "Loss: 0.0629 \n", - "Train_acc: 0.9643\n", - "Epoch: 1232-------- \n", - "Loss: 0.0628 \n", - "Train_acc: 0.9643\n", - "Epoch: 1233-------- \n", - "Loss: 0.0628 \n", - "Train_acc: 0.9643\n", - "Epoch: 1234-------- \n", - "Loss: 0.0627 \n", - "Train_acc: 0.9643\n", - "Epoch: 1235-------- \n", - "Loss: 0.0626 \n", - "Train_acc: 0.9643\n", - "Epoch: 1236-------- \n", - "Loss: 0.0626 \n", - "Train_acc: 0.9643\n", - "Epoch: 1237-------- \n", - "Loss: 0.0625 \n", - "Train_acc: 0.9643\n", - "Epoch: 1238-------- \n", - "Loss: 0.0624 \n", - "Train_acc: 0.9643\n", - "Epoch: 1239-------- \n", - "Loss: 0.0624 \n", - "Train_acc: 0.9643\n", - "Epoch: 1240-------- \n", - "Loss: 0.0623 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 1241-------- \n", - "Loss: 0.0622 \n", - "Train_acc: 0.9643\n", - "Epoch: 1242-------- \n", - "Loss: 0.0622 \n", - "Train_acc: 0.9643\n", - "Epoch: 1243-------- \n", - "Loss: 0.0621 \n", - "Train_acc: 0.9643\n", - "Epoch: 1244-------- \n", - "Loss: 0.0620 \n", - "Train_acc: 0.9643\n", - "Epoch: 1245-------- \n", - "Loss: 0.0620 \n", - "Train_acc: 0.9643\n", - "Epoch: 1246-------- \n", - "Loss: 0.0619 \n", - "Train_acc: 0.9643\n", - "Epoch: 1247-------- \n", - "Loss: 0.0619 \n", - "Train_acc: 0.9643\n", - "Epoch: 1248-------- \n", - "Loss: 0.0618 \n", - "Train_acc: 0.9643\n", - "Epoch: 1249-------- \n", - "Loss: 0.0617 \n", - "Train_acc: 0.9643\n", - "Epoch: 1250-------- \n", - "Loss: 0.0617 \n", - "Train_acc: 0.9643\n", - "Epoch: 1251-------- \n", - "Loss: 0.0616 \n", - "Train_acc: 0.9643\n", - "Epoch: 1252-------- \n", - "Loss: 0.0615 \n", - "Train_acc: 0.9643\n", - "Epoch: 1253-------- \n", - "Loss: 0.0615 \n", - "Train_acc: 0.9643\n", - "Epoch: 1254-------- \n", - "Loss: 0.0614 \n", - "Train_acc: 0.9643\n", - "Epoch: 1255-------- \n", - "Loss: 0.0613 \n", - "Train_acc: 0.9643\n", - "Epoch: 1256-------- \n", - "Loss: 0.0613 \n", - "Train_acc: 0.9643\n", - "Epoch: 1257-------- \n", - "Loss: 0.0612 \n", - "Train_acc: 0.9643\n", - "Epoch: 1258-------- \n", - "Loss: 0.0612 \n", - "Train_acc: 0.9643\n", - "Epoch: 1259-------- \n", - "Loss: 0.0611 \n", - "Train_acc: 0.9643\n", - "Epoch: 1260-------- \n", - "Loss: 0.0610 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 1261-------- \n", - "Loss: 0.0610 \n", - "Train_acc: 0.9643\n", - "Epoch: 1262-------- \n", - "Loss: 0.0609 \n", - "Train_acc: 0.9643\n", - "Epoch: 1263-------- \n", - "Loss: 0.0609 \n", - "Train_acc: 0.9643\n", - "Epoch: 1264-------- \n", - "Loss: 0.0608 \n", - "Train_acc: 0.9643\n", - "Epoch: 1265-------- \n", - "Loss: 0.0607 \n", - "Train_acc: 0.9643\n", - "Epoch: 1266-------- \n", - "Loss: 0.0607 \n", - "Train_acc: 0.9643\n", - "Epoch: 1267-------- \n", - "Loss: 0.0606 \n", - "Train_acc: 0.9643\n", - "Epoch: 1268-------- \n", - "Loss: 0.0606 \n", - "Train_acc: 0.9643\n", - "Epoch: 1269-------- \n", - "Loss: 0.0605 \n", - "Train_acc: 0.9643\n", - "Epoch: 1270-------- \n", - "Loss: 0.0604 \n", - "Train_acc: 0.9643\n", - "Epoch: 1271-------- \n", - "Loss: 0.0604 \n", - "Train_acc: 0.9643\n", - "Epoch: 1272-------- \n", - "Loss: 0.0603 \n", - "Train_acc: 0.9643\n", - "Epoch: 1273-------- \n", - "Loss: 0.0603 \n", - "Train_acc: 0.9643\n", - "Epoch: 1274-------- \n", - "Loss: 0.0602 \n", - "Train_acc: 0.9643\n", - "Epoch: 1275-------- \n", - "Loss: 0.0601 \n", - "Train_acc: 0.9643\n", - "Epoch: 1276-------- \n", - "Loss: 0.0601 \n", - "Train_acc: 0.9643\n", - "Epoch: 1277-------- \n", - "Loss: 0.0600 \n", - "Train_acc: 0.9643\n", - "Epoch: 1278-------- \n", - "Loss: 0.0600 \n", - "Train_acc: 0.9643\n", - "Epoch: 1279-------- \n", - "Loss: 0.0599 \n", - "Train_acc: 0.9643\n", - "Epoch: 1280-------- \n", - "Loss: 0.0598 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 1281-------- \n", - "Loss: 0.0598 \n", - "Train_acc: 0.9643\n", - "Epoch: 1282-------- \n", - "Loss: 0.0597 \n", - "Train_acc: 0.9643\n", - "Epoch: 1283-------- \n", - "Loss: 0.0597 \n", - "Train_acc: 0.9643\n", - "Epoch: 1284-------- \n", - "Loss: 0.0596 \n", - "Train_acc: 0.9643\n", - "Epoch: 1285-------- \n", - "Loss: 0.0595 \n", - "Train_acc: 0.9643\n", - "Epoch: 1286-------- \n", - "Loss: 0.0595 \n", - "Train_acc: 0.9643\n", - "Epoch: 1287-------- \n", - "Loss: 0.0594 \n", - "Train_acc: 0.9643\n", - "Epoch: 1288-------- \n", - "Loss: 0.0594 \n", - "Train_acc: 0.9643\n", - "Epoch: 1289-------- \n", - "Loss: 0.0593 \n", - "Train_acc: 0.9643\n", - "Epoch: 1290-------- \n", - "Loss: 0.0593 \n", - "Train_acc: 0.9643\n", - "Epoch: 1291-------- \n", - "Loss: 0.0592 \n", - "Train_acc: 0.9643\n", - "Epoch: 1292-------- \n", - "Loss: 0.0591 \n", - "Train_acc: 0.9643\n", - "Epoch: 1293-------- \n", - "Loss: 0.0591 \n", - "Train_acc: 0.9643\n", - "Epoch: 1294-------- \n", - "Loss: 0.0590 \n", - "Train_acc: 0.9643\n", - "Epoch: 1295-------- \n", - "Loss: 0.0590 \n", - "Train_acc: 0.9643\n", - "Epoch: 1296-------- \n", - "Loss: 0.0589 \n", - "Train_acc: 0.9643\n", - "Epoch: 1297-------- \n", - "Loss: 0.0589 \n", - "Train_acc: 0.9643\n", - "Epoch: 1298-------- \n", - "Loss: 0.0588 \n", - "Train_acc: 0.9643\n", - "Epoch: 1299-------- \n", - "Loss: 0.0587 \n", - "Train_acc: 0.9643\n", - "Epoch: 1300-------- \n", - "Loss: 0.0587 \n", - "Train_acc: 0.9643\n", - "Test_acc: 1.0000\n", - "Epoch: 1301-------- \n", - "Loss: 0.0586 \n", - "Train_acc: 0.9643\n", - "Epoch: 1302-------- \n", - "Loss: 0.0586 \n", - "Train_acc: 0.9643\n", - "Epoch: 1303-------- \n", - "Loss: 0.0585 \n", - "Train_acc: 0.9643\n", - "Epoch: 1304-------- \n", - "Loss: 0.0585 \n", - "Train_acc: 0.9643\n", - "Epoch: 1305-------- \n", - "Loss: 0.0584 \n", - "Train_acc: 0.9643\n", - "Epoch: 1306-------- \n", - "Loss: 0.0583 \n", - "Train_acc: 0.9643\n", - "Epoch: 1307-------- \n", - "Loss: 0.0583 \n", - "Train_acc: 0.9643\n", - "Epoch: 1308-------- \n", - "Loss: 0.0582 \n", - "Train_acc: 0.9643\n", - "Epoch: 1309-------- \n", - "Loss: 0.0582 \n", - "Train_acc: 0.9643\n", - "Epoch: 1310-------- \n", - "Loss: 0.0581 \n", - "Train_acc: 0.9643\n", - "Epoch: 1311-------- \n", - "Loss: 0.0581 \n", - "Train_acc: 0.9643\n", - "Epoch: 1312-------- \n", - "Loss: 0.0580 \n", - "Train_acc: 0.9643\n", - "Epoch: 1313-------- \n", - "Loss: 0.0580 \n", - "Train_acc: 1.0000\n", - "Epoch: 1314-------- \n", - "Loss: 0.0579 \n", - "Train_acc: 1.0000\n", - "Epoch: 1315-------- \n", - "Loss: 0.0578 \n", - "Train_acc: 1.0000\n", - "Epoch: 1316-------- \n", - "Loss: 0.0578 \n", - "Train_acc: 1.0000\n", - "Epoch: 1317-------- \n", - "Loss: 0.0577 \n", - "Train_acc: 1.0000\n", - "Epoch: 1318-------- \n", - "Loss: 0.0577 \n", - "Train_acc: 1.0000\n", - "Epoch: 1319-------- \n", - "Loss: 0.0576 \n", - "Train_acc: 1.0000\n", - "Epoch: 1320-------- \n", - "Loss: 0.0576 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1321-------- \n", - "Loss: 0.0575 \n", - "Train_acc: 1.0000\n", - "Epoch: 1322-------- \n", - "Loss: 0.0575 \n", - "Train_acc: 1.0000\n", - "Epoch: 1323-------- \n", - "Loss: 0.0574 \n", - "Train_acc: 1.0000\n", - "Epoch: 1324-------- \n", - "Loss: 0.0574 \n", - "Train_acc: 1.0000\n", - "Epoch: 1325-------- \n", - "Loss: 0.0573 \n", - "Train_acc: 1.0000\n", - "Epoch: 1326-------- \n", - "Loss: 0.0573 \n", - "Train_acc: 1.0000\n", - "Epoch: 1327-------- \n", - "Loss: 0.0572 \n", - "Train_acc: 1.0000\n", - "Epoch: 1328-------- \n", - "Loss: 0.0571 \n", - "Train_acc: 1.0000\n", - "Epoch: 1329-------- \n", - "Loss: 0.0571 \n", - "Train_acc: 1.0000\n", - "Epoch: 1330-------- \n", - "Loss: 0.0570 \n", - "Train_acc: 1.0000\n", - "Epoch: 1331-------- \n", - "Loss: 0.0570 \n", - "Train_acc: 1.0000\n", - "Epoch: 1332-------- \n", - "Loss: 0.0569 \n", - "Train_acc: 1.0000\n", - "Epoch: 1333-------- \n", - "Loss: 0.0569 \n", - "Train_acc: 1.0000\n", - "Epoch: 1334-------- \n", - "Loss: 0.0568 \n", - "Train_acc: 1.0000\n", - "Epoch: 1335-------- \n", - "Loss: 0.0568 \n", - "Train_acc: 1.0000\n", - "Epoch: 1336-------- \n", - "Loss: 0.0567 \n", - "Train_acc: 1.0000\n", - "Epoch: 1337-------- \n", - "Loss: 0.0567 \n", - "Train_acc: 1.0000\n", - "Epoch: 1338-------- \n", - "Loss: 0.0566 \n", - "Train_acc: 1.0000\n", - "Epoch: 1339-------- \n", - "Loss: 0.0566 \n", - "Train_acc: 1.0000\n", - "Epoch: 1340-------- \n", - "Loss: 0.0565 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1341-------- \n", - "Loss: 0.0565 \n", - "Train_acc: 1.0000\n", - "Epoch: 1342-------- \n", - "Loss: 0.0564 \n", - "Train_acc: 1.0000\n", - "Epoch: 1343-------- \n", - "Loss: 0.0564 \n", - "Train_acc: 1.0000\n", - "Epoch: 1344-------- \n", - "Loss: 0.0563 \n", - "Train_acc: 1.0000\n", - "Epoch: 1345-------- \n", - "Loss: 0.0563 \n", - "Train_acc: 1.0000\n", - "Epoch: 1346-------- \n", - "Loss: 0.0562 \n", - "Train_acc: 1.0000\n", - "Epoch: 1347-------- \n", - "Loss: 0.0562 \n", - "Train_acc: 1.0000\n", - "Epoch: 1348-------- \n", - "Loss: 0.0561 \n", - "Train_acc: 1.0000\n", - "Epoch: 1349-------- \n", - "Loss: 0.0560 \n", - "Train_acc: 1.0000\n", - "Epoch: 1350-------- \n", - "Loss: 0.0560 \n", - "Train_acc: 1.0000\n", - "Epoch: 1351-------- \n", - "Loss: 0.0559 \n", - "Train_acc: 1.0000\n", - "Epoch: 1352-------- \n", - "Loss: 0.0559 \n", - "Train_acc: 1.0000\n", - "Epoch: 1353-------- \n", - "Loss: 0.0558 \n", - "Train_acc: 1.0000\n", - "Epoch: 1354-------- \n", - "Loss: 0.0558 \n", - "Train_acc: 1.0000\n", - "Epoch: 1355-------- \n", - "Loss: 0.0557 \n", - "Train_acc: 1.0000\n", - "Epoch: 1356-------- \n", - "Loss: 0.0557 \n", - "Train_acc: 1.0000\n", - "Epoch: 1357-------- \n", - "Loss: 0.0556 \n", - "Train_acc: 1.0000\n", - "Epoch: 1358-------- \n", - "Loss: 0.0556 \n", - "Train_acc: 1.0000\n", - "Epoch: 1359-------- \n", - "Loss: 0.0555 \n", - "Train_acc: 1.0000\n", - "Epoch: 1360-------- \n", - "Loss: 0.0555 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1361-------- \n", - "Loss: 0.0554 \n", - "Train_acc: 1.0000\n", - "Epoch: 1362-------- \n", - "Loss: 0.0554 \n", - "Train_acc: 1.0000\n", - "Epoch: 1363-------- \n", - "Loss: 0.0553 \n", - "Train_acc: 1.0000\n", - "Epoch: 1364-------- \n", - "Loss: 0.0553 \n", - "Train_acc: 1.0000\n", - "Epoch: 1365-------- \n", - "Loss: 0.0552 \n", - "Train_acc: 1.0000\n", - "Epoch: 1366-------- \n", - "Loss: 0.0552 \n", - "Train_acc: 1.0000\n", - "Epoch: 1367-------- \n", - "Loss: 0.0551 \n", - "Train_acc: 1.0000\n", - "Epoch: 1368-------- \n", - "Loss: 0.0551 \n", - "Train_acc: 1.0000\n", - "Epoch: 1369-------- \n", - "Loss: 0.0550 \n", - "Train_acc: 1.0000\n", - "Epoch: 1370-------- \n", - "Loss: 0.0550 \n", - "Train_acc: 1.0000\n", - "Epoch: 1371-------- \n", - "Loss: 0.0549 \n", - "Train_acc: 1.0000\n", - "Epoch: 1372-------- \n", - "Loss: 0.0549 \n", - "Train_acc: 1.0000\n", - "Epoch: 1373-------- \n", - "Loss: 0.0548 \n", - "Train_acc: 1.0000\n", - "Epoch: 1374-------- \n", - "Loss: 0.0548 \n", - "Train_acc: 1.0000\n", - "Epoch: 1375-------- \n", - "Loss: 0.0548 \n", - "Train_acc: 1.0000\n", - "Epoch: 1376-------- \n", - "Loss: 0.0547 \n", - "Train_acc: 1.0000\n", - "Epoch: 1377-------- \n", - "Loss: 0.0547 \n", - "Train_acc: 1.0000\n", - "Epoch: 1378-------- \n", - "Loss: 0.0546 \n", - "Train_acc: 1.0000\n", - "Epoch: 1379-------- \n", - "Loss: 0.0546 \n", - "Train_acc: 1.0000\n", - "Epoch: 1380-------- \n", - "Loss: 0.0545 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1381-------- \n", - "Loss: 0.0545 \n", - "Train_acc: 1.0000\n", - "Epoch: 1382-------- \n", - "Loss: 0.0544 \n", - "Train_acc: 1.0000\n", - "Epoch: 1383-------- \n", - "Loss: 0.0544 \n", - "Train_acc: 1.0000\n", - "Epoch: 1384-------- \n", - "Loss: 0.0543 \n", - "Train_acc: 1.0000\n", - "Epoch: 1385-------- \n", - "Loss: 0.0543 \n", - "Train_acc: 1.0000\n", - "Epoch: 1386-------- \n", - "Loss: 0.0542 \n", - "Train_acc: 1.0000\n", - "Epoch: 1387-------- \n", - "Loss: 0.0542 \n", - "Train_acc: 1.0000\n", - "Epoch: 1388-------- \n", - "Loss: 0.0541 \n", - "Train_acc: 1.0000\n", - "Epoch: 1389-------- \n", - "Loss: 0.0541 \n", - "Train_acc: 1.0000\n", - "Epoch: 1390-------- \n", - "Loss: 0.0540 \n", - "Train_acc: 1.0000\n", - "Epoch: 1391-------- \n", - "Loss: 0.0540 \n", - "Train_acc: 1.0000\n", - "Epoch: 1392-------- \n", - "Loss: 0.0539 \n", - "Train_acc: 1.0000\n", - "Epoch: 1393-------- \n", - "Loss: 0.0539 \n", - "Train_acc: 1.0000\n", - "Epoch: 1394-------- \n", - "Loss: 0.0538 \n", - "Train_acc: 1.0000\n", - "Epoch: 1395-------- \n", - "Loss: 0.0538 \n", - "Train_acc: 1.0000\n", - "Epoch: 1396-------- \n", - "Loss: 0.0537 \n", - "Train_acc: 1.0000\n", - "Epoch: 1397-------- \n", - "Loss: 0.0537 \n", - "Train_acc: 1.0000\n", - "Epoch: 1398-------- \n", - "Loss: 0.0537 \n", - "Train_acc: 1.0000\n", - "Epoch: 1399-------- \n", - "Loss: 0.0536 \n", - "Train_acc: 1.0000\n", - "Epoch: 1400-------- \n", - "Loss: 0.0536 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1401-------- \n", - "Loss: 0.0535 \n", - "Train_acc: 1.0000\n", - "Epoch: 1402-------- \n", - "Loss: 0.0535 \n", - "Train_acc: 1.0000\n", - "Epoch: 1403-------- \n", - "Loss: 0.0534 \n", - "Train_acc: 1.0000\n", - "Epoch: 1404-------- \n", - "Loss: 0.0534 \n", - "Train_acc: 1.0000\n", - "Epoch: 1405-------- \n", - "Loss: 0.0533 \n", - "Train_acc: 1.0000\n", - "Epoch: 1406-------- \n", - "Loss: 0.0533 \n", - "Train_acc: 1.0000\n", - "Epoch: 1407-------- \n", - "Loss: 0.0532 \n", - "Train_acc: 1.0000\n", - "Epoch: 1408-------- \n", - "Loss: 0.0532 \n", - "Train_acc: 1.0000\n", - "Epoch: 1409-------- \n", - "Loss: 0.0531 \n", - "Train_acc: 1.0000\n", - "Epoch: 1410-------- \n", - "Loss: 0.0531 \n", - "Train_acc: 1.0000\n", - "Epoch: 1411-------- \n", - "Loss: 0.0530 \n", - "Train_acc: 1.0000\n", - "Epoch: 1412-------- \n", - "Loss: 0.0530 \n", - "Train_acc: 1.0000\n", - "Epoch: 1413-------- \n", - "Loss: 0.0530 \n", - "Train_acc: 1.0000\n", - "Epoch: 1414-------- \n", - "Loss: 0.0529 \n", - "Train_acc: 1.0000\n", - "Epoch: 1415-------- \n", - "Loss: 0.0529 \n", - "Train_acc: 1.0000\n", - "Epoch: 1416-------- \n", - "Loss: 0.0528 \n", - "Train_acc: 1.0000\n", - "Epoch: 1417-------- \n", - "Loss: 0.0528 \n", - "Train_acc: 1.0000\n", - "Epoch: 1418-------- \n", - "Loss: 0.0527 \n", - "Train_acc: 1.0000\n", - "Epoch: 1419-------- \n", - "Loss: 0.0527 \n", - "Train_acc: 1.0000\n", - "Epoch: 1420-------- \n", - "Loss: 0.0526 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1421-------- \n", - "Loss: 0.0526 \n", - "Train_acc: 1.0000\n", - "Epoch: 1422-------- \n", - "Loss: 0.0526 \n", - "Train_acc: 1.0000\n", - "Epoch: 1423-------- \n", - "Loss: 0.0525 \n", - "Train_acc: 1.0000\n", - "Epoch: 1424-------- \n", - "Loss: 0.0525 \n", - "Train_acc: 1.0000\n", - "Epoch: 1425-------- \n", - "Loss: 0.0524 \n", - "Train_acc: 1.0000\n", - "Epoch: 1426-------- \n", - "Loss: 0.0524 \n", - "Train_acc: 1.0000\n", - "Epoch: 1427-------- \n", - "Loss: 0.0523 \n", - "Train_acc: 1.0000\n", - "Epoch: 1428-------- \n", - "Loss: 0.0523 \n", - "Train_acc: 1.0000\n", - "Epoch: 1429-------- \n", - "Loss: 0.0522 \n", - "Train_acc: 1.0000\n", - "Epoch: 1430-------- \n", - "Loss: 0.0522 \n", - "Train_acc: 1.0000\n", - "Epoch: 1431-------- \n", - "Loss: 0.0522 \n", - "Train_acc: 1.0000\n", - "Epoch: 1432-------- \n", - "Loss: 0.0521 \n", - "Train_acc: 1.0000\n", - "Epoch: 1433-------- \n", - "Loss: 0.0521 \n", - "Train_acc: 1.0000\n", - "Epoch: 1434-------- \n", - "Loss: 0.0520 \n", - "Train_acc: 1.0000\n", - "Epoch: 1435-------- \n", - "Loss: 0.0520 \n", - "Train_acc: 1.0000\n", - "Epoch: 1436-------- \n", - "Loss: 0.0519 \n", - "Train_acc: 1.0000\n", - "Epoch: 1437-------- \n", - "Loss: 0.0519 \n", - "Train_acc: 1.0000\n", - "Epoch: 1438-------- \n", - "Loss: 0.0518 \n", - "Train_acc: 1.0000\n", - "Epoch: 1439-------- \n", - "Loss: 0.0518 \n", - "Train_acc: 1.0000\n", - "Epoch: 1440-------- \n", - "Loss: 0.0518 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1441-------- \n", - "Loss: 0.0517 \n", - "Train_acc: 1.0000\n", - "Epoch: 1442-------- \n", - "Loss: 0.0517 \n", - "Train_acc: 1.0000\n", - "Epoch: 1443-------- \n", - "Loss: 0.0516 \n", - "Train_acc: 1.0000\n", - "Epoch: 1444-------- \n", - "Loss: 0.0516 \n", - "Train_acc: 1.0000\n", - "Epoch: 1445-------- \n", - "Loss: 0.0515 \n", - "Train_acc: 1.0000\n", - "Epoch: 1446-------- \n", - "Loss: 0.0515 \n", - "Train_acc: 1.0000\n", - "Epoch: 1447-------- \n", - "Loss: 0.0515 \n", - "Train_acc: 1.0000\n", - "Epoch: 1448-------- \n", - "Loss: 0.0514 \n", - "Train_acc: 1.0000\n", - "Epoch: 1449-------- \n", - "Loss: 0.0514 \n", - "Train_acc: 1.0000\n", - "Epoch: 1450-------- \n", - "Loss: 0.0513 \n", - "Train_acc: 1.0000\n", - "Epoch: 1451-------- \n", - "Loss: 0.0513 \n", - "Train_acc: 1.0000\n", - "Epoch: 1452-------- \n", - "Loss: 0.0512 \n", - "Train_acc: 1.0000\n", - "Epoch: 1453-------- \n", - "Loss: 0.0512 \n", - "Train_acc: 1.0000\n", - "Epoch: 1454-------- \n", - "Loss: 0.0512 \n", - "Train_acc: 1.0000\n", - "Epoch: 1455-------- \n", - "Loss: 0.0511 \n", - "Train_acc: 1.0000\n", - "Epoch: 1456-------- \n", - "Loss: 0.0511 \n", - "Train_acc: 1.0000\n", - "Epoch: 1457-------- \n", - "Loss: 0.0510 \n", - "Train_acc: 1.0000\n", - "Epoch: 1458-------- \n", - "Loss: 0.0510 \n", - "Train_acc: 1.0000\n", - "Epoch: 1459-------- \n", - "Loss: 0.0509 \n", - "Train_acc: 1.0000\n", - "Epoch: 1460-------- \n", - "Loss: 0.0509 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1461-------- \n", - "Loss: 0.0509 \n", - "Train_acc: 1.0000\n", - "Epoch: 1462-------- \n", - "Loss: 0.0508 \n", - "Train_acc: 1.0000\n", - "Epoch: 1463-------- \n", - "Loss: 0.0508 \n", - "Train_acc: 1.0000\n", - "Epoch: 1464-------- \n", - "Loss: 0.0507 \n", - "Train_acc: 1.0000\n", - "Epoch: 1465-------- \n", - "Loss: 0.0507 \n", - "Train_acc: 1.0000\n", - "Epoch: 1466-------- \n", - "Loss: 0.0506 \n", - "Train_acc: 1.0000\n", - "Epoch: 1467-------- \n", - "Loss: 0.0506 \n", - "Train_acc: 1.0000\n", - "Epoch: 1468-------- \n", - "Loss: 0.0506 \n", - "Train_acc: 1.0000\n", - "Epoch: 1469-------- \n", - "Loss: 0.0505 \n", - "Train_acc: 1.0000\n", - "Epoch: 1470-------- \n", - "Loss: 0.0505 \n", - "Train_acc: 1.0000\n", - "Epoch: 1471-------- \n", - "Loss: 0.0504 \n", - "Train_acc: 1.0000\n", - "Epoch: 1472-------- \n", - "Loss: 0.0504 \n", - "Train_acc: 1.0000\n", - "Epoch: 1473-------- \n", - "Loss: 0.0504 \n", - "Train_acc: 1.0000\n", - "Epoch: 1474-------- \n", - "Loss: 0.0503 \n", - "Train_acc: 1.0000\n", - "Epoch: 1475-------- \n", - "Loss: 0.0503 \n", - "Train_acc: 1.0000\n", - "Epoch: 1476-------- \n", - "Loss: 0.0502 \n", - "Train_acc: 1.0000\n", - "Epoch: 1477-------- \n", - "Loss: 0.0502 \n", - "Train_acc: 1.0000\n", - "Epoch: 1478-------- \n", - "Loss: 0.0501 \n", - "Train_acc: 1.0000\n", - "Epoch: 1479-------- \n", - "Loss: 0.0501 \n", - "Train_acc: 1.0000\n", - "Epoch: 1480-------- \n", - "Loss: 0.0501 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1481-------- \n", - "Loss: 0.0500 \n", - "Train_acc: 1.0000\n", - "Epoch: 1482-------- \n", - "Loss: 0.0500 \n", - "Train_acc: 1.0000\n", - "Epoch: 1483-------- \n", - "Loss: 0.0499 \n", - "Train_acc: 1.0000\n", - "Epoch: 1484-------- \n", - "Loss: 0.0499 \n", - "Train_acc: 1.0000\n", - "Epoch: 1485-------- \n", - "Loss: 0.0499 \n", - "Train_acc: 1.0000\n", - "Epoch: 1486-------- \n", - "Loss: 0.0498 \n", - "Train_acc: 1.0000\n", - "Epoch: 1487-------- \n", - "Loss: 0.0498 \n", - "Train_acc: 1.0000\n", - "Epoch: 1488-------- \n", - "Loss: 0.0497 \n", - "Train_acc: 1.0000\n", - "Epoch: 1489-------- \n", - "Loss: 0.0497 \n", - "Train_acc: 1.0000\n", - "Epoch: 1490-------- \n", - "Loss: 0.0497 \n", - "Train_acc: 1.0000\n", - "Epoch: 1491-------- \n", - "Loss: 0.0496 \n", - "Train_acc: 1.0000\n", - "Epoch: 1492-------- \n", - "Loss: 0.0496 \n", - "Train_acc: 1.0000\n", - "Epoch: 1493-------- \n", - "Loss: 0.0495 \n", - "Train_acc: 1.0000\n", - "Epoch: 1494-------- \n", - "Loss: 0.0495 \n", - "Train_acc: 1.0000\n", - "Epoch: 1495-------- \n", - "Loss: 0.0495 \n", - "Train_acc: 1.0000\n", - "Epoch: 1496-------- \n", - "Loss: 0.0494 \n", - "Train_acc: 1.0000\n", - "Epoch: 1497-------- \n", - "Loss: 0.0494 \n", - "Train_acc: 1.0000\n", - "Epoch: 1498-------- \n", - "Loss: 0.0493 \n", - "Train_acc: 1.0000\n", - "Epoch: 1499-------- \n", - "Loss: 0.0493 \n", - "Train_acc: 1.0000\n", - "Epoch: 1500-------- \n", - "Loss: 0.0493 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1501-------- \n", - "Loss: 0.0492 \n", - "Train_acc: 1.0000\n", - "Epoch: 1502-------- \n", - "Loss: 0.0492 \n", - "Train_acc: 1.0000\n", - "Epoch: 1503-------- \n", - "Loss: 0.0491 \n", - "Train_acc: 1.0000\n", - "Epoch: 1504-------- \n", - "Loss: 0.0491 \n", - "Train_acc: 1.0000\n", - "Epoch: 1505-------- \n", - "Loss: 0.0491 \n", - "Train_acc: 1.0000\n", - "Epoch: 1506-------- \n", - "Loss: 0.0490 \n", - "Train_acc: 1.0000\n", - "Epoch: 1507-------- \n", - "Loss: 0.0490 \n", - "Train_acc: 1.0000\n", - "Epoch: 1508-------- \n", - "Loss: 0.0489 \n", - "Train_acc: 1.0000\n", - "Epoch: 1509-------- \n", - "Loss: 0.0489 \n", - "Train_acc: 1.0000\n", - "Epoch: 1510-------- \n", - "Loss: 0.0489 \n", - "Train_acc: 1.0000\n", - "Epoch: 1511-------- \n", - "Loss: 0.0488 \n", - "Train_acc: 1.0000\n", - "Epoch: 1512-------- \n", - "Loss: 0.0488 \n", - "Train_acc: 1.0000\n", - "Epoch: 1513-------- \n", - "Loss: 0.0488 \n", - "Train_acc: 1.0000\n", - "Epoch: 1514-------- \n", - "Loss: 0.0487 \n", - "Train_acc: 1.0000\n", - "Epoch: 1515-------- \n", - "Loss: 0.0487 \n", - "Train_acc: 1.0000\n", - "Epoch: 1516-------- \n", - "Loss: 0.0486 \n", - "Train_acc: 1.0000\n", - "Epoch: 1517-------- \n", - "Loss: 0.0486 \n", - "Train_acc: 1.0000\n", - "Epoch: 1518-------- \n", - "Loss: 0.0486 \n", - "Train_acc: 1.0000\n", - "Epoch: 1519-------- \n", - "Loss: 0.0485 \n", - "Train_acc: 1.0000\n", - "Epoch: 1520-------- \n", - "Loss: 0.0485 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1521-------- \n", - "Loss: 0.0484 \n", - "Train_acc: 1.0000\n", - "Epoch: 1522-------- \n", - "Loss: 0.0484 \n", - "Train_acc: 1.0000\n", - "Epoch: 1523-------- \n", - "Loss: 0.0484 \n", - "Train_acc: 1.0000\n", - "Epoch: 1524-------- \n", - "Loss: 0.0483 \n", - "Train_acc: 1.0000\n", - "Epoch: 1525-------- \n", - "Loss: 0.0483 \n", - "Train_acc: 1.0000\n", - "Epoch: 1526-------- \n", - "Loss: 0.0482 \n", - "Train_acc: 1.0000\n", - "Epoch: 1527-------- \n", - "Loss: 0.0482 \n", - "Train_acc: 1.0000\n", - "Epoch: 1528-------- \n", - "Loss: 0.0482 \n", - "Train_acc: 1.0000\n", - "Epoch: 1529-------- \n", - "Loss: 0.0481 \n", - "Train_acc: 1.0000\n", - "Epoch: 1530-------- \n", - "Loss: 0.0481 \n", - "Train_acc: 1.0000\n", - "Epoch: 1531-------- \n", - "Loss: 0.0481 \n", - "Train_acc: 1.0000\n", - "Epoch: 1532-------- \n", - "Loss: 0.0480 \n", - "Train_acc: 1.0000\n", - "Epoch: 1533-------- \n", - "Loss: 0.0480 \n", - "Train_acc: 1.0000\n", - "Epoch: 1534-------- \n", - "Loss: 0.0479 \n", - "Train_acc: 1.0000\n", - "Epoch: 1535-------- \n", - "Loss: 0.0479 \n", - "Train_acc: 1.0000\n", - "Epoch: 1536-------- \n", - "Loss: 0.0479 \n", - "Train_acc: 1.0000\n", - "Epoch: 1537-------- \n", - "Loss: 0.0478 \n", - "Train_acc: 1.0000\n", - "Epoch: 1538-------- \n", - "Loss: 0.0478 \n", - "Train_acc: 1.0000\n", - "Epoch: 1539-------- \n", - "Loss: 0.0478 \n", - "Train_acc: 1.0000\n", - "Epoch: 1540-------- \n", - "Loss: 0.0477 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1541-------- \n", - "Loss: 0.0477 \n", - "Train_acc: 1.0000\n", - "Epoch: 1542-------- \n", - "Loss: 0.0476 \n", - "Train_acc: 1.0000\n", - "Epoch: 1543-------- \n", - "Loss: 0.0476 \n", - "Train_acc: 1.0000\n", - "Epoch: 1544-------- \n", - "Loss: 0.0476 \n", - "Train_acc: 1.0000\n", - "Epoch: 1545-------- \n", - "Loss: 0.0475 \n", - "Train_acc: 1.0000\n", - "Epoch: 1546-------- \n", - "Loss: 0.0475 \n", - "Train_acc: 1.0000\n", - "Epoch: 1547-------- \n", - "Loss: 0.0475 \n", - "Train_acc: 1.0000\n", - "Epoch: 1548-------- \n", - "Loss: 0.0474 \n", - "Train_acc: 1.0000\n", - "Epoch: 1549-------- \n", - "Loss: 0.0474 \n", - "Train_acc: 1.0000\n", - "Epoch: 1550-------- \n", - "Loss: 0.0473 \n", - "Train_acc: 1.0000\n", - "Epoch: 1551-------- \n", - "Loss: 0.0473 \n", - "Train_acc: 1.0000\n", - "Epoch: 1552-------- \n", - "Loss: 0.0473 \n", - "Train_acc: 1.0000\n", - "Epoch: 1553-------- \n", - "Loss: 0.0472 \n", - "Train_acc: 1.0000\n", - "Epoch: 1554-------- \n", - "Loss: 0.0472 \n", - "Train_acc: 1.0000\n", - "Epoch: 1555-------- \n", - "Loss: 0.0472 \n", - "Train_acc: 1.0000\n", - "Epoch: 1556-------- \n", - "Loss: 0.0471 \n", - "Train_acc: 1.0000\n", - "Epoch: 1557-------- \n", - "Loss: 0.0471 \n", - "Train_acc: 1.0000\n", - "Epoch: 1558-------- \n", - "Loss: 0.0471 \n", - "Train_acc: 1.0000\n", - "Epoch: 1559-------- \n", - "Loss: 0.0470 \n", - "Train_acc: 1.0000\n", - "Epoch: 1560-------- \n", - "Loss: 0.0470 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1561-------- \n", - "Loss: 0.0469 \n", - "Train_acc: 1.0000\n", - "Epoch: 1562-------- \n", - "Loss: 0.0469 \n", - "Train_acc: 1.0000\n", - "Epoch: 1563-------- \n", - "Loss: 0.0469 \n", - "Train_acc: 1.0000\n", - "Epoch: 1564-------- \n", - "Loss: 0.0468 \n", - "Train_acc: 1.0000\n", - "Epoch: 1565-------- \n", - "Loss: 0.0468 \n", - "Train_acc: 1.0000\n", - "Epoch: 1566-------- \n", - "Loss: 0.0468 \n", - "Train_acc: 1.0000\n", - "Epoch: 1567-------- \n", - "Loss: 0.0467 \n", - "Train_acc: 1.0000\n", - "Epoch: 1568-------- \n", - "Loss: 0.0467 \n", - "Train_acc: 1.0000\n", - "Epoch: 1569-------- \n", - "Loss: 0.0467 \n", - "Train_acc: 1.0000\n", - "Epoch: 1570-------- \n", - "Loss: 0.0466 \n", - "Train_acc: 1.0000\n", - "Epoch: 1571-------- \n", - "Loss: 0.0466 \n", - "Train_acc: 1.0000\n", - "Epoch: 1572-------- \n", - "Loss: 0.0465 \n", - "Train_acc: 1.0000\n", - "Epoch: 1573-------- \n", - "Loss: 0.0465 \n", - "Train_acc: 1.0000\n", - "Epoch: 1574-------- \n", - "Loss: 0.0465 \n", - "Train_acc: 1.0000\n", - "Epoch: 1575-------- \n", - "Loss: 0.0464 \n", - "Train_acc: 1.0000\n", - "Epoch: 1576-------- \n", - "Loss: 0.0464 \n", - "Train_acc: 1.0000\n", - "Epoch: 1577-------- \n", - "Loss: 0.0464 \n", - "Train_acc: 1.0000\n", - "Epoch: 1578-------- \n", - "Loss: 0.0463 \n", - "Train_acc: 1.0000\n", - "Epoch: 1579-------- \n", - "Loss: 0.0463 \n", - "Train_acc: 1.0000\n", - "Epoch: 1580-------- \n", - "Loss: 0.0463 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1581-------- \n", - "Loss: 0.0462 \n", - "Train_acc: 1.0000\n", - "Epoch: 1582-------- \n", - "Loss: 0.0462 \n", - "Train_acc: 1.0000\n", - "Epoch: 1583-------- \n", - "Loss: 0.0462 \n", - "Train_acc: 1.0000\n", - "Epoch: 1584-------- \n", - "Loss: 0.0461 \n", - "Train_acc: 1.0000\n", - "Epoch: 1585-------- \n", - "Loss: 0.0461 \n", - "Train_acc: 1.0000\n", - "Epoch: 1586-------- \n", - "Loss: 0.0461 \n", - "Train_acc: 1.0000\n", - "Epoch: 1587-------- \n", - "Loss: 0.0460 \n", - "Train_acc: 1.0000\n", - "Epoch: 1588-------- \n", - "Loss: 0.0460 \n", - "Train_acc: 1.0000\n", - "Epoch: 1589-------- \n", - "Loss: 0.0459 \n", - "Train_acc: 1.0000\n", - "Epoch: 1590-------- \n", - "Loss: 0.0459 \n", - "Train_acc: 1.0000\n", - "Epoch: 1591-------- \n", - "Loss: 0.0459 \n", - "Train_acc: 1.0000\n", - "Epoch: 1592-------- \n", - "Loss: 0.0458 \n", - "Train_acc: 1.0000\n", - "Epoch: 1593-------- \n", - "Loss: 0.0458 \n", - "Train_acc: 1.0000\n", - "Epoch: 1594-------- \n", - "Loss: 0.0458 \n", - "Train_acc: 1.0000\n", - "Epoch: 1595-------- \n", - "Loss: 0.0457 \n", - "Train_acc: 1.0000\n", - "Epoch: 1596-------- \n", - "Loss: 0.0457 \n", - "Train_acc: 1.0000\n", - "Epoch: 1597-------- \n", - "Loss: 0.0457 \n", - "Train_acc: 1.0000\n", - "Epoch: 1598-------- \n", - "Loss: 0.0456 \n", - "Train_acc: 1.0000\n", - "Epoch: 1599-------- \n", - "Loss: 0.0456 \n", - "Train_acc: 1.0000\n", - "Epoch: 1600-------- \n", - "Loss: 0.0456 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1601-------- \n", - "Loss: 0.0455 \n", - "Train_acc: 1.0000\n", - "Epoch: 1602-------- \n", - "Loss: 0.0455 \n", - "Train_acc: 1.0000\n", - "Epoch: 1603-------- \n", - "Loss: 0.0455 \n", - "Train_acc: 1.0000\n", - "Epoch: 1604-------- \n", - "Loss: 0.0454 \n", - "Train_acc: 1.0000\n", - "Epoch: 1605-------- \n", - "Loss: 0.0454 \n", - "Train_acc: 1.0000\n", - "Epoch: 1606-------- \n", - "Loss: 0.0454 \n", - "Train_acc: 1.0000\n", - "Epoch: 1607-------- \n", - "Loss: 0.0453 \n", - "Train_acc: 1.0000\n", - "Epoch: 1608-------- \n", - "Loss: 0.0453 \n", - "Train_acc: 1.0000\n", - "Epoch: 1609-------- \n", - "Loss: 0.0453 \n", - "Train_acc: 1.0000\n", - "Epoch: 1610-------- \n", - "Loss: 0.0452 \n", - "Train_acc: 1.0000\n", - "Epoch: 1611-------- \n", - "Loss: 0.0452 \n", - "Train_acc: 1.0000\n", - "Epoch: 1612-------- \n", - "Loss: 0.0452 \n", - "Train_acc: 1.0000\n", - "Epoch: 1613-------- \n", - "Loss: 0.0451 \n", - "Train_acc: 1.0000\n", - "Epoch: 1614-------- \n", - "Loss: 0.0451 \n", - "Train_acc: 1.0000\n", - "Epoch: 1615-------- \n", - "Loss: 0.0451 \n", - "Train_acc: 1.0000\n", - "Epoch: 1616-------- \n", - "Loss: 0.0450 \n", - "Train_acc: 1.0000\n", - "Epoch: 1617-------- \n", - "Loss: 0.0450 \n", - "Train_acc: 1.0000\n", - "Epoch: 1618-------- \n", - "Loss: 0.0450 \n", - "Train_acc: 1.0000\n", - "Epoch: 1619-------- \n", - "Loss: 0.0449 \n", - "Train_acc: 1.0000\n", - "Epoch: 1620-------- \n", - "Loss: 0.0449 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1621-------- \n", - "Loss: 0.0448 \n", - "Train_acc: 1.0000\n", - "Epoch: 1622-------- \n", - "Loss: 0.0448 \n", - "Train_acc: 1.0000\n", - "Epoch: 1623-------- \n", - "Loss: 0.0448 \n", - "Train_acc: 1.0000\n", - "Epoch: 1624-------- \n", - "Loss: 0.0447 \n", - "Train_acc: 1.0000\n", - "Epoch: 1625-------- \n", - "Loss: 0.0447 \n", - "Train_acc: 1.0000\n", - "Epoch: 1626-------- \n", - "Loss: 0.0447 \n", - "Train_acc: 1.0000\n", - "Epoch: 1627-------- \n", - "Loss: 0.0446 \n", - "Train_acc: 1.0000\n", - "Epoch: 1628-------- \n", - "Loss: 0.0446 \n", - "Train_acc: 1.0000\n", - "Epoch: 1629-------- \n", - "Loss: 0.0446 \n", - "Train_acc: 1.0000\n", - "Epoch: 1630-------- \n", - "Loss: 0.0446 \n", - "Train_acc: 1.0000\n", - "Epoch: 1631-------- \n", - "Loss: 0.0445 \n", - "Train_acc: 1.0000\n", - "Epoch: 1632-------- \n", - "Loss: 0.0445 \n", - "Train_acc: 1.0000\n", - "Epoch: 1633-------- \n", - "Loss: 0.0445 \n", - "Train_acc: 1.0000\n", - "Epoch: 1634-------- \n", - "Loss: 0.0444 \n", - "Train_acc: 1.0000\n", - "Epoch: 1635-------- \n", - "Loss: 0.0444 \n", - "Train_acc: 1.0000\n", - "Epoch: 1636-------- \n", - "Loss: 0.0443 \n", - "Train_acc: 1.0000\n", - "Epoch: 1637-------- \n", - "Loss: 0.0443 \n", - "Train_acc: 1.0000\n", - "Epoch: 1638-------- \n", - "Loss: 0.0443 \n", - "Train_acc: 1.0000\n", - "Epoch: 1639-------- \n", - "Loss: 0.0443 \n", - "Train_acc: 1.0000\n", - "Epoch: 1640-------- \n", - "Loss: 0.0442 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1641-------- \n", - "Loss: 0.0442 \n", - "Train_acc: 1.0000\n", - "Epoch: 1642-------- \n", - "Loss: 0.0442 \n", - "Train_acc: 1.0000\n", - "Epoch: 1643-------- \n", - "Loss: 0.0441 \n", - "Train_acc: 1.0000\n", - "Epoch: 1644-------- \n", - "Loss: 0.0441 \n", - "Train_acc: 1.0000\n", - "Epoch: 1645-------- \n", - "Loss: 0.0441 \n", - "Train_acc: 1.0000\n", - "Epoch: 1646-------- \n", - "Loss: 0.0440 \n", - "Train_acc: 1.0000\n", - "Epoch: 1647-------- \n", - "Loss: 0.0440 \n", - "Train_acc: 1.0000\n", - "Epoch: 1648-------- \n", - "Loss: 0.0440 \n", - "Train_acc: 1.0000\n", - "Epoch: 1649-------- \n", - "Loss: 0.0439 \n", - "Train_acc: 1.0000\n", - "Epoch: 1650-------- \n", - "Loss: 0.0439 \n", - "Train_acc: 1.0000\n", - "Epoch: 1651-------- \n", - "Loss: 0.0439 \n", - "Train_acc: 1.0000\n", - "Epoch: 1652-------- \n", - "Loss: 0.0438 \n", - "Train_acc: 1.0000\n", - "Epoch: 1653-------- \n", - "Loss: 0.0438 \n", - "Train_acc: 1.0000\n", - "Epoch: 1654-------- \n", - "Loss: 0.0438 \n", - "Train_acc: 1.0000\n", - "Epoch: 1655-------- \n", - "Loss: 0.0437 \n", - "Train_acc: 1.0000\n", - "Epoch: 1656-------- \n", - "Loss: 0.0437 \n", - "Train_acc: 1.0000\n", - "Epoch: 1657-------- \n", - "Loss: 0.0437 \n", - "Train_acc: 1.0000\n", - "Epoch: 1658-------- \n", - "Loss: 0.0436 \n", - "Train_acc: 1.0000\n", - "Epoch: 1659-------- \n", - "Loss: 0.0436 \n", - "Train_acc: 1.0000\n", - "Epoch: 1660-------- \n", - "Loss: 0.0436 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1661-------- \n", - "Loss: 0.0435 \n", - "Train_acc: 1.0000\n", - "Epoch: 1662-------- \n", - "Loss: 0.0435 \n", - "Train_acc: 1.0000\n", - "Epoch: 1663-------- \n", - "Loss: 0.0435 \n", - "Train_acc: 1.0000\n", - "Epoch: 1664-------- \n", - "Loss: 0.0434 \n", - "Train_acc: 1.0000\n", - "Epoch: 1665-------- \n", - "Loss: 0.0434 \n", - "Train_acc: 1.0000\n", - "Epoch: 1666-------- \n", - "Loss: 0.0434 \n", - "Train_acc: 1.0000\n", - "Epoch: 1667-------- \n", - "Loss: 0.0433 \n", - "Train_acc: 1.0000\n", - "Epoch: 1668-------- \n", - "Loss: 0.0433 \n", - "Train_acc: 1.0000\n", - "Epoch: 1669-------- \n", - "Loss: 0.0433 \n", - "Train_acc: 1.0000\n", - "Epoch: 1670-------- \n", - "Loss: 0.0433 \n", - "Train_acc: 1.0000\n", - "Epoch: 1671-------- \n", - "Loss: 0.0432 \n", - "Train_acc: 1.0000\n", - "Epoch: 1672-------- \n", - "Loss: 0.0432 \n", - "Train_acc: 1.0000\n", - "Epoch: 1673-------- \n", - "Loss: 0.0432 \n", - "Train_acc: 1.0000\n", - "Epoch: 1674-------- \n", - "Loss: 0.0431 \n", - "Train_acc: 1.0000\n", - "Epoch: 1675-------- \n", - "Loss: 0.0431 \n", - "Train_acc: 1.0000\n", - "Epoch: 1676-------- \n", - "Loss: 0.0431 \n", - "Train_acc: 1.0000\n", - "Epoch: 1677-------- \n", - "Loss: 0.0430 \n", - "Train_acc: 1.0000\n", - "Epoch: 1678-------- \n", - "Loss: 0.0430 \n", - "Train_acc: 1.0000\n", - "Epoch: 1679-------- \n", - "Loss: 0.0430 \n", - "Train_acc: 1.0000\n", - "Epoch: 1680-------- \n", - "Loss: 0.0429 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1681-------- \n", - "Loss: 0.0429 \n", - "Train_acc: 1.0000\n", - "Epoch: 1682-------- \n", - "Loss: 0.0429 \n", - "Train_acc: 1.0000\n", - "Epoch: 1683-------- \n", - "Loss: 0.0428 \n", - "Train_acc: 1.0000\n", - "Epoch: 1684-------- \n", - "Loss: 0.0428 \n", - "Train_acc: 1.0000\n", - "Epoch: 1685-------- \n", - "Loss: 0.0428 \n", - "Train_acc: 1.0000\n", - "Epoch: 1686-------- \n", - "Loss: 0.0427 \n", - "Train_acc: 1.0000\n", - "Epoch: 1687-------- \n", - "Loss: 0.0427 \n", - "Train_acc: 1.0000\n", - "Epoch: 1688-------- \n", - "Loss: 0.0427 \n", - "Train_acc: 1.0000\n", - "Epoch: 1689-------- \n", - "Loss: 0.0427 \n", - "Train_acc: 1.0000\n", - "Epoch: 1690-------- \n", - "Loss: 0.0426 \n", - "Train_acc: 1.0000\n", - "Epoch: 1691-------- \n", - "Loss: 0.0426 \n", - "Train_acc: 1.0000\n", - "Epoch: 1692-------- \n", - "Loss: 0.0426 \n", - "Train_acc: 1.0000\n", - "Epoch: 1693-------- \n", - "Loss: 0.0425 \n", - "Train_acc: 1.0000\n", - "Epoch: 1694-------- \n", - "Loss: 0.0425 \n", - "Train_acc: 1.0000\n", - "Epoch: 1695-------- \n", - "Loss: 0.0425 \n", - "Train_acc: 1.0000\n", - "Epoch: 1696-------- \n", - "Loss: 0.0424 \n", - "Train_acc: 1.0000\n", - "Epoch: 1697-------- \n", - "Loss: 0.0424 \n", - "Train_acc: 1.0000\n", - "Epoch: 1698-------- \n", - "Loss: 0.0424 \n", - "Train_acc: 1.0000\n", - "Epoch: 1699-------- \n", - "Loss: 0.0423 \n", - "Train_acc: 1.0000\n", - "Epoch: 1700-------- \n", - "Loss: 0.0423 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1701-------- \n", - "Loss: 0.0423 \n", - "Train_acc: 1.0000\n", - "Epoch: 1702-------- \n", - "Loss: 0.0423 \n", - "Train_acc: 1.0000\n", - "Epoch: 1703-------- \n", - "Loss: 0.0422 \n", - "Train_acc: 1.0000\n", - "Epoch: 1704-------- \n", - "Loss: 0.0422 \n", - "Train_acc: 1.0000\n", - "Epoch: 1705-------- \n", - "Loss: 0.0422 \n", - "Train_acc: 1.0000\n", - "Epoch: 1706-------- \n", - "Loss: 0.0421 \n", - "Train_acc: 1.0000\n", - "Epoch: 1707-------- \n", - "Loss: 0.0421 \n", - "Train_acc: 1.0000\n", - "Epoch: 1708-------- \n", - "Loss: 0.0421 \n", - "Train_acc: 1.0000\n", - "Epoch: 1709-------- \n", - "Loss: 0.0420 \n", - "Train_acc: 1.0000\n", - "Epoch: 1710-------- \n", - "Loss: 0.0420 \n", - "Train_acc: 1.0000\n", - "Epoch: 1711-------- \n", - "Loss: 0.0420 \n", - "Train_acc: 1.0000\n", - "Epoch: 1712-------- \n", - "Loss: 0.0420 \n", - "Train_acc: 1.0000\n", - "Epoch: 1713-------- \n", - "Loss: 0.0419 \n", - "Train_acc: 1.0000\n", - "Epoch: 1714-------- \n", - "Loss: 0.0419 \n", - "Train_acc: 1.0000\n", - "Epoch: 1715-------- \n", - "Loss: 0.0419 \n", - "Train_acc: 1.0000\n", - "Epoch: 1716-------- \n", - "Loss: 0.0418 \n", - "Train_acc: 1.0000\n", - "Epoch: 1717-------- \n", - "Loss: 0.0418 \n", - "Train_acc: 1.0000\n", - "Epoch: 1718-------- \n", - "Loss: 0.0418 \n", - "Train_acc: 1.0000\n", - "Epoch: 1719-------- \n", - "Loss: 0.0417 \n", - "Train_acc: 1.0000\n", - "Epoch: 1720-------- \n", - "Loss: 0.0417 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1721-------- \n", - "Loss: 0.0417 \n", - "Train_acc: 1.0000\n", - "Epoch: 1722-------- \n", - "Loss: 0.0416 \n", - "Train_acc: 1.0000\n", - "Epoch: 1723-------- \n", - "Loss: 0.0416 \n", - "Train_acc: 1.0000\n", - "Epoch: 1724-------- \n", - "Loss: 0.0416 \n", - "Train_acc: 1.0000\n", - "Epoch: 1725-------- \n", - "Loss: 0.0416 \n", - "Train_acc: 1.0000\n", - "Epoch: 1726-------- \n", - "Loss: 0.0415 \n", - "Train_acc: 1.0000\n", - "Epoch: 1727-------- \n", - "Loss: 0.0415 \n", - "Train_acc: 1.0000\n", - "Epoch: 1728-------- \n", - "Loss: 0.0415 \n", - "Train_acc: 1.0000\n", - "Epoch: 1729-------- \n", - "Loss: 0.0414 \n", - "Train_acc: 1.0000\n", - "Epoch: 1730-------- \n", - "Loss: 0.0414 \n", - "Train_acc: 1.0000\n", - "Epoch: 1731-------- \n", - "Loss: 0.0414 \n", - "Train_acc: 1.0000\n", - "Epoch: 1732-------- \n", - "Loss: 0.0414 \n", - "Train_acc: 1.0000\n", - "Epoch: 1733-------- \n", - "Loss: 0.0413 \n", - "Train_acc: 1.0000\n", - "Epoch: 1734-------- \n", - "Loss: 0.0413 \n", - "Train_acc: 1.0000\n", - "Epoch: 1735-------- \n", - "Loss: 0.0413 \n", - "Train_acc: 1.0000\n", - "Epoch: 1736-------- \n", - "Loss: 0.0412 \n", - "Train_acc: 1.0000\n", - "Epoch: 1737-------- \n", - "Loss: 0.0412 \n", - "Train_acc: 1.0000\n", - "Epoch: 1738-------- \n", - "Loss: 0.0412 \n", - "Train_acc: 1.0000\n", - "Epoch: 1739-------- \n", - "Loss: 0.0411 \n", - "Train_acc: 1.0000\n", - "Epoch: 1740-------- \n", - "Loss: 0.0411 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1741-------- \n", - "Loss: 0.0411 \n", - "Train_acc: 1.0000\n", - "Epoch: 1742-------- \n", - "Loss: 0.0411 \n", - "Train_acc: 1.0000\n", - "Epoch: 1743-------- \n", - "Loss: 0.0410 \n", - "Train_acc: 1.0000\n", - "Epoch: 1744-------- \n", - "Loss: 0.0410 \n", - "Train_acc: 1.0000\n", - "Epoch: 1745-------- \n", - "Loss: 0.0410 \n", - "Train_acc: 1.0000\n", - "Epoch: 1746-------- \n", - "Loss: 0.0409 \n", - "Train_acc: 1.0000\n", - "Epoch: 1747-------- \n", - "Loss: 0.0409 \n", - "Train_acc: 1.0000\n", - "Epoch: 1748-------- \n", - "Loss: 0.0409 \n", - "Train_acc: 1.0000\n", - "Epoch: 1749-------- \n", - "Loss: 0.0409 \n", - "Train_acc: 1.0000\n", - "Epoch: 1750-------- \n", - "Loss: 0.0408 \n", - "Train_acc: 1.0000\n", - "Epoch: 1751-------- \n", - "Loss: 0.0408 \n", - "Train_acc: 1.0000\n", - "Epoch: 1752-------- \n", - "Loss: 0.0408 \n", - "Train_acc: 1.0000\n", - "Epoch: 1753-------- \n", - "Loss: 0.0407 \n", - "Train_acc: 1.0000\n", - "Epoch: 1754-------- \n", - "Loss: 0.0407 \n", - "Train_acc: 1.0000\n", - "Epoch: 1755-------- \n", - "Loss: 0.0407 \n", - "Train_acc: 1.0000\n", - "Epoch: 1756-------- \n", - "Loss: 0.0407 \n", - "Train_acc: 1.0000\n", - "Epoch: 1757-------- \n", - "Loss: 0.0406 \n", - "Train_acc: 1.0000\n", - "Epoch: 1758-------- \n", - "Loss: 0.0406 \n", - "Train_acc: 1.0000\n", - "Epoch: 1759-------- \n", - "Loss: 0.0406 \n", - "Train_acc: 1.0000\n", - "Epoch: 1760-------- \n", - "Loss: 0.0405 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1761-------- \n", - "Loss: 0.0405 \n", - "Train_acc: 1.0000\n", - "Epoch: 1762-------- \n", - "Loss: 0.0405 \n", - "Train_acc: 1.0000\n", - "Epoch: 1763-------- \n", - "Loss: 0.0404 \n", - "Train_acc: 1.0000\n", - "Epoch: 1764-------- \n", - "Loss: 0.0404 \n", - "Train_acc: 1.0000\n", - "Epoch: 1765-------- \n", - "Loss: 0.0404 \n", - "Train_acc: 1.0000\n", - "Epoch: 1766-------- \n", - "Loss: 0.0404 \n", - "Train_acc: 1.0000\n", - "Epoch: 1767-------- \n", - "Loss: 0.0403 \n", - "Train_acc: 1.0000\n", - "Epoch: 1768-------- \n", - "Loss: 0.0403 \n", - "Train_acc: 1.0000\n", - "Epoch: 1769-------- \n", - "Loss: 0.0403 \n", - "Train_acc: 1.0000\n", - "Epoch: 1770-------- \n", - "Loss: 0.0402 \n", - "Train_acc: 1.0000\n", - "Epoch: 1771-------- \n", - "Loss: 0.0402 \n", - "Train_acc: 1.0000\n", - "Epoch: 1772-------- \n", - "Loss: 0.0402 \n", - "Train_acc: 1.0000\n", - "Epoch: 1773-------- \n", - "Loss: 0.0402 \n", - "Train_acc: 1.0000\n", - "Epoch: 1774-------- \n", - "Loss: 0.0401 \n", - "Train_acc: 1.0000\n", - "Epoch: 1775-------- \n", - "Loss: 0.0401 \n", - "Train_acc: 1.0000\n", - "Epoch: 1776-------- \n", - "Loss: 0.0401 \n", - "Train_acc: 1.0000\n", - "Epoch: 1777-------- \n", - "Loss: 0.0401 \n", - "Train_acc: 1.0000\n", - "Epoch: 1778-------- \n", - "Loss: 0.0400 \n", - "Train_acc: 1.0000\n", - "Epoch: 1779-------- \n", - "Loss: 0.0400 \n", - "Train_acc: 1.0000\n", - "Epoch: 1780-------- \n", - "Loss: 0.0400 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1781-------- \n", - "Loss: 0.0399 \n", - "Train_acc: 1.0000\n", - "Epoch: 1782-------- \n", - "Loss: 0.0399 \n", - "Train_acc: 1.0000\n", - "Epoch: 1783-------- \n", - "Loss: 0.0399 \n", - "Train_acc: 1.0000\n", - "Epoch: 1784-------- \n", - "Loss: 0.0399 \n", - "Train_acc: 1.0000\n", - "Epoch: 1785-------- \n", - "Loss: 0.0398 \n", - "Train_acc: 1.0000\n", - "Epoch: 1786-------- \n", - "Loss: 0.0398 \n", - "Train_acc: 1.0000\n", - "Epoch: 1787-------- \n", - "Loss: 0.0398 \n", - "Train_acc: 1.0000\n", - "Epoch: 1788-------- \n", - "Loss: 0.0397 \n", - "Train_acc: 1.0000\n", - "Epoch: 1789-------- \n", - "Loss: 0.0397 \n", - "Train_acc: 1.0000\n", - "Epoch: 1790-------- \n", - "Loss: 0.0397 \n", - "Train_acc: 1.0000\n", - "Epoch: 1791-------- \n", - "Loss: 0.0397 \n", - "Train_acc: 1.0000\n", - "Epoch: 1792-------- \n", - "Loss: 0.0396 \n", - "Train_acc: 1.0000\n", - "Epoch: 1793-------- \n", - "Loss: 0.0396 \n", - "Train_acc: 1.0000\n", - "Epoch: 1794-------- \n", - "Loss: 0.0396 \n", - "Train_acc: 1.0000\n", - "Epoch: 1795-------- \n", - "Loss: 0.0395 \n", - "Train_acc: 1.0000\n", - "Epoch: 1796-------- \n", - "Loss: 0.0395 \n", - "Train_acc: 1.0000\n", - "Epoch: 1797-------- \n", - "Loss: 0.0395 \n", - "Train_acc: 1.0000\n", - "Epoch: 1798-------- \n", - "Loss: 0.0395 \n", - "Train_acc: 1.0000\n", - "Epoch: 1799-------- \n", - "Loss: 0.0394 \n", - "Train_acc: 1.0000\n", - "Epoch: 1800-------- \n", - "Loss: 0.0394 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1801-------- \n", - "Loss: 0.0394 \n", - "Train_acc: 1.0000\n", - "Epoch: 1802-------- \n", - "Loss: 0.0394 \n", - "Train_acc: 1.0000\n", - "Epoch: 1803-------- \n", - "Loss: 0.0393 \n", - "Train_acc: 1.0000\n", - "Epoch: 1804-------- \n", - "Loss: 0.0393 \n", - "Train_acc: 1.0000\n", - "Epoch: 1805-------- \n", - "Loss: 0.0393 \n", - "Train_acc: 1.0000\n", - "Epoch: 1806-------- \n", - "Loss: 0.0392 \n", - "Train_acc: 1.0000\n", - "Epoch: 1807-------- \n", - "Loss: 0.0392 \n", - "Train_acc: 1.0000\n", - "Epoch: 1808-------- \n", - "Loss: 0.0392 \n", - "Train_acc: 1.0000\n", - "Epoch: 1809-------- \n", - "Loss: 0.0392 \n", - "Train_acc: 1.0000\n", - "Epoch: 1810-------- \n", - "Loss: 0.0391 \n", - "Train_acc: 1.0000\n", - "Epoch: 1811-------- \n", - "Loss: 0.0391 \n", - "Train_acc: 1.0000\n", - "Epoch: 1812-------- \n", - "Loss: 0.0391 \n", - "Train_acc: 1.0000\n", - "Epoch: 1813-------- \n", - "Loss: 0.0391 \n", - "Train_acc: 1.0000\n", - "Epoch: 1814-------- \n", - "Loss: 0.0390 \n", - "Train_acc: 1.0000\n", - "Epoch: 1815-------- \n", - "Loss: 0.0390 \n", - "Train_acc: 1.0000\n", - "Epoch: 1816-------- \n", - "Loss: 0.0390 \n", - "Train_acc: 1.0000\n", - "Epoch: 1817-------- \n", - "Loss: 0.0389 \n", - "Train_acc: 1.0000\n", - "Epoch: 1818-------- \n", - "Loss: 0.0389 \n", - "Train_acc: 1.0000\n", - "Epoch: 1819-------- \n", - "Loss: 0.0389 \n", - "Train_acc: 1.0000\n", - "Epoch: 1820-------- \n", - "Loss: 0.0389 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1821-------- \n", - "Loss: 0.0388 \n", - "Train_acc: 1.0000\n", - "Epoch: 1822-------- \n", - "Loss: 0.0388 \n", - "Train_acc: 1.0000\n", - "Epoch: 1823-------- \n", - "Loss: 0.0388 \n", - "Train_acc: 1.0000\n", - "Epoch: 1824-------- \n", - "Loss: 0.0388 \n", - "Train_acc: 1.0000\n", - "Epoch: 1825-------- \n", - "Loss: 0.0387 \n", - "Train_acc: 1.0000\n", - "Epoch: 1826-------- \n", - "Loss: 0.0387 \n", - "Train_acc: 1.0000\n", - "Epoch: 1827-------- \n", - "Loss: 0.0387 \n", - "Train_acc: 1.0000\n", - "Epoch: 1828-------- \n", - "Loss: 0.0386 \n", - "Train_acc: 1.0000\n", - "Epoch: 1829-------- \n", - "Loss: 0.0386 \n", - "Train_acc: 1.0000\n", - "Epoch: 1830-------- \n", - "Loss: 0.0386 \n", - "Train_acc: 1.0000\n", - "Epoch: 1831-------- \n", - "Loss: 0.0386 \n", - "Train_acc: 1.0000\n", - "Epoch: 1832-------- \n", - "Loss: 0.0385 \n", - "Train_acc: 1.0000\n", - "Epoch: 1833-------- \n", - "Loss: 0.0385 \n", - "Train_acc: 1.0000\n", - "Epoch: 1834-------- \n", - "Loss: 0.0385 \n", - "Train_acc: 1.0000\n", - "Epoch: 1835-------- \n", - "Loss: 0.0385 \n", - "Train_acc: 1.0000\n", - "Epoch: 1836-------- \n", - "Loss: 0.0384 \n", - "Train_acc: 1.0000\n", - "Epoch: 1837-------- \n", - "Loss: 0.0384 \n", - "Train_acc: 1.0000\n", - "Epoch: 1838-------- \n", - "Loss: 0.0384 \n", - "Train_acc: 1.0000\n", - "Epoch: 1839-------- \n", - "Loss: 0.0384 \n", - "Train_acc: 1.0000\n", - "Epoch: 1840-------- \n", - "Loss: 0.0383 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1841-------- \n", - "Loss: 0.0383 \n", - "Train_acc: 1.0000\n", - "Epoch: 1842-------- \n", - "Loss: 0.0383 \n", - "Train_acc: 1.0000\n", - "Epoch: 1843-------- \n", - "Loss: 0.0382 \n", - "Train_acc: 1.0000\n", - "Epoch: 1844-------- \n", - "Loss: 0.0382 \n", - "Train_acc: 1.0000\n", - "Epoch: 1845-------- \n", - "Loss: 0.0382 \n", - "Train_acc: 1.0000\n", - "Epoch: 1846-------- \n", - "Loss: 0.0382 \n", - "Train_acc: 1.0000\n", - "Epoch: 1847-------- \n", - "Loss: 0.0381 \n", - "Train_acc: 1.0000\n", - "Epoch: 1848-------- \n", - "Loss: 0.0381 \n", - "Train_acc: 1.0000\n", - "Epoch: 1849-------- \n", - "Loss: 0.0381 \n", - "Train_acc: 1.0000\n", - "Epoch: 1850-------- \n", - "Loss: 0.0381 \n", - "Train_acc: 1.0000\n", - "Epoch: 1851-------- \n", - "Loss: 0.0380 \n", - "Train_acc: 1.0000\n", - "Epoch: 1852-------- \n", - "Loss: 0.0380 \n", - "Train_acc: 1.0000\n", - "Epoch: 1853-------- \n", - "Loss: 0.0380 \n", - "Train_acc: 1.0000\n", - "Epoch: 1854-------- \n", - "Loss: 0.0380 \n", - "Train_acc: 1.0000\n", - "Epoch: 1855-------- \n", - "Loss: 0.0379 \n", - "Train_acc: 1.0000\n", - "Epoch: 1856-------- \n", - "Loss: 0.0379 \n", - "Train_acc: 1.0000\n", - "Epoch: 1857-------- \n", - "Loss: 0.0379 \n", - "Train_acc: 1.0000\n", - "Epoch: 1858-------- \n", - "Loss: 0.0378 \n", - "Train_acc: 1.0000\n", - "Epoch: 1859-------- \n", - "Loss: 0.0378 \n", - "Train_acc: 1.0000\n", - "Epoch: 1860-------- \n", - "Loss: 0.0378 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1861-------- \n", - "Loss: 0.0378 \n", - "Train_acc: 1.0000\n", - "Epoch: 1862-------- \n", - "Loss: 0.0377 \n", - "Train_acc: 1.0000\n", - "Epoch: 1863-------- \n", - "Loss: 0.0377 \n", - "Train_acc: 1.0000\n", - "Epoch: 1864-------- \n", - "Loss: 0.0377 \n", - "Train_acc: 1.0000\n", - "Epoch: 1865-------- \n", - "Loss: 0.0377 \n", - "Train_acc: 1.0000\n", - "Epoch: 1866-------- \n", - "Loss: 0.0376 \n", - "Train_acc: 1.0000\n", - "Epoch: 1867-------- \n", - "Loss: 0.0376 \n", - "Train_acc: 1.0000\n", - "Epoch: 1868-------- \n", - "Loss: 0.0376 \n", - "Train_acc: 1.0000\n", - "Epoch: 1869-------- \n", - "Loss: 0.0376 \n", - "Train_acc: 1.0000\n", - "Epoch: 1870-------- \n", - "Loss: 0.0375 \n", - "Train_acc: 1.0000\n", - "Epoch: 1871-------- \n", - "Loss: 0.0375 \n", - "Train_acc: 1.0000\n", - "Epoch: 1872-------- \n", - "Loss: 0.0375 \n", - "Train_acc: 1.0000\n", - "Epoch: 1873-------- \n", - "Loss: 0.0375 \n", - "Train_acc: 1.0000\n", - "Epoch: 1874-------- \n", - "Loss: 0.0374 \n", - "Train_acc: 1.0000\n", - "Epoch: 1875-------- \n", - "Loss: 0.0374 \n", - "Train_acc: 1.0000\n", - "Epoch: 1876-------- \n", - "Loss: 0.0374 \n", - "Train_acc: 1.0000\n", - "Epoch: 1877-------- \n", - "Loss: 0.0374 \n", - "Train_acc: 1.0000\n", - "Epoch: 1878-------- \n", - "Loss: 0.0373 \n", - "Train_acc: 1.0000\n", - "Epoch: 1879-------- \n", - "Loss: 0.0373 \n", - "Train_acc: 1.0000\n", - "Epoch: 1880-------- \n", - "Loss: 0.0373 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1881-------- \n", - "Loss: 0.0373 \n", - "Train_acc: 1.0000\n", - "Epoch: 1882-------- \n", - "Loss: 0.0372 \n", - "Train_acc: 1.0000\n", - "Epoch: 1883-------- \n", - "Loss: 0.0372 \n", - "Train_acc: 1.0000\n", - "Epoch: 1884-------- \n", - "Loss: 0.0372 \n", - "Train_acc: 1.0000\n", - "Epoch: 1885-------- \n", - "Loss: 0.0372 \n", - "Train_acc: 1.0000\n", - "Epoch: 1886-------- \n", - "Loss: 0.0371 \n", - "Train_acc: 1.0000\n", - "Epoch: 1887-------- \n", - "Loss: 0.0371 \n", - "Train_acc: 1.0000\n", - "Epoch: 1888-------- \n", - "Loss: 0.0371 \n", - "Train_acc: 1.0000\n", - "Epoch: 1889-------- \n", - "Loss: 0.0370 \n", - "Train_acc: 1.0000\n", - "Epoch: 1890-------- \n", - "Loss: 0.0370 \n", - "Train_acc: 1.0000\n", - "Epoch: 1891-------- \n", - "Loss: 0.0370 \n", - "Train_acc: 1.0000\n", - "Epoch: 1892-------- \n", - "Loss: 0.0370 \n", - "Train_acc: 1.0000\n", - "Epoch: 1893-------- \n", - "Loss: 0.0369 \n", - "Train_acc: 1.0000\n", - "Epoch: 1894-------- \n", - "Loss: 0.0369 \n", - "Train_acc: 1.0000\n", - "Epoch: 1895-------- \n", - "Loss: 0.0369 \n", - "Train_acc: 1.0000\n", - "Epoch: 1896-------- \n", - "Loss: 0.0369 \n", - "Train_acc: 1.0000\n", - "Epoch: 1897-------- \n", - "Loss: 0.0368 \n", - "Train_acc: 1.0000\n", - "Epoch: 1898-------- \n", - "Loss: 0.0368 \n", - "Train_acc: 1.0000\n", - "Epoch: 1899-------- \n", - "Loss: 0.0368 \n", - "Train_acc: 1.0000\n", - "Epoch: 1900-------- \n", - "Loss: 0.0368 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1901-------- \n", - "Loss: 0.0367 \n", - "Train_acc: 1.0000\n", - "Epoch: 1902-------- \n", - "Loss: 0.0367 \n", - "Train_acc: 1.0000\n", - "Epoch: 1903-------- \n", - "Loss: 0.0367 \n", - "Train_acc: 1.0000\n", - "Epoch: 1904-------- \n", - "Loss: 0.0367 \n", - "Train_acc: 1.0000\n", - "Epoch: 1905-------- \n", - "Loss: 0.0366 \n", - "Train_acc: 1.0000\n", - "Epoch: 1906-------- \n", - "Loss: 0.0366 \n", - "Train_acc: 1.0000\n", - "Epoch: 1907-------- \n", - "Loss: 0.0366 \n", - "Train_acc: 1.0000\n", - "Epoch: 1908-------- \n", - "Loss: 0.0366 \n", - "Train_acc: 1.0000\n", - "Epoch: 1909-------- \n", - "Loss: 0.0365 \n", - "Train_acc: 1.0000\n", - "Epoch: 1910-------- \n", - "Loss: 0.0365 \n", - "Train_acc: 1.0000\n", - "Epoch: 1911-------- \n", - "Loss: 0.0365 \n", - "Train_acc: 1.0000\n", - "Epoch: 1912-------- \n", - "Loss: 0.0365 \n", - "Train_acc: 1.0000\n", - "Epoch: 1913-------- \n", - "Loss: 0.0364 \n", - "Train_acc: 1.0000\n", - "Epoch: 1914-------- \n", - "Loss: 0.0364 \n", - "Train_acc: 1.0000\n", - "Epoch: 1915-------- \n", - "Loss: 0.0364 \n", - "Train_acc: 1.0000\n", - "Epoch: 1916-------- \n", - "Loss: 0.0364 \n", - "Train_acc: 1.0000\n", - "Epoch: 1917-------- \n", - "Loss: 0.0363 \n", - "Train_acc: 1.0000\n", - "Epoch: 1918-------- \n", - "Loss: 0.0363 \n", - "Train_acc: 1.0000\n", - "Epoch: 1919-------- \n", - "Loss: 0.0363 \n", - "Train_acc: 1.0000\n", - "Epoch: 1920-------- \n", - "Loss: 0.0363 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1921-------- \n", - "Loss: 0.0362 \n", - "Train_acc: 1.0000\n", - "Epoch: 1922-------- \n", - "Loss: 0.0362 \n", - "Train_acc: 1.0000\n", - "Epoch: 1923-------- \n", - "Loss: 0.0362 \n", - "Train_acc: 1.0000\n", - "Epoch: 1924-------- \n", - "Loss: 0.0362 \n", - "Train_acc: 1.0000\n", - "Epoch: 1925-------- \n", - "Loss: 0.0361 \n", - "Train_acc: 1.0000\n", - "Epoch: 1926-------- \n", - "Loss: 0.0361 \n", - "Train_acc: 1.0000\n", - "Epoch: 1927-------- \n", - "Loss: 0.0361 \n", - "Train_acc: 1.0000\n", - "Epoch: 1928-------- \n", - "Loss: 0.0361 \n", - "Train_acc: 1.0000\n", - "Epoch: 1929-------- \n", - "Loss: 0.0360 \n", - "Train_acc: 1.0000\n", - "Epoch: 1930-------- \n", - "Loss: 0.0360 \n", - "Train_acc: 1.0000\n", - "Epoch: 1931-------- \n", - "Loss: 0.0360 \n", - "Train_acc: 1.0000\n", - "Epoch: 1932-------- \n", - "Loss: 0.0360 \n", - "Train_acc: 1.0000\n", - "Epoch: 1933-------- \n", - "Loss: 0.0359 \n", - "Train_acc: 1.0000\n", - "Epoch: 1934-------- \n", - "Loss: 0.0359 \n", - "Train_acc: 1.0000\n", - "Epoch: 1935-------- \n", - "Loss: 0.0359 \n", - "Train_acc: 1.0000\n", - "Epoch: 1936-------- \n", - "Loss: 0.0359 \n", - "Train_acc: 1.0000\n", - "Epoch: 1937-------- \n", - "Loss: 0.0359 \n", - "Train_acc: 1.0000\n", - "Epoch: 1938-------- \n", - "Loss: 0.0358 \n", - "Train_acc: 1.0000\n", - "Epoch: 1939-------- \n", - "Loss: 0.0358 \n", - "Train_acc: 1.0000\n", - "Epoch: 1940-------- \n", - "Loss: 0.0358 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1941-------- \n", - "Loss: 0.0358 \n", - "Train_acc: 1.0000\n", - "Epoch: 1942-------- \n", - "Loss: 0.0357 \n", - "Train_acc: 1.0000\n", - "Epoch: 1943-------- \n", - "Loss: 0.0357 \n", - "Train_acc: 1.0000\n", - "Epoch: 1944-------- \n", - "Loss: 0.0357 \n", - "Train_acc: 1.0000\n", - "Epoch: 1945-------- \n", - "Loss: 0.0357 \n", - "Train_acc: 1.0000\n", - "Epoch: 1946-------- \n", - "Loss: 0.0356 \n", - "Train_acc: 1.0000\n", - "Epoch: 1947-------- \n", - "Loss: 0.0356 \n", - "Train_acc: 1.0000\n", - "Epoch: 1948-------- \n", - "Loss: 0.0356 \n", - "Train_acc: 1.0000\n", - "Epoch: 1949-------- \n", - "Loss: 0.0356 \n", - "Train_acc: 1.0000\n", - "Epoch: 1950-------- \n", - "Loss: 0.0355 \n", - "Train_acc: 1.0000\n", - "Epoch: 1951-------- \n", - "Loss: 0.0355 \n", - "Train_acc: 1.0000\n", - "Epoch: 1952-------- \n", - "Loss: 0.0355 \n", - "Train_acc: 1.0000\n", - "Epoch: 1953-------- \n", - "Loss: 0.0355 \n", - "Train_acc: 1.0000\n", - "Epoch: 1954-------- \n", - "Loss: 0.0354 \n", - "Train_acc: 1.0000\n", - "Epoch: 1955-------- \n", - "Loss: 0.0354 \n", - "Train_acc: 1.0000\n", - "Epoch: 1956-------- \n", - "Loss: 0.0354 \n", - "Train_acc: 1.0000\n", - "Epoch: 1957-------- \n", - "Loss: 0.0354 \n", - "Train_acc: 1.0000\n", - "Epoch: 1958-------- \n", - "Loss: 0.0353 \n", - "Train_acc: 1.0000\n", - "Epoch: 1959-------- \n", - "Loss: 0.0353 \n", - "Train_acc: 1.0000\n", - "Epoch: 1960-------- \n", - "Loss: 0.0353 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1961-------- \n", - "Loss: 0.0353 \n", - "Train_acc: 1.0000\n", - "Epoch: 1962-------- \n", - "Loss: 0.0352 \n", - "Train_acc: 1.0000\n", - "Epoch: 1963-------- \n", - "Loss: 0.0352 \n", - "Train_acc: 1.0000\n", - "Epoch: 1964-------- \n", - "Loss: 0.0352 \n", - "Train_acc: 1.0000\n", - "Epoch: 1965-------- \n", - "Loss: 0.0352 \n", - "Train_acc: 1.0000\n", - "Epoch: 1966-------- \n", - "Loss: 0.0351 \n", - "Train_acc: 1.0000\n", - "Epoch: 1967-------- \n", - "Loss: 0.0351 \n", - "Train_acc: 1.0000\n", - "Epoch: 1968-------- \n", - "Loss: 0.0351 \n", - "Train_acc: 1.0000\n", - "Epoch: 1969-------- \n", - "Loss: 0.0351 \n", - "Train_acc: 1.0000\n", - "Epoch: 1970-------- \n", - "Loss: 0.0351 \n", - "Train_acc: 1.0000\n", - "Epoch: 1971-------- \n", - "Loss: 0.0350 \n", - "Train_acc: 1.0000\n", - "Epoch: 1972-------- \n", - "Loss: 0.0350 \n", - "Train_acc: 1.0000\n", - "Epoch: 1973-------- \n", - "Loss: 0.0350 \n", - "Train_acc: 1.0000\n", - "Epoch: 1974-------- \n", - "Loss: 0.0350 \n", - "Train_acc: 1.0000\n", - "Epoch: 1975-------- \n", - "Loss: 0.0349 \n", - "Train_acc: 1.0000\n", - "Epoch: 1976-------- \n", - "Loss: 0.0349 \n", - "Train_acc: 1.0000\n", - "Epoch: 1977-------- \n", - "Loss: 0.0349 \n", - "Train_acc: 1.0000\n", - "Epoch: 1978-------- \n", - "Loss: 0.0349 \n", - "Train_acc: 1.0000\n", - "Epoch: 1979-------- \n", - "Loss: 0.0348 \n", - "Train_acc: 1.0000\n", - "Epoch: 1980-------- \n", - "Loss: 0.0348 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n", - "Epoch: 1981-------- \n", - "Loss: 0.0348 \n", - "Train_acc: 1.0000\n", - "Epoch: 1982-------- \n", - "Loss: 0.0348 \n", - "Train_acc: 1.0000\n", - "Epoch: 1983-------- \n", - "Loss: 0.0347 \n", - "Train_acc: 1.0000\n", - "Epoch: 1984-------- \n", - "Loss: 0.0347 \n", - "Train_acc: 1.0000\n", - "Epoch: 1985-------- \n", - "Loss: 0.0347 \n", - "Train_acc: 1.0000\n", - "Epoch: 1986-------- \n", - "Loss: 0.0347 \n", - "Train_acc: 1.0000\n", - "Epoch: 1987-------- \n", - "Loss: 0.0347 \n", - "Train_acc: 1.0000\n", - "Epoch: 1988-------- \n", - "Loss: 0.0346 \n", - "Train_acc: 1.0000\n", - "Epoch: 1989-------- \n", - "Loss: 0.0346 \n", - "Train_acc: 1.0000\n", - "Epoch: 1990-------- \n", - "Loss: 0.0346 \n", - "Train_acc: 1.0000\n", - "Epoch: 1991-------- \n", - "Loss: 0.0346 \n", - "Train_acc: 1.0000\n", - "Epoch: 1992-------- \n", - "Loss: 0.0345 \n", - "Train_acc: 1.0000\n", - "Epoch: 1993-------- \n", - "Loss: 0.0345 \n", - "Train_acc: 1.0000\n", - "Epoch: 1994-------- \n", - "Loss: 0.0345 \n", - "Train_acc: 1.0000\n", - "Epoch: 1995-------- \n", - "Loss: 0.0345 \n", - "Train_acc: 1.0000\n", - "Epoch: 1996-------- \n", - "Loss: 0.0344 \n", - "Train_acc: 1.0000\n", - "Epoch: 1997-------- \n", - "Loss: 0.0344 \n", - "Train_acc: 1.0000\n", - "Epoch: 1998-------- \n", - "Loss: 0.0344 \n", - "Train_acc: 1.0000\n", - "Epoch: 1999-------- \n", - "Loss: 0.0344 \n", - "Train_acc: 1.0000\n", - "Test_acc: 1.0000\n" + "/tmp/ipykernel_694483/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + " x_0s = torch.tensor(x_0s)\n", + "/tmp/ipykernel_694483/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + " torch.tensor(y, dtype=torch.long).to(device),\n" ] } ], "source": [ - "test_interval = 20\n", - "num_epochs = 2000\n", - "get_accuracy = lambda yhat, ytrue: (yhat == ytrue).float().mean()\n", - "losses = np.full((num_epochs), np.nan)\n", - "train_accs = np.full((num_epochs), np.nan)\n", - "test_accs = np.full((num_epochs), np.nan)\n", - "for epoch_i in range(num_epochs):\n", - " # Train model\n", - " model.train()\n", - " optimizer.zero_grad()\n", - " y_hat, y_hat_cls = model(x_0, x_1)\n", - " loss = criterion(y_hat[ind_train], y_train)\n", - " loss.backward()\n", - " optimizer.step()\n", - " train_acc = get_accuracy(y_hat_cls[ind_train], y[ind_train])\n", - " print(\n", - " f\"Epoch: {epoch_i}-------- \\nLoss: {loss.item():.4f} \\nTrain_acc: {train_acc.item():.4f}\",\n", - " flush=True,\n", - " )\n", - " # Evaluate model\n", - " if epoch_i % test_interval == 0 or epoch_i == num_epochs - 1:\n", - " with torch.no_grad():\n", - " y_hat, y_hat_cls = model(x_0, x_1)\n", - " test_acc = get_accuracy(y_hat_cls[ind_test], y[ind_test])\n", - " print(f\"Test_acc: {test_acc.item():.4f}\", flush=True)\n", - " test_accs[epoch_i] = test_acc.item()\n", - "\n", - " # Store metrics\n", - " losses[epoch_i] = loss.item()\n", - " train_accs[epoch_i] = train_acc.item()" + "x_0s = torch.tensor(x_0s)\n", + "x_0s, incidence_1, y = (\n", + " x_0s.float().to(device),\n", + " incidence_1.float().to(device),\n", + " torch.tensor(y, dtype=torch.long).to(device),\n", + " )" ] }, { + "attachments": {}, "cell_type": "markdown", "metadata": {}, "source": [ - "Finally, we plot the training results" + "The following cell performs the training, looping over the network for a low amount of epochs. We keep training minimal for the purpose of rapid testing." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch: 5 \n", + "Train_loss: 1.1216, acc: 0.9929\n", + "Val_loss: 0.8693, Val_acc: 0.7340\n", + "Test_loss: 0.8030, Test_acc: 0.7570\n", + "Epoch: 10 \n", + "Train_loss: 0.5751, acc: 1.0000\n", + "Val_loss: 1.6033, Val_acc: 0.7140\n", + "Test_loss: 1.3768, Test_acc: 0.7370\n", + "Epoch: 15 \n", + "Train_loss: 0.3835, acc: 1.0000\n", + "Val_loss: 2.6746, Val_acc: 0.7120\n", + "Test_loss: 2.2858, Test_acc: 0.7320\n", + "Epoch: 20 \n", + "Train_loss: 0.2876, acc: 1.0000\n", + "Val_loss: 3.5548, Val_acc: 0.7160\n", + "Test_loss: 3.0300, Test_acc: 0.7310\n", + "Epoch: 25 \n", + "Train_loss: 0.2301, acc: 1.0000\n", + "Val_loss: 4.1970, Val_acc: 0.7120\n", + "Test_loss: 3.5745, Test_acc: 0.7310\n", + "Epoch: 30 \n", + "Train_loss: 0.1917, acc: 1.0000\n", + "Val_loss: 4.6384, Val_acc: 0.7140\n", + "Test_loss: 3.9496, Test_acc: 0.7310\n" + ] + } + ], "source": [ - "plt.figure(dpi=300)\n", - "plt.plot(losses, label=\"Training loss\")\n", - "plt.plot(train_accs, label=\"Training accuracy\")\n", - "test_epochs = np.isfinite(test_accs)\n", - "plt.plot(\n", - " np.arange(num_epochs)[test_epochs],\n", - " test_accs[test_epochs],\n", - " label=\"Test accuracy\",\n", - " linestyle=\"-\",\n", - " marker=\"o\",\n", - ")\n", - "plt.legend()\n", - "plt.xlabel(\"Epochs\")\n", - "plt.title(\"Training results\")" + "\n", + "test_interval = 5\n", + "num_epochs = 30\n", + "\n", + "epoch_loss = []\n", + "for epoch_i in range(1, num_epochs + 1):\n", + " \n", + " model.train()\n", + "\n", + " opt.zero_grad()\n", + " \n", + " # Extract edge_index from sparse incidence matrix\n", + " y_hat = model(x_0s, incidence_1)\n", + " loss = loss_fn(y_hat[train_mask], y[train_mask])\n", + "\n", + " loss.backward()\n", + " opt.step()\n", + " epoch_loss.append(loss.item())\n", + "\n", + " \n", + "\n", + " if epoch_i % test_interval == 0:\n", + " \n", + " model.eval()\n", + " y_hat = model(x_0s, incidence_1)\n", + "\n", + " loss = loss_fn(y_hat[train_mask], y[train_mask])\n", + " print(f\"Epoch: {epoch_i} \")\n", + " print(f\"Train_loss: {np.mean(epoch_loss):.4f}, acc: {acc_fn(y_hat[train_mask].argmax(1), y[train_mask]):.4f}\",flush=True)\n", + "\n", + " loss = loss_fn(y_hat[val_mask], y[val_mask])\n", + " \n", + " print(f\"Val_loss: {loss:.4f}, Val_acc: {acc_fn(y_hat[val_mask].argmax(1), y[val_mask]):.4f}\", flush=True)\n", + "\n", + " loss = loss_fn(y_hat[test_mask], y[test_mask])\n", + " print(f\"Test_loss: {loss:.4f}, Test_acc: {acc_fn(y_hat[test_mask].argmax(1), y[test_mask]):.4f}\", flush=True)" ] } ], "metadata": { "kernelspec": { - "display_name": "my_conda_env_with_py310", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -6521,7 +531,11 @@ "pygments_lexer": "ipython3", "version": "3.11.3" }, - "orig_nbformat": 4 + "vscode": { + "interpreter": { + "hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6" + } + } }, "nbformat": 4, "nbformat_minor": 2 diff --git a/tutorials/hypergraph/hypergat_train.ipynb b/tutorials/hypergraph/hypergat_train.ipynb index 86fa18856..e46bef69a 100644 --- a/tutorials/hypergraph/hypergat_train.ipynb +++ b/tutorials/hypergraph/hypergat_train.ipynb @@ -208,23 +208,125 @@ "source": [ "# Train the Neural Network\n", "\n", - "We specify the model, the loss, and an optimizer." + "Define the network that initializes the base model and sets up the readout operation.\n", + "Different downstream tasks might require different pooling procedures." ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "class Network(torch.nn.Module):\n", + " \"\"\" Network class that initializes the AllSet model and readout layer.\n", + "\n", + " Base model parameters:\n", + " ----------\n", + " Reqired:\n", + " in_channels : int\n", + " Dimension of the input features.\n", + " hidden_channels : int\n", + " Dimension of the hidden features.\n", + "\n", + " Optitional:\n", + " **kwargs : dict\n", + " Additional arguments for the base model.\n", + " \n", + " Readout layer parameters:\n", + " ----------\n", + " out_channels : int\n", + " Dimension of the output features.\n", + " task_level : str\n", + " Level of the task. Either \"graph\" or \"node\". \n", + " \"\"\"\n", + " def __init__(\n", + " self, \n", + " in_channels, \n", + " hidden_channels,\n", + " out_channels, \n", + " \n", + " task_level=\"graph\",\n", + " **kwargs):\n", + " super().__init__()\n", + " \n", + " # Define the model\n", + " self.base_model = HyperGAT(\n", + " in_channels=in_channels,\n", + " hidden_channels=hidden_channels,\n", + " **kwargs\n", + " )\n", + "\n", + "\n", + " # Readout\n", + " self.linear = torch.nn.Linear(hidden_channels, out_channels)\n", + " self.out_pool = True if task_level == \"graph\" else False\n", + " \n", + " def forward(self, x_0, incidence_1):\n", + " # Base model\n", + " x_0, x_1 = self.base_model(x_0, incidence_1)\n", + "\n", + " # Pool over all nodes in the hypergraph \n", + " if self.out_pool is True:\n", + " x = torch.max(x_0, dim=0)[0]\n", + " else:\n", + " x = x_0\n", + "\n", + " return self.linear(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Initialize the model" + ] + }, + { + "cell_type": "code", + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ + "# Base model hyperparameters\n", "in_channels = x_0s[0].shape[1]\n", "hidden_channels = 32\n", "out_dim = 1\n", "n_layers = 3\n", "\n", - "# Define the model\n", - "model = HyperGAT(in_channels=in_channels, hidden_channels=hidden_channels, out_channels=out_dim, n_layers=n_layers)\n", - "model = model.to(device)\n", + "# Readout hyperparameters\n", + "out_channels = 1\n", + "task_level = \"graph\" \n", + "\n", + "\n", + "model = Network(\n", + " in_channels=in_channels,\n", + " hidden_channels=hidden_channels,\n", + " out_channels=out_channels, \n", + " n_layers=n_layers,\n", + " task_level=task_level,\n", + " ).to(device)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "# in_channels = x_0s[0].shape[1]\n", + "# hidden_channels = 32\n", + "# out_dim = 1\n", + "# n_layers = 3\n", + "\n", + "# # Define the model\n", + "# model = HyperGAT(\n", + "# in_channels=in_channels, \n", + "# hidden_channels=hidden_channels, \n", + "# out_channels=out_dim, \n", + "# n_layers=n_layers\n", + "# )\n", + "# model = model.to(device)\n", "\n", "# Optimizer and loss\n", "opt = torch.optim.Adam(model.parameters(), lr=0.01)\n", @@ -233,7 +335,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ @@ -245,24 +347,38 @@ "y_train, y_test = train_test_split(ys, test_size=test_size, shuffle=False)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The following cell performs the training, looping over the network for a low amount of epochs. We keep training minimal for the purpose of rapid testing." + ] + }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 11, "metadata": {}, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/usr/local/lib/python3.11/site-packages/torch/nn/modules/loss.py:536: UserWarning: Using a target size (torch.Size([])) that is different to the input size (torch.Size([1])). This will likely lead to incorrect results due to broadcasting. Please ensure they have the same size.\n", + " return F.mse_loss(input, target, reduction=self.reduction)\n" + ] + }, { "name": "stdout", "output_type": "stream", "text": [ - "Epoch: 5 train_loss 2793.0022 test_loss: 3603.5338\n", - "Epoch: 10 train_loss 850.0561 test_loss: 973.0185\n", - "Epoch: 15 train_loss 214.8615 test_loss: 419.0050\n", - "Epoch: 20 train_loss 131.6955 test_loss: 234.3142\n" + "Epoch: 5 train_loss 1576.8879 test_loss: 5926.1705\n", + "Epoch: 10 train_loss 1071.0735 test_loss: 2550.9387\n", + "Epoch: 15 train_loss 2870.6875 test_loss: 1568.6725\n", + "Epoch: 20 train_loss 253.5367 test_loss: 662.3142\n" ] } ], "source": [ - "\n", "test_interval = 5\n", "num_epochs = 20\n", "for epoch_i in range(1, num_epochs + 1):\n", diff --git a/tutorials/hypergraph/hypersage_train.ipynb b/tutorials/hypergraph/hypersage_train.ipynb index 4f9f2eef7..d4ff2808a 100644 --- a/tutorials/hypergraph/hypersage_train.ipynb +++ b/tutorials/hypergraph/hypersage_train.ipynb @@ -5,33 +5,35 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Train an All-Set TNN\n", + "# Train a Hypersage TNN\n", "\n", - "In this notebook, we will create and train a two-step message passing network named AllSet (Chien et al., [2021](https://arxiv.org/abs/2106.13264)) in the hypergraph domain. We will use a benchmark dataset, shrec16, a collection of 3D meshes, to train the model to perform classification at the level of the hypergraph. \n", + "In this notebook, we will create and train HyperSAGE layer (Arya et al., [2020](https://arxiv.org/abs/2010.04558)) - two-levels message passing strategy for hypergraphs learning. We will use a benchmark dataset, shrec16, a collection of 3D meshes, to train the model to perform classification at the level of the hypergraph.\n", "\n", - "🟧 $\\quad m_{\\rightarrow z}^{(\\rightarrow 1)} = AGG_{y \\in \\mathcal{B}(z)} (h_y^{t, (0)}, h_z^{t,(1)})$ \n", + "Following the \"awesome-tnns\" [github repo.](https://github.com/awesome-tnns/awesome-tnns/blob/main/Hypergraphs.md)\n", "\n", - "🟦 $\\quad h_z^{t+1,(1)} = \\sigma(m_{\\rightarrow z}^{(\\rightarrow 1)})$ \n", + "🟥 $\\quad m_{y \\rightarrow z}^{(0 \\rightarrow 1)} = (B_1)^T_{zy} \\cdot w_y \\cdot (h_y^{(0)})^p$ \n", "\n", - "Edge to vertex: \n", + "🟥 $\\quad m_z^{(0 \\rightarrow 1)} = \\left(\\frac{1}{\\vert \\mathcal{B}(z)\\vert}\\sum_{y \\in \\mathcal{B}(z)} m_{y \\rightarrow z}^{(0 \\rightarrow 1)}\\right)^{\\frac{1}{p}}$\n", "\n", - "🟧 $\\quad m_{\\rightarrow x}^{(\\rightarrow 0)} = AGG_{z \\in \\mathcal{C}(x)} (h_z^{t+1,(1)}, h_x^{t,(0)})$ \n", + "🟥 $\\quad m_{z \\rightarrow x}^{(1 \\rightarrow 0)} = (B_1)_{xz} \\cdot w_z \\cdot (m_z^{(0 \\rightarrow 1)})^p$\n", "\n", - "🟦 $\\quad h_x^{t+1,(0)} = \\sigma(m_{\\rightarrow x}^{(\\rightarrow 0)})$\n", + "🟧 $\\quad m_x^{(1 \\rightarrow 0)} = \\left(\\frac{1}{\\vert \\mathcal{C}(x) \\vert}\\sum_{z \\in \\mathcal{C}(x)} m_{z \\rightarrow x}^{(1 \\rightarrow 0)}\\right)^{\\frac{1}{p}}$\n", "\n", - "### Additional theoretical clarifications\n", - "Given a hypergraph $G=(\\mathcal{V}, \\mathcal{E})$, let $\\textbf{X} \\in \\mathbb{R}^{|\\mathcal{V}| \\times F}$ and $\\textbf{Z} \\in \\mathbb{R}^{|\\mathcal{E}| \\times F'}$ denote the hidden node and hyperedge representations, respectively. Additionally, define $V_{e, \\textbf{X}} = \\{\\textbf{X}_{u,:}: u \\in e\\}$ as the multiset of hidden node representations in the hyperedge $e$ and $E_{v, \\textbf{Z}} = \\{\\textbf{Z}_{e,:}: v \\in e\\}$ as the multiset of hidden representations of hyperedges containing $v$.\n", + "🟩 $\\quad m_x^{(0)} = m_x^{(1 \\rightarrow 0)}$ \n", + "\n", + "🟦 $\\quad h_x^{t+1, (0)} = \\sigma \\left(\\frac{m_x^{(0)} + h_x^{t,(0)}}{\\lvert m_x^{(0)} + h_x^{t,(0)}\\rvert} \\cdot \\Theta^t\\right)$ \n", "\n", - "\\\n", - "In this setting, the two general update rules that AllSet's framework puts in place in each layer are:\n", + "### Additional theoretical clarifications\n", "\n", - "🔷 $\\textbf{Z}_{e,:}^{(t+1)} = f_{\\mathcal{V} \\rightarrow \\mathcal{E}}(V_{e, \\textbf{X}^{(t)}}; \\textbf{Z}_{e,:}^{(t)})$\n", + "Arya et al propose to interpret the propagation of information in a given hypergraph as a two-level aggregation problem, where the neighborhood of any node is divided into intra-edge neighbors and inter-edge neighbors. Given a hypergraph $H=(\\mathcal{V}, \\mathcal{E})$, let $\\textbf{X}$ denote the feature matrix, such that $\\textbf{x}_{i} \\in \\textbf{X}$ is the feature set for node $\\textbf{v}_{i} \\in \\textbf{V}$ . For two-level aggregation, \n", + "let $\\mathcal{F}_{1}(·)$ and $\\mathcal{F}_{2}(·)$ denote the intra-edge and inter-edge aggregation functions, respectively. Message passing at node vi for aggregation of information at the $\\mathcal{l}^{th}$ layer can then be stated as\n", "\n", - "🔷 $\\textbf{X}_{v,:}^{(t+1)} = f_{\\mathcal{E} \\rightarrow \\mathcal{V}}(E_{v, \\textbf{Z}^{(t+1)}}; \\textbf{X}_{v,:}^{(t)})$\n", + "$ \\mathcal{x}_{i,l}^{(e)} \\leftarrow \\mathcal{F}_{1}(\\{ \\mathcal{x}_{j,l-1} | \\mathcal{v}_{j} \\in \\mathcal{N}( \\mathcal{v}_{i},\n", + "\\textbf{e},\\alpha) \\}), $\n", "\n", - "in which $f_{\\mathcal{V} \\rightarrow \\mathcal{E}}$ and $f_{\\mathcal{E} \\rightarrow \\mathcal{V}}$ are two permutation invariant functions with respect to their first input. The matrices $\\textbf{Z}_{e,:}^{(0)}$ and $\\textbf{X}_{v,:}^{(0)}$ are initialized with the hyperedge and node features respectively, if available, otherwise they are set to be all-zero matrices.\n", + "$ \\mathcal{x}_{i,l} \\leftarrow \\mathcal{x}_{i,l-1} + \\mathcal{F}_{2}(\\{ \\mathcal{x}_{i,l}^{(e)} | \\mathcal{v}_{i} \\in {E}( \\mathcal{v}_{i}) \\}), $\n", "\n", - "In the practical implementation of the model, $f_{\\mathcal{V} \\rightarrow \\mathcal{E}}$ and $f_{\\mathcal{E} \\rightarrow \\mathcal{V}}$ are parametrized and $learnt$ for each dataset and task, and the information of their second argument is not utilized. \n" + "where, $ \\mathcal{x}_{i,l}^{(e)}$ refers to the aggregated feature set at $\\mathcal{v}_{i}$ obtained with intra-edge aggregation for edge $\\textbf{e}$." ] }, { @@ -46,7 +48,7 @@ "outputs": [], "source": [ "\"\"\"\n", - "This module contains the AllSet class for hypergraph-based neural networks.\n", + "This module contains the HyperSAGE class for hypergraph-based neural networks.\n", "\n", "The AllSet class implements a specific hypergraph-based neural network architecture\n", "used for solving certain types of problems.\n", @@ -61,7 +63,9 @@ "import torch_geometric.datasets as geom_datasets\n", "\n", "from topomodelx.nn.hypergraph.hypersage import HyperSAGE\n", - "from topomodelx.utils.sparse import from_sparse\n" + "\n", + "torch.manual_seed(0)\n", + "np.random.seed(0)\n" ] }, { @@ -267,32 +271,109 @@ "# Create the Neural Network" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Define the network that initializes the base model and sets up the readout operation.\n", + "Different downstream tasks might require different pooling procedures.\n" + ] + }, { "cell_type": "code", "execution_count": 7, - "metadata": { - "ExecuteTime": { - "end_time": "2023-06-01T16:14:55.343005145Z", - "start_time": "2023-06-01T16:14:55.339481459Z" - } - }, + "metadata": {}, "outputs": [], "source": [ + "class Network(torch.nn.Module):\n", + " \"\"\" Network class that initializes the base model and readout layer.\n", + "\n", + " Base model parameters:\n", + " ----------\n", + " Reqired:\n", + " in_channels : int\n", + " Dimension of the input features.\n", + " hidden_channels : int\n", + " Dimension of the hidden features.\n", + "\n", + " Optitional:\n", + " **kwargs : dict\n", + " Additional arguments for the base model.\n", + " \n", + " Readout layer parameters:\n", + " ----------\n", + " out_channels : int\n", + " Dimension of the output features.\n", + " task_level : str\n", + " Level of the task. Either \"graph\" or \"node\". \n", + " \"\"\"\n", + " def __init__(\n", + " self, \n", + " in_channels, \n", + " hidden_channels,\n", + " out_channels, \n", + " \n", + " task_level=\"graph\",\n", + " **kwargs):\n", + " super().__init__()\n", + " \n", + " # Define the model\n", + " self.base_model = HyperSAGE(\n", + " in_channels=in_channels,\n", + " hidden_channels=hidden_channels,\n", + " **kwargs\n", + " )\n", + "\n", + "\n", + " # Readout\n", + " self.linear = torch.nn.Linear(hidden_channels, out_channels)\n", + " self.out_pool = True if task_level == \"graph\" else False\n", + " \n", + " def forward(self, x_0, incidence_1):\n", + " # Base model\n", + " x_0 = self.base_model(x_0, incidence_1)\n", + "\n", + " # Pool over all nodes in the hypergraph \n", + " if self.out_pool is True:\n", + " x = torch.max(x_0, dim=0)[0]\n", + " else:\n", + " x = x_0\n", + "\n", + " return self.linear(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Initialize the model" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# Base model hyperparameters\n", "in_channels = x_0s.shape[1]\n", "hidden_channels = 128\n", + "n_layers=1\n", + "mlp_num_layers=1\n", + "\n", + "# Readout hyperparameters\n", "out_channels = torch.unique(y).shape[0]\n", "task_level = \"graph\" if out_channels==1 else \"node\"\n", - "n_layers=1\n", "\n", - "model = HyperSAGE(\n", + "\n", + "model = Network(\n", " in_channels=in_channels,\n", " hidden_channels=hidden_channels,\n", - " out_channels=out_channels,\n", + " out_channels=out_channels, \n", " n_layers=n_layers,\n", - " device=\"cpu\",\n", - " \n", - ")\n", - "model = model.to(device)" + " device=device,\n", + " task_level=task_level,\n", + " ).to(device)" ] }, { @@ -307,7 +388,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ @@ -323,7 +404,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 11, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:59.046068930Z", @@ -335,9 +416,9 @@ "name": "stderr", "output_type": "stream", "text": [ - "/tmp/ipykernel_452380/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_703454/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " x_0s = torch.tensor(x_0s)\n", - "/tmp/ipykernel_452380/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_703454/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " torch.tensor(y, dtype=torch.long).to(device),\n" ] } @@ -361,7 +442,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -369,29 +450,29 @@ "output_type": "stream", "text": [ "Epoch: 5 \n", - "Train_loss: 1.9424, acc: 0.1571\n", - "Val_loss: 1.9429, Val_acc: 0.1220\n", - "Test_loss: 1.9424, Test_acc: 0.1300\n", + "Train_loss: 1.9426, acc: 0.3357\n", + "Val_loss: 1.9326, Val_acc: 0.2720\n", + "Test_loss: 1.9334, Test_acc: 0.2660\n", "Epoch: 10 \n", - "Train_loss: 1.9310, acc: 0.9286\n", - "Val_loss: 1.9259, Val_acc: 0.4980\n", - "Test_loss: 1.9261, Test_acc: 0.4960\n", + "Train_loss: 1.9306, acc: 0.8786\n", + "Val_loss: 1.9296, Val_acc: 0.4560\n", + "Test_loss: 1.9294, Test_acc: 0.4540\n", "Epoch: 15 \n", - "Train_loss: 1.9116, acc: 0.9857\n", - "Val_loss: 1.8915, Val_acc: 0.6960\n", - "Test_loss: 1.8925, Test_acc: 0.6970\n", + "Train_loss: 1.9107, acc: 0.9643\n", + "Val_loss: 1.9026, Val_acc: 0.5480\n", + "Test_loss: 1.9021, Test_acc: 0.5300\n", "Epoch: 20 \n", - "Train_loss: 1.8826, acc: 1.0000\n", - "Val_loss: 1.8473, Val_acc: 0.7140\n", - "Test_loss: 1.8488, Test_acc: 0.7150\n", + "Train_loss: 1.8813, acc: 1.0000\n", + "Val_loss: 1.8525, Val_acc: 0.6880\n", + "Test_loss: 1.8527, Test_acc: 0.6820\n", "Epoch: 25 \n", - "Train_loss: 1.8432, acc: 0.9929\n", - "Val_loss: 1.7892, Val_acc: 0.7360\n", - "Test_loss: 1.7912, Test_acc: 0.7180\n", + "Train_loss: 1.8415, acc: 1.0000\n", + "Val_loss: 1.7858, Val_acc: 0.7460\n", + "Test_loss: 1.7870, Test_acc: 0.7270\n", "Epoch: 30 \n", - "Train_loss: 1.7929, acc: 0.9857\n", - "Val_loss: 1.7125, Val_acc: 0.7460\n", - "Test_loss: 1.7151, Test_acc: 0.7180\n" + "Train_loss: 1.7908, acc: 1.0000\n", + "Val_loss: 1.7072, Val_acc: 0.7460\n", + "Test_loss: 1.7094, Test_acc: 0.7330\n" ] } ], @@ -415,8 +496,6 @@ " opt.step()\n", " epoch_loss.append(loss.item())\n", "\n", - " \n", - "\n", " if epoch_i % test_interval == 0:\n", " \n", " model.eval()\n", diff --git a/tutorials/hypergraph/unigcn_train.ipynb b/tutorials/hypergraph/unigcn_train.ipynb index c5362e555..6ef1aaa15 100644 --- a/tutorials/hypergraph/unigcn_train.ipynb +++ b/tutorials/hypergraph/unigcn_train.ipynb @@ -13,13 +13,39 @@ "from torch_geometric.datasets import TUDataset\n", "from torch_geometric.utils.convert import to_networkx\n", "from toponetx.classes.simplicial_complex import SimplicialComplex\n", - "\n", + "from topomodelx.utils.sparse import from_sparse\n", "from topomodelx.nn.hypergraph.unigcn import UniGCN\n", - "import warnings\n", "\n", - "warnings.filterwarnings(\"ignore\")\n", - "# %load_ext autoreload\n", - "# %autoreload 2" + "\n", + "torch.manual_seed(0)\n", + "np.random.seed(0)" + ] + }, + { + "cell_type": "markdown", + "id": "b413568a", + "metadata": {}, + "source": [ + "If GPU's are available, we will make use of them. Otherwise, this will run on CPU.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "cc0ff113", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "cpu\n" + ] + } + ], + "source": [ + "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n", + "print(device)" ] }, { @@ -48,7 +74,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "id": "8075441c", "metadata": {}, "outputs": [], @@ -61,14 +87,14 @@ "for graph in dataset:\n", " hg = SimplicialComplex(to_networkx(graph)).to_hypergraph()\n", " hg_list.append(hg)\n", - " x_1_list.append(graph.x)\n", - " y_list.append(int(graph.y))\n", + " x_1_list.append(graph.x.to(device))\n", + " y_list.append(int(graph.y.to(device)))\n", "\n", "incidence_1_list = []\n", "for hg in hg_list:\n", " incidence_1 = hg.incidence_matrix()\n", - " incidence_1 = torch.from_numpy(incidence_1.todense()).to_sparse_csr()\n", - " incidence_1_list.append(incidence_1)" + " incidence_1 = from_sparse(incidence_1)\n", + " incidence_1_list.append(incidence_1.to(device))" ] }, { @@ -78,28 +104,107 @@ "source": [ "# Create the Neural Network\n", "\n", - "Using the UniGCNLayer class, we create a neural network with stacked layers." + "Define the network that initializes the base model and sets up the readout operation.\n", + "Different downstream tasks might require different pooling procedures." ] }, { "cell_type": "code", - "execution_count": 3, - "id": "ccbc8498", + "execution_count": 4, + "id": "fb337a87", "metadata": {}, "outputs": [], "source": [ - "channels_edge = x_1_list[0].shape[1]\n", + "class Network(torch.nn.Module):\n", + " \"\"\" Network class that initializes the base model and readout layer.\n", + "\n", + " Base model parameters:\n", + " ----------\n", + " Reqired:\n", + " in_channels : int\n", + " Dimension of the input features.\n", + " hidden_channels : int\n", + " Dimension of the hidden features.\n", + "\n", + " Optitional:\n", + " **kwargs : dict\n", + " Additional arguments for the base model.\n", + " \n", + " Readout layer parameters:\n", + " ----------\n", + " out_channels : int\n", + " Dimension of the output features.\n", + " task_level : str\n", + " Level of the task. Either \"graph\" or \"node\". \n", + " \"\"\"\n", + " def __init__(\n", + " self, \n", + " in_channels, \n", + " hidden_channels,\n", + " out_channels, \n", + " \n", + " task_level=\"graph\",\n", + " **kwargs):\n", + " super().__init__()\n", + " \n", + " # Define the model\n", + " self.base_model = UniGCN(\n", + " in_channels=in_channels,\n", + " hidden_channels=hidden_channels,\n", + " **kwargs\n", + " )\n", + "\n", + "\n", + " # Readout\n", + " self.linear = torch.nn.Linear(hidden_channels, out_channels)\n", + " self.out_pool = True if task_level == \"graph\" else False\n", + " \n", + " def forward(self, x_0, incidence_1):\n", + " # Base model\n", + " x_0, x_1 = self.base_model(x_0, incidence_1)\n", + "\n", + " # Pool over all nodes in the hypergraph \n", + " if self.out_pool is True:\n", + " x = torch.max(x_0, dim=0)[0]\n", + " else:\n", + " x = x_0\n", + "\n", + " return self.linear(x)" + ] + }, + { + "cell_type": "markdown", + "id": "30a7fc1c", + "metadata": {}, + "source": [ + "Initialize the model" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "9ed1b248", + "metadata": {}, + "outputs": [], + "source": [ + "# Base model hyperparameters\n", + "in_channels = x_1_list[0].shape[1]\n", "hidden_channels = 32\n", - "out_channels = 1\n", "n_layers = 2\n", - "task_level = \"graph\" if out_channels==1 else \"node\"\n", + "mlp_num_layers=1\n", + "\n", + "# Readout hyperparameters\n", + "out_channels = 2\n", + "task_level = \"graph\"\n", "\n", - "model = UniGCN(\n", - " in_channels=channels_edge,\n", - " hidden_channels=hidden_channels,\n", - " out_channels=out_channels,\n", - " n_layers=n_layers,\n", - " task_level=task_level,)" + "\n", + "model = Network(\n", + " in_channels=in_channels,\n", + " hidden_channels=hidden_channels,\n", + " out_channels=out_channels,\n", + " n_layers=n_layers,\n", + " task_level=task_level,\n", + " ).to(device)" ] }, { @@ -114,13 +219,13 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 7, "id": "2f3d2abf", "metadata": {}, "outputs": [], "source": [ - "optimizer = torch.optim.Adam(model.parameters(), lr=1e-2)\n", - "crit = torch.nn.BCELoss()" + "optimizer = torch.optim.Adam(model.parameters(), lr=0.01)\n", + "crit = torch.nn.CrossEntropyLoss()" ] }, { @@ -133,7 +238,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 8, "id": "505a424d", "metadata": {}, "outputs": [], @@ -161,71 +266,67 @@ }, { "cell_type": "code", - "execution_count": 6, - "id": "d64c7e80", + "execution_count": 9, + "id": "78e26ec9", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Epoch 0 train loss: 88.3000259399414\n", - "Epoch 0 Val acc: 0.4375\n", - "Epoch 10 train loss: 49.60942077636719\n", - "Epoch 10 Val acc: 0.5625\n", - "Epoch 20 train loss: 30.046979904174805\n", - "Epoch 20 Val acc: 0.625\n", - "Test accuracy: 0.8\n" + "Epoch 0 loss: 303.8309020996094\n", + "Epoch 0 Validation accuracy: 0.5625\n", + "Epoch 10 loss: 78.16102600097656\n", + "Epoch 10 Validation accuracy: 0.5625\n", + "Epoch 20 loss: 28.61541175842285\n", + "Epoch 20 Validation accuracy: 0.5625\n", + "Epoch 30 loss: 29.697616577148438\n", + "Epoch 30 Validation accuracy: 0.625\n", + "Epoch 40 loss: 26.69053077697754\n", + "Epoch 40 Validation accuracy: 0.625\n", + "Epoch 50 loss: 24.988874435424805\n", + "Epoch 50 Validation accuracy: 0.625\n", + "Epoch 60 loss: 23.865966796875\n", + "Epoch 60 Validation accuracy: 0.625\n", + "Test accuracy: 0.75\n" ] } ], "source": [ - "torch.manual_seed(0)\n", + "\n", "test_interval = 10\n", - "num_epochs = 30\n", + "num_epochs = 70\n", "for epoch in range(num_epochs):\n", " model.train()\n", " optimizer.zero_grad()\n", " loss = 0\n", " for x_1, incidence_1, y in zip(x_1_train, incidence_1_train, y_train):\n", - " output = model(x_1.float(), incidence_1.float())\n", - " output = torch.nn.functional.sigmoid(output)\n", - " loss += crit(output, torch.tensor([y]).float())\n", + " output = model(x_1, incidence_1)\n", + " loss += crit(output.unsqueeze(0), torch.tensor([y]))\n", " loss.backward()\n", " optimizer.step()\n", - " \n", " if epoch % test_interval == 0:\n", - " print(f\"Epoch {epoch} train loss: {loss.item()}\")\n", + " print(f\"Epoch {epoch} loss: {loss.item()}\")\n", " model.eval()\n", " with torch.no_grad():\n", " correct = 0\n", " for x_1, incidence_1, y in zip(x_1_val, incidence_1_val, y_val):\n", - " output = model(x_1.float(), incidence_1.float())\n", - " output = torch.nn.functional.sigmoid(output)\n", - " pred = output > 0.5\n", + " output = model(x_1, incidence_1)\n", + " pred = torch.argmax(output)\n", " if pred == y:\n", " correct += 1\n", - " print(f\"Epoch {epoch} Val acc: {correct / len(y_val)}\")\n", + " print(f\"Epoch {epoch} Validation accuracy: {correct / len(y_val)}\")\n", "\n", "model.eval()\n", "with torch.no_grad():\n", " correct = 0\n", " for x_1, incidence_1, y in zip(x_1_test, incidence_1_test, y_test):\n", - " output = model(x_1.float(), incidence_1.float())\n", - " output = torch.nn.functional.sigmoid(output)\n", - " pred = output > 0.5\n", + " output = model(x_1, incidence_1)\n", + " pred = torch.argmax(output)\n", " if pred == y:\n", " correct += 1\n", " print(f\"Test accuracy: {correct / len(y_test)}\")" ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "efa3bc9b", - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/tutorials/hypergraph/unigcnii_train.ipynb b/tutorials/hypergraph/unigcnii_train.ipynb index 578860874..6976ac1f6 100644 --- a/tutorials/hypergraph/unigcnii_train.ipynb +++ b/tutorials/hypergraph/unigcnii_train.ipynb @@ -25,7 +25,10 @@ "import numpy as np\n", "import scipy.sparse as sp\n", "\n", - "from topomodelx.nn.hypergraph.unigcnii import UniGCNII" + "from topomodelx.nn.hypergraph.unigcnii import UniGCNII\n", + "\n", + "torch.manual_seed(0)\n", + "np.random.seed(0)" ] }, { @@ -73,53 +76,53 @@ "name": "stdout", "output_type": "stream", "text": [ - "--2023-10-31 11:48:45-- https://github.com/malllabiisc/HyperGCN/raw/master/data/cocitation/cora/features.pickle\n", - "Resolving github.com (github.com)... 140.82.121.3\n", - "Connecting to github.com (github.com)|140.82.121.3|:443... connected.\n", + "--2023-11-03 14:49:01-- https://github.com/malllabiisc/HyperGCN/raw/master/data/cocitation/cora/features.pickle\n", + "Resolving github.com (github.com)... 140.82.121.4\n", + "Connecting to github.com (github.com)|140.82.121.4|:443... connected.\n", "HTTP request sent, awaiting response... 302 Found\n", "Location: https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/features.pickle [following]\n", - "--2023-10-31 11:48:46-- https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/features.pickle\n", - "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.109.133, 185.199.110.133, 185.199.111.133, ...\n", - "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.109.133|:443... connected.\n", + "--2023-11-03 14:49:01-- https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/features.pickle\n", + "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n", + "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.\n", "HTTP request sent, awaiting response... 200 OK\n", "Length: 404937 (395K) [application/octet-stream]\n", - "Saving to: ‘features.pickle.5’\n", + "Saving to: ‘features.pickle.1’\n", "\n", - "features.pickle.5 100%[===================>] 395.45K --.-KB/s in 0.006s \n", + "features.pickle.1 100%[===================>] 395.45K --.-KB/s in 0.04s \n", "\n", - "2023-10-31 11:48:46 (64.7 MB/s) - ‘features.pickle.5’ saved [404937/404937]\n", + "2023-11-03 14:49:02 (10.7 MB/s) - ‘features.pickle.1’ saved [404937/404937]\n", "\n", - "--2023-10-31 11:48:46-- https://github.com/malllabiisc/HyperGCN/raw/master/data/cocitation/cora/hypergraph.pickle\n", - "Resolving github.com (github.com)... 140.82.121.3\n", - "Connecting to github.com (github.com)|140.82.121.3|:443... connected.\n", + "--2023-11-03 14:49:02-- https://github.com/malllabiisc/HyperGCN/raw/master/data/cocitation/cora/hypergraph.pickle\n", + "Resolving github.com (github.com)... 140.82.121.4\n", + "Connecting to github.com (github.com)|140.82.121.4|:443... connected.\n", "HTTP request sent, awaiting response... 302 Found\n", "Location: https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/hypergraph.pickle [following]\n", - "--2023-10-31 11:48:46-- https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/hypergraph.pickle\n", - "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.109.133, 185.199.110.133, 185.199.111.133, ...\n", - "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.109.133|:443... connected.\n", + "--2023-11-03 14:49:02-- https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/hypergraph.pickle\n", + "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n", + "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.\n", "HTTP request sent, awaiting response... 200 OK\n", "Length: 101905 (100K) [application/octet-stream]\n", - "Saving to: ‘hypergraph.pickle.5’\n", + "Saving to: ‘hypergraph.pickle.1’\n", "\n", - "hypergraph.pickle.5 100%[===================>] 99.52K --.-KB/s in 0.02s \n", + "hypergraph.pickle.1 100%[===================>] 99.52K --.-KB/s in 0.02s \n", "\n", - "2023-10-31 11:48:46 (4.63 MB/s) - ‘hypergraph.pickle.5’ saved [101905/101905]\n", + "2023-11-03 14:49:02 (4.43 MB/s) - ‘hypergraph.pickle.1’ saved [101905/101905]\n", "\n", - "--2023-10-31 11:48:46-- https://github.com/malllabiisc/HyperGCN/raw/master/data/cocitation/cora/labels.pickle\n", - "Resolving github.com (github.com)... 140.82.121.3\n", - "Connecting to github.com (github.com)|140.82.121.3|:443... connected.\n", + "--2023-11-03 14:49:03-- https://github.com/malllabiisc/HyperGCN/raw/master/data/cocitation/cora/labels.pickle\n", + "Resolving github.com (github.com)... 140.82.121.4\n", + "Connecting to github.com (github.com)|140.82.121.4|:443... connected.\n", "HTTP request sent, awaiting response... 302 Found\n", "Location: https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/labels.pickle [following]\n", - "--2023-10-31 11:48:47-- https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/labels.pickle\n", - "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.109.133, 185.199.110.133, 185.199.111.133, ...\n", - "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.109.133|:443... connected.\n", + "--2023-11-03 14:49:03-- https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/labels.pickle\n", + "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n", + "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.\n", "HTTP request sent, awaiting response... 200 OK\n", "Length: 5436 (5.3K) [application/octet-stream]\n", - "Saving to: ‘labels.pickle.5’\n", + "Saving to: ‘labels.pickle.1’\n", "\n", - "labels.pickle.5 100%[===================>] 5.31K --.-KB/s in 0s \n", + "labels.pickle.1 100%[===================>] 5.31K --.-KB/s in 0s \n", "\n", - "2023-10-31 11:48:47 (57.9 MB/s) - ‘labels.pickle.5’ saved [5436/5436]\n", + "2023-11-03 14:49:03 (49.2 MB/s) - ‘labels.pickle.1’ saved [5436/5436]\n", "\n" ] } @@ -139,21 +142,21 @@ "name": "stdout", "output_type": "stream", "text": [ - "--2023-10-31 11:48:47-- https://github.com/malllabiisc/HyperGCN/raw/master/data/cocitation/cora/splits/1.pickle\n", - "Resolving github.com (github.com)... 140.82.121.3\n", - "Connecting to github.com (github.com)|140.82.121.3|:443... connected.\n", + "--2023-11-03 14:49:04-- https://github.com/malllabiisc/HyperGCN/raw/master/data/cocitation/cora/splits/1.pickle\n", + "Resolving github.com (github.com)... 140.82.121.4\n", + "Connecting to github.com (github.com)|140.82.121.4|:443... connected.\n", "HTTP request sent, awaiting response... 302 Found\n", "Location: https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/splits/1.pickle [following]\n", - "--2023-10-31 11:48:47-- https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/splits/1.pickle\n", - "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.109.133, 185.199.110.133, 185.199.111.133, ...\n", - "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.109.133|:443... connected.\n", + "--2023-11-03 14:49:04-- https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/splits/1.pickle\n", + "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n", + "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.\n", "HTTP request sent, awaiting response... 200 OK\n", "Length: 51582 (50K) [application/octet-stream]\n", - "Saving to: ‘1.pickle.5’\n", + "Saving to: ‘1.pickle.1’\n", "\n", - "1.pickle.5 100%[===================>] 50.37K --.-KB/s in 0.01s \n", + "1.pickle.1 100%[===================>] 50.37K --.-KB/s in 0.002s \n", "\n", - "2023-10-31 11:48:47 (4.02 MB/s) - ‘1.pickle.5’ saved [51582/51582]\n", + "2023-11-03 14:49:04 (27.8 MB/s) - ‘1.pickle.1’ saved [51582/51582]\n", "\n" ] } @@ -178,7 +181,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/tmp/ipykernel_42535/2369537045.py:2: DeprecationWarning: Please use `csr_matrix` from the `scipy.sparse` namespace, the `scipy.sparse.csr` namespace is deprecated.\n", + "/tmp/ipykernel_670387/2369537045.py:2: DeprecationWarning: Please use `csr_matrix` from the `scipy.sparse` namespace, the `scipy.sparse.csr` namespace is deprecated.\n", " features = pickle.load(handle).todense()\n" ] } @@ -231,7 +234,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/tmp/ipykernel_42535/2226475299.py:6: UserWarning: Sparse CSR tensor support is in beta state. If you miss a functionality in the sparse tensor support, please submit a feature request to https://github.com/pytorch/pytorch/issues. (Triggered internally at ../aten/src/ATen/SparseCsrTensorImpl.cpp:54.)\n", + "/tmp/ipykernel_670387/2226475299.py:6: UserWarning: Sparse CSR tensor support is in beta state. If you miss a functionality in the sparse tensor support, please submit a feature request to https://github.com/pytorch/pytorch/issues. (Triggered internally at ../aten/src/ATen/SparseCsrTensorImpl.cpp:54.)\n", " incidence = torch.Tensor(incidence).to_sparse_csr()\n" ] } @@ -275,27 +278,109 @@ "## Creating a neural network" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Define the network that initializes the base model and sets up the readout operation.\n", + "Different downstream tasks might require different pooling procedures.\n" + ] + }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ + "class Network(torch.nn.Module):\n", + " \"\"\" Network class that initializes the base model and readout layer.\n", + "\n", + " Base model parameters:\n", + " ----------\n", + " Reqired:\n", + " in_channels : int\n", + " Dimension of the input features.\n", + " hidden_channels : int\n", + " Dimension of the hidden features.\n", + "\n", + " Optitional:\n", + " **kwargs : dict\n", + " Additional arguments for the base model.\n", + " \n", + " Readout layer parameters:\n", + " ----------\n", + " out_channels : int\n", + " Dimension of the output features.\n", + " task_level : str\n", + " Level of the task. Either \"graph\" or \"node\". \n", + " \"\"\"\n", + " def __init__(\n", + " self, \n", + " in_channels, \n", + " hidden_channels,\n", + " out_channels, \n", + " task_level=\"graph\",\n", + " **kwargs):\n", + " super().__init__()\n", + " \n", + " # Define the model\n", + " self.base_model = UniGCNII(\n", + " in_channels=in_channels,\n", + " hidden_channels=hidden_channels,\n", + " **kwargs\n", + " )\n", + "\n", + "\n", + " # Readout\n", + " self.linear = torch.nn.Linear(hidden_channels, out_channels)\n", + " self.out_pool = True if task_level == \"graph\" else False\n", + " \n", + " def forward(self, x_0, incidence_1):\n", + " # Base model\n", + " x_0, x_1 = self.base_model(x_0, incidence_1)\n", + "\n", + " # Pool over all nodes in the hypergraph \n", + " if self.out_pool is True:\n", + " x = torch.max(x_0, dim=0)[0]\n", + " else:\n", + " x = x_0\n", + "\n", + " return self.linear(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Initialize the model" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "# Base model hyperparameters\n", "in_channels = x_0.shape[1]\n", "hidden_channels = 128\n", + "n_layers=2\n", + "mlp_num_layers=1\n", + "input_drop=0.5\n", + "\n", + "# Readout hyperparameters\n", "out_channels = torch.unique(y).shape[0]\n", "task_level = \"graph\" if out_channels==1 else \"node\"\n", - "n_layers=2\n", "\n", - "model = UniGCNII(\n", + "\n", + "model = Network(\n", " in_channels=in_channels,\n", " hidden_channels=hidden_channels,\n", " out_channels=out_channels,\n", " n_layers=n_layers,\n", - " input_drop=0.5,\n", + " input_drop=input_drop,\n", " task_level=task_level,\n", - " \n", - ").to(device)" + " ).to(device)" ] }, { @@ -309,7 +394,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -326,7 +411,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ @@ -349,24 +434,24 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Epoch: 0 Train_loss: 1.6293, Train_acc: 0.9000 Test_loss: 1.8150, Test_acc: 0.5078\n", - "Epoch: 5 Train_loss: 0.0929, Train_acc: 1.0000 Test_loss: 0.9898, Test_acc: 0.6928\n", - "Epoch: 10 Train_loss: 0.0060, Train_acc: 1.0000 Test_loss: 2.0497, Test_acc: 0.6515\n", - "Epoch: 15 Train_loss: 0.0097, Train_acc: 0.9929 Test_loss: 3.4201, Test_acc: 0.6604\n", - "Epoch: 20 Train_loss: 0.0007, Train_acc: 1.0000 Test_loss: 5.2454, Test_acc: 0.6293\n", - "Epoch: 25 Train_loss: 0.0000, Train_acc: 1.0000 Test_loss: 4.5545, Test_acc: 0.6538\n" + "Epoch: 0 Train_loss: 1.8349, Train_acc: 0.5000 Test_loss: 1.8957, Test_acc: 0.2819\n", + "Epoch: 5 Train_loss: 0.3446, Train_acc: 1.0000 Test_loss: 1.0406, Test_acc: 0.7099\n", + "Epoch: 10 Train_loss: 0.0204, Train_acc: 1.0000 Test_loss: 1.2339, Test_acc: 0.7079\n", + "Epoch: 15 Train_loss: 0.0401, Train_acc: 0.9929 Test_loss: 3.0919, Test_acc: 0.6223\n", + "Epoch: 20 Train_loss: 0.0021, Train_acc: 1.0000 Test_loss: 3.9843, Test_acc: 0.6083\n", + "Epoch: 25 Train_loss: 0.0006, Train_acc: 1.0000 Test_loss: 3.0639, Test_acc: 0.6748\n" ] } ], "source": [ - "torch.manual_seed(0)\n", + "\n", "for epoch in range(num_epochs):\n", " # set model to training mode\n", " model.train()\n", @@ -391,20 +476,6 @@ " Test_loss: {loss:.4f}, Test_acc: {acc_fn(y_hat[test_idx].argmax(1), y[test_idx]):.4f}\",\n", " flush=True)" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/tutorials/hypergraph/unigin_train.ipynb b/tutorials/hypergraph/unigin_train.ipynb index 81ac49fb5..62825f996 100644 --- a/tutorials/hypergraph/unigin_train.ipynb +++ b/tutorials/hypergraph/unigin_train.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ @@ -13,7 +13,35 @@ "from torch_geometric.utils.convert import to_networkx\n", "from toponetx.classes.simplicial_complex import SimplicialComplex\n", "from topomodelx.nn.hypergraph.unigin import UniGIN\n", - "from topomodelx.utils.sparse import from_sparse" + "from topomodelx.utils.sparse import from_sparse\n", + "\n", + "torch.manual_seed(0)\n", + "np.random.seed(0)\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If GPU's are available, we will make use of them. Otherwise, this will run on CPU." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "cpu\n" + ] + } + ], + "source": [ + "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n", + "print(device)" ] }, { @@ -41,7 +69,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ @@ -53,14 +81,14 @@ "for graph in dataset:\n", " hg = SimplicialComplex(to_networkx(graph)).to_hypergraph()\n", " hg_list.append(hg)\n", - " x_1_list.append(graph.x)\n", - " y_list.append(int(graph.y))\n", + " x_1_list.append(graph.x.to(device))\n", + " y_list.append(int(graph.y.to(device)))\n", "\n", "incidence_1_list = []\n", "for hg in hg_list:\n", " incidence_1 = hg.incidence_matrix()\n", " incidence_1 = from_sparse(incidence_1)\n", - " incidence_1_list.append(incidence_1)" + " incidence_1_list.append(incidence_1.to(device))" ] }, { @@ -70,30 +98,108 @@ "source": [ "# Create the Neural Network\n", "\n", - "Using the UniGINLayer class, we create a neural network with stacked layers." + "Define the network that initializes the base model and sets up the readout operation.\n", + "Different downstream tasks might require different pooling procedures.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "class Network(torch.nn.Module):\n", + " \"\"\" Network class that initializes the base modelo and readout layer.\n", + "\n", + " Base model parameters:\n", + " ----------\n", + " Reqired:\n", + " in_channels : int\n", + " Dimension of the input features.\n", + " hidden_channels : int\n", + " Dimension of the hidden features.\n", + "\n", + " Optitional:\n", + " **kwargs : dict\n", + " Additional arguments for the base model.\n", + " \n", + " Readout layer parameters:\n", + " ----------\n", + " out_channels : int\n", + " Dimension of the output features.\n", + " task_level : str\n", + " Level of the task. Either \"graph\" or \"node\". \n", + " \"\"\"\n", + " def __init__(\n", + " self, \n", + " in_channels, \n", + " hidden_channels,\n", + " out_channels, \n", + " \n", + " task_level=\"graph\",\n", + " **kwargs):\n", + " super().__init__()\n", + " \n", + " # Define the model\n", + " self.base_model = UniGIN(\n", + " in_channels=in_channels,\n", + " hidden_channels=hidden_channels,\n", + " **kwargs\n", + " )\n", + "\n", + "\n", + " # Readout\n", + " self.linear = torch.nn.Linear(hidden_channels, out_channels)\n", + " self.out_pool = True if task_level == \"graph\" else False\n", + " \n", + " def forward(self, x_0, incidence_1):\n", + " # Base model\n", + " x_0, x_1 = self.base_model(x_0, incidence_1)\n", + "\n", + " # Pool over all nodes in the hypergraph \n", + " if self.out_pool is True:\n", + " x = torch.max(x_0, dim=0)[0]\n", + " else:\n", + " x = x_0\n", + "\n", + " return self.linear(x)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Initialize the model" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 14, "metadata": {}, "outputs": [], "source": [ + "# Base model hyperparameters\n", "in_channels = x_1_list[0].shape[1]\n", "hidden_channels = 32\n", - "out_channels = 2\n", "n_layers= 3\n", + "mlp_num_layers=1\n", + "input_drop=0.2\n", + "layer_drop=0.2\n", + "\n", + "# Readout hyperparameters\n", + "out_channels = 2\n", "task_level = \"graph\"\n", "\n", - "model = UniGIN(\n", + "\n", + "model = Network(\n", " in_channels=in_channels,\n", " hidden_channels=hidden_channels,\n", - " out_channels=out_channels, \n", - " input_drop=0.2,\n", - " layer_drop=0.2,\n", + " input_drop=input_drop,\n", + " layer_drop=layer_drop,\n", " n_layers=n_layers,\n", + " out_channels=out_channels, \n", " task_level=task_level,\n", - ")" + " ).to(device)" ] }, { @@ -108,7 +214,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 15, "metadata": {}, "outputs": [], "source": [ @@ -126,7 +232,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 16, "metadata": {}, "outputs": [], "source": [ @@ -153,33 +259,32 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Epoch 0 loss: 264.6469421386719\n", + "Epoch 0 loss: 1279.834716796875\n", "Epoch 0 Validation accuracy: 0.5625\n", - "Epoch 10 loss: 41.20396041870117\n", - "Epoch 10 Validation accuracy: 0.5625\n", - "Epoch 20 loss: 35.169708251953125\n", - "Epoch 20 Validation accuracy: 0.5625\n", - "Epoch 30 loss: 30.082611083984375\n", + "Epoch 10 loss: 43.52538299560547\n", + "Epoch 10 Validation accuracy: 0.3125\n", + "Epoch 20 loss: 32.36000442504883\n", + "Epoch 20 Validation accuracy: 0.25\n", + "Epoch 30 loss: 28.736360549926758\n", "Epoch 30 Validation accuracy: 0.5625\n", - "Epoch 40 loss: 26.874971389770508\n", + "Epoch 40 loss: 26.598899841308594\n", "Epoch 40 Validation accuracy: 0.5625\n", - "Epoch 50 loss: 21.022449493408203\n", - "Epoch 50 Validation accuracy: 0.5625\n", - "Epoch 60 loss: 26.520870208740234\n", - "Epoch 60 Validation accuracy: 0.625\n", + "Epoch 50 loss: 24.64439582824707\n", + "Epoch 50 Validation accuracy: 0.625\n", + "Epoch 60 loss: 26.797300338745117\n", + "Epoch 60 Validation accuracy: 0.5625\n", "Test accuracy: 0.7\n" ] } ], "source": [ - "torch.manual_seed(0)\n", "test_interval = 10\n", "num_epochs = 70\n", "for epoch in range(num_epochs):\n", @@ -213,20 +318,6 @@ " correct += 1\n", " print(f\"Test accuracy: {correct / len(y_test)}\")" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/tutorials/hypergraph/unisage_train.ipynb b/tutorials/hypergraph/unisage_train.ipynb index f6acea943..a89b173df 100644 --- a/tutorials/hypergraph/unisage_train.ipynb +++ b/tutorials/hypergraph/unisage_train.ipynb @@ -10,14 +10,13 @@ "\n", "import torch\n", "import numpy as np\n", - "from sklearn.model_selection import train_test_split\n", "from torch_geometric.utils import to_undirected\n", "import torch_geometric.datasets as geom_datasets\n", "\n", "from topomodelx.nn.hypergraph.unisage import UniSAGE\n", - "import warnings\n", "\n", - "warnings.filterwarnings(\"ignore\")" + "torch.manual_seed(0)\n", + "np.random.seed(0)" ] }, { @@ -64,7 +63,16 @@ "execution_count": 3, "id": "b9e6b0d0", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/usr/local/lib/python3.11/site-packages/torch_geometric/data/in_memory_dataset.py:284: UserWarning: It is not recommended to directly access the internal storage format `data` of an 'InMemoryDataset'. If you are absolutely certain what you are doing, access the internal storage via `InMemoryDataset._data` instead to suppress this warning. Alternatively, you can access stacked individual attributes of every graph via `dataset.{attr_name}`.\n", + " warnings.warn(msg)\n" + ] + } + ], "source": [ "cora = geom_datasets.Planetoid(root=\"/TopoModelX/data/cora\", name=\"Cora\")\n", "data = cora.data\n", @@ -203,22 +211,99 @@ "source": [ "# Create the Neural Network\n", "\n", - "Using the UniSAGELayer class, we create a neural network with stacked layers." + "Define the network that initializes the base model and sets up the readout operation.\n", + "Different downstream tasks might require different pooling procedures.\n" ] }, { "cell_type": "code", "execution_count": 7, - "id": "4e133a18", + "id": "f9bb2b49", + "metadata": {}, + "outputs": [], + "source": [ + "class Network(torch.nn.Module):\n", + " \"\"\" Network class that initializes the base model and readout layer.\n", + "\n", + " Base model parameters:\n", + " ----------\n", + " Reqired:\n", + " in_channels : int\n", + " Dimension of the input features.\n", + " hidden_channels : int\n", + " Dimension of the hidden features.\n", + "\n", + " Optitional:\n", + " **kwargs : dict\n", + " Additional arguments for the base model.\n", + " \n", + " Readout layer parameters:\n", + " ----------\n", + " out_channels : int\n", + " Dimension of the output features.\n", + " task_level : str\n", + " Level of the task. Either \"graph\" or \"node\". \n", + " \"\"\"\n", + " def __init__(\n", + " self, \n", + " in_channels, \n", + " hidden_channels,\n", + " out_channels, \n", + " \n", + " task_level=\"graph\",\n", + " **kwargs):\n", + " super().__init__()\n", + " \n", + " # Define the model\n", + " self.base_model = UniSAGE(\n", + " in_channels=in_channels,\n", + " hidden_channels=hidden_channels,\n", + " **kwargs\n", + " )\n", + "\n", + "\n", + " # Readout\n", + " self.linear = torch.nn.Linear(hidden_channels, out_channels)\n", + " self.out_pool = True if task_level == \"graph\" else False\n", + " \n", + " def forward(self, x_0, incidence_1):\n", + " # Base model\n", + " x_0, x_1 = self.base_model(x_0, incidence_1)\n", + "\n", + " # Pool over all nodes in the hypergraph \n", + " if self.out_pool is True:\n", + " x = torch.max(x_0, dim=0)[0]\n", + " else:\n", + " x = x_0\n", + "\n", + " return self.linear(x)" + ] + }, + { + "cell_type": "markdown", + "id": "edf5c31c", + "metadata": {}, + "source": [ + "Initialize the model" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "9d0f3923", "metadata": {}, "outputs": [], "source": [ + "# Base model hyperparameters\n", "in_channels = x_0s.shape[1]\n", "hidden_channels = 128\n", + "n_layers=1\n", + "\n", + "# Readout hyperparameters\n", "out_channels = torch.unique(y).shape[0]\n", "task_level = \"graph\" if out_channels==1 else \"node\"\n", - "n_layers=1\n", - "model = UniSAGE(\n", + "\n", + "model = Network(\n", " in_channels=in_channels,\n", " hidden_channels=hidden_channels,\n", " out_channels=out_channels, \n", @@ -226,7 +311,7 @@ " layer_drop=0.2,\n", " n_layers=n_layers,\n", " task_level=task_level,\n", - ").to(device)" + " ).to(device)" ] }, { @@ -241,7 +326,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "id": "89ae1cce", "metadata": {}, "outputs": [], @@ -258,10 +343,21 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 10, "id": "078a11cd", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/tmp/ipykernel_662599/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + " x_0s = torch.tensor(x_0s)\n", + "/tmp/ipykernel_662599/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + " torch.tensor(y, dtype=torch.long).to(device),\n" + ] + } + ], "source": [ "x_0s = torch.tensor(x_0s)\n", "x_0s, incidence_1, y = (\n", @@ -281,7 +377,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 11, "id": "491ebe34", "metadata": {}, "outputs": [ @@ -290,35 +386,49 @@ "output_type": "stream", "text": [ "Epoch: 5 \n", - "Train_loss: 1.1164, acc: 0.9714\n", - "Val_loss: 0.9324, Val_acc: 0.7820\n", - "Test_loss: 1.0056, Test_acc: 0.7930\n", + "Train_loss: 1.1114, acc: 0.9643\n", + "Val_loss: 0.9522, Val_acc: 0.7680\n", + "Test_loss: 1.0774, Test_acc: 0.7820\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ "Epoch: 10 \n", - "Train_loss: 0.6460, acc: 0.9929\n", - "Val_loss: 1.4363, Val_acc: 0.7640\n", - "Test_loss: 1.7823, Test_acc: 0.7450\n", - "Epoch: 15 \n", - "Train_loss: 0.4511, acc: 1.0000\n", - "Val_loss: 1.6066, Val_acc: 0.7520\n", - "Test_loss: 1.7711, Test_acc: 0.7620\n", - "Epoch: 20 \n", - "Train_loss: 0.3402, acc: 1.0000\n", - "Val_loss: 2.0556, Val_acc: 0.7520\n", - "Test_loss: 2.4377, Test_acc: 0.7490\n" + "Train_loss: 0.6466, acc: 0.9929\n", + "Val_loss: 1.3639, Val_acc: 0.7640\n", + "Test_loss: 1.5591, Test_acc: 0.7510\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/TopoModelX/topomodelx/nn/hypergraph/unisage_layer.py:120: UserWarning: Sparse CSR tensor support is in beta state. If you miss a functionality in the sparse tensor support, please submit a feature request to https://github.com/pytorch/pytorch/issues. (Triggered internally at ../aten/src/ATen/SparseCsrTensorImpl.cpp:54.)\n", + " incidence_1_transpose = incidence_1.T.to_sparse_csr()\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ + "Epoch: 15 \n", + "Train_loss: 0.4479, acc: 1.0000\n", + "Val_loss: 1.5922, Val_acc: 0.7680\n", + "Test_loss: 1.8342, Test_acc: 0.7620\n", + "Epoch: 20 \n", + "Train_loss: 0.3434, acc: 1.0000\n", + "Val_loss: 1.8131, Val_acc: 0.7620\n", + "Test_loss: 2.0800, Test_acc: 0.7640\n", "Epoch: 25 \n", - "Train_loss: 0.2747, acc: 1.0000\n", - "Val_loss: 2.1278, Val_acc: 0.7460\n", - "Test_loss: 2.4358, Test_acc: 0.7490\n", + "Train_loss: 0.2765, acc: 1.0000\n", + "Val_loss: 1.9989, Val_acc: 0.7620\n", + "Test_loss: 2.2934, Test_acc: 0.7660\n", "Epoch: 30 \n", - "Train_loss: 0.2295, acc: 1.0000\n", - "Val_loss: 2.2190, Val_acc: 0.7500\n", - "Test_loss: 2.5519, Test_acc: 0.7460\n" + "Train_loss: 0.2362, acc: 1.0000\n", + "Val_loss: 2.2402, Val_acc: 0.7600\n", + "Test_loss: 2.6936, Test_acc: 0.7470\n" ] } ], From 18719d57281fdfbd643291f3887f878611686392 Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Mon, 6 Nov 2023 10:50:48 +0000 Subject: [PATCH 08/39] tests --- test/nn/hypergraph/test_allset.py | 7 +- test/nn/hypergraph/test_allset_layer.py | 7 +- test/nn/hypergraph/test_allset_transformer.py | 7 +- .../test_allset_transformer_layer.py | 5 +- test/nn/hypergraph/test_dhgcn.py | 13 +- test/nn/hypergraph/test_dhgcn_layer.py | 4 +- test/nn/hypergraph/test_hmpnn.py | 28 +- test/nn/hypergraph/test_hnhn.py | 53 +--- test/nn/hypergraph/test_hnhn_layer.py | 22 +- test/nn/hypergraph/test_hypergat.py | 20 +- test/nn/hypergraph/test_hypergat_layer.py | 12 +- test/nn/hypergraph/test_hypersage.py | 11 +- test/nn/hypergraph/test_hypersage_layer.py | 1 - test/nn/hypergraph/test_unigcn.py | 19 +- test/nn/hypergraph/test_unigcn_layer.py | 16 +- test/nn/hypergraph/test_unigcnii.py | 24 +- test/nn/hypergraph/test_unigcnii_layer.py | 33 ++- test/nn/hypergraph/test_unigin.py | 21 +- test/nn/hypergraph/test_unigin_layer.py | 26 +- test/nn/hypergraph/test_unisage.py | 22 +- test/nn/hypergraph/test_unisage_layer.py | 11 +- topomodelx/nn/hypergraph/dhgcn.py | 36 +-- topomodelx/nn/hypergraph/dhgcn_layer.py | 8 +- topomodelx/nn/hypergraph/hnhn.py | 7 +- topomodelx/nn/hypergraph/hnhn_layer.py | 2 +- topomodelx/nn/hypergraph/hypergat.py | 4 +- topomodelx/nn/hypergraph/hypergat_layer.py | 18 +- topomodelx/nn/hypergraph/unigcn_layer.py | 2 +- topomodelx/nn/hypergraph/unigcnii_layer.py | 8 +- topomodelx/nn/hypergraph/unisage.py | 4 +- topomodelx/nn/hypergraph/unisage_layer.py | 10 +- tutorials/hypergraph/dhgcn_train.ipynb | 150 +++++++--- tutorials/hypergraph/hmpnn_train.ipynb | 19 +- tutorials/hypergraph/hnhn_train.ipynb | 23 +- tutorials/hypergraph/hypergat_train.ipynb | 8 +- tutorials/hypergraph/unigcnii_train.ipynb | 276 +++++++----------- 36 files changed, 475 insertions(+), 462 deletions(-) diff --git a/test/nn/hypergraph/test_allset.py b/test/nn/hypergraph/test_allset.py index 14e0e18e2..c7ed15490 100644 --- a/test/nn/hypergraph/test_allset.py +++ b/test/nn/hypergraph/test_allset.py @@ -15,7 +15,6 @@ def test_forward(self): model = AllSet( in_channels=4, hidden_channels=4, - out_channels=4, n_layers=2, mlp_num_layers=1, ) @@ -23,8 +22,8 @@ def test_forward(self): x_0 = torch.rand(4, 4) incidence_1 = torch.from_numpy(np.random.rand(4, 4)).to_sparse() - x_0 = torch.tensor(x_0).float().to(device) + x_0 = x_0.float().to(device) incidence_1 = incidence_1.float().to(device) - y = model(x_0, incidence_1) - assert y.shape == torch.Size([]) + x_0, _ = model(x_0, incidence_1) + assert x_0.shape==(4, 4) diff --git a/test/nn/hypergraph/test_allset_layer.py b/test/nn/hypergraph/test_allset_layer.py index 2e28495cb..6a783a27a 100644 --- a/test/nn/hypergraph/test_allset_layer.py +++ b/test/nn/hypergraph/test_allset_layer.py @@ -30,8 +30,11 @@ def test_forward(self, allset_layer): incidence_1 = torch.tensor( [[1, 0, 0], [0, 1, 1], [1, 1, 1]], dtype=torch.float32 ).to_sparse() - output = allset_layer.forward(x_0, incidence_1) - assert output.shape == (3, 64) + x_0, x_1 = allset_layer.forward(x_0, incidence_1) + + assert x_0.shape == (3, 64) + assert x_1.shape == (3, 64) + def test_AllSetBlock(self): """Test the AllSetBlock class. diff --git a/test/nn/hypergraph/test_allset_transformer.py b/test/nn/hypergraph/test_allset_transformer.py index f4606c7ea..6f0ade3df 100644 --- a/test/nn/hypergraph/test_allset_transformer.py +++ b/test/nn/hypergraph/test_allset_transformer.py @@ -16,7 +16,6 @@ def test_forward(self): in_channels=2, hidden_channels=2, heads=1, - out_channels=1, n_layers=2, mlp_num_layers=1, ) @@ -24,8 +23,8 @@ def test_forward(self): x_0 = torch.rand(2, 2) incidence_1 = torch.from_numpy(np.random.rand(2, 2)).to_sparse() - x_0 = torch.tensor(x_0).float().to(device) + x_0 = x_0.float().to(device) incidence_1 = incidence_1.float().to(device) - y = model(x_0, incidence_1) - assert y.shape == torch.Size([]) + x_0, _ = model(x_0, incidence_1) + assert x_0.shape == (2,2) diff --git a/test/nn/hypergraph/test_allset_transformer_layer.py b/test/nn/hypergraph/test_allset_transformer_layer.py index 41aeb4534..0984d1f3b 100644 --- a/test/nn/hypergraph/test_allset_transformer_layer.py +++ b/test/nn/hypergraph/test_allset_transformer_layer.py @@ -36,8 +36,9 @@ def test_forward(self, allset_transformer_layer): incidence_1 = torch.tensor( [[1, 0, 0], [0, 1, 1], [1, 1, 1]], dtype=torch.float32 ).to_sparse() - output = allset_transformer_layer.forward(x_0, incidence_1) - assert output.shape == (3, 64) + x_0, x_1 = allset_transformer_layer.forward(x_0, incidence_1) + assert x_0.shape == (3, 64) + assert x_1.shape == (3, 64) def test_forward_with_invalid_input(self, allset_transformer_layer): """Test the forward pass of the allsettransformer layer with invalid input.""" diff --git a/test/nn/hypergraph/test_dhgcn.py b/test/nn/hypergraph/test_dhgcn.py index ccf1aa158..35737856f 100644 --- a/test/nn/hypergraph/test_dhgcn.py +++ b/test/nn/hypergraph/test_dhgcn.py @@ -11,9 +11,14 @@ class TestDHGCNL: def test_forward(self): """Test forward method.""" # device = torch.device("cuda" if torch.cuda.is_available() else "cpu") - model = DHGCN(channels_node=8, hidden_channels=8, n_layers=2) + in_channels, hidden_channels = 8,4 + model = DHGCN( + in_channels=in_channels, + hidden_channels=hidden_channels, + n_layers=2) - x_0 = torch.rand(8, 8) + n_nodes = 8 + x_0 = torch.rand(n_nodes, in_channels) - y = model(x_0) - assert y.shape == torch.Size([]) + x_0, _ = model(x_0) + assert x_0.shape == torch.Size([n_nodes, hidden_channels]) diff --git a/test/nn/hypergraph/test_dhgcn_layer.py b/test/nn/hypergraph/test_dhgcn_layer.py index 89a392fd4..649d75968 100644 --- a/test/nn/hypergraph/test_dhgcn_layer.py +++ b/test/nn/hypergraph/test_dhgcn_layer.py @@ -41,8 +41,8 @@ def test_kmeans_with_invalid_input(self, dhgcn_layer): def test_forward(self, dhgcn_layer): """Test the forward pass of the DHGCN layer.""" x = torch.randn(4, 10) - output = dhgcn_layer.forward(x) - assert output.shape == (4, 10) + x_0, _ = dhgcn_layer.forward(x) + assert x_0.shape == (4, 10) def test_forward_invalid_input(self, dhgcn_layer): """Test the forward pass of the DHGCN layer.""" diff --git a/test/nn/hypergraph/test_hmpnn.py b/test/nn/hypergraph/test_hmpnn.py index 8624a70c9..aedd1b8b0 100644 --- a/test/nn/hypergraph/test_hmpnn.py +++ b/test/nn/hypergraph/test_hmpnn.py @@ -12,18 +12,20 @@ class TestHMPNN: def test_forward(self): """Test forward method.""" device = torch.device("cuda" if torch.cuda.is_available() else "cpu") - model = HMPNN(8, (8, 8), 1, 1).to(device) - - x_0 = torch.rand(8, 8) - x_1 = torch.rand(8, 8) - - adjacency_1 = torch.from_numpy(np.random.rand(8, 8)).to_sparse() - - x_0, x_1 = ( - torch.tensor(x_0).float().to(device), - torch.tensor(x_1).float().to(device), - ) + in_channels = 8 + hidden_channels = 32 + model = HMPNN( + in_channels=in_channels, + hidden_channels=hidden_channels, + ).to(device) + + n_nodes, n_edges = 8, 10 + x_0 = torch.rand(n_nodes, in_channels).float().to(device) + x_1 = torch.rand(n_edges, in_channels).float().to(device) + + adjacency_1 = torch.from_numpy(np.random.rand(n_nodes, n_edges)).to_sparse() adjacency_1 = adjacency_1.float().to(device) - y = model(x_0, x_1, adjacency_1) - assert y.shape == torch.Size([8, 1]) + x_0, x_1 = model(x_0, x_1, adjacency_1) + assert x_0.shape == torch.Size([n_nodes, hidden_channels]) + assert x_1.shape == torch.Size([n_edges, hidden_channels]) diff --git a/test/nn/hypergraph/test_hnhn.py b/test/nn/hypergraph/test_hnhn.py index c6d265f44..365d77755 100644 --- a/test/nn/hypergraph/test_hnhn.py +++ b/test/nn/hypergraph/test_hnhn.py @@ -3,7 +3,7 @@ import numpy as np import torch -from topomodelx.nn.hypergraph.hnhn import HNHN, HNHNNetwork +from topomodelx.nn.hypergraph.hnhn import HNHN class TestHNHN: @@ -15,54 +15,17 @@ def test_forward(self): adjacency_1 = torch.from_numpy(np.random.rand(2, 2)).to_sparse() adjacency_1 = adjacency_1.float().to(device) + hidden_channels = 5 model = HNHN( - channels_node=2, - channels_edge=2, + in_channels=2, + hidden_channels=hidden_channels, incidence_1=adjacency_1, - n_classes=1, n_layers=2, ).to(device) - x_0 = torch.rand(2, 2) - x_1 = torch.rand(2, 2) + x_0 = torch.rand(2, 2).float().to(device) - x_0, x_1 = ( - torch.tensor(x_0).float().to(device), - torch.tensor(x_1).float().to(device), - ) - - y1, y2 = model(x_0, x_1) - assert y1.shape == torch.Size([2, 1]) - assert y2.shape == torch.Size([2]) - - -class TestHNHNNetwork: - """Test the HNHNNetwork.""" - - def test_forward(self): - """Test forward method.""" - device = torch.device("cuda" if torch.cuda.is_available() else "cpu") - - adjacency_1 = torch.from_numpy(np.random.rand(2, 2)).to_sparse() - adjacency_1 = adjacency_1.float().to(device) - - model = HNHNNetwork( - channels_node=2, - channels_edge=2, - incidence_1=adjacency_1, - n_classes=1, - n_layers=2, - ).to(device) - - x_0 = torch.rand(2, 2) - x_1 = torch.rand(2, 2) - - x_0, x_1 = ( - torch.tensor(x_0).float().to(device), - torch.tensor(x_1).float().to(device), - ) - - y1, y2 = model(x_0, x_1) - assert y1.shape == torch.Size([2, 1]) - assert y2.shape == torch.Size([2]) + x_0, x_1 = model(x_0) + assert x_0.shape == torch.Size([2, hidden_channels]) + assert x_1.shape == torch.Size([2, hidden_channels]) diff --git a/test/nn/hypergraph/test_hnhn_layer.py b/test/nn/hypergraph/test_hnhn_layer.py index 3aa56847b..0ac72444c 100644 --- a/test/nn/hypergraph/test_hnhn_layer.py +++ b/test/nn/hypergraph/test_hnhn_layer.py @@ -11,29 +11,29 @@ class TestHNHNLayer: @pytest.fixture def template_layer(self): """Initialize and return an HNHN layer.""" - channels_node = 5 - channels_edge = 8 + self.in_channels = 5 + self.hidden_channels = 8 n_nodes = 10 n_edges = 20 incidence_1 = torch.randint(0, 2, (n_nodes, n_edges)).float() return HNHNLayer( - channels_node=channels_node, - channels_edge=channels_edge, + in_channels=self.in_channels, + hidden_channels=self.hidden_channels, incidence_1=incidence_1, ) def test_forward(self, template_layer): """Test the forward pass of the HNHN layer.""" n_nodes, n_edges = template_layer.incidence_1.shape - channels_node = template_layer.channels_node - channels_edge = template_layer.channels_edge - x_0 = torch.randn(n_nodes, channels_node) - x_1 = torch.randn(n_edges, channels_edge) - x_0_out, x_1_out = template_layer.forward(x_0, x_1) + - assert x_0_out.shape == x_0.shape - assert x_1_out.shape == x_1.shape + x_0 = torch.randn(n_nodes, self.in_channels) + x_0_out, x_1_out = template_layer.forward(x_0) + + assert x_0_out.shape == (n_nodes, self.hidden_channels) + assert x_1_out.shape == (n_edges, self.hidden_channels) + return def test_compute_normalization_matrices(self, template_layer): diff --git a/test/nn/hypergraph/test_hypergat.py b/test/nn/hypergraph/test_hypergat.py index 57c46401e..eae46b018 100644 --- a/test/nn/hypergraph/test_hypergat.py +++ b/test/nn/hypergraph/test_hypergat.py @@ -12,15 +12,19 @@ class TestHNHN: def test_forward(self): """Test forward method.""" device = torch.device("cuda" if torch.cuda.is_available() else "cpu") - - incidence = torch.from_numpy(np.random.rand(2, 2)).to_sparse() + + n_nodes, n_edges = 2, 2 + incidence = torch.from_numpy(np.random.rand(n_nodes, n_edges)).to_sparse() incidence = incidence.float().to(device) - model = HyperGAT(in_channels=2, out_channels=2, n_layers=2).to(device) - - x_0 = torch.rand(2, 2) + + in_channels, hidden_channels = 2, 6 + model = HyperGAT(in_channels=in_channels, + hidden_channels=hidden_channels, + n_layers=2).to(device) - x_0 = torch.tensor(x_0).float().to(device) + x_0 = torch.rand(2, 2).float().to(device) - y1 = model(x_0, incidence) + x_0, x_1 = model(x_0, incidence) - assert len(y1.shape) != -1 + assert x_0.shape == torch.Size([n_nodes, hidden_channels]) + assert x_1.shape == torch.Size([n_edges, hidden_channels]) diff --git a/test/nn/hypergraph/test_hypergat_layer.py b/test/nn/hypergraph/test_hypergat_layer.py index 4940bc1b0..b5b505307 100644 --- a/test/nn/hypergraph/test_hypergat_layer.py +++ b/test/nn/hypergraph/test_hypergat_layer.py @@ -12,17 +12,19 @@ class TestHyperGATLayer: def hypergat_layer(self): """Return a hypergat layer.""" in_channels = 10 - out_channels = 30 - return HyperGATLayer(in_channels, out_channels) + self.hidden_channels = 30 + return HyperGATLayer(in_channels=in_channels, hidden_channels=self.hidden_channels) def test_forward(self, hypergat_layer): """Test the forward pass of the hypergat layer.""" - x_2 = torch.randn(3, 10) + n_nodes, n_edges = 3, 3 + x_0 = torch.randn(n_nodes, 10) incidence_2 = torch.tensor( [[1, 0, 0], [0, 1, 1], [1, 1, 1]], dtype=torch.float32 ).to_sparse() - output = hypergat_layer.forward(x_2, incidence_2) - assert output.shape == (3, 30) + x_0, x_1 = hypergat_layer.forward(x_0, incidence_2) + assert x_0.shape == torch.Size([n_nodes, self.hidden_channels]) + assert x_1.shape == torch.Size([n_edges, self.hidden_channels]) def test_forward_with_invalid_input(self, hypergat_layer): """Test the forward pass of the hypergat layer with invalid input.""" diff --git a/test/nn/hypergraph/test_hypersage.py b/test/nn/hypergraph/test_hypersage.py index 9e1b85483..2c168d7b2 100644 --- a/test/nn/hypergraph/test_hypersage.py +++ b/test/nn/hypergraph/test_hypersage.py @@ -17,14 +17,11 @@ def test_forward(self): incidence = incidence.float().to(device) model = HyperSAGE( in_channels=2, - out_channels=2, + hidden_channels=2, n_layers=2, initialization="xavier_uniform", ).to(device) - x_0 = torch.rand(2, 2) + x_0 = torch.rand(2, 2).float().to(device) + x_0 = model(x_0, incidence) - x_0 = torch.tensor(x_0).float().to(device) - - y1 = model(x_0, incidence) - - assert y1.shape == torch.Size([]) + assert x_0.shape == torch.Size([2, 2]) diff --git a/test/nn/hypergraph/test_hypersage_layer.py b/test/nn/hypergraph/test_hypersage_layer.py index 04aa0490f..7adcdf513 100644 --- a/test/nn/hypergraph/test_hypersage_layer.py +++ b/test/nn/hypergraph/test_hypersage_layer.py @@ -21,7 +21,6 @@ def test_forward(self, hypersage_layer): incidence_2 = torch.tensor( [[1, 0], [0, 1], [1, 1]], dtype=torch.float32 ).to_sparse() - print(incidence_2) output = hypersage_layer.forward(x_2, incidence_2) assert output.shape == (3, 30) diff --git a/test/nn/hypergraph/test_unigcn.py b/test/nn/hypergraph/test_unigcn.py index 3cce0c106..2f2f8ed9f 100644 --- a/test/nn/hypergraph/test_unigcn.py +++ b/test/nn/hypergraph/test_unigcn.py @@ -12,15 +12,20 @@ class TestUniGCN: def test_forward(self): """Test forward method.""" device = torch.device("cuda" if torch.cuda.is_available() else "cpu") - - incidence = torch.from_numpy(np.random.rand(2, 2)).to_sparse() + n_nodes, n_edges = 2, 5 + incidence = torch.from_numpy(np.random.rand(n_nodes, n_edges)).to_sparse() incidence = incidence.float().to(device) - model = UniGCN(channels_edge=2, channels_node=2, n_layers=2).to(device) + in_channels, hidden_channels = 2, 10 + model = UniGCN( + in_channels=in_channels, + hidden_channels=hidden_channels, + n_layers=2 + ).to(device) - x_0 = torch.rand(2, 2) + x_0 = torch.rand(n_nodes, in_channels).float().to(device) - x_0 = torch.tensor(x_0).float().to(device) - y1 = model(x_0, incidence) + x_0, x_1 = model(x_0, incidence) - assert y1.shape == torch.Size([1]) + assert x_0.shape == torch.Size([n_nodes, hidden_channels]) + assert x_1.shape == torch.Size([n_edges, hidden_channels]) diff --git a/test/nn/hypergraph/test_unigcn_layer.py b/test/nn/hypergraph/test_unigcn_layer.py index e2303f5ae..f47433980 100644 --- a/test/nn/hypergraph/test_unigcn_layer.py +++ b/test/nn/hypergraph/test_unigcn_layer.py @@ -13,20 +13,20 @@ def test_forward(self): x = torch.randn(3, 10) layer = UniGCNLayer(10, 30) incidence = torch.tensor([[1, 1, 0], [1, 1, 1], [0, 1, 1]], dtype=torch.float32) - output = layer.forward(x, incidence) - assert output.shape == (3, 30) + x_0, _ = layer.forward(x, incidence) + assert x_0.shape == torch.Size([3, 30]) layer = UniGCNLayer(10, 30, use_bn=True) - output = layer.forward(x, incidence) - assert output.shape == (3, 30) + x_0, _ = layer.forward(x, incidence) + assert x_0.shape == torch.Size([3, 30]) def test_sum_aggregator(self): """Test sum aggregator.""" x = torch.randn(3, 10) incidence = torch.tensor([[1, 1, 0], [1, 1, 1], [0, 1, 1]], dtype=torch.float32) layer = UniGCNLayer(10, 30) - output = layer(x, incidence) - assert output.shape == (3, 30) + x_0, _ = layer(x, incidence) + assert x_0.shape == (3, 30) def test_aggregator_validation(self): """Test validation.""" @@ -66,8 +66,8 @@ def test_aggr_norm( incidence = torch.tensor([[1, 1, 0], [1, 1, 1], [0, 1, 1]], dtype=torch.float32) layer = UniGCNLayer(10, 30, aggr_norm=True) - output = layer(x, incidence) - assert output.shape == (3, 30) + x_0, _ = layer(x, incidence) + assert x_0.shape == (3, 30) def test_batchnorm(self): """Test batchnorm.""" diff --git a/test/nn/hypergraph/test_unigcnii.py b/test/nn/hypergraph/test_unigcnii.py index 50703f3f1..677337c52 100644 --- a/test/nn/hypergraph/test_unigcnii.py +++ b/test/nn/hypergraph/test_unigcnii.py @@ -13,14 +13,18 @@ def test_forward(self): """Test forward method.""" device = torch.device("cuda" if torch.cuda.is_available() else "cpu") - incidence = torch.from_numpy(np.random.rand(2, 2)).to_sparse() + n_nodes, n_edges = 2, 5 + incidence = torch.from_numpy(np.random.rand(n_nodes, n_edges)).to_sparse() incidence = incidence.float().to(device) - model = UniGCNII(num_classes=1, in_features=2, num_layers=2).to(device) - - x_0 = torch.rand(2, 2) - - x_0 = torch.tensor(x_0).float().to(device) - - y1 = model(x_0, incidence) - - assert len(y1.shape) != -1 + in_channels, hidden_channels = 2, 10 + model = UniGCNII( + in_channels=in_channels, + hidden_channels=hidden_channels, + n_layers=2 + ).to(device) + + x_0 = torch.rand(n_nodes, in_channels).float().to(device) + x_0, x_1 = model(x_0, incidence) + + assert x_0.shape == torch.Size([n_nodes, hidden_channels]) + assert x_1.shape == torch.Size([n_edges, hidden_channels]) diff --git a/test/nn/hypergraph/test_unigcnii_layer.py b/test/nn/hypergraph/test_unigcnii_layer.py index ea96ff296..e1d61a36c 100644 --- a/test/nn/hypergraph/test_unigcnii_layer.py +++ b/test/nn/hypergraph/test_unigcnii_layer.py @@ -14,26 +14,41 @@ def unigcnii_layer(self): in_channels = 10 alpha = 0.1 beta = 0.1 - return UniGCNIILayer(in_channels, alpha, beta) + return UniGCNIILayer( + in_channels = in_channels, + hidden_channels = in_channels, + alpha = alpha, + beta = beta + ) def test_forward(self, unigcnii_layer): """Test the forward pass.""" - x_0 = torch.randn(3, 10) + + n_nodes, in_channels = 3, 10 + x_0 = torch.randn(n_nodes, in_channels) incidence_1 = torch.tensor([[1, 0], [1, 1], [0, 1]], dtype=torch.float32) - output = unigcnii_layer.forward(x_0, incidence_1) + x_0, _ = unigcnii_layer.forward(x_0, incidence_1) - assert output.shape == (3, 10) + assert x_0.shape == torch.Size([n_nodes, in_channels]) def test_forward_with_skip(self): """Test the forward pass where alpha=1 and beta=0. The result should be the same as the skip connection. """ - x_0 = torch.randn(3, 10) + n_nodes, in_channels = 3, 10 + + x_0 = torch.rand(n_nodes, in_channels).float() incidence_1 = torch.tensor([[1, 0], [1, 1], [0, 1]], dtype=torch.float32) - x_skip = torch.randn(3, 10) + x_skip =torch.rand(n_nodes, in_channels).float() + + layer = UniGCNIILayer( + in_channels = in_channels, + hidden_channels = in_channels, + alpha = 1, + beta = 0 + ) - layer = UniGCNIILayer(10, 1, 0) - output = layer(x_0, incidence_1, x_skip) + x_0, _ = layer(x_0, incidence_1, x_skip) - torch.testing.assert_close(output, x_skip, rtol=1e-4, atol=1e-4) + torch.testing.assert_close(x_0, x_skip, rtol=1e-4, atol=1e-4) diff --git a/test/nn/hypergraph/test_unigin.py b/test/nn/hypergraph/test_unigin.py index a55c805e8..b133008fc 100644 --- a/test/nn/hypergraph/test_unigin.py +++ b/test/nn/hypergraph/test_unigin.py @@ -13,18 +13,17 @@ def test_forward(self): """Test forward method.""" device = torch.device("cuda" if torch.cuda.is_available() else "cpu") - incidence = torch.from_numpy(np.random.rand(2, 2)).to_sparse() + n_nodes, n_edges = 2, 5 + incidence = torch.from_numpy(np.random.rand(n_nodes, n_edges)).to_sparse() incidence = incidence.float().to(device) + in_channels, hidden_channels = 2, 10 model = UniGIN( - in_channels_node=2, - intermediate_channels=2, - out_channels=2, - n_layers=2, + in_channels=in_channels, + hidden_channels=hidden_channels, + n_layers=2 ).to(device) - x_0 = torch.rand(2, 2) + x_0 = torch.rand(n_nodes, in_channels).float().to(device) + x_0, x_1 = model(x_0, incidence) - x_0 = torch.tensor(x_0).float().to(device) - - y1 = model(x_0, incidence) - - assert len(y1.shape) != -1 + assert x_0.shape == torch.Size([n_nodes, hidden_channels]) + assert x_1.shape == torch.Size([n_edges, hidden_channels]) \ No newline at end of file diff --git a/test/nn/hypergraph/test_unigin_layer.py b/test/nn/hypergraph/test_unigin_layer.py index c3e738b63..3eb69c54a 100644 --- a/test/nn/hypergraph/test_unigin_layer.py +++ b/test/nn/hypergraph/test_unigin_layer.py @@ -1,6 +1,7 @@ """Test the UniGIN layer.""" import pytest import torch +import numpy as np from topomodelx.nn.hypergraph.unigin_layer import UniGINLayer @@ -11,19 +12,18 @@ class TestUniGINLayer: @pytest.fixture def UniGIN_layer(self): """Return a UniGIN layer.""" - in_channels = 10 - intermediate_channels = 20 - out_channels = 30 - nn = torch.nn.Sequential( - torch.nn.Linear(in_channels, intermediate_channels), - torch.nn.ReLU(), - torch.nn.Linear(intermediate_channels, out_channels), - ) - return UniGINLayer(nn, in_channels) + self.in_channels = 10 + return UniGINLayer(in_channels=self.in_channels) def test_forward(self, UniGIN_layer): """Test the forward pass of the UniGIN layer.""" - x = torch.randn(3, 10) - incidence = torch.tensor([[1, 1, 0], [1, 1, 1], [0, 1, 1]], dtype=torch.float32) - output = UniGIN_layer.forward(x, incidence) - assert output.shape == (3, 30) + + n_nodes, n_edges = 2, 3 + incidence = torch.from_numpy(np.random.rand(n_nodes, n_edges)).to_sparse() + incidence = incidence.float() + x_0 = torch.rand(n_nodes, self.in_channels).float() + x_0, x_1 = UniGIN_layer.forward(x_0, incidence) + + assert x_0.shape == torch.Size([n_nodes, self.in_channels]) + assert x_1.shape == torch.Size([n_edges, self.in_channels]) + diff --git a/test/nn/hypergraph/test_unisage.py b/test/nn/hypergraph/test_unisage.py index f7ae1b753..678354760 100644 --- a/test/nn/hypergraph/test_unisage.py +++ b/test/nn/hypergraph/test_unisage.py @@ -13,13 +13,17 @@ def test_forward(self): """Test forward method.""" device = torch.device("cuda" if torch.cuda.is_available() else "cpu") - incidence = torch.from_numpy(np.random.rand(2, 2)).to_sparse_csr() + n_nodes, n_edges = 2, 5 + incidence = torch.from_numpy(np.random.rand(n_nodes, n_edges)).to_sparse() incidence = incidence.float().to(device) - model = UniSAGE(channels_edge=2, channels_node=2, n_layers=2).to(device) - x_0 = torch.rand(2, 2) - - x_0 = torch.tensor(x_0).float().to(device) - - y1 = model(x_0, incidence) - - assert len(y1.shape) != -1 + in_channels, hidden_channels = 2, 10 + model = UniSAGE( + in_channels=in_channels, + hidden_channels=hidden_channels, + n_layers=2 + ).to(device) + x_0 = torch.rand(n_nodes, in_channels).float().to(device) + x_0, x_1 = model(x_0, incidence) + + assert x_0.shape == torch.Size([n_nodes, hidden_channels]) + assert x_1.shape == torch.Size([n_edges, hidden_channels]) \ No newline at end of file diff --git a/test/nn/hypergraph/test_unisage_layer.py b/test/nn/hypergraph/test_unisage_layer.py index 6a5d94676..de12efb66 100644 --- a/test/nn/hypergraph/test_unisage_layer.py +++ b/test/nn/hypergraph/test_unisage_layer.py @@ -19,16 +19,19 @@ def test_forward(self, uniSAGE_layer): """Test forward pass.""" x = torch.randn(3, 10) incidence = torch.tensor([[1, 1, 0], [1, 1, 1], [0, 1, 1]], dtype=torch.float32) - output = uniSAGE_layer.forward(x, incidence) - assert output.shape == (3, 30) + x_0, x_1 = uniSAGE_layer.forward(x, incidence) + assert x_0.shape == torch.Size([3, 30]) + assert x_1.shape == torch.Size([3, 30]) def test_sum_aggregator(self): """Test sum aggregator.""" x = torch.randn(3, 10) incidence = torch.tensor([[1, 1, 0], [1, 1, 1], [0, 1, 1]], dtype=torch.float32) layer = UniSAGELayer(10, 30, e_aggr="sum") - output = layer(x, incidence) - assert output.shape == (3, 30) + x_0, x_1 = layer(x, incidence) + + assert x_0.shape == torch.Size([3, 30]) + assert x_1.shape == torch.Size([3, 30]) def test_aggregator_validation(self, uniSAGE_layer): """Test aggregator validation.""" diff --git a/topomodelx/nn/hypergraph/dhgcn.py b/topomodelx/nn/hypergraph/dhgcn.py index 6652de8af..c8803759b 100644 --- a/topomodelx/nn/hypergraph/dhgcn.py +++ b/topomodelx/nn/hypergraph/dhgcn.py @@ -12,16 +12,13 @@ class DHGCN(torch.nn.Module): Parameters ---------- - channels_edge : int - Dimension of edge features - channels_node : int - Dimension of node features + in_channels : int + Dimension of the input features. + hidden_channels : int + Dimension of the hidden features. n_layer : int, default = 2 Amount of message passing layers. - task_level: str, default="graph" - Level of the task. Either "graph" or "node". - If "graph", the output is pooled over all nodes in the hypergraph. - + References ---------- .. [1] Yin, Feng, Luo, Zhang, Wang, Luo, Chen and Hua. @@ -32,10 +29,8 @@ class DHGCN(torch.nn.Module): def __init__( self, in_channels, - hidden_channels, - out_channels, + hidden_channels, n_layers=1, - task_level="graph" ): super().__init__() layers = [] @@ -55,8 +50,7 @@ def __init__( ) ) self.layers = torch.nn.ModuleList(layers) - self.linear = torch.nn.Linear(hidden_channels, out_channels) - self.out_pool = True if task_level == "graph" else False + def forward(self, x_0): @@ -69,16 +63,12 @@ def forward(self, x_0): Returns ------- - torch.Tensor, shape = (1) - Label assigned to whole complex. + x_0 : torch.Tensor + Output node features. + x_1 : torch.Tensor + Output hyperedge features. """ for layer in self.layers: - x_0 = layer(x_0) - - # Pool over all nodes in the hypergraph - if self.out_pool is True: - x = torch.max(x_0, dim=0)[0] - else: - x = x_0 + x_0, x_1 = layer(x_0) - return self.linear(x) + return (x_0, x_1) diff --git a/topomodelx/nn/hypergraph/dhgcn_layer.py b/topomodelx/nn/hypergraph/dhgcn_layer.py index 7d48f6c01..368b24277 100644 --- a/topomodelx/nn/hypergraph/dhgcn_layer.py +++ b/topomodelx/nn/hypergraph/dhgcn_layer.py @@ -212,8 +212,10 @@ def forward(self, x_0): Returns ------- - x_0 : torch.Tensor, shape = (n_nodes, out_channels) - Output features on the nodes of the simplicial complex. + x_0 : torch.Tensor + Output node features. + x_1 : torch.Tensor + Output hyperedge features. """ # dynamic topology processing: x_0_features = self.fc_layer(x_0) @@ -225,7 +227,7 @@ def forward(self, x_0): x_0_features, incidence_1_dynamic_topology_transpose ) x_0_features = self.conv_dt_level0_1_to_0(x_1, incidence_1_dynamic_topology) - return x_0_features + return x_0_features, x_1 def reset_parameters(self) -> None: r"""Reset learnable parameters.""" diff --git a/topomodelx/nn/hypergraph/hnhn.py b/topomodelx/nn/hypergraph/hnhn.py index 19df7d5c0..3b988d859 100644 --- a/topomodelx/nn/hypergraph/hnhn.py +++ b/topomodelx/nn/hypergraph/hnhn.py @@ -55,7 +55,7 @@ def __init__( self.layers = torch.nn.ModuleList(layers) - def forward(self, x_0, x_1): + def forward(self, x_0): """Forward computation. Parameters @@ -63,9 +63,6 @@ def forward(self, x_0, x_1): x_0 : torch.Tensor, shape = (n_nodes, channels_node) Hypernode features. - x_1 : torch.Tensor, shape = (n_nodes, channels_edge) - Hyperedge features. - incidence_1 : torch.Tensor, shape = (n_nodes, n_edges) Boundary matrix of rank 1. @@ -78,7 +75,7 @@ def forward(self, x_0, x_1): """ for layer in self.layers: - x_0, x_1 = layer(x_0, x_1) + x_0, x_1 = layer(x_0) return x_0, x_1 diff --git a/topomodelx/nn/hypergraph/hnhn_layer.py b/topomodelx/nn/hypergraph/hnhn_layer.py index 75c0006f0..5e4c513d8 100644 --- a/topomodelx/nn/hypergraph/hnhn_layer.py +++ b/topomodelx/nn/hypergraph/hnhn_layer.py @@ -158,7 +158,7 @@ def reset_parameters(self) -> None: if self.use_bias: self.init_biases() - def forward(self, x_0, x_1): + def forward(self, x_0): r"""Forward computation. The forward pass was initially proposed in [1]_. diff --git a/topomodelx/nn/hypergraph/hypergat.py b/topomodelx/nn/hypergraph/hypergat.py index 8084bfecc..af911c144 100644 --- a/topomodelx/nn/hypergraph/hypergat.py +++ b/topomodelx/nn/hypergraph/hypergat.py @@ -32,10 +32,10 @@ def __init__( ): super().__init__() layers = [] - layers.append(HyperGATLayer(in_channels=in_channels, out_channels=hidden_channels)) + layers.append(HyperGATLayer(in_channels=in_channels, hidden_channels=hidden_channels)) for _ in range(1, n_layers): layers.append( - HyperGATLayer(in_channels=hidden_channels, out_channels=hidden_channels) + HyperGATLayer(in_channels=hidden_channels, hidden_channels=hidden_channels) ) self.layers = torch.nn.ModuleList(layers) diff --git a/topomodelx/nn/hypergraph/hypergat_layer.py b/topomodelx/nn/hypergraph/hypergat_layer.py index cef2dbc82..851eff238 100644 --- a/topomodelx/nn/hypergraph/hypergat_layer.py +++ b/topomodelx/nn/hypergraph/hypergat_layer.py @@ -13,7 +13,7 @@ class HyperGATLayer(MessagePassing): ---------- in_channels : int Dimension of the input features. - out_channels : int + hidden_channels : int Dimension of the output features. update_func : string, default = "relu" Update method to apply to message. @@ -30,7 +30,7 @@ class HyperGATLayer(MessagePassing): def __init__( self, in_channels, - out_channels, + hidden_channels, update_func: str = "relu", initialization: Literal["xavier_uniform", "xavier_normal"] = "xavier_uniform", initialization_gain: float = 1.414, @@ -39,18 +39,18 @@ def __init__( initialization=initialization, initialization_gain=initialization_gain ) self.in_channels = in_channels - self.out_channels = out_channels + self.hidden_channels = hidden_channels self.update_func = update_func self.weight1 = torch.nn.Parameter( - torch.Tensor(self.in_channels, self.out_channels) + torch.Tensor(self.in_channels, self.hidden_channels) ) self.weight2 = torch.nn.Parameter( - torch.Tensor(self.out_channels, self.out_channels) + torch.Tensor(self.hidden_channels, self.hidden_channels) ) - self.att_weight1 = torch.nn.Parameter(torch.zeros(size=(out_channels, 1))) - self.att_weight2 = torch.nn.Parameter(torch.zeros(size=(2 * out_channels, 1))) + self.att_weight1 = torch.nn.Parameter(torch.zeros(size=(hidden_channels, 1))) + self.att_weight2 = torch.nn.Parameter(torch.zeros(size=(2 * hidden_channels, 1))) self.reset_parameters() def reset_parameters(self): @@ -134,12 +134,12 @@ def update(self, x_message_on_target, x_target=None): Parameters ---------- - x_message_on_target : torch.Tensor, shape = (n_target_cells, out_channels) + x_message_on_target : torch.Tensor, shape = (n_target_cells, hidden_channels) Output features on target cells. Returns ------- - torch.Tensor, shape = (n_target_cells, out_channels) + torch.Tensor, shape = (n_target_cells, hidden_channels) Updated output features on target cells. """ if self.update_func == "sigmoid": diff --git a/topomodelx/nn/hypergraph/unigcn_layer.py b/topomodelx/nn/hypergraph/unigcn_layer.py index 4a0935d6e..17c53d7b8 100644 --- a/topomodelx/nn/hypergraph/unigcn_layer.py +++ b/topomodelx/nn/hypergraph/unigcn_layer.py @@ -59,7 +59,7 @@ def __init__( aggr_norm=aggr_norm, update_func=None, ) - self.bn = nn.BatchNorm1d(in_channels) if use_bn else None + self.bn = nn.BatchNorm1d(hidden_channels) if use_bn else None def reset_parameters(self) -> None: r"""Reset learnable parameters.""" diff --git a/topomodelx/nn/hypergraph/unigcnii_layer.py b/topomodelx/nn/hypergraph/unigcnii_layer.py index 587715e18..8ce895eeb 100644 --- a/topomodelx/nn/hypergraph/unigcnii_layer.py +++ b/topomodelx/nn/hypergraph/unigcnii_layer.py @@ -95,7 +95,7 @@ def forward(self, x_0, incidence_1, x_skip=None): incidence_1_transpose = incidence_1.transpose(0, 1) # First message without any learning or parameters - m_0_1 = torch.sparse.mm(incidence_1_transpose, x_0) + x_1 = torch.sparse.mm(incidence_1_transpose, x_0) # Compute node and edge degrees for normalization. node_degree = torch.sum(incidence_1.to_dense(), dim=1) @@ -113,11 +113,11 @@ def forward(self, x_0, incidence_1, x_skip=None): edge_degree = edge_degree / torch.sum(incidence_1.to_dense(), dim=0) # Second message normalized with node and edge degrees (using broadcasting) - x_1 = (1 / torch.sqrt(node_degree).unsqueeze(-1)) * torch.sparse.mm( - incidence_1 @ torch.diag(1 / torch.sqrt(edge_degree)), m_0_1 + x_0 = (1 / torch.sqrt(node_degree).unsqueeze(-1)) * torch.sparse.mm( + incidence_1 @ torch.diag(1 / torch.sqrt(edge_degree)), x_1 ) # Introduce skip connections with hyperparameter alpha and beta - x_combined = ((1 - self.alpha) * x_1) + (self.alpha * x_skip) + x_combined = ((1 - self.alpha) * x_0) + (self.alpha * x_skip) x_0 = ((1 - self.beta) * x_combined) + self.beta * self.linear(x_combined) return x_0, x_1 diff --git a/topomodelx/nn/hypergraph/unisage.py b/topomodelx/nn/hypergraph/unisage.py index 8a8403474..b8a6a6b44 100644 --- a/topomodelx/nn/hypergraph/unisage.py +++ b/topomodelx/nn/hypergraph/unisage.py @@ -46,14 +46,14 @@ def __init__( layers.append( UniSAGELayer( in_channels=in_channels, - out_channels=hidden_channels, + hidden_channels=hidden_channels, ) ) for _ in range(n_layers - 1): layers.append( UniSAGELayer( in_channels=hidden_channels, - out_channels=hidden_channels, + hidden_channels=hidden_channels, ) ) self.layers = torch.nn.ModuleList(layers) diff --git a/topomodelx/nn/hypergraph/unisage_layer.py b/topomodelx/nn/hypergraph/unisage_layer.py index 8142013af..3d8f8c3d3 100644 --- a/topomodelx/nn/hypergraph/unisage_layer.py +++ b/topomodelx/nn/hypergraph/unisage_layer.py @@ -12,7 +12,7 @@ class UniSAGELayer(torch.nn.Module): ---------- in_channels : int Dimension of input features. - out_channels : int + hidden_channels : int Dimension of output features. e_aggr : Literal["sum", "mean", "amax", "amin"], default="sum" Aggregator function for hyperedges. @@ -44,16 +44,16 @@ def _validate_aggr(self, aggr): def __init__( self, in_channels, - out_channels, + hidden_channels, e_aggr: Literal["sum", "mean", "amax", "amin"] = "sum", v_aggr: Literal["sum", "mean", "amax", "amin"] = "mean", use_bn: bool = False, ) -> None: super().__init__() self.in_channels = in_channels - self.out_channels = out_channels - self.bn = torch.nn.BatchNorm1d(out_channels) if use_bn else None - self.linear = torch.nn.Linear(in_channels, out_channels) + self.hidden_channels = hidden_channels + self.bn = torch.nn.BatchNorm1d(hidden_channels) if use_bn else None + self.linear = torch.nn.Linear(in_channels, hidden_channels) self.v_aggr = v_aggr self.e_aggr = e_aggr diff --git a/tutorials/hypergraph/dhgcn_train.ipynb b/tutorials/hypergraph/dhgcn_train.ipynb index 8af681150..11a6a8db9 100644 --- a/tutorials/hypergraph/dhgcn_train.ipynb +++ b/tutorials/hypergraph/dhgcn_train.ipynb @@ -12,7 +12,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:51.222779223Z", @@ -40,7 +40,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:51.959770754Z", @@ -79,7 +79,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:53.022151550Z", @@ -111,7 +111,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -120,7 +120,7 @@ "((100,), (100, 750, 10), (100, 500, 7), (100,), (100,))" ] }, - "execution_count": 4, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -131,7 +131,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, "outputs": [ { @@ -140,7 +140,7 @@ "((252, 6), (750, 10), (500, 7))" ] }, - "execution_count": 5, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -152,7 +152,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -192,7 +192,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:53.022151550Z", @@ -213,7 +213,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "metadata": {}, "outputs": [ { @@ -238,32 +238,96 @@ "source": [ "# Create the Neural Network\n", "\n", - "Using the TemplateLayer class, we create a neural network with stacked layers." + "Define the network that initializes the base model and sets up the readout operation.\n", + "Different downstream tasks might require different pooling procedures.\n" ] }, { "cell_type": "code", - "execution_count": 20, - "metadata": { - "ExecuteTime": { - "end_time": "2023-06-01T16:14:55.343005145Z", - "start_time": "2023-06-01T16:14:55.339481459Z" - } - }, + "execution_count": 17, + "metadata": {}, "outputs": [], "source": [ - "channels_edge = x_1s[0].shape[1]\n", - "channels_node = x_0s[0].shape[1]\n", + "class Network(torch.nn.Module):\n", + " \"\"\" Network class that initializes the base model and readout layer.\n", + "\n", + " Base model parameters:\n", + " ----------\n", + " Reqired:\n", + " in_channels : int\n", + " Dimension of the input features.\n", + " hidden_channels : int\n", + " Dimension of the hidden features.\n", + "\n", + " Optitional:\n", + " **kwargs : dict\n", + " Additional arguments for the base model.\n", + " \n", + " Readout layer parameters:\n", + " ----------\n", + " out_channels : int\n", + " Dimension of the output features.\n", + " task_level : str\n", + " Level of the task. Either \"graph\" or \"node\". \n", + " \"\"\"\n", + " def __init__(\n", + " self, \n", + " in_channels, \n", + " hidden_channels,\n", + " out_channels, \n", + " \n", + " task_level=\"graph\",\n", + " **kwargs):\n", + " super().__init__()\n", + " \n", + " # Define the model\n", + " self.base_model = DHGCN(\n", + " in_channels=in_channels,\n", + " hidden_channels=hidden_channels,\n", + " **kwargs\n", + " )\n", + "\n", + "\n", + " # Readout\n", + " self.linear = torch.nn.Linear(hidden_channels, out_channels)\n", + " self.out_pool = True if task_level == \"graph\" else False\n", + " \n", + " def forward(self, x_0):\n", + " # Base model\n", + " x_0, x_1 = self.base_model(x_0)\n", + "\n", + " # Pool over all nodes in the hypergraph \n", + " if self.out_pool is True:\n", + " x = torch.max(x_0, dim=0)[0]\n", + " else:\n", + " x = x_0\n", + "\n", + " return self.linear(x)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "# Base model hyperparameters\n", + "in_channels = x_0s[0].shape[1]\n", "hidden_channels = 6\n", + "n_layers=2\n", + "\n", + "# Readout hyperparameters\n", "out_channels = 1\n", "task_level = \"graph\" if out_channels==1 else \"node\"\n", "\n", - "model = DHGCN(in_channels=channels_node,\n", - " hidden_channels=hidden_channels, \n", - " out_channels=out_channels,\n", - " n_layers=2,\n", - " task_level=task_level)\n", - "model = model.to(device)" + "\n", + "model = Network(\n", + " in_channels=in_channels,\n", + " hidden_channels=hidden_channels,\n", + " out_channels=out_channels, \n", + " n_layers=n_layers,\n", + " task_level=task_level,\n", + " ).to(device)" ] }, { @@ -278,7 +342,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 20, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:58.153514385Z", @@ -301,7 +365,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 21, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:59.046068930Z", @@ -325,7 +389,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 22, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:15:01.683216142Z", @@ -333,20 +397,28 @@ } }, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/usr/local/lib/python3.11/site-packages/torch/nn/modules/loss.py:536: UserWarning: Using a target size (torch.Size([])) that is different to the input size (torch.Size([1])). This will likely lead to incorrect results due to broadcasting. Please ensure they have the same size.\n", + " return F.mse_loss(input, target, reduction=self.reduction)\n" + ] + }, { "name": "stdout", "output_type": "stream", "text": [ - "Epoch: 1 loss: 5970948.3681\n", - "Test_loss: 113531.4844\n", - "Epoch: 2 loss: 6257.3332\n", - "Test_loss: 283.5760\n", - "Epoch: 3 loss: 2764.6070\n", - "Test_loss: 290.4227\n", - "Epoch: 4 loss: 1391.9918\n", - "Test_loss: 685.2422\n", - "Epoch: 5 loss: 835.5999\n", - "Test_loss: 284.1080\n" + "Epoch: 1 loss: 12533533.0041\n", + "Test_loss: 1476.5474\n", + "Epoch: 2 loss: 16311.6069\n", + "Test_loss: 67.2163\n", + "Epoch: 3 loss: 2506.7854\n", + "Test_loss: 2814.6946\n", + "Epoch: 4 loss: 2899.9972\n", + "Test_loss: 5.7347\n", + "Epoch: 5 loss: 2714.4102\n", + "Test_loss: 6.6283\n" ] } ], diff --git a/tutorials/hypergraph/hmpnn_train.ipynb b/tutorials/hypergraph/hmpnn_train.ipynb index 396d76025..33eaf57b2 100644 --- a/tutorials/hypergraph/hmpnn_train.ipynb +++ b/tutorials/hypergraph/hmpnn_train.ipynb @@ -15,7 +15,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 3, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:51.222779223Z", @@ -27,6 +27,7 @@ "import torch\n", "import torch_geometric.datasets as geom_datasets\n", "from sklearn.metrics import accuracy_score\n", + "import numpy as np\n", "\n", "from topomodelx.nn.hypergraph.hmpnn import HMPNN\n", "\n", @@ -44,7 +45,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 4, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:51.959770754Z", @@ -77,7 +78,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -93,7 +94,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -105,7 +106,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -126,7 +127,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ @@ -196,7 +197,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -221,7 +222,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 10, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:58.153514385Z", @@ -253,7 +254,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 11, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:15:01.683216142Z", diff --git a/tutorials/hypergraph/hnhn_train.ipynb b/tutorials/hypergraph/hnhn_train.ipynb index 4f956bf35..ae02eb98f 100644 --- a/tutorials/hypergraph/hnhn_train.ipynb +++ b/tutorials/hypergraph/hnhn_train.ipynb @@ -326,9 +326,9 @@ " self.linear = torch.nn.Linear(hidden_channels, out_channels)\n", " self.out_pool = True if task_level == \"graph\" else False\n", " \n", - " def forward(self, x_0, incidence_1):\n", + " def forward(self, x_0):\n", " # Base model\n", - " x_0, x_1 = self.base_model(x_0, incidence_1)\n", + " x_0, x_1 = self.base_model(x_0)\n", "\n", " # Pool over all nodes in the hypergraph \n", " if self.out_pool is True:\n", @@ -385,7 +385,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -401,7 +401,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 10, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:59.046068930Z", @@ -413,9 +413,9 @@ "name": "stderr", "output_type": "stream", "text": [ - "/tmp/ipykernel_694483/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_771339/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " x_0s = torch.tensor(x_0s)\n", - "/tmp/ipykernel_694483/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_771339/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " torch.tensor(y, dtype=torch.long).to(device),\n" ] } @@ -486,7 +486,7 @@ " opt.zero_grad()\n", " \n", " # Extract edge_index from sparse incidence matrix\n", - " y_hat = model(x_0s, incidence_1)\n", + " y_hat = model(x_0s)\n", " loss = loss_fn(y_hat[train_mask], y[train_mask])\n", "\n", " loss.backward()\n", @@ -498,7 +498,7 @@ " if epoch_i % test_interval == 0:\n", " \n", " model.eval()\n", - " y_hat = model(x_0s, incidence_1)\n", + " y_hat = model(x_0s)\n", "\n", " loss = loss_fn(y_hat[train_mask], y[train_mask])\n", " print(f\"Epoch: {epoch_i} \")\n", @@ -511,6 +511,13 @@ " loss = loss_fn(y_hat[test_mask], y[test_mask])\n", " print(f\"Test_loss: {loss:.4f}, Test_acc: {acc_fn(y_hat[test_mask].argmax(1), y[test_mask]):.4f}\", flush=True)" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { diff --git a/tutorials/hypergraph/hypergat_train.ipynb b/tutorials/hypergraph/hypergat_train.ipynb index e46bef69a..be0c000c8 100644 --- a/tutorials/hypergraph/hypergat_train.ipynb +++ b/tutorials/hypergraph/hypergat_train.ipynb @@ -371,10 +371,10 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch: 5 train_loss 1576.8879 test_loss: 5926.1705\n", - "Epoch: 10 train_loss 1071.0735 test_loss: 2550.9387\n", - "Epoch: 15 train_loss 2870.6875 test_loss: 1568.6725\n", - "Epoch: 20 train_loss 253.5367 test_loss: 662.3142\n" + "Epoch: 5 train_loss 2978.1547 test_loss: 1478.9974\n", + "Epoch: 10 train_loss 970.8229 test_loss: 1610.4103\n", + "Epoch: 15 train_loss 812.0088 test_loss: 1999.1152\n", + "Epoch: 20 train_loss 943.5183 test_loss: 1675.4498\n" ] } ], diff --git a/tutorials/hypergraph/unigcnii_train.ipynb b/tutorials/hypergraph/unigcnii_train.ipynb index 6976ac1f6..1fbedf373 100644 --- a/tutorials/hypergraph/unigcnii_train.ipynb +++ b/tutorials/hypergraph/unigcnii_train.ipynb @@ -21,14 +21,17 @@ "outputs": [], "source": [ "import torch\n", - "import pickle\n", + "\n", "import numpy as np\n", - "import scipy.sparse as sp\n", + "from torch_geometric.utils import to_undirected\n", + "import torch_geometric.datasets as geom_datasets\n", + "from sklearn.metrics import accuracy_score\n", + "\n", "\n", "from topomodelx.nn.hypergraph.unigcnii import UniGCNII\n", "\n", "torch.manual_seed(0)\n", - "np.random.seed(0)" + "np.random.seed(0)\n" ] }, { @@ -60,11 +63,11 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Loading the data\n", + "# Pre-processing\n", "\n", - "We are using the Cora co-citation dataset. Here, the nodes represent documents and the edges in the graph represent documents which are co-cited. It is possible to compute this graph from the citation network directly. However, this is computationally very expensive. Instead, we load the dataset directly as it is available to download.\n", + "## Import data ##\n", "\n", - "The task here is to classify each node and assign one of 7 possible classes to it. The dataset is a standard benchmark used in HGNN literature." + "The first step is to import the dataset, Cora, a benchmark classification datase. We then lift the graph into our domain of choice, a hypergraph.\n" ] }, { @@ -73,202 +76,139 @@ "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "--2023-11-03 14:49:01-- https://github.com/malllabiisc/HyperGCN/raw/master/data/cocitation/cora/features.pickle\n", - "Resolving github.com (github.com)... 140.82.121.4\n", - "Connecting to github.com (github.com)|140.82.121.4|:443... connected.\n", - "HTTP request sent, awaiting response... 302 Found\n", - "Location: https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/features.pickle [following]\n", - "--2023-11-03 14:49:01-- https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/features.pickle\n", - "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n", - "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.\n", - "HTTP request sent, awaiting response... 200 OK\n", - "Length: 404937 (395K) [application/octet-stream]\n", - "Saving to: ‘features.pickle.1’\n", - "\n", - "features.pickle.1 100%[===================>] 395.45K --.-KB/s in 0.04s \n", - "\n", - "2023-11-03 14:49:02 (10.7 MB/s) - ‘features.pickle.1’ saved [404937/404937]\n", - "\n", - "--2023-11-03 14:49:02-- https://github.com/malllabiisc/HyperGCN/raw/master/data/cocitation/cora/hypergraph.pickle\n", - "Resolving github.com (github.com)... 140.82.121.4\n", - "Connecting to github.com (github.com)|140.82.121.4|:443... connected.\n", - "HTTP request sent, awaiting response... 302 Found\n", - "Location: https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/hypergraph.pickle [following]\n", - "--2023-11-03 14:49:02-- https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/hypergraph.pickle\n", - "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n", - "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.\n", - "HTTP request sent, awaiting response... 200 OK\n", - "Length: 101905 (100K) [application/octet-stream]\n", - "Saving to: ‘hypergraph.pickle.1’\n", - "\n", - "hypergraph.pickle.1 100%[===================>] 99.52K --.-KB/s in 0.02s \n", - "\n", - "2023-11-03 14:49:02 (4.43 MB/s) - ‘hypergraph.pickle.1’ saved [101905/101905]\n", - "\n", - "--2023-11-03 14:49:03-- https://github.com/malllabiisc/HyperGCN/raw/master/data/cocitation/cora/labels.pickle\n", - "Resolving github.com (github.com)... 140.82.121.4\n", - "Connecting to github.com (github.com)|140.82.121.4|:443... connected.\n", - "HTTP request sent, awaiting response... 302 Found\n", - "Location: https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/labels.pickle [following]\n", - "--2023-11-03 14:49:03-- https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/labels.pickle\n", - "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n", - "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.\n", - "HTTP request sent, awaiting response... 200 OK\n", - "Length: 5436 (5.3K) [application/octet-stream]\n", - "Saving to: ‘labels.pickle.1’\n", - "\n", - "labels.pickle.1 100%[===================>] 5.31K --.-KB/s in 0s \n", - "\n", - "2023-11-03 14:49:03 (49.2 MB/s) - ‘labels.pickle.1’ saved [5436/5436]\n", - "\n" - ] - } - ], - "source": [ - "! wget https://github.com/malllabiisc/HyperGCN/raw/master/data/cocitation/cora/features.pickle\n", - "! wget https://github.com/malllabiisc/HyperGCN/raw/master/data/cocitation/cora/hypergraph.pickle\n", - "! wget https://github.com/malllabiisc/HyperGCN/raw/master/data/cocitation/cora/labels.pickle" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", + "name": "stderr", "output_type": "stream", "text": [ - "--2023-11-03 14:49:04-- https://github.com/malllabiisc/HyperGCN/raw/master/data/cocitation/cora/splits/1.pickle\n", - "Resolving github.com (github.com)... 140.82.121.4\n", - "Connecting to github.com (github.com)|140.82.121.4|:443... connected.\n", - "HTTP request sent, awaiting response... 302 Found\n", - "Location: https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/splits/1.pickle [following]\n", - "--2023-11-03 14:49:04-- https://raw.githubusercontent.com/malllabiisc/HyperGCN/master/data/cocitation/cora/splits/1.pickle\n", - "Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.109.133, 185.199.110.133, ...\n", - "Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.\n", - "HTTP request sent, awaiting response... 200 OK\n", - "Length: 51582 (50K) [application/octet-stream]\n", - "Saving to: ‘1.pickle.1’\n", - "\n", - "1.pickle.1 100%[===================>] 50.37K --.-KB/s in 0.002s \n", - "\n", - "2023-11-03 14:49:04 (27.8 MB/s) - ‘1.pickle.1’ saved [51582/51582]\n", - "\n" + "/usr/local/lib/python3.11/site-packages/torch_geometric/data/in_memory_dataset.py:284: UserWarning: It is not recommended to directly access the internal storage format `data` of an 'InMemoryDataset'. If you are absolutely certain what you are doing, access the internal storage via `InMemoryDataset._data` instead to suppress this warning. Alternatively, you can access stacked individual attributes of every graph via `dataset.{attr_name}`.\n", + " warnings.warn(msg)\n" ] } ], "source": [ - "! wget https://github.com/malllabiisc/HyperGCN/raw/master/data/cocitation/cora/splits/1.pickle" + "\n", + "cora = geom_datasets.Planetoid(root=\"/TopoModelX/data/cora\", name=\"Cora\")\n", + "data = cora.data\n", + "\n", + "x_0s = data.x\n", + "y = data.y\n", + "edge_index = data.edge_index\n", + "\n", + "train_mask = data.train_mask\n", + "val_mask = data.val_mask\n", + "test_mask = data.test_mask\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Now, we can load the loaded dataset" + "## Define neighborhood structures and lift into hypergraph domain. ##\n", + "\n", + "Now we retrieve the neighborhood structure (i.e. their representative matrice) that we will use to send messges from node to hyperedges. In the case of this architecture, we need the boundary matrix (or incidence matrix) $B_1$ with shape $n_\\text{nodes} \\times n_\\text{edges}$.\n", + "\n", + "In citation Cora dataset we lift graph structure to the hypergraph domain by creating hyperedges from 1-hop graph neighbourhood of each node. \n" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/tmp/ipykernel_670387/2369537045.py:2: DeprecationWarning: Please use `csr_matrix` from the `scipy.sparse` namespace, the `scipy.sparse.csr` namespace is deprecated.\n", - " features = pickle.load(handle).todense()\n" - ] - } - ], + "outputs": [], "source": [ - "with open(\"features.pickle\", \"rb\") as handle:\n", - " features = pickle.load(handle).todense()\n", + "# Ensure the graph is undirected (optional but often useful for one-hop neighborhoods).\n", + "edge_index = to_undirected(edge_index)\n", "\n", - "with open(\"hypergraph.pickle\", \"rb\") as handle:\n", - " hypergraph = pickle.load(handle)\n", + "# Create a list of one-hop neighborhoods for each node.\n", + "one_hop_neighborhoods = []\n", + "for node in range(data.num_nodes):\n", + " # Get the one-hop neighbors of the current node.\n", + " neighbors = data.edge_index[1, data.edge_index[0] == node]\n", "\n", - "with open(\"labels.pickle\", \"rb\") as handle:\n", - " labels = pickle.load(handle)" + " # Append the neighbors to the list of one-hop neighborhoods.\n", + " one_hop_neighborhoods.append(neighbors.numpy())\n", + "\n", + "# Detect and eliminate duplicate hyperedges.\n", + "unique_hyperedges = set()\n", + "hyperedges = []\n", + "for neighborhood in one_hop_neighborhoods:\n", + " # Sort the neighborhood to ensure consistent comparison.\n", + " neighborhood = tuple(sorted(neighborhood))\n", + " if neighborhood not in unique_hyperedges:\n", + " hyperedges.append(list(neighborhood))\n", + " unique_hyperedges.add(neighborhood) " ] }, { - "cell_type": "code", - "execution_count": 6, + "cell_type": "markdown", "metadata": {}, - "outputs": [], "source": [ - "# transform the input and output features to pytorch\n", - "x_0 = sp.csr_matrix(np.array(features), dtype=np.float32)\n", - "x_0 = torch.FloatTensor(np.array(x_0.todense()))\n", - "x_0 = x_0.to(device)\n", - "\n", - "y = torch.LongTensor(np.array(labels))\n", - "y = y.to(device)\n", - "\n", - "# construct the incidence matrix\n", - "h = np.zeros((x_0.shape[0], len(hypergraph)))\n", - "\n", - "for num, nodes in enumerate(hypergraph.values()):\n", - " h[list(nodes), num] = 1" + "Additionally we print the statictis associated with obtained incidence matrix" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Finally, we add self-loops to the dataset i.e. for every node $v$, we add a hyper-edge only containing that specific node $e = \\{ v \\}$. This is the standard format expected by the GCNII layers and transform the matrix into a sparse pytorch tensor." + "Now, we can load the loaded dataset" ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 5, "metadata": {}, "outputs": [ { - "name": "stderr", + "name": "stdout", "output_type": "stream", "text": [ - "/tmp/ipykernel_670387/2226475299.py:6: UserWarning: Sparse CSR tensor support is in beta state. If you miss a functionality in the sparse tensor support, please submit a feature request to https://github.com/pytorch/pytorch/issues. (Triggered internally at ../aten/src/ATen/SparseCsrTensorImpl.cpp:54.)\n", - " incidence = torch.Tensor(incidence).to_sparse_csr()\n" + "Hyperedge statistics: \n", + "Number of hyperedges without duplicated hyperedges 2581\n", + "min = 1, \n", + "max = 168, \n", + "mean = 4.003099573808601, \n", + "median = 3.0, \n", + "std = 5.327622607829558, \n", + "Number of hyperedges with size equal to one = 412\n" ] } ], "source": [ - "# add self loops\n", - "h2 = np.eye(x_0.shape[0])\n", - "incidence = np.hstack((h, h2))\n", "\n", - "# transform to pytorch\n", - "incidence = torch.Tensor(incidence).to_sparse_csr()\n", - "incidence = incidence.to(device)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now, we can load the predefine split in test and train data before we start constructing the HGNN." + "# Calculate hyperedge statistics.\n", + "hyperedge_sizes = [len(he) for he in hyperedges]\n", + "min_size = min(hyperedge_sizes)\n", + "max_size = max(hyperedge_sizes)\n", + "mean_size = np.mean(hyperedge_sizes)\n", + "median_size = np.median(hyperedge_sizes)\n", + "std_size = np.std(hyperedge_sizes)\n", + "num_single_node_hyperedges = sum(np.array(hyperedge_sizes) == 1)\n", + "\n", + "# Print the hyperedge statistics.\n", + "print(f'Hyperedge statistics: ')\n", + "print('Number of hyperedges without duplicated hyperedges', len(hyperedges))\n", + "print(f'min = {min_size}, ')\n", + "print(f'max = {max_size}, ')\n", + "print(f'mean = {mean_size}, ')\n", + "print(f'median = {median_size}, ')\n", + "print(f'std = {std_size}, ')\n", + "print(f'Number of hyperedges with size equal to one = {num_single_node_hyperedges}')" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ - "# load the train-test split given by the dataset\n", - "with open(\"1.pickle\", \"rb\") as H:\n", - " splits = pickle.load(H)\n", - " train, test = splits[\"train\"], splits[\"test\"]\n", + "max_edges = len(hyperedges)\n", + "incidence_1 = np.zeros((x_0s.shape[0], max_edges))\n", + "for col, neighibourhood in enumerate(hyperedges):\n", + " for row in neighibourhood:\n", + " incidence_1[row, col] = 1\n", "\n", - "train_idx = torch.LongTensor(train).to(device)\n", - "test_idx = torch.LongTensor(test).to(device)" + "assert all(incidence_1.sum(0)>0) == True, \"Some hyperedges are empty\"\n", + "assert all(incidence_1.sum(1)>0) == True, \"Some nodes are not in any hyperedges\"\n", + "incidence_1 = torch.Tensor(incidence_1).to_sparse_coo()" ] }, { @@ -288,7 +228,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -357,12 +297,12 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "# Base model hyperparameters\n", - "in_channels = x_0.shape[1]\n", + "in_channels = x_0s.shape[1]\n", "hidden_channels = 128\n", "n_layers=2\n", "mlp_num_layers=1\n", @@ -394,7 +334,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -411,7 +351,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ @@ -434,19 +374,19 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Epoch: 0 Train_loss: 1.8349, Train_acc: 0.5000 Test_loss: 1.8957, Test_acc: 0.2819\n", - "Epoch: 5 Train_loss: 0.3446, Train_acc: 1.0000 Test_loss: 1.0406, Test_acc: 0.7099\n", - "Epoch: 10 Train_loss: 0.0204, Train_acc: 1.0000 Test_loss: 1.2339, Test_acc: 0.7079\n", - "Epoch: 15 Train_loss: 0.0401, Train_acc: 0.9929 Test_loss: 3.0919, Test_acc: 0.6223\n", - "Epoch: 20 Train_loss: 0.0021, Train_acc: 1.0000 Test_loss: 3.9843, Test_acc: 0.6083\n", - "Epoch: 25 Train_loss: 0.0006, Train_acc: 1.0000 Test_loss: 3.0639, Test_acc: 0.6748\n" + "Epoch: 0 Train_loss: 6.5894, Train_acc: 0.1429 Test_loss: 8.7642, Test_acc: 0.1430\n", + "Epoch: 5 Train_loss: 1.6524, Train_acc: 0.5643 Test_loss: 1.7561, Test_acc: 0.4770\n", + "Epoch: 10 Train_loss: 1.4487, Train_acc: 0.6857 Test_loss: 1.6757, Test_acc: 0.5350\n", + "Epoch: 15 Train_loss: 1.1535, Train_acc: 0.7500 Test_loss: 1.5980, Test_acc: 0.6030\n", + "Epoch: 20 Train_loss: 0.8682, Train_acc: 0.8143 Test_loss: 1.6471, Test_acc: 0.6620\n", + "Epoch: 25 Train_loss: 0.6407, Train_acc: 0.8500 Test_loss: 1.8455, Test_acc: 0.6860\n" ] } ], @@ -456,8 +396,8 @@ " # set model to training mode\n", " model.train()\n", "\n", - " y_hat = model(x_0, incidence)\n", - " loss = loss_fn(y_hat[train_idx], y[train_idx])\n", + " y_hat = model(x_0s, incidence_1)\n", + " loss = loss_fn(y_hat[train_mask], y[train_mask])\n", "\n", " loss.backward()\n", " optimizer.step()\n", @@ -467,13 +407,13 @@ " if epoch % test_interval == 0:\n", " \n", " model.eval()\n", - " y_hat = model(x_0, incidence)\n", + " y_hat = model(x_0s, incidence_1)\n", "\n", - " train_loss = loss_fn(y_hat[train_idx], y[train_idx])\n", - " loss = loss_fn(y_hat[test_idx], y[test_idx])\n", + " train_loss = loss_fn(y_hat[train_mask], y[train_mask])\n", + " loss = loss_fn(y_hat[test_mask], y[test_mask])\n", " print(f\"Epoch: {epoch} \\\n", - " Train_loss: {train_loss:.4f}, Train_acc: {acc_fn(y_hat[train_idx].argmax(1), y[train_idx]):.4f} \\\n", - " Test_loss: {loss:.4f}, Test_acc: {acc_fn(y_hat[test_idx].argmax(1), y[test_idx]):.4f}\",\n", + " Train_loss: {train_loss:.4f}, Train_acc: {acc_fn(y_hat[train_mask].argmax(1), y[train_mask]):.4f} \\\n", + " Test_loss: {loss:.4f}, Test_acc: {acc_fn(y_hat[test_mask].argmax(1), y[test_mask]):.4f}\",\n", " flush=True)" ] } From 6834282a10f7a8e49a291fdb6618c608f5ef8910 Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Mon, 6 Nov 2023 15:47:33 +0000 Subject: [PATCH 09/39] hypergraphs --- test/nn/hypergraph/test_allset.py | 2 +- test/nn/hypergraph/test_allset_transformer.py | 2 +- test/nn/hypergraph/test_dhgcn_layer.py | 2 +- test/nn/hypergraph/test_hnhn.py | 2 +- test/nn/hypergraph/test_hypersage.py | 1 + test/nn/hypergraph/test_unisage_layer.py | 2 +- topomodelx/nn/hypergraph/dhgcn_layer.py | 10 +-- topomodelx/nn/hypergraph/hypersage.py | 4 +- topomodelx/nn/hypergraph/hypersage_layer.py | 10 +-- topomodelx/nn/hypergraph/unisage_layer.py | 47 ++++++------ tutorials/hypergraph/allset_train.ipynb | 52 ++++++-------- .../hypergraph/allset_transformer_train.ipynb | 42 +++++------ tutorials/hypergraph/dhgcn_train.ipynb | 59 +++++++-------- tutorials/hypergraph/hmpnn_train.ipynb | 66 ++++++++--------- tutorials/hypergraph/hnhn_train.ipynb | 12 ++-- tutorials/hypergraph/hypergat_train.ipynb | 10 +-- tutorials/hypergraph/hypersage_train.ipynb | 71 +++++++++++++------ tutorials/hypergraph/unigcn_train.ipynb | 63 +++++++++++----- tutorials/hypergraph/unigcnii_train.ipynb | 46 ++++++++++-- tutorials/hypergraph/unigin_train.ipynb | 42 +++++------ tutorials/hypergraph/unisage_train.ipynb | 62 ++++++---------- 21 files changed, 335 insertions(+), 272 deletions(-) diff --git a/test/nn/hypergraph/test_allset.py b/test/nn/hypergraph/test_allset.py index c7ed15490..f09d4beea 100644 --- a/test/nn/hypergraph/test_allset.py +++ b/test/nn/hypergraph/test_allset.py @@ -17,7 +17,7 @@ def test_forward(self): hidden_channels=4, n_layers=2, mlp_num_layers=1, - ) + ).to(device) x_0 = torch.rand(4, 4) incidence_1 = torch.from_numpy(np.random.rand(4, 4)).to_sparse() diff --git a/test/nn/hypergraph/test_allset_transformer.py b/test/nn/hypergraph/test_allset_transformer.py index 6f0ade3df..b1c5cb536 100644 --- a/test/nn/hypergraph/test_allset_transformer.py +++ b/test/nn/hypergraph/test_allset_transformer.py @@ -18,7 +18,7 @@ def test_forward(self): heads=1, n_layers=2, mlp_num_layers=1, - ) + ).to(device) x_0 = torch.rand(2, 2) incidence_1 = torch.from_numpy(np.random.rand(2, 2)).to_sparse() diff --git a/test/nn/hypergraph/test_dhgcn_layer.py b/test/nn/hypergraph/test_dhgcn_layer.py index 649d75968..6f45b644a 100644 --- a/test/nn/hypergraph/test_dhgcn_layer.py +++ b/test/nn/hypergraph/test_dhgcn_layer.py @@ -28,7 +28,7 @@ def test_kmeans(self, dhgcn_layer): output = dhgcn_layer.kmeans(x_0, k=dhgcn_layer.k_centroids) assert output.shape == (2, 4) if torch.cuda.is_available(): - x_0 = x_0.to("gpu") + x_0 = x_0 output = dhgcn_layer.kmeans(x_0, k=dhgcn_layer.k_centroids) assert output.device.type == x_0.device.type diff --git a/test/nn/hypergraph/test_hnhn.py b/test/nn/hypergraph/test_hnhn.py index 365d77755..e0718913c 100644 --- a/test/nn/hypergraph/test_hnhn.py +++ b/test/nn/hypergraph/test_hnhn.py @@ -14,7 +14,7 @@ def test_forward(self): device = torch.device("cuda" if torch.cuda.is_available() else "cpu") adjacency_1 = torch.from_numpy(np.random.rand(2, 2)).to_sparse() - adjacency_1 = adjacency_1.float().to(device) + adjacency_1 = adjacency_1.float() hidden_channels = 5 model = HNHN( diff --git a/test/nn/hypergraph/test_hypersage.py b/test/nn/hypergraph/test_hypersage.py index 2c168d7b2..d7e1a0741 100644 --- a/test/nn/hypergraph/test_hypersage.py +++ b/test/nn/hypergraph/test_hypersage.py @@ -19,6 +19,7 @@ def test_forward(self): in_channels=2, hidden_channels=2, n_layers=2, + device=device, initialization="xavier_uniform", ).to(device) x_0 = torch.rand(2, 2).float().to(device) diff --git a/test/nn/hypergraph/test_unisage_layer.py b/test/nn/hypergraph/test_unisage_layer.py index de12efb66..2f79ef828 100644 --- a/test/nn/hypergraph/test_unisage_layer.py +++ b/test/nn/hypergraph/test_unisage_layer.py @@ -39,7 +39,7 @@ def test_aggregator_validation(self, uniSAGE_layer): _ = UniSAGELayer(10, 30, e_aggr="invalid_aggregator") assert ( str(exc_info.value) - == "Unsupported aggregator: invalid_aggregator, should be 'sum', 'mean', 'amax', or 'amin'" + == "Unsupported aggregator: invalid_aggregator, should be 'sum', 'mean'," ) def test_reset_params(self, uniSAGE_layer): diff --git a/topomodelx/nn/hypergraph/dhgcn_layer.py b/topomodelx/nn/hypergraph/dhgcn_layer.py index 368b24277..c0de452a0 100644 --- a/topomodelx/nn/hypergraph/dhgcn_layer.py +++ b/topomodelx/nn/hypergraph/dhgcn_layer.py @@ -169,25 +169,27 @@ def get_dynamic_topology(self, x_0_features): """ device = x_0_features.device n_nodes = x_0_features.size(0) - batch = torch.zeros(x_0_features.size(0), dtype=torch.long, device=device) + batch = torch.zeros(x_0_features.size(0), dtype=torch.long, device='cpu') local_edge_index = knn_graph( - x_0_features, + x_0_features.cpu(), k=self.k_neighbours, batch=batch, loop=False, flow="source_to_target", - ) + ).to(device) local_hyperedges = torch.sparse_coo_tensor( local_edge_index, torch.ones(local_edge_index.size(1), device=device), size=(n_nodes, n_nodes), + device=device, ) # [n_nodes, n_hyperedges = n_nodes] - global_edge_index = self.kmeans(x_0_features) + global_edge_index = self.kmeans(x_0_features.cpu()) global_hyperedges = torch.sparse_coo_tensor( global_edge_index, torch.ones(n_nodes, device=device), size=(n_nodes, self.k_centroids), + device=device, ) # [n_nodes, n_hyperedges = k_centroids] return torch.cat((local_hyperedges, global_hyperedges), dim=1) diff --git a/topomodelx/nn/hypergraph/hypersage.py b/topomodelx/nn/hypergraph/hypersage.py index 5c7f44346..165aeb9d0 100644 --- a/topomodelx/nn/hypergraph/hypersage.py +++ b/topomodelx/nn/hypergraph/hypersage.py @@ -39,7 +39,9 @@ def __init__( for _ in range(1, n_layers): layers.append( HyperSAGELayer( - in_channels=hidden_channels, out_channels=hidden_channels, **kwargs + in_channels=hidden_channels, + out_channels=hidden_channels, + **kwargs ) ) self.layers = torch.nn.ModuleList(layers) diff --git a/topomodelx/nn/hypergraph/hypersage_layer.py b/topomodelx/nn/hypergraph/hypersage_layer.py index 2e4ab4d95..71a939637 100644 --- a/topomodelx/nn/hypergraph/hypersage_layer.py +++ b/topomodelx/nn/hypergraph/hypersage_layer.py @@ -179,16 +179,16 @@ def forward(self, x: torch.Tensor, incidence: torch.Tensor): # type: ignore[ove def nodes_per_edge(e): return ( - torch.index_select(input=incidence, dim=1, index=torch.LongTensor([e])) + torch.index_select(input=incidence.to("cpu"), dim=1, index=torch.LongTensor([e])) .coalesce() - .indices()[0] + .indices()[0].to(self.device) ) def edges_per_node(v): return ( - torch.index_select(input=incidence, dim=0, index=torch.LongTensor([v])) + torch.index_select(input=incidence.to("cpu"), dim=0, index=torch.LongTensor([v])) .coalesce() - .indices()[1] + .indices()[1].to(self.device) ) messages_per_edges = [ @@ -196,7 +196,7 @@ def edges_per_node(v): ] num_of_messages_per_edges = torch.Tensor( [message.size()[-2] for message in messages_per_edges] - ).reshape(-1, 1) + ).reshape(-1, 1).to(self.device) intra_edge_aggregation = torch.stack( [self.aggregate(message, mode="intra") for message in messages_per_edges] ) diff --git a/topomodelx/nn/hypergraph/unisage_layer.py b/topomodelx/nn/hypergraph/unisage_layer.py index 3d8f8c3d3..db5b8f8be 100644 --- a/topomodelx/nn/hypergraph/unisage_layer.py +++ b/topomodelx/nn/hypergraph/unisage_layer.py @@ -3,7 +3,7 @@ from typing import Literal import torch - +from topomodelx.base.conv import Conv class UniSAGELayer(torch.nn.Module): """Layer of UniSAGE proposed in [1]_. @@ -14,9 +14,9 @@ class UniSAGELayer(torch.nn.Module): Dimension of input features. hidden_channels : int Dimension of output features. - e_aggr : Literal["sum", "mean", "amax", "amin"], default="sum" + e_aggr : Literal["sum", "mean",], default="sum" Aggregator function for hyperedges. - v_aggr : Literal["sum", "mean", "amax", "amin"], default="mean" + v_aggr : Literal["sum", "mean",], default="mean" Aggregator function for nodes. use_bn : boolean Whether to use bathnorm after the linear transformation. @@ -36,30 +36,48 @@ class UniSAGELayer(torch.nn.Module): """ def _validate_aggr(self, aggr): - if aggr not in {"sum", "mean", "amax", "amin"}: + if aggr not in {"sum", "mean",}: raise ValueError( - f"Unsupported aggregator: {aggr}, should be 'sum', 'mean', 'amax', or 'amin'" + f"Unsupported aggregator: {aggr}, should be 'sum', 'mean'," ) def __init__( self, in_channels, hidden_channels, - e_aggr: Literal["sum", "mean", "amax", "amin"] = "sum", - v_aggr: Literal["sum", "mean", "amax", "amin"] = "mean", + e_aggr: Literal["sum", "mean",] = "sum", + v_aggr: Literal["sum", "mean",] = "mean", use_bn: bool = False, ) -> None: super().__init__() self.in_channels = in_channels self.hidden_channels = hidden_channels self.bn = torch.nn.BatchNorm1d(hidden_channels) if use_bn else None + + # Initial linear transformation self.linear = torch.nn.Linear(in_channels, hidden_channels) + + # Define the aggregation self.v_aggr = v_aggr self.e_aggr = e_aggr self._validate_aggr(v_aggr) self._validate_aggr(e_aggr) + self.vertex2edge = Conv( + in_channels=hidden_channels, + out_channels=hidden_channels, + aggr_norm=False if self.e_aggr=="sum" else True, + with_linear_transform=False, + ) + + self.edge2vertex = Conv( + in_channels=hidden_channels, + out_channels=hidden_channels, + aggr_norm=False if self.v_aggr=="sum" else True, + with_linear_transform=False, + ) + def reset_parameters(self) -> None: r"""Reset learnable parameters.""" self.linear.reset_parameters() @@ -115,19 +133,8 @@ def forward(self, x_0, incidence_1): if self.bn is not None: x_0 = self.bn(x_0) - # Use sparse CSR to enable reduce operation - if incidence_1.layout != torch.sparse_csr: - incidence_1_transpose = incidence_1.T.to_sparse_csr() - incidence_1 = incidence_1.to_sparse_csr() - else: - # Transpose generates CSC tensor, thus we have to convert to csr - incidence_1_transpose = incidence_1.transpose(1, 0).to_sparse_csr() - - # First pass fills in features of edges by adding features of constituent nodes - x_1 = torch.sparse.mm(incidence_1_transpose.float(), x_0, reduce=self.e_aggr) - - # Second pass fills in features of nodes by adding features of the incident edges - m_1_0 = torch.sparse.mm(incidence_1.float(), x_1, reduce=self.v_aggr) + x_1 = self.vertex2edge(x_0, incidence_1.transpose(1, 0)) + m_1_0 = self.edge2vertex(x_1, incidence_1) x_0 = x_0 + m_1_0 return (x_0, x_1) diff --git a/tutorials/hypergraph/allset_train.ipynb b/tutorials/hypergraph/allset_train.ipynb index 70370fb83..d8c0627d9 100644 --- a/tutorials/hypergraph/allset_train.ipynb +++ b/tutorials/hypergraph/allset_train.ipynb @@ -76,7 +76,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 2, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:51.959770754Z", @@ -88,7 +88,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "cpu\n" + "cuda\n" ] } ], @@ -279,7 +279,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -414,9 +414,9 @@ "name": "stderr", "output_type": "stream", "text": [ - "/tmp/ipykernel_645923/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_1791/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " x_0s = torch.tensor(x_0s)\n", - "/tmp/ipykernel_645923/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_1791/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " torch.tensor(y, dtype=torch.long).to(device),\n" ] } @@ -448,35 +448,29 @@ "output_type": "stream", "text": [ "Epoch: 5 \n", - "Train_loss: 1.8073, acc: 0.5143\n", - "Val_loss: 1.6731, Val_acc: 0.4200\n", - "Test_loss: 1.6482, Test_acc: 0.4550\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ + "Train_loss: 1.8307, acc: 0.4929\n", + "Val_loss: 1.7379, Val_acc: 0.3560\n", + "Test_loss: 1.6873, Test_acc: 0.4080\n", "Epoch: 10 \n", - "Train_loss: 1.5072, acc: 0.7714\n", - "Val_loss: 1.2418, Val_acc: 0.5940\n", - "Test_loss: 1.2165, Test_acc: 0.6140\n", + "Train_loss: 1.4922, acc: 0.6857\n", + "Val_loss: 1.5380, Val_acc: 0.5160\n", + "Test_loss: 1.3973, Test_acc: 0.5380\n", "Epoch: 15 \n", - "Train_loss: 1.1989, acc: 0.9714\n", - "Val_loss: 1.9284, Val_acc: 0.6380\n", - "Test_loss: 1.9215, Test_acc: 0.6280\n", + "Train_loss: 1.1529, acc: 0.9786\n", + "Val_loss: 2.0844, Val_acc: 0.6820\n", + "Test_loss: 1.9983, Test_acc: 0.7010\n", "Epoch: 20 \n", - "Train_loss: 0.9625, acc: 0.9429\n", - "Val_loss: 2.6081, Val_acc: 0.6860\n", - "Test_loss: 2.4626, Test_acc: 0.6990\n", + "Train_loss: 1.0032, acc: 0.9214\n", + "Val_loss: 3.8625, Val_acc: 0.5820\n", + "Test_loss: 3.7555, Test_acc: 0.5950\n", "Epoch: 25 \n", - "Train_loss: 0.7969, acc: 1.0000\n", - "Val_loss: 3.6042, Val_acc: 0.6840\n", - "Test_loss: 3.5520, Test_acc: 0.6730\n", + "Train_loss: 0.8708, acc: 1.0000\n", + "Val_loss: 2.0274, Val_acc: 0.7040\n", + "Test_loss: 1.8696, Test_acc: 0.6960\n", "Epoch: 30 \n", - "Train_loss: 0.6704, acc: 1.0000\n", - "Val_loss: 3.7970, Val_acc: 0.7140\n", - "Test_loss: 3.6409, Test_acc: 0.7040\n" + "Train_loss: 0.7377, acc: 1.0000\n", + "Val_loss: 2.0471, Val_acc: 0.6940\n", + "Test_loss: 1.8233, Test_acc: 0.7040\n" ] } ], diff --git a/tutorials/hypergraph/allset_transformer_train.ipynb b/tutorials/hypergraph/allset_transformer_train.ipynb index 800272fe4..f345f5833 100644 --- a/tutorials/hypergraph/allset_transformer_train.ipynb +++ b/tutorials/hypergraph/allset_transformer_train.ipynb @@ -118,7 +118,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "cpu\n" + "cuda\n" ] } ], @@ -442,9 +442,9 @@ "name": "stderr", "output_type": "stream", "text": [ - "/tmp/ipykernel_695904/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_2070/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " x_0s = torch.tensor(x_0s)\n", - "/tmp/ipykernel_695904/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_2070/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " torch.tensor(y, dtype=torch.long).to(device),\n" ] } @@ -481,29 +481,29 @@ "output_type": "stream", "text": [ "Epoch: 5 \n", - "Train_loss: 1.5815, acc: 0.9857\n", - "Val_loss: 0.9676, Val_acc: 0.7300\n", - "Test_loss: 0.9331, Test_acc: 0.7400\n", + "Train_loss: 1.6679, acc: 0.9786\n", + "Val_loss: 1.0352, Val_acc: 0.7260\n", + "Test_loss: 0.9883, Test_acc: 0.7420\n", "Epoch: 10 \n", - "Train_loss: 0.8823, acc: 1.0000\n", - "Val_loss: 1.0689, Val_acc: 0.7400\n", - "Test_loss: 1.0016, Test_acc: 0.7490\n", + "Train_loss: 0.9572, acc: 1.0000\n", + "Val_loss: 1.0956, Val_acc: 0.7260\n", + "Test_loss: 0.9612, Test_acc: 0.7430\n", "Epoch: 15 \n", - "Train_loss: 0.5933, acc: 1.0000\n", - "Val_loss: 1.5343, Val_acc: 0.7100\n", - "Test_loss: 1.4664, Test_acc: 0.7310\n", + "Train_loss: 0.6462, acc: 1.0000\n", + "Val_loss: 1.4786, Val_acc: 0.7340\n", + "Test_loss: 1.2396, Test_acc: 0.7440\n", "Epoch: 20 \n", - "Train_loss: 0.4458, acc: 1.0000\n", - "Val_loss: 1.9383, Val_acc: 0.7020\n", - "Test_loss: 1.7923, Test_acc: 0.7170\n", + "Train_loss: 0.4861, acc: 1.0000\n", + "Val_loss: 1.8393, Val_acc: 0.7180\n", + "Test_loss: 1.5967, Test_acc: 0.7330\n", "Epoch: 25 \n", - "Train_loss: 0.3568, acc: 1.0000\n", - "Val_loss: 2.2001, Val_acc: 0.7080\n", - "Test_loss: 2.0025, Test_acc: 0.7140\n", + "Train_loss: 0.3892, acc: 1.0000\n", + "Val_loss: 2.1019, Val_acc: 0.7100\n", + "Test_loss: 1.8659, Test_acc: 0.7310\n", "Epoch: 30 \n", - "Train_loss: 0.2988, acc: 0.9929\n", - "Val_loss: 2.0959, Val_acc: 0.7020\n", - "Test_loss: 1.8342, Test_acc: 0.7450\n" + "Train_loss: 0.3244, acc: 1.0000\n", + "Val_loss: 2.2488, Val_acc: 0.7100\n", + "Test_loss: 2.0038, Test_acc: 0.7350\n" ] } ], diff --git a/tutorials/hypergraph/dhgcn_train.ipynb b/tutorials/hypergraph/dhgcn_train.ipynb index 11a6a8db9..a03751135 100644 --- a/tutorials/hypergraph/dhgcn_train.ipynb +++ b/tutorials/hypergraph/dhgcn_train.ipynb @@ -12,7 +12,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:51.222779223Z", @@ -40,7 +40,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:51.959770754Z", @@ -52,7 +52,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "cpu\n" + "cuda\n" ] } ], @@ -79,7 +79,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 3, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:53.022151550Z", @@ -111,7 +111,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -120,7 +120,7 @@ "((100,), (100, 750, 10), (100, 500, 7), (100,), (100,))" ] }, - "execution_count": 5, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -131,7 +131,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -140,7 +140,7 @@ "((252, 6), (750, 10), (500, 7))" ] }, - "execution_count": 6, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -152,7 +152,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "metadata": {}, "outputs": [ { @@ -192,7 +192,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 7, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:53.022151550Z", @@ -213,7 +213,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 8, "metadata": {}, "outputs": [ { @@ -244,7 +244,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -307,7 +307,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ @@ -342,7 +342,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 11, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:58.153514385Z", @@ -365,7 +365,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 12, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:59.046068930Z", @@ -389,7 +389,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 13, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:15:01.683216142Z", @@ -409,16 +409,16 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch: 1 loss: 12533533.0041\n", - "Test_loss: 1476.5474\n", - "Epoch: 2 loss: 16311.6069\n", - "Test_loss: 67.2163\n", - "Epoch: 3 loss: 2506.7854\n", - "Test_loss: 2814.6946\n", - "Epoch: 4 loss: 2899.9972\n", - "Test_loss: 5.7347\n", - "Epoch: 5 loss: 2714.4102\n", - "Test_loss: 6.6283\n" + "Epoch: 1 loss: 11062303.5101\n", + "Test_loss: 135039.8750\n", + "Epoch: 2 loss: 12746.0434\n", + "Test_loss: 7911.8130\n", + "Epoch: 3 loss: 1477.9950\n", + "Test_loss: 228.0758\n", + "Epoch: 4 loss: 702.3154\n", + "Test_loss: 10.2958\n", + "Epoch: 5 loss: 872.6976\n", + "Test_loss: 1025.2914\n" ] } ], @@ -459,13 +459,6 @@ "\n", " print(f\"Test_loss: {loss:.4f}\", flush=True)" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/tutorials/hypergraph/hmpnn_train.ipynb b/tutorials/hypergraph/hmpnn_train.ipynb index 33eaf57b2..85be4dbda 100644 --- a/tutorials/hypergraph/hmpnn_train.ipynb +++ b/tutorials/hypergraph/hmpnn_train.ipynb @@ -15,7 +15,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 1, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:51.222779223Z", @@ -45,7 +45,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 2, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:51.959770754Z", @@ -57,7 +57,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "cpu\n" + "cuda\n" ] } ], @@ -78,7 +78,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -94,7 +94,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -106,7 +106,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -127,7 +127,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -197,7 +197,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -222,7 +222,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 8, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:58.153514385Z", @@ -254,7 +254,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 9, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:15:01.683216142Z", @@ -266,26 +266,26 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch: 6 train loss: 1.2548 train acc: 0.82 val loss: 1.9955 val acc: 0.23 test loss: 0.2190 val acc: 0.22\n", - "Epoch: 11 train loss: 0.8370 train acc: 1.00 val loss: 1.7554 val acc: 0.38 test loss: 0.3870 val acc: 0.39\n", - "Epoch: 16 train loss: 0.4960 train acc: 1.00 val loss: 1.6560 val acc: 0.42 test loss: 0.4450 val acc: 0.45\n", - "Epoch: 21 train loss: 0.2625 train acc: 1.00 val loss: 1.5750 val acc: 0.43 test loss: 0.4490 val acc: 0.45\n", - "Epoch: 26 train loss: 0.1403 train acc: 1.00 val loss: 1.5674 val acc: 0.45 test loss: 0.4420 val acc: 0.44\n", - "Epoch: 31 train loss: 0.0737 train acc: 1.00 val loss: 1.6039 val acc: 0.45 test loss: 0.4540 val acc: 0.45\n", - "Epoch: 36 train loss: 0.0448 train acc: 1.00 val loss: 1.6474 val acc: 0.45 test loss: 0.4700 val acc: 0.47\n", - "Epoch: 41 train loss: 0.0269 train acc: 1.00 val loss: 1.6880 val acc: 0.46 test loss: 0.4710 val acc: 0.47\n", - "Epoch: 46 train loss: 0.0182 train acc: 1.00 val loss: 1.7079 val acc: 0.44 test loss: 0.4700 val acc: 0.47\n", - "Epoch: 51 train loss: 0.0139 train acc: 1.00 val loss: 1.6682 val acc: 0.47 test loss: 0.4790 val acc: 0.48\n", - "Epoch: 56 train loss: 0.0116 train acc: 1.00 val loss: 1.6277 val acc: 0.49 test loss: 0.4970 val acc: 0.50\n", - "Epoch: 61 train loss: 0.0100 train acc: 1.00 val loss: 1.6208 val acc: 0.49 test loss: 0.5000 val acc: 0.50\n", - "Epoch: 66 train loss: 0.0086 train acc: 1.00 val loss: 1.6295 val acc: 0.51 test loss: 0.5020 val acc: 0.50\n", - "Epoch: 71 train loss: 0.0072 train acc: 1.00 val loss: 1.6361 val acc: 0.50 test loss: 0.5040 val acc: 0.50\n", - "Epoch: 76 train loss: 0.0063 train acc: 1.00 val loss: 1.6177 val acc: 0.51 test loss: 0.5060 val acc: 0.51\n", - "Epoch: 81 train loss: 0.0060 train acc: 1.00 val loss: 1.6049 val acc: 0.51 test loss: 0.5090 val acc: 0.51\n", - "Epoch: 86 train loss: 0.0055 train acc: 1.00 val loss: 1.6047 val acc: 0.52 test loss: 0.5180 val acc: 0.52\n", - "Epoch: 91 train loss: 0.0056 train acc: 1.00 val loss: 1.6063 val acc: 0.53 test loss: 0.5200 val acc: 0.52\n", - "Epoch: 96 train loss: 0.0047 train acc: 1.00 val loss: 1.6037 val acc: 0.53 test loss: 0.5170 val acc: 0.52\n", - "Epoch: 101 train loss: 0.0050 train acc: 1.00 val loss: 1.6076 val acc: 0.53 test loss: 0.5160 val acc: 0.52\n" + "Epoch: 6 train loss: 1.2665 train acc: 0.82 val loss: 1.9848 val acc: 0.23 test loss: 0.2270 val acc: 0.23\n", + "Epoch: 11 train loss: 0.8439 train acc: 0.99 val loss: 1.7569 val acc: 0.38 test loss: 0.3970 val acc: 0.40\n", + "Epoch: 16 train loss: 0.5119 train acc: 1.00 val loss: 1.6846 val acc: 0.39 test loss: 0.4160 val acc: 0.42\n", + "Epoch: 21 train loss: 0.2717 train acc: 1.00 val loss: 1.5872 val acc: 0.43 test loss: 0.4500 val acc: 0.45\n", + "Epoch: 26 train loss: 0.1571 train acc: 1.00 val loss: 1.6143 val acc: 0.41 test loss: 0.4230 val acc: 0.42\n", + "Epoch: 31 train loss: 0.0816 train acc: 1.00 val loss: 1.5894 val acc: 0.45 test loss: 0.4490 val acc: 0.45\n", + "Epoch: 36 train loss: 0.0478 train acc: 1.00 val loss: 1.6020 val acc: 0.46 test loss: 0.4630 val acc: 0.46\n", + "Epoch: 41 train loss: 0.0298 train acc: 1.00 val loss: 1.6153 val acc: 0.47 test loss: 0.4670 val acc: 0.47\n", + "Epoch: 46 train loss: 0.0214 train acc: 1.00 val loss: 1.6499 val acc: 0.47 test loss: 0.4720 val acc: 0.47\n", + "Epoch: 51 train loss: 0.0160 train acc: 1.00 val loss: 1.6764 val acc: 0.48 test loss: 0.4830 val acc: 0.48\n", + "Epoch: 56 train loss: 0.0149 train acc: 1.00 val loss: 1.6986 val acc: 0.48 test loss: 0.4900 val acc: 0.49\n", + "Epoch: 61 train loss: 0.0123 train acc: 1.00 val loss: 1.6888 val acc: 0.47 test loss: 0.4920 val acc: 0.49\n", + "Epoch: 66 train loss: 0.0097 train acc: 1.00 val loss: 1.6670 val acc: 0.48 test loss: 0.4970 val acc: 0.50\n", + "Epoch: 71 train loss: 0.0078 train acc: 1.00 val loss: 1.6547 val acc: 0.49 test loss: 0.5030 val acc: 0.50\n", + "Epoch: 76 train loss: 0.0072 train acc: 1.00 val loss: 1.6484 val acc: 0.49 test loss: 0.5030 val acc: 0.50\n", + "Epoch: 81 train loss: 0.0066 train acc: 1.00 val loss: 1.6378 val acc: 0.49 test loss: 0.5100 val acc: 0.51\n", + "Epoch: 86 train loss: 0.0064 train acc: 1.00 val loss: 1.6507 val acc: 0.49 test loss: 0.5110 val acc: 0.51\n", + "Epoch: 91 train loss: 0.0060 train acc: 1.00 val loss: 1.6745 val acc: 0.50 test loss: 0.5100 val acc: 0.51\n", + "Epoch: 96 train loss: 0.0051 train acc: 1.00 val loss: 1.6682 val acc: 0.50 test loss: 0.5150 val acc: 0.52\n", + "Epoch: 101 train loss: 0.0047 train acc: 1.00 val loss: 1.6412 val acc: 0.50 test loss: 0.5190 val acc: 0.52\n" ] } ], @@ -306,7 +306,7 @@ "\n", " train_loss = loss.item()\n", " y_pred = y_hat.argmax(dim=-1)\n", - " train_acc = accuracy_score(y[train_mask], y_pred[train_mask])\n", + " train_acc = accuracy_score(y[train_mask].cpu(), y_pred[train_mask].cpu())\n", " \n", " if epoch % test_interval == 0:\n", " model.eval()\n", @@ -314,12 +314,12 @@ " y_hat = model(x_0s, initial_x_1, incidence_1)\n", " val_loss = loss_fn(y_hat[val_mask], y[val_mask]).item()\n", " y_pred = y_hat.argmax(dim=-1)\n", - " val_acc = accuracy_score(y[val_mask], y_pred[val_mask])\n", + " val_acc = accuracy_score(y[val_mask].cpu(), y_pred[val_mask].cpu())\n", "\n", "\n", " test_loss = loss_fn(y_hat[test_mask], y[test_mask]).item()\n", " y_pred = y_hat.argmax(dim=-1)\n", - " test_acc = accuracy_score(y[test_mask], y_pred[test_mask])\n", + " test_acc = accuracy_score(y[test_mask].cpu(), y_pred[test_mask].cpu())\n", " print(\n", " f\"Epoch: {epoch + 1} train loss: {train_loss:.4f} train acc: {train_acc:.2f} \"\n", " f\" val loss: {val_loss:.4f} val acc: {val_acc:.2f}\"\n", diff --git a/tutorials/hypergraph/hnhn_train.ipynb b/tutorials/hypergraph/hnhn_train.ipynb index ae02eb98f..fb861e635 100644 --- a/tutorials/hypergraph/hnhn_train.ipynb +++ b/tutorials/hypergraph/hnhn_train.ipynb @@ -87,7 +87,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "cpu\n" + "cuda\n" ] } ], @@ -413,9 +413,9 @@ "name": "stderr", "output_type": "stream", "text": [ - "/tmp/ipykernel_771339/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_96287/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " x_0s = torch.tensor(x_0s)\n", - "/tmp/ipykernel_771339/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_96287/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " torch.tensor(y, dtype=torch.long).to(device),\n" ] } @@ -439,7 +439,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -452,7 +452,7 @@ "Test_loss: 0.8030, Test_acc: 0.7570\n", "Epoch: 10 \n", "Train_loss: 0.5751, acc: 1.0000\n", - "Val_loss: 1.6033, Val_acc: 0.7140\n", + "Val_loss: 1.6032, Val_acc: 0.7140\n", "Test_loss: 1.3768, Test_acc: 0.7370\n", "Epoch: 15 \n", "Train_loss: 0.3835, acc: 1.0000\n", @@ -464,7 +464,7 @@ "Test_loss: 3.0300, Test_acc: 0.7310\n", "Epoch: 25 \n", "Train_loss: 0.2301, acc: 1.0000\n", - "Val_loss: 4.1970, Val_acc: 0.7120\n", + "Val_loss: 4.1969, Val_acc: 0.7120\n", "Test_loss: 3.5745, Test_acc: 0.7310\n", "Epoch: 30 \n", "Train_loss: 0.1917, acc: 1.0000\n", diff --git a/tutorials/hypergraph/hypergat_train.ipynb b/tutorials/hypergraph/hypergat_train.ipynb index be0c000c8..53a898521 100644 --- a/tutorials/hypergraph/hypergat_train.ipynb +++ b/tutorials/hypergraph/hypergat_train.ipynb @@ -72,7 +72,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "cpu\n" + "cuda\n" ] } ], @@ -371,10 +371,10 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch: 5 train_loss 2978.1547 test_loss: 1478.9974\n", - "Epoch: 10 train_loss 970.8229 test_loss: 1610.4103\n", - "Epoch: 15 train_loss 812.0088 test_loss: 1999.1152\n", - "Epoch: 20 train_loss 943.5183 test_loss: 1675.4498\n" + "Epoch: 5 train_loss 7195.0287 test_loss: 19283.1447\n", + "Epoch: 10 train_loss 1705.4479 test_loss: 4695.8421\n", + "Epoch: 15 train_loss 2624.2060 test_loss: 3844.4079\n", + "Epoch: 20 train_loss 6754.1770 test_loss: 4970.3517\n" ] } ], diff --git a/tutorials/hypergraph/hypersage_train.ipynb b/tutorials/hypergraph/hypersage_train.ipynb index d4ff2808a..2b6840423 100644 --- a/tutorials/hypergraph/hypersage_train.ipynb +++ b/tutorials/hypergraph/hypersage_train.ipynb @@ -90,7 +90,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "cpu\n" + "cuda\n" ] } ], @@ -388,7 +388,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -404,7 +404,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 10, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:59.046068930Z", @@ -416,9 +416,9 @@ "name": "stderr", "output_type": "stream", "text": [ - "/tmp/ipykernel_703454/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_33450/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " x_0s = torch.tensor(x_0s)\n", - "/tmp/ipykernel_703454/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_33450/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " torch.tensor(y, dtype=torch.long).to(device),\n" ] } @@ -440,6 +440,31 @@ "The following cell performs the training, looping over the network for a low amount of epochs. We keep training minimal for the purpose of rapid testing." ] }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/tmp/ipykernel_33450/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + " x_0s = torch.tensor(x_0s)\n", + "/tmp/ipykernel_33450/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + " torch.tensor(y, dtype=torch.long).to(device),\n" + ] + } + ], + "source": [ + "x_0s = torch.tensor(x_0s)\n", + "x_0s, incidence_1, y = (\n", + " x_0s.float().to(device),\n", + " incidence_1.float().to(device),\n", + " torch.tensor(y, dtype=torch.long).to(device),\n", + " )" + ] + }, { "cell_type": "code", "execution_count": 12, @@ -450,29 +475,29 @@ "output_type": "stream", "text": [ "Epoch: 5 \n", - "Train_loss: 1.9426, acc: 0.3357\n", - "Val_loss: 1.9326, Val_acc: 0.2720\n", - "Test_loss: 1.9334, Test_acc: 0.2660\n", + "Train_loss: 1.9424, acc: 0.5929\n", + "Val_loss: 1.9401, Val_acc: 0.2460\n", + "Test_loss: 1.9405, Test_acc: 0.2620\n", "Epoch: 10 \n", - "Train_loss: 1.9306, acc: 0.8786\n", - "Val_loss: 1.9296, Val_acc: 0.4560\n", - "Test_loss: 1.9294, Test_acc: 0.4540\n", + "Train_loss: 1.9305, acc: 0.9357\n", + "Val_loss: 1.9221, Val_acc: 0.5680\n", + "Test_loss: 1.9220, Test_acc: 0.5580\n", "Epoch: 15 \n", - "Train_loss: 1.9107, acc: 0.9643\n", - "Val_loss: 1.9026, Val_acc: 0.5480\n", - "Test_loss: 1.9021, Test_acc: 0.5300\n", + "Train_loss: 1.9105, acc: 0.9714\n", + "Val_loss: 1.8899, Val_acc: 0.6560\n", + "Test_loss: 1.8904, Test_acc: 0.6490\n", "Epoch: 20 \n", - "Train_loss: 1.8813, acc: 1.0000\n", - "Val_loss: 1.8525, Val_acc: 0.6880\n", - "Test_loss: 1.8527, Test_acc: 0.6820\n", + "Train_loss: 1.8811, acc: 0.9786\n", + "Val_loss: 1.8450, Val_acc: 0.7260\n", + "Test_loss: 1.8466, Test_acc: 0.6990\n", "Epoch: 25 \n", - "Train_loss: 1.8415, acc: 1.0000\n", - "Val_loss: 1.7858, Val_acc: 0.7460\n", - "Test_loss: 1.7870, Test_acc: 0.7270\n", + "Train_loss: 1.8412, acc: 0.9929\n", + "Val_loss: 1.7831, Val_acc: 0.7360\n", + "Test_loss: 1.7857, Test_acc: 0.7210\n", "Epoch: 30 \n", - "Train_loss: 1.7908, acc: 1.0000\n", - "Val_loss: 1.7072, Val_acc: 0.7460\n", - "Test_loss: 1.7094, Test_acc: 0.7330\n" + "Train_loss: 1.7905, acc: 1.0000\n", + "Val_loss: 1.7067, Val_acc: 0.7420\n", + "Test_loss: 1.7103, Test_acc: 0.7220\n" ] } ], diff --git a/tutorials/hypergraph/unigcn_train.ipynb b/tutorials/hypergraph/unigcn_train.ipynb index 6ef1aaa15..201e0fbdb 100644 --- a/tutorials/hypergraph/unigcn_train.ipynb +++ b/tutorials/hypergraph/unigcn_train.ipynb @@ -39,7 +39,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "cpu\n" + "cuda\n" ] } ], @@ -74,7 +74,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 9, "id": "8075441c", "metadata": {}, "outputs": [], @@ -88,7 +88,7 @@ " hg = SimplicialComplex(to_networkx(graph)).to_hypergraph()\n", " hg_list.append(hg)\n", " x_1_list.append(graph.x.to(device))\n", - " y_list.append(int(graph.y.to(device)))\n", + " y_list.append(graph.y.to(device))\n", "\n", "incidence_1_list = []\n", "for hg in hg_list:\n", @@ -110,7 +110,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 10, "id": "fb337a87", "metadata": {}, "outputs": [], @@ -182,7 +182,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 11, "id": "9ed1b248", "metadata": {}, "outputs": [], @@ -219,7 +219,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 12, "id": "2f3d2abf", "metadata": {}, "outputs": [], @@ -238,7 +238,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 13, "id": "505a424d", "metadata": {}, "outputs": [], @@ -266,7 +266,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 18, "id": "78e26ec9", "metadata": {}, "outputs": [ @@ -274,21 +274,21 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch 0 loss: 303.8309020996094\n", + "Epoch 0 loss: 389.1796569824219\n", "Epoch 0 Validation accuracy: 0.5625\n", - "Epoch 10 loss: 78.16102600097656\n", + "Epoch 10 loss: 64.91588592529297\n", "Epoch 10 Validation accuracy: 0.5625\n", - "Epoch 20 loss: 28.61541175842285\n", - "Epoch 20 Validation accuracy: 0.5625\n", - "Epoch 30 loss: 29.697616577148438\n", + "Epoch 20 loss: 40.873802185058594\n", + "Epoch 20 Validation accuracy: 0.4375\n", + "Epoch 30 loss: 26.046907424926758\n", "Epoch 30 Validation accuracy: 0.625\n", - "Epoch 40 loss: 26.69053077697754\n", + "Epoch 40 loss: 25.672311782836914\n", "Epoch 40 Validation accuracy: 0.625\n", - "Epoch 50 loss: 24.988874435424805\n", + "Epoch 50 loss: 24.973644256591797\n", "Epoch 50 Validation accuracy: 0.625\n", - "Epoch 60 loss: 23.865966796875\n", + "Epoch 60 loss: 24.025209426879883\n", "Epoch 60 Validation accuracy: 0.625\n", - "Test accuracy: 0.75\n" + "Test accuracy: 0.8\n" ] } ], @@ -302,7 +302,7 @@ " loss = 0\n", " for x_1, incidence_1, y in zip(x_1_train, incidence_1_train, y_train):\n", " output = model(x_1, incidence_1)\n", - " loss += crit(output.unsqueeze(0), torch.tensor([y]))\n", + " loss += crit(output.unsqueeze(0), y)\n", " loss.backward()\n", " optimizer.step()\n", " if epoch % test_interval == 0:\n", @@ -327,6 +327,33 @@ " correct += 1\n", " print(f\"Test accuracy: {correct / len(y_test)}\")" ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "tensor([1], device='cuda:0')" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "y" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { diff --git a/tutorials/hypergraph/unigcnii_train.ipynb b/tutorials/hypergraph/unigcnii_train.ipynb index 1fbedf373..3cf4fd820 100644 --- a/tutorials/hypergraph/unigcnii_train.ipynb +++ b/tutorials/hypergraph/unigcnii_train.ipynb @@ -50,7 +50,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "cpu\n" + "cuda\n" ] } ], @@ -372,6 +372,31 @@ "Now, we are ready to train the created model and evaluate the performance on the validation set." ] }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/tmp/ipykernel_7355/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + " x_0s = torch.tensor(x_0s)\n", + "/tmp/ipykernel_7355/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + " torch.tensor(y, dtype=torch.long).to(device),\n" + ] + } + ], + "source": [ + "x_0s = torch.tensor(x_0s)\n", + "x_0s, incidence_1, y = (\n", + " x_0s.float().to(device),\n", + " incidence_1.float().to(device),\n", + " torch.tensor(y, dtype=torch.long).to(device),\n", + " )" + ] + }, { "cell_type": "code", "execution_count": 12, @@ -381,12 +406,12 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch: 0 Train_loss: 6.5894, Train_acc: 0.1429 Test_loss: 8.7642, Test_acc: 0.1430\n", - "Epoch: 5 Train_loss: 1.6524, Train_acc: 0.5643 Test_loss: 1.7561, Test_acc: 0.4770\n", - "Epoch: 10 Train_loss: 1.4487, Train_acc: 0.6857 Test_loss: 1.6757, Test_acc: 0.5350\n", - "Epoch: 15 Train_loss: 1.1535, Train_acc: 0.7500 Test_loss: 1.5980, Test_acc: 0.6030\n", - "Epoch: 20 Train_loss: 0.8682, Train_acc: 0.8143 Test_loss: 1.6471, Test_acc: 0.6620\n", - "Epoch: 25 Train_loss: 0.6407, Train_acc: 0.8500 Test_loss: 1.8455, Test_acc: 0.6860\n" + "Epoch: 0 Train_loss: 6.3311, Train_acc: 0.1429 Test_loss: 8.4650, Test_acc: 0.1430\n", + "Epoch: 5 Train_loss: 1.7255, Train_acc: 0.6000 Test_loss: 1.7909, Test_acc: 0.4460\n", + "Epoch: 10 Train_loss: 1.4779, Train_acc: 0.6714 Test_loss: 1.6235, Test_acc: 0.5080\n", + "Epoch: 15 Train_loss: 1.2046, Train_acc: 0.7786 Test_loss: 1.5192, Test_acc: 0.5790\n", + "Epoch: 20 Train_loss: 0.8618, Train_acc: 0.8500 Test_loss: 1.4219, Test_acc: 0.6350\n", + "Epoch: 25 Train_loss: 0.6326, Train_acc: 0.8643 Test_loss: 1.4752, Test_acc: 0.6700\n" ] } ], @@ -416,6 +441,13 @@ " Test_loss: {loss:.4f}, Test_acc: {acc_fn(y_hat[test_mask].argmax(1), y[test_mask]):.4f}\",\n", " flush=True)" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { diff --git a/tutorials/hypergraph/unigin_train.ipynb b/tutorials/hypergraph/unigin_train.ipynb index 62825f996..1ea4fb196 100644 --- a/tutorials/hypergraph/unigin_train.ipynb +++ b/tutorials/hypergraph/unigin_train.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 10, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -28,14 +28,14 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "cpu\n" + "cuda\n" ] } ], @@ -69,7 +69,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -82,7 +82,7 @@ " hg = SimplicialComplex(to_networkx(graph)).to_hypergraph()\n", " hg_list.append(hg)\n", " x_1_list.append(graph.x.to(device))\n", - " y_list.append(int(graph.y.to(device)))\n", + " y_list.append(graph.y.to(device))\n", "\n", "incidence_1_list = []\n", "for hg in hg_list:\n", @@ -104,7 +104,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -174,7 +174,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -214,7 +214,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -232,7 +232,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -259,26 +259,26 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Epoch 0 loss: 1279.834716796875\n", + "Epoch 0 loss: 1261.591552734375\n", "Epoch 0 Validation accuracy: 0.5625\n", - "Epoch 10 loss: 43.52538299560547\n", - "Epoch 10 Validation accuracy: 0.3125\n", - "Epoch 20 loss: 32.36000442504883\n", - "Epoch 20 Validation accuracy: 0.25\n", - "Epoch 30 loss: 28.736360549926758\n", - "Epoch 30 Validation accuracy: 0.5625\n", - "Epoch 40 loss: 26.598899841308594\n", + "Epoch 10 loss: 50.00477600097656\n", + "Epoch 10 Validation accuracy: 0.5625\n", + "Epoch 20 loss: 37.117366790771484\n", + "Epoch 20 Validation accuracy: 0.4375\n", + "Epoch 30 loss: 30.90342903137207\n", + "Epoch 30 Validation accuracy: 0.3125\n", + "Epoch 40 loss: 25.588314056396484\n", "Epoch 40 Validation accuracy: 0.5625\n", - "Epoch 50 loss: 24.64439582824707\n", + "Epoch 50 loss: 26.57889747619629\n", "Epoch 50 Validation accuracy: 0.625\n", - "Epoch 60 loss: 26.797300338745117\n", + "Epoch 60 loss: 19.412574768066406\n", "Epoch 60 Validation accuracy: 0.5625\n", "Test accuracy: 0.7\n" ] @@ -293,7 +293,7 @@ " loss = 0\n", " for x_1, incidence_1, y in zip(x_1_train, incidence_1_train, y_train):\n", " output = model(x_1, incidence_1)\n", - " loss += crit(output.unsqueeze(0), torch.tensor([y]))\n", + " loss += crit(output.unsqueeze(0), y)\n", " loss.backward()\n", " optimizer.step()\n", " if epoch % test_interval == 0:\n", diff --git a/tutorials/hypergraph/unisage_train.ipynb b/tutorials/hypergraph/unisage_train.ipynb index a89b173df..a4c67e810 100644 --- a/tutorials/hypergraph/unisage_train.ipynb +++ b/tutorials/hypergraph/unisage_train.ipynb @@ -29,7 +29,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "cpu\n" + "cuda\n" ] } ], @@ -351,9 +351,9 @@ "name": "stderr", "output_type": "stream", "text": [ - "/tmp/ipykernel_662599/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_20995/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " x_0s = torch.tensor(x_0s)\n", - "/tmp/ipykernel_662599/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_20995/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " torch.tensor(y, dtype=torch.long).to(device),\n" ] } @@ -386,49 +386,29 @@ "output_type": "stream", "text": [ "Epoch: 5 \n", - "Train_loss: 1.1114, acc: 0.9643\n", - "Val_loss: 0.9522, Val_acc: 0.7680\n", - "Test_loss: 1.0774, Test_acc: 0.7820\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ + "Train_loss: 1.0359, acc: 0.9786\n", + "Val_loss: 0.9799, Val_acc: 0.7840\n", + "Test_loss: 1.0519, Test_acc: 0.7970\n", "Epoch: 10 \n", - "Train_loss: 0.6466, acc: 0.9929\n", - "Val_loss: 1.3639, Val_acc: 0.7640\n", - "Test_loss: 1.5591, Test_acc: 0.7510\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/TopoModelX/topomodelx/nn/hypergraph/unisage_layer.py:120: UserWarning: Sparse CSR tensor support is in beta state. If you miss a functionality in the sparse tensor support, please submit a feature request to https://github.com/pytorch/pytorch/issues. (Triggered internally at ../aten/src/ATen/SparseCsrTensorImpl.cpp:54.)\n", - " incidence_1_transpose = incidence_1.T.to_sparse_csr()\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ + "Train_loss: 0.5867, acc: 0.9929\n", + "Val_loss: 1.4344, Val_acc: 0.7620\n", + "Test_loss: 1.6381, Test_acc: 0.7570\n", "Epoch: 15 \n", - "Train_loss: 0.4479, acc: 1.0000\n", - "Val_loss: 1.5922, Val_acc: 0.7680\n", - "Test_loss: 1.8342, Test_acc: 0.7620\n", + "Train_loss: 0.4123, acc: 1.0000\n", + "Val_loss: 1.7868, Val_acc: 0.7440\n", + "Test_loss: 1.8944, Test_acc: 0.7610\n", "Epoch: 20 \n", - "Train_loss: 0.3434, acc: 1.0000\n", - "Val_loss: 1.8131, Val_acc: 0.7620\n", - "Test_loss: 2.0800, Test_acc: 0.7640\n", + "Train_loss: 0.3157, acc: 1.0000\n", + "Val_loss: 2.1006, Val_acc: 0.7520\n", + "Test_loss: 2.3052, Test_acc: 0.7560\n", "Epoch: 25 \n", - "Train_loss: 0.2765, acc: 1.0000\n", - "Val_loss: 1.9989, Val_acc: 0.7620\n", - "Test_loss: 2.2934, Test_acc: 0.7660\n", + "Train_loss: 0.2532, acc: 1.0000\n", + "Val_loss: 2.4428, Val_acc: 0.7480\n", + "Test_loss: 2.7105, Test_acc: 0.7460\n", "Epoch: 30 \n", - "Train_loss: 0.2362, acc: 1.0000\n", - "Val_loss: 2.2402, Val_acc: 0.7600\n", - "Test_loss: 2.6936, Test_acc: 0.7470\n" + "Train_loss: 0.2113, acc: 1.0000\n", + "Val_loss: 2.5174, Val_acc: 0.7480\n", + "Test_loss: 2.7498, Test_acc: 0.7520\n" ] } ], From 41c38a851538f2e011c2b7fa624c797913ad8e43 Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Mon, 6 Nov 2023 15:59:50 +0000 Subject: [PATCH 10/39] comments correction --- topomodelx/nn/hypergraph/hmpnn.py | 4 ++-- topomodelx/nn/hypergraph/hnhn_layer.py | 6 +++--- topomodelx/nn/hypergraph/hypergat.py | 2 +- topomodelx/nn/hypergraph/unigcn.py | 2 +- topomodelx/nn/hypergraph/unisage.py | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/topomodelx/nn/hypergraph/hmpnn.py b/topomodelx/nn/hypergraph/hmpnn.py index 230050006..a9d792708 100644 --- a/topomodelx/nn/hypergraph/hmpnn.py +++ b/topomodelx/nn/hypergraph/hmpnn.py @@ -11,9 +11,9 @@ class HMPNN(torch.nn.Module): Parameters ---------- - in_features : int + in_channels : int Dimension of input features - hidden_features : Tuple[int] + hidden_channels : Tuple[int] A tuple of hidden feature dimensions to gradually reduce node/hyperedge representations feature dimension from in_features to the last item in the tuple. num_classes: int diff --git a/topomodelx/nn/hypergraph/hnhn_layer.py b/topomodelx/nn/hypergraph/hnhn_layer.py index 5e4c513d8..76f9af5dc 100644 --- a/topomodelx/nn/hypergraph/hnhn_layer.py +++ b/topomodelx/nn/hypergraph/hnhn_layer.py @@ -21,10 +21,10 @@ class HNHNLayer(torch.nn.Module): Parameters ---------- - channels_node : int + in_channels : int Dimension of node features. - channels_edge : int - Dimension of edge features. + hidden_channels : int + Dimension of hidden features. incidence_1 : torch.sparse, shape = (n_nodes, n_edges) Incidence matrix mapping edges to nodes (B_1). use_bias : bool diff --git a/topomodelx/nn/hypergraph/hypergat.py b/topomodelx/nn/hypergraph/hypergat.py index af911c144..dfe4260e0 100644 --- a/topomodelx/nn/hypergraph/hypergat.py +++ b/topomodelx/nn/hypergraph/hypergat.py @@ -14,7 +14,7 @@ class HyperGAT(torch.nn.Module): Dimension of the input features. hidden_channels : int Dimension of the hidden features. - n_layer : int, default = 2 + n_layers : int, default = 2 Amount of message passing layers. References diff --git a/topomodelx/nn/hypergraph/unigcn.py b/topomodelx/nn/hypergraph/unigcn.py index 824744d07..1db8653e8 100644 --- a/topomodelx/nn/hypergraph/unigcn.py +++ b/topomodelx/nn/hypergraph/unigcn.py @@ -14,7 +14,7 @@ class UniGCN(torch.nn.Module): Dimension of the input features. hidden_channels : int Dimension of the hidden features. - n_layer : int, default = 2 + n_layers : int, default = 2 Amount of message passing layers. References diff --git a/topomodelx/nn/hypergraph/unisage.py b/topomodelx/nn/hypergraph/unisage.py index b8a6a6b44..87d6774ee 100644 --- a/topomodelx/nn/hypergraph/unisage.py +++ b/topomodelx/nn/hypergraph/unisage.py @@ -18,7 +18,7 @@ class UniSAGE(torch.nn.Module): Dropout rate for the input features. layer_drop: float, default=0.2 Dropout rate for the hidden features. - n_layer : int, default = 2 + n_layers : int, default = 2 Amount of message passing layers. References From 66b312560b67589b418374860f8d7f2977e46930 Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Mon, 6 Nov 2023 17:22:01 +0000 Subject: [PATCH 11/39] checked CCs --- tutorials/cell/can_train.ipynb | 45 +++++----- tutorials/cell/ccxn_train.ipynb | 93 ++++++++++++--------- tutorials/cell/cwn_train.ipynb | 26 +++--- tutorials/combinatorial/hmc_train.ipynb | 104 ++++++++++++------------ 4 files changed, 145 insertions(+), 123 deletions(-) diff --git a/tutorials/cell/can_train.ipynb b/tutorials/cell/can_train.ipynb index 734f304a8..0e794c05b 100644 --- a/tutorials/cell/can_train.ipynb +++ b/tutorials/cell/can_train.ipynb @@ -125,7 +125,10 @@ "\n", "\n", "from topomodelx.nn.cell.can import CAN\n", - "from topomodelx.utils.sparse import from_sparse" + "from topomodelx.utils.sparse import from_sparse\n", + "\n", + "torch.manual_seed(0)\n", + "np.random.seed(0)" ] }, { @@ -137,7 +140,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 4, "metadata": { "ExecuteTime": { "end_time": "2023-05-31T09:13:53.006542411Z", @@ -149,7 +152,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "cpu\n" + "cuda:2\n" ] } ], @@ -177,7 +180,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 5, "metadata": { "ExecuteTime": { "end_time": "2023-05-31T09:13:55.279147916Z", @@ -235,7 +238,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 6, "metadata": { "ExecuteTime": { "end_time": "2023-05-31T09:13:55.832585216Z", @@ -280,7 +283,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 7, "metadata": { "ExecuteTime": { "end_time": "2023-05-31T09:13:56.672913561Z", @@ -327,7 +330,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 8, "metadata": { "ExecuteTime": { "end_time": "2023-05-31T09:19:40.411845803Z", @@ -376,7 +379,7 @@ ")" ] }, - "execution_count": 6, + "execution_count": 8, "metadata": {}, "output_type": "execute_result" } @@ -396,7 +399,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 9, "metadata": { "ExecuteTime": { "end_time": "2023-05-31T09:19:41.150933630Z", @@ -422,7 +425,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 10, "metadata": { "ExecuteTime": { "end_time": "2023-05-31T09:19:42.918836083Z", @@ -434,22 +437,22 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch: 1 loss: 0.6251 Train_acc: 0.6794\n", + "Epoch: 1 loss: 0.6348 Train_acc: 0.6718\n", "Test_acc: 0.5965\n", - "Epoch: 2 loss: 0.6007 Train_acc: 0.6947\n", + "Epoch: 2 loss: 0.6101 Train_acc: 0.6947\n", "Test_acc: 0.5965\n", - "Epoch: 3 loss: 0.6094 Train_acc: 0.6947\n", + "Epoch: 3 loss: 0.6008 Train_acc: 0.6947\n", "Test_acc: 0.5965\n", - "Epoch: 4 loss: 0.5881 Train_acc: 0.6947\n", - "Test_acc: 0.5965\n", - "Epoch: 5 loss: 0.5885 Train_acc: 0.7099\n", - "Test_acc: 0.6316\n", - "Epoch: 6 loss: 0.5685 Train_acc: 0.7252\n", + "Epoch: 4 loss: 0.5888 Train_acc: 0.7099\n", "Test_acc: 0.6316\n", - "Epoch: 7 loss: 0.5792 Train_acc: 0.7176\n", + "Epoch: 5 loss: 0.5850 Train_acc: 0.7252\n", + "Test_acc: 0.7368\n", + "Epoch: 6 loss: 0.5841 Train_acc: 0.7328\n", + "Test_acc: 0.6491\n", + "Epoch: 7 loss: 0.5772 Train_acc: 0.7328\n", "Test_acc: 0.6491\n", - "Epoch: 8 loss: 0.5614 Train_acc: 0.7405\n", - "Test_acc: 0.7368\n" + "Epoch: 8 loss: 0.5375 Train_acc: 0.7405\n", + "Test_acc: 0.7193\n" ] } ], diff --git a/tutorials/cell/ccxn_train.ipynb b/tutorials/cell/ccxn_train.ipynb index 1412f19b5..8127a423f 100644 --- a/tutorials/cell/ccxn_train.ipynb +++ b/tutorials/cell/ccxn_train.ipynb @@ -48,7 +48,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 1, "metadata": { "ExecuteTime": { "end_time": "2023-05-31T09:06:36.009880829Z", @@ -66,7 +66,10 @@ "\n", "\n", "from topomodelx.nn.cell.ccxn import CCXN\n", - "from topomodelx.utils.sparse import from_sparse" + "from topomodelx.utils.sparse import from_sparse\n", + "\n", + "torch.manual_seed(0)\n", + "np.random.seed(0)" ] }, { @@ -78,7 +81,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 2, "metadata": { "ExecuteTime": { "end_time": "2023-05-31T09:13:53.006542411Z", @@ -90,7 +93,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "cpu\n" + "cuda\n" ] } ], @@ -116,7 +119,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 3, "metadata": {}, "outputs": [ { @@ -143,7 +146,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -182,7 +185,7 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -203,7 +206,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 6, "metadata": { "ExecuteTime": { "end_time": "2023-05-31T09:13:55.832585216Z", @@ -241,7 +244,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 7, "metadata": { "ExecuteTime": { "end_time": "2023-05-31T09:13:56.672913561Z", @@ -279,7 +282,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": 8, "metadata": { "ExecuteTime": { "end_time": "2023-05-31T09:19:40.411845803Z", @@ -289,7 +292,7 @@ "outputs": [], "source": [ "crit = torch.nn.CrossEntropyLoss()\n", - "opt = torch.optim.Adam(model.parameters(), lr=0.1)\n", + "opt = torch.optim.Adam(model.parameters(), lr=0.01)\n", "loss_fn = torch.nn.MSELoss()" ] }, @@ -302,7 +305,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 9, "metadata": { "ExecuteTime": { "end_time": "2023-05-31T09:19:41.150933630Z", @@ -332,7 +335,7 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 10, "metadata": { "ExecuteTime": { "end_time": "2023-05-31T09:19:42.918836083Z", @@ -340,22 +343,29 @@ } }, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/usr/local/lib/python3.11/site-packages/torch/nn/modules/loss.py:536: UserWarning: Using a target size (torch.Size([])) that is different to the input size (torch.Size([1])). This will likely lead to incorrect results due to broadcasting. Please ensure they have the same size.\n", + " return F.mse_loss(input, target, reduction=self.reduction)\n" + ] + }, { "name": "stdout", "output_type": "stream", "text": [ - "Epoch: 1 loss: 93.0369\n", - "Epoch: 2 loss: 83.5211\n", - "Test_loss: 45.6080\n", - "Epoch: 3 loss: 85.5098\n", - "Epoch: 4 loss: 81.9403\n", - "Test_loss: 34.5233\n" + "Epoch:2, Train Loss: 82.9399 Test Loss: 72.3905\n", + "Epoch:4, Train Loss: 79.9278 Test Loss: 76.1475\n", + "Epoch:6, Train Loss: 76.7409 Test Loss: 75.5150\n", + "Epoch:8, Train Loss: 74.2580 Test Loss: 76.6475\n", + "Epoch:10, Train Loss: 72.1732 Test Loss: 78.3276\n" ] } ], "source": [ "test_interval = 2\n", - "num_epochs = 4\n", + "num_epochs = 10\n", "for epoch_i in range(1, num_epochs + 1):\n", " epoch_loss = []\n", " model.train()\n", @@ -376,12 +386,10 @@ " loss.backward()\n", " opt.step()\n", " epoch_loss.append(loss.item())\n", - " print(\n", - " f\"Epoch: {epoch_i} loss: {np.mean(epoch_loss):.4f}\",\n", - " flush=True,\n", - " )\n", + " \n", " if epoch_i % test_interval == 0:\n", " with torch.no_grad():\n", + " train_mean_loss = np.mean(epoch_loss)\n", " for x_0, x_1, incidence_2_t, adjacency_0, y in zip(\n", " x_0_test, x_1_test, incidence_2_t_test, adjacency_0_test, y_test\n", " ):\n", @@ -395,7 +403,7 @@ " ), adjacency_0.float().to(device)\n", " y_hat = model(x_0, x_1, adjacency_0, incidence_2_t)\n", " test_loss = loss_fn(y_hat, y)\n", - " print(f\"Test_loss: {test_loss:.4f}\", flush=True)" + " print(f\"Epoch:{epoch_i}, Train Loss: {train_mean_loss:.4f} Test Loss: {test_loss:.4f}\", flush=True)" ] }, { @@ -414,7 +422,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 11, "metadata": { "ExecuteTime": { "end_time": "2023-05-31T09:20:01.334080388Z", @@ -428,7 +436,7 @@ ")\n", "model = model.to(device)\n", "crit = torch.nn.CrossEntropyLoss()\n", - "opt = torch.optim.Adam(model.parameters(), lr=0.1)\n", + "opt = torch.optim.Adam(model.parameters(), lr=0.01)\n", "loss_fn = torch.nn.MSELoss()" ] }, @@ -441,7 +449,7 @@ }, { "cell_type": "code", - "execution_count": 24, + "execution_count": 12, "metadata": { "ExecuteTime": { "end_time": "2023-05-31T09:21:57.205551344Z", @@ -449,22 +457,29 @@ } }, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/usr/local/lib/python3.11/site-packages/torch/nn/modules/loss.py:536: UserWarning: Using a target size (torch.Size([])) that is different to the input size (torch.Size([2])). This will likely lead to incorrect results due to broadcasting. Please ensure they have the same size.\n", + " return F.mse_loss(input, target, reduction=self.reduction)\n" + ] + }, { "name": "stdout", "output_type": "stream", "text": [ - "Epoch: 1 loss: 100.7646\n", - "Epoch: 2 loss: 85.0686\n", - "Test_loss: 65.3428\n", - "Epoch: 3 loss: 82.4051\n", - "Epoch: 4 loss: 83.0310\n", - "Test_loss: 35.6043\n" + "Epoch:2, Train Loss: 96.2627 Test Loss: 67.7411\n", + "Epoch:4, Train Loss: 83.8081 Test Loss: 60.9365\n", + "Epoch:6, Train Loss: 78.7461 Test Loss: 64.3800\n", + "Epoch:8, Train Loss: 76.0083 Test Loss: 67.3870\n", + "Epoch:10, Train Loss: 73.6383 Test Loss: 67.6792\n" ] } ], "source": [ "test_interval = 2\n", - "num_epochs = 4\n", + "num_epochs = 10\n", "for epoch_i in range(1, num_epochs + 1):\n", " epoch_loss = []\n", " model.train()\n", @@ -485,12 +500,10 @@ " loss.backward()\n", " opt.step()\n", " epoch_loss.append(loss.item())\n", - " print(\n", - " f\"Epoch: {epoch_i} loss: {np.mean(epoch_loss):.4f}\",\n", - " flush=True,\n", - " )\n", + " \n", " if epoch_i % test_interval == 0:\n", " with torch.no_grad():\n", + " train_mean_loss = np.mean(epoch_loss)\n", " for x_0, x_1, incidence_2_t, adjacency_0, y in zip(\n", " x_0_test, x_1_test, incidence_2_t_test, adjacency_0_test, y_test\n", " ):\n", @@ -504,7 +517,7 @@ " ), adjacency_0.float().to(device)\n", " y_hat = model(x_0, x_1, adjacency_0, incidence_2_t)\n", " test_loss = loss_fn(y_hat, y)\n", - " print(f\"Test_loss: {test_loss:.4f}\", flush=True)" + " print(f\"Epoch:{epoch_i}, Train Loss: {train_mean_loss:.4f} Test Loss: {test_loss:.4f}\", flush=True)" ] }, { diff --git a/tutorials/cell/cwn_train.ipynb b/tutorials/cell/cwn_train.ipynb index 45a185a3c..3c301936b 100644 --- a/tutorials/cell/cwn_train.ipynb +++ b/tutorials/cell/cwn_train.ipynb @@ -62,7 +62,10 @@ "import toponetx.datasets as datasets\n", "\n", "from topomodelx.nn.cell.cwn import CWN\n", - "from topomodelx.utils.sparse import from_sparse" + "from topomodelx.utils.sparse import from_sparse\n", + "\n", + "torch.manual_seed(0)\n", + "np.random.seed(0)" ] }, { @@ -93,7 +96,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "cpu\n" + "cuda\n" ] } ], @@ -351,7 +354,7 @@ }, "outputs": [], "source": [ - "optimizer = torch.optim.Adam(model.parameters(), lr=0.05)\n", + "optimizer = torch.optim.Adam(model.parameters(), lr=0.01)\n", "criterion = torch.nn.MSELoss()" ] }, @@ -423,18 +426,17 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch: 1, Train Loss: 107.6411\n", - "Epoch: 2, Train Loss: 84.9619\n", - "Test Loss: 51.5892\n", - "Epoch: 3, Train Loss: 84.2476\n", - "Epoch: 4, Train Loss: 83.7038\n", - "Test Loss: 50.7303\n" + "Epoch:2, Train Loss: 83.8053 Test Loss: 73.7517\n", + "Epoch:4, Train Loss: 81.9552 Test Loss: 50.2781\n", + "Epoch:6, Train Loss: 78.3991 Test Loss: 49.9034\n", + "Epoch:8, Train Loss: 75.8107 Test Loss: 45.7201\n", + "Epoch:10, Train Loss: 74.3833 Test Loss: 40.5558\n" ] } ], "source": [ "test_interval = 2\n", - "num_epochs = 4\n", + "num_epochs = 10\n", "\n", "for epoch_i in range(1, num_epochs + 1):\n", " epoch_loss = []\n", @@ -467,9 +469,9 @@ " optimizer.step()\n", " epoch_loss.append(loss.item())\n", "\n", - " print(f\"Epoch: {epoch_i}, Train Loss: {np.mean(epoch_loss):.4f}\", flush=True)\n", " if epoch_i % test_interval == 0:\n", " with torch.no_grad():\n", + " train_mean_loss = np.mean(epoch_loss)\n", " for x_0, x_1, x_2, adjacency_1, incidence_2, incidence_1_t, y in zip(\n", " x_0_test,\n", " x_1_test,\n", @@ -492,7 +494,7 @@ "\n", " y_hat = model(x_0, x_1, x_2, adjacency_1, incidence_2, incidence_1_t)\n", " test_loss = criterion(y_hat, y)\n", - " print(f\"Test Loss: {test_loss:.4f}\", flush=True)" + " print(f\"Epoch:{epoch_i}, Train Loss: {train_mean_loss:.4f} Test Loss: {test_loss:.4f}\", flush=True)" ] }, { diff --git a/tutorials/combinatorial/hmc_train.ipynb b/tutorials/combinatorial/hmc_train.ipynb index 3482a6158..69c979dba 100644 --- a/tutorials/combinatorial/hmc_train.ipynb +++ b/tutorials/combinatorial/hmc_train.ipynb @@ -2,6 +2,9 @@ "cells": [ { "cell_type": "markdown", + "metadata": { + "collapsed": false + }, "source": [ "# Train a Combinatorial Complex Attention Neural Network for Mesh Classification.\n", "\n", @@ -109,10 +112,7 @@ "We lift the simplicial complexes representing each mesh to a topologically equivalent combinatorial complex representation.\n", "\n", "The task is to predict the class that a certain mesh belongs to, given its combinatorial complex representation. For this purpose we implement the Higher Order Attention Model for Mesh Classification first introduced in [Hajij et. al : Topological Deep Learning: Going Beyond Graph Data (2023)](https://arxiv.org/pdf/2206.00606.pdf)." - ], - "metadata": { - "collapsed": false - } + ] }, { "cell_type": "markdown", @@ -140,6 +140,31 @@ "from topomodelx.nn.combinatorial.hmc import HMC" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If GPU's are available, we will make use of them. Otherwise, this will run on CPU." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "cuda\n" + ] + } + ], + "source": [ + "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n", + "print(device)" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -153,7 +178,7 @@ }, { "cell_type": "code", - "execution_count": 34, + "execution_count": 3, "metadata": { "ExecuteTime": { "end_time": "2023-08-24T06:49:28.810114967Z", @@ -290,7 +315,7 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 4, "metadata": { "ExecuteTime": { "end_time": "2023-08-24T06:49:29.818662234Z", @@ -325,7 +350,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 5, "metadata": { "ExecuteTime": { "end_time": "2023-08-24T06:50:47.902394227Z", @@ -347,7 +372,7 @@ }, { "cell_type": "code", - "execution_count": 37, + "execution_count": 6, "metadata": { "ExecuteTime": { "end_time": "2023-08-24T06:55:26.795250682Z", @@ -386,18 +411,18 @@ }, { "cell_type": "markdown", + "metadata": { + "collapsed": false + }, "source": [ "# Train the Neural Network\n", "\n", "We create the trainer class. The model is trained using the Adam optimizer and the Cross Entropy Loss function." - ], - "metadata": { - "collapsed": false - } + ] }, { "cell_type": "code", - "execution_count": 38, + "execution_count": 7, "metadata": { "ExecuteTime": { "end_time": "2023-08-24T06:55:26.814069014Z", @@ -595,7 +620,7 @@ }, { "cell_type": "code", - "execution_count": 39, + "execution_count": 8, "metadata": { "ExecuteTime": { "end_time": "2023-08-24T06:55:28.220563261Z", @@ -633,7 +658,7 @@ }, { "cell_type": "code", - "execution_count": 40, + "execution_count": 9, "metadata": { "ExecuteTime": { "end_time": "2023-08-24T07:01:54.496249166Z", @@ -649,16 +674,21 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch: 0 loss: 3.5354 Train_acc: 0.0521\n", - "Epoch: 1 loss: 3.1654 Train_acc: 0.0688\n", - "Epoch: 2 loss: 2.9049 Train_acc: 0.1229\n", - "Epoch: 3 loss: 2.6443 Train_acc: 0.1917\n", - "Epoch: 4 loss: 2.3331 Train_acc: 0.2604\n" + "Epoch: 0 loss: 3.6020 Train_acc: 0.0333\n", + "Test_acc: 0.0917\n", + "Epoch: 1 loss: 3.2161 Train_acc: 0.0750\n", + "Test_acc: 0.1333\n", + "Epoch: 2 loss: 2.9366 Train_acc: 0.1437\n", + "Test_acc: 0.1583\n", + "Epoch: 3 loss: 2.6148 Train_acc: 0.2167\n", + "Test_acc: 0.2500\n", + "Epoch: 4 loss: 2.3257 Train_acc: 0.2875\n", + "Test_acc: 0.2750\n" ] } ], "source": [ - "trainer.train(num_epochs=4)" + "trainer.train(num_epochs=5, test_interval=1)" ] }, { @@ -670,7 +700,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": { "ExecuteTime": { "end_time": "2023-08-24T07:13:58.198454432Z", @@ -681,35 +711,9 @@ "outputs_hidden": false } }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Epoch: 0 loss: 2.0427 Train_acc: 0.3438\n", - "Epoch: 1 loss: 1.7749 Train_acc: 0.4167\n", - "Epoch: 2 loss: 1.5524 Train_acc: 0.4958\n", - "Epoch: 3 loss: 1.4013 Train_acc: 0.5333\n", - "Epoch: 4 loss: 1.2587 Train_acc: 0.6042\n", - "Epoch: 5 loss: 1.1615 Train_acc: 0.6208\n", - "Epoch: 6 loss: 1.0356 Train_acc: 0.6292\n", - "Epoch: 7 loss: 1.0127 Train_acc: 0.6604\n", - "Epoch: 8 loss: 0.9019 Train_acc: 0.6937\n", - "Epoch: 9 loss: 0.8633 Train_acc: 0.7083\n", - "Test_acc: 0.6750\n", - "Epoch: 10 loss: 0.7822 Train_acc: 0.7354\n", - "Epoch: 11 loss: 0.7564 Train_acc: 0.7479\n", - "Epoch: 12 loss: 0.7253 Train_acc: 0.7500\n", - "Epoch: 13 loss: 0.6240 Train_acc: 0.8063\n", - "Epoch: 14 loss: 0.6154 Train_acc: 0.7979\n", - "Epoch: 15 loss: 0.6222 Train_acc: 0.8021\n", - "Epoch: 16 loss: 0.5450 Train_acc: 0.8042\n", - "Epoch: 17 loss: 0.5201 Train_acc: 0.8396\n" - ] - } - ], + "outputs": [], "source": [ - "# trainer.train(num_epochs=5, test_interval=10)" + "#trainer.train(num_epochs=30, test_interval=10)" ] } ], From 697fcfb67797bf4f42e76a8e2bd982271fd9678c Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Mon, 6 Nov 2023 17:50:58 +0000 Subject: [PATCH 12/39] checked hp/ccs --- test/nn/cell/test_can.py | 2 +- test/nn/cell/test_ccxn.py | 2 +- test/nn/cell/test_cwn.py | 2 +- test/nn/combinatorial/test_hmc.py | 6 +++++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/test/nn/cell/test_can.py b/test/nn/cell/test_can.py index 1d2f56922..c4c19eb02 100644 --- a/test/nn/cell/test_can.py +++ b/test/nn/cell/test_can.py @@ -21,7 +21,7 @@ def test_forward(self): num_classes=1, n_layers=2, att_lift=False, - ) + ).to(device) x_0 = torch.rand(2, 2) x_1 = torch.rand(2, 2) diff --git a/test/nn/cell/test_ccxn.py b/test/nn/cell/test_ccxn.py index 43ccc18a4..a2fc4d920 100644 --- a/test/nn/cell/test_ccxn.py +++ b/test/nn/cell/test_ccxn.py @@ -18,7 +18,7 @@ def test_forward(self): num_classes=1, n_layers=2, att=False, - ) + ).to(device) x_0 = torch.rand(2, 2) x_1 = torch.rand(2, 2) diff --git a/test/nn/cell/test_cwn.py b/test/nn/cell/test_cwn.py index 6597c0b00..e7e4f3abf 100644 --- a/test/nn/cell/test_cwn.py +++ b/test/nn/cell/test_cwn.py @@ -18,7 +18,7 @@ def test_forward(self): hid_channels=16, num_classes=1, n_layers=2, - ) + ).to(device) x_0 = torch.rand(2, 2) x_1 = torch.rand(2, 2) diff --git a/test/nn/combinatorial/test_hmc.py b/test/nn/combinatorial/test_hmc.py index d423930e1..e43d35145 100644 --- a/test/nn/combinatorial/test_hmc.py +++ b/test/nn/combinatorial/test_hmc.py @@ -15,7 +15,11 @@ def test_forward(self): intermediate_channels = [2, 2, 2] final_channels = [2, 2, 2] channels_per_layer = [[in_channels, intermediate_channels, final_channels]] - model = HMC(channels_per_layer, negative_slope=0.2, num_classes=2) + model = HMC( + channels_per_layer, + negative_slope=0.2, + num_classes=2 + ).to(device) x_0 = torch.rand(2, 2) x_1 = torch.rand(2, 2) From a9856bd39c9173c499d0774d226f010ec4d2f035 Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Mon, 6 Nov 2023 17:56:34 +0000 Subject: [PATCH 13/39] no docker --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 4ae7bb540..ccec3489a 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,6 @@ topomodelx/base/debug.ipynb tutorials/hypergraph/citeseer6cls3703.pt.1 tutorials/hypergraph/cora tags + +Dockerfile +docker-compose.yml \ No newline at end of file From e002b535ceefa79a67cd4222a68f15122ae3096e Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Mon, 6 Nov 2023 17:58:14 +0000 Subject: [PATCH 14/39] no docker --- .gitignore | 5 +---- Dockerfile | 16 ---------------- docker-compose.yml | 17 ----------------- 3 files changed, 1 insertion(+), 37 deletions(-) delete mode 100644 Dockerfile delete mode 100644 docker-compose.yml diff --git a/.gitignore b/.gitignore index ccec3489a..ce557fd86 100644 --- a/.gitignore +++ b/.gitignore @@ -23,7 +23,4 @@ topomodelx/nn/cell/attcxn_layer.py topomodelx/base/debug.ipynb tutorials/hypergraph/citeseer6cls3703.pt.1 tutorials/hypergraph/cora -tags - -Dockerfile -docker-compose.yml \ No newline at end of file +tags \ No newline at end of file diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index d3914df1d..000000000 --- a/Dockerfile +++ /dev/null @@ -1,16 +0,0 @@ -FROM python:3.11.3 - -WORKDIR /TopoModelX - -COPY . . - -RUN pip install --upgrade pip - -RUN pip install -e '.[all]' - -RUN pip install torch==2.0.1 --extra-index-url https://download.pytorch.org/whl/cu115 -RUN pip install torch-scatter torch-sparse -f https://data.pyg.org/whl/torch-2.0.1+cu115.html -RUN pip install torch-cluster -f https://data.pyg.org/whl/torch-2.0.0+cu115.html -RUN pip install jupyterlab -RUN pip install notebook -RUN pip install ipykernel \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index db9a5110d..000000000 --- a/docker-compose.yml +++ /dev/null @@ -1,17 +0,0 @@ -version: '3' -services: - myapp: - build: . - image: topomodelx:new - stdin_open: true - tty: true - volumes: - - ${PWD}:/TopoModelX - # deploy: - # resources: - # reservations: - # devices: - # - driver: nvidia - # count: 1 - # capabilities: [gpu] - From 546008a3de634c24eefc16d1390a27556ac582c6 Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Tue, 7 Nov 2023 14:14:10 +0000 Subject: [PATCH 15/39] changed weight to none --- Dockerfile | 16 ++++++++++++++++ docker-compose.yml | 17 +++++++++++++++++ test/nn/simplicial/test_sccnn.py | 2 +- test/nn/simplicial/test_scnn.py | 2 +- tutorials/hypergraph/1.pickle | Bin 0 -> 51582 bytes tutorials/hypergraph/features.pickle | Bin 0 -> 404937 bytes tutorials/hypergraph/hypergraph.pickle | Bin 0 -> 101905 bytes tutorials/hypergraph/labels.pickle | Bin 0 -> 5436 bytes 8 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 Dockerfile create mode 100644 docker-compose.yml create mode 100644 tutorials/hypergraph/1.pickle create mode 100644 tutorials/hypergraph/features.pickle create mode 100644 tutorials/hypergraph/hypergraph.pickle create mode 100644 tutorials/hypergraph/labels.pickle diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..d3914df1d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,16 @@ +FROM python:3.11.3 + +WORKDIR /TopoModelX + +COPY . . + +RUN pip install --upgrade pip + +RUN pip install -e '.[all]' + +RUN pip install torch==2.0.1 --extra-index-url https://download.pytorch.org/whl/cu115 +RUN pip install torch-scatter torch-sparse -f https://data.pyg.org/whl/torch-2.0.1+cu115.html +RUN pip install torch-cluster -f https://data.pyg.org/whl/torch-2.0.0+cu115.html +RUN pip install jupyterlab +RUN pip install notebook +RUN pip install ipykernel \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..db9a5110d --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,17 @@ +version: '3' +services: + myapp: + build: . + image: topomodelx:new + stdin_open: true + tty: true + volumes: + - ${PWD}:/TopoModelX + # deploy: + # resources: + # reservations: + # devices: + # - driver: nvidia + # count: 1 + # capabilities: [gpu] + diff --git a/test/nn/simplicial/test_sccnn.py b/test/nn/simplicial/test_sccnn.py index 3ef35b550..a120b4efc 100644 --- a/test/nn/simplicial/test_sccnn.py +++ b/test/nn/simplicial/test_sccnn.py @@ -43,7 +43,7 @@ def test_forward(self): incidence_1 = simplicial_complex.incidence_matrix(rank=1) incidence_2 = simplicial_complex.incidence_matrix(rank=2) laplacian_0 = simplicial_complex.hodge_laplacian_matrix(rank=0, weight=True) - laplacian_down_1 = simplicial_complex.down_laplacian_matrix(rank=1, weight=True) + laplacian_down_1 = simplicial_complex.down_laplacian_matrix(rank=1) laplacian_up_1 = simplicial_complex.up_laplacian_matrix(rank=1) laplacian_2 = simplicial_complex.hodge_laplacian_matrix(rank=2, weight=True) diff --git a/test/nn/simplicial/test_scnn.py b/test/nn/simplicial/test_scnn.py index c630da4f8..b3b7f784f 100644 --- a/test/nn/simplicial/test_scnn.py +++ b/test/nn/simplicial/test_scnn.py @@ -38,7 +38,7 @@ def test_forward(self): incidence_1 = simplicial_complex.incidence_matrix(rank=1) incidence_2 = simplicial_complex.incidence_matrix(rank=2) laplacian_0 = simplicial_complex.hodge_laplacian_matrix(rank=0, weight=True) - laplacian_down_1 = simplicial_complex.down_laplacian_matrix(rank=1, weight=True) + laplacian_down_1 = simplicial_complex.down_laplacian_matrix(rank=1) laplacian_up_1 = simplicial_complex.up_laplacian_matrix(rank=1) laplacian_2 = simplicial_complex.hodge_laplacian_matrix(rank=2, weight=True) diff --git a/tutorials/hypergraph/1.pickle b/tutorials/hypergraph/1.pickle new file mode 100644 index 0000000000000000000000000000000000000000..06caacce0df239d760b06f1881c6c695ba4f544f GIT binary patch literal 51582 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 T6QqgKBx$lV-wH% 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 kr5yu_W+L-g#B#Qjge}6LS4hs+M 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 literal 0 HcmV?d00001 diff --git a/tutorials/hypergraph/labels.pickle b/tutorials/hypergraph/labels.pickle new file mode 100644 index 0000000000000000000000000000000000000000..d2b96af714770960324be56efe695e985555d329 GIT binary patch literal 5436 zcmY+`+mRbd3`9|K$e{=8gT6Lm?HC*MDL-U{^kvI03{k;;;@y*AxEHUQ^kqulGE6Z$B^~yP&t6H`C8zR~Weavrn=FwiOwzP)|iF%D>&5KRhTElmlrg)vsX8hA* zwYqvSB>3j2A+l)hDi-EWf>qS4xbK%4_qs6NA?m{_8&`JAl9JU_{KfTll{@=tR<>fi zTZpOx^eyi?Zwk_@y66`1FqeNC4a>Xz9)8SX(cTP+Kep+xyv>f+`fUyV%XO z1_`q%5*|-nUG+_jVCZU9#s!c6=zo_Vss9AyReYU)>F`!?RAee2GDS^ zj;Bgj`?wonY(1vbue$NK-Y-(sS-kSBGFJzuH3WD2qxd_Aj#xjw{b5y=JAXvc&t)=Y zja)3VE@D;1&1&_^vfmuPI%zJ8Ry;*njhZdL&UzZk%L+EK*a`Gr$00!O*ABP3thY$T zU345(#IqPI>TN!Fo55f{;>YFEHICw0rCn@jWGyE6L$ONLBGnHp?aO5}T~$kLmvh6q zQz6E64h#O-z?n~q!-~gLOlAE0;-Rm{&U>qJ;%`@oLHqT5-kvmq&YET4zQRna^(j0^ zc38VCJN{`IN;#E1{J0dgsSa$r1Y^C zGIrH&Z=SwoB2(j3WGk+_|1DCY=wW9qlb!guP!S52Ayx@?amCSU5j|&}HaMp7^ep%0 z_+lmce2v)1!&)a%{Ri!Rw$ml#bm`OyvrIzAN_Un~`)oZynX>IPPAU27JR0)SIn9*O zIxoKbp*GujP{r$V8HP~D@EX^Y#jgsrVs_fqm)E>81y>DrSf+%Csib-=)3KO!O}kdi zb%EUZ>!LL4^s8Q-Fwm+^kwZ_vd?++!M3OU~o$2cZD^-bK3fSq*V~<5ywz|HASFD)m zd6C$bTX@A@XHqD|WX@;Y>w==Sf*A~&iXg#(o*#)oH7iu{`mpN-;`f`N?3{ACAW_ zx_EBtq%#Fle*KlUQvmNOyBwjXx0$f3;*~>~Skf%(*cKbQ$g-+(cypgWdRDJ9ljyi=C1FD&&cQ*v}h#fx;bPx@6p&pF_+@T?xKg>3^S8-nM{L7*k&GQb& zJFoKKrJiN8^JXUujbkLgRmjd|Z>2BTos{O&r|PFu8L|)2v&xxc-yUy&Qd@V(+6qP3 zyf RE1lvCYFDbH`QyjG{{yebJRAT3 literal 0 HcmV?d00001 From 19e7db3d531ac206dd25c8d8314c0c43c07c572f Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Tue, 7 Nov 2023 14:14:49 +0000 Subject: [PATCH 16/39] changed weight to none --- Dockerfile | 16 ---------------- docker-compose.yml | 17 ----------------- tutorials/hypergraph/1.pickle | Bin 51582 -> 0 bytes tutorials/hypergraph/features.pickle | Bin 404937 -> 0 bytes tutorials/hypergraph/hypergraph.pickle | Bin 101905 -> 0 bytes tutorials/hypergraph/labels.pickle | Bin 5436 -> 0 bytes 6 files changed, 33 deletions(-) delete mode 100644 Dockerfile delete mode 100644 docker-compose.yml delete mode 100644 tutorials/hypergraph/1.pickle delete mode 100644 tutorials/hypergraph/features.pickle delete mode 100644 tutorials/hypergraph/hypergraph.pickle delete mode 100644 tutorials/hypergraph/labels.pickle diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index d3914df1d..000000000 --- a/Dockerfile +++ /dev/null @@ -1,16 +0,0 @@ -FROM python:3.11.3 - -WORKDIR /TopoModelX - -COPY . . - -RUN pip install --upgrade pip - -RUN pip install -e '.[all]' - -RUN pip install torch==2.0.1 --extra-index-url https://download.pytorch.org/whl/cu115 -RUN pip install torch-scatter torch-sparse -f https://data.pyg.org/whl/torch-2.0.1+cu115.html -RUN pip install torch-cluster -f https://data.pyg.org/whl/torch-2.0.0+cu115.html -RUN pip install jupyterlab -RUN pip install notebook -RUN pip install ipykernel \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index db9a5110d..000000000 --- a/docker-compose.yml +++ /dev/null @@ -1,17 +0,0 @@ -version: '3' -services: - myapp: - build: . - image: topomodelx:new - stdin_open: true - tty: true - volumes: - - ${PWD}:/TopoModelX - # deploy: - # resources: - # reservations: - # devices: - # - driver: nvidia - # count: 1 - # capabilities: [gpu] - diff --git a/tutorials/hypergraph/1.pickle b/tutorials/hypergraph/1.pickle deleted file mode 100644 index 06caacce0df239d760b06f1881c6c695ba4f544f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 51582 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 T6QqgKBx$lV-wH% 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 kr5yu_W+L-g#B#Qjge}6LS4hs+M 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 diff --git a/tutorials/hypergraph/labels.pickle b/tutorials/hypergraph/labels.pickle deleted file mode 100644 index d2b96af714770960324be56efe695e985555d329..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5436 zcmY+`+mRbd3`9|K$e{=8gT6Lm?HC*MDL-U{^kvI03{k;;;@y*AxEHUQ^kqulGE6Z$B^~yP&t6H`C8zR~Weavrn=FwiOwzP)|iF%D>&5KRhTElmlrg)vsX8hA* zwYqvSB>3j2A+l)hDi-EWf>qS4xbK%4_qs6NA?m{_8&`JAl9JU_{KfTll{@=tR<>fi zTZpOx^eyi?Zwk_@y66`1FqeNC4a>Xz9)8SX(cTP+Kep+xyv>f+`fUyV%XO z1_`q%5*|-nUG+_jVCZU9#s!c6=zo_Vss9AyReYU)>F`!?RAee2GDS^ zj;Bgj`?wonY(1vbue$NK-Y-(sS-kSBGFJzuH3WD2qxd_Aj#xjw{b5y=JAXvc&t)=Y zja)3VE@D;1&1&_^vfmuPI%zJ8Ry;*njhZdL&UzZk%L+EK*a`Gr$00!O*ABP3thY$T zU345(#IqPI>TN!Fo55f{;>YFEHICw0rCn@jWGyE6L$ONLBGnHp?aO5}T~$kLmvh6q zQz6E64h#O-z?n~q!-~gLOlAE0;-Rm{&U>qJ;%`@oLHqT5-kvmq&YET4zQRna^(j0^ zc38VCJN{`IN;#E1{J0dgsSa$r1Y^C zGIrH&Z=SwoB2(j3WGk+_|1DCY=wW9qlb!guP!S52Ayx@?amCSU5j|&}HaMp7^ep%0 z_+lmce2v)1!&)a%{Ri!Rw$ml#bm`OyvrIzAN_Un~`)oZynX>IPPAU27JR0)SIn9*O zIxoKbp*GujP{r$V8HP~D@EX^Y#jgsrVs_fqm)E>81y>DrSf+%Csib-=)3KO!O}kdi zb%EUZ>!LL4^s8Q-Fwm+^kwZ_vd?++!M3OU~o$2cZD^-bK3fSq*V~<5ywz|HASFD)m zd6C$bTX@A@XHqD|WX@;Y>w==Sf*A~&iXg#(o*#)oH7iu{`mpN-;`f`N?3{ACAW_ zx_EBtq%#Fle*KlUQvmNOyBwjXx0$f3;*~>~Skf%(*cKbQ$g-+(cypgWdRDJ9ljyi=C1FD&&cQ*v}h#fx;bPx@6p&pF_+@T?xKg>3^S8-nM{L7*k&GQb& zJFoKKrJiN8^JXUujbkLgRmjd|Z>2BTos{O&r|PFu8L|)2v&xxc-yUy&Qd@V(+6qP3 zyf RE1lvCYFDbH`QyjG{{yebJRAT3 From 8d2273a4bf35873e72c53d68602eae5367a3946e Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Tue, 7 Nov 2023 14:30:11 +0000 Subject: [PATCH 17/39] checking issue with dataset --- tutorials/hypergraph/Cora/raw/ind.cora.allx | Bin 0 -> 257305 bytes tutorials/hypergraph/Cora/raw/ind.cora.ally | Bin 0 -> 47959 bytes tutorials/hypergraph/Cora/raw/ind.cora.graph | Bin 0 -> 59847 bytes .../hypergraph/Cora/raw/ind.cora.test.index | 1000 +++++++++++++++++ tutorials/hypergraph/Cora/raw/ind.cora.tx | Bin 0 -> 148025 bytes tutorials/hypergraph/Cora/raw/ind.cora.ty | Bin 0 -> 28135 bytes tutorials/hypergraph/Cora/raw/ind.cora.x | Bin 0 -> 22119 bytes tutorials/hypergraph/Cora/raw/ind.cora.y | Bin 0 -> 4054 bytes tutorials/hypergraph/allset_train.ipynb | 16 +- .../hypergraph/allset_transformer_train.ipynb | 2 +- tutorials/hypergraph/hmpnn_train.ipynb | 2 +- tutorials/hypergraph/hnhn_train.ipynb | 2 +- tutorials/hypergraph/hypersage_train.ipynb | 2 +- tutorials/hypergraph/unigcnii_train.ipynb | 2 +- tutorials/hypergraph/unisage_train.ipynb | 2 +- 15 files changed, 1019 insertions(+), 9 deletions(-) create mode 100644 tutorials/hypergraph/Cora/raw/ind.cora.allx create mode 100644 tutorials/hypergraph/Cora/raw/ind.cora.ally create mode 100644 tutorials/hypergraph/Cora/raw/ind.cora.graph create mode 100644 tutorials/hypergraph/Cora/raw/ind.cora.test.index create mode 100644 tutorials/hypergraph/Cora/raw/ind.cora.tx create mode 100644 tutorials/hypergraph/Cora/raw/ind.cora.ty create mode 100644 tutorials/hypergraph/Cora/raw/ind.cora.x create mode 100644 tutorials/hypergraph/Cora/raw/ind.cora.y diff --git a/tutorials/hypergraph/Cora/raw/ind.cora.allx b/tutorials/hypergraph/Cora/raw/ind.cora.allx new file mode 100644 index 0000000000000000000000000000000000000000..44d53b1fece343538e45592caac521d73c6f98d6 GIT binary patch literal 257305 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 z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#jHhhXxMY_waq6 G`Tqf}DSCbY literal 0 HcmV?d00001 diff --git a/tutorials/hypergraph/Cora/raw/ind.cora.ally b/tutorials/hypergraph/Cora/raw/ind.cora.ally new file mode 100644 index 0000000000000000000000000000000000000000..04fbd0b083d09341fcf16b395c642329637f0542 GIT binary patch literal 47959 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 My~lCyzWDTi0g%o(9smFU literal 0 HcmV?d00001 diff --git a/tutorials/hypergraph/Cora/raw/ind.cora.graph b/tutorials/hypergraph/Cora/raw/ind.cora.graph new file mode 100644 index 0000000000000000000000000000000000000000..4d3bf85dfc8b1c105a2c995597a1b3eed6947925 GIT binary patch literal 59847 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 A!vFvP literal 0 HcmV?d00001 diff --git a/tutorials/hypergraph/Cora/raw/ind.cora.test.index b/tutorials/hypergraph/Cora/raw/ind.cora.test.index new file mode 100644 index 000000000..ded8092db --- /dev/null +++ b/tutorials/hypergraph/Cora/raw/ind.cora.test.index @@ -0,0 +1,1000 @@ +2692 +2532 +2050 +1715 +2362 +2609 +2622 +1975 +2081 +1767 +2263 +1725 +2588 +2259 +2357 +1998 +2574 +2179 +2291 +2382 +1812 +1751 +2422 +1937 +2631 +2510 +2378 +2589 +2345 +1943 +1850 +2298 +1825 +2035 +2507 +2313 +1906 +1797 +2023 +2159 +2495 +1886 +2122 +2369 +2461 +1925 +2565 +1858 +2234 +2000 +1846 +2318 +1723 +2559 +2258 +1763 +1991 +1922 +2003 +2662 +2250 +2064 +2529 +1888 +2499 +2454 +2320 +2287 +2203 +2018 +2002 +2632 +2554 +2314 +2537 +1760 +2088 +2086 +2218 +2605 +1953 +2403 +1920 +2015 +2335 +2535 +1837 +2009 +1905 +2636 +1942 +2193 +2576 +2373 +1873 +2463 +2509 +1954 +2656 +2455 +2494 +2295 +2114 +2561 +2176 +2275 +2635 +2442 +2704 +2127 +2085 +2214 +2487 +1739 +2543 +1783 +2485 +2262 +2472 +2326 +1738 +2170 +2100 +2384 +2152 +2647 +2693 +2376 +1775 +1726 +2476 +2195 +1773 +1793 +2194 +2581 +1854 +2524 +1945 +1781 +1987 +2599 +1744 +2225 +2300 +1928 +2042 +2202 +1958 +1816 +1916 +2679 +2190 +1733 +2034 +2643 +2177 +1883 +1917 +1996 +2491 +2268 +2231 +2471 +1919 +1909 +2012 +2522 +1865 +2466 +2469 +2087 +2584 +2563 +1924 +2143 +1736 +1966 +2533 +2490 +2630 +1973 +2568 +1978 +2664 +2633 +2312 +2178 +1754 +2307 +2480 +1960 +1742 +1962 +2160 +2070 +2553 +2433 +1768 +2659 +2379 +2271 +1776 +2153 +1877 +2027 +2028 +2155 +2196 +2483 +2026 +2158 +2407 +1821 +2131 +2676 +2277 +2489 +2424 +1963 +1808 +1859 +2597 +2548 +2368 +1817 +2405 +2413 +2603 +2350 +2118 +2329 +1969 +2577 +2475 +2467 +2425 +1769 +2092 +2044 +2586 +2608 +1983 +2109 +2649 +1964 +2144 +1902 +2411 +2508 +2360 +1721 +2005 +2014 +2308 +2646 +1949 +1830 +2212 +2596 +1832 +1735 +1866 +2695 +1941 +2546 +2498 +2686 +2665 +1784 +2613 +1970 +2021 +2211 +2516 +2185 +2479 +2699 +2150 +1990 +2063 +2075 +1979 +2094 +1787 +2571 +2690 +1926 +2341 +2566 +1957 +1709 +1955 +2570 +2387 +1811 +2025 +2447 +2696 +2052 +2366 +1857 +2273 +2245 +2672 +2133 +2421 +1929 +2125 +2319 +2641 +2167 +2418 +1765 +1761 +1828 +2188 +1972 +1997 +2419 +2289 +2296 +2587 +2051 +2440 +2053 +2191 +1923 +2164 +1861 +2339 +2333 +2523 +2670 +2121 +1921 +1724 +2253 +2374 +1940 +2545 +2301 +2244 +2156 +1849 +2551 +2011 +2279 +2572 +1757 +2400 +2569 +2072 +2526 +2173 +2069 +2036 +1819 +1734 +1880 +2137 +2408 +2226 +2604 +1771 +2698 +2187 +2060 +1756 +2201 +2066 +2439 +1844 +1772 +2383 +2398 +1708 +1992 +1959 +1794 +2426 +2702 +2444 +1944 +1829 +2660 +2497 +2607 +2343 +1730 +2624 +1790 +1935 +1967 +2401 +2255 +2355 +2348 +1931 +2183 +2161 +2701 +1948 +2501 +2192 +2404 +2209 +2331 +1810 +2363 +2334 +1887 +2393 +2557 +1719 +1732 +1986 +2037 +2056 +1867 +2126 +1932 +2117 +1807 +1801 +1743 +2041 +1843 +2388 +2221 +1833 +2677 +1778 +2661 +2306 +2394 +2106 +2430 +2371 +2606 +2353 +2269 +2317 +2645 +2372 +2550 +2043 +1968 +2165 +2310 +1985 +2446 +1982 +2377 +2207 +1818 +1913 +1766 +1722 +1894 +2020 +1881 +2621 +2409 +2261 +2458 +2096 +1712 +2594 +2293 +2048 +2359 +1839 +2392 +2254 +1911 +2101 +2367 +1889 +1753 +2555 +2246 +2264 +2010 +2336 +2651 +2017 +2140 +1842 +2019 +1890 +2525 +2134 +2492 +2652 +2040 +2145 +2575 +2166 +1999 +2434 +1711 +2276 +2450 +2389 +2669 +2595 +1814 +2039 +2502 +1896 +2168 +2344 +2637 +2031 +1977 +2380 +1936 +2047 +2460 +2102 +1745 +2650 +2046 +2514 +1980 +2352 +2113 +1713 +2058 +2558 +1718 +1864 +1876 +2338 +1879 +1891 +2186 +2451 +2181 +2638 +2644 +2103 +2591 +2266 +2468 +1869 +2582 +2674 +2361 +2462 +1748 +2215 +2615 +2236 +2248 +2493 +2342 +2449 +2274 +1824 +1852 +1870 +2441 +2356 +1835 +2694 +2602 +2685 +1893 +2544 +2536 +1994 +1853 +1838 +1786 +1930 +2539 +1892 +2265 +2618 +2486 +2583 +2061 +1796 +1806 +2084 +1933 +2095 +2136 +2078 +1884 +2438 +2286 +2138 +1750 +2184 +1799 +2278 +2410 +2642 +2435 +1956 +2399 +1774 +2129 +1898 +1823 +1938 +2299 +1862 +2420 +2673 +1984 +2204 +1717 +2074 +2213 +2436 +2297 +2592 +2667 +2703 +2511 +1779 +1782 +2625 +2365 +2315 +2381 +1788 +1714 +2302 +1927 +2325 +2506 +2169 +2328 +2629 +2128 +2655 +2282 +2073 +2395 +2247 +2521 +2260 +1868 +1988 +2324 +2705 +2541 +1731 +2681 +2707 +2465 +1785 +2149 +2045 +2505 +2611 +2217 +2180 +1904 +2453 +2484 +1871 +2309 +2349 +2482 +2004 +1965 +2406 +2162 +1805 +2654 +2007 +1947 +1981 +2112 +2141 +1720 +1758 +2080 +2330 +2030 +2432 +2089 +2547 +1820 +1815 +2675 +1840 +2658 +2370 +2251 +1908 +2029 +2068 +2513 +2549 +2267 +2580 +2327 +2351 +2111 +2022 +2321 +2614 +2252 +2104 +1822 +2552 +2243 +1798 +2396 +2663 +2564 +2148 +2562 +2684 +2001 +2151 +2706 +2240 +2474 +2303 +2634 +2680 +2055 +2090 +2503 +2347 +2402 +2238 +1950 +2054 +2016 +1872 +2233 +1710 +2032 +2540 +2628 +1795 +2616 +1903 +2531 +2567 +1946 +1897 +2222 +2227 +2627 +1856 +2464 +2241 +2481 +2130 +2311 +2083 +2223 +2284 +2235 +2097 +1752 +2515 +2527 +2385 +2189 +2283 +2182 +2079 +2375 +2174 +2437 +1993 +2517 +2443 +2224 +2648 +2171 +2290 +2542 +2038 +1855 +1831 +1759 +1848 +2445 +1827 +2429 +2205 +2598 +2657 +1728 +2065 +1918 +2427 +2573 +2620 +2292 +1777 +2008 +1875 +2288 +2256 +2033 +2470 +2585 +2610 +2082 +2230 +1915 +1847 +2337 +2512 +2386 +2006 +2653 +2346 +1951 +2110 +2639 +2520 +1939 +2683 +2139 +2220 +1910 +2237 +1900 +1836 +2197 +1716 +1860 +2077 +2519 +2538 +2323 +1914 +1971 +1845 +2132 +1802 +1907 +2640 +2496 +2281 +2198 +2416 +2285 +1755 +2431 +2071 +2249 +2123 +1727 +2459 +2304 +2199 +1791 +1809 +1780 +2210 +2417 +1874 +1878 +2116 +1961 +1863 +2579 +2477 +2228 +2332 +2578 +2457 +2024 +1934 +2316 +1841 +1764 +1737 +2322 +2239 +2294 +1729 +2488 +1974 +2473 +2098 +2612 +1834 +2340 +2423 +2175 +2280 +2617 +2208 +2560 +1741 +2600 +2059 +1747 +2242 +2700 +2232 +2057 +2147 +2682 +1792 +1826 +2120 +1895 +2364 +2163 +1851 +2391 +2414 +2452 +1803 +1989 +2623 +2200 +2528 +2415 +1804 +2146 +2619 +2687 +1762 +2172 +2270 +2678 +2593 +2448 +1882 +2257 +2500 +1899 +2478 +2412 +2107 +1746 +2428 +2115 +1800 +1901 +2397 +2530 +1912 +2108 +2206 +2091 +1740 +2219 +1976 +2099 +2142 +2671 +2668 +2216 +2272 +2229 +2666 +2456 +2534 +2697 +2688 +2062 +2691 +2689 +2154 +2590 +2626 +2390 +1813 +2067 +1952 +2518 +2358 +1789 +2076 +2049 +2119 +2013 +2124 +2556 +2105 +2093 +1885 +2305 +2354 +2135 +2601 +1770 +1995 +2504 +1749 +2157 diff --git a/tutorials/hypergraph/Cora/raw/ind.cora.tx b/tutorials/hypergraph/Cora/raw/ind.cora.tx new file mode 100644 index 0000000000000000000000000000000000000000..6e856d777401ee15dc8619db76c97d0a40ba2d60 GIT binary patch literal 148025 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 diff --git a/tutorials/hypergraph/Cora/raw/ind.cora.x b/tutorials/hypergraph/Cora/raw/ind.cora.x deleted file mode 100644 index c4a91d008245403e7f26aa616b437191509793c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22119 zcmeI2hnrT_oyT9=00Ssx(I6!ds!1qP1O!*9L53zU6a{9d(aSWHL4gt8p{SHlL_k<9 zh(ysSj|Cxuzy_6o2*|3qf{GF)paBy?k>vB4yl0nvp56c8`uK5PXYTplbAJ8anWEB} z`I+N#3R~por03;lx5&)TONO*b=>>V?rX}Z=y7{5p(lc_)G)qkyJtdFt=9Wz@!v(2H zY58N*bFy>Gr99eqRk^vTN#iDG(~45{8RFulvqK=g28P|$4dUG$baiY8|Vf1z!)fmd9Vi7 z!AtNi?1wMl5>zV{i#37v&>8we226zoun3-oZEy%q!3DSo)wq8XxDEP4CKSSA*a+L< z2%LtiP@_yN))3l53Jib@D1>G33~Ytp!4dcv&cao=v1}|>2UJ(S1U z4WI*bhv6_0X2D9>413@xoQ1N<+yicbZZH%IGE(cMW#%V>J}qr*dVX5|l)QrMtTdu} zTxNEDZsqx@<-_MHW6O{IpLo5Fco3@y+a29JS3 zIRUnV`#c3|b^v}{VxPOw=*_w}!GvhT4@STYXvFo)AnfS?pTB~0&>f9m!Hwu#fQINy zhflzLHDJB>o(HZs(Az;KwB`EwuoAS5iR&7ZvJ>mN!n(xz=UKZMw1@WfzP%tDTCu(o z>jr{$7z|?|4(GtL{2S{`M$djPYevFZ*1g7>(OjbsR&m{Gcmpm#8}9|->@V{943uSU zYq%9U!%|oV_n~*U_v4x^d_D?ipaJgy5quFU$Hpswdi0WK|x9}DGd zh(mSuTN8|d{h+-{abY|75R7mA_6gKNzbh16bDzt6_C9q$Us!C~pnHbvSMsx+(2@V2 z05hQoEYQD&I^3%fJOUP7@2#B|fpO#6%!^)V+ztBMeDG}M!2s9;X{;**<3z1B@Fsi- z`Y#`z0E_R_@F5t(+EvY`K)aPew=pzL=m$GJ#ywWShv0r^!9jQ(%>$r~_CsSd+-pA= z1rLMz`q?;h--93%ok!s?d=ukcpSE|emQH$bB*@#nt6QhAavvVccHfptOqu? zpMy1F3)r|ax!&`B3Hr%e*cDy#c_1`JrxTn2b4y<>gX8FZ59gsAIxmCGa0ctOomzhZ z&$8=kNsUtuu4s4%Uo@jo_Z%2YqbAbYJRtCTrhB$cL#=86E4*FJX*d(X?K> z$C>apR6^g{x&nTQu1(o|Q&)S2dTk?~h(WVcwa|9I z+PVnhuo&8*^B~yM{seEJq5Z76>bZAgBaX&$aL?vIsNL3=+3-1-Pv3z#HH)?S&Ugy; ze3#GX!CbQDE=laE4c~Ha_L8wM3G8J%U;r8)!{5NY82=7$+OjoT*7jLoZ(0g#z`j-$ z?KWWi>Mt%Y@s%^eKG09=;jiF+^_OS=4D7qcuysXk?dZ9!yLHj>{PrwojJjOk2Y#Pe zH;A?Of^&d5(ULXB>|>ygajDh?&?okvtc0GqIuNYU??4?ir@?$M|E*E_q%XQx;1)Ej zRcd|!>e>&wKruWF9ndrXGa(Ld!C?q~N=0u1SYu8>TXZ*pwctF|K+|}2@79G(*6MSI zctBQ~;1uYudm#8K)GxKo zQ~SC#U@~amOms(sacdoz2Va0a-dxp>&QbdC2e_Vl7`x_^_gD}5PkR_sW5JrJmOc9w z)?R_WtX1PRaJFiP#tL{3tSJY<{xuwy!49xK{sKL1tacpcf^}CL&xZBzF_h*W)?o9Z zH2TKGF0f8IPr2uB!F+b#?l;(@51K>4`c(_9@sNy8ZRnfO^r5X7_Q5Q4j1P0y*xCZ> zX=8h=vtfT2gwDON3kuLNUpK&BFy|J6GoLe)IeR9dI}$DXxSHqTdbHYszVqDnZR_?( zcnE%qUUSwOx7NB^tTC^wB|c+VKNqmp^I4~?A=97;MzYq2*e78(I6vthYn46AbKVcj zK)cyXYM|pea}s*Sr*X3$o&x>hY`6m*&t~2mJ8J4@ZDzgO3P-?t@?t=HPw3r|*Mv;4|Ra??7`N zyb60E*uj|h8N_{C2j2j-jZf`h&1#5N5zK*|VC?7@^{q3Z7CNWe>pCYit+Q(&6)opK z&oCFXwe@B{90X%Q8|icFi9NIk9plHI(gu3KbzJ8@)lnnFru}&=_?*DEOYGo2A3{g} zt7o21L2m6G5&mpdkSjuvyR|QTbp}md+WP1 z!Bp;JU$jQr5A>sf5wz`R)<-p4@}uX_*aZ6UN4OmgW7?Q7U!9E`pwSW3HE)dxeP!Qz z5JFwG9~c*NAOnpjVGkSy_xA}jMbBJb1e?HG;6C-Ed-cpd6L=5zXe^imt@!=}@DZ3N zTfiKg0^0pPw9V)BU>&T*b?#MPu7*Fr0dNj)+K2p%3f?8^X$$Y`rRJs zOn(x}C3LE??k8Ng9NfcNI1gc7vkuhedTU@h7&rT&JnMZ9vJP0EL*H|6`pUj#ZES+R z&zGLnoYj8b$8%l;_jfybvtc9bgkPYcy{!39!%0X+V**_d~}4Ds%}kn8!j_xK~UN6UUa zTs^M$xp@>=f470pp!aj%T3j;{a$p@e=Y{%QjkWs08mzyZIdVYzc%LFz2mcNipcp-8 zaO+U074}=t<+GkWMEe`Z&W@hPd@!c0HASE=jeF++-%Dw8HOyIa%vx(qwSh3-snHG% z`y(GqVyYisA7H(){adik+HscR#7U*?>a5i5E z{{`%e=DIO&P4Ru6`|~--9M%3OKpTd4Grlvq70u7VJ$?kve_neW?9-mX`)XV7ZQUIL zUqN-QT?oeCr|@SO#v0FZ7(Rr*Lly30@3qHgfcCA8mU^KsT3>yq;XFDXotCV#m%Rb* zTl?B8j5j`(yz6m>Sq1v(J@Eaee)oB%F&aJx{tdLlA@JQ_7VLt(U`z~xbTDp1%!OVx z9o^ID*`u^UcNh%jrFH9l&_7+!(%->H?r{gW&rqASug?b71AE{tXnq5}JG9Rq0?%#l z>%h9Luq~ls{c8?tjrA+*hlBlSG#WlrdNKyTxTrXU!BM7NlnqQS6lz= ztNO7a8s@fjE7;~ow5$uhN8bn9SuJh71p1<5Z}ZH?n|3#6orfx*QxU9*Q$f4?eB`@{ zkhkWBu@!7xQgc}UCX7U58W^*6!THnJ|2A<(=b-TH;tb$3qR$`)!1%IXe}>LUFo%qR z>S%--ZG4)mw}8*$FF+CNoKJk`twu{Utks@dpY(~BLw?qQ8+kG8$i{Pq0St`KY1Tqw40*oY&#f2O?Qs*_aEkRe{`*{ zyCDfZb6ETOj1p|@S?m|1!C0t)u0DJf>Z6+nhrrnCgr@Ou1%89(^RN>hLeJXsK9oYk z*w2I&a1ZN7z;y5#?<>#-&Y3rZ{r%^xYYm~_Sih_bpTP+*2Eu!&96non-K%v*e-8JqYY29>S2^2xk0oHu=mK*f4(3=XGzNgbE72Cm z!J2U#R-xrPHS0uIbhJmP!6A-~9e>~CzBi-i{_JBd!C3SeFxbXtKedew_j@Op!_FK& z|L8;evNrb&&d$b&^Ee;>`#sQVK07O!&(=+Qw6l>uv#vR>yWaYH6x^fn6$f+HHP$xw zqR;Kw)<<*o0QkI70G?4BR^|TH!Q61hwa)~<>jP_LS9FX~d%{a-)M8zI(D!q|GpVQV zYog;^I05wgooL2Ee|RQ)f;nvd>fc;g51)du^&jB*)O!;`kEn!}J;GRT0(U?+&?nB| zox$I4JODn!h1|+U*IMYja{}DrosW>Id*Woco;) z+9LEt?cuYOI@2K7V=JG}fwD0?{lK}Z2ZVQ>x3iZ}Pwh#@i?(%7&%tY;&L!y2 z9<3|Ll*GKxw)Q6Ve5QX8+Hjp~Ujg&-b#T4C*7@DIb5E}I-S9b3!{?4*yCn2HuV=N+ zu0{7&H1fcDlnVi1U@Tfai8&E&gwt!_4ej0&uqH*Ia!?$D2z-L6CbB2TUw-$Py zS(`f>x?ks`hu{VlSS4K(ce&d8qI-mSK?!NXkJl55QQ)1Z%#De-w1zIFp=lihF- zj=)Lqxxl*YbISK`$`3^1v9iMq8UNfW0H+ti3b??4@hLIV$v0b13vvYoI;JzFHp*`;eMT!5;X3 z_0;>(jf1tjIl9&rb9EQkTkD`X5N5&}cm{mO)c~}OcJV&(R0|huNNQ#dd%-!FVsl znksNB_&)U7I^P5x-`Q##XZsUitmC7P#XNQ2RnY7NrO`D;%A#ic=HN}raKH*Ru4?)53HQ_E(h z7o_J_{a=5OSuOlQCVwHsZih(Ewq8Nx`Ac}z~2BH{HsZih(Ewq8Nx` eAc}z~2BH{XwA?(mi%HW=y8Nk`m#gZfZ8l|_*XfSRtJ%)2vyi+M>Gb2F z9t=YozQWb}A2MsZ^*paHifnNcl8|nZ%V8K4>FsztzWd&Ozds>qr=O4a*U7<`9$d$V zch@E z_)U4svp6lM=~fqdo-DAyd0FIP(of1uS}a3-x@%pU4q469bo!o^*F3FP)3qK;2akSI zx1_}~F`swxo91!X7){3M)Gr@gSp*gihZ(EXIRt(>RFljjV-`8#-fIAA=S)#=Hf%f$XpPe1+-IJFGwIFa{E z$ar!Zqv`N=UoVygpMKgqnvPlYaiY$r Date: Tue, 7 Nov 2023 14:36:06 +0000 Subject: [PATCH 19/39] checking issue with datat --- tutorials/hypergraph/allset_train.ipynb | 2 +- tutorials/hypergraph/allset_transformer_train.ipynb | 2 +- tutorials/hypergraph/hmpnn_train.ipynb | 2 +- tutorials/hypergraph/hnhn_train.ipynb | 2 +- tutorials/hypergraph/hypersage_train.ipynb | 2 +- tutorials/hypergraph/unigcnii_train.ipynb | 2 +- tutorials/hypergraph/unisage_train.ipynb | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tutorials/hypergraph/allset_train.ipynb b/tutorials/hypergraph/allset_train.ipynb index a6e64bdd3..f4cf29e46 100644 --- a/tutorials/hypergraph/allset_train.ipynb +++ b/tutorials/hypergraph/allset_train.ipynb @@ -140,7 +140,7 @@ ], "source": [ "\n", - "cora = geom_datasets.Planetoid(root=\".\", name=\"Cora\")\n", + "cora = geom_datasets.Planetoid(root=\"tmp/\", name=\"Cora\")\n", "data = cora.data\n", "\n", "x_0s = data.x\n", diff --git a/tutorials/hypergraph/allset_transformer_train.ipynb b/tutorials/hypergraph/allset_transformer_train.ipynb index 4e1e77993..bad88e7c4 100644 --- a/tutorials/hypergraph/allset_transformer_train.ipynb +++ b/tutorials/hypergraph/allset_transformer_train.ipynb @@ -159,7 +159,7 @@ } ], "source": [ - "cora = geom_datasets.Planetoid(root=\".\", name=\"Cora\")\n", + "cora = geom_datasets.Planetoid(root=\"tmp/\", name=\"Cora\")\n", "data = cora.data\n", "\n", "x_0s = data.x\n", diff --git a/tutorials/hypergraph/hmpnn_train.ipynb b/tutorials/hypergraph/hmpnn_train.ipynb index 5c10d3693..168f30597 100644 --- a/tutorials/hypergraph/hmpnn_train.ipynb +++ b/tutorials/hypergraph/hmpnn_train.ipynb @@ -82,7 +82,7 @@ "metadata": {}, "outputs": [], "source": [ - "dataset = geom_datasets.Planetoid(root=\".\", name=\"Cora\")[0]" + "dataset = geom_datasets.Planetoid(root=\"tmp/\", name=\"Cora\")[0]" ] }, { diff --git a/tutorials/hypergraph/hnhn_train.ipynb b/tutorials/hypergraph/hnhn_train.ipynb index 7946e34af..83f5fcff5 100644 --- a/tutorials/hypergraph/hnhn_train.ipynb +++ b/tutorials/hypergraph/hnhn_train.ipynb @@ -129,7 +129,7 @@ ], "source": [ "\n", - "cora = geom_datasets.Planetoid(root=\".\", name=\"Cora\")\n", + "cora = geom_datasets.Planetoid(root=\"tmp/\", name=\"Cora\")\n", "data = cora.data\n", "\n", "x_0s = data.x\n", diff --git a/tutorials/hypergraph/hypersage_train.ipynb b/tutorials/hypergraph/hypersage_train.ipynb index ed1205035..6c64be517 100644 --- a/tutorials/hypergraph/hypersage_train.ipynb +++ b/tutorials/hypergraph/hypersage_train.ipynb @@ -132,7 +132,7 @@ ], "source": [ "\n", - "cora = geom_datasets.Planetoid(root=\".\", name=\"Cora\")\n", + "cora = geom_datasets.Planetoid(root=\"tmp/\", name=\"Cora\")\n", "data = cora.data\n", "\n", "x_0s = data.x\n", diff --git a/tutorials/hypergraph/unigcnii_train.ipynb b/tutorials/hypergraph/unigcnii_train.ipynb index d67f1d80c..f61a72867 100644 --- a/tutorials/hypergraph/unigcnii_train.ipynb +++ b/tutorials/hypergraph/unigcnii_train.ipynb @@ -86,7 +86,7 @@ ], "source": [ "\n", - "cora = geom_datasets.Planetoid(root=\".\", name=\"Cora\")\n", + "cora = geom_datasets.Planetoid(root=\"tmp/\", name=\"Cora\")\n", "data = cora.data\n", "\n", "x_0s = data.x\n", diff --git a/tutorials/hypergraph/unisage_train.ipynb b/tutorials/hypergraph/unisage_train.ipynb index 7dea53d87..f2e1352ce 100644 --- a/tutorials/hypergraph/unisage_train.ipynb +++ b/tutorials/hypergraph/unisage_train.ipynb @@ -74,7 +74,7 @@ } ], "source": [ - "cora = geom_datasets.Planetoid(root=\".\", name=\"Cora\")\n", + "cora = geom_datasets.Planetoid(root=\"tmp/\", name=\"Cora\")\n", "data = cora.data\n", "\n", "x_0s = data.x\n", From aa6ed60b7de5ca450f6745bf90c05f1e963f6444 Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Tue, 7 Nov 2023 15:58:32 +0000 Subject: [PATCH 20/39] lint changes --- test/nn/combinatorial/test_hmc.py | 6 +- test/nn/hypergraph/test_allset.py | 2 +- test/nn/hypergraph/test_allset_layer.py | 3 +- test/nn/hypergraph/test_allset_transformer.py | 2 +- test/nn/hypergraph/test_dhgcn.py | 7 +- test/nn/hypergraph/test_hnhn_layer.py | 3 +- test/nn/hypergraph/test_hypergat.py | 10 +- test/nn/hypergraph/test_hypergat_layer.py | 6 +- test/nn/hypergraph/test_unigcn.py | 5 +- test/nn/hypergraph/test_unigcnii.py | 4 +- test/nn/hypergraph/test_unigcnii_layer.py | 15 +- test/nn/hypergraph/test_unigin.py | 6 +- test/nn/hypergraph/test_unigin_layer.py | 4 +- test/nn/hypergraph/test_unisage.py | 6 +- test/nn/hypergraph/test_unisage_layer.py | 2 +- topomodelx/nn/hypergraph/allset.py | 7 +- topomodelx/nn/hypergraph/allset_layer.py | 4 +- .../nn/hypergraph/allset_transformer.py | 6 +- topomodelx/nn/hypergraph/dhgcn.py | 14 +- topomodelx/nn/hypergraph/dhgcn_layer.py | 2 +- topomodelx/nn/hypergraph/hmpnn.py | 2 +- topomodelx/nn/hypergraph/hnhn.py | 24 +- topomodelx/nn/hypergraph/hnhn_layer.py | 2 +- topomodelx/nn/hypergraph/hypergat.py | 22 +- topomodelx/nn/hypergraph/hypergat_layer.py | 6 +- topomodelx/nn/hypergraph/hypersage.py | 22 +- topomodelx/nn/hypergraph/hypersage_layer.py | 22 +- topomodelx/nn/hypergraph/unigcn.py | 16 +- topomodelx/nn/hypergraph/unigcn_layer.py | 11 +- topomodelx/nn/hypergraph/unigcnii.py | 40 +- topomodelx/nn/hypergraph/unigcnii_layer.py | 11 +- topomodelx/nn/hypergraph/unigin.py | 16 +- topomodelx/nn/hypergraph/unigin_layer.py | 6 +- topomodelx/nn/hypergraph/unisage.py | 23 +- topomodelx/nn/hypergraph/unisage_layer.py | 35 +- tutorials/cell/ccxn_train.ipynb | 14 +- tutorials/cell/cwn_train.ipynb | 5 +- tutorials/combinatorial/hmc_train.ipynb | 2 +- tutorials/hypergraph/allset_train.ipynb | 97 +- .../hypergraph/allset_transformer_train.ipynb | 101 +- tutorials/hypergraph/dhgcn_train.ipynb | 35 +- tutorials/hypergraph/hmpnn_train.ipynb | 52 +- tutorials/hypergraph/hnhn_train.ipynb | 97 +- tutorials/hypergraph/hypergat_train.ipynb | 48 +- tutorials/hypergraph/hypersage_train.ipynb | 102 +- .../hypergraph/tmp/Cora/raw/ind.cora.allx | Bin 0 -> 257305 bytes .../hypergraph/tmp/Cora/raw/ind.cora.ally | Bin 0 -> 47959 bytes .../hypergraph/tmp/Cora/raw/ind.cora.graph | Bin 0 -> 59847 bytes .../tmp/Cora/raw/ind.cora.test.index | 1000 +++++++++++++++++ tutorials/hypergraph/tmp/Cora/raw/ind.cora.tx | Bin 0 -> 148025 bytes tutorials/hypergraph/tmp/Cora/raw/ind.cora.ty | Bin 0 -> 28135 bytes tutorials/hypergraph/tmp/Cora/raw/ind.cora.x | Bin 0 -> 22119 bytes tutorials/hypergraph/tmp/Cora/raw/ind.cora.y | Bin 0 -> 4054 bytes tutorials/hypergraph/unigcn_train.ipynb | 32 +- tutorials/hypergraph/unigcnii_train.ipynb | 81 +- tutorials/hypergraph/unigin_train.ipynb | 41 +- tutorials/hypergraph/unisage_train.ipynb | 89 +- 57 files changed, 1538 insertions(+), 630 deletions(-) create mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.allx create mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.ally create mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.graph create mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.test.index create mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.tx create mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.ty create mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.x create mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.y diff --git a/test/nn/combinatorial/test_hmc.py b/test/nn/combinatorial/test_hmc.py index e43d35145..a4371bc3e 100644 --- a/test/nn/combinatorial/test_hmc.py +++ b/test/nn/combinatorial/test_hmc.py @@ -15,11 +15,7 @@ def test_forward(self): intermediate_channels = [2, 2, 2] final_channels = [2, 2, 2] channels_per_layer = [[in_channels, intermediate_channels, final_channels]] - model = HMC( - channels_per_layer, - negative_slope=0.2, - num_classes=2 - ).to(device) + model = HMC(channels_per_layer, negative_slope=0.2, num_classes=2).to(device) x_0 = torch.rand(2, 2) x_1 = torch.rand(2, 2) diff --git a/test/nn/hypergraph/test_allset.py b/test/nn/hypergraph/test_allset.py index f09d4beea..68ff86f20 100644 --- a/test/nn/hypergraph/test_allset.py +++ b/test/nn/hypergraph/test_allset.py @@ -26,4 +26,4 @@ def test_forward(self): incidence_1 = incidence_1.float().to(device) x_0, _ = model(x_0, incidence_1) - assert x_0.shape==(4, 4) + assert x_0.shape == (4, 4) diff --git a/test/nn/hypergraph/test_allset_layer.py b/test/nn/hypergraph/test_allset_layer.py index 6a783a27a..64a75d6e7 100644 --- a/test/nn/hypergraph/test_allset_layer.py +++ b/test/nn/hypergraph/test_allset_layer.py @@ -31,10 +31,9 @@ def test_forward(self, allset_layer): [[1, 0, 0], [0, 1, 1], [1, 1, 1]], dtype=torch.float32 ).to_sparse() x_0, x_1 = allset_layer.forward(x_0, incidence_1) - + assert x_0.shape == (3, 64) assert x_1.shape == (3, 64) - def test_AllSetBlock(self): """Test the AllSetBlock class. diff --git a/test/nn/hypergraph/test_allset_transformer.py b/test/nn/hypergraph/test_allset_transformer.py index b1c5cb536..a7542ff62 100644 --- a/test/nn/hypergraph/test_allset_transformer.py +++ b/test/nn/hypergraph/test_allset_transformer.py @@ -27,4 +27,4 @@ def test_forward(self): incidence_1 = incidence_1.float().to(device) x_0, _ = model(x_0, incidence_1) - assert x_0.shape == (2,2) + assert x_0.shape == (2, 2) diff --git a/test/nn/hypergraph/test_dhgcn.py b/test/nn/hypergraph/test_dhgcn.py index 35737856f..4a6f7e17d 100644 --- a/test/nn/hypergraph/test_dhgcn.py +++ b/test/nn/hypergraph/test_dhgcn.py @@ -11,11 +11,10 @@ class TestDHGCNL: def test_forward(self): """Test forward method.""" # device = torch.device("cuda" if torch.cuda.is_available() else "cpu") - in_channels, hidden_channels = 8,4 + in_channels, hidden_channels = 8, 4 model = DHGCN( - in_channels=in_channels, - hidden_channels=hidden_channels, - n_layers=2) + in_channels=in_channels, hidden_channels=hidden_channels, n_layers=2 + ) n_nodes = 8 x_0 = torch.rand(n_nodes, in_channels) diff --git a/test/nn/hypergraph/test_hnhn_layer.py b/test/nn/hypergraph/test_hnhn_layer.py index 0ac72444c..4ddb7998b 100644 --- a/test/nn/hypergraph/test_hnhn_layer.py +++ b/test/nn/hypergraph/test_hnhn_layer.py @@ -26,14 +26,13 @@ def template_layer(self): def test_forward(self, template_layer): """Test the forward pass of the HNHN layer.""" n_nodes, n_edges = template_layer.incidence_1.shape - x_0 = torch.randn(n_nodes, self.in_channels) x_0_out, x_1_out = template_layer.forward(x_0) assert x_0_out.shape == (n_nodes, self.hidden_channels) assert x_1_out.shape == (n_edges, self.hidden_channels) - + return def test_compute_normalization_matrices(self, template_layer): diff --git a/test/nn/hypergraph/test_hypergat.py b/test/nn/hypergraph/test_hypergat.py index eae46b018..b6be4312b 100644 --- a/test/nn/hypergraph/test_hypergat.py +++ b/test/nn/hypergraph/test_hypergat.py @@ -12,15 +12,15 @@ class TestHNHN: def test_forward(self): """Test forward method.""" device = torch.device("cuda" if torch.cuda.is_available() else "cpu") - + n_nodes, n_edges = 2, 2 incidence = torch.from_numpy(np.random.rand(n_nodes, n_edges)).to_sparse() incidence = incidence.float().to(device) - + in_channels, hidden_channels = 2, 6 - model = HyperGAT(in_channels=in_channels, - hidden_channels=hidden_channels, - n_layers=2).to(device) + model = HyperGAT( + in_channels=in_channels, hidden_channels=hidden_channels, n_layers=2 + ).to(device) x_0 = torch.rand(2, 2).float().to(device) diff --git a/test/nn/hypergraph/test_hypergat_layer.py b/test/nn/hypergraph/test_hypergat_layer.py index b5b505307..e1a296722 100644 --- a/test/nn/hypergraph/test_hypergat_layer.py +++ b/test/nn/hypergraph/test_hypergat_layer.py @@ -13,11 +13,13 @@ def hypergat_layer(self): """Return a hypergat layer.""" in_channels = 10 self.hidden_channels = 30 - return HyperGATLayer(in_channels=in_channels, hidden_channels=self.hidden_channels) + return HyperGATLayer( + in_channels=in_channels, hidden_channels=self.hidden_channels + ) def test_forward(self, hypergat_layer): """Test the forward pass of the hypergat layer.""" - n_nodes, n_edges = 3, 3 + n_nodes, n_edges = 3, 3 x_0 = torch.randn(n_nodes, 10) incidence_2 = torch.tensor( [[1, 0, 0], [0, 1, 1], [1, 1, 1]], dtype=torch.float32 diff --git a/test/nn/hypergraph/test_unigcn.py b/test/nn/hypergraph/test_unigcn.py index 2f2f8ed9f..479d06a5a 100644 --- a/test/nn/hypergraph/test_unigcn.py +++ b/test/nn/hypergraph/test_unigcn.py @@ -17,14 +17,11 @@ def test_forward(self): incidence = incidence.float().to(device) in_channels, hidden_channels = 2, 10 model = UniGCN( - in_channels=in_channels, - hidden_channels=hidden_channels, - n_layers=2 + in_channels=in_channels, hidden_channels=hidden_channels, n_layers=2 ).to(device) x_0 = torch.rand(n_nodes, in_channels).float().to(device) - x_0, x_1 = model(x_0, incidence) assert x_0.shape == torch.Size([n_nodes, hidden_channels]) diff --git a/test/nn/hypergraph/test_unigcnii.py b/test/nn/hypergraph/test_unigcnii.py index 677337c52..77c5a729a 100644 --- a/test/nn/hypergraph/test_unigcnii.py +++ b/test/nn/hypergraph/test_unigcnii.py @@ -18,9 +18,7 @@ def test_forward(self): incidence = incidence.float().to(device) in_channels, hidden_channels = 2, 10 model = UniGCNII( - in_channels=in_channels, - hidden_channels=hidden_channels, - n_layers=2 + in_channels=in_channels, hidden_channels=hidden_channels, n_layers=2 ).to(device) x_0 = torch.rand(n_nodes, in_channels).float().to(device) diff --git a/test/nn/hypergraph/test_unigcnii_layer.py b/test/nn/hypergraph/test_unigcnii_layer.py index e1d61a36c..1b3fd68e3 100644 --- a/test/nn/hypergraph/test_unigcnii_layer.py +++ b/test/nn/hypergraph/test_unigcnii_layer.py @@ -15,15 +15,11 @@ def unigcnii_layer(self): alpha = 0.1 beta = 0.1 return UniGCNIILayer( - in_channels = in_channels, - hidden_channels = in_channels, - alpha = alpha, - beta = beta + in_channels=in_channels, hidden_channels=in_channels, alpha=alpha, beta=beta ) def test_forward(self, unigcnii_layer): """Test the forward pass.""" - n_nodes, in_channels = 3, 10 x_0 = torch.randn(n_nodes, in_channels) incidence_1 = torch.tensor([[1, 0], [1, 1], [0, 1]], dtype=torch.float32) @@ -37,16 +33,13 @@ def test_forward_with_skip(self): The result should be the same as the skip connection. """ n_nodes, in_channels = 3, 10 - + x_0 = torch.rand(n_nodes, in_channels).float() incidence_1 = torch.tensor([[1, 0], [1, 1], [0, 1]], dtype=torch.float32) - x_skip =torch.rand(n_nodes, in_channels).float() + x_skip = torch.rand(n_nodes, in_channels).float() layer = UniGCNIILayer( - in_channels = in_channels, - hidden_channels = in_channels, - alpha = 1, - beta = 0 + in_channels=in_channels, hidden_channels=in_channels, alpha=1, beta=0 ) x_0, _ = layer(x_0, incidence_1, x_skip) diff --git a/test/nn/hypergraph/test_unigin.py b/test/nn/hypergraph/test_unigin.py index b133008fc..9292e4270 100644 --- a/test/nn/hypergraph/test_unigin.py +++ b/test/nn/hypergraph/test_unigin.py @@ -18,12 +18,10 @@ def test_forward(self): incidence = incidence.float().to(device) in_channels, hidden_channels = 2, 10 model = UniGIN( - in_channels=in_channels, - hidden_channels=hidden_channels, - n_layers=2 + in_channels=in_channels, hidden_channels=hidden_channels, n_layers=2 ).to(device) x_0 = torch.rand(n_nodes, in_channels).float().to(device) x_0, x_1 = model(x_0, incidence) assert x_0.shape == torch.Size([n_nodes, hidden_channels]) - assert x_1.shape == torch.Size([n_edges, hidden_channels]) \ No newline at end of file + assert x_1.shape == torch.Size([n_edges, hidden_channels]) diff --git a/test/nn/hypergraph/test_unigin_layer.py b/test/nn/hypergraph/test_unigin_layer.py index 3eb69c54a..23e93ae5f 100644 --- a/test/nn/hypergraph/test_unigin_layer.py +++ b/test/nn/hypergraph/test_unigin_layer.py @@ -1,7 +1,7 @@ """Test the UniGIN layer.""" +import numpy as np import pytest import torch -import numpy as np from topomodelx.nn.hypergraph.unigin_layer import UniGINLayer @@ -17,7 +17,6 @@ def UniGIN_layer(self): def test_forward(self, UniGIN_layer): """Test the forward pass of the UniGIN layer.""" - n_nodes, n_edges = 2, 3 incidence = torch.from_numpy(np.random.rand(n_nodes, n_edges)).to_sparse() incidence = incidence.float() @@ -26,4 +25,3 @@ def test_forward(self, UniGIN_layer): assert x_0.shape == torch.Size([n_nodes, self.in_channels]) assert x_1.shape == torch.Size([n_edges, self.in_channels]) - diff --git a/test/nn/hypergraph/test_unisage.py b/test/nn/hypergraph/test_unisage.py index 678354760..59ccd8f6f 100644 --- a/test/nn/hypergraph/test_unisage.py +++ b/test/nn/hypergraph/test_unisage.py @@ -18,12 +18,10 @@ def test_forward(self): incidence = incidence.float().to(device) in_channels, hidden_channels = 2, 10 model = UniSAGE( - in_channels=in_channels, - hidden_channels=hidden_channels, - n_layers=2 + in_channels=in_channels, hidden_channels=hidden_channels, n_layers=2 ).to(device) x_0 = torch.rand(n_nodes, in_channels).float().to(device) x_0, x_1 = model(x_0, incidence) assert x_0.shape == torch.Size([n_nodes, hidden_channels]) - assert x_1.shape == torch.Size([n_edges, hidden_channels]) \ No newline at end of file + assert x_1.shape == torch.Size([n_edges, hidden_channels]) diff --git a/test/nn/hypergraph/test_unisage_layer.py b/test/nn/hypergraph/test_unisage_layer.py index 2f79ef828..40c7b31b5 100644 --- a/test/nn/hypergraph/test_unisage_layer.py +++ b/test/nn/hypergraph/test_unisage_layer.py @@ -29,7 +29,7 @@ def test_sum_aggregator(self): incidence = torch.tensor([[1, 1, 0], [1, 1, 1], [0, 1, 1]], dtype=torch.float32) layer = UniSAGELayer(10, 30, e_aggr="sum") x_0, x_1 = layer(x, incidence) - + assert x_0.shape == torch.Size([3, 30]) assert x_1.shape == torch.Size([3, 30]) diff --git a/topomodelx/nn/hypergraph/allset.py b/topomodelx/nn/hypergraph/allset.py index e03c72664..520fe9095 100644 --- a/topomodelx/nn/hypergraph/allset.py +++ b/topomodelx/nn/hypergraph/allset.py @@ -28,7 +28,7 @@ class AllSet(torch.nn.Module): Activation function in the MLP. mlp_norm : bool, default: False Whether to apply input normalization in the MLP. - + References ---------- .. [1] Chien, Pan, Peng and Milenkovic. @@ -74,7 +74,6 @@ def __init__( ) ) self.layers = torch.nn.ModuleList(layers) - def forward(self, x_0, incidence_1): """Forward computation. @@ -93,11 +92,7 @@ def forward(self, x_0, incidence_1): x_1 : torch.Tensor Output hyperedge features. """ - for layer in self.layers: x_0, x_1 = layer(x_0, incidence_1) return (x_0, x_1) - - - diff --git a/topomodelx/nn/hypergraph/allset_layer.py b/topomodelx/nn/hypergraph/allset_layer.py index bb4134760..f05a8e244 100644 --- a/topomodelx/nn/hypergraph/allset_layer.py +++ b/topomodelx/nn/hypergraph/allset_layer.py @@ -6,7 +6,8 @@ class AllSetLayer(nn.Module): - r"""AllSet Layer Module [1]_. + """ + AllSet Layer Module [1]_. A module for AllSet layer in a bipartite graph. @@ -26,6 +27,7 @@ class AllSetLayer(nn.Module): Dropout probability in the MLP. mlp_norm : str or None, optional Type of layer normalization in the MLP. + References ---------- .. [1] Chien, Pan, Peng and Milenkovic. diff --git a/topomodelx/nn/hypergraph/allset_transformer.py b/topomodelx/nn/hypergraph/allset_transformer.py index d0889e6ac..ded6b95a3 100644 --- a/topomodelx/nn/hypergraph/allset_transformer.py +++ b/topomodelx/nn/hypergraph/allset_transformer.py @@ -26,7 +26,7 @@ class AllSetTransformer(torch.nn.Module): Number of layers in the MLP. mlp_dropout: Dropout probability in the MLP. - + References ---------- .. [1] Chien, Pan, Peng and Milenkovic. @@ -69,7 +69,6 @@ def __init__( ) ) self.layers = torch.nn.ModuleList(layers) - def forward(self, x_0, incidence_1): """ @@ -89,6 +88,5 @@ def forward(self, x_0, incidence_1): """ for layer in self.layers: x_0, x_1 = layer(x_0, incidence_1) - + return (x_0, x_1) - \ No newline at end of file diff --git a/topomodelx/nn/hypergraph/dhgcn.py b/topomodelx/nn/hypergraph/dhgcn.py index c8803759b..a81c077e4 100644 --- a/topomodelx/nn/hypergraph/dhgcn.py +++ b/topomodelx/nn/hypergraph/dhgcn.py @@ -18,7 +18,7 @@ class DHGCN(torch.nn.Module): Dimension of the hidden features. n_layer : int, default = 2 Amount of message passing layers. - + References ---------- .. [1] Yin, Feng, Luo, Zhang, Wang, Luo, Chen and Hua. @@ -27,10 +27,10 @@ class DHGCN(torch.nn.Module): """ def __init__( - self, - in_channels, - hidden_channels, - n_layers=1, + self, + in_channels, + hidden_channels, + n_layers=1, ): super().__init__() layers = [] @@ -50,8 +50,6 @@ def __init__( ) ) self.layers = torch.nn.ModuleList(layers) - - def forward(self, x_0): """Forward computation through layers, then global average pooling, then linear layer. @@ -70,5 +68,5 @@ def forward(self, x_0): """ for layer in self.layers: x_0, x_1 = layer(x_0) - + return (x_0, x_1) diff --git a/topomodelx/nn/hypergraph/dhgcn_layer.py b/topomodelx/nn/hypergraph/dhgcn_layer.py index c0de452a0..0f2252072 100644 --- a/topomodelx/nn/hypergraph/dhgcn_layer.py +++ b/topomodelx/nn/hypergraph/dhgcn_layer.py @@ -169,7 +169,7 @@ def get_dynamic_topology(self, x_0_features): """ device = x_0_features.device n_nodes = x_0_features.size(0) - batch = torch.zeros(x_0_features.size(0), dtype=torch.long, device='cpu') + batch = torch.zeros(x_0_features.size(0), dtype=torch.long, device="cpu") local_edge_index = knn_graph( x_0_features.cpu(), k=self.k_neighbours, diff --git a/topomodelx/nn/hypergraph/hmpnn.py b/topomodelx/nn/hypergraph/hmpnn.py index a9d792708..6540a2000 100644 --- a/topomodelx/nn/hypergraph/hmpnn.py +++ b/topomodelx/nn/hypergraph/hmpnn.py @@ -62,7 +62,7 @@ def __init__( for _ in range(n_layers) ] ) - #self.to_categories_linear = torch.nn.Linear(hidden_features[-1], num_classes) + # self.to_categories_linear = torch.nn.Linear(hidden_features[-1], num_classes) def forward(self, x_0, x_1, incidence_1): """Forward computation through layers. diff --git a/topomodelx/nn/hypergraph/hnhn.py b/topomodelx/nn/hypergraph/hnhn.py index 5f151e57b..8d61ac15c 100644 --- a/topomodelx/nn/hypergraph/hnhn.py +++ b/topomodelx/nn/hypergraph/hnhn.py @@ -27,23 +27,17 @@ class HNHN(torch.nn.Module): https://grlplus.github.io/papers/40.pdf """ - def __init__( - self, - in_channels, - hidden_channels, - incidence_1, - n_layers=2 - ): + def __init__(self, in_channels, hidden_channels, incidence_1, n_layers=2): super().__init__() layers = [] layers.append( - HNHNLayer( - in_channels=in_channels, - hidden_channels=hidden_channels, - incidence_1=incidence_1, - ) + HNHNLayer( + in_channels=in_channels, + hidden_channels=hidden_channels, + incidence_1=incidence_1, ) + ) for _ in range(n_layers - 1): layers.append( HNHNLayer( @@ -54,7 +48,6 @@ def __init__( ) self.layers = torch.nn.ModuleList(layers) - def forward(self, x_0): """Forward computation. @@ -73,8 +66,7 @@ def forward(self, x_0): x_1 : torch.Tensor Output hyperedge features. """ - for layer in self.layers: x_0, x_1 = layer(x_0) - - return x_0, x_1 \ No newline at end of file + + return x_0, x_1 diff --git a/topomodelx/nn/hypergraph/hnhn_layer.py b/topomodelx/nn/hypergraph/hnhn_layer.py index 76f9af5dc..7b162ca05 100644 --- a/topomodelx/nn/hypergraph/hnhn_layer.py +++ b/topomodelx/nn/hypergraph/hnhn_layer.py @@ -77,7 +77,7 @@ def __init__( self.use_normalized_incidence = use_normalized_incidence self.incidence_1 = incidence_1 self.incidence_1_transpose = incidence_1.transpose(1, 0) - + self.conv_0_to_1 = Conv( in_channels=in_channels, out_channels=hidden_channels, diff --git a/topomodelx/nn/hypergraph/hypergat.py b/topomodelx/nn/hypergraph/hypergat.py index 3c5a2a84c..e0b984ef3 100644 --- a/topomodelx/nn/hypergraph/hypergat.py +++ b/topomodelx/nn/hypergraph/hypergat.py @@ -25,17 +25,21 @@ class HyperGAT(torch.nn.Module): """ def __init__( - self, - in_channels, - hidden_channels, - n_layers=2, - ): + self, + in_channels, + hidden_channels, + n_layers=2, + ): super().__init__() layers = [] - layers.append(HyperGATLayer(in_channels=in_channels, hidden_channels=hidden_channels)) + layers.append( + HyperGATLayer(in_channels=in_channels, hidden_channels=hidden_channels) + ) for _ in range(1, n_layers): layers.append( - HyperGATLayer(in_channels=hidden_channels, hidden_channels=hidden_channels) + HyperGATLayer( + in_channels=hidden_channels, hidden_channels=hidden_channels + ) ) self.layers = torch.nn.ModuleList(layers) @@ -58,5 +62,5 @@ def forward(self, x_0, incidence_1): """ for layer in self.layers: x_0, x_1 = layer.forward(x_0, incidence_1) - - return x_0, x_1 \ No newline at end of file + + return x_0, x_1 diff --git a/topomodelx/nn/hypergraph/hypergat_layer.py b/topomodelx/nn/hypergraph/hypergat_layer.py index 42f993a60..e58a27ed4 100644 --- a/topomodelx/nn/hypergraph/hypergat_layer.py +++ b/topomodelx/nn/hypergraph/hypergat_layer.py @@ -52,7 +52,9 @@ def __init__( ) self.att_weight1 = torch.nn.Parameter(torch.zeros(size=(hidden_channels, 1))) - self.att_weight2 = torch.nn.Parameter(torch.zeros(size=(2 * hidden_channels, 1))) + self.att_weight2 = torch.nn.Parameter( + torch.zeros(size=(2 * hidden_channels, 1)) + ) self.reset_parameters() def reset_parameters(self): @@ -204,5 +206,5 @@ def forward(self, x_source, incidence): inter_aggregation_with_attention = incidence_with_attention @ ( messages_on_edges @ self.weight2 ) - + return self.update(inter_aggregation_with_attention), messages_on_edges diff --git a/topomodelx/nn/hypergraph/hypersage.py b/topomodelx/nn/hypergraph/hypersage.py index 13b61c10c..1738af17a 100644 --- a/topomodelx/nn/hypergraph/hypersage.py +++ b/topomodelx/nn/hypergraph/hypersage.py @@ -24,28 +24,22 @@ class HyperSAGE(torch.nn.Module): https://arxiv.org/abs/2010.04558 """ - def __init__( - self, - in_channels, - hidden_channels, - n_layers=2, - **kwargs - ): + def __init__(self, in_channels, hidden_channels, n_layers=2, **kwargs): super().__init__() layers = [] layers.append( - HyperSAGELayer(in_channels=in_channels, out_channels=hidden_channels, **kwargs) + HyperSAGELayer( + in_channels=in_channels, out_channels=hidden_channels, **kwargs + ) ) for _ in range(1, n_layers): layers.append( HyperSAGELayer( - in_channels=hidden_channels, - out_channels=hidden_channels, - **kwargs + in_channels=hidden_channels, out_channels=hidden_channels, **kwargs ) ) self.layers = torch.nn.ModuleList(layers) - + def forward(self, x_0, incidence): """Forward computation through layers, then linear layer, then global max pooling. @@ -63,5 +57,5 @@ def forward(self, x_0, incidence): """ for layer in self.layers: x_0 = layer.forward(x_0, incidence) - - return x_0 \ No newline at end of file + + return x_0 diff --git a/topomodelx/nn/hypergraph/hypersage_layer.py b/topomodelx/nn/hypergraph/hypersage_layer.py index 447e27ae3..74c5b7d25 100644 --- a/topomodelx/nn/hypergraph/hypersage_layer.py +++ b/topomodelx/nn/hypergraph/hypersage_layer.py @@ -185,24 +185,32 @@ def forward(self, x: torch.Tensor, incidence: torch.Tensor): # type: ignore[ove def nodes_per_edge(e): return ( - torch.index_select(input=incidence.to("cpu"), dim=1, index=torch.LongTensor([e])) + torch.index_select( + input=incidence.to("cpu"), dim=1, index=torch.LongTensor([e]) + ) .coalesce() - .indices()[0].to(self.device) + .indices()[0] + .to(self.device) ) def edges_per_node(v): return ( - torch.index_select(input=incidence.to("cpu"), dim=0, index=torch.LongTensor([v])) + torch.index_select( + input=incidence.to("cpu"), dim=0, index=torch.LongTensor([v]) + ) .coalesce() - .indices()[1].to(self.device) + .indices()[1] + .to(self.device) ) messages_per_edges = [ x[nodes_per_edge(e), :] for e in range(incidence.size()[1]) ] - num_of_messages_per_edges = torch.Tensor( - [message.size()[-2] for message in messages_per_edges] - ).reshape(-1, 1).to(self.device) + num_of_messages_per_edges = ( + torch.Tensor([message.size()[-2] for message in messages_per_edges]) + .reshape(-1, 1) + .to(self.device) + ) intra_edge_aggregation = torch.stack( [self.aggregate(message, mode="intra") for message in messages_per_edges] ) diff --git a/topomodelx/nn/hypergraph/unigcn.py b/topomodelx/nn/hypergraph/unigcn.py index 1db8653e8..40d87105f 100644 --- a/topomodelx/nn/hypergraph/unigcn.py +++ b/topomodelx/nn/hypergraph/unigcn.py @@ -25,7 +25,8 @@ class UniGCN(torch.nn.Module): https://arxiv.org/pdf/2105.00956.pdf """ - def __init__(self, + def __init__( + self, in_channels, hidden_channels, n_layers=2, @@ -33,11 +34,11 @@ def __init__(self, super().__init__() layers = [] layers.append( - UniGCNLayer( - in_channels=in_channels, - hidden_channels=hidden_channels, - ) + UniGCNLayer( + in_channels=in_channels, + hidden_channels=hidden_channels, ) + ) for _ in range(n_layers - 1): layers.append( UniGCNLayer( @@ -47,7 +48,6 @@ def __init__(self, ) self.layers = torch.nn.ModuleList(layers) - def forward(self, x_0, incidence_1): """Forward computation through layers, then linear layer, then global max pooling. @@ -68,5 +68,5 @@ def forward(self, x_0, incidence_1): """ for layer in self.layers: x_0, x_1 = layer(x_0, incidence_1) - - return (x_0, x_1) \ No newline at end of file + + return (x_0, x_1) diff --git a/topomodelx/nn/hypergraph/unigcn_layer.py b/topomodelx/nn/hypergraph/unigcn_layer.py index 50d5b944d..0de324290 100644 --- a/topomodelx/nn/hypergraph/unigcn_layer.py +++ b/topomodelx/nn/hypergraph/unigcn_layer.py @@ -36,15 +36,15 @@ class UniGCNLayer(torch.nn.Module): """ def __init__( - self, + self, in_channels, hidden_channels, - aggr_norm: bool = False, - use_bn: bool = False + aggr_norm: bool = False, + use_bn: bool = False, ) -> None: super().__init__() - - with_linear_transform = False if in_channels == hidden_channels else True + + with_linear_transform = False if in_channels == hidden_channels else True self.conv_level1_0_to_1 = Conv( in_channels=in_channels, out_channels=hidden_channels, @@ -112,7 +112,6 @@ def forward(self, x_0, incidence_1): x_1 : torch.Tensor Output hyperedge features. """ - if x_0.shape[-2] != incidence_1.shape[-2]: raise ValueError( f"Mismatch in number of nodes in features and nodes: {x_0.shape[-2]} and {incidence_1.shape[-2]}." diff --git a/topomodelx/nn/hypergraph/unigcnii.py b/topomodelx/nn/hypergraph/unigcnii.py index d47ccca1e..12bbb459d 100644 --- a/topomodelx/nn/hypergraph/unigcnii.py +++ b/topomodelx/nn/hypergraph/unigcnii.py @@ -1,7 +1,9 @@ """UniGCNII class.""" -import torch import math + +import torch + from topomodelx.nn.hypergraph.unigcnii_layer import UniGCNIILayer @@ -34,33 +36,34 @@ class UniGCNII(torch.nn.Module): """ def __init__( - self, - in_channels, - hidden_channels, - n_layers=2, - alpha=0.5, - beta=0.5, - input_drop=0.2, - layer_drop=0.2, - ): + self, + in_channels, + hidden_channels, + n_layers=2, + alpha=0.5, + beta=0.5, + input_drop=0.2, + layer_drop=0.2, + ): super().__init__() layers = [] - + self.input_drop = torch.nn.Dropout(input_drop) self.layer_drop = torch.nn.Dropout(layer_drop) # Define initial linear layer self.linear_init = torch.nn.Linear(in_channels, hidden_channels) - - # Define convolutional layers + + # Define convolutional layers for i in range(n_layers): - beta = math.log(alpha/(i+1)+1) + beta = math.log(alpha / (i + 1) + 1) layers.append( UniGCNIILayer( - in_channels=hidden_channels, + in_channels=hidden_channels, hidden_channels=hidden_channels, alpha=alpha, - beta=beta) + beta=beta, ) + ) self.layers = torch.nn.ModuleList(layers) @@ -82,7 +85,6 @@ def forward(self, x_0, incidence_1): x_1 : torch.Tensor Output hyperedge features. """ - x_0 = self.input_drop(x_0) x_0 = self.linear_init(x_0) x_0 = torch.nn.functional.relu(x_0) @@ -92,5 +94,5 @@ def forward(self, x_0, incidence_1): x_0, x_1 = layer(x_0, incidence_1, x_0_skip) x_0 = self.layer_drop(x_0) x_0 = torch.nn.functional.relu(x_0) - - return (x_0, x_1) \ No newline at end of file + + return (x_0, x_1) diff --git a/topomodelx/nn/hypergraph/unigcnii_layer.py b/topomodelx/nn/hypergraph/unigcnii_layer.py index 8ce895eeb..e13519772 100644 --- a/topomodelx/nn/hypergraph/unigcnii_layer.py +++ b/topomodelx/nn/hypergraph/unigcnii_layer.py @@ -3,7 +3,8 @@ class UniGCNIILayer(torch.nn.Module): - r"""Implementation of the UniGCNII layer [1]_. + r""" + Implementation of the UniGCNII layer [1]_. Parameters ---------- @@ -24,13 +25,7 @@ class UniGCNIILayer(torch.nn.Module): https://arxiv.org/pdf/2105.00956.pdf """ - def __init__( - self, - in_channels, - hidden_channels, - alpha: float, - beta: float - ) -> None: + def __init__(self, in_channels, hidden_channels, alpha: float, beta: float) -> None: super().__init__() self.alpha = alpha diff --git a/topomodelx/nn/hypergraph/unigin.py b/topomodelx/nn/hypergraph/unigin.py index 41344201a..2bf7a43ab 100644 --- a/topomodelx/nn/hypergraph/unigin.py +++ b/topomodelx/nn/hypergraph/unigin.py @@ -20,7 +20,7 @@ class UniGIN(torch.nn.Module): Dropout rate for the input features. layer_drop: float, default=0.2 Dropout rate for the hidden features. - + References ---------- @@ -31,25 +31,23 @@ class UniGIN(torch.nn.Module): """ def __init__( - self, + self, in_channels, hidden_channels, n_layers=2, input_drop=0.2, layer_drop=0.2, - ): super().__init__() layers = [] - + self.input_drop = torch.nn.Dropout(input_drop) self.layer_drop = torch.nn.Dropout(layer_drop) - - # Define initial linear layer + + # Define initial linear layer self.linear_init = torch.nn.Linear(in_channels, hidden_channels) for _ in range(n_layers): - layers.append( UniGINLayer( in_channels=hidden_channels, @@ -57,7 +55,7 @@ def __init__( ) self.layers = torch.nn.ModuleList(layers) - + def forward(self, x_0, incidence_1): """Forward computation through layers, then linear layer, then global max pooling. @@ -82,4 +80,4 @@ def forward(self, x_0, incidence_1): x_0 = self.layer_drop(x_0) x_0 = torch.nn.functional.relu(x_0) - return (x_0, x_1) \ No newline at end of file + return (x_0, x_1) diff --git a/topomodelx/nn/hypergraph/unigin_layer.py b/topomodelx/nn/hypergraph/unigin_layer.py index 68b61fac4..eac6f2c25 100644 --- a/topomodelx/nn/hypergraph/unigin_layer.py +++ b/topomodelx/nn/hypergraph/unigin_layer.py @@ -33,17 +33,17 @@ class UniGINLayer(torch.nn.Module): def __init__( self, in_channels, - eps: float = 0., + eps: float = 0.0, train_eps: bool = False, ) -> None: super().__init__() - + self.initial_eps = eps if train_eps: self.eps = torch.nn.Parameter(torch.Tensor([eps])) else: self.register_buffer("eps", torch.Tensor([eps])) - + self.linear = torch.nn.Linear(in_channels, in_channels) def forward(self, x_0, incidence_1): diff --git a/topomodelx/nn/hypergraph/unisage.py b/topomodelx/nn/hypergraph/unisage.py index 87d6774ee..87ac14815 100644 --- a/topomodelx/nn/hypergraph/unisage.py +++ b/topomodelx/nn/hypergraph/unisage.py @@ -20,7 +20,7 @@ class UniSAGE(torch.nn.Module): Dropout rate for the hidden features. n_layers : int, default = 2 Amount of message passing layers. - + References ---------- .. [1] Huang and Yang. @@ -30,7 +30,7 @@ class UniSAGE(torch.nn.Module): """ def __init__( - self, + self, in_channels, hidden_channels, input_drop=0.2, @@ -41,14 +41,14 @@ def __init__( self.input_drop = torch.nn.Dropout(input_drop) self.layer_drop = torch.nn.Dropout(layer_drop) - + layers = [] layers.append( - UniSAGELayer( - in_channels=in_channels, - hidden_channels=hidden_channels, - ) + UniSAGELayer( + in_channels=in_channels, + hidden_channels=hidden_channels, ) + ) for _ in range(n_layers - 1): layers.append( UniSAGELayer( @@ -57,8 +57,7 @@ def __init__( ) ) self.layers = torch.nn.ModuleList(layers) - - + def forward(self, x_0, incidence_1): """Forward computation through layers, then linear layer, then global max pooling. @@ -77,14 +76,12 @@ def forward(self, x_0, incidence_1): x_1 : torch.Tensor Output hyperedge features. """ - x_0 = self.input_drop(x_0) - + # Iterate over layers for layer in self.layers: x_0, x_1 = layer(x_0, incidence_1) x_0 = self.layer_drop(x_0) x_0 = torch.nn.functional.relu(x_0) - - return (x_0, x_1) + return (x_0, x_1) diff --git a/topomodelx/nn/hypergraph/unisage_layer.py b/topomodelx/nn/hypergraph/unisage_layer.py index db5b8f8be..2fd2054b8 100644 --- a/topomodelx/nn/hypergraph/unisage_layer.py +++ b/topomodelx/nn/hypergraph/unisage_layer.py @@ -3,8 +3,10 @@ from typing import Literal import torch + from topomodelx.base.conv import Conv + class UniSAGELayer(torch.nn.Module): """Layer of UniSAGE proposed in [1]_. @@ -36,7 +38,10 @@ class UniSAGELayer(torch.nn.Module): """ def _validate_aggr(self, aggr): - if aggr not in {"sum", "mean",}: + if aggr not in { + "sum", + "mean", + }: raise ValueError( f"Unsupported aggregator: {aggr}, should be 'sum', 'mean'," ) @@ -45,18 +50,24 @@ def __init__( self, in_channels, hidden_channels, - e_aggr: Literal["sum", "mean",] = "sum", - v_aggr: Literal["sum", "mean",] = "mean", + e_aggr: Literal[ + "sum", + "mean", + ] = "sum", + v_aggr: Literal[ + "sum", + "mean", + ] = "mean", use_bn: bool = False, ) -> None: super().__init__() self.in_channels = in_channels self.hidden_channels = hidden_channels self.bn = torch.nn.BatchNorm1d(hidden_channels) if use_bn else None - + # Initial linear transformation self.linear = torch.nn.Linear(in_channels, hidden_channels) - + # Define the aggregation self.v_aggr = v_aggr self.e_aggr = e_aggr @@ -67,16 +78,16 @@ def __init__( self.vertex2edge = Conv( in_channels=hidden_channels, out_channels=hidden_channels, - aggr_norm=False if self.e_aggr=="sum" else True, - with_linear_transform=False, - ) + aggr_norm=False if self.e_aggr == "sum" else True, + with_linear_transform=False, + ) self.edge2vertex = Conv( in_channels=hidden_channels, out_channels=hidden_channels, - aggr_norm=False if self.v_aggr=="sum" else True, + aggr_norm=False if self.v_aggr == "sum" else True, with_linear_transform=False, - ) + ) def reset_parameters(self) -> None: r"""Reset learnable parameters.""" @@ -133,8 +144,8 @@ def forward(self, x_0, incidence_1): if self.bn is not None: x_0 = self.bn(x_0) - x_1 = self.vertex2edge(x_0, incidence_1.transpose(1, 0)) + x_1 = self.vertex2edge(x_0, incidence_1.transpose(1, 0)) m_1_0 = self.edge2vertex(x_1, incidence_1) x_0 = x_0 + m_1_0 - + return (x_0, x_1) diff --git a/tutorials/cell/ccxn_train.ipynb b/tutorials/cell/ccxn_train.ipynb index 8127a423f..f1f56aea1 100644 --- a/tutorials/cell/ccxn_train.ipynb +++ b/tutorials/cell/ccxn_train.ipynb @@ -386,7 +386,7 @@ " loss.backward()\n", " opt.step()\n", " epoch_loss.append(loss.item())\n", - " \n", + "\n", " if epoch_i % test_interval == 0:\n", " with torch.no_grad():\n", " train_mean_loss = np.mean(epoch_loss)\n", @@ -403,7 +403,10 @@ " ), adjacency_0.float().to(device)\n", " y_hat = model(x_0, x_1, adjacency_0, incidence_2_t)\n", " test_loss = loss_fn(y_hat, y)\n", - " print(f\"Epoch:{epoch_i}, Train Loss: {train_mean_loss:.4f} Test Loss: {test_loss:.4f}\", flush=True)" + " print(\n", + " f\"Epoch:{epoch_i}, Train Loss: {train_mean_loss:.4f} Test Loss: {test_loss:.4f}\",\n", + " flush=True,\n", + " )" ] }, { @@ -500,7 +503,7 @@ " loss.backward()\n", " opt.step()\n", " epoch_loss.append(loss.item())\n", - " \n", + "\n", " if epoch_i % test_interval == 0:\n", " with torch.no_grad():\n", " train_mean_loss = np.mean(epoch_loss)\n", @@ -517,7 +520,10 @@ " ), adjacency_0.float().to(device)\n", " y_hat = model(x_0, x_1, adjacency_0, incidence_2_t)\n", " test_loss = loss_fn(y_hat, y)\n", - " print(f\"Epoch:{epoch_i}, Train Loss: {train_mean_loss:.4f} Test Loss: {test_loss:.4f}\", flush=True)" + " print(\n", + " f\"Epoch:{epoch_i}, Train Loss: {train_mean_loss:.4f} Test Loss: {test_loss:.4f}\",\n", + " flush=True,\n", + " )" ] }, { diff --git a/tutorials/cell/cwn_train.ipynb b/tutorials/cell/cwn_train.ipynb index 3c301936b..67c949ca3 100644 --- a/tutorials/cell/cwn_train.ipynb +++ b/tutorials/cell/cwn_train.ipynb @@ -494,7 +494,10 @@ "\n", " y_hat = model(x_0, x_1, x_2, adjacency_1, incidence_2, incidence_1_t)\n", " test_loss = criterion(y_hat, y)\n", - " print(f\"Epoch:{epoch_i}, Train Loss: {train_mean_loss:.4f} Test Loss: {test_loss:.4f}\", flush=True)" + " print(\n", + " f\"Epoch:{epoch_i}, Train Loss: {train_mean_loss:.4f} Test Loss: {test_loss:.4f}\",\n", + " flush=True,\n", + " )" ] }, { diff --git a/tutorials/combinatorial/hmc_train.ipynb b/tutorials/combinatorial/hmc_train.ipynb index 69c979dba..6b27c6853 100644 --- a/tutorials/combinatorial/hmc_train.ipynb +++ b/tutorials/combinatorial/hmc_train.ipynb @@ -713,7 +713,7 @@ }, "outputs": [], "source": [ - "#trainer.train(num_epochs=30, test_interval=10)" + "# trainer.train(num_epochs=30, test_interval=10)" ] } ], diff --git a/tutorials/hypergraph/allset_train.ipynb b/tutorials/hypergraph/allset_train.ipynb index f4cf29e46..fe52c3440 100644 --- a/tutorials/hypergraph/allset_train.ipynb +++ b/tutorials/hypergraph/allset_train.ipynb @@ -63,7 +63,7 @@ "from topomodelx.nn.hypergraph.allset import AllSet\n", "\n", "torch.manual_seed(0)\n", - "np.random.seed(0)\n" + "np.random.seed(0)" ] }, { @@ -139,7 +139,6 @@ } ], "source": [ - "\n", "cora = geom_datasets.Planetoid(root=\"tmp/\", name=\"Cora\")\n", "data = cora.data\n", "\n", @@ -149,7 +148,7 @@ "\n", "train_mask = data.train_mask\n", "val_mask = data.val_mask\n", - "test_mask = data.test_mask\n" + "test_mask = data.test_mask" ] }, { @@ -195,7 +194,7 @@ " neighborhood = tuple(sorted(neighborhood))\n", " if neighborhood not in unique_hyperedges:\n", " hyperedges.append(list(neighborhood))\n", - " unique_hyperedges.add(neighborhood) " + " unique_hyperedges.add(neighborhood)" ] }, { @@ -226,7 +225,6 @@ } ], "source": [ - "\n", "# Calculate hyperedge statistics.\n", "hyperedge_sizes = [len(he) for he in hyperedges]\n", "min_size = min(hyperedge_sizes)\n", @@ -237,14 +235,14 @@ "num_single_node_hyperedges = sum(np.array(hyperedge_sizes) == 1)\n", "\n", "# Print the hyperedge statistics.\n", - "print(f'Hyperedge statistics: ')\n", - "print('Number of hyperedges without duplicated hyperedges', len(hyperedges))\n", - "print(f'min = {min_size}, ')\n", - "print(f'max = {max_size}, ')\n", - "print(f'mean = {mean_size}, ')\n", - "print(f'median = {median_size}, ')\n", - "print(f'std = {std_size}, ')\n", - "print(f'Number of hyperedges with size equal to one = {num_single_node_hyperedges}')\n" + "print(f\"Hyperedge statistics: \")\n", + "print(\"Number of hyperedges without duplicated hyperedges\", len(hyperedges))\n", + "print(f\"min = {min_size}, \")\n", + "print(f\"max = {max_size}, \")\n", + "print(f\"mean = {mean_size}, \")\n", + "print(f\"median = {median_size}, \")\n", + "print(f\"std = {std_size}, \")\n", + "print(f\"Number of hyperedges with size equal to one = {num_single_node_hyperedges}\")" ] }, { @@ -266,8 +264,8 @@ " for row in neighibourhood:\n", " incidence_1[row, col] = 1\n", "\n", - "assert all(incidence_1.sum(0)>0) == True, \"Some hyperedges are empty\"\n", - "assert all(incidence_1.sum(1)>0) == True, \"Some nodes are not in any hyperedges\"\n", + "assert all(incidence_1.sum(0) > 0) == True, \"Some hyperedges are empty\"\n", + "assert all(incidence_1.sum(1) > 0) == True, \"Some nodes are not in any hyperedges\"\n", "incidence_1 = torch.Tensor(incidence_1).to_sparse_coo()" ] }, @@ -294,7 +292,7 @@ "outputs": [], "source": [ "class Network(torch.nn.Module):\n", - " \"\"\" Network class that initializes the AllSet model and readout layer.\n", + " \"\"\"Network class that initializes the AllSet model and readout layer.\n", "\n", " Base model parameters:\n", " ----------\n", @@ -307,41 +305,34 @@ " Optitional:\n", " **kwargs : dict\n", " Additional arguments for the base model.\n", - " \n", + "\n", " Readout layer parameters:\n", " ----------\n", " out_channels : int\n", " Dimension of the output features.\n", " task_level : str\n", - " Level of the task. Either \"graph\" or \"node\". \n", + " Level of the task. Either \"graph\" or \"node\".\n", " \"\"\"\n", + "\n", " def __init__(\n", - " self, \n", - " in_channels, \n", - " hidden_channels,\n", - " out_channels, \n", - " \n", - " task_level=\"graph\",\n", - " **kwargs):\n", + " self, in_channels, hidden_channels, out_channels, task_level=\"graph\", **kwargs\n", + " ):\n", " super().__init__()\n", - " \n", + "\n", " # Define the model\n", " self.base_model = AllSet(\n", - " in_channels=in_channels,\n", - " hidden_channels=hidden_channels,\n", - " **kwargs\n", + " in_channels=in_channels, hidden_channels=hidden_channels, **kwargs\n", " )\n", "\n", - "\n", " # Readout\n", " self.linear = torch.nn.Linear(hidden_channels, out_channels)\n", " self.out_pool = True if task_level == \"graph\" else False\n", - " \n", + "\n", " def forward(self, x_0, incidence_1):\n", " # Base model\n", " x_0, x_1 = self.base_model(x_0, incidence_1)\n", "\n", - " # Pool over all nodes in the hypergraph \n", + " # Pool over all nodes in the hypergraph\n", " if self.out_pool is True:\n", " x = torch.max(x_0, dim=0)[0]\n", " else:\n", @@ -366,22 +357,22 @@ "# Base model hyperparameters\n", "in_channels = x_0s.shape[1]\n", "hidden_channels = 128\n", - "n_layers=1\n", - "mlp_num_layers=1\n", + "n_layers = 1\n", + "mlp_num_layers = 1\n", "\n", "# Readout hyperparameters\n", "out_channels = torch.unique(y).shape[0]\n", - "task_level = \"graph\" if out_channels==1 else \"node\"\n", + "task_level = \"graph\" if out_channels == 1 else \"node\"\n", "\n", "\n", "model = Network(\n", " in_channels=in_channels,\n", " hidden_channels=hidden_channels,\n", - " out_channels=out_channels, \n", + " out_channels=out_channels,\n", " n_layers=n_layers,\n", " mlp_num_layers=mlp_num_layers,\n", " task_level=task_level,\n", - " ).to(device)" + ").to(device)" ] }, { @@ -434,10 +425,10 @@ "source": [ "x_0s = torch.tensor(x_0s)\n", "x_0s, incidence_1, y = (\n", - " x_0s.float().to(device),\n", - " incidence_1.float().to(device),\n", - " torch.tensor(y, dtype=torch.long).to(device),\n", - " )" + " x_0s.float().to(device),\n", + " incidence_1.float().to(device),\n", + " torch.tensor(y, dtype=torch.long).to(device),\n", + ")" ] }, { @@ -485,17 +476,15 @@ } ], "source": [ - "\n", "test_interval = 5\n", "num_epochs = 30\n", "\n", "epoch_loss = []\n", "for epoch_i in range(1, num_epochs + 1):\n", - " \n", " model.train()\n", "\n", " opt.zero_grad()\n", - " \n", + "\n", " # Extract edge_index from sparse incidence matrix\n", " y_hat = model(x_0s, incidence_1)\n", " loss = loss_fn(y_hat[train_mask], y[train_mask])\n", @@ -504,23 +493,29 @@ " opt.step()\n", " epoch_loss.append(loss.item())\n", "\n", - " \n", - "\n", " if epoch_i % test_interval == 0:\n", - " \n", " model.eval()\n", " y_hat = model(x_0s, incidence_1)\n", "\n", " loss = loss_fn(y_hat[train_mask], y[train_mask])\n", " print(f\"Epoch: {epoch_i} \")\n", - " print(f\"Train_loss: {np.mean(epoch_loss):.4f}, acc: {acc_fn(y_hat[train_mask].argmax(1), y[train_mask]):.4f}\",flush=True)\n", + " print(\n", + " f\"Train_loss: {np.mean(epoch_loss):.4f}, acc: {acc_fn(y_hat[train_mask].argmax(1), y[train_mask]):.4f}\",\n", + " flush=True,\n", + " )\n", "\n", " loss = loss_fn(y_hat[val_mask], y[val_mask])\n", - " \n", - " print(f\"Val_loss: {loss:.4f}, Val_acc: {acc_fn(y_hat[val_mask].argmax(1), y[val_mask]):.4f}\", flush=True)\n", + "\n", + " print(\n", + " f\"Val_loss: {loss:.4f}, Val_acc: {acc_fn(y_hat[val_mask].argmax(1), y[val_mask]):.4f}\",\n", + " flush=True,\n", + " )\n", "\n", " loss = loss_fn(y_hat[test_mask], y[test_mask])\n", - " print(f\"Test_loss: {loss:.4f}, Test_acc: {acc_fn(y_hat[test_mask].argmax(1), y[test_mask]):.4f}\", flush=True)" + " print(\n", + " f\"Test_loss: {loss:.4f}, Test_acc: {acc_fn(y_hat[test_mask].argmax(1), y[test_mask]):.4f}\",\n", + " flush=True,\n", + " )" ] } ], diff --git a/tutorials/hypergraph/allset_transformer_train.ipynb b/tutorials/hypergraph/allset_transformer_train.ipynb index bad88e7c4..70c8c8231 100644 --- a/tutorials/hypergraph/allset_transformer_train.ipynb +++ b/tutorials/hypergraph/allset_transformer_train.ipynb @@ -93,7 +93,7 @@ "from topomodelx.nn.hypergraph.allset_transformer import AllSetTransformer\n", "\n", "torch.manual_seed(0)\n", - "np.random.seed(0)\n" + "np.random.seed(0)" ] }, { @@ -214,7 +214,7 @@ " neighborhood = tuple(sorted(neighborhood))\n", " if neighborhood not in unique_hyperedges:\n", " hyperedges.append(list(neighborhood))\n", - " unique_hyperedges.add(neighborhood) " + " unique_hyperedges.add(neighborhood)" ] }, { @@ -245,7 +245,6 @@ } ], "source": [ - "\n", "# Calculate hyperedge statistics.\n", "hyperedge_sizes = [len(he) for he in hyperedges]\n", "min_size = min(hyperedge_sizes)\n", @@ -256,14 +255,14 @@ "num_single_node_hyperedges = sum(np.array(hyperedge_sizes) == 1)\n", "\n", "# Print the hyperedge statistics.\n", - "print(f'Hyperedge statistics: ')\n", - "print('Number of hyperedges without duplicated hyperedges', len(hyperedges))\n", - "print(f'min = {min_size}, ')\n", - "print(f'max = {max_size}, ')\n", - "print(f'mean = {mean_size}, ')\n", - "print(f'median = {median_size}, ')\n", - "print(f'std = {std_size}, ')\n", - "print(f'Number of hyperedges with size equal to one = {num_single_node_hyperedges}')\n" + "print(f\"Hyperedge statistics: \")\n", + "print(\"Number of hyperedges without duplicated hyperedges\", len(hyperedges))\n", + "print(f\"min = {min_size}, \")\n", + "print(f\"max = {max_size}, \")\n", + "print(f\"mean = {mean_size}, \")\n", + "print(f\"median = {median_size}, \")\n", + "print(f\"std = {std_size}, \")\n", + "print(f\"Number of hyperedges with size equal to one = {num_single_node_hyperedges}\")" ] }, { @@ -285,8 +284,8 @@ " for row in neighibourhood:\n", " incidence_1[row, col] = 1\n", "\n", - "assert all(incidence_1.sum(0)>0) == True, \"Some hyperedges are empty\"\n", - "assert all(incidence_1.sum(1)>0) == True, \"Some nodes are not in any hyperedges\"\n", + "assert all(incidence_1.sum(0) > 0) == True, \"Some hyperedges are empty\"\n", + "assert all(incidence_1.sum(1) > 0) == True, \"Some nodes are not in any hyperedges\"\n", "incidence_1 = torch.Tensor(incidence_1).to_sparse_coo()" ] }, @@ -314,7 +313,7 @@ "outputs": [], "source": [ "class Network(torch.nn.Module):\n", - " \"\"\" Network class that initializes the base model and readout layer.\n", + " \"\"\"Network class that initializes the base model and readout layer.\n", "\n", " Base model parameters:\n", " ----------\n", @@ -327,41 +326,34 @@ " Optitional:\n", " **kwargs : dict\n", " Additional arguments for the base model.\n", - " \n", + "\n", " Readout layer parameters:\n", " ----------\n", " out_channels : int\n", " Dimension of the output features.\n", " task_level : str\n", - " Level of the task. Either \"graph\" or \"node\". \n", + " Level of the task. Either \"graph\" or \"node\".\n", " \"\"\"\n", + "\n", " def __init__(\n", - " self, \n", - " in_channels, \n", - " hidden_channels,\n", - " out_channels, \n", - " \n", - " task_level=\"graph\",\n", - " **kwargs):\n", + " self, in_channels, hidden_channels, out_channels, task_level=\"graph\", **kwargs\n", + " ):\n", " super().__init__()\n", - " \n", + "\n", " # Define the model\n", " self.base_model = AllSetTransformer(\n", - " in_channels=in_channels,\n", - " hidden_channels=hidden_channels,\n", - " **kwargs\n", + " in_channels=in_channels, hidden_channels=hidden_channels, **kwargs\n", " )\n", "\n", - "\n", " # Readout\n", " self.linear = torch.nn.Linear(hidden_channels, out_channels)\n", " self.out_pool = True if task_level == \"graph\" else False\n", - " \n", + "\n", " def forward(self, x_0, incidence_1):\n", " # Base model\n", " x_0, x_1 = self.base_model(x_0, incidence_1)\n", "\n", - " # Pool over all nodes in the hypergraph \n", + " # Pool over all nodes in the hypergraph\n", " if self.out_pool is True:\n", " x = torch.max(x_0, dim=0)[0]\n", " else:\n", @@ -393,18 +385,18 @@ "\n", "# Readout hyperparameters\n", "out_channels = torch.unique(y).shape[0]\n", - "task_level = \"graph\" if out_channels==1 else \"node\"\n", + "task_level = \"graph\" if out_channels == 1 else \"node\"\n", "\n", "\n", "model = Network(\n", - " in_channels=in_channels,\n", - " hidden_channels=hidden_channels,\n", - " out_channels=out_channels,\n", - " heads=heads,\n", - " n_layers=n_layers,\n", - " mlp_num_layers=mlp_num_layers,\n", - " task_level=task_level,\n", - " ).to(device)" + " in_channels=in_channels,\n", + " hidden_channels=hidden_channels,\n", + " out_channels=out_channels,\n", + " heads=heads,\n", + " n_layers=n_layers,\n", + " mlp_num_layers=mlp_num_layers,\n", + " task_level=task_level,\n", + ").to(device)" ] }, { @@ -452,10 +444,10 @@ "source": [ "x_0s = torch.tensor(x_0s)\n", "x_0s, incidence_1, y = (\n", - " x_0s.float().to(device),\n", - " incidence_1.float().to(device),\n", - " torch.tensor(y, dtype=torch.long).to(device),\n", - " )" + " x_0s.float().to(device),\n", + " incidence_1.float().to(device),\n", + " torch.tensor(y, dtype=torch.long).to(device),\n", + ")" ] }, { @@ -514,11 +506,10 @@ "\n", "epoch_loss = []\n", "for epoch_i in range(1, num_epochs + 1):\n", - " \n", " model.train()\n", "\n", " opt.zero_grad()\n", - " \n", + "\n", " # Extract edge_index from sparse incidence matrix\n", " y_hat = model(x_0s, incidence_1)\n", " loss = loss_fn(y_hat[train_mask], y[train_mask])\n", @@ -527,23 +518,29 @@ " opt.step()\n", " epoch_loss.append(loss.item())\n", "\n", - " \n", - "\n", " if epoch_i % test_interval == 0:\n", - " \n", " model.eval()\n", " y_hat = model(x_0s, incidence_1)\n", "\n", " loss = loss_fn(y_hat[train_mask], y[train_mask])\n", " print(f\"Epoch: {epoch_i} \")\n", - " print(f\"Train_loss: {np.mean(epoch_loss):.4f}, acc: {acc_fn(y_hat[train_mask].argmax(1), y[train_mask]):.4f}\",flush=True)\n", + " print(\n", + " f\"Train_loss: {np.mean(epoch_loss):.4f}, acc: {acc_fn(y_hat[train_mask].argmax(1), y[train_mask]):.4f}\",\n", + " flush=True,\n", + " )\n", "\n", " loss = loss_fn(y_hat[val_mask], y[val_mask])\n", - " \n", - " print(f\"Val_loss: {loss:.4f}, Val_acc: {acc_fn(y_hat[val_mask].argmax(1), y[val_mask]):.4f}\", flush=True)\n", + "\n", + " print(\n", + " f\"Val_loss: {loss:.4f}, Val_acc: {acc_fn(y_hat[val_mask].argmax(1), y[val_mask]):.4f}\",\n", + " flush=True,\n", + " )\n", "\n", " loss = loss_fn(y_hat[test_mask], y[test_mask])\n", - " print(f\"Test_loss: {loss:.4f}, Test_acc: {acc_fn(y_hat[test_mask].argmax(1), y[test_mask]):.4f}\", flush=True)" + " print(\n", + " f\"Test_loss: {loss:.4f}, Test_acc: {acc_fn(y_hat[test_mask].argmax(1), y[test_mask]):.4f}\",\n", + " flush=True,\n", + " )" ] } ], diff --git a/tutorials/hypergraph/dhgcn_train.ipynb b/tutorials/hypergraph/dhgcn_train.ipynb index a03751135..1639a0c66 100644 --- a/tutorials/hypergraph/dhgcn_train.ipynb +++ b/tutorials/hypergraph/dhgcn_train.ipynb @@ -249,7 +249,7 @@ "outputs": [], "source": [ "class Network(torch.nn.Module):\n", - " \"\"\" Network class that initializes the base model and readout layer.\n", + " \"\"\"Network class that initializes the base model and readout layer.\n", "\n", " Base model parameters:\n", " ----------\n", @@ -262,41 +262,34 @@ " Optitional:\n", " **kwargs : dict\n", " Additional arguments for the base model.\n", - " \n", + "\n", " Readout layer parameters:\n", " ----------\n", " out_channels : int\n", " Dimension of the output features.\n", " task_level : str\n", - " Level of the task. Either \"graph\" or \"node\". \n", + " Level of the task. Either \"graph\" or \"node\".\n", " \"\"\"\n", + "\n", " def __init__(\n", - " self, \n", - " in_channels, \n", - " hidden_channels,\n", - " out_channels, \n", - " \n", - " task_level=\"graph\",\n", - " **kwargs):\n", + " self, in_channels, hidden_channels, out_channels, task_level=\"graph\", **kwargs\n", + " ):\n", " super().__init__()\n", - " \n", + "\n", " # Define the model\n", " self.base_model = DHGCN(\n", - " in_channels=in_channels,\n", - " hidden_channels=hidden_channels,\n", - " **kwargs\n", + " in_channels=in_channels, hidden_channels=hidden_channels, **kwargs\n", " )\n", "\n", - "\n", " # Readout\n", " self.linear = torch.nn.Linear(hidden_channels, out_channels)\n", " self.out_pool = True if task_level == \"graph\" else False\n", - " \n", + "\n", " def forward(self, x_0):\n", " # Base model\n", " x_0, x_1 = self.base_model(x_0)\n", "\n", - " # Pool over all nodes in the hypergraph \n", + " # Pool over all nodes in the hypergraph\n", " if self.out_pool is True:\n", " x = torch.max(x_0, dim=0)[0]\n", " else:\n", @@ -314,20 +307,20 @@ "# Base model hyperparameters\n", "in_channels = x_0s[0].shape[1]\n", "hidden_channels = 6\n", - "n_layers=2\n", + "n_layers = 2\n", "\n", "# Readout hyperparameters\n", "out_channels = 1\n", - "task_level = \"graph\" if out_channels==1 else \"node\"\n", + "task_level = \"graph\" if out_channels == 1 else \"node\"\n", "\n", "\n", "model = Network(\n", " in_channels=in_channels,\n", " hidden_channels=hidden_channels,\n", - " out_channels=out_channels, \n", + " out_channels=out_channels,\n", " n_layers=n_layers,\n", " task_level=task_level,\n", - " ).to(device)" + ").to(device)" ] }, { diff --git a/tutorials/hypergraph/hmpnn_train.ipynb b/tutorials/hypergraph/hmpnn_train.ipynb index 168f30597..c2a74df66 100644 --- a/tutorials/hypergraph/hmpnn_train.ipynb +++ b/tutorials/hypergraph/hmpnn_train.ipynb @@ -132,7 +132,7 @@ "outputs": [], "source": [ "class Network(torch.nn.Module):\n", - " \"\"\" Network class that initializes the base model and readout layer.\n", + " \"\"\"Network class that initializes the base model and readout layer.\n", "\n", " Base model parameters:\n", " ----------\n", @@ -145,41 +145,34 @@ " Optitional:\n", " **kwargs : dict\n", " Additional arguments for the base model.\n", - " \n", + "\n", " Readout layer parameters:\n", " ----------\n", " out_channels : int\n", " Dimension of the output features.\n", " task_level : str\n", - " Level of the task. Either \"graph\" or \"node\". \n", + " Level of the task. Either \"graph\" or \"node\".\n", " \"\"\"\n", + "\n", " def __init__(\n", - " self, \n", - " in_channels, \n", - " hidden_channels,\n", - " out_channels, \n", - " \n", - " task_level=\"graph\",\n", - " **kwargs):\n", + " self, in_channels, hidden_channels, out_channels, task_level=\"graph\", **kwargs\n", + " ):\n", " super().__init__()\n", - " \n", + "\n", " # Define the model\n", " self.base_model = HMPNN(\n", - " in_channels=in_channels,\n", - " hidden_channels=hidden_channels,\n", - " **kwargs\n", + " in_channels=in_channels, hidden_channels=hidden_channels, **kwargs\n", " )\n", "\n", - "\n", " # Readout\n", " self.linear = torch.nn.Linear(hidden_channels, out_channels)\n", " self.out_pool = True if task_level == \"graph\" else False\n", - " \n", + "\n", " def forward(self, x_0, x_1, incidence_1):\n", " # Base model\n", " x_0, x_1 = self.base_model(x_0, x_1, incidence_1)\n", "\n", - " # Pool over all nodes in the hypergraph \n", + " # Pool over all nodes in the hypergraph\n", " if self.out_pool is True:\n", " x = torch.max(x_0, dim=0)[0]\n", " else:\n", @@ -204,20 +197,20 @@ "# Base model hyperparameters\n", "in_channels = x_0s.shape[1]\n", "hidden_channels = 128\n", - "n_layers=1\n", + "n_layers = 1\n", "\n", "# Readout hyperparameters\n", "out_channels = torch.unique(y).shape[0]\n", - "task_level = \"graph\" if out_channels==1 else \"node\"\n", + "task_level = \"graph\" if out_channels == 1 else \"node\"\n", "\n", "\n", "model = Network(\n", " in_channels=in_channels,\n", " hidden_channels=hidden_channels,\n", - " out_channels=out_channels, \n", + " out_channels=out_channels,\n", " n_layers=n_layers,\n", " task_level=task_level,\n", - " ).to(device)" + ").to(device)" ] }, { @@ -231,17 +224,13 @@ }, "outputs": [], "source": [ - "\n", "optimizer = torch.optim.Adam(model.parameters(), lr=0.01)\n", "loss_fn = torch.nn.CrossEntropyLoss()\n", "\n", "\n", - "\n", "train_mask = dataset[\"train_mask\"]\n", "val_mask = dataset[\"val_mask\"]\n", - "test_mask = dataset[\"test_mask\"]\n", - "\n", - "\n" + "test_mask = dataset[\"test_mask\"]" ] }, { @@ -292,7 +281,7 @@ "source": [ "torch.manual_seed(0)\n", "test_interval = 5\n", - "num_epochs=100\n", + "num_epochs = 100\n", "\n", "\n", "initial_x_1 = torch.zeros_like(x_0s)\n", @@ -307,16 +296,15 @@ " train_loss = loss.item()\n", " y_pred = y_hat.argmax(dim=-1)\n", " train_acc = accuracy_score(y[train_mask].cpu(), y_pred[train_mask].cpu())\n", - " \n", + "\n", " if epoch % test_interval == 0:\n", " model.eval()\n", - " \n", + "\n", " y_hat = model(x_0s, initial_x_1, incidence_1)\n", " val_loss = loss_fn(y_hat[val_mask], y[val_mask]).item()\n", " y_pred = y_hat.argmax(dim=-1)\n", " val_acc = accuracy_score(y[val_mask].cpu(), y_pred[val_mask].cpu())\n", "\n", - "\n", " test_loss = loss_fn(y_hat[test_mask], y[test_mask]).item()\n", " y_pred = y_hat.argmax(dim=-1)\n", " test_acc = accuracy_score(y[test_mask].cpu(), y_pred[test_mask].cpu())\n", @@ -324,9 +312,7 @@ " f\"Epoch: {epoch + 1} train loss: {train_loss:.4f} train acc: {train_acc:.2f} \"\n", " f\" val loss: {val_loss:.4f} val acc: {val_acc:.2f}\"\n", " f\" test loss: {test_acc:.4f} val acc: {test_acc:.2f}\"\n", - " )\n", - "\n", - " \n" + " )" ] }, { diff --git a/tutorials/hypergraph/hnhn_train.ipynb b/tutorials/hypergraph/hnhn_train.ipynb index 83f5fcff5..6db9aef91 100644 --- a/tutorials/hypergraph/hnhn_train.ipynb +++ b/tutorials/hypergraph/hnhn_train.ipynb @@ -62,7 +62,7 @@ "from topomodelx.nn.hypergraph.hnhn import HNHN\n", "\n", "torch.manual_seed(0)\n", - "np.random.seed(0)\n" + "np.random.seed(0)" ] }, { @@ -128,7 +128,6 @@ } ], "source": [ - "\n", "cora = geom_datasets.Planetoid(root=\"tmp/\", name=\"Cora\")\n", "data = cora.data\n", "\n", @@ -138,7 +137,7 @@ "\n", "train_mask = data.train_mask\n", "val_mask = data.val_mask\n", - "test_mask = data.test_mask\n" + "test_mask = data.test_mask" ] }, { @@ -184,7 +183,7 @@ " neighborhood = tuple(sorted(neighborhood))\n", " if neighborhood not in unique_hyperedges:\n", " hyperedges.append(list(neighborhood))\n", - " unique_hyperedges.add(neighborhood) " + " unique_hyperedges.add(neighborhood)" ] }, { @@ -215,7 +214,6 @@ } ], "source": [ - "\n", "# Calculate hyperedge statistics.\n", "hyperedge_sizes = [len(he) for he in hyperedges]\n", "min_size = min(hyperedge_sizes)\n", @@ -226,14 +224,14 @@ "num_single_node_hyperedges = sum(np.array(hyperedge_sizes) == 1)\n", "\n", "# Print the hyperedge statistics.\n", - "print(f'Hyperedge statistics: ')\n", - "print('Number of hyperedges without duplicated hyperedges', len(hyperedges))\n", - "print(f'min = {min_size}, ')\n", - "print(f'max = {max_size}, ')\n", - "print(f'mean = {mean_size}, ')\n", - "print(f'median = {median_size}, ')\n", - "print(f'std = {std_size}, ')\n", - "print(f'Number of hyperedges with size equal to one = {num_single_node_hyperedges}')\n" + "print(f\"Hyperedge statistics: \")\n", + "print(\"Number of hyperedges without duplicated hyperedges\", len(hyperedges))\n", + "print(f\"min = {min_size}, \")\n", + "print(f\"max = {max_size}, \")\n", + "print(f\"mean = {mean_size}, \")\n", + "print(f\"median = {median_size}, \")\n", + "print(f\"std = {std_size}, \")\n", + "print(f\"Number of hyperedges with size equal to one = {num_single_node_hyperedges}\")" ] }, { @@ -255,8 +253,8 @@ " for row in neighibourhood:\n", " incidence_1[row, col] = 1\n", "\n", - "assert all(incidence_1.sum(0)>0) == True, \"Some hyperedges are empty\"\n", - "assert all(incidence_1.sum(1)>0) == True, \"Some nodes are not in any hyperedges\"\n", + "assert all(incidence_1.sum(0) > 0) == True, \"Some hyperedges are empty\"\n", + "assert all(incidence_1.sum(1) > 0) == True, \"Some nodes are not in any hyperedges\"\n", "incidence_1 = torch.Tensor(incidence_1).to_sparse_coo()" ] }, @@ -283,7 +281,7 @@ "outputs": [], "source": [ "class Network(torch.nn.Module):\n", - " \"\"\" Network class that initializes the base model and readout layer.\n", + " \"\"\"Network class that initializes the base model and readout layer.\n", "\n", " Base model parameters:\n", " ----------\n", @@ -296,41 +294,34 @@ " Optitional:\n", " **kwargs : dict\n", " Additional arguments for the base model.\n", - " \n", + "\n", " Readout layer parameters:\n", " ----------\n", " out_channels : int\n", " Dimension of the output features.\n", " task_level : str\n", - " Level of the task. Either \"graph\" or \"node\". \n", + " Level of the task. Either \"graph\" or \"node\".\n", " \"\"\"\n", + "\n", " def __init__(\n", - " self, \n", - " in_channels, \n", - " hidden_channels,\n", - " out_channels, \n", - " \n", - " task_level=\"graph\",\n", - " **kwargs):\n", + " self, in_channels, hidden_channels, out_channels, task_level=\"graph\", **kwargs\n", + " ):\n", " super().__init__()\n", - " \n", + "\n", " # Define the model\n", " self.base_model = HNHN(\n", - " in_channels=in_channels,\n", - " hidden_channels=hidden_channels,\n", - " **kwargs\n", + " in_channels=in_channels, hidden_channels=hidden_channels, **kwargs\n", " )\n", "\n", - "\n", " # Readout\n", " self.linear = torch.nn.Linear(hidden_channels, out_channels)\n", " self.out_pool = True if task_level == \"graph\" else False\n", - " \n", + "\n", " def forward(self, x_0):\n", " # Base model\n", " x_0, x_1 = self.base_model(x_0)\n", "\n", - " # Pool over all nodes in the hypergraph \n", + " # Pool over all nodes in the hypergraph\n", " if self.out_pool is True:\n", " x = torch.max(x_0, dim=0)[0]\n", " else:\n", @@ -355,22 +346,22 @@ "# Base model hyperparameters\n", "in_channels = x_0s.shape[1]\n", "hidden_channels = 128\n", - "n_layers=1\n", - "mlp_num_layers=1\n", + "n_layers = 1\n", + "mlp_num_layers = 1\n", "\n", "# Readout hyperparameters\n", "out_channels = torch.unique(y).shape[0]\n", - "task_level = \"graph\" if out_channels==1 else \"node\"\n", + "task_level = \"graph\" if out_channels == 1 else \"node\"\n", "\n", "\n", "model = Network(\n", " in_channels=in_channels,\n", " hidden_channels=hidden_channels,\n", - " out_channels=out_channels, \n", + " out_channels=out_channels,\n", " n_layers=n_layers,\n", " incidence_1=incidence_1,\n", " task_level=task_level,\n", - " ).to(device)" + ").to(device)" ] }, { @@ -423,10 +414,10 @@ "source": [ "x_0s = torch.tensor(x_0s)\n", "x_0s, incidence_1, y = (\n", - " x_0s.float().to(device),\n", - " incidence_1.float().to(device),\n", - " torch.tensor(y, dtype=torch.long).to(device),\n", - " )" + " x_0s.float().to(device),\n", + " incidence_1.float().to(device),\n", + " torch.tensor(y, dtype=torch.long).to(device),\n", + ")" ] }, { @@ -474,17 +465,15 @@ } ], "source": [ - "\n", "test_interval = 5\n", "num_epochs = 30\n", "\n", "epoch_loss = []\n", "for epoch_i in range(1, num_epochs + 1):\n", - " \n", " model.train()\n", "\n", " opt.zero_grad()\n", - " \n", + "\n", " # Extract edge_index from sparse incidence matrix\n", " y_hat = model(x_0s)\n", " loss = loss_fn(y_hat[train_mask], y[train_mask])\n", @@ -493,23 +482,29 @@ " opt.step()\n", " epoch_loss.append(loss.item())\n", "\n", - " \n", - "\n", " if epoch_i % test_interval == 0:\n", - " \n", " model.eval()\n", " y_hat = model(x_0s)\n", "\n", " loss = loss_fn(y_hat[train_mask], y[train_mask])\n", " print(f\"Epoch: {epoch_i} \")\n", - " print(f\"Train_loss: {np.mean(epoch_loss):.4f}, acc: {acc_fn(y_hat[train_mask].argmax(1), y[train_mask]):.4f}\",flush=True)\n", + " print(\n", + " f\"Train_loss: {np.mean(epoch_loss):.4f}, acc: {acc_fn(y_hat[train_mask].argmax(1), y[train_mask]):.4f}\",\n", + " flush=True,\n", + " )\n", "\n", " loss = loss_fn(y_hat[val_mask], y[val_mask])\n", - " \n", - " print(f\"Val_loss: {loss:.4f}, Val_acc: {acc_fn(y_hat[val_mask].argmax(1), y[val_mask]):.4f}\", flush=True)\n", + "\n", + " print(\n", + " f\"Val_loss: {loss:.4f}, Val_acc: {acc_fn(y_hat[val_mask].argmax(1), y[val_mask]):.4f}\",\n", + " flush=True,\n", + " )\n", "\n", " loss = loss_fn(y_hat[test_mask], y[test_mask])\n", - " print(f\"Test_loss: {loss:.4f}, Test_acc: {acc_fn(y_hat[test_mask].argmax(1), y[test_mask]):.4f}\", flush=True)" + " print(\n", + " f\"Test_loss: {loss:.4f}, Test_acc: {acc_fn(y_hat[test_mask].argmax(1), y[test_mask]):.4f}\",\n", + " flush=True,\n", + " )" ] }, { diff --git a/tutorials/hypergraph/hypergat_train.ipynb b/tutorials/hypergraph/hypergat_train.ipynb index 53a898521..1cb89dfbe 100644 --- a/tutorials/hypergraph/hypergat_train.ipynb +++ b/tutorials/hypergraph/hypergat_train.ipynb @@ -219,7 +219,7 @@ "outputs": [], "source": [ "class Network(torch.nn.Module):\n", - " \"\"\" Network class that initializes the AllSet model and readout layer.\n", + " \"\"\"Network class that initializes the AllSet model and readout layer.\n", "\n", " Base model parameters:\n", " ----------\n", @@ -232,41 +232,34 @@ " Optitional:\n", " **kwargs : dict\n", " Additional arguments for the base model.\n", - " \n", + "\n", " Readout layer parameters:\n", " ----------\n", " out_channels : int\n", " Dimension of the output features.\n", " task_level : str\n", - " Level of the task. Either \"graph\" or \"node\". \n", + " Level of the task. Either \"graph\" or \"node\".\n", " \"\"\"\n", + "\n", " def __init__(\n", - " self, \n", - " in_channels, \n", - " hidden_channels,\n", - " out_channels, \n", - " \n", - " task_level=\"graph\",\n", - " **kwargs):\n", + " self, in_channels, hidden_channels, out_channels, task_level=\"graph\", **kwargs\n", + " ):\n", " super().__init__()\n", - " \n", + "\n", " # Define the model\n", " self.base_model = HyperGAT(\n", - " in_channels=in_channels,\n", - " hidden_channels=hidden_channels,\n", - " **kwargs\n", + " in_channels=in_channels, hidden_channels=hidden_channels, **kwargs\n", " )\n", "\n", - "\n", " # Readout\n", " self.linear = torch.nn.Linear(hidden_channels, out_channels)\n", " self.out_pool = True if task_level == \"graph\" else False\n", - " \n", + "\n", " def forward(self, x_0, incidence_1):\n", " # Base model\n", " x_0, x_1 = self.base_model(x_0, incidence_1)\n", "\n", - " # Pool over all nodes in the hypergraph \n", + " # Pool over all nodes in the hypergraph\n", " if self.out_pool is True:\n", " x = torch.max(x_0, dim=0)[0]\n", " else:\n", @@ -296,16 +289,16 @@ "\n", "# Readout hyperparameters\n", "out_channels = 1\n", - "task_level = \"graph\" \n", + "task_level = \"graph\"\n", "\n", "\n", "model = Network(\n", " in_channels=in_channels,\n", " hidden_channels=hidden_channels,\n", - " out_channels=out_channels, \n", + " out_channels=out_channels,\n", " n_layers=n_layers,\n", " task_level=task_level,\n", - " ).to(device)" + ").to(device)" ] }, { @@ -321,9 +314,9 @@ "\n", "# # Define the model\n", "# model = HyperGAT(\n", - "# in_channels=in_channels, \n", - "# hidden_channels=hidden_channels, \n", - "# out_channels=out_dim, \n", + "# in_channels=in_channels,\n", + "# hidden_channels=hidden_channels,\n", + "# out_channels=out_dim,\n", "# n_layers=n_layers\n", "# )\n", "# model = model.to(device)\n", @@ -401,12 +394,10 @@ " opt.step()\n", " epoch_loss.append(loss.item())\n", "\n", - " \n", " if epoch_i % test_interval == 0:\n", " with torch.no_grad():\n", - " \n", " train_loss = np.mean(epoch_loss)\n", - " \n", + "\n", " test_epoch_loss = []\n", " for x_0, incidence_1, y in zip(x_0_test, incidence_1_test, y_test):\n", " x_0 = torch.tensor(x_0)\n", @@ -418,12 +409,11 @@ " y_hat = model(x_0, incidence_1)\n", " loss = loss_fn(y_hat, y)\n", " test_epoch_loss.append(loss.item())\n", - " \n", + "\n", " print(\n", " f\"Epoch: {epoch_i} train_loss {train_loss:.4f} test_loss: {np.mean(test_epoch_loss):.4f}\",\n", " flush=True,\n", - " )\n", - " " + " )" ] } ], diff --git a/tutorials/hypergraph/hypersage_train.ipynb b/tutorials/hypergraph/hypersage_train.ipynb index 6c64be517..9a2c5aa88 100644 --- a/tutorials/hypergraph/hypersage_train.ipynb +++ b/tutorials/hypergraph/hypersage_train.ipynb @@ -65,7 +65,7 @@ "from topomodelx.nn.hypergraph.hypersage import HyperSAGE\n", "\n", "torch.manual_seed(0)\n", - "np.random.seed(0)\n" + "np.random.seed(0)" ] }, { @@ -131,7 +131,6 @@ } ], "source": [ - "\n", "cora = geom_datasets.Planetoid(root=\"tmp/\", name=\"Cora\")\n", "data = cora.data\n", "\n", @@ -141,7 +140,7 @@ "\n", "train_mask = data.train_mask\n", "val_mask = data.val_mask\n", - "test_mask = data.test_mask\n" + "test_mask = data.test_mask" ] }, { @@ -187,7 +186,7 @@ " neighborhood = tuple(sorted(neighborhood))\n", " if neighborhood not in unique_hyperedges:\n", " hyperedges.append(list(neighborhood))\n", - " unique_hyperedges.add(neighborhood) " + " unique_hyperedges.add(neighborhood)" ] }, { @@ -218,7 +217,6 @@ } ], "source": [ - "\n", "# Calculate hyperedge statistics.\n", "hyperedge_sizes = [len(he) for he in hyperedges]\n", "min_size = min(hyperedge_sizes)\n", @@ -229,14 +227,14 @@ "num_single_node_hyperedges = sum(np.array(hyperedge_sizes) == 1)\n", "\n", "# Print the hyperedge statistics.\n", - "print(f'Hyperedge statistics: ')\n", - "print('Number of hyperedges without duplicated hyperedges', len(hyperedges))\n", - "print(f'min = {min_size}, ')\n", - "print(f'max = {max_size}, ')\n", - "print(f'mean = {mean_size}, ')\n", - "print(f'median = {median_size}, ')\n", - "print(f'std = {std_size}, ')\n", - "print(f'Number of hyperedges with size equal to one = {num_single_node_hyperedges}')\n" + "print(f\"Hyperedge statistics: \")\n", + "print(\"Number of hyperedges without duplicated hyperedges\", len(hyperedges))\n", + "print(f\"min = {min_size}, \")\n", + "print(f\"max = {max_size}, \")\n", + "print(f\"mean = {mean_size}, \")\n", + "print(f\"median = {median_size}, \")\n", + "print(f\"std = {std_size}, \")\n", + "print(f\"Number of hyperedges with size equal to one = {num_single_node_hyperedges}\")" ] }, { @@ -258,8 +256,8 @@ " for row in neighibourhood:\n", " incidence_1[row, col] = 1\n", "\n", - "assert all(incidence_1.sum(0)>0) == True, \"Some hyperedges are empty\"\n", - "assert all(incidence_1.sum(1)>0) == True, \"Some nodes are not in any hyperedges\"\n", + "assert all(incidence_1.sum(0) > 0) == True, \"Some hyperedges are empty\"\n", + "assert all(incidence_1.sum(1) > 0) == True, \"Some nodes are not in any hyperedges\"\n", "incidence_1 = torch.Tensor(incidence_1).to_sparse_coo()" ] }, @@ -286,7 +284,7 @@ "outputs": [], "source": [ "class Network(torch.nn.Module):\n", - " \"\"\" Network class that initializes the base model and readout layer.\n", + " \"\"\"Network class that initializes the base model and readout layer.\n", "\n", " Base model parameters:\n", " ----------\n", @@ -299,41 +297,34 @@ " Optitional:\n", " **kwargs : dict\n", " Additional arguments for the base model.\n", - " \n", + "\n", " Readout layer parameters:\n", " ----------\n", " out_channels : int\n", " Dimension of the output features.\n", " task_level : str\n", - " Level of the task. Either \"graph\" or \"node\". \n", + " Level of the task. Either \"graph\" or \"node\".\n", " \"\"\"\n", + "\n", " def __init__(\n", - " self, \n", - " in_channels, \n", - " hidden_channels,\n", - " out_channels, \n", - " \n", - " task_level=\"graph\",\n", - " **kwargs):\n", + " self, in_channels, hidden_channels, out_channels, task_level=\"graph\", **kwargs\n", + " ):\n", " super().__init__()\n", - " \n", + "\n", " # Define the model\n", " self.base_model = HyperSAGE(\n", - " in_channels=in_channels,\n", - " hidden_channels=hidden_channels,\n", - " **kwargs\n", + " in_channels=in_channels, hidden_channels=hidden_channels, **kwargs\n", " )\n", "\n", - "\n", " # Readout\n", " self.linear = torch.nn.Linear(hidden_channels, out_channels)\n", " self.out_pool = True if task_level == \"graph\" else False\n", - " \n", + "\n", " def forward(self, x_0, incidence_1):\n", " # Base model\n", " x_0 = self.base_model(x_0, incidence_1)\n", "\n", - " # Pool over all nodes in the hypergraph \n", + " # Pool over all nodes in the hypergraph\n", " if self.out_pool is True:\n", " x = torch.max(x_0, dim=0)[0]\n", " else:\n", @@ -358,22 +349,22 @@ "# Base model hyperparameters\n", "in_channels = x_0s.shape[1]\n", "hidden_channels = 128\n", - "n_layers=1\n", - "mlp_num_layers=1\n", + "n_layers = 1\n", + "mlp_num_layers = 1\n", "\n", "# Readout hyperparameters\n", "out_channels = torch.unique(y).shape[0]\n", - "task_level = \"graph\" if out_channels==1 else \"node\"\n", + "task_level = \"graph\" if out_channels == 1 else \"node\"\n", "\n", "\n", "model = Network(\n", " in_channels=in_channels,\n", " hidden_channels=hidden_channels,\n", - " out_channels=out_channels, \n", + " out_channels=out_channels,\n", " n_layers=n_layers,\n", " device=device,\n", " task_level=task_level,\n", - " ).to(device)" + ").to(device)" ] }, { @@ -426,10 +417,10 @@ "source": [ "x_0s = torch.tensor(x_0s)\n", "x_0s, incidence_1, y = (\n", - " x_0s.float().to(device),\n", - " incidence_1.float().to(device),\n", - " torch.tensor(y, dtype=torch.long).to(device),\n", - " )" + " x_0s.float().to(device),\n", + " incidence_1.float().to(device),\n", + " torch.tensor(y, dtype=torch.long).to(device),\n", + ")" ] }, { @@ -459,10 +450,10 @@ "source": [ "x_0s = torch.tensor(x_0s)\n", "x_0s, incidence_1, y = (\n", - " x_0s.float().to(device),\n", - " incidence_1.float().to(device),\n", - " torch.tensor(y, dtype=torch.long).to(device),\n", - " )" + " x_0s.float().to(device),\n", + " incidence_1.float().to(device),\n", + " torch.tensor(y, dtype=torch.long).to(device),\n", + ")" ] }, { @@ -508,11 +499,10 @@ "\n", "epoch_loss = []\n", "for epoch_i in range(1, num_epochs + 1):\n", - " \n", " model.train()\n", "\n", " opt.zero_grad()\n", - " \n", + "\n", " # Extract edge_index from sparse incidence matrix\n", " y_hat = model(x_0s, incidence_1)\n", " loss = loss_fn(y_hat[train_mask], y[train_mask])\n", @@ -522,20 +512,28 @@ " epoch_loss.append(loss.item())\n", "\n", " if epoch_i % test_interval == 0:\n", - " \n", " model.eval()\n", " y_hat = model(x_0s, incidence_1)\n", "\n", " loss = loss_fn(y_hat[train_mask], y[train_mask])\n", " print(f\"Epoch: {epoch_i} \")\n", - " print(f\"Train_loss: {np.mean(epoch_loss):.4f}, acc: {acc_fn(y_hat[train_mask].argmax(1), y[train_mask]):.4f}\",flush=True)\n", + " print(\n", + " f\"Train_loss: {np.mean(epoch_loss):.4f}, acc: {acc_fn(y_hat[train_mask].argmax(1), y[train_mask]):.4f}\",\n", + " flush=True,\n", + " )\n", "\n", " loss = loss_fn(y_hat[val_mask], y[val_mask])\n", - " \n", - " print(f\"Val_loss: {loss:.4f}, Val_acc: {acc_fn(y_hat[val_mask].argmax(1), y[val_mask]):.4f}\", flush=True)\n", + "\n", + " print(\n", + " f\"Val_loss: {loss:.4f}, Val_acc: {acc_fn(y_hat[val_mask].argmax(1), y[val_mask]):.4f}\",\n", + " flush=True,\n", + " )\n", "\n", " loss = loss_fn(y_hat[test_mask], y[test_mask])\n", - " print(f\"Test_loss: {loss:.4f}, Test_acc: {acc_fn(y_hat[test_mask].argmax(1), y[test_mask]):.4f}\", flush=True)" + " print(\n", + " f\"Test_loss: {loss:.4f}, Test_acc: {acc_fn(y_hat[test_mask].argmax(1), y[test_mask]):.4f}\",\n", + " flush=True,\n", + " )" ] } ], diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.allx b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.allx new file mode 100644 index 0000000000000000000000000000000000000000..44d53b1fece343538e45592caac521d73c6f98d6 GIT binary patch literal 257305 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 z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#jHhhXxMY_waq6 G`Tqf}DSCbY literal 0 HcmV?d00001 diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.ally b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.ally new file mode 100644 index 0000000000000000000000000000000000000000..04fbd0b083d09341fcf16b395c642329637f0542 GIT binary patch literal 47959 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 My~lCyzWDTi0g%o(9smFU literal 0 HcmV?d00001 diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.graph b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.graph new file mode 100644 index 0000000000000000000000000000000000000000..4d3bf85dfc8b1c105a2c995597a1b3eed6947925 GIT binary patch literal 59847 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 A!vFvP literal 0 HcmV?d00001 diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.test.index b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.test.index new file mode 100644 index 000000000..ded8092db --- /dev/null +++ b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.test.index @@ -0,0 +1,1000 @@ +2692 +2532 +2050 +1715 +2362 +2609 +2622 +1975 +2081 +1767 +2263 +1725 +2588 +2259 +2357 +1998 +2574 +2179 +2291 +2382 +1812 +1751 +2422 +1937 +2631 +2510 +2378 +2589 +2345 +1943 +1850 +2298 +1825 +2035 +2507 +2313 +1906 +1797 +2023 +2159 +2495 +1886 +2122 +2369 +2461 +1925 +2565 +1858 +2234 +2000 +1846 +2318 +1723 +2559 +2258 +1763 +1991 +1922 +2003 +2662 +2250 +2064 +2529 +1888 +2499 +2454 +2320 +2287 +2203 +2018 +2002 +2632 +2554 +2314 +2537 +1760 +2088 +2086 +2218 +2605 +1953 +2403 +1920 +2015 +2335 +2535 +1837 +2009 +1905 +2636 +1942 +2193 +2576 +2373 +1873 +2463 +2509 +1954 +2656 +2455 +2494 +2295 +2114 +2561 +2176 +2275 +2635 +2442 +2704 +2127 +2085 +2214 +2487 +1739 +2543 +1783 +2485 +2262 +2472 +2326 +1738 +2170 +2100 +2384 +2152 +2647 +2693 +2376 +1775 +1726 +2476 +2195 +1773 +1793 +2194 +2581 +1854 +2524 +1945 +1781 +1987 +2599 +1744 +2225 +2300 +1928 +2042 +2202 +1958 +1816 +1916 +2679 +2190 +1733 +2034 +2643 +2177 +1883 +1917 +1996 +2491 +2268 +2231 +2471 +1919 +1909 +2012 +2522 +1865 +2466 +2469 +2087 +2584 +2563 +1924 +2143 +1736 +1966 +2533 +2490 +2630 +1973 +2568 +1978 +2664 +2633 +2312 +2178 +1754 +2307 +2480 +1960 +1742 +1962 +2160 +2070 +2553 +2433 +1768 +2659 +2379 +2271 +1776 +2153 +1877 +2027 +2028 +2155 +2196 +2483 +2026 +2158 +2407 +1821 +2131 +2676 +2277 +2489 +2424 +1963 +1808 +1859 +2597 +2548 +2368 +1817 +2405 +2413 +2603 +2350 +2118 +2329 +1969 +2577 +2475 +2467 +2425 +1769 +2092 +2044 +2586 +2608 +1983 +2109 +2649 +1964 +2144 +1902 +2411 +2508 +2360 +1721 +2005 +2014 +2308 +2646 +1949 +1830 +2212 +2596 +1832 +1735 +1866 +2695 +1941 +2546 +2498 +2686 +2665 +1784 +2613 +1970 +2021 +2211 +2516 +2185 +2479 +2699 +2150 +1990 +2063 +2075 +1979 +2094 +1787 +2571 +2690 +1926 +2341 +2566 +1957 +1709 +1955 +2570 +2387 +1811 +2025 +2447 +2696 +2052 +2366 +1857 +2273 +2245 +2672 +2133 +2421 +1929 +2125 +2319 +2641 +2167 +2418 +1765 +1761 +1828 +2188 +1972 +1997 +2419 +2289 +2296 +2587 +2051 +2440 +2053 +2191 +1923 +2164 +1861 +2339 +2333 +2523 +2670 +2121 +1921 +1724 +2253 +2374 +1940 +2545 +2301 +2244 +2156 +1849 +2551 +2011 +2279 +2572 +1757 +2400 +2569 +2072 +2526 +2173 +2069 +2036 +1819 +1734 +1880 +2137 +2408 +2226 +2604 +1771 +2698 +2187 +2060 +1756 +2201 +2066 +2439 +1844 +1772 +2383 +2398 +1708 +1992 +1959 +1794 +2426 +2702 +2444 +1944 +1829 +2660 +2497 +2607 +2343 +1730 +2624 +1790 +1935 +1967 +2401 +2255 +2355 +2348 +1931 +2183 +2161 +2701 +1948 +2501 +2192 +2404 +2209 +2331 +1810 +2363 +2334 +1887 +2393 +2557 +1719 +1732 +1986 +2037 +2056 +1867 +2126 +1932 +2117 +1807 +1801 +1743 +2041 +1843 +2388 +2221 +1833 +2677 +1778 +2661 +2306 +2394 +2106 +2430 +2371 +2606 +2353 +2269 +2317 +2645 +2372 +2550 +2043 +1968 +2165 +2310 +1985 +2446 +1982 +2377 +2207 +1818 +1913 +1766 +1722 +1894 +2020 +1881 +2621 +2409 +2261 +2458 +2096 +1712 +2594 +2293 +2048 +2359 +1839 +2392 +2254 +1911 +2101 +2367 +1889 +1753 +2555 +2246 +2264 +2010 +2336 +2651 +2017 +2140 +1842 +2019 +1890 +2525 +2134 +2492 +2652 +2040 +2145 +2575 +2166 +1999 +2434 +1711 +2276 +2450 +2389 +2669 +2595 +1814 +2039 +2502 +1896 +2168 +2344 +2637 +2031 +1977 +2380 +1936 +2047 +2460 +2102 +1745 +2650 +2046 +2514 +1980 +2352 +2113 +1713 +2058 +2558 +1718 +1864 +1876 +2338 +1879 +1891 +2186 +2451 +2181 +2638 +2644 +2103 +2591 +2266 +2468 +1869 +2582 +2674 +2361 +2462 +1748 +2215 +2615 +2236 +2248 +2493 +2342 +2449 +2274 +1824 +1852 +1870 +2441 +2356 +1835 +2694 +2602 +2685 +1893 +2544 +2536 +1994 +1853 +1838 +1786 +1930 +2539 +1892 +2265 +2618 +2486 +2583 +2061 +1796 +1806 +2084 +1933 +2095 +2136 +2078 +1884 +2438 +2286 +2138 +1750 +2184 +1799 +2278 +2410 +2642 +2435 +1956 +2399 +1774 +2129 +1898 +1823 +1938 +2299 +1862 +2420 +2673 +1984 +2204 +1717 +2074 +2213 +2436 +2297 +2592 +2667 +2703 +2511 +1779 +1782 +2625 +2365 +2315 +2381 +1788 +1714 +2302 +1927 +2325 +2506 +2169 +2328 +2629 +2128 +2655 +2282 +2073 +2395 +2247 +2521 +2260 +1868 +1988 +2324 +2705 +2541 +1731 +2681 +2707 +2465 +1785 +2149 +2045 +2505 +2611 +2217 +2180 +1904 +2453 +2484 +1871 +2309 +2349 +2482 +2004 +1965 +2406 +2162 +1805 +2654 +2007 +1947 +1981 +2112 +2141 +1720 +1758 +2080 +2330 +2030 +2432 +2089 +2547 +1820 +1815 +2675 +1840 +2658 +2370 +2251 +1908 +2029 +2068 +2513 +2549 +2267 +2580 +2327 +2351 +2111 +2022 +2321 +2614 +2252 +2104 +1822 +2552 +2243 +1798 +2396 +2663 +2564 +2148 +2562 +2684 +2001 +2151 +2706 +2240 +2474 +2303 +2634 +2680 +2055 +2090 +2503 +2347 +2402 +2238 +1950 +2054 +2016 +1872 +2233 +1710 +2032 +2540 +2628 +1795 +2616 +1903 +2531 +2567 +1946 +1897 +2222 +2227 +2627 +1856 +2464 +2241 +2481 +2130 +2311 +2083 +2223 +2284 +2235 +2097 +1752 +2515 +2527 +2385 +2189 +2283 +2182 +2079 +2375 +2174 +2437 +1993 +2517 +2443 +2224 +2648 +2171 +2290 +2542 +2038 +1855 +1831 +1759 +1848 +2445 +1827 +2429 +2205 +2598 +2657 +1728 +2065 +1918 +2427 +2573 +2620 +2292 +1777 +2008 +1875 +2288 +2256 +2033 +2470 +2585 +2610 +2082 +2230 +1915 +1847 +2337 +2512 +2386 +2006 +2653 +2346 +1951 +2110 +2639 +2520 +1939 +2683 +2139 +2220 +1910 +2237 +1900 +1836 +2197 +1716 +1860 +2077 +2519 +2538 +2323 +1914 +1971 +1845 +2132 +1802 +1907 +2640 +2496 +2281 +2198 +2416 +2285 +1755 +2431 +2071 +2249 +2123 +1727 +2459 +2304 +2199 +1791 +1809 +1780 +2210 +2417 +1874 +1878 +2116 +1961 +1863 +2579 +2477 +2228 +2332 +2578 +2457 +2024 +1934 +2316 +1841 +1764 +1737 +2322 +2239 +2294 +1729 +2488 +1974 +2473 +2098 +2612 +1834 +2340 +2423 +2175 +2280 +2617 +2208 +2560 +1741 +2600 +2059 +1747 +2242 +2700 +2232 +2057 +2147 +2682 +1792 +1826 +2120 +1895 +2364 +2163 +1851 +2391 +2414 +2452 +1803 +1989 +2623 +2200 +2528 +2415 +1804 +2146 +2619 +2687 +1762 +2172 +2270 +2678 +2593 +2448 +1882 +2257 +2500 +1899 +2478 +2412 +2107 +1746 +2428 +2115 +1800 +1901 +2397 +2530 +1912 +2108 +2206 +2091 +1740 +2219 +1976 +2099 +2142 +2671 +2668 +2216 +2272 +2229 +2666 +2456 +2534 +2697 +2688 +2062 +2691 +2689 +2154 +2590 +2626 +2390 +1813 +2067 +1952 +2518 +2358 +1789 +2076 +2049 +2119 +2013 +2124 +2556 +2105 +2093 +1885 +2305 +2354 +2135 +2601 +1770 +1995 +2504 +1749 +2157 diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.tx b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.tx new file mode 100644 index 0000000000000000000000000000000000000000..6e856d777401ee15dc8619db76c97d0a40ba2d60 GIT binary patch literal 148025 zcmcG%d7RE=-?)DvdrBmsx+B?&kv03S;^^&mKl<*jYOiD$j}|3 zRI+4H5k;0Zaw8$RzsE7pbv{3@`}O?$dtT4+oiXz{-=FvS-p})zo^ML-#Nmkplg3mV zo|KS0ykE7%;mL)d*WiQ^$pfD(G%Q!;3Bz)aAC{+5e7?tqCiBx_*Tm=Hf%tsAh7U+c z>NhNJyPxv3o0Iq1_BjH7O z1y;j0_yLZ<1-Jsmaz!E)paDDxUEy&U1`}ZpEQj^59ZtaSkSlj2QUWSNHE0T5;87S3 zli(G|gfCzR9D?&uI1jo)O}H1@LkH*wgCGs&!n^P>d<}=-4CKFt^>8cP1FfJdJOL?? z4ohG?d<940G8D~=uFw!VLL!WWF%X40upBnQcW?#@=8HtGhq6!uT0>Xp4WnQ(EP(f5 zD;$8ca1n~+k3?>P8c+vXLw9%rQeZMnhsCfCw!(fm19=MYZnzz4!u{|FBtaDB!ZO$l z``{GhE*Od240l6)=m`B_9L#{XAPc^P!|)6I4Us~TNNI?JHt;AU!)TZWZ@^mE4twDz z$W<5}p#un9he&tN-z2fxEL zBvfgr49%b;bcex^0_iXpR>3CN2S3AKkgF)ZhkM{Y=nhZ7IG75HAq#fFarg^vxFHg$ z2o0eV41gh!3bWvCSOuTLH*gXzL5X7c02)CDNQ6-^4$@%}tb<)}3@*TB$Xz@VDG6nu zIy8ai@G$g;C*gUR1#@8qY=G@>41R&gjgd%RCS{K@ELpuXP`hy zbcMU28FYrn;3-IlS+EQ?!*_57^4^Rup&B%R2jOve24=x*SOy=#9{3JUL9SAm2TDRE zXber^As7s)FdLS_M%V+#;XiO=X=*Ywg|09JQsG5-13rW;un&HND{x~O_6GMr9cT#; zLSJ|iroyYR5m!9h3$k+Q@Ylz=jDH#CL^;W2m$ zGGHmJh3#+@E<%xVk;olTADTf|NQ7iagITZ~-iK}QJ)DL=puio}a<~iXLt|(U36KoW z!2(zatKkbc3}@j26e*ADPy^aP0*rxauoO1JZa4vdL&-a-lh6tth8{2!CcO}7Qy@QDSQnF;WXr~ zf^DD*G=$F38%DxZm<5YqC2WLjI0EP43KYAG^-vX>!~M_!`ok!A0T#js@Hu=BC*j|4 z0j|9}61fwqLQCilN$@mGhqErd6b`{j$WxX61=XMxJPbo&0?dN9VIypZBXA7< zglnteQ@9t}LN6EzlVA=kgAK3?PQYa-6c>qO%)e zgc0x*Oodk=6Slx^I03&yzM9m3Cf7Q!0%3Vw#aA%7k03e})F#6y1= z4C7%sya6A;HaG&mLZmLa1#!?4x)*20Id3HHK%I1Rb(#lCPCG>0BA0-l3c z;eFTw2jDcEgWUCqPpAehp*tkOM3@aLU=?hFy>Jlz4SDMGF1QOCLuVKS;~^bp!*cit zcEC??63#=u2G|DfhC0v&dcsghgPHIqd;nj-UN{C9p=iTMKY{G|Yr0unazd18^3uX@bw- zR;UhbAOXh0ba)At!w0Ypet>iEAGon8GX^wJI_ z37Cd#bzBNw3}izIWR8Pp;35=9W+^BO#gSJE=;b*VBOUmf2+u)1-Z2%{!oT4!i02)J zkm);;k)__d;d*3g$2u{Y*{mx43s|?S-aqSxQMJ$$QcdeVP;I`JifjHtKkr+Yh(B)==;gg33=Nf zUrgU~$h#hScSALB&&uuvPlEQ;_sY5#T7mi{LKJqxEy!vH$73?}TLI*@g3j<9)JCqC zI&(n385`Q+Z3wYtT$Do|^I^_~lIwRvRi1AJoxsbXCGa^M0A;)j>%l#L4~IdS*P?4( z=m*9C^)50VZbiSXpwC7k-`H~h-Ju6mWo>I14q0#AO#K>fkrO@f2q zp5mYbY=}Ld!W#Fs2KIu!)^>@=&~CodeU)atv6c#XS!+z6fnhxFMV&FR6|4!y@XHX^ zpW=IU(s#Acxd{|Njy7oqyWku60p3GqZsb`bvcWjGfpyA!6wI}epzK?aqmA`le_`za z(8k)L0Bem`<6$^x*KN>+waSXdd2}O)&lpu2Yfc2-!BYIr>t& zJOQb$4NJJNrOe=nnls+lSgT zmfv&6%CV(;m;r~tH9vs8=TUeI8Y8ze=r8MfHXMT7$Vh+&ta}|6!)8!t>#w?g1Y5xT zHQrXh`=GAoti4B@)PRs{>(HwW>y5*gL3!%G4fL)1cmR$-1!Rl@ZTtZkllBSw?gOA5 zw59p7ndh^iFwa26+GStc z1leGHu;#4;^Ua=VT$r!rU;tbOKQz#H%6<*9pq#SN#T<0+by%nVi{KvCB=LLuNDnY? z&9n9J3ykJ@X9?FDBi1*2lsTaPe2+HL_8pNk1g1ecRAhZ3SkLFe8(>_TYh|E4j7Qef z5Ncg5I46Tnzj-e%YVe#rA37=OleO>j<|4aUirU>&ty=HvUWkPb89Ey&ILt^;kI z0ke5_9`uXJG_N~@bCh;fCg;IO8Y}>3;Y(m0@k6scU@RMR55ZF~ADSU=0%Sm_8`{Di zp`GnVEX$EUim%(j*}^(81>Od0lXHfBr!D9=W1>28tVbh2o7?+BUXNf+CDv4jtNo;p z> z=s(}%jP@@2nQzwHCwTT2etsRYo5B6?0JMcIun#`sS^JJ>4nI`9i#08w4NQmAP!1VG z!1uThXDV~U_|Sj#U?N!Wc7gA=pEUsW*aZ5|c$*B`_;;}OCm`>=nB1F@XD?Uw2G*Pb zb%^rsXTf^m%zX^(pC=*YwmE6M?F0MFKydDQiS_HDDDS8Sb-=s~A8MZBd-v1=`60&3 zAlI5?4@&~~bP$|b+?%=NOkuBl1=fT0(LFkom>DvaI)9=G<&QKMt?+tiB4f zO7Pb>WKRd>-VWBLC~Sh}=xM#PUjGipQ!&sMo_j+d_=4|^tCesJ!Z}+1={Mum_&*Sn z;khpv_JHwV4zvX0q6cVSV{``?5Bkr(Y(Mrqs&DLd=0J#l&*fu~_cu6;GzWDu&dajC z5=?+@$QT0VZ8qG5jIuBio&sZc9VpjX%h)yctqsA?_O_&$JbU~ux2=n1!p(& zsRrxywe{m&WE_MvbaHM}zeC_2oz}PM#2PI)A#IaWU)dOwj z%%J^^8*3I{B3(c~ybUc`uOCjqwXAOl@4#NLMkp)TKauYr2lMA8uupgvnF!7aiJ<)& zqt_}}1KO-Cvh5ez&fbs?o{yJ76XYy|<)DuCUUkzK-dh+a+Dtj-wsp*$F2veFpq>p_ zHyWZ~j40do- zc7U=y0~k-%xrLyeweJ9Mmbn&r4}t!3R&>s?u66?F{UmTU*Ty~INpQw>_Sz1{+Dvd3 zac)Zidz^XWnWq42!@08y&)dJW<;!5+yb2$KHq}oJz#4CiI$zX+@n9b|KHa-D(zDLr zV13L0_i0QTOV$easn5eXrvfs@fPW;V4Eu%q`w2YH7?;ZV4cwD?Xx^x&vg`#f0Kbkj z;s0@#@#n^r_VRvGxyGaMuREcN9S)?7$S_`!A7%-lqCB(qeCOU>OXsw^X)U>S?4$ey^IaznJ4P#xhE+m)4uK8Xw5nrljXd; z2wltz_dG1NPQM#l`$1c^fhnMFo8Sj<&(<1aOquT6I`|O!SQ}2j?=ju9gT2X_MH~D9 z+CUxSkTVQYz*^xu4ubOIkZlgCw|6W0q7+zj3$y+%0TbW}R_h zEqWZBQAV;Z=bZ#-!TPCi1PUOdGy|cW1BOToTO+0JOcMiG?|6q-^tqptvg?Psu;Q7HEeh&2EhoD_NOGJ@*D)w&c zq-P!Pbd|5}+O{FGf`5`(r|!yA#s#o8B>|7-#BDRaTIVJr!@kj%U)VFv18d5C&>bd$ z@iGLIxdC>-kDzSj)q%R;jAXAn1oQZX{o*sYj_1mQay;W2JL_O4cwTuFjC<6`(Jhg$ zyTJYv#}EBnOMAv6OWO|xYs7wV@7h(JCxi1%@QM1FulmMX$Y-OG`@ncGM!ln{hul<{ z4w;b1`U0$Tuk*ni^$zqqaJKd?v=WSEt#^&q)$wq3ZSnkTebEN5gSFlJ9%UNu+Ryt5 zZFmaQ)7s_i5PG|_p)+7l@JyD;GtL5hn`5K9`I-n(Fy|J4apyV2Gg&nrbdJA`b>^9| zV9py`?}P8Gj=W6P8QaE^`Jg@fvd;K6zwC1%9@W`())I5x`e&_juB!$=z>jbl^qIag z_P+viRv(!&ameTk+Qf6eXTr0f4fK^gco;;%JV#W{UPtkDHvf1F)VDk`D}Z`?UcChw z##u$M*XTR@sP|{ak-pN$2f_88tJTdlO`sKAUH60k^;c2kcs}uN%GtdIGLOK2*Qcv% z(=X^$kG20@leD3|)SPJpE!73mz}V66&TpR0v%q@coai~&GoE=AV#>3xGy6c`(VSUG ze|A7tF`f&#U~G+rW&G~n;F-7t3yjlmc}_c3<>&kjMvkpJ^ZUM#44!YamotpL%`?8W zqCC17C(bd>>H5_k6h6b#pT?MRQW~1VqwpL!H~3kEa&JVIv2iVHt-JQ$(3=Xg-aUHG ziHC0BoDlT+G^R@<)?2T%lQFN)w6piO)|N!p9ECc(FXU=r)}Dhita*lKohi&u<2~f3 zc54M~KpQ2&!^rV`WlgTl`abX`d>9Ei!%-iKmxj4Nx1cdps6Irj6W{A?uX3-6!2AHNOx zTOpj)qsX^jIsd7%x_Y+m3F>PcYu7NZoZ)-@V{b7A+ac3hU@m9_=LzezIiX#9K&W#e1}^b4WhNps z3ihX?@FcR;EyRO!;R$prh)n0rHmn;B?%P-nx>@fAfIVsqYx=XsGmAdAemd*@2!DdL z*Iexf+R!>4^y-Mro}g~t**Q~hfg;GXUOBruQ)|0Q$aN0WuVF5>zTAVn8sPqGfpP46 zj46JdQ=9ckHWWjS^N)A^$~5=YUA-@We%IgX9P;35ea$6xHin|0kF6nd!Thxr=p*BN zD|m;bUdb>LUI1g<*|{le)8I$wk1n6a^tlyT&bTQs3DRK=C}%BXf%Y>$jYI2#HMtX* zJAQ^T5!A5-ggNs6njzKMxEcumJxeY`w(oL|R8~Ex4{5Lg2BPl^;9R0DohPl?>g?Qa zEcOD=sv#bYBln=*o;S@$Ym?_Wd$)3~uCYHM=UQ~ru1jGv*fTRg|5jtI_B1X-4u-wo zfsW>(Gm0}#SJ2MRWbV5Pc&;vo9Aid*E7!XFJsbx8ZOt`4tt-xVOJE&r1JB6jw|W;u zuCkrWPJnado5)x15R>M&GCha5?-nt62l@IR7>%3|@77df(_UlDYXjrbefQ+qry&Y+ zL0!y6^=S{<(!FZS9*~!{16XGqnj0a8lywHI@$QjtbNX>tzS^hk%m0M?kYR276AB@# zCB#E7c#1{JoD0UK^7Khx7!Dc8F;9#W^UawfoHuS@z55yu;d8vReDADg-PQ-rn?=F; zqy4;pb!OHV&O=c!zcaz!=4Wr`;R^KTU6g5_`s4 z-xsvCe-GmvSq043o#5>3{7|1Y;XTU8!+Q7Q{A~_7cZdFUE#KRlj16_ye;2`6aE`F9 z`gce6&fLhV0rj9QxQ~_KJ#b#+diSm0JU=<_JNsC(w4Hm5f^i*cm;UUGeCI=BdOpM< z%X($rdG@gmnkUvjV>!f}`%q?k=m>)$+*hf$d80j^2InhnS`|7%@U{C0GutV?*B{2W zd(iLZci2NaULQ^ZW8`h{F0}<{V`t4>;Jjrlo&$Bvx&Pp+ zpPRBIr=M@+tM^#WTIE=?0L=GBVBZZr()}vSJ)Z?X6AN)Lh3{v9d7lbtV4moAWql5Q z?qjTI=TiL6S@CPoCRfLbdG7s=_VMfy5Be_n)%Y_`jPXQR0p_Q7rk;U9{yN{=XN>Qn zP#h+M@uxp)Ayc2G!wRt9*dy#Yt&s12w2AL^UaSM&m5c}N?q?2vfU#8td7hO@@vQMY z2A05f@ZQjv8ws96JS(KaCTNJh>i!yN2k+#JInO-y=^3E?Ld{aoqo7Xq8e`7S!JYu^ zVZAc$%pv#P5Iif{S3J)v>wR#a>f-a(iK*bdjpzAL=ge2*!8^)0o;Oz~gK^+`b+DgW z)2yEzVmhQE>m9JCcvoy3lxIKs)jn^%cb+vy-IwvD4??dBeagD#=LyD`x_XacJ@a1G z9z7kb_nFX$ci3b8hGM*@B-q3JTMX^lpLd;yT*w>>uYtC-2YL^2hcci)M8Ur0U7mhk zACuwPHa{{-gLS7eY=nHsuok}#+Cu+!V6A>N9@l|&*SiOEU!699pZi#Um8&iFWlhkZ z?s+zHmV@(GIAes~tS!wC>ql#_2RY}MpQk{1#z!U4H|7jWB1OPBu{R%uOHdp6+xVq+ zvZfl-wUB3?=<^Yv+)OBd9Oq4Izdm^c`hfDxJ7pXK^JZyGuWMKr2m0CisT}ol26NAY zz}!d!b#rD?o^d=6nbtY&rjB1jI2#(@^T2-S+&BZ&GYibSP@6o%cpmhgAgJry>^o^|H2 zuXF@w>5o~bZ4zM~dCbZ?m_!#Z*Ai|<6N2q>bx2m+D2Ox0Q;dJPulmz7q*bmgT0obRUDUFAqn|m+Hx)2-683W$o=)2yK2z#L#GR+G=OShkvMP7f_ ztDAFCh=Xjt_wSLbfOa&`?NiF}+>;8Y!8ux+s%r}JyvzI!)YJO87+N69o-q;5f-{Es zr41(_!`^1Tz6#f});z7iI?p7>L7jF(*l%9eX|w6Tqmk<&dX*e?X~Hk8WyZgGtgJ!N1nCR^UFn!NaV7 z6js6~up9K}9WV}3z`4PAwjQ}(eQHkF1FM2(Idd|KZtD0lcwRM6?1KlueTN$EIXKi6 zd!jwVx#k%NHP09_KcesoYk!RC<=)h(48N}iH6i4*y6ptx_XJos)sZhb`JTwv7at$ZB6lBa3FZLv;G@v#@PwbALhGz(LP7Pzm+gnZbwF4cnqR)A|!;-H;!J5MzBv1mk@l7>|RI z^$M&9^Y;*3hb(1#F71J=;b4rqU+wQadl)&lu--U)7Oc_tLJQaeb$Q;iuzkn()&&0^ z!abY=JbZy@A}_XF-J#F{o&mh*83a2`m7=fHEZa>}#b`N})NkY~<^-$4elj5T!&el%W< zFKbMD)_Z>u&OZ9F1ah3y?7dOY2Gx;eeX*t}ZxMt&`}bCI5 zWf@yj;AUiLb7x2E=wqxmAIE_E%7p8YVa>KLYXje*+@JaPdcH4;JnN1+73bes;Qpha z&dx!>C&r&T{|d^v3}uj23GA897yKyaEdLi@4H$FX8uAS9c5X2iwZTqgSc}r&73jg* zM0gyuo#zN;m4>E}0EuAUJMU|UmdMpNFM+mL1WRBCXb}sHxi`-{QJ4lx zARERb!+4p;8uw|8*a!9R5M(&3Xj5zDCD2dS59^z~Lp#}DLvJg9oHAfvwZ2_Jj%&?V zZRfep8kr92WUqV=j)OBwQ)Fqk$zV>~BkV=mPkHYk?+9oldqpo$wrAn|$n-M>W5~O+ zdwJ|lu;*wq?-4!Ihra81-p@}vvetYx2F!z^P=IyD-gt1%`vE*Vc@{FatYL@2HTE}W zapUGs*vd17d8Qi}`^JuSPCME!*22|uuloKII=cWqmQ0w5>WtL4SKb(AVnT2C5*(x!(VlU?BvX2EEitKPksLRhKpTU@=$+ zzF#{PuGceW?U@FXqu%}b($r!5##@P+X@?O3s zB)}o~8??=NxSq9ftO>R?)^>xs_XYLWFW-Xo<6hqF8QlH11@9j0an2qsU<4@38sc1O zy)~xHarG&J9A&1%T=1^GGK>N1@1IZ{`PLkJvitPD$X=t|hmc{uPY2IS$}-mdTtWM2 z6LT*MoCp0(F3dq2_+I;%N9tu>>!-Vr@dH>Bd$7jyUQM1+wmp6m>;Q92zi0>V%FHd# z^NC=ews!dbm%;ZRg96A=2W@P=**~5Eb;<&D8GsJHE8NF5K(_n0-)d`h(Y8Zj3}^?} z?gINy*pquPe!cH_IVRJY$9rz`&^T28a$t>E3fk8@1M|@{K|ipz`VM^<;@CQ^|2*56 z*So+OLt7}z_`CyM?ZMt{tO4!eowmAehZEp_&%s|{KWPi~k(CD4v25@h?YZSvaBiFh z&Oe@0?Kj4Qx+>TFy%nOd^?vT-`M~(}oMT>Ud+qN0<-T0^E&KrHytZ!!t)UAT?;+=^ zBWo>u2-Z*SH3*D(eYgtjhwe*R+PgcXz{e0~3hTRfq3+9A*#_>(&$B$Ez6fKG5oU|U ze7^_EBQw-{{i@t3JP+DQe|j!>3Y;4^$7Jv2t3AX!A?>BU?p-}Y53+a6f@7dBKLh>e zor*QnS<3qBoNy28%?sy__Q<$;4pOGQ&0cvY*xT|Uvk@f17%={giXU;PIP1-Rq zPqrd+KX}eu0w&^3UF7oWL63oFcS`^U0> z)0s>E{t5Qq3anoolaa{t!JaGl-hFyj4>~%78ms!<{$X5=1ZSTwk((b~ot;)dVb)m- ztwkZ{jAi5aIq<&Ay!G#htOuTf^rJmWKZe?5{5lW#KKH=V2*1vm=T{=z^Uw+?h@4I^ z7Cgu4Cu^MX74+9%o;%f9S=JeI!q`0v_N_O;n6R%e1#6};TMIe8Ks$$;@Dbl@AM@=r zcu(Mbz5%Qyby$~&pL?I={(LTl_c(v~PG{@8d3GPq>I>^aDV})*W`g!u2=2wT>Tmt` z+|>_4UYpBXz&>LAe;E8*DDNcPi}S0oGZFd5bqg>~yw|d3{szWHX`a;v_R-tGI_v&V z!!4{eR?Oi?VIVvQ+ND0U2koPt=3Y_sOGIX7OgC%7<2=6tit~HlZ~nR;@1XRHX9a!Y z9-6=d&;?e(0kBq^U;0MBe*~X_I@$+3=lkEqi~-Mbose(MRu|7s6~X@IJ&yLX&mDz! ztRD=lJb~z}wHgXPtevE@|V0?ZL`aUmm?gH_3ACS1mUv=&(>LBt#;3^!Xa?x9|ut|ZaxHUYW-7>5a;^W z8tQsu;s)040OP_~aIG`_RtPz0PdD$oK@wC!UQ$dadx!ab2J$2CX7HTZ1$@sjFkY-p z)|72f1R3Vwbg*Vj;u+^W`_04rz6G+qLtP5SrS)2w`rUeJuK4_SP?P6fGX#>sxjW=% z$b0j$Bv?bVMRjmynh*L%+1hd}Yu&$k>SO(DESq=MAn$tJzx7Tz&hf3l{?`rWf%|z2 zDj+ip%olak-$^h6X2V+W9o9(m&)PaICii~ic-Bb+?|!W*<&fn$$C%#&)|WiUR`09p z%x%cZ0OLu&T?Y*z6*=~M&)wc#Rz{}2vp(o2&!on;x;ooi=R(g{&%(&K6N~}(A8K(0 zWErR0z`I+|@Y^7K*4zoX=9YDTKD-Iq#k0M(UI@zH$@&a_=6zTNQ!+=gp@%VBcxRI^)UvcIWgj zU>DqvEOki(-*3G%pNyqStgQ>qrp8bl&p!z6?GDy8hnC=M?!Fp<`>>vvJJ$EA&>i$$ zB3M7VBFp^#06h2keq+GdM!ydN{cdcii$8OH6tdxV*Q*a0XWIJ`oJ5}MJYR;K(LUA= z?{Cb#>7ZToyRm6pdVV?!^I2zX+VhrPZ)FQ@GZ1QztJ&W?Pt#0VHPk4CLk*c)?DW^>+Wi>=5}Mf zb~j)D1J=l72!6AUS)USF=ik1p1M9@MpuZckCMW*+YQF1p<0h=PUmpSMhPh=toBz(* z&err@L#k-1~a1)E~0d1q6!GF#nJem_1=9Knv4*3DD zj*DqLbQ^N4h1n2AhB2qFYD00>dd9RS+h0T9GH$JZ+FO0RXK+67KG1#l1pBVOxA&T( z%8G(_iJseQBh&ou1mnTa%8rBi@d~U1?;AX~7^_vlee1_KF!uYP;}B$-r}bDn6h^@q z$j90S;5yH5#*+TGt{U&^r(e8#z54!f760A~7r_0#4*K>oR6@pI;J%)PFu!@`$&W79 zckc`*f@cKl*nObh_EB@nx$r*l-oiXmpL*~ZnD^TMBA9dKz<4xg^r>?|Db^-}bA|Tv zysDhS=x5yxIy+a}Q`BAGIHOxPth;-l6|$^%%Ct_shz!pm_L1v(RvV{+Hp+sXpl)F< zai8i?jdjN5e0~>ZbpP){J_P;wy=NSA(|9(gLXKYG`%uq4tD6YsOD|B?8}KWbFB2e* zM?x%~LS8)U2Z3jZ{ouJ_4w&m-!&(2$dS`=hMmU0uVyx9(H?c;2w2wMn;rSbRzCLsT zW5j*CXKTE3n7(@uoa^kpCm>HuUR7i)fOAj+SxzTFHvzGfaUaW)WRVElS>S??vyDcc!m|g}YSnJ=j`OLR)5yA|a z$nTx^_rOW;+~X|ZJzYW8*>AM3xtN3u>&x4)AFP?avnAAKT`Jg&JU2O$G-r*mXs;>C z+Lcg>b=uXLz&`gkSZmZbf#qMY?gG?`t##%$76*WKG=J-YGQ1!93G|P;xc7U&98}(; z$a@mZ!zeftWP*2v_kg)$y!#I0$GG_gj2mm1eZn50TxYhIAdU6LU=nMs(c!#r99a+D zr#|-{L>rw0XEx8^YjC-XE<*uC)`7X`p&O%?q!Ub z|GtyaR^eVoIsez)Ot=RaiEL*=Ys*A%kJ`sxG!~ozUIlfu)-M9jJ=#eMibJa??1jdIxt_~f+zTX!)#)vg`4k$nP*?Q>T{@72HT^za2dHOQU zAl4OoS{&=FC(1DQPJwdly`B&B$5gO?EJDUour|0)`-Q#LnM{9#xj|j5_h%sFoPN2YZw=tvVJ!rt{2v@Es?iDKgC$ZMqMPaciJ=Q3=Rf3}F^AhMch;h7d=^ zkYOx62PIhh4=|>BLk4IEYe^mC8A}fX%X92%Y^K8kSOVI`cj^C^!P>MLx+B}aqtza# zKphi#J_^o*{diWt8H4s7`}29I#G3Fq^DBIBTx!n*Fel#uW!djmgSqT1==-g)r@{JA z7+L0y^Pu(XXV7LLzQg>iZq^rlY%DwbI&0Vm-v-Yn#*04pGnO!SZ07r$SgQ{%fw?yk zjOE9m19GgX=2;4BjpJEhueaXlS7!$I+JyDa^sj^YZ2Wl+)Td36wGOi3Tk!LhvdA=M zT7x;K4XuafopEE|)`xpQTUon2FPn3rUpmvc-{YX|c7gWu%&I)^FXw`@xi+x=#382+ zC_f#1hx=FGU!XMdt@Y+u9-ik%k(Y;Rq`?Z9jXXaO_z9*X%li=hWuNyfUmv;NS?6KBJh#Nvdzt+;2v%V_pt_ynNPv<(mpU| z^sjdJiFbCBAqiRD z!RA9oNoWauS-&+V!#bxe%~@kjdB%ahayGJ#dWYj@3{l7gb3~twL)J#Her6y?zqtM& z^kR)Ra$f^sBWR}~;M`LVhQnz%2c849O$E@$)*x$R7C0|{3HrAna_y1MRs1vO9SM9* zgwK&}ei=7|!ML9X`@wlg`GvsxVr^~&lVKtBM3^@49q#u*D2+^gY(Mv$uOC_>$6l^{ zb3mUc+w;0{)Qk1bHrm1Ya5Jd;oyZ%7EPY`;@czm=piFDZFK{R8ozu+AG4KpHf4E+s z{0Qo&Uz`_=$qm8FZ?)>4*Wsj`I8fExy_hG(1$j{AzKcF-3F=o}>JTm7C z^Q>`eyqyHsdN#JtSjPu|GpMl~1#{Ebw`Q+~wP0Kg0DEu?NCtCq9VpLvq$B9BjF_x4 z$Y=^X!I*STSPh=p<5*J{GQs_N1~>)Ex`y@EH)GV9!T#b|a{~Laj(i5cK??si7wj|E zI_qf-bamEi#XBAYXYn@3)L+J{vEW@w6udjvW_||idBr+(D{GxQtYgN!GlYF#IZNRa z*arH^S=qQ!XZO86_B~&6?nUPE^(YiWt~wTGo#&NXz}jZbPY3H$sQLCo^|Utme~)S; zl#9vpbGAM(6FMO85%7%l3K$pmLFWPWF2{O(lm^PvSK9dyXj|uHXFTI4$$umBS1?wM zf9s2JW_{5f2f=fec5oK^0h}}JeabdgLx1v2ZGASLQXmx)km(uKIIp7Mo#sKvSM6&III|cB=Ho(G1V@k+YG5zq z^akx}U9l%9cQ=%0eIIxZlxJP>+%N$?Le4I*_v#z#i0eJ?e+t^tc+?kTA;ge=Q7>cZ zELiK>LOhsDQ(+O@j4b_ZzMJdYz}jT3w(hy-Enw|4rWS&+Z#Rd5A-nJxe{6y9V6%1u)i) zEp-iNZ|jurX#w4#6LPih0qBLiJz#A10OhLhY*6+p*a7xCeWxAl1G7L|*jx94btTM{ z6Zu|0+5?R%ZQ=~z9CiSXfwJ{o(EAGCYiIAm`$B$Xs&_Nk2)^eqIM-|Q3dp@5jNe(v zo5}hxw=amvHO?9$%ews*Yp%fS=+>4sSKtZOnVUsR z9DIg##>`T6Vmhq;gi)`_ZM-8F`c!==bF-q!N_Pl5l<$-m$EdN04T ze*PQOP1`Qy*^)eDF8>JTSr=q^K8S+(q+hJzCwRU*&wmBhyfo17=9Bt(UuNE$@8-GZ zq+~b%uFqz@apO!r6pWov_cya%8;1K%9?h9~68Rd1sjvm?pFhUrUEm?>MUWBh*UTx; z``#h=S+((EPNjkSH{P~FN!C|~CeRN&KO1|-j&p;4zYV>rf;~jrzXjSzUA232WOjvZ z$kV3&_hgSl5*RCqkOHpNMxGg*4fL0K8G}VxZ=UHtXV`xr%en42XgB3L)6ECtxfL?( zo1vdoLdF0n!P@$;6q>Q_UC`#3z&O&^=@4|f#P|BnJsDH>1a-x)D|kM)uDNf|!;`?7 zM)~@?EOM(OCmwo&H7D#tf7mnmQBH01{8koPz<5yBOxO*Fp$f8`@1vm3#_>upw~ZZr z6b~;$S!9MgOKV11@DA!2oB-p<7_w$qyONP-{dJxzi#+XM4f8y+9rl3r>=dZ?NU)DR z0iH#j5k1>=h6HeCejS|g?8zU3wswB-?$=z@4#tG~AA)m`gj~<$=A^QmKa^9A_4k7D z{udbY`foB=FSo;J)=vlJ8XLx~`S}2{-UIIqdV_s@G2DzC=O=Y@9y5ouud!h7Gl$HD zg^&gI8go^d_9XkSdRB+mz#3^B*ux)&r$Id@z+CWbn+58d2U(#`YHM{i-oh;9d0acR zN9N<;XJx672HLkFvTGv8-gy|z4{fO(&%pJp)dto#&mjH{^@FVK32#FtIG?Gnapw7B z5^~flKyw@>j9_1zMu_vL6~R#EY!T! zhAqIem$ktBt;~9T^flCCz5P<(8?QBx(FKCd+^;pjd*M{pCh?5D$vXQym}BY}g;n6^ z;{H8@eWEQNySU$Qj_=6&DNu~{)+hIAJyAdJLfvl`=;P2&i}U<$eir7g7m=$yy*IE= zy#@BVTX;^p&I8ZN=2p08e2Vw^Ig>rXUZX9HF?IEG3iqeY%r9eW6BuvS0c-eRe!m9n z6UM_-p4DHsAVb~N*&KEM&7e0}2mL%zKm7qeBS)Lw%KCLNIo8&O@CjH03n51vtb=gp z(1o?;cs7(_y*gP#+;4x-FE4^JJ&WxFXHRRj^N0Q38fx4)7rMtNvh@2h*a&`J&=0vK zSf?!}!YojxJ=ObhYe_rgc(3^_90z5Z>#1Pv*o2(!$O(7t?$`dJ?LGv1iapA+r@eL_ ztN`nhd6Nm&{Sf2U`UcPx#vn_1-?Ls{IYYR9F&u!3th2^jkE7uHr;j7(rM!AzZPUNj z3+s3>eyCI0Dwt7VtP|r#Ha(wT~OODZpbnfB#W0rf+5B7+04;n}qZ8HomvM=sWYk zI8#UM?TlXsIo5mgbOBg5s_=VjMmo4gpS#BS%KUME)+yu4yR2E@JX8uw!(6bJI6Joo zKTq^L8R|tTj@8|>GyXY(HbunbAo3<;6j8X6ucn|3ee;0B*ds(+;Kri;|XIy@+ zoCasX_*Y+ZDd@M6wSJyI6x^#l#9CAxyn8T@JS&CzVGMh2(bx88<5nMR1%1npB8dpbfNd@QXIEhwvrmoHLtm8u5KM51g-$LmcaUkGhBYY+Z=*4*&a$>EN8^9v(o~p70oiT(eGx{%YP; zM5cF9`p=v*KD6~&D2FWbOI=$bV>z4$_ixObOV+|S!P;+qQP!`Zo;BeY_zje4z8VXy zARd|i4L}3r`Cj|0@n(FOSC!!zSOOP7{jI;5ptA;m@ADmXU0Z3+(T5X2drt>rdLZvu2i{}U zLtYA4Z}nROSTB{OzDGd&R6&;U&9^yssm_C)!5PLr^a~6?jy8AZIS=lCDHzYz80A@m zPk}l*ca4M@pnd%e!8+L*y1*mor>>z^?BaWSuQP*wwSRbKFn6xu9rl2SU@zRjJJP{f z!ui;q{sL?DlQHf&UmN*e*WJVSQNEuB<9!A~ZrZduv$Zwbn$QH4N!@*)^D{rn`R_fp@YOpm zbIaQE4H#d_wC;3+bWr!jpiPux&(;1@K;K!@roiNwtn$dPPS|tpx8q?h^gx#9BJEpeN?63R5zmF*l=8C>Afc%2s`O-enAC`c#gzs^_ zbbq%a+cS_d?O&mf-hd461@^)TP?oi{UTmGSk9pkE{^y*hvr+vxwBf_hwDl#`=&0%5rAy1nOhFIm69@kXz1h#!EBS zN5Q$~CCCP6n-usNLVnq6jLX8v{0o$6tR#avehL@h31p4}>x{lIza9eb^nxwZ_@AtGj%+8_Or+P4s%%B>L+W1w(SV^<3~W1JTzp=Cvl$QrN#*n@Wxfw;CI)?bM&f6QU5B3`S@Z(?(8T;DZcvAKw5YDN}_pYaE z>>Ykq_gWh;}YazjXru3PJsPPJ0`*B;LPm3lC{8fJHcH04nnLuo391+@LV__w4r?>9_$bN zGv{xswP7FdbF`LV@3L@9vtgQ2ml%G=%-CXIbQ0=Z(umFpl)M{@4fk zkoN(2=CmI!M4oXO{M`i^)-vVp2Il}{%DW+LP#zuwb@aUXE}R1Wt6w~uC|4ib+m?Yg zFovu-7r+_D7)?aZ8E{^-2L&IiqkguAJ4;y;Jv*7p&IakAOk-Y~8Z+ji`R$x{9rC=( z`2_6YA%C=`@|+n5!FbpSV_2`e#qcE@1!WpD>S>MArq;O!kk=MkvTiV>!WLM{^Zakl z{lhxGZiL^!&kXDr);|3=AKruZJgl9kg8K>etpx9|Cv^nhX+0=|oH1bjW`cW)Aa@&R zBkO?sv97w-xx?Iyf_3RAoC0IO9I_UL*mYhg1?Hf>*~D{u!5&=)JTC;lEMT2+a~TTp zKJPwiv&OnpnD=U{L9zGOK!&oc2l~k&aD}(vl6pU^Ck-%E( z$`Pu7ZoM!Uvmn$BV_lybL-t$e&7R2J1=e@{VUL*s zFM~E|1jbh@upVE7JZ+rBfU&Nfx*=;Gc;BzwSCJR;aX;TTK$bD0ZIv^C zwW(mAsKa{a%0GGT1kd@teEiIuSH82*F7PbT7Bav-?cCz$Nza1kmLjYx3e`XzA4Ik~ zRz}9%@DF4Rfj8keG((O$zR23Qz@GgM=qGE2w)FEueKiw|N$-$D3>09kd0m3F-jz*- z)va!EBob)sJ1Z&oP+&ayWhb1(mLw-u?{qZ zgZ*P-!QY3U`wr!+ zw|8;I={d00Xon5Rb`J9lr|$NmIA{&}Pg_p~?c#iE{qsHA*Sg{?(I2c|-UnNEJ#;I|22F`=` z3f`p*f_d;fYn5XTeh2m}^Y1p+TK6)*K2wUdcY=M(y?PE*rw{|q&GsAp7HX>X&@=c( z@IA)WdC;asc!%d$^TIk}u4&u0V9whU?7P+#ZJ_Ta#q4PfDS`~`Rvq-exsV3-EPdrZ zUO|R2W_~$~>nCNchaVus?(N9cU-tE6WSa*wU>?{H?4MDX4QIhx>|CU6)YJP{ZQ~7=im~YmIfiM>Ifp#bj=9)hA9opad(7U;iD=YZk{WxzM z!%ss4WJbZ+e-q?Io;EU<$AK}j50oA9#5)<|O(+FCnU8@0nq_y){pbA!htN5J@ZZZ~#ofVD>d84K#x2ztQ~P`?b=0U_p$ zX={&vzvWpV3X@pefc}+LuaSgkm0@mkMI|Szh80x?pwLe4N;f{ znP9$zyyA2m7dH_ugZC%K zd0()PnBUeRd-p25^p zTPR~a`0NRub8bk3e?e(}HWv0lO@3!D{SdZ6ut!1UIa7{<^`OoRA#x`&^Rd@5>{d?93x#?NezccY1 zwiwQU=diuV@%~>~HQ_I)z*^(MdSbm(mbP%;)_wQhjrCD5$FsmbGY@&@hI6Iybr*P7 zVLX@*%JFX?oT);;|NpZ;RX`{E>QK;rWzefCSl^d{dYS{z$8^-U*5i8c0BB2f_I&8x zozeP$I%~JD;bzwOdD-V+{#(nnSy*fT^zUk1Z@qNyAtw;?zn|}=^8Lr~GxR`LZD~Kf z2)qAwc8|W_9DNE_fj!1r=RT)^e=ng<#>i@9s7Eq#j9q8Yi(q}L3bnyn zvIthdMYw{zn~~$)a){$7vaJ0#BFp;b`J)_iI)Jl{ebMuXwa$8V7R>Kb$nw7XHn8rS zd*+*ShBo(H6Njv6Fc&mnnxOW_<4xmn#_|ZnzIQtY~O^8kJ&GcEYyZ0S$!Vd5ZVGV8y#)dWv zbDVoMPlv%cWE%&{ISI})huHFOuGEiT<@~oX_SA;pEN^_B2WwA$ z1wvh`i7fx`Ho5O1FcOTrW1tUaL21_OhinM5dzjgOMQ8m|3YqF0 z^mVQ|4)$N;BAsXSQ8|8QOegvk*{xwQm}fP3t`_tM>wz^U4w;?6oHe#Hzj)Y3x8*aXH?kfomP^Ghg%9Q&Cu>F0jVXU?VG6?X+=vmDQb zxiy8~eFgqJk@rjmXRgig321-+zCe3B$3Fz-nYK0`w5{>hk@px|o;5Z?8J@ovx`8pE zJ)A?ffi^h|p?9@n{lb_mZQ%JS}^73++B-)&8`p5})v&;~z(^MN_wocI{50PX6% zrun2S&z0`O`BJ-Hipk2USv+eDMnPMC58k)fFFpJ6XwKgP_u*?&Y-_j^t^ zZZ?BGT$xv37&69zdkQ&O1$lL2GI=CNFME?UNgq`OKeN#v`n@mM@9fRa8s0m12kV@2 zt08LwDC=ghM%p|5OvB!h%rAm{I`h0S^EjAm?p3|c03vei)QGR%Lz++C!MGo7+m4@m z{}TmsaSxmT?}5C>Qs0uSQQvTv-5;!q_p_^|$k!``6#0=Y*PU z-?HcQhgmQm)GrQs?!|l$`D72$_Y=W9^*rGFtMl(D|K1G0K^#AS7d*q40B!y<7;DzU zZpc^v3s8ggy}|S2MDU%)n)eOLbuaoN5xEl}3fig~@;$>}T@&UY?=3J^lw)nNmp22x z&9TEdzFJ4^Z4=-dI1iOs;~klGz*(gp3(`TK8oSm2b?FV(e14QOr<~;Ld1#5u=imh> zhCI*x)+&9jPUcl6i#Eb;a8@peoI&83r6Mw%6Fl!7275tWWX%VC_6+!W&5v*^vW`P* zWEgkubpeF?Oy?MFHylFm=!hI+NMCy|W2_rX3qfC-=gzvxFaeaA1;$nIMGgKJD$s zigS&=PzP(BXQC9C4%)2-GR)(hkjUC^;U?CqOA5>cZRI&|3UcNm!#Q62?}uwxR~z(a z=uyV6@6P~xm3gmy^r2_(O1#%O$M+lC1Nd1I@NLe2i`9jnry}n?u%4X)?XwZx)a(DX zcjw{0kM;h?Nit_jwP}zc@~gH&wGEj{9S(M~6>+dPnT`x;kkpQ4tRvZR2qjWf6uZ=> zVb^w26v|Md5>Aq+V>i+Cdp_2+KG)?s|NZ{>{rBnWdDgPl=YD_g`+dLO!+n2O&ZaT! zADuiJ>fnZPKv-{&Pwpk3>7)0K;d4a$C~u2D^QLS0Tg)7qEpv5#ac)y*hWo93`~Jvy zSE$d^!nuJBXR8YvZxQrByK2rd*;qTQThA+Z)7WD3%g%z3PZtF3nu~scFNd14YIfXZ zSo6n1?q=J%-?{P%j7j&bacuKaXHFid@DG&E$@_)a+d0+R9 z=lATzabw7-8-)9*hvN_7&c!^p40Ust49EfQNBB?7zH7>^`F%6wQuoHgKB^5gLSsXG z>%rt<`CQ(3OYgEz>bl$^&+QjJOZt20&8&ewua7%o=t&m${nFW5DGrQnvMCSiA?U*1 z(jdR=mTmQT$WJR|d#l(t33qpK4-^v@C1^b7E_*5I^qq}-e4DJ!n zSM`jZb#DAH{u=gM?A;&o6CXN%BP4oJfOTH0z z=ApO$VeldUv&WBTh5LhNW=Bk1k&Q3Mu%|!i`9XK;m3PTIOZJ}CVrGbOXCCk2|C{5s zpgVPs*6aZdTe}=7KgxriH=i~8nZCfif%C?U-nCD-i=f8?d){Xka>5S1&$(Kio!0pG z#~I<=Zw^n(9-H*HU$#CLmxg^7Z|-i~=?)sxf6ts6JIr4$;j71Dh3uHWxkwDV_wzlne`6fg?@tRknGN%JdOxQ-dLQodmh2g4T=nO~m>1T2chHo6U97z?+$F4# zEjdr`qMxE|>vZ<((Mf%-&{zGGI(=O~d{5)}h?dM{wVr)ZyfO|7dqRtR@3X&);KAxIqlP)a{JoC3c2&^Cb=2=ZSbA*pvhHkMg&8XV=>0 zI665i^ms#z{!icATY94(cDD)|x~1{oYrMN^Yi36;PrGzD?_*94y`cX&a zpjCS3;5#+<67`>x;BcFLq4_V7lk#_i~Kn|J8~xfuGTpBfY-;J zp>NruaeKvOaZ2OlsE>qo*eB<;Rlm+;!?bbfZp)&8KHqJ=UX% z#lzy581A0E=U=Dnne#T;av%Hk&}0218{*p8h0o}~IvFSW@E(1!q7*lKWk-U zgK#!}MaZlAAZMWO$6)IPy<5*ctuf~R&G>fc(TDtLt}}b)O<}(_kBK-l7R18vUa{m| zde?=qY<4cl&VG&eIksFeD?Zt?>iE-oMn1J~{HwOD*Z0nV-s#R`w~)K(T`%&io}V6a z_=~bF=NhlB-4e#BYwR5#LoPb8u@kWXv;wKCTWm{;H`li~Gvg>XlxdFP|I7hdTI_-hFiF_1U8J*HzJapx?r>D|5% zwB+-q_lG_44tf5V5MN?h|L0xHH)nb2ZQ1s|XJ%6`IpoZVZ0R5Eu^Rq^;9q0;cZU$8 za?{E2^|&F-RUY8ev*U%?P&?!)^ZZzL#HpB(Cw(4ZuYA7g^Ah_cN4k3yyYqrCu8c1Q zEe-G3CVRI8T`tJZ|HQ%BurJQWG^DTiXbk%<=RO*2(7HNDPxj{3K?8g$CN~a$Kd8RR zr+oRbu>Rr9M(b>UBJ>LKoV8Abo{!(`xAUVM@!e2&)iyoG`@vNG2zs6#PtM`aUG~I0dt`D>?`b>@J5TCs`TWp+Y3wV*o}L@lEe}2zG`D^> zhBL5O`*6H5n`>t83-R@MMz+MRSmi_K5xV|Bur0TUk27L8AMmSnPtP8|>aoQ0YT1_m z7l$6{4cU{wuGXzLv3B`qwZ_W_*M_=izwZxob$(hs8()v_ z1>MYOyt%Sxer(F&KGWMO`p3!t-N8E9Ft=A^W4Hs_sPS(I`{FKvU*%RgLCmnJ=N;y` zdiD+sKD|7<>K@IUAGc@MdiTuETjRp8-e)&{SnthKw&Yj2i=AI)!(E#Dl{3R#9_`uN zA*Wo}_jiXnvN-+`{Lha0oEh@;+e2>Vzmu|IZ_jKFKI@l5_{p8%Sz&E*fwisC_@Uns zYfnDYKQ&uw)po&ua=sqlIb`FwCB(>vy@xjK%aYmLBjke5WREWN!p7N8Ib^4xXSMtV zjggbh?~<^O)l+3#<$PUHFOD{)WI$gBhbz zJ`-w)ddzQhc1nCTtl3<)3bnyGLfv^h_H7Pwus-3(ArHT*@$OpL;(v2{Z`kiIhR>e( zQ|$67?Xhp2Gh${;gn81RKKY`MpXFvYho0W&s4od|EcR$gzOi;bR72c{oEz$|y5`Kv zf6nJVPUuoUFK^TLJF__v_WuX*NT^HV?z-4HJ9-au zz9~EI=(o$psX^P;ePJBj@A+#{$WMdcPV0HPwXV&BR@8L+GZFS#U6~)&?C%22OWj;4 zyX@cR9nD3aqDgsw$8f$nJC@46J+eREbw@leTc3=Tv$J8?8(QBs_KDkqFYWitY}^q; z4=bO(w6O<?w&EYHcs##z^+VJv^i#nvdl40|9~S?8=6 zdcrNTrN-@>y{qC!VU2pDiI|=}J<`0O@5M3n*R=Ax##-Cz#`e3R9;%~<_VcgC&EYxu zl}-7ICtL@&(Ds2@Pomx?o7lT`}SCFcyYFT9{wL}#*4CNPc92*>I<^@ z)A)0!oiB>N#=EmI)TD)d|8T6IJ$25S=Va@oaCTcGJM#2%vmxKei9Wx&H)b?$hj7k6 zC5F8*Pv-!BbpB!UpaKa*)cISr;GY}SNt@7+uSzGhCHqRHNU&FC->Wr zv*HusF4-AGteKbnpy~5tQM@NR&S5u(Jr=*})7L^R6~oVsjYAyY8DdXXjH zdNQ7eIv@t0h-YS>KWAlA-kQ;a+s8R^Wqd2-?(>2##I>5Q_qR9vdQz;Jtu2C{oCkgo z-my)#-x2Ed&%(RZpvyxJSEuE=y<&LJWqq&zvUl%{{j=k2VXrm{8c+-G4)OTsVD~B6 zTr1=Nz7q3W#cP7^t>MzJ4*SU8=4tQPK0VYjz7XF#h5V>~Z6C(-?U09@2h^6sdS3tV z`H<6}*_ge<+UCXOF|Dy{g*nOJ&g1vTlG&5zHpmvg%?UM7?`5CGpZll7;;5egK$r&` z{G&Dvdo9v=JB#OL zi*9|Ut^c4i`P$#d@qzP+opu zoU`k2cGjU8S-ZI%Umve%@76+f1+e_jT z!Eby<|3e1=)?I$9@A&}8=9Nr7eR0G(i+{qizR zt0zzH3D?Q~M9BZn6>Im7;auUK>swEHhnz=0<}Kd%)_mQe%n5U*$%C?UUWfd z`kSHlf4K41DYx&_SaWz=4E1Nz?92{&qR9=WY|7Vnh2DlX*}Xc<>p!z;KD7D9m=kZ0 z<6~|toqbweHhcE#wCw1`)O~uoD(us+#)GrBO5?s2&QT{d##ux@mS+|=mQQKY_~XKS zhC62ck#n9Nib96! z6n_tSaoZU3{^r>k@~XSmW8*LJcy^X-ENu;UDAvGd`nNlR@8wkbQpe>7bNX{UHZ>3W zS|;R$1z{gnYaCz5&3YgD|HIU{3mQkC-tY6|x5N>lALo<(;>my0Azsy?>*E)pMlOz( zvPrZ2c}?8VIKA;ju^@*2&@;{?^!C!=NBQj082TVOprOBn+G!p3bm#2M34Mh8W=;B! z6Q=yIeRlsXCgQ%(cU~Ok!!L(~^OW=6s*SZbG|JC2;B0Ho z@^BtMIveN3rNQp}c=Fwv`r+@}w#n2#!)IeN!e^dphPw9h_+dO8M`V*eN^Hm&WGVO`>DdiGu$uZxM0yR6}k zP;cZpx!Zo~?dZ`xi}+&8JO{1Fwc_>hxHCI^Z$A7n|&a=DK0_oGmB9=MLLs z!@BjMa-z9;PK|UAwJ7v~NA~-7g>%scy<@*PEA)2!B_HzhijB2Ky~DdgPjXe*_rYJ* zvvFJ)>#!FqWrI%T6n?jNbgG8CgYs*;}n~ zd|=M+iywtN{Oho{{OSBH53L#e_s^hKZ+sO%8maXVu@WgADXgfF3v*F?fHYk{Kd1m+!@1M-q7=M zKc83+e~Op2n~OR-Z)#q8!u8^TkR!zKt9vgW)5r4~!zbo3BkcR`!S`pyykK7(@D+WY z8?-6=6;5%n~z0I%VZ?Q?^ z|N? zlbYDJuZu&y-y$1BT&+1Z*1ml;z8U=USgg``b>f`H(c|~Ry`kKEOX&OPkrq~HKKDFn zPJ1_=Piafeu}1!rpVdcs@9l9yoFAW$WwNdI9vd`AZ|BDqAy?cQbhbEVW!IcnY}~72 zn-IGv#6*}Y8)DaID)Ohk-)HBi#PW@OddU0ycUI8f&9QRxbDq?9o|r9r{_W7~{hw^U zF6_tMu`s*qX3yR_1ITCJ4LQ@^@FgEOSGeEOYrAW{E%dMU)LkxLSr2`h0}aY2J~uib z`q5<0vnF*_j^leVaDMONdp6`|>u}B<-n~TQ)rSqUA?K?L?~i>NOT!n17`Hg?~}-4c3MTA;$0WZ-4V-Y$A0OL ztZ#bH^4*DH9@fJzbYvZBfN`(rSz3AWSUKjKL6367`{JdIbq^=c4Clr3`~D}vUSB59 zD9!`38_OU5KJ>ECH_$p?i{n+ZcYHWsSns=IZkVUq;{NgS5KBvCd(gf)i$^(eS~v@x z5EJ1{eOnygTAtH8AqjAd+&$i(coKW5;dU5CwrgSQ#RMiroLsH zesMtPf8-+h@}}6MvF6SO&CQJcLY#gm%y*A?ZmK>>in&{5vDDczjsT zQ+n?a;jH$Z_+Ss|DdfMs8mk6*@5YVSm&>`{Hzy|IpvKU;T&o{fH{=|7)m#pV%fnh; zmK{CO;14l3tYe#O?H*UgUfDY=^gQb8&DnZ?<3A90hdq_kKN?>S=RGxuKkOf$_5$xHo!N>9-TlPv$n8=R(Ul8hsdmK6N-(rm^yYlN(vblYn z5o~=i9*a$~AwKzyfB0o~Y})Uf@%QiN^TIh-jQc#sJgr$y{Xv+cy_gpZ!k+M-^_r7< z=kI3pS=RgR5NGCeUdVO&==~ex9ODk;tavEc(wA-)>e-&*K208S231Sw+@3y?jp;pa zKHG=>@@ug|WBKinuvYzz9@cr5&K?M{^QGW3{lzK(%ntJRc2t=EXh3M~}uQdiE{7 z$9d}8pzl3}|yZkL{St}xy{@u@lUrFuE!Eqf&o zn&*0r6)O|r9{aqI3$F{BG)F$50rwJmFZbFT#ST;U=S{uC{N53CLGSL9Xk9MTAL_Bx zLvcLJQGS~lYOp(iD;sBibhJ-n{B4eRs~6TM*KON#>gS<7^X@n|?CH|I>seFpJiD)Y zyK92RPU)X%TdyOp@`?A{8|L@=m=(vyg|TMO9UfndXZJk)9~CS2-ZzH1swvj$-Fi$K zx}~v)^xREhj(#_-pS>&Se`f3!{HkuLSN2*yS{%+Mr-hocTw`Axd~$QJMX&lT@6x}W z5MPV^v-R@ETdQ93`;DL0^K!5HN3V;5R(A<^_i_sjZ4leD5fia6eC{}$&#un4-cbIe zr%%Rx@wx1YCw^34?DfHMdi3i_zrMAv^15}O74Df|njLo_*N3&!fF9z!Y{=)A8L%OJsL=m$}OeLmqfj@8A>f5nJB~by&^xcX483<2WYd zD(_i7ti>Ixd^jh2Zwq>#h~Ye-*75njN2Vrot+<&Ja^r2GAJ->|zZJ8!W$5XLx_)cl zKN@^vAL;8IF?@c1ayI;}jvnUYp`SI^i{sG{4_^;@ogVVcaQAje-w(E5K4n)ub#F*_ z{9r$6iyzhr_ak2mb=scF6|czt^Rl&d%nF}@sA=vwP4_>8wtt_Ezr_lTpVmYB#6fX%*sCFqd`|S&SUX!A#;!qAdS|-YHs%C> z(3PHwT{>MZ_K(ZMKJlkIsRvjuW`%unhMC!Tb!yjmFq{$W(T`)5#$OtHG~PT1U)pbb zttXK;PK)!ib79E&KEviWwss0R)n}Z1X#Mo5_j_T;O;5xdvT3e-X}-hi{tU^h-YiFhxU(;PV9FNhB);ZrT2Kwd+rahFSl8{ z&q{9(u`gbY-!9xCIm4bEO=t4_dO%-4A7WSzJUIA#nUJ%@hMv$`tU>*f3(Z>&pe6ke z{aAw<=wfxIvfm``%tJ-*~l$&*+mT z=|{hPcdXF(*+GwIhq$&U>t)Yp8)Dp^DIzRUA2mU_old)YkcMbb{NjBM{ z%M;^_pwFL&_1ou58?Qd_pY_X~4~07PoovX#M}{8nEAd~kdgHB~hRsdgT{+a;gJXrp zs+UJLUav$e^rY5J#JrFTUe+_$#_d5F zj*Zj88g}lz^2*%c3;A?<<6jnh!0so5Kl?H{zv+!L=IwEQh*k5lH)@bI-xB6wKlB;a zE6((@eCUqix50n28h>bbzcY@{x@qWhVSS6koOTGgXjt!%KlHl~#lzu!eVOd9_HEoy z=jAo?{Bl2gBwp7;KZ-#&dd}gF;OEVWmVecAyY&noSkv|4U5mqe+zIR+G<{|?Y>Ab_ z=iO@eaUoYZ2gz3lg_zSzUJyHFhrjF_UpZHw6vH`S+3e_b-4F5kTSK0<7QM6>aL+wI zz8-AYcY3v7hX#8zb!+47k(zr&&pkNxycieX)<7et#KocKl?PV~^Hz79wKi`20daIJ z40-p3@#e5Mr^LK)PUy?zzi)WWzUql5;@SW-L&Usg!dmA_Ui{B7usWUvA=TIXR~2#i^86;@$tAk_*K54<6RoJ zZ=4Y9nG<_!W`lqItpIx)WKWL0EeK#?sM~U^`f*XHQ3q!8z{Z~yPtFJWvTdfuyFc0` z%!~ev(OvKaAh7v2yoa$Z6H^$lziW5Svp%uAP&XMz;n+>@} zp1C4!&5qn62HE;b$RYMu%=|Kb73wA%J}Xk66U{nf_5w>d2edgfo6F+cgiygn1(iW_@YOzQ!?&%2zFuMeLK zu}g>YwE9Bdp1&-v40-g7VE>XZ{?U*})G6AM7oMFBIs2NpG5r0F^>2~AcZPM}6m(+! z`Xs%s`I|SpY_6NFQ<~RsKXORVs(td|%R)}1OYy9yQIF+D<8KZ&oU`eExuCVff=?#G z=LhsFXKvQ~?Af7lcib^Gw?FlDiEOMGJA}2fZQt4dNBH-qsQYrp%n;}AYZ!luPjT&D zZSQcm<$Na}e?RVtp^q4RNu%F&WzKt`N5Fa{t^1#RIC zp3xlDXTBPItdAUWI{OEQzPiUJ{}$!GzS_r4LVUZYp$+lawdeSh-Q z?5rAkVtL@0xH#UJjnm`*^$tbO-Y3M0T=Smnx>vX>=vrTUL&!B>jQheFn6HnC&jhW| z#)^&iw;g|oeHyzU_*G7zZGPRo@q5SHL;j@gqk~_s3~Qzf@upW&uk`Qskbk$06Jm&) z9kPFTcGa%a!#nubU5)zgjIdW+A4_F>*vBD`*3Yi<(2?Q%?z74n;qUDBjG_O$t?%`V z-wA!b*rtuY#+>Y`XP1UGn7dkLzHFKEL^#X1yX03sd0)sy;@#&q&exv_zPLHWwcJBn zKIiF2lYNQYZqH5(IpmC(ALjVhY%h^bbNqRTm4`yVC%0@6a*NM;?3?wQ?@96WhOX6k zwPLr>8+<0*yL=_gn_u-Q9}o8-^eU$12>YcEJT^OX!+IYHIcUemvbj?8pj-3#T;u8f z;1F9MjUn%tle2;N)w>P%i9TPF&)3M7xYYxi*V@_JE976feeG`ZF8-1>`l6*7~ ze7xC|ZTs$Sc&l*s9b!zq(imgRCZW^T^8L;mEOV|&gX4D&ueo1YB1+1&zd>pkgMoY2}w z;y>f>G30wXenz&}2=Cz27iUN8sa5VQr#JrgDO+;WpF{6+RhZ}8_-G9C{Z!x6z%?

^S&?^sjPTp}uoF4ZE&HYF4<(465zpZyn%Z~jY^8Wn3mrwsYhV?I%U3rRq`zBVl zinqm4F+bEUdGOH~v?dSE3cmVXESb&cguJ^`$h)g#k6+Zr9Yf!tKKhS4ksV@o{8#)S z#JpU-FvR3vLcH_Yg|SyQ-xg|)wOE6G!Tq!O4>@Di#_SY}`u%^!%d-87*dl(^J2vij z?noYszr_~W-Z6HKd7-{7+qhHWyl_^!C1`xO_tu}ty$@vbolo+MK5Vtd8+T*e94qyl zI6kiD)KztQi?C0_eKsA7FMS(*^5ecCZm*7Sg#OKE8qSUlos5fn`?_K_x0tdmUZ34B zX?@4oC)Al+;`gy-whswsRC~le4T|NX8|yw)j$9COmgip|=B7T&TmOi4dwz(w!AC>> zvM+iram${%r{7^`^M0qt@vO6nXZ2)qoWFb9J>C?2B}Xib?}dGv$i}%-bNWHH{u(s5 zU+9@>`}Wu}dvx}K?CcdsH1;oH4r=FT_UGbY-wr7~9`twQsU)Y}94eqs2#4fkC%y;i@| zyl7E7Q`=N$jcwio}4r%Bc)NTJyaj z4~UODLyYpL^Md#g`)r!m8rh?@Ss@;sL0=kb&V}(n*sFibrv69m@Qy!)+Ce#MhzV9N9FN<4SM;HX!xX`e8VnZJ~caHj!*9nbJSznTlM)X!AIu2cH^DPUe~z2 zW1l#uv2wfhetT*za=^cYe8tXHp?6Z>cMkuX*h90!$JXX=h|dpkbzX=CYdSsTY&K|h zLG003_4{d!9W*wp@AU-gfmjklE60jGFK38NW3A!w_(!-)^Zx7Nh~8};?s0rZ#xM5M zeB>ngLJxgXHsw&Y^V;y)^cgR2ocbZ=ggzq1E& zz&#-bzR=Iji!Hxf(9itG7csAYQ!|`JuZcymTXWEB&5bpC&|M;cNiXkv_WX_3>e=KQ@nH{NkPUhK zWAV+fUb>abCt{e}?8Yt(c}xzY`A0%-c6W1Q@Dt726Zu)}em~f-Hg`Bj#+>X7@yjOd zZj{|&@A+4)w`TjjUgI~7eS+^!4DYx%=(R7Cd&URewM(`x2&#Ud`@$ryf9}jw=JMZ>6>do<+7~;EcC+&#s8F6;V9qx!94sodm z8Dd;*aaMg^@Y~$DF6`ry&B?jvyNwekPivgm9?pP2>wCFJ&N(zY&VCy;&faYwV*0jt zMmF?`{N(?SnHoqNYPcJaAEwy%Q{z+K#MB`U$ydHC=xr9DV zynZ{x8jaEFQ+s}T$Pf0=`N)2)H8m%-!QXt&i9_O?aQ>PT#|OR21w;Id6 zA7m%wE1D6f>cMb66tA;Gyqc@IJs3l5y(D|vhR;yVQ!dgE%86?>M(=ZR*qap^cSg{N zI<;rd?HBKjJ41c?a>&{A!EZj}F_!}y?;iWUcy;5=Yjm6>1gO5%KYhEkl=N+=E zSCp^VrKR&j4q7$4e-6H;p`rHi_h8dmaCRISM~B?-^YD!K%nrKxUiSH7sebn_p`P>S zDj`ZY~H3ulM5%!!FmJD&*a+B?n)>lte4 zYS}g?`>IerE!GLXw9nS(+)P8(Mwe=We)^A%`EI}WZuOD==ZAWv4(We4$o{#pT+fPY zwdm|AyJAR?j|4x6o9*M^ z_;j{>Ms`cQAvb?E6%?sxKc9-lK>$ocDLaf+hK2yWR_SQWo zu4#%-?bk#^;V&98h)GvdwM&FnQ!+xyS_(MWW$Xm`4de?WvH{+KfFa99p z#Pger&-K+VIoCU`3HowYVxN9a4YgQ}mtU=Io5q{t;c;BJ|8{O&K6`T5v$DbFf}qtQ z*UDY}deZl_uNJVkN@LAQ@98ridBu5&4LQo(oRNMLe4sy}o9AU~+xTKOhzx&9e4|&@$N3Fcm%V$0Hfc=lz|EN_C zUgqFscUt14Sxe47Ww)bN-EgNRcV2gglMY^f)>GcP=}vtx+YeXUaHpkaExF|`yX>;# zKl{(*|Jf;fr|teBVqIcxe-1P<`e4++sDV)fqXtF|j2ajmS}fefjrqe{ysE`OlAUKK|by%r|%Me|Yue?LVGB`u3kU zS2x$cF&}+$^Z5Dor_Y`}`|OwB{(k>=b9MLPr!T*Hef5{W>%VLt7N;5PPlzsOy>e}nNQzx=#{gg|(dmG;1yw<}x zm)-GGf6{mEaZKymc_%a4r90T9!(THoN#`u`M_A2c*ACsm>1>?yoW`A(_$hl|I=^$B zQ!lvYCok#kK9_MC-j$|ibay#0n2m9sYN_X_j^31mzos&}gH5{YKxXp5weH4fPIqM6 zbQ!0uj-(&;S`WXqaq8*5+q28H{`UP-&SiHpc(=0Cj+{=-!B6_Gzc|<7w8Y}BGk&^f z>YQ?C{3$cNNxy&UJL^w5_s-qS#3euJc#HbFgTrjT^PGmRH76e|b9{!cGcifOB)`+y znB*m$->Qu6%;MY_^>jx^nvQpx%RA0#nq`L1%3*hm)4;De`8$ku=+5`y3BwO!r#m>Fj&T|?>gf(HP33jxT=SS) z=ftY6yY^t8xaCg_x-ga3J#o-^rYx8v{=`n5Eq}y2!s1PCYLD(N!&>5(>CUV>JKkx?CNJs8t(lmlx6DI%t=GNNX{$s35|{LqZyxt6r~B09c{zEEr=ITMcuq|7&wA_rls&5BTh8RpWTyKj{~_*7o#`zTzj719 zKA&+XX7j-CY<%-phx)qnJvb|)J2=edH_zo8-#pg^&CS)d(}!$glfH7vOFHhtbez+` zubF(+b>|M8Cq{kU(Zh3MCVzD~#%bx^iA{H;KGsuqy0iJtbK1^3!0hDHx9oQ49n+3p zH#G|;>CT_nm2r&I(9csj-I+~i&FIcK^>k+z=SvyR^BMg*CuZ_jpJR5lBk$2p-L=c@ zn$evz$xAx2$xk|RYbHi@-MK^0JM3b1xYgabs;pj0`4wdOpLnO!IKJW1QCb9d9v5dK-)Tj&?poZs(m7 zqrUF^Zg*B*cg{2qoHDwD)7iM@p$7~mbT=Dw)?4?qZ1VrE4F3-8&gP**8QsBQI^SvF zc{0amX87C~^>pVRoEy`;m48TIyLHF=c^+XVcJlT6C;p5-W%Lb4e+%&K9_Kj?UFl6n zGZUZgJDWq_Zr*WDLoX&6Oz3So)@iAOSw1V@Jg~~>o;c`fx*n%--uX_OGRtqd=3SC) zz3S=C-{j8B^VzY}H=OmSdy}ua?(Q3Q8224h&iPK`H%&g+#5sLeL${mSp*v@qx47n? z^>Ba6v(9JabUMaqn$taHlD_in@tM1m&WxTlqdW7>TU_#!em2u`%UgeE?rb^j)BX2L z|M+*-;|`o%m(v=*JeP4AdeU?mr=>fajyttacW`bdHtFs?jdeWUG364sn@e|3`G@jT zuhX4|-viSzPD{T7dU&S%#N2mor!Rfi*=))sefmvy{MMbkq)+#?T=UZJ-1Nzt{Pdn9 zdSchz{5NsUZ{E7Y`A)-o)YBatX7igj<)>`(o#!;XVa=odQJ(M8vv%nYKI!n+Y)tZ! zj$ZY32iK-%bmwgI7MJ{_r%dDVp2j3E>F7-FX*#m4J9$ob+RhzE7<^B=3w=DnW3uPY zjr)J{*4xv2lAbb+Pno6TujSR#9UX0IMt5YBzWn4J)p3`bu8TE3yF6=&P5R0&|!Txv|Yd zk21Q0!)$)?lD;~dr~VNZ@8#+8PMb39gzuB!^gZNzmrW2?qBmhnAQOglke7ZW17c3iDRA5oYk{(x=+0NydUjq zeDiRpGP;A~*%Z98SiMO@%WA%M&G-Wag5XO4!whQoLjzm$h$jQ&UsGb zew>xl9URZbG!Gq(ah__rqnGEzINxd9xz0NbxLp?fn*6tuPmJoi^F4fST=TSJmtDEU zCLMPr|A?Mg+`)5)ZOrnTkGm$O`DeX#_a)hsZ=ET#bo^;vcW{`=Px_Qof9e6h=ESP6 zJ9pvi7^i{9Y>e}qhORZ6ub%GQGj)M=9ZqXJJf5i|=`Op&y4<9}Z~e_fe$B--wt3vc z=ag}})6k`!?%>i?UU%e@4j;2|&U4!8N;>Z0nON5O%vnAsCh0p_X4aXz_zccz@N_Dx z`@|pdwOe=XTKmK_Up?LVzUCd_Qcu!%x?Ofx<9?i779LOL_{$#=Tb(1UrD+2PT> zrt-QsmOa-6zjYqXObsFC{`L5SxoW}RKo}_VZrx*NU?_NCp6<0Jg)&Kwi literal 0 HcmV?d00001 diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.x b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.x new file mode 100644 index 0000000000000000000000000000000000000000..c4a91d008245403e7f26aa616b437191509793c0 GIT binary patch literal 22119 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 == True, \"Some hyperedges are empty\"\n", - "assert all(incidence_1.sum(1)>0) == True, \"Some nodes are not in any hyperedges\"\n", + "assert all(incidence_1.sum(0) > 0) == True, \"Some hyperedges are empty\"\n", + "assert all(incidence_1.sum(1) > 0) == True, \"Some nodes are not in any hyperedges\"\n", "incidence_1 = torch.Tensor(incidence_1).to_sparse_coo()" ] }, @@ -233,7 +231,7 @@ "outputs": [], "source": [ "class Network(torch.nn.Module):\n", - " \"\"\" Network class that initializes the base model and readout layer.\n", + " \"\"\"Network class that initializes the base model and readout layer.\n", "\n", " Base model parameters:\n", " ----------\n", @@ -246,40 +244,34 @@ " Optitional:\n", " **kwargs : dict\n", " Additional arguments for the base model.\n", - " \n", + "\n", " Readout layer parameters:\n", " ----------\n", " out_channels : int\n", " Dimension of the output features.\n", " task_level : str\n", - " Level of the task. Either \"graph\" or \"node\". \n", + " Level of the task. Either \"graph\" or \"node\".\n", " \"\"\"\n", + "\n", " def __init__(\n", - " self, \n", - " in_channels, \n", - " hidden_channels,\n", - " out_channels, \n", - " task_level=\"graph\",\n", - " **kwargs):\n", + " self, in_channels, hidden_channels, out_channels, task_level=\"graph\", **kwargs\n", + " ):\n", " super().__init__()\n", - " \n", + "\n", " # Define the model\n", " self.base_model = UniGCNII(\n", - " in_channels=in_channels,\n", - " hidden_channels=hidden_channels,\n", - " **kwargs\n", + " in_channels=in_channels, hidden_channels=hidden_channels, **kwargs\n", " )\n", "\n", - "\n", " # Readout\n", " self.linear = torch.nn.Linear(hidden_channels, out_channels)\n", " self.out_pool = True if task_level == \"graph\" else False\n", - " \n", + "\n", " def forward(self, x_0, incidence_1):\n", " # Base model\n", " x_0, x_1 = self.base_model(x_0, incidence_1)\n", "\n", - " # Pool over all nodes in the hypergraph \n", + " # Pool over all nodes in the hypergraph\n", " if self.out_pool is True:\n", " x = torch.max(x_0, dim=0)[0]\n", " else:\n", @@ -304,13 +296,13 @@ "# Base model hyperparameters\n", "in_channels = x_0s.shape[1]\n", "hidden_channels = 128\n", - "n_layers=2\n", - "mlp_num_layers=1\n", - "input_drop=0.5\n", + "n_layers = 2\n", + "mlp_num_layers = 1\n", + "input_drop = 0.5\n", "\n", "# Readout hyperparameters\n", "out_channels = torch.unique(y).shape[0]\n", - "task_level = \"graph\" if out_channels==1 else \"node\"\n", + "task_level = \"graph\" if out_channels == 1 else \"node\"\n", "\n", "\n", "model = Network(\n", @@ -320,7 +312,7 @@ " n_layers=n_layers,\n", " input_drop=input_drop,\n", " task_level=task_level,\n", - " ).to(device)" + ").to(device)" ] }, { @@ -391,10 +383,10 @@ "source": [ "x_0s = torch.tensor(x_0s)\n", "x_0s, incidence_1, y = (\n", - " x_0s.float().to(device),\n", - " incidence_1.float().to(device),\n", - " torch.tensor(y, dtype=torch.long).to(device),\n", - " )" + " x_0s.float().to(device),\n", + " incidence_1.float().to(device),\n", + " torch.tensor(y, dtype=torch.long).to(device),\n", + ")" ] }, { @@ -416,7 +408,6 @@ } ], "source": [ - "\n", "for epoch in range(num_epochs):\n", " # set model to training mode\n", " model.train()\n", @@ -428,18 +419,18 @@ " optimizer.step()\n", " optimizer.zero_grad()\n", "\n", - "\n", " if epoch % test_interval == 0:\n", - " \n", " model.eval()\n", " y_hat = model(x_0s, incidence_1)\n", "\n", " train_loss = loss_fn(y_hat[train_mask], y[train_mask])\n", " loss = loss_fn(y_hat[test_mask], y[test_mask])\n", - " print(f\"Epoch: {epoch} \\\n", + " print(\n", + " f\"Epoch: {epoch} \\\n", " Train_loss: {train_loss:.4f}, Train_acc: {acc_fn(y_hat[train_mask].argmax(1), y[train_mask]):.4f} \\\n", " Test_loss: {loss:.4f}, Test_acc: {acc_fn(y_hat[test_mask].argmax(1), y[test_mask]):.4f}\",\n", - " flush=True)" + " flush=True,\n", + " )" ] }, { diff --git a/tutorials/hypergraph/unigin_train.ipynb b/tutorials/hypergraph/unigin_train.ipynb index 1ea4fb196..efde5f78c 100644 --- a/tutorials/hypergraph/unigin_train.ipynb +++ b/tutorials/hypergraph/unigin_train.ipynb @@ -16,7 +16,7 @@ "from topomodelx.utils.sparse import from_sparse\n", "\n", "torch.manual_seed(0)\n", - "np.random.seed(0)\n" + "np.random.seed(0)" ] }, { @@ -109,7 +109,7 @@ "outputs": [], "source": [ "class Network(torch.nn.Module):\n", - " \"\"\" Network class that initializes the base modelo and readout layer.\n", + " \"\"\"Network class that initializes the base modelo and readout layer.\n", "\n", " Base model parameters:\n", " ----------\n", @@ -122,41 +122,34 @@ " Optitional:\n", " **kwargs : dict\n", " Additional arguments for the base model.\n", - " \n", + "\n", " Readout layer parameters:\n", " ----------\n", " out_channels : int\n", " Dimension of the output features.\n", " task_level : str\n", - " Level of the task. Either \"graph\" or \"node\". \n", + " Level of the task. Either \"graph\" or \"node\".\n", " \"\"\"\n", + "\n", " def __init__(\n", - " self, \n", - " in_channels, \n", - " hidden_channels,\n", - " out_channels, \n", - " \n", - " task_level=\"graph\",\n", - " **kwargs):\n", + " self, in_channels, hidden_channels, out_channels, task_level=\"graph\", **kwargs\n", + " ):\n", " super().__init__()\n", - " \n", + "\n", " # Define the model\n", " self.base_model = UniGIN(\n", - " in_channels=in_channels,\n", - " hidden_channels=hidden_channels,\n", - " **kwargs\n", + " in_channels=in_channels, hidden_channels=hidden_channels, **kwargs\n", " )\n", "\n", - "\n", " # Readout\n", " self.linear = torch.nn.Linear(hidden_channels, out_channels)\n", " self.out_pool = True if task_level == \"graph\" else False\n", - " \n", + "\n", " def forward(self, x_0, incidence_1):\n", " # Base model\n", " x_0, x_1 = self.base_model(x_0, incidence_1)\n", "\n", - " # Pool over all nodes in the hypergraph \n", + " # Pool over all nodes in the hypergraph\n", " if self.out_pool is True:\n", " x = torch.max(x_0, dim=0)[0]\n", " else:\n", @@ -181,10 +174,10 @@ "# Base model hyperparameters\n", "in_channels = x_1_list[0].shape[1]\n", "hidden_channels = 32\n", - "n_layers= 3\n", - "mlp_num_layers=1\n", - "input_drop=0.2\n", - "layer_drop=0.2\n", + "n_layers = 3\n", + "mlp_num_layers = 1\n", + "input_drop = 0.2\n", + "layer_drop = 0.2\n", "\n", "# Readout hyperparameters\n", "out_channels = 2\n", @@ -197,9 +190,9 @@ " input_drop=input_drop,\n", " layer_drop=layer_drop,\n", " n_layers=n_layers,\n", - " out_channels=out_channels, \n", + " out_channels=out_channels,\n", " task_level=task_level,\n", - " ).to(device)" + ").to(device)" ] }, { diff --git a/tutorials/hypergraph/unisage_train.ipynb b/tutorials/hypergraph/unisage_train.ipynb index f2e1352ce..baba79210 100644 --- a/tutorials/hypergraph/unisage_train.ipynb +++ b/tutorials/hypergraph/unisage_train.ipynb @@ -7,7 +7,6 @@ "metadata": {}, "outputs": [], "source": [ - "\n", "import torch\n", "import numpy as np\n", "from torch_geometric.utils import to_undirected\n", @@ -125,7 +124,7 @@ " neighborhood = tuple(sorted(neighborhood))\n", " if neighborhood not in unique_hyperedges:\n", " hyperedges.append(list(neighborhood))\n", - " unique_hyperedges.add(neighborhood) " + " unique_hyperedges.add(neighborhood)" ] }, { @@ -168,14 +167,14 @@ "num_single_node_hyperedges = sum(np.array(hyperedge_sizes) == 1)\n", "\n", "# Print the hyperedge statistics.\n", - "print(f'Hyperedge statistics: ')\n", - "print('Number of hyperedges without duplicated hyperedges', len(hyperedges))\n", - "print(f'min = {min_size}, ')\n", - "print(f'max = {max_size}, ')\n", - "print(f'mean = {mean_size}, ')\n", - "print(f'median = {median_size}, ')\n", - "print(f'std = {std_size}, ')\n", - "print(f'Number of hyperedges with size equal to one = {num_single_node_hyperedges}')\n" + "print(f\"Hyperedge statistics: \")\n", + "print(\"Number of hyperedges without duplicated hyperedges\", len(hyperedges))\n", + "print(f\"min = {min_size}, \")\n", + "print(f\"max = {max_size}, \")\n", + "print(f\"mean = {mean_size}, \")\n", + "print(f\"median = {median_size}, \")\n", + "print(f\"std = {std_size}, \")\n", + "print(f\"Number of hyperedges with size equal to one = {num_single_node_hyperedges}\")" ] }, { @@ -199,8 +198,8 @@ " for row in neighibourhood:\n", " incidence_1[row, col] = 1\n", "\n", - "assert all(incidence_1.sum(0)>0) == True, \"Some hyperedges are empty\"\n", - "assert all(incidence_1.sum(1)>0) == True, \"Some nodes are not in any hyperedges\"\n", + "assert all(incidence_1.sum(0) > 0) == True, \"Some hyperedges are empty\"\n", + "assert all(incidence_1.sum(1) > 0) == True, \"Some nodes are not in any hyperedges\"\n", "incidence_1 = torch.Tensor(incidence_1).to_sparse_coo()" ] }, @@ -223,7 +222,7 @@ "outputs": [], "source": [ "class Network(torch.nn.Module):\n", - " \"\"\" Network class that initializes the base model and readout layer.\n", + " \"\"\"Network class that initializes the base model and readout layer.\n", "\n", " Base model parameters:\n", " ----------\n", @@ -236,41 +235,34 @@ " Optitional:\n", " **kwargs : dict\n", " Additional arguments for the base model.\n", - " \n", + "\n", " Readout layer parameters:\n", " ----------\n", " out_channels : int\n", " Dimension of the output features.\n", " task_level : str\n", - " Level of the task. Either \"graph\" or \"node\". \n", + " Level of the task. Either \"graph\" or \"node\".\n", " \"\"\"\n", + "\n", " def __init__(\n", - " self, \n", - " in_channels, \n", - " hidden_channels,\n", - " out_channels, \n", - " \n", - " task_level=\"graph\",\n", - " **kwargs):\n", + " self, in_channels, hidden_channels, out_channels, task_level=\"graph\", **kwargs\n", + " ):\n", " super().__init__()\n", - " \n", + "\n", " # Define the model\n", " self.base_model = UniSAGE(\n", - " in_channels=in_channels,\n", - " hidden_channels=hidden_channels,\n", - " **kwargs\n", + " in_channels=in_channels, hidden_channels=hidden_channels, **kwargs\n", " )\n", "\n", - "\n", " # Readout\n", " self.linear = torch.nn.Linear(hidden_channels, out_channels)\n", " self.out_pool = True if task_level == \"graph\" else False\n", - " \n", + "\n", " def forward(self, x_0, incidence_1):\n", " # Base model\n", " x_0, x_1 = self.base_model(x_0, incidence_1)\n", "\n", - " # Pool over all nodes in the hypergraph \n", + " # Pool over all nodes in the hypergraph\n", " if self.out_pool is True:\n", " x = torch.max(x_0, dim=0)[0]\n", " else:\n", @@ -297,21 +289,21 @@ "# Base model hyperparameters\n", "in_channels = x_0s.shape[1]\n", "hidden_channels = 128\n", - "n_layers=1\n", + "n_layers = 1\n", "\n", "# Readout hyperparameters\n", "out_channels = torch.unique(y).shape[0]\n", - "task_level = \"graph\" if out_channels==1 else \"node\"\n", + "task_level = \"graph\" if out_channels == 1 else \"node\"\n", "\n", "model = Network(\n", " in_channels=in_channels,\n", " hidden_channels=hidden_channels,\n", - " out_channels=out_channels, \n", + " out_channels=out_channels,\n", " input_drop=0.2,\n", " layer_drop=0.2,\n", " n_layers=n_layers,\n", " task_level=task_level,\n", - " ).to(device)" + ").to(device)" ] }, { @@ -361,10 +353,10 @@ "source": [ "x_0s = torch.tensor(x_0s)\n", "x_0s, incidence_1, y = (\n", - " x_0s.float().to(device),\n", - " incidence_1.float().to(device),\n", - " torch.tensor(y, dtype=torch.long).to(device),\n", - " )" + " x_0s.float().to(device),\n", + " incidence_1.float().to(device),\n", + " torch.tensor(y, dtype=torch.long).to(device),\n", + ")" ] }, { @@ -419,11 +411,10 @@ "\n", "epoch_loss = []\n", "for epoch_i in range(1, num_epochs + 1):\n", - " \n", " model.train()\n", "\n", " opt.zero_grad()\n", - " \n", + "\n", " # Extract edge_index from sparse incidence matrix\n", " y_hat = model(x_0s, incidence_1)\n", " loss = loss_fn(y_hat[train_mask], y[train_mask])\n", @@ -432,23 +423,29 @@ " opt.step()\n", " epoch_loss.append(loss.item())\n", "\n", - " \n", - "\n", " if epoch_i % test_interval == 0:\n", - " \n", " model.eval()\n", " y_hat = model(x_0s, incidence_1)\n", "\n", " loss = loss_fn(y_hat[train_mask], y[train_mask])\n", " print(f\"Epoch: {epoch_i} \")\n", - " print(f\"Train_loss: {np.mean(epoch_loss):.4f}, acc: {acc_fn(y_hat[train_mask].argmax(1), y[train_mask]):.4f}\",flush=True)\n", + " print(\n", + " f\"Train_loss: {np.mean(epoch_loss):.4f}, acc: {acc_fn(y_hat[train_mask].argmax(1), y[train_mask]):.4f}\",\n", + " flush=True,\n", + " )\n", "\n", " loss = loss_fn(y_hat[val_mask], y[val_mask])\n", - " \n", - " print(f\"Val_loss: {loss:.4f}, Val_acc: {acc_fn(y_hat[val_mask].argmax(1), y[val_mask]):.4f}\", flush=True)\n", + "\n", + " print(\n", + " f\"Val_loss: {loss:.4f}, Val_acc: {acc_fn(y_hat[val_mask].argmax(1), y[val_mask]):.4f}\",\n", + " flush=True,\n", + " )\n", "\n", " loss = loss_fn(y_hat[test_mask], y[test_mask])\n", - " print(f\"Test_loss: {loss:.4f}, Test_acc: {acc_fn(y_hat[test_mask].argmax(1), y[test_mask]):.4f}\", flush=True)" + " print(\n", + " f\"Test_loss: {loss:.4f}, Test_acc: {acc_fn(y_hat[test_mask].argmax(1), y[test_mask]):.4f}\",\n", + " flush=True,\n", + " )" ] } ], From d2a096ff8876838bd57d80d6bf75d81f1db8d925 Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Tue, 7 Nov 2023 15:58:54 +0000 Subject: [PATCH 21/39] lint changes --- .../hypergraph/tmp/Cora/raw/ind.cora.allx | Bin 257305 -> 0 bytes .../hypergraph/tmp/Cora/raw/ind.cora.ally | Bin 47959 -> 0 bytes .../hypergraph/tmp/Cora/raw/ind.cora.graph | Bin 59847 -> 0 bytes .../tmp/Cora/raw/ind.cora.test.index | 1000 ----------------- tutorials/hypergraph/tmp/Cora/raw/ind.cora.tx | Bin 148025 -> 0 bytes tutorials/hypergraph/tmp/Cora/raw/ind.cora.ty | Bin 28135 -> 0 bytes tutorials/hypergraph/tmp/Cora/raw/ind.cora.x | Bin 22119 -> 0 bytes tutorials/hypergraph/tmp/Cora/raw/ind.cora.y | Bin 4054 -> 0 bytes 8 files changed, 1000 deletions(-) delete mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.allx delete mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.ally delete mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.graph delete mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.test.index delete mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.tx delete mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.ty delete mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.x delete mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.y diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.allx b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.allx deleted file mode 100644 index 44d53b1fece343538e45592caac521d73c6f98d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 257305 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 z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#jHhhXxMY_waq6 G`Tqf}DSCbY diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.ally b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.ally deleted file mode 100644 index 04fbd0b083d09341fcf16b395c642329637f0542..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47959 zcmd6jL9%66bwpLd#t|9`EwyNR1XNfJ0<|4TsG$fWsB)>H9v$rPTo?hPU`CitIipgk z%-rYR_rAqz{C#%j$~@=(KYaYzrX$J z%in$TpYPs&`{lb&-n@EGee%t3-n(x;e*MuOKY#VbfB*8$Pk#3L)xZ7er?3Czzy6Q; z&Aab@|J5gN{^|3NzyA5_k6yp}8}rXUd;OEoU;XQ6pMCa=zy9s__dl;cdiTZu{OT`% z{^)zZSKr%yxHO+VKL4=ggOWI>JMBZ$hg0K{=X9sxmga%MOl;C8cgJg))VXC+Zgl>+ z9;a;?_UEh}x-;Lr#-&`+TNk{O?6AX~vfyX(&*h!AW!UF)>Pq@#lb3Y9ujP}MdXt`d znm!)?T({G<%;syS?wrRtF-b=b^Mq4I_meJ{aoXK3z)TtFnBY(5 zWKMF4N&4J<*W0q=^Do_#bY$UULf6^+2zhy2fXg z&sVd|x1Lk4aeUXDndNii{*gU?TlyZ=b>|K~KZBc&XY|awxQEaDW<76Q^VQS+%3Uqn zyt$+K&+=N&mG9*Do_20r@{`VQ(6=|Q^|f5{T4(e0-C!}**FAAbZ{M(ae7E-N-q^cd zyMsID>{zEE*E}$oiFLZu(1V#6*7=NFnu$$1dYYfSq)%t^l8$$1_Jr3=>S7(|*5AB# zr+Qn@$y>mn`x%{ENAi=7xA9xuS@XJUCizL{yfV5oi*sUCS!4yUL}mq)&hHl8!eeKk0Yx zYJIMAhs>1J6_Aoz0FrocYZgY zH%@)sxeMowN&Xc*vGa!J;f;G}ywgrPTh4h-<9l#UT+&az+cB-r@!R|0W48X}UDew= z?|A8cd=pQ{It`iRB^^1Q!*2ZMPoFZn^PP@YpLf^gG|u3xobKRs4tIssJoeVnye*%y zNq2o4iwvgnx+e}gX3D{z*_da0SNa;u?{D9r9lC3e?#k=l?$$2su4C&-nU>Rx?s!j| zDWkgXu5)A9=drGzL^-UY+e5YwIc4qnPd}wXn>2MjnBQZ{QTI$=_ z&7WRnbl1CeS6+AKn>XC%E0g%7^INnF-j9{V{a4=A-r79A3->j?d9F(}-L+45@J@Fc zc%E0eQyzCHulsOLLmsm+&-Pj$-ZL|CNk_K%&O6o6kLhwJ-Y{3Qj&~aF$8?O-z`L1v z*7>X*&0{ukNuTUXc>JbxN4ppK#3WtsN?g)4k9VY*dXk>{8;`qBnAGn&w!Y?H^%{TW z&G-&C(;Y9Z<1Oi)?faVFI$t8^I=44WhJTKC8Zvji$+v9sQ|79U_hY7fddJmV>qi&Q z#H+45ci^my?%;H8+~!Z8GP>)X*p<^A+|0XP>u84Oy3g$8+P7 zue$ChZ`>HydHQzE>drlUKH(hWwA8z?$R#f6$j#gs^>yd2*4J{)Yn^vGyjcFVEPXYFpDva>th zX~;G&F|*8#%bU&9pkjbtFF6t-SzM0=Kd|~ zm^+#Dt#`Zb=JXxz`;yl5%^QDy?%hs%Pk;F9m{aXT%lnhdG1GkYbmtyEE2lfNd{$0( zX44rN%)~)YT+&@`W0B$6GR||_^d%j4H9vVt|1s`sciw$x%jy5^gnfxO>N~JwrgtSB zIn2Z*{gIsObQah}t(6FakfhR<{Jhiy#ql8(EZf5&SXcjpOz=i5(u?=qUx z9pA~bF?T)mw|x5Fxs20N9(QA=EPTw3Q(t%VU?yL6-H}fdJZ9pYt{L4qqn_@};(Wpk z+c@=f$6Y)hWi+q*_U6;KxZW+BGD%0D`nrSDnYg4QzxjDybj`|fn7&ZOgwCwGBOT}e;fjZc}RZ(ZBlwfD47bGSz*_wiY|t?!X6?s6Tc+V;M7 z$4h$pF84i;-jBTA1-;#wGN;+bZTF_THK#l7lDFNH za?o{7-)SdjHKRMTI49;=`rMPcwl{2k>P`CAH@;?dM+Z;GIBmMATSon@qxs28`rQ3vd+mPy-<)uXxvJydlxzRDXJ_17+8vIE zrqlH}jdPn1Ryp0l=}a7SOwG;SJmxp9`RwtT`}KU6+j8pb&hKa*xW>GMH}|IAq_@oW z9d|qL=F(eTpVRO?ZaUs+$lmqz8(I(U!fb5w^iH?q4xXt~b=^-on3=P7=&n5W6HXc3 z(S@nL?%;Gbu6gK5%vF8*QfBkoTUux8bs4AOUY*SHS-Euo3Agp4Lpj~SVJ1K6$jwYl z(pzTpoZs#lo_~&Y8Zypv8hD+`>aP6kjY(e8x&JD2!lPeV-NEr}jC#6rkDis?cFoVO znWUX&!MWZO@8o{&<}>=!Z0s|=D_vJu_gyW|yyKjPjPslZo+opBX2zYB)g76n!=Je^ z&2OG|Ut#%uIB$8q4>`=1cb?Nux}N=xtq*U)(>CP;lPdLY@raRxk z=M%0m@G!Ys&yO&g)m`tJ{ZZzTyk>RR_ulneE_qk=)Bk1T+?`J2|4Z|emvr;>obY#`nJ#o<8OdZ2I&uQpw-U-w4&EvOj9NvNHc&9b~*x^P7iz z9pg0cJRRpW&dj+n&-CtewG6%^F-iZia_N8F-q}2SN9u*I9ovqa&bvA8Iq6V_^L$oL zcV_jhtnQEUoNwL9dzSv_JCINB8NYd)KjFY{y{^k?=u=O3a6C^K@QGDjcjVnvR(HH^E~%#%apyev)CP<&$?+pZikgu6lMXPLoZrrqImw+cxJy~x!C`LxaLVY8E}o8Y+M^ldTQ@vRWYSDr($TZ| z!!-sTCVJa!>|GD{UCk#x>2pu>lHW4Td-ivw_u-!AZ|_uJcfP}&6Mt22->`Xjm%Gzx z;8X9N3_4rZc}_zY&%`Ai+2$uN=_j4TxV+O&`drRw=)&BXTHmvT;b8oHYY z#@){z&f29rILziZZ}RN(8Qt5|jP5S)7^h7(>D+sjxytiheC8fLGvm(6>W<7+9XU*w zcN%!ijk)SK{*Ko&_=cGqr@ro2y1=3X6S_|4J56)5CobvSk(i{n?3Phqckag7F-`-o zv$4)Q)$|_hoaZxq%;tg7IhmGg9=aZ7TK=WIyZ!ifo{w}*w&kC7&-Ao=lIL`%ZTwy=iTgyF_<9jhTKXE6y#3UVe&18np%;-6BN!R@B%<|c>$~%TT_{?n5nZY@+ zs_TwC=H?HljPB^-dBT8Ctka#g^^E@#xzy|KavI*9df3OAd-x3B&1Z0}BY94D8s4m) z?%;GPr@QiQ*NpDSBpv=t$2g5MkL2!T^*y@l+n#ZU>rB0l#Tzjlqncx##<}Jv&*@G( My~lCyzWDTi0g%o(9smFU diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.graph b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.graph deleted file mode 100644 index 4d3bf85dfc8b1c105a2c995597a1b3eed6947925..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59847 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 A!vFvP diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.test.index b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.test.index deleted file mode 100644 index ded8092db..000000000 --- a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.test.index +++ /dev/null @@ -1,1000 +0,0 @@ -2692 -2532 -2050 -1715 -2362 -2609 -2622 -1975 -2081 -1767 -2263 -1725 -2588 -2259 -2357 -1998 -2574 -2179 -2291 -2382 -1812 -1751 -2422 -1937 -2631 -2510 -2378 -2589 -2345 -1943 -1850 -2298 -1825 -2035 -2507 -2313 -1906 -1797 -2023 -2159 -2495 -1886 -2122 -2369 -2461 -1925 -2565 -1858 -2234 -2000 -1846 -2318 -1723 -2559 -2258 -1763 -1991 -1922 -2003 -2662 -2250 -2064 -2529 -1888 -2499 -2454 -2320 -2287 -2203 -2018 -2002 -2632 -2554 -2314 -2537 -1760 -2088 -2086 -2218 -2605 -1953 -2403 -1920 -2015 -2335 -2535 -1837 -2009 -1905 -2636 -1942 -2193 -2576 -2373 -1873 -2463 -2509 -1954 -2656 -2455 -2494 -2295 -2114 -2561 -2176 -2275 -2635 -2442 -2704 -2127 -2085 -2214 -2487 -1739 -2543 -1783 -2485 -2262 -2472 -2326 -1738 -2170 -2100 -2384 -2152 -2647 -2693 -2376 -1775 -1726 -2476 -2195 -1773 -1793 -2194 -2581 -1854 -2524 -1945 -1781 -1987 -2599 -1744 -2225 -2300 -1928 -2042 -2202 -1958 -1816 -1916 -2679 -2190 -1733 -2034 -2643 -2177 -1883 -1917 -1996 -2491 -2268 -2231 -2471 -1919 -1909 -2012 -2522 -1865 -2466 -2469 -2087 -2584 -2563 -1924 -2143 -1736 -1966 -2533 -2490 -2630 -1973 -2568 -1978 -2664 -2633 -2312 -2178 -1754 -2307 -2480 -1960 -1742 -1962 -2160 -2070 -2553 -2433 -1768 -2659 -2379 -2271 -1776 -2153 -1877 -2027 -2028 -2155 -2196 -2483 -2026 -2158 -2407 -1821 -2131 -2676 -2277 -2489 -2424 -1963 -1808 -1859 -2597 -2548 -2368 -1817 -2405 -2413 -2603 -2350 -2118 -2329 -1969 -2577 -2475 -2467 -2425 -1769 -2092 -2044 -2586 -2608 -1983 -2109 -2649 -1964 -2144 -1902 -2411 -2508 -2360 -1721 -2005 -2014 -2308 -2646 -1949 -1830 -2212 -2596 -1832 -1735 -1866 -2695 -1941 -2546 -2498 -2686 -2665 -1784 -2613 -1970 -2021 -2211 -2516 -2185 -2479 -2699 -2150 -1990 -2063 -2075 -1979 -2094 -1787 -2571 -2690 -1926 -2341 -2566 -1957 -1709 -1955 -2570 -2387 -1811 -2025 -2447 -2696 -2052 -2366 -1857 -2273 -2245 -2672 -2133 -2421 -1929 -2125 -2319 -2641 -2167 -2418 -1765 -1761 -1828 -2188 -1972 -1997 -2419 -2289 -2296 -2587 -2051 -2440 -2053 -2191 -1923 -2164 -1861 -2339 -2333 -2523 -2670 -2121 -1921 -1724 -2253 -2374 -1940 -2545 -2301 -2244 -2156 -1849 -2551 -2011 -2279 -2572 -1757 -2400 -2569 -2072 -2526 -2173 -2069 -2036 -1819 -1734 -1880 -2137 -2408 -2226 -2604 -1771 -2698 -2187 -2060 -1756 -2201 -2066 -2439 -1844 -1772 -2383 -2398 -1708 -1992 -1959 -1794 -2426 -2702 -2444 -1944 -1829 -2660 -2497 -2607 -2343 -1730 -2624 -1790 -1935 -1967 -2401 -2255 -2355 -2348 -1931 -2183 -2161 -2701 -1948 -2501 -2192 -2404 -2209 -2331 -1810 -2363 -2334 -1887 -2393 -2557 -1719 -1732 -1986 -2037 -2056 -1867 -2126 -1932 -2117 -1807 -1801 -1743 -2041 -1843 -2388 -2221 -1833 -2677 -1778 -2661 -2306 -2394 -2106 -2430 -2371 -2606 -2353 -2269 -2317 -2645 -2372 -2550 -2043 -1968 -2165 -2310 -1985 -2446 -1982 -2377 -2207 -1818 -1913 -1766 -1722 -1894 -2020 -1881 -2621 -2409 -2261 -2458 -2096 -1712 -2594 -2293 -2048 -2359 -1839 -2392 -2254 -1911 -2101 -2367 -1889 -1753 -2555 -2246 -2264 -2010 -2336 -2651 -2017 -2140 -1842 -2019 -1890 -2525 -2134 -2492 -2652 -2040 -2145 -2575 -2166 -1999 -2434 -1711 -2276 -2450 -2389 -2669 -2595 -1814 -2039 -2502 -1896 -2168 -2344 -2637 -2031 -1977 -2380 -1936 -2047 -2460 -2102 -1745 -2650 -2046 -2514 -1980 -2352 -2113 -1713 -2058 -2558 -1718 -1864 -1876 -2338 -1879 -1891 -2186 -2451 -2181 -2638 -2644 -2103 -2591 -2266 -2468 -1869 -2582 -2674 -2361 -2462 -1748 -2215 -2615 -2236 -2248 -2493 -2342 -2449 -2274 -1824 -1852 -1870 -2441 -2356 -1835 -2694 -2602 -2685 -1893 -2544 -2536 -1994 -1853 -1838 -1786 -1930 -2539 -1892 -2265 -2618 -2486 -2583 -2061 -1796 -1806 -2084 -1933 -2095 -2136 -2078 -1884 -2438 -2286 -2138 -1750 -2184 -1799 -2278 -2410 -2642 -2435 -1956 -2399 -1774 -2129 -1898 -1823 -1938 -2299 -1862 -2420 -2673 -1984 -2204 -1717 -2074 -2213 -2436 -2297 -2592 -2667 -2703 -2511 -1779 -1782 -2625 -2365 -2315 -2381 -1788 -1714 -2302 -1927 -2325 -2506 -2169 -2328 -2629 -2128 -2655 -2282 -2073 -2395 -2247 -2521 -2260 -1868 -1988 -2324 -2705 -2541 -1731 -2681 -2707 -2465 -1785 -2149 -2045 -2505 -2611 -2217 -2180 -1904 -2453 -2484 -1871 -2309 -2349 -2482 -2004 -1965 -2406 -2162 -1805 -2654 -2007 -1947 -1981 -2112 -2141 -1720 -1758 -2080 -2330 -2030 -2432 -2089 -2547 -1820 -1815 -2675 -1840 -2658 -2370 -2251 -1908 -2029 -2068 -2513 -2549 -2267 -2580 -2327 -2351 -2111 -2022 -2321 -2614 -2252 -2104 -1822 -2552 -2243 -1798 -2396 -2663 -2564 -2148 -2562 -2684 -2001 -2151 -2706 -2240 -2474 -2303 -2634 -2680 -2055 -2090 -2503 -2347 -2402 -2238 -1950 -2054 -2016 -1872 -2233 -1710 -2032 -2540 -2628 -1795 -2616 -1903 -2531 -2567 -1946 -1897 -2222 -2227 -2627 -1856 -2464 -2241 -2481 -2130 -2311 -2083 -2223 -2284 -2235 -2097 -1752 -2515 -2527 -2385 -2189 -2283 -2182 -2079 -2375 -2174 -2437 -1993 -2517 -2443 -2224 -2648 -2171 -2290 -2542 -2038 -1855 -1831 -1759 -1848 -2445 -1827 -2429 -2205 -2598 -2657 -1728 -2065 -1918 -2427 -2573 -2620 -2292 -1777 -2008 -1875 -2288 -2256 -2033 -2470 -2585 -2610 -2082 -2230 -1915 -1847 -2337 -2512 -2386 -2006 -2653 -2346 -1951 -2110 -2639 -2520 -1939 -2683 -2139 -2220 -1910 -2237 -1900 -1836 -2197 -1716 -1860 -2077 -2519 -2538 -2323 -1914 -1971 -1845 -2132 -1802 -1907 -2640 -2496 -2281 -2198 -2416 -2285 -1755 -2431 -2071 -2249 -2123 -1727 -2459 -2304 -2199 -1791 -1809 -1780 -2210 -2417 -1874 -1878 -2116 -1961 -1863 -2579 -2477 -2228 -2332 -2578 -2457 -2024 -1934 -2316 -1841 -1764 -1737 -2322 -2239 -2294 -1729 -2488 -1974 -2473 -2098 -2612 -1834 -2340 -2423 -2175 -2280 -2617 -2208 -2560 -1741 -2600 -2059 -1747 -2242 -2700 -2232 -2057 -2147 -2682 -1792 -1826 -2120 -1895 -2364 -2163 -1851 -2391 -2414 -2452 -1803 -1989 -2623 -2200 -2528 -2415 -1804 -2146 -2619 -2687 -1762 -2172 -2270 -2678 -2593 -2448 -1882 -2257 -2500 -1899 -2478 -2412 -2107 -1746 -2428 -2115 -1800 -1901 -2397 -2530 -1912 -2108 -2206 -2091 -1740 -2219 -1976 -2099 -2142 -2671 -2668 -2216 -2272 -2229 -2666 -2456 -2534 -2697 -2688 -2062 -2691 -2689 -2154 -2590 -2626 -2390 -1813 -2067 -1952 -2518 -2358 -1789 -2076 -2049 -2119 -2013 -2124 -2556 -2105 -2093 -1885 -2305 -2354 -2135 -2601 -1770 -1995 -2504 -1749 -2157 diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.tx b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.tx deleted file mode 100644 index 6e856d777401ee15dc8619db76c97d0a40ba2d60..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 148025 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 diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.x b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.x deleted file mode 100644 index c4a91d008245403e7f26aa616b437191509793c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22119 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 Date: Tue, 7 Nov 2023 16:10:18 +0000 Subject: [PATCH 22/39] locally works --- .../hypergraph/tmp/Cora/raw/ind.cora.allx | Bin 0 -> 257305 bytes .../hypergraph/tmp/Cora/raw/ind.cora.ally | Bin 0 -> 47959 bytes .../hypergraph/tmp/Cora/raw/ind.cora.graph | Bin 0 -> 59847 bytes .../tmp/Cora/raw/ind.cora.test.index | 1000 +++++++++++++++++ tutorials/hypergraph/tmp/Cora/raw/ind.cora.tx | Bin 0 -> 148025 bytes tutorials/hypergraph/tmp/Cora/raw/ind.cora.ty | Bin 0 -> 28135 bytes tutorials/hypergraph/tmp/Cora/raw/ind.cora.x | Bin 0 -> 22119 bytes tutorials/hypergraph/tmp/Cora/raw/ind.cora.y | Bin 0 -> 4054 bytes 8 files changed, 1000 insertions(+) create mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.allx create mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.ally create mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.graph create mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.test.index create mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.tx create mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.ty create mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.x create mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.y diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.allx b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.allx new file mode 100644 index 0000000000000000000000000000000000000000..44d53b1fece343538e45592caac521d73c6f98d6 GIT binary patch literal 257305 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 z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#jHhhXxMY_waq6 G`Tqf}DSCbY literal 0 HcmV?d00001 diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.ally b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.ally new file mode 100644 index 0000000000000000000000000000000000000000..04fbd0b083d09341fcf16b395c642329637f0542 GIT binary patch literal 47959 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 My~lCyzWDTi0g%o(9smFU literal 0 HcmV?d00001 diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.graph b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.graph new file mode 100644 index 0000000000000000000000000000000000000000..4d3bf85dfc8b1c105a2c995597a1b3eed6947925 GIT binary patch literal 59847 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 A!vFvP literal 0 HcmV?d00001 diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.test.index b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.test.index new file mode 100644 index 000000000..ded8092db --- /dev/null +++ b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.test.index @@ -0,0 +1,1000 @@ +2692 +2532 +2050 +1715 +2362 +2609 +2622 +1975 +2081 +1767 +2263 +1725 +2588 +2259 +2357 +1998 +2574 +2179 +2291 +2382 +1812 +1751 +2422 +1937 +2631 +2510 +2378 +2589 +2345 +1943 +1850 +2298 +1825 +2035 +2507 +2313 +1906 +1797 +2023 +2159 +2495 +1886 +2122 +2369 +2461 +1925 +2565 +1858 +2234 +2000 +1846 +2318 +1723 +2559 +2258 +1763 +1991 +1922 +2003 +2662 +2250 +2064 +2529 +1888 +2499 +2454 +2320 +2287 +2203 +2018 +2002 +2632 +2554 +2314 +2537 +1760 +2088 +2086 +2218 +2605 +1953 +2403 +1920 +2015 +2335 +2535 +1837 +2009 +1905 +2636 +1942 +2193 +2576 +2373 +1873 +2463 +2509 +1954 +2656 +2455 +2494 +2295 +2114 +2561 +2176 +2275 +2635 +2442 +2704 +2127 +2085 +2214 +2487 +1739 +2543 +1783 +2485 +2262 +2472 +2326 +1738 +2170 +2100 +2384 +2152 +2647 +2693 +2376 +1775 +1726 +2476 +2195 +1773 +1793 +2194 +2581 +1854 +2524 +1945 +1781 +1987 +2599 +1744 +2225 +2300 +1928 +2042 +2202 +1958 +1816 +1916 +2679 +2190 +1733 +2034 +2643 +2177 +1883 +1917 +1996 +2491 +2268 +2231 +2471 +1919 +1909 +2012 +2522 +1865 +2466 +2469 +2087 +2584 +2563 +1924 +2143 +1736 +1966 +2533 +2490 +2630 +1973 +2568 +1978 +2664 +2633 +2312 +2178 +1754 +2307 +2480 +1960 +1742 +1962 +2160 +2070 +2553 +2433 +1768 +2659 +2379 +2271 +1776 +2153 +1877 +2027 +2028 +2155 +2196 +2483 +2026 +2158 +2407 +1821 +2131 +2676 +2277 +2489 +2424 +1963 +1808 +1859 +2597 +2548 +2368 +1817 +2405 +2413 +2603 +2350 +2118 +2329 +1969 +2577 +2475 +2467 +2425 +1769 +2092 +2044 +2586 +2608 +1983 +2109 +2649 +1964 +2144 +1902 +2411 +2508 +2360 +1721 +2005 +2014 +2308 +2646 +1949 +1830 +2212 +2596 +1832 +1735 +1866 +2695 +1941 +2546 +2498 +2686 +2665 +1784 +2613 +1970 +2021 +2211 +2516 +2185 +2479 +2699 +2150 +1990 +2063 +2075 +1979 +2094 +1787 +2571 +2690 +1926 +2341 +2566 +1957 +1709 +1955 +2570 +2387 +1811 +2025 +2447 +2696 +2052 +2366 +1857 +2273 +2245 +2672 +2133 +2421 +1929 +2125 +2319 +2641 +2167 +2418 +1765 +1761 +1828 +2188 +1972 +1997 +2419 +2289 +2296 +2587 +2051 +2440 +2053 +2191 +1923 +2164 +1861 +2339 +2333 +2523 +2670 +2121 +1921 +1724 +2253 +2374 +1940 +2545 +2301 +2244 +2156 +1849 +2551 +2011 +2279 +2572 +1757 +2400 +2569 +2072 +2526 +2173 +2069 +2036 +1819 +1734 +1880 +2137 +2408 +2226 +2604 +1771 +2698 +2187 +2060 +1756 +2201 +2066 +2439 +1844 +1772 +2383 +2398 +1708 +1992 +1959 +1794 +2426 +2702 +2444 +1944 +1829 +2660 +2497 +2607 +2343 +1730 +2624 +1790 +1935 +1967 +2401 +2255 +2355 +2348 +1931 +2183 +2161 +2701 +1948 +2501 +2192 +2404 +2209 +2331 +1810 +2363 +2334 +1887 +2393 +2557 +1719 +1732 +1986 +2037 +2056 +1867 +2126 +1932 +2117 +1807 +1801 +1743 +2041 +1843 +2388 +2221 +1833 +2677 +1778 +2661 +2306 +2394 +2106 +2430 +2371 +2606 +2353 +2269 +2317 +2645 +2372 +2550 +2043 +1968 +2165 +2310 +1985 +2446 +1982 +2377 +2207 +1818 +1913 +1766 +1722 +1894 +2020 +1881 +2621 +2409 +2261 +2458 +2096 +1712 +2594 +2293 +2048 +2359 +1839 +2392 +2254 +1911 +2101 +2367 +1889 +1753 +2555 +2246 +2264 +2010 +2336 +2651 +2017 +2140 +1842 +2019 +1890 +2525 +2134 +2492 +2652 +2040 +2145 +2575 +2166 +1999 +2434 +1711 +2276 +2450 +2389 +2669 +2595 +1814 +2039 +2502 +1896 +2168 +2344 +2637 +2031 +1977 +2380 +1936 +2047 +2460 +2102 +1745 +2650 +2046 +2514 +1980 +2352 +2113 +1713 +2058 +2558 +1718 +1864 +1876 +2338 +1879 +1891 +2186 +2451 +2181 +2638 +2644 +2103 +2591 +2266 +2468 +1869 +2582 +2674 +2361 +2462 +1748 +2215 +2615 +2236 +2248 +2493 +2342 +2449 +2274 +1824 +1852 +1870 +2441 +2356 +1835 +2694 +2602 +2685 +1893 +2544 +2536 +1994 +1853 +1838 +1786 +1930 +2539 +1892 +2265 +2618 +2486 +2583 +2061 +1796 +1806 +2084 +1933 +2095 +2136 +2078 +1884 +2438 +2286 +2138 +1750 +2184 +1799 +2278 +2410 +2642 +2435 +1956 +2399 +1774 +2129 +1898 +1823 +1938 +2299 +1862 +2420 +2673 +1984 +2204 +1717 +2074 +2213 +2436 +2297 +2592 +2667 +2703 +2511 +1779 +1782 +2625 +2365 +2315 +2381 +1788 +1714 +2302 +1927 +2325 +2506 +2169 +2328 +2629 +2128 +2655 +2282 +2073 +2395 +2247 +2521 +2260 +1868 +1988 +2324 +2705 +2541 +1731 +2681 +2707 +2465 +1785 +2149 +2045 +2505 +2611 +2217 +2180 +1904 +2453 +2484 +1871 +2309 +2349 +2482 +2004 +1965 +2406 +2162 +1805 +2654 +2007 +1947 +1981 +2112 +2141 +1720 +1758 +2080 +2330 +2030 +2432 +2089 +2547 +1820 +1815 +2675 +1840 +2658 +2370 +2251 +1908 +2029 +2068 +2513 +2549 +2267 +2580 +2327 +2351 +2111 +2022 +2321 +2614 +2252 +2104 +1822 +2552 +2243 +1798 +2396 +2663 +2564 +2148 +2562 +2684 +2001 +2151 +2706 +2240 +2474 +2303 +2634 +2680 +2055 +2090 +2503 +2347 +2402 +2238 +1950 +2054 +2016 +1872 +2233 +1710 +2032 +2540 +2628 +1795 +2616 +1903 +2531 +2567 +1946 +1897 +2222 +2227 +2627 +1856 +2464 +2241 +2481 +2130 +2311 +2083 +2223 +2284 +2235 +2097 +1752 +2515 +2527 +2385 +2189 +2283 +2182 +2079 +2375 +2174 +2437 +1993 +2517 +2443 +2224 +2648 +2171 +2290 +2542 +2038 +1855 +1831 +1759 +1848 +2445 +1827 +2429 +2205 +2598 +2657 +1728 +2065 +1918 +2427 +2573 +2620 +2292 +1777 +2008 +1875 +2288 +2256 +2033 +2470 +2585 +2610 +2082 +2230 +1915 +1847 +2337 +2512 +2386 +2006 +2653 +2346 +1951 +2110 +2639 +2520 +1939 +2683 +2139 +2220 +1910 +2237 +1900 +1836 +2197 +1716 +1860 +2077 +2519 +2538 +2323 +1914 +1971 +1845 +2132 +1802 +1907 +2640 +2496 +2281 +2198 +2416 +2285 +1755 +2431 +2071 +2249 +2123 +1727 +2459 +2304 +2199 +1791 +1809 +1780 +2210 +2417 +1874 +1878 +2116 +1961 +1863 +2579 +2477 +2228 +2332 +2578 +2457 +2024 +1934 +2316 +1841 +1764 +1737 +2322 +2239 +2294 +1729 +2488 +1974 +2473 +2098 +2612 +1834 +2340 +2423 +2175 +2280 +2617 +2208 +2560 +1741 +2600 +2059 +1747 +2242 +2700 +2232 +2057 +2147 +2682 +1792 +1826 +2120 +1895 +2364 +2163 +1851 +2391 +2414 +2452 +1803 +1989 +2623 +2200 +2528 +2415 +1804 +2146 +2619 +2687 +1762 +2172 +2270 +2678 +2593 +2448 +1882 +2257 +2500 +1899 +2478 +2412 +2107 +1746 +2428 +2115 +1800 +1901 +2397 +2530 +1912 +2108 +2206 +2091 +1740 +2219 +1976 +2099 +2142 +2671 +2668 +2216 +2272 +2229 +2666 +2456 +2534 +2697 +2688 +2062 +2691 +2689 +2154 +2590 +2626 +2390 +1813 +2067 +1952 +2518 +2358 +1789 +2076 +2049 +2119 +2013 +2124 +2556 +2105 +2093 +1885 +2305 +2354 +2135 +2601 +1770 +1995 +2504 +1749 +2157 diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.tx b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.tx new file mode 100644 index 0000000000000000000000000000000000000000..6e856d777401ee15dc8619db76c97d0a40ba2d60 GIT binary patch literal 148025 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 literal 0 HcmV?d00001 diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.x b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.x new file mode 100644 index 0000000000000000000000000000000000000000..c4a91d008245403e7f26aa616b437191509793c0 GIT binary patch literal 22119 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 Date: Tue, 7 Nov 2023 16:36:10 +0000 Subject: [PATCH 23/39] locally everything works --- tutorials/hypergraph/allset_transformer_train.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tutorials/hypergraph/allset_transformer_train.ipynb b/tutorials/hypergraph/allset_transformer_train.ipynb index 70c8c8231..367a2b87b 100644 --- a/tutorials/hypergraph/allset_transformer_train.ipynb +++ b/tutorials/hypergraph/allset_transformer_train.ipynb @@ -502,7 +502,7 @@ "source": [ "torch.manual_seed(0)\n", "test_interval = 5\n", - "num_epochs = 30\n", + "num_epochs = 10\n", "\n", "epoch_loss = []\n", "for epoch_i in range(1, num_epochs + 1):\n", From f362b7c981bb764c72d2676a22a235a5fe2f6b9c Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Tue, 7 Nov 2023 17:05:31 +0000 Subject: [PATCH 24/39] locally everything works --- .../hypergraph/allset_transformer_train.ipynb | 573 ------------------ 1 file changed, 573 deletions(-) delete mode 100644 tutorials/hypergraph/allset_transformer_train.ipynb diff --git a/tutorials/hypergraph/allset_transformer_train.ipynb b/tutorials/hypergraph/allset_transformer_train.ipynb deleted file mode 100644 index 367a2b87b..000000000 --- a/tutorials/hypergraph/allset_transformer_train.ipynb +++ /dev/null @@ -1,573 +0,0 @@ -{ - "cells": [ - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "\n", - "\n", - "# Train an All-Set-Transformer TNN\n", - "\n", - "In this notebook, we will create and train a two-step message passing network named AllSetTransformer (Chien et al., [2021](https://arxiv.org/abs/2106.13264)) in the hypergraph domain. We will use a benchmark dataset, shrec16, a collection of 3D meshes, to train the model to perform classification at the level of the hypergraph. \n", - "\n", - "Following the \"awesome-tnns\" [github repo.](https://github.com/awesome-tnns/awesome-tnns/blob/main/Hypergraphs.md)\n", - "\n", - "🟧 $\\quad m_{\\rightarrow z}^{(\\rightarrow 1)} = AGG_{y \\in \\mathcal{B}(z)} (h_y^{t, (0)}, h_z^{t,(1)}) \\quad \\text{with attention}$ \n", - "\n", - "🟦 $\\quad h_z^{t+1,(1)} = \\text{LN}(m_{\\rightarrow z}^{(\\rightarrow 1)} + \\text{MLP}(m_{\\rightarrow z}^{(\\rightarrow 1)} ))$ \n", - "\n", - "Edge to vertex: \n", - "\n", - "🟧 $\\quad m_{\\rightarrow x}^{(\\rightarrow 0)} = AGG_{z \\in \\mathcal{C}(x)} (h_z^{t+1,(1)}, h_x^{t,(0)}) \\quad \\text{with attention}$ \n", - "\n", - "🟦 $\\quad h_x^{t+1,(0)} = \\text{LN}(m_{\\rightarrow x}^{(\\rightarrow 0)} + \\text{MLP}(m_{\\rightarrow x}^{(\\rightarrow 0)} ))$\n", - "\n", - "\n", - "\n", - "### Additional theoretical clarifications\n", - "\n", - "Given a hypergraph $G=(\\mathcal{V}, \\mathcal{E})$, let $\\textbf{X} \\in \\mathbb{R}^{|\\mathcal{V}| \\times F}$ and $\\textbf{Z} \\in \\mathbb{R}^{|\\mathcal{E}| \\times F'}$ denote the hidden node and hyperedge representations, respectively. Additionally, define $V_{e, \\textbf{X}} = \\{\\textbf{X}_{u,:}: u \\in e\\}$ as the multiset of hidden node representations in the hyperedge $e$ and $E_{v, \\textbf{Z}} = \\{\\textbf{Z}_{e,:}: v \\in e\\}$ as the multiset of hidden representations of hyperedges containing $v$.\n", - "\n", - "\\\n", - "In this setting, the two general update rules that AllSet's framework puts in place in each layer are:\n", - "\n", - "🔷 $\\textbf{Z}_{e,:}^{(t+1)} = f_{\\mathcal{V} \\rightarrow \\mathcal{E}}(V_{e, \\textbf{X}^{(t)}}; \\textbf{Z}_{e,:}^{(t)})$\n", - "\n", - "🔷 $\\textbf{X}_{v,:}^{(t+1)} = f_{\\mathcal{E} \\rightarrow \\mathcal{V}}(E_{v, \\textbf{Z}^{(t+1)}}; \\textbf{X}_{v,:}^{(t)})$\n", - "\n", - "in which $f_{\\mathcal{V} \\rightarrow \\mathcal{E}}$ and $f_{\\mathcal{E} \\rightarrow \\mathcal{V}}$ are two permutation invariant functions with respect to their first input. The matrices $\\textbf{Z}_{e,:}^{(0)}$ and $\\textbf{X}_{v,:}^{(0)}$ are initialized with the hyperedge and node features respectively, if available, otherwise they are set to be all-zero matrices.\n", - "\n", - "In the practical implementation of the model, $f_{\\mathcal{V} \\rightarrow \\mathcal{E}}$ and $f_{\\mathcal{E} \\rightarrow \\mathcal{V}}$ are parametrized and $learnt$ for each dataset and task, and the information of their second argument is not utilized. The option achieving the best results makes use of attention-based layers, giving rise to the so-called AllSetTransformer architecture.\n", - "\n", - "\\\n", - "We now dive deep into the details of AllSetTransformer, describing how the update functions $f_{\\mathcal{V} \\rightarrow \\mathcal{E}}$ and $f_{\\mathcal{E} \\rightarrow \\mathcal{V}}$ are iteratively defined.\n", - "Their input is a matrix $\\textbf{S} \\in \\mathbb{R}^{|S| \\times F}$ which corresponds the multiset of $F$-dimensional feature vectors:\n", - "\n", - "1️⃣ $\\textbf{K}^{(i)} = \\text{MLP}^{K, i}(\\textbf{S}), \\textbf{V}^{(i)} = \\text{MLP}^{V, i}(\\textbf{S})$, where $i \\in \\{1, ..., h\\},$\n", - "\n", - "2️⃣ $ \\textbf{O}^{(i)} = \\omega (\\theta^{(i)}(\\textbf{K}^{(i)})^{T}) \\textbf{V}^{(i)},$ \n", - "\n", - "3️⃣ $\\theta \\overset{\\Delta}{=} \\mathbin\\Vert_{i=1}^{h} \\theta^{(i)}, $\n", - "\n", - "4️⃣ $ \\text{MH}_{h, \\omega}(\\theta, \\textbf{S}, \\textbf{S}) = \\mathbin\\Vert_{i=1}^{h} \\textbf{O}^{(i)}, $\n", - "\n", - "5️⃣ $ \\textbf{Y} = \\text{LN} (\\theta + \\text{MH}_{h, \\omega}(\\theta, \\textbf{S}, \\textbf{S})), $\n", - "\n", - "6️⃣ $f_{\\mathcal{V} \\rightarrow \\mathcal{E}}(\\textbf{S}) = f_{\\mathcal{E} \\rightarrow \\mathcal{V}}(\\textbf{S}) = \\text{LN} (\\textbf{Y} + \\text{MLP}(\\textbf{Y}))$.\n", - "\n", - "\\\n", - "\n", - "The elements and operations used in these steps are defined as follows:\n", - "\n", - "🔶 $\\text{LN}$ means layer normalization (Ba et al., [2016](https://arxiv.org/abs/1607.06450)),\n", - "\n", - "🔶 $\\mathbin\\Vert$ represents concatenation,\n", - "\n", - "🔶 $\\theta \\in \\mathbb{R}^{1 \\times hF_{h}}$ is a learnable weight,\n", - "\n", - "🔶 $\\text{MH}_{h, \\omega}$ denotes a multihead attention mechanism with $h$ heads and activation function $\\omega$ (Vaswani et al., [2017](https://proceedings.neurips.cc/paper_files/paper/2017/hash/3f5ee243547dee91fbd053c1c4a845aa-Abstract.html)),\n", - "\n", - "🔶 all $\\text{MLP}$ modules are multi-layer perceptrons that operate row-wise, so they are applied identically and independently to each multiset element of $\\textbf{S}$.\n", - "\n", - "\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "ExecuteTime": { - "end_time": "2023-06-01T16:14:51.222779223Z", - "start_time": "2023-06-01T16:14:49.575421023Z" - } - }, - "outputs": [], - "source": [ - "import torch\n", - "import numpy as np\n", - "from torch_geometric.utils import to_undirected\n", - "import torch_geometric.datasets as geom_datasets\n", - "\n", - "from topomodelx.nn.hypergraph.allset_transformer import AllSetTransformer\n", - "\n", - "torch.manual_seed(0)\n", - "np.random.seed(0)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "If GPU's are available, we will make use of them. Otherwise, this will run on CPU." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": { - "ExecuteTime": { - "end_time": "2023-06-01T16:14:51.959770754Z", - "start_time": "2023-06-01T16:14:51.956096841Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "cuda\n" - ] - } - ], - "source": [ - "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n", - "print(device)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Pre-processing\n", - "\n", - "## Import data ##\n", - "\n", - "The first step is to import the dataset, Cora, a benchmark classification datase. We then lift the graph into our domain of choice, a hypergraph." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": { - "ExecuteTime": { - "end_time": "2023-06-01T16:14:53.022151550Z", - "start_time": "2023-06-01T16:14:52.949636599Z" - } - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/usr/local/lib/python3.11/site-packages/torch_geometric/data/in_memory_dataset.py:284: UserWarning: It is not recommended to directly access the internal storage format `data` of an 'InMemoryDataset'. If you are absolutely certain what you are doing, access the internal storage via `InMemoryDataset._data` instead to suppress this warning. Alternatively, you can access stacked individual attributes of every graph via `dataset.{attr_name}`.\n", - " warnings.warn(msg)\n" - ] - } - ], - "source": [ - "cora = geom_datasets.Planetoid(root=\"tmp/\", name=\"Cora\")\n", - "data = cora.data\n", - "\n", - "x_0s = data.x\n", - "y = data.y\n", - "edge_index = data.edge_index\n", - "\n", - "train_mask = data.train_mask\n", - "val_mask = data.val_mask\n", - "test_mask = data.test_mask" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Define neighborhood structures and lift into hypergraph domain. ##\n", - "\n", - "Now we retrieve the neighborhood structure (i.e. their representative matrice) that we will use to send messges from node to hyperedges. In the case of this architecture, we need the boundary matrix (or incidence matrix) $B_1$ with shape $n_\\text{nodes} \\times n_\\text{edges}$.\n", - "\n", - "In citation Cora dataset we lift graph structure to the hypergraph domain by creating hyperedges from 1-hop graph neighbourhood of each node. \n" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": { - "ExecuteTime": { - "end_time": "2023-06-01T16:14:53.022151550Z", - "start_time": "2023-06-01T16:14:52.949636599Z" - } - }, - "outputs": [], - "source": [ - "# Ensure the graph is undirected (optional but often useful for one-hop neighborhoods).\n", - "edge_index = to_undirected(edge_index)\n", - "\n", - "# Create a list of one-hop neighborhoods for each node.\n", - "one_hop_neighborhoods = []\n", - "for node in range(data.num_nodes):\n", - " # Get the one-hop neighbors of the current node.\n", - " neighbors = data.edge_index[1, data.edge_index[0] == node]\n", - "\n", - " # Append the neighbors to the list of one-hop neighborhoods.\n", - " one_hop_neighborhoods.append(neighbors.numpy())\n", - "\n", - "# Detect and eliminate duplicate hyperedges.\n", - "unique_hyperedges = set()\n", - "hyperedges = []\n", - "for neighborhood in one_hop_neighborhoods:\n", - " # Sort the neighborhood to ensure consistent comparison.\n", - " neighborhood = tuple(sorted(neighborhood))\n", - " if neighborhood not in unique_hyperedges:\n", - " hyperedges.append(list(neighborhood))\n", - " unique_hyperedges.add(neighborhood)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Additionally we print the statictis associated with obtained incidence matrix" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Hyperedge statistics: \n", - "Number of hyperedges without duplicated hyperedges 2581\n", - "min = 1, \n", - "max = 168, \n", - "mean = 4.003099573808601, \n", - "median = 3.0, \n", - "std = 5.327622607829558, \n", - "Number of hyperedges with size equal to one = 412\n" - ] - } - ], - "source": [ - "# Calculate hyperedge statistics.\n", - "hyperedge_sizes = [len(he) for he in hyperedges]\n", - "min_size = min(hyperedge_sizes)\n", - "max_size = max(hyperedge_sizes)\n", - "mean_size = np.mean(hyperedge_sizes)\n", - "median_size = np.median(hyperedge_sizes)\n", - "std_size = np.std(hyperedge_sizes)\n", - "num_single_node_hyperedges = sum(np.array(hyperedge_sizes) == 1)\n", - "\n", - "# Print the hyperedge statistics.\n", - "print(f\"Hyperedge statistics: \")\n", - "print(\"Number of hyperedges without duplicated hyperedges\", len(hyperedges))\n", - "print(f\"min = {min_size}, \")\n", - "print(f\"max = {max_size}, \")\n", - "print(f\"mean = {mean_size}, \")\n", - "print(f\"median = {median_size}, \")\n", - "print(f\"std = {std_size}, \")\n", - "print(f\"Number of hyperedges with size equal to one = {num_single_node_hyperedges}\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Construct incidence matrix" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [], - "source": [ - "max_edges = len(hyperedges)\n", - "incidence_1 = np.zeros((x_0s.shape[0], max_edges))\n", - "for col, neighibourhood in enumerate(hyperedges):\n", - " for row in neighibourhood:\n", - " incidence_1[row, col] = 1\n", - "\n", - "assert all(incidence_1.sum(0) > 0) == True, \"Some hyperedges are empty\"\n", - "assert all(incidence_1.sum(1) > 0) == True, \"Some nodes are not in any hyperedges\"\n", - "incidence_1 = torch.Tensor(incidence_1).to_sparse_coo()" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Define the Neural Network\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Define the network that initializes the base model and sets up the readout operation.\n", - "Different downstream tasks might require different pooling procedures." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "class Network(torch.nn.Module):\n", - " \"\"\"Network class that initializes the base model and readout layer.\n", - "\n", - " Base model parameters:\n", - " ----------\n", - " Reqired:\n", - " in_channels : int\n", - " Dimension of the input features.\n", - " hidden_channels : int\n", - " Dimension of the hidden features.\n", - "\n", - " Optitional:\n", - " **kwargs : dict\n", - " Additional arguments for the base model.\n", - "\n", - " Readout layer parameters:\n", - " ----------\n", - " out_channels : int\n", - " Dimension of the output features.\n", - " task_level : str\n", - " Level of the task. Either \"graph\" or \"node\".\n", - " \"\"\"\n", - "\n", - " def __init__(\n", - " self, in_channels, hidden_channels, out_channels, task_level=\"graph\", **kwargs\n", - " ):\n", - " super().__init__()\n", - "\n", - " # Define the model\n", - " self.base_model = AllSetTransformer(\n", - " in_channels=in_channels, hidden_channels=hidden_channels, **kwargs\n", - " )\n", - "\n", - " # Readout\n", - " self.linear = torch.nn.Linear(hidden_channels, out_channels)\n", - " self.out_pool = True if task_level == \"graph\" else False\n", - "\n", - " def forward(self, x_0, incidence_1):\n", - " # Base model\n", - " x_0, x_1 = self.base_model(x_0, incidence_1)\n", - "\n", - " # Pool over all nodes in the hypergraph\n", - " if self.out_pool is True:\n", - " x = torch.max(x_0, dim=0)[0]\n", - " else:\n", - " x = x_0\n", - "\n", - " return self.linear(x)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Initialize the model" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [], - "source": [ - "# Base model hyperparameters\n", - "in_channels = x_0s.shape[1]\n", - "hidden_channels = 128\n", - "\n", - "heads = 4\n", - "n_layers = 1\n", - "mlp_num_layers = 2\n", - "\n", - "# Readout hyperparameters\n", - "out_channels = torch.unique(y).shape[0]\n", - "task_level = \"graph\" if out_channels == 1 else \"node\"\n", - "\n", - "\n", - "model = Network(\n", - " in_channels=in_channels,\n", - " hidden_channels=hidden_channels,\n", - " out_channels=out_channels,\n", - " heads=heads,\n", - " n_layers=n_layers,\n", - " mlp_num_layers=mlp_num_layers,\n", - " task_level=task_level,\n", - ").to(device)" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Train the Neural Network\n", - "\n", - "We specify the model, the loss, and an optimizer." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [], - "source": [ - "# Optimizer and loss\n", - "opt = torch.optim.Adam(model.parameters(), lr=0.01)\n", - "\n", - "# Categorial cross-entropy loss\n", - "loss_fn = torch.nn.CrossEntropyLoss()\n", - "\n", - "# Accuracy\n", - "acc_fn = lambda y, y_hat: (y == y_hat).float().mean()" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/tmp/ipykernel_2070/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", - " x_0s = torch.tensor(x_0s)\n", - "/tmp/ipykernel_2070/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", - " torch.tensor(y, dtype=torch.long).to(device),\n" - ] - } - ], - "source": [ - "x_0s = torch.tensor(x_0s)\n", - "x_0s, incidence_1, y = (\n", - " x_0s.float().to(device),\n", - " incidence_1.float().to(device),\n", - " torch.tensor(y, dtype=torch.long).to(device),\n", - ")" - ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The following cell performs the training, looping over the network for a low amount of epochs. We keep training minimal for the purpose of rapid testing." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": { - "ExecuteTime": { - "end_time": "2023-06-01T16:15:01.683216142Z", - "start_time": "2023-06-01T16:15:00.727075750Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Epoch: 5 \n", - "Train_loss: 1.6679, acc: 0.9786\n", - "Val_loss: 1.0352, Val_acc: 0.7260\n", - "Test_loss: 0.9883, Test_acc: 0.7420\n", - "Epoch: 10 \n", - "Train_loss: 0.9572, acc: 1.0000\n", - "Val_loss: 1.0956, Val_acc: 0.7260\n", - "Test_loss: 0.9612, Test_acc: 0.7430\n", - "Epoch: 15 \n", - "Train_loss: 0.6462, acc: 1.0000\n", - "Val_loss: 1.4786, Val_acc: 0.7340\n", - "Test_loss: 1.2396, Test_acc: 0.7440\n", - "Epoch: 20 \n", - "Train_loss: 0.4861, acc: 1.0000\n", - "Val_loss: 1.8393, Val_acc: 0.7180\n", - "Test_loss: 1.5967, Test_acc: 0.7330\n", - "Epoch: 25 \n", - "Train_loss: 0.3892, acc: 1.0000\n", - "Val_loss: 2.1019, Val_acc: 0.7100\n", - "Test_loss: 1.8659, Test_acc: 0.7310\n", - "Epoch: 30 \n", - "Train_loss: 0.3244, acc: 1.0000\n", - "Val_loss: 2.2488, Val_acc: 0.7100\n", - "Test_loss: 2.0038, Test_acc: 0.7350\n" - ] - } - ], - "source": [ - "torch.manual_seed(0)\n", - "test_interval = 5\n", - "num_epochs = 10\n", - "\n", - "epoch_loss = []\n", - "for epoch_i in range(1, num_epochs + 1):\n", - " model.train()\n", - "\n", - " opt.zero_grad()\n", - "\n", - " # Extract edge_index from sparse incidence matrix\n", - " y_hat = model(x_0s, incidence_1)\n", - " loss = loss_fn(y_hat[train_mask], y[train_mask])\n", - "\n", - " loss.backward()\n", - " opt.step()\n", - " epoch_loss.append(loss.item())\n", - "\n", - " if epoch_i % test_interval == 0:\n", - " model.eval()\n", - " y_hat = model(x_0s, incidence_1)\n", - "\n", - " loss = loss_fn(y_hat[train_mask], y[train_mask])\n", - " print(f\"Epoch: {epoch_i} \")\n", - " print(\n", - " f\"Train_loss: {np.mean(epoch_loss):.4f}, acc: {acc_fn(y_hat[train_mask].argmax(1), y[train_mask]):.4f}\",\n", - " flush=True,\n", - " )\n", - "\n", - " loss = loss_fn(y_hat[val_mask], y[val_mask])\n", - "\n", - " print(\n", - " f\"Val_loss: {loss:.4f}, Val_acc: {acc_fn(y_hat[val_mask].argmax(1), y[val_mask]):.4f}\",\n", - " flush=True,\n", - " )\n", - "\n", - " loss = loss_fn(y_hat[test_mask], y[test_mask])\n", - " print(\n", - " f\"Test_loss: {loss:.4f}, Test_acc: {acc_fn(y_hat[test_mask].argmax(1), y[test_mask]):.4f}\",\n", - " flush=True,\n", - " )" - ] - } - ], - "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" - }, - "vscode": { - "interpreter": { - "hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6" - } - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} From cbef40950c14173b11920c756bea4ec5347cc783 Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Tue, 7 Nov 2023 17:23:17 +0000 Subject: [PATCH 25/39] add allsettr --- tutorials/hypergraph/allset_transformer_train.ipynb | 1 + 1 file changed, 1 insertion(+) diff --git a/tutorials/hypergraph/allset_transformer_train.ipynb b/tutorials/hypergraph/allset_transformer_train.ipynb index 70c8c8231..b1b57d39d 100644 --- a/tutorials/hypergraph/allset_transformer_train.ipynb +++ b/tutorials/hypergraph/allset_transformer_train.ipynb @@ -197,6 +197,7 @@ "# Ensure the graph is undirected (optional but often useful for one-hop neighborhoods).\n", "edge_index = to_undirected(edge_index)\n", "\n", + "\n", "# Create a list of one-hop neighborhoods for each node.\n", "one_hop_neighborhoods = []\n", "for node in range(data.num_nodes):\n", From 0a2161da6c76bfcc441b46e84fb5ab4903161889 Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Tue, 7 Nov 2023 17:37:31 +0000 Subject: [PATCH 26/39] added allsettr --- test/tutorials/test_hypergraph.py | 2 +- .../hypergraph/allset_transformer_train.ipynb | 101 +++++++----------- 2 files changed, 38 insertions(+), 65 deletions(-) diff --git a/test/tutorials/test_hypergraph.py b/test/tutorials/test_hypergraph.py index 720cd341e..ecce2b48b 100644 --- a/test/tutorials/test_hypergraph.py +++ b/test/tutorials/test_hypergraph.py @@ -16,7 +16,7 @@ def _exec_tutorial(path): "--to", "notebook", "--execute", - "--ExecutePreprocessor.timeout=1000", + "--ExecutePreprocessor.timeout=1500", "--ExecutePreprocessor.kernel_name=python3", "--output", file_name, diff --git a/tutorials/hypergraph/allset_transformer_train.ipynb b/tutorials/hypergraph/allset_transformer_train.ipynb index b1b57d39d..b73b18cbb 100644 --- a/tutorials/hypergraph/allset_transformer_train.ipynb +++ b/tutorials/hypergraph/allset_transformer_train.ipynb @@ -118,7 +118,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "cuda\n" + "cpu\n" ] } ], @@ -153,7 +153,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "/usr/local/lib/python3.11/site-packages/torch_geometric/data/in_memory_dataset.py:284: UserWarning: It is not recommended to directly access the internal storage format `data` of an 'InMemoryDataset'. If you are absolutely certain what you are doing, access the internal storage via `InMemoryDataset._data` instead to suppress this warning. Alternatively, you can access stacked individual attributes of every graph via `dataset.{attr_name}`.\n", + "/usr/local/lib/python3.11/site-packages/torch_geometric/data/in_memory_dataset.py:285: UserWarning: It is not recommended to directly access the internal storage format `data` of an 'InMemoryDataset'. If you are absolutely certain what you are doing, access the internal storage via `InMemoryDataset._data` instead to suppress this warning. Alternatively, you can access stacked individual attributes of every graph via `dataset.{attr_name}`.\n", " warnings.warn(msg)\n" ] } @@ -229,41 +229,26 @@ "cell_type": "code", "execution_count": 5, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Hyperedge statistics: \n", - "Number of hyperedges without duplicated hyperedges 2581\n", - "min = 1, \n", - "max = 168, \n", - "mean = 4.003099573808601, \n", - "median = 3.0, \n", - "std = 5.327622607829558, \n", - "Number of hyperedges with size equal to one = 412\n" - ] - } - ], + "outputs": [], "source": [ - "# Calculate hyperedge statistics.\n", - "hyperedge_sizes = [len(he) for he in hyperedges]\n", - "min_size = min(hyperedge_sizes)\n", - "max_size = max(hyperedge_sizes)\n", - "mean_size = np.mean(hyperedge_sizes)\n", - "median_size = np.median(hyperedge_sizes)\n", - "std_size = np.std(hyperedge_sizes)\n", - "num_single_node_hyperedges = sum(np.array(hyperedge_sizes) == 1)\n", - "\n", - "# Print the hyperedge statistics.\n", - "print(f\"Hyperedge statistics: \")\n", - "print(\"Number of hyperedges without duplicated hyperedges\", len(hyperedges))\n", - "print(f\"min = {min_size}, \")\n", - "print(f\"max = {max_size}, \")\n", - "print(f\"mean = {mean_size}, \")\n", - "print(f\"median = {median_size}, \")\n", - "print(f\"std = {std_size}, \")\n", - "print(f\"Number of hyperedges with size equal to one = {num_single_node_hyperedges}\")" + "# # Calculate hyperedge statistics.\n", + "# hyperedge_sizes = [len(he) for he in hyperedges]\n", + "# min_size = min(hyperedge_sizes)\n", + "# max_size = max(hyperedge_sizes)\n", + "# mean_size = np.mean(hyperedge_sizes)\n", + "# median_size = np.median(hyperedge_sizes)\n", + "# std_size = np.std(hyperedge_sizes)\n", + "# num_single_node_hyperedges = sum(np.array(hyperedge_sizes) == 1)\n", + "\n", + "# # Print the hyperedge statistics.\n", + "# print(f\"Hyperedge statistics: \")\n", + "# print(\"Number of hyperedges without duplicated hyperedges\", len(hyperedges))\n", + "# print(f\"min = {min_size}, \")\n", + "# print(f\"max = {max_size}, \")\n", + "# print(f\"mean = {mean_size}, \")\n", + "# print(f\"median = {median_size}, \")\n", + "# print(f\"std = {std_size}, \")\n", + "# print(f\"Number of hyperedges with size equal to one = {num_single_node_hyperedges}\")" ] }, { @@ -435,9 +420,9 @@ "name": "stderr", "output_type": "stream", "text": [ - "/tmp/ipykernel_2070/1422611997.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_793301/276484184.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " x_0s = torch.tensor(x_0s)\n", - "/tmp/ipykernel_2070/1422611997.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_793301/276484184.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " torch.tensor(y, dtype=torch.long).to(device),\n" ] } @@ -473,37 +458,25 @@ "name": "stdout", "output_type": "stream", "text": [ - "Epoch: 5 \n", - "Train_loss: 1.6679, acc: 0.9786\n", - "Val_loss: 1.0352, Val_acc: 0.7260\n", - "Test_loss: 0.9883, Test_acc: 0.7420\n", - "Epoch: 10 \n", - "Train_loss: 0.9572, acc: 1.0000\n", - "Val_loss: 1.0956, Val_acc: 0.7260\n", - "Test_loss: 0.9612, Test_acc: 0.7430\n", - "Epoch: 15 \n", - "Train_loss: 0.6462, acc: 1.0000\n", - "Val_loss: 1.4786, Val_acc: 0.7340\n", - "Test_loss: 1.2396, Test_acc: 0.7440\n", - "Epoch: 20 \n", - "Train_loss: 0.4861, acc: 1.0000\n", - "Val_loss: 1.8393, Val_acc: 0.7180\n", - "Test_loss: 1.5967, Test_acc: 0.7330\n", - "Epoch: 25 \n", - "Train_loss: 0.3892, acc: 1.0000\n", - "Val_loss: 2.1019, Val_acc: 0.7100\n", - "Test_loss: 1.8659, Test_acc: 0.7310\n", - "Epoch: 30 \n", - "Train_loss: 0.3244, acc: 1.0000\n", - "Val_loss: 2.2488, Val_acc: 0.7100\n", - "Test_loss: 2.0038, Test_acc: 0.7350\n" + "Epoch: 2 \n", + "Train_loss: 2.0269, acc: 0.2714\n", + "Val_loss: 1.8961, Val_acc: 0.1720\n", + "Test_loss: 1.8887, Test_acc: 0.1700\n", + "Epoch: 4 \n", + "Train_loss: 1.7836, acc: 0.9643\n", + "Val_loss: 1.0763, Val_acc: 0.7780\n", + "Test_loss: 1.0503, Test_acc: 0.7930\n", + "Epoch: 6 \n", + "Train_loss: 1.3919, acc: 1.0000\n", + "Val_loss: 0.8018, Val_acc: 0.7680\n", + "Test_loss: 0.7479, Test_acc: 0.7920\n" ] } ], "source": [ "torch.manual_seed(0)\n", - "test_interval = 5\n", - "num_epochs = 30\n", + "test_interval = 2\n", + "num_epochs = 6\n", "\n", "epoch_loss = []\n", "for epoch_i in range(1, num_epochs + 1):\n", From 7b5ec2532b85e70456cf586622ee75273af013d8 Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Tue, 7 Nov 2023 17:45:59 +0000 Subject: [PATCH 27/39] added allsettr --- .../hypergraph/allset_transformer_train.ipynb | 47 ------------------- 1 file changed, 47 deletions(-) diff --git a/tutorials/hypergraph/allset_transformer_train.ipynb b/tutorials/hypergraph/allset_transformer_train.ipynb index b73b18cbb..2ab136407 100644 --- a/tutorials/hypergraph/allset_transformer_train.ipynb +++ b/tutorials/hypergraph/allset_transformer_train.ipynb @@ -24,53 +24,6 @@ "🟦 $\\quad h_x^{t+1,(0)} = \\text{LN}(m_{\\rightarrow x}^{(\\rightarrow 0)} + \\text{MLP}(m_{\\rightarrow x}^{(\\rightarrow 0)} ))$\n", "\n", "\n", - "\n", - "### Additional theoretical clarifications\n", - "\n", - "Given a hypergraph $G=(\\mathcal{V}, \\mathcal{E})$, let $\\textbf{X} \\in \\mathbb{R}^{|\\mathcal{V}| \\times F}$ and $\\textbf{Z} \\in \\mathbb{R}^{|\\mathcal{E}| \\times F'}$ denote the hidden node and hyperedge representations, respectively. Additionally, define $V_{e, \\textbf{X}} = \\{\\textbf{X}_{u,:}: u \\in e\\}$ as the multiset of hidden node representations in the hyperedge $e$ and $E_{v, \\textbf{Z}} = \\{\\textbf{Z}_{e,:}: v \\in e\\}$ as the multiset of hidden representations of hyperedges containing $v$.\n", - "\n", - "\\\n", - "In this setting, the two general update rules that AllSet's framework puts in place in each layer are:\n", - "\n", - "🔷 $\\textbf{Z}_{e,:}^{(t+1)} = f_{\\mathcal{V} \\rightarrow \\mathcal{E}}(V_{e, \\textbf{X}^{(t)}}; \\textbf{Z}_{e,:}^{(t)})$\n", - "\n", - "🔷 $\\textbf{X}_{v,:}^{(t+1)} = f_{\\mathcal{E} \\rightarrow \\mathcal{V}}(E_{v, \\textbf{Z}^{(t+1)}}; \\textbf{X}_{v,:}^{(t)})$\n", - "\n", - "in which $f_{\\mathcal{V} \\rightarrow \\mathcal{E}}$ and $f_{\\mathcal{E} \\rightarrow \\mathcal{V}}$ are two permutation invariant functions with respect to their first input. The matrices $\\textbf{Z}_{e,:}^{(0)}$ and $\\textbf{X}_{v,:}^{(0)}$ are initialized with the hyperedge and node features respectively, if available, otherwise they are set to be all-zero matrices.\n", - "\n", - "In the practical implementation of the model, $f_{\\mathcal{V} \\rightarrow \\mathcal{E}}$ and $f_{\\mathcal{E} \\rightarrow \\mathcal{V}}$ are parametrized and $learnt$ for each dataset and task, and the information of their second argument is not utilized. The option achieving the best results makes use of attention-based layers, giving rise to the so-called AllSetTransformer architecture.\n", - "\n", - "\\\n", - "We now dive deep into the details of AllSetTransformer, describing how the update functions $f_{\\mathcal{V} \\rightarrow \\mathcal{E}}$ and $f_{\\mathcal{E} \\rightarrow \\mathcal{V}}$ are iteratively defined.\n", - "Their input is a matrix $\\textbf{S} \\in \\mathbb{R}^{|S| \\times F}$ which corresponds the multiset of $F$-dimensional feature vectors:\n", - "\n", - "1️⃣ $\\textbf{K}^{(i)} = \\text{MLP}^{K, i}(\\textbf{S}), \\textbf{V}^{(i)} = \\text{MLP}^{V, i}(\\textbf{S})$, where $i \\in \\{1, ..., h\\},$\n", - "\n", - "2️⃣ $ \\textbf{O}^{(i)} = \\omega (\\theta^{(i)}(\\textbf{K}^{(i)})^{T}) \\textbf{V}^{(i)},$ \n", - "\n", - "3️⃣ $\\theta \\overset{\\Delta}{=} \\mathbin\\Vert_{i=1}^{h} \\theta^{(i)}, $\n", - "\n", - "4️⃣ $ \\text{MH}_{h, \\omega}(\\theta, \\textbf{S}, \\textbf{S}) = \\mathbin\\Vert_{i=1}^{h} \\textbf{O}^{(i)}, $\n", - "\n", - "5️⃣ $ \\textbf{Y} = \\text{LN} (\\theta + \\text{MH}_{h, \\omega}(\\theta, \\textbf{S}, \\textbf{S})), $\n", - "\n", - "6️⃣ $f_{\\mathcal{V} \\rightarrow \\mathcal{E}}(\\textbf{S}) = f_{\\mathcal{E} \\rightarrow \\mathcal{V}}(\\textbf{S}) = \\text{LN} (\\textbf{Y} + \\text{MLP}(\\textbf{Y}))$.\n", - "\n", - "\\\n", - "\n", - "The elements and operations used in these steps are defined as follows:\n", - "\n", - "🔶 $\\text{LN}$ means layer normalization (Ba et al., [2016](https://arxiv.org/abs/1607.06450)),\n", - "\n", - "🔶 $\\mathbin\\Vert$ represents concatenation,\n", - "\n", - "🔶 $\\theta \\in \\mathbb{R}^{1 \\times hF_{h}}$ is a learnable weight,\n", - "\n", - "🔶 $\\text{MH}_{h, \\omega}$ denotes a multihead attention mechanism with $h$ heads and activation function $\\omega$ (Vaswani et al., [2017](https://proceedings.neurips.cc/paper_files/paper/2017/hash/3f5ee243547dee91fbd053c1c4a845aa-Abstract.html)),\n", - "\n", - "🔶 all $\\text{MLP}$ modules are multi-layer perceptrons that operate row-wise, so they are applied identically and independently to each multiset element of $\\textbf{S}$.\n", - "\n", - "\n", "\n" ] }, From c1df84ee521b83207944f3601af495d7b604fcbe Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Tue, 7 Nov 2023 17:53:35 +0000 Subject: [PATCH 28/39] new allsettr --- .../hypergraph/allset_transformer_train.ipynb | 192 ++++++++++++------ 1 file changed, 131 insertions(+), 61 deletions(-) diff --git a/tutorials/hypergraph/allset_transformer_train.ipynb b/tutorials/hypergraph/allset_transformer_train.ipynb index 2ab136407..3641dc8f9 100644 --- a/tutorials/hypergraph/allset_transformer_train.ipynb +++ b/tutorials/hypergraph/allset_transformer_train.ipynb @@ -5,8 +5,6 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "\n", - "\n", "# Train an All-Set-Transformer TNN\n", "\n", "In this notebook, we will create and train a two-step message passing network named AllSetTransformer (Chien et al., [2021](https://arxiv.org/abs/2106.13264)) in the hypergraph domain. We will use a benchmark dataset, shrec16, a collection of 3D meshes, to train the model to perform classification at the level of the hypergraph. \n", @@ -23,13 +21,56 @@ "\n", "🟦 $\\quad h_x^{t+1,(0)} = \\text{LN}(m_{\\rightarrow x}^{(\\rightarrow 0)} + \\text{MLP}(m_{\\rightarrow x}^{(\\rightarrow 0)} ))$\n", "\n", + "### Additional theoretical clarifications\n", + "\n", + "Given a hypergraph $G=(\\mathcal{V}, \\mathcal{E})$, let $\\textbf{X} \\in \\mathbb{R}^{|\\mathcal{V}| \\times F}$ and $\\textbf{Z} \\in \\mathbb{R}^{|\\mathcal{E}| \\times F'}$ denote the hidden node and hyperedge representations, respectively. Additionally, define $V_{e, \\textbf{X}} = \\{\\textbf{X}_{u,:}: u \\in e\\}$ as the multiset of hidden node representations in the hyperedge $e$ and $E_{v, \\textbf{Z}} = \\{\\textbf{Z}_{e,:}: v \\in e\\}$ as the multiset of hidden representations of hyperedges containing $v$.\n", + "\n", + "\\\n", + "In this setting, the two general update rules that AllSet's framework puts in place in each layer are:\n", + "\n", + "🔷 $\\textbf{Z}_{e,:}^{(t+1)} = f_{\\mathcal{V} \\rightarrow \\mathcal{E}}(V_{e, \\textbf{X}^{(t)}}; \\textbf{Z}_{e,:}^{(t)})$\n", + "\n", + "🔷 $\\textbf{X}_{v,:}^{(t+1)} = f_{\\mathcal{E} \\rightarrow \\mathcal{V}}(E_{v, \\textbf{Z}^{(t+1)}}; \\textbf{X}_{v,:}^{(t)})$\n", + "\n", + "in which $f_{\\mathcal{V} \\rightarrow \\mathcal{E}}$ and $f_{\\mathcal{E} \\rightarrow \\mathcal{V}}$ are two permutation invariant functions with respect to their first input. The matrices $\\textbf{Z}_{e,:}^{(0)}$ and $\\textbf{X}_{v,:}^{(0)}$ are initialized with the hyperedge and node features respectively, if available, otherwise they are set to be all-zero matrices.\n", + "\n", + "In the practical implementation of the model, $f_{\\mathcal{V} \\rightarrow \\mathcal{E}}$ and $f_{\\mathcal{E} \\rightarrow \\mathcal{V}}$ are parametrized and $learnt$ for each dataset and task, and the information of their second argument is not utilized. The option achieving the best results makes use of attention-based layers, giving rise to the so-called AllSetTransformer architecture.\n", + "\n", + "\\\n", + "We now dive deep into the details of AllSetTransformer, describing how the update functions $f_{\\mathcal{V} \\rightarrow \\mathcal{E}}$ and $f_{\\mathcal{E} \\rightarrow \\mathcal{V}}$ are iteratively defined.\n", + "Their input is a matrix $\\textbf{S} \\in \\mathbb{R}^{|S| \\times F}$ which corresponds the multiset of $F$-dimensional feature vectors:\n", + "\n", + "1️⃣ $\\textbf{K}^{(i)} = \\text{MLP}^{K, i}(\\textbf{S}), \\textbf{V}^{(i)} = \\text{MLP}^{V, i}(\\textbf{S})$, where $i \\in \\{1, ..., h\\},$\n", + "\n", + "2️⃣ $ \\textbf{O}^{(i)} = \\omega (\\theta^{(i)}(\\textbf{K}^{(i)})^{T}) \\textbf{V}^{(i)},$ \n", + "\n", + "3️⃣ $\\theta \\overset{\\Delta}{=} \\mathbin\\Vert_{i=1}^{h} \\theta^{(i)}, $\n", + "\n", + "4️⃣ $ \\text{MH}_{h, \\omega}(\\theta, \\textbf{S}, \\textbf{S}) = \\mathbin\\Vert_{i=1}^{h} \\textbf{O}^{(i)}, $\n", + "\n", + "5️⃣ $ \\textbf{Y} = \\text{LN} (\\theta + \\text{MH}_{h, \\omega}(\\theta, \\textbf{S}, \\textbf{S})), $\n", + "\n", + "6️⃣ $f_{\\mathcal{V} \\rightarrow \\mathcal{E}}(\\textbf{S}) = f_{\\mathcal{E} \\rightarrow \\mathcal{V}}(\\textbf{S}) = \\text{LN} (\\textbf{Y} + \\text{MLP}(\\textbf{Y}))$.\n", + "\n", + "\\\n", "\n", + "The elements and operations used in these steps are defined as follows:\n", + "\n", + "🔶 $\\text{LN}$ means layer normalization (Ba et al., [2016](https://arxiv.org/abs/1607.06450)),\n", + "\n", + "🔶 $\\mathbin\\Vert$ represents concatenation,\n", + "\n", + "🔶 $\\theta \\in \\mathbb{R}^{1 \\times hF_{h}}$ is a learnable weight,\n", + "\n", + "🔶 $\\text{MH}_{h, \\omega}$ denotes a multihead attention mechanism with $h$ heads and activation function $\\omega$ (Vaswani et al., [2017](https://proceedings.neurips.cc/paper_files/paper/2017/hash/3f5ee243547dee91fbd053c1c4a845aa-Abstract.html)),\n", + "\n", + "🔶 all $\\text{MLP}$ modules are multi-layer perceptrons that operate row-wise, so they are applied identically and independently to each multiset element of $\\textbf{S}$.\n", "\n" ] }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 4, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:51.222779223Z", @@ -38,6 +79,16 @@ }, "outputs": [], "source": [ + "\"\"\"\n", + "This module contains the AllSet class for hypergraph-based neural networks.\n", + "\n", + "The AllSet class implements a specific hypergraph-based neural network architecture\n", + "used for solving certain types of problems.\n", + "\n", + "Author: Your Name\n", + "\n", + "\"\"\"\n", + "\n", "import torch\n", "import numpy as np\n", "from torch_geometric.utils import to_undirected\n", @@ -59,7 +110,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 5, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:51.959770754Z", @@ -89,12 +140,12 @@ "\n", "## Import data ##\n", "\n", - "The first step is to import the dataset, Cora, a benchmark classification datase. We then lift the graph into our domain of choice, a hypergraph." + "The first step is to import the dataset, Cora, a benchmark classification datase. We then lift the graph into our domain of choice, a hypergraph.\n" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 6, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:53.022151550Z", @@ -138,7 +189,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 7, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:53.022151550Z", @@ -150,7 +201,6 @@ "# Ensure the graph is undirected (optional but often useful for one-hop neighborhoods).\n", "edge_index = to_undirected(edge_index)\n", "\n", - "\n", "# Create a list of one-hop neighborhoods for each node.\n", "one_hop_neighborhoods = []\n", "for node in range(data.num_nodes):\n", @@ -180,28 +230,43 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 8, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Hyperedge statistics: \n", + "Number of hyperedges without duplicated hyperedges 2581\n", + "min = 1, \n", + "max = 168, \n", + "mean = 4.003099573808601, \n", + "median = 3.0, \n", + "std = 5.327622607829558, \n", + "Number of hyperedges with size equal to one = 412\n" + ] + } + ], "source": [ - "# # Calculate hyperedge statistics.\n", - "# hyperedge_sizes = [len(he) for he in hyperedges]\n", - "# min_size = min(hyperedge_sizes)\n", - "# max_size = max(hyperedge_sizes)\n", - "# mean_size = np.mean(hyperedge_sizes)\n", - "# median_size = np.median(hyperedge_sizes)\n", - "# std_size = np.std(hyperedge_sizes)\n", - "# num_single_node_hyperedges = sum(np.array(hyperedge_sizes) == 1)\n", - "\n", - "# # Print the hyperedge statistics.\n", - "# print(f\"Hyperedge statistics: \")\n", - "# print(\"Number of hyperedges without duplicated hyperedges\", len(hyperedges))\n", - "# print(f\"min = {min_size}, \")\n", - "# print(f\"max = {max_size}, \")\n", - "# print(f\"mean = {mean_size}, \")\n", - "# print(f\"median = {median_size}, \")\n", - "# print(f\"std = {std_size}, \")\n", - "# print(f\"Number of hyperedges with size equal to one = {num_single_node_hyperedges}\")" + "# Calculate hyperedge statistics.\n", + "hyperedge_sizes = [len(he) for he in hyperedges]\n", + "min_size = min(hyperedge_sizes)\n", + "max_size = max(hyperedge_sizes)\n", + "mean_size = np.mean(hyperedge_sizes)\n", + "median_size = np.median(hyperedge_sizes)\n", + "std_size = np.std(hyperedge_sizes)\n", + "num_single_node_hyperedges = sum(np.array(hyperedge_sizes) == 1)\n", + "\n", + "# Print the hyperedge statistics.\n", + "print(f\"Hyperedge statistics: \")\n", + "print(\"Number of hyperedges without duplicated hyperedges\", len(hyperedges))\n", + "print(f\"min = {min_size}, \")\n", + "print(f\"max = {max_size}, \")\n", + "print(f\"mean = {mean_size}, \")\n", + "print(f\"median = {median_size}, \")\n", + "print(f\"std = {std_size}, \")\n", + "print(f\"Number of hyperedges with size equal to one = {num_single_node_hyperedges}\")" ] }, { @@ -213,7 +278,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -233,8 +298,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "# Define the Neural Network\n", - "\n" + "# Create the Neural Network" ] }, { @@ -242,12 +306,12 @@ "metadata": {}, "source": [ "Define the network that initializes the base model and sets up the readout operation.\n", - "Different downstream tasks might require different pooling procedures." + "Different downstream tasks might require different pooling procedures.\n" ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ @@ -310,7 +374,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 13, "metadata": {}, "outputs": [], "source": [ @@ -350,7 +414,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 14, "metadata": {}, "outputs": [], "source": [ @@ -366,16 +430,21 @@ }, { "cell_type": "code", - "execution_count": 10, - "metadata": {}, + "execution_count": 15, + "metadata": { + "ExecuteTime": { + "end_time": "2023-06-01T16:14:59.046068930Z", + "start_time": "2023-06-01T16:14:59.037648626Z" + } + }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "/tmp/ipykernel_793301/276484184.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_802086/276484184.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " x_0s = torch.tensor(x_0s)\n", - "/tmp/ipykernel_793301/276484184.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_802086/276484184.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " torch.tensor(y, dtype=torch.long).to(device),\n" ] } @@ -399,37 +468,31 @@ }, { "cell_type": "code", - "execution_count": 11, - "metadata": { - "ExecuteTime": { - "end_time": "2023-06-01T16:15:01.683216142Z", - "start_time": "2023-06-01T16:15:00.727075750Z" - } - }, + "execution_count": 16, + "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Epoch: 2 \n", - "Train_loss: 2.0269, acc: 0.2714\n", - "Val_loss: 1.8961, Val_acc: 0.1720\n", - "Test_loss: 1.8887, Test_acc: 0.1700\n", - "Epoch: 4 \n", - "Train_loss: 1.7836, acc: 0.9643\n", - "Val_loss: 1.0763, Val_acc: 0.7780\n", - "Test_loss: 1.0503, Test_acc: 0.7930\n", - "Epoch: 6 \n", - "Train_loss: 1.3919, acc: 1.0000\n", - "Val_loss: 0.8018, Val_acc: 0.7680\n", - "Test_loss: 0.7479, Test_acc: 0.7920\n" + "Epoch: 5 \n", + "Train_loss: 1.5679, acc: 0.9929\n", + "Val_loss: 0.9291, Val_acc: 0.7360\n", + "Test_loss: 0.8751, Test_acc: 0.7670\n", + "Epoch: 10 \n", + "Train_loss: 0.8660, acc: 1.0000\n", + "Val_loss: 1.0993, Val_acc: 0.7380\n", + "Test_loss: 1.0621, Test_acc: 0.7370\n", + "Epoch: 15 \n", + "Train_loss: 0.5851, acc: 1.0000\n", + "Val_loss: 1.7357, Val_acc: 0.6780\n", + "Test_loss: 1.5269, Test_acc: 0.7230\n" ] } ], "source": [ - "torch.manual_seed(0)\n", - "test_interval = 2\n", - "num_epochs = 6\n", + "test_interval = 5\n", + "num_epochs = 10\n", "\n", "epoch_loss = []\n", "for epoch_i in range(1, num_epochs + 1):\n", @@ -469,6 +532,13 @@ " flush=True,\n", " )" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { From 6d53cd21c6204021b891474d2f395c9fa4e18c97 Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Tue, 7 Nov 2023 18:57:25 +0000 Subject: [PATCH 29/39] corrections --- topomodelx/nn/hypergraph/allset.py | 6 +- topomodelx/nn/hypergraph/allset_layer.py | 2 +- .../nn/hypergraph/allset_transformer.py | 8 +- .../nn/hypergraph/allset_transformer_layer.py | 4 +- topomodelx/nn/hypergraph/dhgcn.py | 2 +- topomodelx/nn/hypergraph/dhgcn_layer.py | 2 +- topomodelx/nn/hypergraph/hmpnn.py | 12 +-- topomodelx/nn/hypergraph/hmpnn_layer.py | 9 +- topomodelx/nn/hypergraph/hnhn.py | 2 +- topomodelx/nn/hypergraph/hnhn_layer_bis.py | 97 ------------------- topomodelx/nn/hypergraph/hypersage_layer.py | 4 +- topomodelx/nn/hypergraph/unigcn.py | 2 +- topomodelx/nn/hypergraph/unigcn_layer.py | 4 +- topomodelx/nn/hypergraph/unigcnii.py | 15 ++- topomodelx/nn/hypergraph/unigin.py | 11 +-- topomodelx/nn/hypergraph/unigin_layer.py | 6 +- topomodelx/nn/hypergraph/unisage.py | 7 +- topomodelx/nn/hypergraph/unisage_layer.py | 4 +- 18 files changed, 44 insertions(+), 153 deletions(-) delete mode 100644 topomodelx/nn/hypergraph/hnhn_layer_bis.py diff --git a/topomodelx/nn/hypergraph/allset.py b/topomodelx/nn/hypergraph/allset.py index 520fe9095..a5eb211b1 100644 --- a/topomodelx/nn/hypergraph/allset.py +++ b/topomodelx/nn/hypergraph/allset.py @@ -18,13 +18,13 @@ class AllSet(torch.nn.Module): Dimension of the hidden features. n_layers : int, default: 2 Number of AllSet layers in the network. - layer_dropout: + layer_dropout: float, default: 0.2 Dropout probability for the AllSet layer. mlp_num_layers : int, default: 2 Number of layers in the MLP. mlp_dropout : float, default: 0.0 Dropout probability for the MLP. - mlp_activation: + mlp_activation : torch.nn.Module, default: None Activation function in the MLP. mlp_norm : bool, default: False Whether to apply input normalization in the MLP. @@ -95,4 +95,4 @@ def forward(self, x_0, incidence_1): for layer in self.layers: x_0, x_1 = layer(x_0, incidence_1) - return (x_0, x_1) + return x_0, x_1 diff --git a/topomodelx/nn/hypergraph/allset_layer.py b/topomodelx/nn/hypergraph/allset_layer.py index f05a8e244..0c9ed84ca 100644 --- a/topomodelx/nn/hypergraph/allset_layer.py +++ b/topomodelx/nn/hypergraph/allset_layer.py @@ -126,7 +126,7 @@ def forward(self, x_0, incidence_1): x_0 = self.edge2vertex(x_1, incidence_1) x_0 = F.dropout(x_0, p=self.dropout, training=self.training) - return (x_0, x_1) + return x_0, x_1 class MLP(nn.Sequential): diff --git a/topomodelx/nn/hypergraph/allset_transformer.py b/topomodelx/nn/hypergraph/allset_transformer.py index ded6b95a3..88f2199ba 100644 --- a/topomodelx/nn/hypergraph/allset_transformer.py +++ b/topomodelx/nn/hypergraph/allset_transformer.py @@ -20,11 +20,11 @@ class AllSetTransformer(torch.nn.Module): Number of AllSet layers in the network. heads : int, default: 4 Number of attention heads. - dropout : float + dropout : float, default: 0.2 Dropout probability. mlp_num_layers : int, default: 2 Number of layers in the MLP. - mlp_dropout: + mlp_dropout: float, default: 0.2 Dropout probability in the MLP. References @@ -43,7 +43,7 @@ def __init__( heads=4, dropout=0.2, mlp_num_layers=2, - mlp_dropout=0.0, + mlp_dropout=0.2, ): super().__init__() layers = [ @@ -89,4 +89,4 @@ def forward(self, x_0, incidence_1): for layer in self.layers: x_0, x_1 = layer(x_0, incidence_1) - return (x_0, x_1) + return x_0, x_1 diff --git a/topomodelx/nn/hypergraph/allset_transformer_layer.py b/topomodelx/nn/hypergraph/allset_transformer_layer.py index af0eba3ca..fa93f92bb 100644 --- a/topomodelx/nn/hypergraph/allset_transformer_layer.py +++ b/topomodelx/nn/hypergraph/allset_transformer_layer.py @@ -164,7 +164,7 @@ class AllSetTransformerBlock(nn.Module): Number of attention heads. number_queries : int, default=1 Number of queries. - dropout : float, optional + dropout : float, default=0.0 Dropout probability. mlp_num_layers : int, default=1 Number of layers in the MLP. @@ -184,7 +184,7 @@ def __init__( hidden_channels, heads: int = 4, number_queries: int = 1, - dropout: float = 0.0, + dropout: float = 0., mlp_num_layers: int = 1, mlp_activation=None, mlp_dropout: float = 0.0, diff --git a/topomodelx/nn/hypergraph/dhgcn.py b/topomodelx/nn/hypergraph/dhgcn.py index a81c077e4..f421562ba 100644 --- a/topomodelx/nn/hypergraph/dhgcn.py +++ b/topomodelx/nn/hypergraph/dhgcn.py @@ -69,4 +69,4 @@ def forward(self, x_0): for layer in self.layers: x_0, x_1 = layer(x_0) - return (x_0, x_1) + return x_0, x_1 diff --git a/topomodelx/nn/hypergraph/dhgcn_layer.py b/topomodelx/nn/hypergraph/dhgcn_layer.py index 0f2252072..d04b1e80f 100644 --- a/topomodelx/nn/hypergraph/dhgcn_layer.py +++ b/topomodelx/nn/hypergraph/dhgcn_layer.py @@ -219,7 +219,7 @@ def forward(self, x_0): x_1 : torch.Tensor Output hyperedge features. """ - # dynamic topology processing: + # Dynamic topology processing: x_0_features = self.fc_layer(x_0) incidence_1_dynamic_topology = self.get_dynamic_topology(x_0_features) incidence_1_dynamic_topology_transpose = incidence_1_dynamic_topology.transpose( diff --git a/topomodelx/nn/hypergraph/hmpnn.py b/topomodelx/nn/hypergraph/hmpnn.py index 6540a2000..2ff151731 100644 --- a/topomodelx/nn/hypergraph/hmpnn.py +++ b/topomodelx/nn/hypergraph/hmpnn.py @@ -22,7 +22,7 @@ class HMPNN(torch.nn.Module): Number of HMPNNLayer layers. adjacency_dropout_rate: int, default = 0.7 Adjacency dropout rate. - regular_dropout_rate: int, default = 0.5 + regular_dropout_rate : int, default = 0.5 Regular dropout rate applied on features. References @@ -45,12 +45,6 @@ def __init__( self.linear_node = torch.nn.Linear(in_channels, hidden_channels) self.linear_edge = torch.nn.Linear(in_channels, hidden_channels) - # self.to_hidden_linear = torch.nn.Sequential( - # *[ - # torch.nn.Linear(hidden_features[i], hidden_features[i + 1]) - # for i in range(len(hidden_features) - 1) - # ] - # ) self.layers = torch.nn.ModuleList( [ @@ -62,7 +56,7 @@ def __init__( for _ in range(n_layers) ] ) - # self.to_categories_linear = torch.nn.Linear(hidden_features[-1], num_classes) + def forward(self, x_0, x_1, incidence_1): """Forward computation through layers. @@ -89,4 +83,4 @@ def forward(self, x_0, x_1, incidence_1): for layer in self.layers: x_0, x_1 = layer(x_0, x_1, incidence_1) - return (x_0, x_1) + return x_0, x_1 diff --git a/topomodelx/nn/hypergraph/hmpnn_layer.py b/topomodelx/nn/hypergraph/hmpnn_layer.py index 2b181e041..e9b7a7bdf 100644 --- a/topomodelx/nn/hypergraph/hmpnn_layer.py +++ b/topomodelx/nn/hypergraph/hmpnn_layer.py @@ -94,7 +94,6 @@ def forward(self, x_1, m_0): class _DefaultUpdatingFunc(nn.Module): def __init__(self, in_channels) -> None: super().__init__() - # self.linear = nn.Linear(in_channels, in_channels) def forward(self, x, m): return F.sigmoid(x + m) @@ -134,13 +133,13 @@ class HMPNNLayer(nn.Module): and aggregated messages of nodes as input and returns hyperedge messages. If not given, two inputs are concatenated and a linear layer reducing back to in_channels plus sigmoid is applied, according to the paper. - adjacency_dropout: int, default = 0.7 + adjacency_dropout : int, default = 0.7 Adjacency dropout rate. - aggr_func: Literal["sum", "mean", "add"], default="sum" + aggr_func : Literal["sum", "mean", "add"], default="sum" Message aggregation function. - updating_dropout: int, default = 0.5 + updating_dropout : int, default = 0.5 Regular dropout rate applied to node and hyperedge features. - updating_func: None + updating_func : callable or None, default = None The final function or nn.Module object to be called on node and hyperedge features to retrieve their new representation. If not given, a linear layer is applied, received message is added and sigmoid is called. diff --git a/topomodelx/nn/hypergraph/hnhn.py b/topomodelx/nn/hypergraph/hnhn.py index 8d61ac15c..ce9a9977e 100644 --- a/topomodelx/nn/hypergraph/hnhn.py +++ b/topomodelx/nn/hypergraph/hnhn.py @@ -16,7 +16,7 @@ class HNHN(torch.nn.Module): Dimension of the hidden features. incidence_1 : torch.sparse, shape = (n_nodes, n_edges) Incidence matrix mapping edges to nodes (B_1). - n_layers : int + n_layers : int, default = 2 Number of HNHN message passing layers. References diff --git a/topomodelx/nn/hypergraph/hnhn_layer_bis.py b/topomodelx/nn/hypergraph/hnhn_layer_bis.py deleted file mode 100644 index 2758283d8..000000000 --- a/topomodelx/nn/hypergraph/hnhn_layer_bis.py +++ /dev/null @@ -1,97 +0,0 @@ -"""HNHN (Hypergraph Network with Hyperedge Neurons) Layer introduced in Dong et al. 2020.""" - -import torch -from torch.nn import functional as F - - -class HNHNLayer(torch.nn.Module): - """HNHN Layer [1]_. - - Given the input representation of nodes, this layer returns a new representation using hyperedges - as a relay. In other words it makes a intermediary representation for hyperedges with those of the nodes - and then makes the final representation of the nodes using the representation of the hyperedges. - During building the representation for a hyperedge/node, this layer multiplies a normalized weight to the - features of the neighboring nodes/hyperedges, reflecting different levels of importance across the neighbors. - - Parameters - ---------- - in_features : int - The input dimension of node features. - incidence_1 : torch.sparse.Tensor, shape = (n_nodes, n_edges) - Incidence matrix mapping hyperedges to nodes (B_1). - activation_func : Callable - Called on the new representations. - normalization_param_alpha : float - The param that weights multiplied into hyperedge representations are powered to beforehand. - normalization_param_beta : float - The param that weights multiplied into node representations are powered to beforehand. - - References - ---------- - .. [1] Dong, Sawin, Bengio. - HNHN: hypergraph networks with hyperedge neurons. - Graph Representation Learning and Beyond Workshop at ICML 2020. - https://grlplus.github.io/papers/40.pdf - """ - - def __init__( - self, - in_features, - incidence_1, - activation_func=F.relu, - normalization_param_alpha: float = 0.0, - normalization_param_beta: float = 0.0, - ) -> None: - super().__init__() - - incidence_1 = incidence_1.to(torch.float) - - d_E = incidence_1.sum(dim=0).to_dense() - d_E_powered = d_E**normalization_param_alpha - # In HNHN layer, it is assumed that a node is attached to at least one hyperedge, so the - # division below is valid. - normalizing_factor = 1 / torch.sparse.mm(incidence_1, d_E_powered.view(-1, 1)) - self.weighted_hyperedge_to_node_incidence = ( - normalizing_factor * incidence_1 * d_E_powered - ) - - d_V = incidence_1.sum(dim=1).to_dense() - d_V_powered = d_V**normalization_param_beta - incidence_1_T = incidence_1.transpose(1, 0) - normalizing_factor = 1 / torch.sparse.mm(incidence_1_T, d_V_powered.view(-1, 1)) - self.weighted_node_to_hyperedge_incidence = ( - normalizing_factor * incidence_1_T * d_V_powered - ) - - self.node_linear_transform = torch.nn.Linear(in_features, in_features) - self.hyperedge_linear_transform = torch.nn.Linear(in_features, in_features) - - self.activation = activation_func - - def forward(self, x_0): - r"""Forward computation. - - Parameters - ---------- - x_0 : torch.Tensor, shape = (n_nodes, in_features) - Input features of the nodes. - - Returns - ------- - x_0 : torch.Tensor, shape = (n_nodes, in_features) - Output features of the nodes. - x_1 : torch.Tensor, shape = (n_hyperedges, in_features) - Output features of the hyperedges. - """ - x_1_prime = self.activation( - self.hyperedge_linear_transform( - self.weighted_node_to_hyperedge_incidence @ x_0 - ) - ) - x_0_prime = self.activation( - self.node_linear_transform( - self.weighted_hyperedge_to_node_incidence @ x_1_prime - ) - ) - - return x_0_prime, x_1_prime diff --git a/topomodelx/nn/hypergraph/hypersage_layer.py b/topomodelx/nn/hypergraph/hypersage_layer.py index 74c5b7d25..c3ce0d240 100644 --- a/topomodelx/nn/hypergraph/hypersage_layer.py +++ b/topomodelx/nn/hypergraph/hypersage_layer.py @@ -51,9 +51,9 @@ class HyperSAGELayer(MessagePassing): Dimension of the input features. out_channels : int Dimension of the output features. - aggr_func_intra : Aggregation + aggr_func_intra : callable, default=GeneralizedMean(p=2) Aggregation function. Default is GeneralizedMean(p=2). - aggr_func_inter : Aggregation + aggr_func_inter : callable, default=GeneralizedMean(p=2) Aggregation function. Default is GeneralizedMean(p=2). update_func : Literal["relu", "sigmoid"], default="relu" Update method to apply to message. diff --git a/topomodelx/nn/hypergraph/unigcn.py b/topomodelx/nn/hypergraph/unigcn.py index 40d87105f..5296b113e 100644 --- a/topomodelx/nn/hypergraph/unigcn.py +++ b/topomodelx/nn/hypergraph/unigcn.py @@ -69,4 +69,4 @@ def forward(self, x_0, incidence_1): for layer in self.layers: x_0, x_1 = layer(x_0, incidence_1) - return (x_0, x_1) + return x_0, x_1 diff --git a/topomodelx/nn/hypergraph/unigcn_layer.py b/topomodelx/nn/hypergraph/unigcn_layer.py index 0de324290..2fe963fee 100644 --- a/topomodelx/nn/hypergraph/unigcn_layer.py +++ b/topomodelx/nn/hypergraph/unigcn_layer.py @@ -16,7 +16,7 @@ class UniGCNLayer(torch.nn.Module): Dimension of the input features. hidden_channels : int Dimension of the hidden features. - use_bn : boolean, default=False + use_bn : bool, default=False Whether to use bathnorm after the linear transformation. aggr_norm : bool, default=False Whether to normalize the aggregated message by the neighborhood size. @@ -122,4 +122,4 @@ def forward(self, x_0, incidence_1): if self.bn is not None: x_1 = self.bn(x_1) x_0 = self.conv_level2_1_to_0(x_1, incidence_1) - return (x_0, x_1) + return x_0, x_1 diff --git a/topomodelx/nn/hypergraph/unigcnii.py b/topomodelx/nn/hypergraph/unigcnii.py index 12bbb459d..210f8e618 100644 --- a/topomodelx/nn/hypergraph/unigcnii.py +++ b/topomodelx/nn/hypergraph/unigcnii.py @@ -16,15 +16,15 @@ class UniGCNII(torch.nn.Module): Dimension of the input features. hidden_channels : int Dimension of the hidden features. - n_layers: int, default=2 + n_layers : int, default=2 Number of UniGCNII message passing layers. alpha : float, default=0.5 Parameter of the UniGCNII layer. beta : float, default=0.5 Parameter of the UniGCNII layer. - input_drop: float, default=0.2 + input_drop : float, default=0.2 Dropout rate for the input features. - layer_drop: float, default=0.2 + layer_drop : float, default=0.2 Dropout rate for the hidden features. References @@ -50,10 +50,9 @@ def __init__( self.input_drop = torch.nn.Dropout(input_drop) self.layer_drop = torch.nn.Dropout(layer_drop) - # Define initial linear layer - self.linear_init = torch.nn.Linear(in_channels, hidden_channels) - # Define convolutional layers + self.initial_linear_layer = torch.nn.Linear(in_channels, hidden_channels) + for i in range(n_layers): beta = math.log(alpha / (i + 1) + 1) layers.append( @@ -86,7 +85,7 @@ def forward(self, x_0, incidence_1): Output hyperedge features. """ x_0 = self.input_drop(x_0) - x_0 = self.linear_init(x_0) + x_0 = self.initial_linear_layer(x_0) x_0 = torch.nn.functional.relu(x_0) x_0_skip = x_0 @@ -95,4 +94,4 @@ def forward(self, x_0, incidence_1): x_0 = self.layer_drop(x_0) x_0 = torch.nn.functional.relu(x_0) - return (x_0, x_1) + return x_0, x_1 diff --git a/topomodelx/nn/hypergraph/unigin.py b/topomodelx/nn/hypergraph/unigin.py index 2bf7a43ab..e6d7376a4 100644 --- a/topomodelx/nn/hypergraph/unigin.py +++ b/topomodelx/nn/hypergraph/unigin.py @@ -16,9 +16,9 @@ class UniGIN(torch.nn.Module): Dimension of the hidden features. n_layers : int, default = 2 Amount of message passing layers. - input_drop: float, default=0.2 + input_drop : float, default=0.2 Dropout rate for the input features. - layer_drop: float, default=0.2 + layer_drop : float, default=0.2 Dropout rate for the hidden features. @@ -44,8 +44,7 @@ def __init__( self.input_drop = torch.nn.Dropout(input_drop) self.layer_drop = torch.nn.Dropout(layer_drop) - # Define initial linear layer - self.linear_init = torch.nn.Linear(in_channels, hidden_channels) + self.initial_linear_layer = torch.nn.Linear(in_channels, hidden_channels) for _ in range(n_layers): layers.append( @@ -74,10 +73,10 @@ def forward(self, x_0, incidence_1): x_1 : torch.Tensor Output hyperedge features. """ - x_0 = self.linear_init(x_0) + x_0 = self.initial_linear_layer(x_0) for layer in self.layers: x_0, x_1 = layer(x_0, incidence_1) x_0 = self.layer_drop(x_0) x_0 = torch.nn.functional.relu(x_0) - return (x_0, x_1) + return x_0, x_1 diff --git a/topomodelx/nn/hypergraph/unigin_layer.py b/topomodelx/nn/hypergraph/unigin_layer.py index eac6f2c25..5add4e297 100644 --- a/topomodelx/nn/hypergraph/unigin_layer.py +++ b/topomodelx/nn/hypergraph/unigin_layer.py @@ -11,9 +11,9 @@ class UniGINLayer(torch.nn.Module): ---------- in_channels : int Dimension of input features. - eps : float + eps : float, default=0.0 Constant in GIN Update equation. - train_eps : bool + train_eps : boolm, default=False Whether to make eps a trainable parameter. References @@ -98,4 +98,4 @@ def forward(self, x_0, incidence_1): m_1_0 = torch.sparse.mm(incidence_1.float(), x_1) # Update node features using GIN update equation x_0 = self.linear((1 + self.eps) * x_0 + m_1_0) - return (x_0, x_1) + return x_0, x_1 diff --git a/topomodelx/nn/hypergraph/unisage.py b/topomodelx/nn/hypergraph/unisage.py index 87ac14815..ecb5072a1 100644 --- a/topomodelx/nn/hypergraph/unisage.py +++ b/topomodelx/nn/hypergraph/unisage.py @@ -14,9 +14,9 @@ class UniSAGE(torch.nn.Module): Dimension of the input features. hidden_channels : int Dimension of the hidden features. - input_drop: float, default=0.2 + input_drop : float, default=0.2 Dropout rate for the input features. - layer_drop: float, default=0.2 + layer_drop : float, default=0.2 Dropout rate for the hidden features. n_layers : int, default = 2 Amount of message passing layers. @@ -78,10 +78,9 @@ def forward(self, x_0, incidence_1): """ x_0 = self.input_drop(x_0) - # Iterate over layers for layer in self.layers: x_0, x_1 = layer(x_0, incidence_1) x_0 = self.layer_drop(x_0) x_0 = torch.nn.functional.relu(x_0) - return (x_0, x_1) + return x_0, x_1 diff --git a/topomodelx/nn/hypergraph/unisage_layer.py b/topomodelx/nn/hypergraph/unisage_layer.py index 2fd2054b8..b1264860c 100644 --- a/topomodelx/nn/hypergraph/unisage_layer.py +++ b/topomodelx/nn/hypergraph/unisage_layer.py @@ -65,10 +65,8 @@ def __init__( self.hidden_channels = hidden_channels self.bn = torch.nn.BatchNorm1d(hidden_channels) if use_bn else None - # Initial linear transformation self.linear = torch.nn.Linear(in_channels, hidden_channels) - # Define the aggregation self.v_aggr = v_aggr self.e_aggr = e_aggr @@ -148,4 +146,4 @@ def forward(self, x_0, incidence_1): m_1_0 = self.edge2vertex(x_1, incidence_1) x_0 = x_0 + m_1_0 - return (x_0, x_1) + return x_0, x_1 From b745e702dac09223e03f2f482d1a87e6a2b048f2 Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Tue, 7 Nov 2023 19:00:20 +0000 Subject: [PATCH 30/39] corrections and black . --- topomodelx/nn/hypergraph/allset_transformer_layer.py | 2 +- topomodelx/nn/hypergraph/hmpnn.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/topomodelx/nn/hypergraph/allset_transformer_layer.py b/topomodelx/nn/hypergraph/allset_transformer_layer.py index fa93f92bb..9d2271f69 100644 --- a/topomodelx/nn/hypergraph/allset_transformer_layer.py +++ b/topomodelx/nn/hypergraph/allset_transformer_layer.py @@ -184,7 +184,7 @@ def __init__( hidden_channels, heads: int = 4, number_queries: int = 1, - dropout: float = 0., + dropout: float = 0.0, mlp_num_layers: int = 1, mlp_activation=None, mlp_dropout: float = 0.0, diff --git a/topomodelx/nn/hypergraph/hmpnn.py b/topomodelx/nn/hypergraph/hmpnn.py index 2ff151731..d2ef5a6eb 100644 --- a/topomodelx/nn/hypergraph/hmpnn.py +++ b/topomodelx/nn/hypergraph/hmpnn.py @@ -57,7 +57,6 @@ def __init__( ] ) - def forward(self, x_0, x_1, incidence_1): """Forward computation through layers. From 751aef8c2d0a39d5c72e08cd61a6e2a8a16c048d Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Tue, 7 Nov 2023 20:44:41 +0000 Subject: [PATCH 31/39] allsettransformer once more --- .../hypergraph/allset_transformer_train.ipynb | 52 +++++++------------ 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/tutorials/hypergraph/allset_transformer_train.ipynb b/tutorials/hypergraph/allset_transformer_train.ipynb index 3641dc8f9..93004150d 100644 --- a/tutorials/hypergraph/allset_transformer_train.ipynb +++ b/tutorials/hypergraph/allset_transformer_train.ipynb @@ -70,7 +70,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 1, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:51.222779223Z", @@ -110,7 +110,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 2, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:51.959770754Z", @@ -145,7 +145,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 3, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:53.022151550Z", @@ -189,7 +189,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 4, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:53.022151550Z", @@ -230,7 +230,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -278,7 +278,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -311,12 +311,12 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "class Network(torch.nn.Module):\n", - " \"\"\"Network class that initializes the base model and readout layer.\n", + " \"\"\"Network class that initializes the AllSet model and readout layer.\n", "\n", " Base model parameters:\n", " ----------\n", @@ -374,7 +374,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ @@ -395,7 +395,6 @@ " in_channels=in_channels,\n", " hidden_channels=hidden_channels,\n", " out_channels=out_channels,\n", - " heads=heads,\n", " n_layers=n_layers,\n", " mlp_num_layers=mlp_num_layers,\n", " task_level=task_level,\n", @@ -414,7 +413,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -430,7 +429,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 10, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:59.046068930Z", @@ -442,9 +441,9 @@ "name": "stderr", "output_type": "stream", "text": [ - "/tmp/ipykernel_802086/276484184.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_850617/276484184.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " x_0s = torch.tensor(x_0s)\n", - "/tmp/ipykernel_802086/276484184.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_850617/276484184.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " torch.tensor(y, dtype=torch.long).to(device),\n" ] } @@ -468,7 +467,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -476,17 +475,13 @@ "output_type": "stream", "text": [ "Epoch: 5 \n", - "Train_loss: 1.5679, acc: 0.9929\n", - "Val_loss: 0.9291, Val_acc: 0.7360\n", - "Test_loss: 0.8751, Test_acc: 0.7670\n", + "Train_loss: 1.7016, acc: 0.9714\n", + "Val_loss: 1.1253, Val_acc: 0.6820\n", + "Test_loss: 1.0647, Test_acc: 0.6940\n", "Epoch: 10 \n", - "Train_loss: 0.8660, acc: 1.0000\n", - "Val_loss: 1.0993, Val_acc: 0.7380\n", - "Test_loss: 1.0621, Test_acc: 0.7370\n", - "Epoch: 15 \n", - "Train_loss: 0.5851, acc: 1.0000\n", - "Val_loss: 1.7357, Val_acc: 0.6780\n", - "Test_loss: 1.5269, Test_acc: 0.7230\n" + "Train_loss: 0.9825, acc: 1.0000\n", + "Val_loss: 0.9897, Val_acc: 0.7340\n", + "Test_loss: 0.8711, Test_acc: 0.7730\n" ] } ], @@ -532,13 +527,6 @@ " flush=True,\n", " )" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { From 8d2ce7de33b3450e655ce07937691a5931edc212 Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Tue, 7 Nov 2023 20:53:16 +0000 Subject: [PATCH 32/39] allsettransformer once more --- .../hypergraph/allset_transformer_train.ipynb | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/tutorials/hypergraph/allset_transformer_train.ipynb b/tutorials/hypergraph/allset_transformer_train.ipynb index 93004150d..c8bac06bc 100644 --- a/tutorials/hypergraph/allset_transformer_train.ipynb +++ b/tutorials/hypergraph/allset_transformer_train.ipynb @@ -249,24 +249,24 @@ } ], "source": [ - "# Calculate hyperedge statistics.\n", - "hyperedge_sizes = [len(he) for he in hyperedges]\n", - "min_size = min(hyperedge_sizes)\n", - "max_size = max(hyperedge_sizes)\n", - "mean_size = np.mean(hyperedge_sizes)\n", - "median_size = np.median(hyperedge_sizes)\n", - "std_size = np.std(hyperedge_sizes)\n", - "num_single_node_hyperedges = sum(np.array(hyperedge_sizes) == 1)\n", - "\n", - "# Print the hyperedge statistics.\n", - "print(f\"Hyperedge statistics: \")\n", - "print(\"Number of hyperedges without duplicated hyperedges\", len(hyperedges))\n", - "print(f\"min = {min_size}, \")\n", - "print(f\"max = {max_size}, \")\n", - "print(f\"mean = {mean_size}, \")\n", - "print(f\"median = {median_size}, \")\n", - "print(f\"std = {std_size}, \")\n", - "print(f\"Number of hyperedges with size equal to one = {num_single_node_hyperedges}\")" + "# # Calculate hyperedge statistics.\n", + "# hyperedge_sizes = [len(he) for he in hyperedges]\n", + "# min_size = min(hyperedge_sizes)\n", + "# max_size = max(hyperedge_sizes)\n", + "# mean_size = np.mean(hyperedge_sizes)\n", + "# median_size = np.median(hyperedge_sizes)\n", + "# std_size = np.std(hyperedge_sizes)\n", + "# num_single_node_hyperedges = sum(np.array(hyperedge_sizes) == 1)\n", + "\n", + "# # Print the hyperedge statistics.\n", + "# print(f\"Hyperedge statistics: \")\n", + "# print(\"Number of hyperedges without duplicated hyperedges\", len(hyperedges))\n", + "# print(f\"min = {min_size}, \")\n", + "# print(f\"max = {max_size}, \")\n", + "# print(f\"mean = {mean_size}, \")\n", + "# print(f\"median = {median_size}, \")\n", + "# print(f\"std = {std_size}, \")\n", + "# print(f\"Number of hyperedges with size equal to one = {num_single_node_hyperedges}\")" ] }, { From 98bc6ee5b581eb858c046bcc2384b25aa3fe99ee Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Tue, 7 Nov 2023 21:09:13 +0000 Subject: [PATCH 33/39] allsettransformer once more --- tutorials/hypergraph/allset_transformer_train.ipynb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tutorials/hypergraph/allset_transformer_train.ipynb b/tutorials/hypergraph/allset_transformer_train.ipynb index c8bac06bc..b3702d62d 100644 --- a/tutorials/hypergraph/allset_transformer_train.ipynb +++ b/tutorials/hypergraph/allset_transformer_train.ipynb @@ -80,7 +80,7 @@ "outputs": [], "source": [ "\"\"\"\n", - "This module contains the AllSet class for hypergraph-based neural networks.\n", + "This module contains the AllSetTransformer class for hypergraph-based neural networks.\n", "\n", "The AllSet class implements a specific hypergraph-based neural network architecture\n", "used for solving certain types of problems.\n", @@ -486,8 +486,8 @@ } ], "source": [ - "test_interval = 5\n", - "num_epochs = 10\n", + "test_interval = 0\n", + "num_epochs = 0\n", "\n", "epoch_loss = []\n", "for epoch_i in range(1, num_epochs + 1):\n", From e1484f58e740d23c7c26055c8fcdcc3d923c5912 Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Thu, 9 Nov 2023 15:24:59 +0000 Subject: [PATCH 34/39] fix path --- data/cora/Cora/raw/ind.cora.allx | Bin 257305 -> 0 bytes data/cora/Cora/raw/ind.cora.ally | Bin 47959 -> 0 bytes data/cora/Cora/raw/ind.cora.graph | Bin 59847 -> 0 bytes data/cora/Cora/raw/ind.cora.test.index | 1000 ----------------- data/cora/Cora/raw/ind.cora.tx | Bin 148025 -> 0 bytes data/cora/Cora/raw/ind.cora.ty | Bin 28135 -> 0 bytes data/cora/Cora/raw/ind.cora.x | Bin 22119 -> 0 bytes data/cora/Cora/raw/ind.cora.y | Bin 4054 -> 0 bytes tutorials/hypergraph/allset_train.ipynb | 2 +- .../hypergraph/allset_transformer_train.ipynb | 2 +- tutorials/hypergraph/hmpnn_train.ipynb | 2 +- tutorials/hypergraph/hnhn_train.ipynb | 2 +- tutorials/hypergraph/hypersage_train.ipynb | 2 +- tutorials/hypergraph/unigcn_train.ipynb | 2 +- tutorials/hypergraph/unigcnii_train.ipynb | 4 +- tutorials/hypergraph/unigin_train.ipynb | 4 +- tutorials/hypergraph/unisage_train.ipynb | 2 +- 17 files changed, 11 insertions(+), 1011 deletions(-) delete mode 100644 data/cora/Cora/raw/ind.cora.allx delete mode 100644 data/cora/Cora/raw/ind.cora.ally delete mode 100644 data/cora/Cora/raw/ind.cora.graph delete mode 100644 data/cora/Cora/raw/ind.cora.test.index delete mode 100644 data/cora/Cora/raw/ind.cora.tx delete mode 100644 data/cora/Cora/raw/ind.cora.ty delete mode 100644 data/cora/Cora/raw/ind.cora.x delete mode 100644 data/cora/Cora/raw/ind.cora.y diff --git a/data/cora/Cora/raw/ind.cora.allx b/data/cora/Cora/raw/ind.cora.allx deleted file mode 100644 index 44d53b1fece343538e45592caac521d73c6f98d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 257305 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 z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#jHhhXxMY_waq6 G`Tqf}DSCbY diff --git a/data/cora/Cora/raw/ind.cora.ally b/data/cora/Cora/raw/ind.cora.ally deleted file mode 100644 index 04fbd0b083d09341fcf16b395c642329637f0542..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47959 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 My~lCyzWDTi0g%o(9smFU diff --git a/data/cora/Cora/raw/ind.cora.graph b/data/cora/Cora/raw/ind.cora.graph deleted file mode 100644 index 4d3bf85dfc8b1c105a2c995597a1b3eed6947925..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59847 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 A!vFvP diff --git a/data/cora/Cora/raw/ind.cora.test.index b/data/cora/Cora/raw/ind.cora.test.index deleted file mode 100644 index ded8092db..000000000 --- a/data/cora/Cora/raw/ind.cora.test.index +++ /dev/null @@ -1,1000 +0,0 @@ -2692 -2532 -2050 -1715 -2362 -2609 -2622 -1975 -2081 -1767 -2263 -1725 -2588 -2259 -2357 -1998 -2574 -2179 -2291 -2382 -1812 -1751 -2422 -1937 -2631 -2510 -2378 -2589 -2345 -1943 -1850 -2298 -1825 -2035 -2507 -2313 -1906 -1797 -2023 -2159 -2495 -1886 -2122 -2369 -2461 -1925 -2565 -1858 -2234 -2000 -1846 -2318 -1723 -2559 -2258 -1763 -1991 -1922 -2003 -2662 -2250 -2064 -2529 -1888 -2499 -2454 -2320 -2287 -2203 -2018 -2002 -2632 -2554 -2314 -2537 -1760 -2088 -2086 -2218 -2605 -1953 -2403 -1920 -2015 -2335 -2535 -1837 -2009 -1905 -2636 -1942 -2193 -2576 -2373 -1873 -2463 -2509 -1954 -2656 -2455 -2494 -2295 -2114 -2561 -2176 -2275 -2635 -2442 -2704 -2127 -2085 -2214 -2487 -1739 -2543 -1783 -2485 -2262 -2472 -2326 -1738 -2170 -2100 -2384 -2152 -2647 -2693 -2376 -1775 -1726 -2476 -2195 -1773 -1793 -2194 -2581 -1854 -2524 -1945 -1781 -1987 -2599 -1744 -2225 -2300 -1928 -2042 -2202 -1958 -1816 -1916 -2679 -2190 -1733 -2034 -2643 -2177 -1883 -1917 -1996 -2491 -2268 -2231 -2471 -1919 -1909 -2012 -2522 -1865 -2466 -2469 -2087 -2584 -2563 -1924 -2143 -1736 -1966 -2533 -2490 -2630 -1973 -2568 -1978 -2664 -2633 -2312 -2178 -1754 -2307 -2480 -1960 -1742 -1962 -2160 -2070 -2553 -2433 -1768 -2659 -2379 -2271 -1776 -2153 -1877 -2027 -2028 -2155 -2196 -2483 -2026 -2158 -2407 -1821 -2131 -2676 -2277 -2489 -2424 -1963 -1808 -1859 -2597 -2548 -2368 -1817 -2405 -2413 -2603 -2350 -2118 -2329 -1969 -2577 -2475 -2467 -2425 -1769 -2092 -2044 -2586 -2608 -1983 -2109 -2649 -1964 -2144 -1902 -2411 -2508 -2360 -1721 -2005 -2014 -2308 -2646 -1949 -1830 -2212 -2596 -1832 -1735 -1866 -2695 -1941 -2546 -2498 -2686 -2665 -1784 -2613 -1970 -2021 -2211 -2516 -2185 -2479 -2699 -2150 -1990 -2063 -2075 -1979 -2094 -1787 -2571 -2690 -1926 -2341 -2566 -1957 -1709 -1955 -2570 -2387 -1811 -2025 -2447 -2696 -2052 -2366 -1857 -2273 -2245 -2672 -2133 -2421 -1929 -2125 -2319 -2641 -2167 -2418 -1765 -1761 -1828 -2188 -1972 -1997 -2419 -2289 -2296 -2587 -2051 -2440 -2053 -2191 -1923 -2164 -1861 -2339 -2333 -2523 -2670 -2121 -1921 -1724 -2253 -2374 -1940 -2545 -2301 -2244 -2156 -1849 -2551 -2011 -2279 -2572 -1757 -2400 -2569 -2072 -2526 -2173 -2069 -2036 -1819 -1734 -1880 -2137 -2408 -2226 -2604 -1771 -2698 -2187 -2060 -1756 -2201 -2066 -2439 -1844 -1772 -2383 -2398 -1708 -1992 -1959 -1794 -2426 -2702 -2444 -1944 -1829 -2660 -2497 -2607 -2343 -1730 -2624 -1790 -1935 -1967 -2401 -2255 -2355 -2348 -1931 -2183 -2161 -2701 -1948 -2501 -2192 -2404 -2209 -2331 -1810 -2363 -2334 -1887 -2393 -2557 -1719 -1732 -1986 -2037 -2056 -1867 -2126 -1932 -2117 -1807 -1801 -1743 -2041 -1843 -2388 -2221 -1833 -2677 -1778 -2661 -2306 -2394 -2106 -2430 -2371 -2606 -2353 -2269 -2317 -2645 -2372 -2550 -2043 -1968 -2165 -2310 -1985 -2446 -1982 -2377 -2207 -1818 -1913 -1766 -1722 -1894 -2020 -1881 -2621 -2409 -2261 -2458 -2096 -1712 -2594 -2293 -2048 -2359 -1839 -2392 -2254 -1911 -2101 -2367 -1889 -1753 -2555 -2246 -2264 -2010 -2336 -2651 -2017 -2140 -1842 -2019 -1890 -2525 -2134 -2492 -2652 -2040 -2145 -2575 -2166 -1999 -2434 -1711 -2276 -2450 -2389 -2669 -2595 -1814 -2039 -2502 -1896 -2168 -2344 -2637 -2031 -1977 -2380 -1936 -2047 -2460 -2102 -1745 -2650 -2046 -2514 -1980 -2352 -2113 -1713 -2058 -2558 -1718 -1864 -1876 -2338 -1879 -1891 -2186 -2451 -2181 -2638 -2644 -2103 -2591 -2266 -2468 -1869 -2582 -2674 -2361 -2462 -1748 -2215 -2615 -2236 -2248 -2493 -2342 -2449 -2274 -1824 -1852 -1870 -2441 -2356 -1835 -2694 -2602 -2685 -1893 -2544 -2536 -1994 -1853 -1838 -1786 -1930 -2539 -1892 -2265 -2618 -2486 -2583 -2061 -1796 -1806 -2084 -1933 -2095 -2136 -2078 -1884 -2438 -2286 -2138 -1750 -2184 -1799 -2278 -2410 -2642 -2435 -1956 -2399 -1774 -2129 -1898 -1823 -1938 -2299 -1862 -2420 -2673 -1984 -2204 -1717 -2074 -2213 -2436 -2297 -2592 -2667 -2703 -2511 -1779 -1782 -2625 -2365 -2315 -2381 -1788 -1714 -2302 -1927 -2325 -2506 -2169 -2328 -2629 -2128 -2655 -2282 -2073 -2395 -2247 -2521 -2260 -1868 -1988 -2324 -2705 -2541 -1731 -2681 -2707 -2465 -1785 -2149 -2045 -2505 -2611 -2217 -2180 -1904 -2453 -2484 -1871 -2309 -2349 -2482 -2004 -1965 -2406 -2162 -1805 -2654 -2007 -1947 -1981 -2112 -2141 -1720 -1758 -2080 -2330 -2030 -2432 -2089 -2547 -1820 -1815 -2675 -1840 -2658 -2370 -2251 -1908 -2029 -2068 -2513 -2549 -2267 -2580 -2327 -2351 -2111 -2022 -2321 -2614 -2252 -2104 -1822 -2552 -2243 -1798 -2396 -2663 -2564 -2148 -2562 -2684 -2001 -2151 -2706 -2240 -2474 -2303 -2634 -2680 -2055 -2090 -2503 -2347 -2402 -2238 -1950 -2054 -2016 -1872 -2233 -1710 -2032 -2540 -2628 -1795 -2616 -1903 -2531 -2567 -1946 -1897 -2222 -2227 -2627 -1856 -2464 -2241 -2481 -2130 -2311 -2083 -2223 -2284 -2235 -2097 -1752 -2515 -2527 -2385 -2189 -2283 -2182 -2079 -2375 -2174 -2437 -1993 -2517 -2443 -2224 -2648 -2171 -2290 -2542 -2038 -1855 -1831 -1759 -1848 -2445 -1827 -2429 -2205 -2598 -2657 -1728 -2065 -1918 -2427 -2573 -2620 -2292 -1777 -2008 -1875 -2288 -2256 -2033 -2470 -2585 -2610 -2082 -2230 -1915 -1847 -2337 -2512 -2386 -2006 -2653 -2346 -1951 -2110 -2639 -2520 -1939 -2683 -2139 -2220 -1910 -2237 -1900 -1836 -2197 -1716 -1860 -2077 -2519 -2538 -2323 -1914 -1971 -1845 -2132 -1802 -1907 -2640 -2496 -2281 -2198 -2416 -2285 -1755 -2431 -2071 -2249 -2123 -1727 -2459 -2304 -2199 -1791 -1809 -1780 -2210 -2417 -1874 -1878 -2116 -1961 -1863 -2579 -2477 -2228 -2332 -2578 -2457 -2024 -1934 -2316 -1841 -1764 -1737 -2322 -2239 -2294 -1729 -2488 -1974 -2473 -2098 -2612 -1834 -2340 -2423 -2175 -2280 -2617 -2208 -2560 -1741 -2600 -2059 -1747 -2242 -2700 -2232 -2057 -2147 -2682 -1792 -1826 -2120 -1895 -2364 -2163 -1851 -2391 -2414 -2452 -1803 -1989 -2623 -2200 -2528 -2415 -1804 -2146 -2619 -2687 -1762 -2172 -2270 -2678 -2593 -2448 -1882 -2257 -2500 -1899 -2478 -2412 -2107 -1746 -2428 -2115 -1800 -1901 -2397 -2530 -1912 -2108 -2206 -2091 -1740 -2219 -1976 -2099 -2142 -2671 -2668 -2216 -2272 -2229 -2666 -2456 -2534 -2697 -2688 -2062 -2691 -2689 -2154 -2590 -2626 -2390 -1813 -2067 -1952 -2518 -2358 -1789 -2076 -2049 -2119 -2013 -2124 -2556 -2105 -2093 -1885 -2305 -2354 -2135 -2601 -1770 -1995 -2504 -1749 -2157 diff --git a/data/cora/Cora/raw/ind.cora.tx b/data/cora/Cora/raw/ind.cora.tx deleted file mode 100644 index 6e856d777401ee15dc8619db76c97d0a40ba2d60..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 148025 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 diff --git a/data/cora/Cora/raw/ind.cora.x b/data/cora/Cora/raw/ind.cora.x deleted file mode 100644 index c4a91d008245403e7f26aa616b437191509793c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22119 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 Date: Thu, 9 Nov 2023 15:26:19 +0000 Subject: [PATCH 35/39] fix path --- .../hypergraph/allset_transformer_train.ipynb | 66 +++++------------- .../tmp/{Cora => cora}/raw/ind.cora.allx | Bin .../tmp/{Cora => cora}/raw/ind.cora.ally | Bin .../tmp/{Cora => cora}/raw/ind.cora.graph | Bin .../{Cora => cora}/raw/ind.cora.test.index | 0 .../tmp/{Cora => cora}/raw/ind.cora.tx | Bin .../tmp/{Cora => cora}/raw/ind.cora.ty | Bin .../tmp/{Cora => cora}/raw/ind.cora.x | Bin .../tmp/{Cora => cora}/raw/ind.cora.y | Bin 9 files changed, 19 insertions(+), 47 deletions(-) rename tutorials/hypergraph/tmp/{Cora => cora}/raw/ind.cora.allx (100%) rename tutorials/hypergraph/tmp/{Cora => cora}/raw/ind.cora.ally (100%) rename tutorials/hypergraph/tmp/{Cora => cora}/raw/ind.cora.graph (100%) rename tutorials/hypergraph/tmp/{Cora => cora}/raw/ind.cora.test.index (100%) rename tutorials/hypergraph/tmp/{Cora => cora}/raw/ind.cora.tx (100%) rename tutorials/hypergraph/tmp/{Cora => cora}/raw/ind.cora.ty (100%) rename tutorials/hypergraph/tmp/{Cora => cora}/raw/ind.cora.x (100%) rename tutorials/hypergraph/tmp/{Cora => cora}/raw/ind.cora.y (100%) diff --git a/tutorials/hypergraph/allset_transformer_train.ipynb b/tutorials/hypergraph/allset_transformer_train.ipynb index 024d59399..b30d0e94a 100644 --- a/tutorials/hypergraph/allset_transformer_train.ipynb +++ b/tutorials/hypergraph/allset_transformer_train.ipynb @@ -70,7 +70,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 12, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:51.222779223Z", @@ -110,7 +110,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 13, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:51.959770754Z", @@ -145,23 +145,14 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 14, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:53.022151550Z", "start_time": "2023-06-01T16:14:52.949636599Z" } }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/usr/local/lib/python3.11/site-packages/torch_geometric/data/in_memory_dataset.py:285: UserWarning: It is not recommended to directly access the internal storage format `data` of an 'InMemoryDataset'. If you are absolutely certain what you are doing, access the internal storage via `InMemoryDataset._data` instead to suppress this warning. Alternatively, you can access stacked individual attributes of every graph via `dataset.{attr_name}`.\n", - " warnings.warn(msg)\n" - ] - } - ], + "outputs": [], "source": [ "cora = geom_datasets.Planetoid(root=\"tmp/\", name=\"cora\")\n", "data = cora.data\n", @@ -189,7 +180,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 15, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:53.022151550Z", @@ -230,24 +221,9 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 16, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Hyperedge statistics: \n", - "Number of hyperedges without duplicated hyperedges 2581\n", - "min = 1, \n", - "max = 168, \n", - "mean = 4.003099573808601, \n", - "median = 3.0, \n", - "std = 5.327622607829558, \n", - "Number of hyperedges with size equal to one = 412\n" - ] - } - ], + "outputs": [], "source": [ "# # Calculate hyperedge statistics.\n", "# hyperedge_sizes = [len(he) for he in hyperedges]\n", @@ -278,7 +254,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 17, "metadata": {}, "outputs": [], "source": [ @@ -311,7 +287,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 18, "metadata": {}, "outputs": [], "source": [ @@ -374,7 +350,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 19, "metadata": {}, "outputs": [], "source": [ @@ -413,7 +389,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 20, "metadata": {}, "outputs": [], "source": [ @@ -429,7 +405,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 21, "metadata": { "ExecuteTime": { "end_time": "2023-06-01T16:14:59.046068930Z", @@ -441,9 +417,9 @@ "name": "stderr", "output_type": "stream", "text": [ - "/tmp/ipykernel_850617/276484184.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_909051/276484184.py:1: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " x_0s = torch.tensor(x_0s)\n", - "/tmp/ipykernel_850617/276484184.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", + "/tmp/ipykernel_909051/276484184.py:5: UserWarning: To copy construct from a tensor, it is recommended to use sourceTensor.clone().detach() or sourceTensor.clone().detach().requires_grad_(True), rather than torch.tensor(sourceTensor).\n", " torch.tensor(y, dtype=torch.long).to(device),\n" ] } @@ -467,27 +443,23 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Epoch: 5 \n", - "Train_loss: 1.7016, acc: 0.9714\n", - "Val_loss: 1.1253, Val_acc: 0.6820\n", - "Test_loss: 1.0647, Test_acc: 0.6940\n", "Epoch: 10 \n", "Train_loss: 0.9825, acc: 1.0000\n", - "Val_loss: 0.9897, Val_acc: 0.7340\n", - "Test_loss: 0.8711, Test_acc: 0.7730\n" + "Val_loss: 0.9895, Val_acc: 0.7380\n", + "Test_loss: 0.8713, Test_acc: 0.7740\n" ] } ], "source": [ - "test_interval = 1\n", - "num_epochs = 1\n", + "test_interval = 5\n", + "num_epochs = 5\n", "\n", "epoch_loss = []\n", "for epoch_i in range(1, num_epochs + 1):\n", diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.allx b/tutorials/hypergraph/tmp/cora/raw/ind.cora.allx similarity index 100% rename from tutorials/hypergraph/tmp/Cora/raw/ind.cora.allx rename to tutorials/hypergraph/tmp/cora/raw/ind.cora.allx diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.ally b/tutorials/hypergraph/tmp/cora/raw/ind.cora.ally similarity index 100% rename from tutorials/hypergraph/tmp/Cora/raw/ind.cora.ally rename to tutorials/hypergraph/tmp/cora/raw/ind.cora.ally diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.graph b/tutorials/hypergraph/tmp/cora/raw/ind.cora.graph similarity index 100% rename from tutorials/hypergraph/tmp/Cora/raw/ind.cora.graph rename to tutorials/hypergraph/tmp/cora/raw/ind.cora.graph diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.test.index b/tutorials/hypergraph/tmp/cora/raw/ind.cora.test.index similarity index 100% rename from tutorials/hypergraph/tmp/Cora/raw/ind.cora.test.index rename to tutorials/hypergraph/tmp/cora/raw/ind.cora.test.index diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.tx b/tutorials/hypergraph/tmp/cora/raw/ind.cora.tx similarity index 100% rename from tutorials/hypergraph/tmp/Cora/raw/ind.cora.tx rename to tutorials/hypergraph/tmp/cora/raw/ind.cora.tx diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.ty b/tutorials/hypergraph/tmp/cora/raw/ind.cora.ty similarity index 100% rename from tutorials/hypergraph/tmp/Cora/raw/ind.cora.ty rename to tutorials/hypergraph/tmp/cora/raw/ind.cora.ty diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.x b/tutorials/hypergraph/tmp/cora/raw/ind.cora.x similarity index 100% rename from tutorials/hypergraph/tmp/Cora/raw/ind.cora.x rename to tutorials/hypergraph/tmp/cora/raw/ind.cora.x diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.y b/tutorials/hypergraph/tmp/cora/raw/ind.cora.y similarity index 100% rename from tutorials/hypergraph/tmp/Cora/raw/ind.cora.y rename to tutorials/hypergraph/tmp/cora/raw/ind.cora.y From f584f79babe727f5a3fb7475ed4aad7555da1b61 Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Thu, 9 Nov 2023 15:40:51 +0000 Subject: [PATCH 36/39] tests magic bug --- tutorials/hypergraph/allset_train.ipynb | 2 +- .../hypergraph/allset_transformer_train.ipynb | 4 +- tutorials/hypergraph/hmpnn_train.ipynb | 9 +- tutorials/hypergraph/hnhn_train.ipynb | 11 +- tutorials/hypergraph/hypergat_train.ipynb | 9 +- tutorials/hypergraph/hypersage_train.ipynb | 9 +- .../hypergraph/tmp/Cora/raw/ind.cora.allx | Bin 0 -> 257305 bytes .../hypergraph/tmp/Cora/raw/ind.cora.ally | Bin 0 -> 47959 bytes .../hypergraph/tmp/Cora/raw/ind.cora.graph | Bin 0 -> 59847 bytes .../tmp/Cora/raw/ind.cora.test.index | 1000 +++++++++++++++++ tutorials/hypergraph/tmp/Cora/raw/ind.cora.tx | Bin 0 -> 148025 bytes tutorials/hypergraph/tmp/Cora/raw/ind.cora.ty | Bin 0 -> 28135 bytes tutorials/hypergraph/tmp/Cora/raw/ind.cora.x | Bin 0 -> 22119 bytes tutorials/hypergraph/tmp/Cora/raw/ind.cora.y | Bin 0 -> 4054 bytes tutorials/hypergraph/unigcn_train.ipynb | 27 - tutorials/hypergraph/unigcnii_train.ipynb | 4 +- tutorials/hypergraph/unisage_train.ipynb | 9 +- 17 files changed, 1046 insertions(+), 38 deletions(-) create mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.allx create mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.ally create mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.graph create mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.test.index create mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.tx create mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.ty create mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.x create mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.y diff --git a/tutorials/hypergraph/allset_train.ipynb b/tutorials/hypergraph/allset_train.ipynb index 71a1d172a..715c4ca67 100644 --- a/tutorials/hypergraph/allset_train.ipynb +++ b/tutorials/hypergraph/allset_train.ipynb @@ -477,7 +477,7 @@ ], "source": [ "test_interval = 5\n", - "num_epochs = 30\n", + "num_epochs = 5\n", "\n", "epoch_loss = []\n", "for epoch_i in range(1, num_epochs + 1):\n", diff --git a/tutorials/hypergraph/allset_transformer_train.ipynb b/tutorials/hypergraph/allset_transformer_train.ipynb index b30d0e94a..4ae594f7c 100644 --- a/tutorials/hypergraph/allset_transformer_train.ipynb +++ b/tutorials/hypergraph/allset_transformer_train.ipynb @@ -458,8 +458,8 @@ } ], "source": [ - "test_interval = 5\n", - "num_epochs = 5\n", + "test_interval = 1\n", + "num_epochs = 1\n", "\n", "epoch_loss = []\n", "for epoch_i in range(1, num_epochs + 1):\n", diff --git a/tutorials/hypergraph/hmpnn_train.ipynb b/tutorials/hypergraph/hmpnn_train.ipynb index 769f1719d..e7d54785a 100644 --- a/tutorials/hypergraph/hmpnn_train.ipynb +++ b/tutorials/hypergraph/hmpnn_train.ipynb @@ -241,6 +241,13 @@ "Now it's time to train the model, looping over the network for a low amount of epochs. We keep training minimal for the purpose of rapid testing." ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Note: The number of epochs below have been kept low to facilitate debugging and testing. Real use cases should likely require more epochs.**" + ] + }, { "cell_type": "code", "execution_count": 9, @@ -281,7 +288,7 @@ "source": [ "torch.manual_seed(0)\n", "test_interval = 5\n", - "num_epochs = 100\n", + "num_epochs = 5\n", "\n", "\n", "initial_x_1 = torch.zeros_like(x_0s)\n", diff --git a/tutorials/hypergraph/hnhn_train.ipynb b/tutorials/hypergraph/hnhn_train.ipynb index 95421deff..59d0026b9 100644 --- a/tutorials/hypergraph/hnhn_train.ipynb +++ b/tutorials/hypergraph/hnhn_train.ipynb @@ -428,6 +428,13 @@ "The following cell performs the training, looping over the network for a low amount of epochs. We keep training minimal for the purpose of rapid testing." ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Note: The number of epochs below have been kept low to facilitate debugging and testing. Real use cases should likely require more epochs.**" + ] + }, { "cell_type": "code", "execution_count": 11, @@ -465,8 +472,8 @@ } ], "source": [ - "test_interval = 20\n", - "num_epochs = 20\n", + "test_interval = 5\n", + "num_epochs = 5\n", "\n", "epoch_loss = []\n", "for epoch_i in range(1, num_epochs + 1):\n", diff --git a/tutorials/hypergraph/hypergat_train.ipynb b/tutorials/hypergraph/hypergat_train.ipynb index 1cb89dfbe..09d0a240e 100644 --- a/tutorials/hypergraph/hypergat_train.ipynb +++ b/tutorials/hypergraph/hypergat_train.ipynb @@ -347,6 +347,13 @@ "The following cell performs the training, looping over the network for a low amount of epochs. We keep training minimal for the purpose of rapid testing." ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Note: The number of epochs below have been kept low to facilitate debugging and testing. Real use cases should likely require more epochs.**" + ] + }, { "cell_type": "code", "execution_count": 11, @@ -373,7 +380,7 @@ ], "source": [ "test_interval = 5\n", - "num_epochs = 20\n", + "num_epochs = 5\n", "for epoch_i in range(1, num_epochs + 1):\n", " epoch_loss = []\n", " model.train()\n", diff --git a/tutorials/hypergraph/hypersage_train.ipynb b/tutorials/hypergraph/hypersage_train.ipynb index 020d24192..0206b6c30 100644 --- a/tutorials/hypergraph/hypersage_train.ipynb +++ b/tutorials/hypergraph/hypersage_train.ipynb @@ -456,6 +456,13 @@ ")" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Note: The number of epochs below have been kept low to facilitate debugging and testing. Real use cases should likely require more epochs.**" + ] + }, { "cell_type": "code", "execution_count": 12, @@ -495,7 +502,7 @@ "source": [ "torch.manual_seed(0)\n", "test_interval = 5\n", - "num_epochs = 30\n", + "num_epochs = 5\n", "\n", "epoch_loss = []\n", "for epoch_i in range(1, num_epochs + 1):\n", diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.allx b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.allx new file mode 100644 index 0000000000000000000000000000000000000000..44d53b1fece343538e45592caac521d73c6f98d6 GIT binary patch literal 257305 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 z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#jHhhXxMY_waq6 G`Tqf}DSCbY literal 0 HcmV?d00001 diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.ally b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.ally new file mode 100644 index 0000000000000000000000000000000000000000..04fbd0b083d09341fcf16b395c642329637f0542 GIT binary patch literal 47959 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 My~lCyzWDTi0g%o(9smFU literal 0 HcmV?d00001 diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.graph b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.graph new file mode 100644 index 0000000000000000000000000000000000000000..4d3bf85dfc8b1c105a2c995597a1b3eed6947925 GIT binary patch literal 59847 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 A!vFvP literal 0 HcmV?d00001 diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.test.index b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.test.index new file mode 100644 index 000000000..ded8092db --- /dev/null +++ b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.test.index @@ -0,0 +1,1000 @@ +2692 +2532 +2050 +1715 +2362 +2609 +2622 +1975 +2081 +1767 +2263 +1725 +2588 +2259 +2357 +1998 +2574 +2179 +2291 +2382 +1812 +1751 +2422 +1937 +2631 +2510 +2378 +2589 +2345 +1943 +1850 +2298 +1825 +2035 +2507 +2313 +1906 +1797 +2023 +2159 +2495 +1886 +2122 +2369 +2461 +1925 +2565 +1858 +2234 +2000 +1846 +2318 +1723 +2559 +2258 +1763 +1991 +1922 +2003 +2662 +2250 +2064 +2529 +1888 +2499 +2454 +2320 +2287 +2203 +2018 +2002 +2632 +2554 +2314 +2537 +1760 +2088 +2086 +2218 +2605 +1953 +2403 +1920 +2015 +2335 +2535 +1837 +2009 +1905 +2636 +1942 +2193 +2576 +2373 +1873 +2463 +2509 +1954 +2656 +2455 +2494 +2295 +2114 +2561 +2176 +2275 +2635 +2442 +2704 +2127 +2085 +2214 +2487 +1739 +2543 +1783 +2485 +2262 +2472 +2326 +1738 +2170 +2100 +2384 +2152 +2647 +2693 +2376 +1775 +1726 +2476 +2195 +1773 +1793 +2194 +2581 +1854 +2524 +1945 +1781 +1987 +2599 +1744 +2225 +2300 +1928 +2042 +2202 +1958 +1816 +1916 +2679 +2190 +1733 +2034 +2643 +2177 +1883 +1917 +1996 +2491 +2268 +2231 +2471 +1919 +1909 +2012 +2522 +1865 +2466 +2469 +2087 +2584 +2563 +1924 +2143 +1736 +1966 +2533 +2490 +2630 +1973 +2568 +1978 +2664 +2633 +2312 +2178 +1754 +2307 +2480 +1960 +1742 +1962 +2160 +2070 +2553 +2433 +1768 +2659 +2379 +2271 +1776 +2153 +1877 +2027 +2028 +2155 +2196 +2483 +2026 +2158 +2407 +1821 +2131 +2676 +2277 +2489 +2424 +1963 +1808 +1859 +2597 +2548 +2368 +1817 +2405 +2413 +2603 +2350 +2118 +2329 +1969 +2577 +2475 +2467 +2425 +1769 +2092 +2044 +2586 +2608 +1983 +2109 +2649 +1964 +2144 +1902 +2411 +2508 +2360 +1721 +2005 +2014 +2308 +2646 +1949 +1830 +2212 +2596 +1832 +1735 +1866 +2695 +1941 +2546 +2498 +2686 +2665 +1784 +2613 +1970 +2021 +2211 +2516 +2185 +2479 +2699 +2150 +1990 +2063 +2075 +1979 +2094 +1787 +2571 +2690 +1926 +2341 +2566 +1957 +1709 +1955 +2570 +2387 +1811 +2025 +2447 +2696 +2052 +2366 +1857 +2273 +2245 +2672 +2133 +2421 +1929 +2125 +2319 +2641 +2167 +2418 +1765 +1761 +1828 +2188 +1972 +1997 +2419 +2289 +2296 +2587 +2051 +2440 +2053 +2191 +1923 +2164 +1861 +2339 +2333 +2523 +2670 +2121 +1921 +1724 +2253 +2374 +1940 +2545 +2301 +2244 +2156 +1849 +2551 +2011 +2279 +2572 +1757 +2400 +2569 +2072 +2526 +2173 +2069 +2036 +1819 +1734 +1880 +2137 +2408 +2226 +2604 +1771 +2698 +2187 +2060 +1756 +2201 +2066 +2439 +1844 +1772 +2383 +2398 +1708 +1992 +1959 +1794 +2426 +2702 +2444 +1944 +1829 +2660 +2497 +2607 +2343 +1730 +2624 +1790 +1935 +1967 +2401 +2255 +2355 +2348 +1931 +2183 +2161 +2701 +1948 +2501 +2192 +2404 +2209 +2331 +1810 +2363 +2334 +1887 +2393 +2557 +1719 +1732 +1986 +2037 +2056 +1867 +2126 +1932 +2117 +1807 +1801 +1743 +2041 +1843 +2388 +2221 +1833 +2677 +1778 +2661 +2306 +2394 +2106 +2430 +2371 +2606 +2353 +2269 +2317 +2645 +2372 +2550 +2043 +1968 +2165 +2310 +1985 +2446 +1982 +2377 +2207 +1818 +1913 +1766 +1722 +1894 +2020 +1881 +2621 +2409 +2261 +2458 +2096 +1712 +2594 +2293 +2048 +2359 +1839 +2392 +2254 +1911 +2101 +2367 +1889 +1753 +2555 +2246 +2264 +2010 +2336 +2651 +2017 +2140 +1842 +2019 +1890 +2525 +2134 +2492 +2652 +2040 +2145 +2575 +2166 +1999 +2434 +1711 +2276 +2450 +2389 +2669 +2595 +1814 +2039 +2502 +1896 +2168 +2344 +2637 +2031 +1977 +2380 +1936 +2047 +2460 +2102 +1745 +2650 +2046 +2514 +1980 +2352 +2113 +1713 +2058 +2558 +1718 +1864 +1876 +2338 +1879 +1891 +2186 +2451 +2181 +2638 +2644 +2103 +2591 +2266 +2468 +1869 +2582 +2674 +2361 +2462 +1748 +2215 +2615 +2236 +2248 +2493 +2342 +2449 +2274 +1824 +1852 +1870 +2441 +2356 +1835 +2694 +2602 +2685 +1893 +2544 +2536 +1994 +1853 +1838 +1786 +1930 +2539 +1892 +2265 +2618 +2486 +2583 +2061 +1796 +1806 +2084 +1933 +2095 +2136 +2078 +1884 +2438 +2286 +2138 +1750 +2184 +1799 +2278 +2410 +2642 +2435 +1956 +2399 +1774 +2129 +1898 +1823 +1938 +2299 +1862 +2420 +2673 +1984 +2204 +1717 +2074 +2213 +2436 +2297 +2592 +2667 +2703 +2511 +1779 +1782 +2625 +2365 +2315 +2381 +1788 +1714 +2302 +1927 +2325 +2506 +2169 +2328 +2629 +2128 +2655 +2282 +2073 +2395 +2247 +2521 +2260 +1868 +1988 +2324 +2705 +2541 +1731 +2681 +2707 +2465 +1785 +2149 +2045 +2505 +2611 +2217 +2180 +1904 +2453 +2484 +1871 +2309 +2349 +2482 +2004 +1965 +2406 +2162 +1805 +2654 +2007 +1947 +1981 +2112 +2141 +1720 +1758 +2080 +2330 +2030 +2432 +2089 +2547 +1820 +1815 +2675 +1840 +2658 +2370 +2251 +1908 +2029 +2068 +2513 +2549 +2267 +2580 +2327 +2351 +2111 +2022 +2321 +2614 +2252 +2104 +1822 +2552 +2243 +1798 +2396 +2663 +2564 +2148 +2562 +2684 +2001 +2151 +2706 +2240 +2474 +2303 +2634 +2680 +2055 +2090 +2503 +2347 +2402 +2238 +1950 +2054 +2016 +1872 +2233 +1710 +2032 +2540 +2628 +1795 +2616 +1903 +2531 +2567 +1946 +1897 +2222 +2227 +2627 +1856 +2464 +2241 +2481 +2130 +2311 +2083 +2223 +2284 +2235 +2097 +1752 +2515 +2527 +2385 +2189 +2283 +2182 +2079 +2375 +2174 +2437 +1993 +2517 +2443 +2224 +2648 +2171 +2290 +2542 +2038 +1855 +1831 +1759 +1848 +2445 +1827 +2429 +2205 +2598 +2657 +1728 +2065 +1918 +2427 +2573 +2620 +2292 +1777 +2008 +1875 +2288 +2256 +2033 +2470 +2585 +2610 +2082 +2230 +1915 +1847 +2337 +2512 +2386 +2006 +2653 +2346 +1951 +2110 +2639 +2520 +1939 +2683 +2139 +2220 +1910 +2237 +1900 +1836 +2197 +1716 +1860 +2077 +2519 +2538 +2323 +1914 +1971 +1845 +2132 +1802 +1907 +2640 +2496 +2281 +2198 +2416 +2285 +1755 +2431 +2071 +2249 +2123 +1727 +2459 +2304 +2199 +1791 +1809 +1780 +2210 +2417 +1874 +1878 +2116 +1961 +1863 +2579 +2477 +2228 +2332 +2578 +2457 +2024 +1934 +2316 +1841 +1764 +1737 +2322 +2239 +2294 +1729 +2488 +1974 +2473 +2098 +2612 +1834 +2340 +2423 +2175 +2280 +2617 +2208 +2560 +1741 +2600 +2059 +1747 +2242 +2700 +2232 +2057 +2147 +2682 +1792 +1826 +2120 +1895 +2364 +2163 +1851 +2391 +2414 +2452 +1803 +1989 +2623 +2200 +2528 +2415 +1804 +2146 +2619 +2687 +1762 +2172 +2270 +2678 +2593 +2448 +1882 +2257 +2500 +1899 +2478 +2412 +2107 +1746 +2428 +2115 +1800 +1901 +2397 +2530 +1912 +2108 +2206 +2091 +1740 +2219 +1976 +2099 +2142 +2671 +2668 +2216 +2272 +2229 +2666 +2456 +2534 +2697 +2688 +2062 +2691 +2689 +2154 +2590 +2626 +2390 +1813 +2067 +1952 +2518 +2358 +1789 +2076 +2049 +2119 +2013 +2124 +2556 +2105 +2093 +1885 +2305 +2354 +2135 +2601 +1770 +1995 +2504 +1749 +2157 diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.tx b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.tx new file mode 100644 index 0000000000000000000000000000000000000000..6e856d777401ee15dc8619db76c97d0a40ba2d60 GIT binary patch literal 148025 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 literal 0 HcmV?d00001 diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.x b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.x new file mode 100644 index 0000000000000000000000000000000000000000..c4a91d008245403e7f26aa616b437191509793c0 GIT binary patch literal 22119 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 Date: Thu, 9 Nov 2023 15:42:44 +0000 Subject: [PATCH 37/39] fix cora path --- tutorials/hypergraph/hnhn_train.ipynb | 7 - .../hypergraph/tmp/Cora/raw/ind.cora.allx | Bin 257305 -> 0 bytes .../hypergraph/tmp/Cora/raw/ind.cora.ally | Bin 47959 -> 0 bytes .../hypergraph/tmp/Cora/raw/ind.cora.graph | Bin 59847 -> 0 bytes .../tmp/Cora/raw/ind.cora.test.index | 1000 ----------------- tutorials/hypergraph/tmp/Cora/raw/ind.cora.tx | Bin 148025 -> 0 bytes tutorials/hypergraph/tmp/Cora/raw/ind.cora.ty | Bin 28135 -> 0 bytes tutorials/hypergraph/tmp/Cora/raw/ind.cora.x | Bin 22119 -> 0 bytes tutorials/hypergraph/tmp/Cora/raw/ind.cora.y | Bin 4054 -> 0 bytes tutorials/hypergraph/unigcnii_train.ipynb | 2 +- 10 files changed, 1 insertion(+), 1008 deletions(-) delete mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.allx delete mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.ally delete mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.graph delete mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.test.index delete mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.tx delete mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.ty delete mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.x delete mode 100644 tutorials/hypergraph/tmp/Cora/raw/ind.cora.y diff --git a/tutorials/hypergraph/hnhn_train.ipynb b/tutorials/hypergraph/hnhn_train.ipynb index 59d0026b9..525ad1db1 100644 --- a/tutorials/hypergraph/hnhn_train.ipynb +++ b/tutorials/hypergraph/hnhn_train.ipynb @@ -513,13 +513,6 @@ " flush=True,\n", " )" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.allx b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.allx deleted file mode 100644 index 44d53b1fece343538e45592caac521d73c6f98d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 257305 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 z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#jHhhXxMY_waq6 G`Tqf}DSCbY diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.ally b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.ally deleted file mode 100644 index 04fbd0b083d09341fcf16b395c642329637f0542..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47959 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 My~lCyzWDTi0g%o(9smFU diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.graph b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.graph deleted file mode 100644 index 4d3bf85dfc8b1c105a2c995597a1b3eed6947925..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59847 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 A!vFvP diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.test.index b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.test.index deleted file mode 100644 index ded8092db..000000000 --- a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.test.index +++ /dev/null @@ -1,1000 +0,0 @@ -2692 -2532 -2050 -1715 -2362 -2609 -2622 -1975 -2081 -1767 -2263 -1725 -2588 -2259 -2357 -1998 -2574 -2179 -2291 -2382 -1812 -1751 -2422 -1937 -2631 -2510 -2378 -2589 -2345 -1943 -1850 -2298 -1825 -2035 -2507 -2313 -1906 -1797 -2023 -2159 -2495 -1886 -2122 -2369 -2461 -1925 -2565 -1858 -2234 -2000 -1846 -2318 -1723 -2559 -2258 -1763 -1991 -1922 -2003 -2662 -2250 -2064 -2529 -1888 -2499 -2454 -2320 -2287 -2203 -2018 -2002 -2632 -2554 -2314 -2537 -1760 -2088 -2086 -2218 -2605 -1953 -2403 -1920 -2015 -2335 -2535 -1837 -2009 -1905 -2636 -1942 -2193 -2576 -2373 -1873 -2463 -2509 -1954 -2656 -2455 -2494 -2295 -2114 -2561 -2176 -2275 -2635 -2442 -2704 -2127 -2085 -2214 -2487 -1739 -2543 -1783 -2485 -2262 -2472 -2326 -1738 -2170 -2100 -2384 -2152 -2647 -2693 -2376 -1775 -1726 -2476 -2195 -1773 -1793 -2194 -2581 -1854 -2524 -1945 -1781 -1987 -2599 -1744 -2225 -2300 -1928 -2042 -2202 -1958 -1816 -1916 -2679 -2190 -1733 -2034 -2643 -2177 -1883 -1917 -1996 -2491 -2268 -2231 -2471 -1919 -1909 -2012 -2522 -1865 -2466 -2469 -2087 -2584 -2563 -1924 -2143 -1736 -1966 -2533 -2490 -2630 -1973 -2568 -1978 -2664 -2633 -2312 -2178 -1754 -2307 -2480 -1960 -1742 -1962 -2160 -2070 -2553 -2433 -1768 -2659 -2379 -2271 -1776 -2153 -1877 -2027 -2028 -2155 -2196 -2483 -2026 -2158 -2407 -1821 -2131 -2676 -2277 -2489 -2424 -1963 -1808 -1859 -2597 -2548 -2368 -1817 -2405 -2413 -2603 -2350 -2118 -2329 -1969 -2577 -2475 -2467 -2425 -1769 -2092 -2044 -2586 -2608 -1983 -2109 -2649 -1964 -2144 -1902 -2411 -2508 -2360 -1721 -2005 -2014 -2308 -2646 -1949 -1830 -2212 -2596 -1832 -1735 -1866 -2695 -1941 -2546 -2498 -2686 -2665 -1784 -2613 -1970 -2021 -2211 -2516 -2185 -2479 -2699 -2150 -1990 -2063 -2075 -1979 -2094 -1787 -2571 -2690 -1926 -2341 -2566 -1957 -1709 -1955 -2570 -2387 -1811 -2025 -2447 -2696 -2052 -2366 -1857 -2273 -2245 -2672 -2133 -2421 -1929 -2125 -2319 -2641 -2167 -2418 -1765 -1761 -1828 -2188 -1972 -1997 -2419 -2289 -2296 -2587 -2051 -2440 -2053 -2191 -1923 -2164 -1861 -2339 -2333 -2523 -2670 -2121 -1921 -1724 -2253 -2374 -1940 -2545 -2301 -2244 -2156 -1849 -2551 -2011 -2279 -2572 -1757 -2400 -2569 -2072 -2526 -2173 -2069 -2036 -1819 -1734 -1880 -2137 -2408 -2226 -2604 -1771 -2698 -2187 -2060 -1756 -2201 -2066 -2439 -1844 -1772 -2383 -2398 -1708 -1992 -1959 -1794 -2426 -2702 -2444 -1944 -1829 -2660 -2497 -2607 -2343 -1730 -2624 -1790 -1935 -1967 -2401 -2255 -2355 -2348 -1931 -2183 -2161 -2701 -1948 -2501 -2192 -2404 -2209 -2331 -1810 -2363 -2334 -1887 -2393 -2557 -1719 -1732 -1986 -2037 -2056 -1867 -2126 -1932 -2117 -1807 -1801 -1743 -2041 -1843 -2388 -2221 -1833 -2677 -1778 -2661 -2306 -2394 -2106 -2430 -2371 -2606 -2353 -2269 -2317 -2645 -2372 -2550 -2043 -1968 -2165 -2310 -1985 -2446 -1982 -2377 -2207 -1818 -1913 -1766 -1722 -1894 -2020 -1881 -2621 -2409 -2261 -2458 -2096 -1712 -2594 -2293 -2048 -2359 -1839 -2392 -2254 -1911 -2101 -2367 -1889 -1753 -2555 -2246 -2264 -2010 -2336 -2651 -2017 -2140 -1842 -2019 -1890 -2525 -2134 -2492 -2652 -2040 -2145 -2575 -2166 -1999 -2434 -1711 -2276 -2450 -2389 -2669 -2595 -1814 -2039 -2502 -1896 -2168 -2344 -2637 -2031 -1977 -2380 -1936 -2047 -2460 -2102 -1745 -2650 -2046 -2514 -1980 -2352 -2113 -1713 -2058 -2558 -1718 -1864 -1876 -2338 -1879 -1891 -2186 -2451 -2181 -2638 -2644 -2103 -2591 -2266 -2468 -1869 -2582 -2674 -2361 -2462 -1748 -2215 -2615 -2236 -2248 -2493 -2342 -2449 -2274 -1824 -1852 -1870 -2441 -2356 -1835 -2694 -2602 -2685 -1893 -2544 -2536 -1994 -1853 -1838 -1786 -1930 -2539 -1892 -2265 -2618 -2486 -2583 -2061 -1796 -1806 -2084 -1933 -2095 -2136 -2078 -1884 -2438 -2286 -2138 -1750 -2184 -1799 -2278 -2410 -2642 -2435 -1956 -2399 -1774 -2129 -1898 -1823 -1938 -2299 -1862 -2420 -2673 -1984 -2204 -1717 -2074 -2213 -2436 -2297 -2592 -2667 -2703 -2511 -1779 -1782 -2625 -2365 -2315 -2381 -1788 -1714 -2302 -1927 -2325 -2506 -2169 -2328 -2629 -2128 -2655 -2282 -2073 -2395 -2247 -2521 -2260 -1868 -1988 -2324 -2705 -2541 -1731 -2681 -2707 -2465 -1785 -2149 -2045 -2505 -2611 -2217 -2180 -1904 -2453 -2484 -1871 -2309 -2349 -2482 -2004 -1965 -2406 -2162 -1805 -2654 -2007 -1947 -1981 -2112 -2141 -1720 -1758 -2080 -2330 -2030 -2432 -2089 -2547 -1820 -1815 -2675 -1840 -2658 -2370 -2251 -1908 -2029 -2068 -2513 -2549 -2267 -2580 -2327 -2351 -2111 -2022 -2321 -2614 -2252 -2104 -1822 -2552 -2243 -1798 -2396 -2663 -2564 -2148 -2562 -2684 -2001 -2151 -2706 -2240 -2474 -2303 -2634 -2680 -2055 -2090 -2503 -2347 -2402 -2238 -1950 -2054 -2016 -1872 -2233 -1710 -2032 -2540 -2628 -1795 -2616 -1903 -2531 -2567 -1946 -1897 -2222 -2227 -2627 -1856 -2464 -2241 -2481 -2130 -2311 -2083 -2223 -2284 -2235 -2097 -1752 -2515 -2527 -2385 -2189 -2283 -2182 -2079 -2375 -2174 -2437 -1993 -2517 -2443 -2224 -2648 -2171 -2290 -2542 -2038 -1855 -1831 -1759 -1848 -2445 -1827 -2429 -2205 -2598 -2657 -1728 -2065 -1918 -2427 -2573 -2620 -2292 -1777 -2008 -1875 -2288 -2256 -2033 -2470 -2585 -2610 -2082 -2230 -1915 -1847 -2337 -2512 -2386 -2006 -2653 -2346 -1951 -2110 -2639 -2520 -1939 -2683 -2139 -2220 -1910 -2237 -1900 -1836 -2197 -1716 -1860 -2077 -2519 -2538 -2323 -1914 -1971 -1845 -2132 -1802 -1907 -2640 -2496 -2281 -2198 -2416 -2285 -1755 -2431 -2071 -2249 -2123 -1727 -2459 -2304 -2199 -1791 -1809 -1780 -2210 -2417 -1874 -1878 -2116 -1961 -1863 -2579 -2477 -2228 -2332 -2578 -2457 -2024 -1934 -2316 -1841 -1764 -1737 -2322 -2239 -2294 -1729 -2488 -1974 -2473 -2098 -2612 -1834 -2340 -2423 -2175 -2280 -2617 -2208 -2560 -1741 -2600 -2059 -1747 -2242 -2700 -2232 -2057 -2147 -2682 -1792 -1826 -2120 -1895 -2364 -2163 -1851 -2391 -2414 -2452 -1803 -1989 -2623 -2200 -2528 -2415 -1804 -2146 -2619 -2687 -1762 -2172 -2270 -2678 -2593 -2448 -1882 -2257 -2500 -1899 -2478 -2412 -2107 -1746 -2428 -2115 -1800 -1901 -2397 -2530 -1912 -2108 -2206 -2091 -1740 -2219 -1976 -2099 -2142 -2671 -2668 -2216 -2272 -2229 -2666 -2456 -2534 -2697 -2688 -2062 -2691 -2689 -2154 -2590 -2626 -2390 -1813 -2067 -1952 -2518 -2358 -1789 -2076 -2049 -2119 -2013 -2124 -2556 -2105 -2093 -1885 -2305 -2354 -2135 -2601 -1770 -1995 -2504 -1749 -2157 diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.tx b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.tx deleted file mode 100644 index 6e856d777401ee15dc8619db76c97d0a40ba2d60..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 148025 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 diff --git a/tutorials/hypergraph/tmp/Cora/raw/ind.cora.x b/tutorials/hypergraph/tmp/Cora/raw/ind.cora.x deleted file mode 100644 index c4a91d008245403e7f26aa616b437191509793c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22119 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 Date: Thu, 9 Nov 2023 15:47:52 +0000 Subject: [PATCH 38/39] allsettransformer num_epochs=0 --- tutorials/hypergraph/allset_transformer_train.ipynb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tutorials/hypergraph/allset_transformer_train.ipynb b/tutorials/hypergraph/allset_transformer_train.ipynb index 4ae594f7c..a1a2cc2eb 100644 --- a/tutorials/hypergraph/allset_transformer_train.ipynb +++ b/tutorials/hypergraph/allset_transformer_train.ipynb @@ -458,8 +458,8 @@ } ], "source": [ - "test_interval = 1\n", - "num_epochs = 1\n", + "test_interval = 0\n", + "num_epochs = 0\n", "\n", "epoch_loss = []\n", "for epoch_i in range(1, num_epochs + 1):\n", From 62513dcd20369a113f3c19b9662b1bff1c13e109 Mon Sep 17 00:00:00 2001 From: levtelyatnikov Date: Thu, 9 Nov 2023 16:50:52 +0000 Subject: [PATCH 39/39] fix bug with groupd --- .github/workflows/test_tutorials.yml | 2 +- .test_durations | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/test_tutorials.yml b/.github/workflows/test_tutorials.yml index ad33980c1..2eac136a9 100644 --- a/.github/workflows/test_tutorials.yml +++ b/.github/workflows/test_tutorials.yml @@ -71,7 +71,7 @@ jobs: torch-version: [2.0.1] include: - torch-version: 2.0.1 - test-group: [1, 2, 3, 4] + test-group: [1, 2, 3] steps: - uses: actions/checkout@v3 diff --git a/.test_durations b/.test_durations index 4fe06f322..c6aef3420 100644 --- a/.test_durations +++ b/.test_durations @@ -148,18 +148,18 @@ "test/tutorials/test_cell.py::test_tutorial[tutorials/cell/ccxn_train.ipynb]": 10.362705206964165, "test/tutorials/test_cell.py::test_tutorial[tutorials/cell/cwn_train.ipynb]": 10.345093041891232, "test/tutorials/test_combinatorial.py::test_tutorial[tutorials/combinatorial/hmc_train.ipynb]": 113.72826133295894, - "test/tutorials/test_hypergraph.py::test_tutorial[tutorials/hypergraph/allset_train.ipynb]": 10.690549792023376, - "test/tutorials/test_hypergraph.py::test_tutorial[tutorials/hypergraph/allset_transformer_train.ipynb]": 17.616297374945134, - "test/tutorials/test_hypergraph.py::test_tutorial[tutorials/hypergraph/dhgcn_train.ipynb]": 47.93890062533319, - "test/tutorials/test_hypergraph.py::test_tutorial[tutorials/hypergraph/hmpnn_train.ipynb]": 7.804051124723628, - "test/tutorials/test_hypergraph.py::test_tutorial[tutorials/hypergraph/hnhn_train.ipynb]": 5.239491417305544, + "test/tutorials/test_hypergraph.py::test_tutorial[tutorials/hypergraph/allset_train.ipynb]": 8.943679120042361, + "test/tutorials/test_hypergraph.py::test_tutorial[tutorials/hypergraph/allset_transformer_train.ipynb]": 5.0502030230127275, + "test/tutorials/test_hypergraph.py::test_tutorial[tutorials/hypergraph/dhgcn_train.ipynb]": 80.38319573295303, + "test/tutorials/test_hypergraph.py::test_tutorial[tutorials/hypergraph/hmpnn_train.ipynb]": 5.240434563951567, + "test/tutorials/test_hypergraph.py::test_tutorial[tutorials/hypergraph/hnhn_train.ipynb]": 5.292717668809928, "test/tutorials/test_hypergraph.py::test_tutorial[tutorials/hypergraph/hnhn_train_bis.ipynb]": 16.502087499015033, - "test/tutorials/test_hypergraph.py::test_tutorial[tutorials/hypergraph/hypergat_train.ipynb]": 16.043949334183708, - "test/tutorials/test_hypergraph.py::test_tutorial[tutorials/hypergraph/hypersage_train.ipynb]": 44.49209712515585, - "test/tutorials/test_hypergraph.py::test_tutorial[tutorials/hypergraph/unigcn_train.ipynb]": 5.906059790868312, - "test/tutorials/test_hypergraph.py::test_tutorial[tutorials/hypergraph/unigcnii_train.ipynb]": 19.70078912517056, - "test/tutorials/test_hypergraph.py::test_tutorial[tutorials/hypergraph/unigin_train.ipynb]": 8.093902500113472, - "test/tutorials/test_hypergraph.py::test_tutorial[tutorials/hypergraph/unisage_train.ipynb]": 8.754238750087097, + "test/tutorials/test_hypergraph.py::test_tutorial[tutorials/hypergraph/hypergat_train.ipynb]": 16.28355930291582, + "test/tutorials/test_hypergraph.py::test_tutorial[tutorials/hypergraph/hypersage_train.ipynb]": 8.78812964912504, + "test/tutorials/test_hypergraph.py::test_tutorial[tutorials/hypergraph/unigcn_train.ipynb]": 6.283768973895349, + "test/tutorials/test_hypergraph.py::test_tutorial[tutorials/hypergraph/unigcnii_train.ipynb]": 6.922894097981043, + "test/tutorials/test_hypergraph.py::test_tutorial[tutorials/hypergraph/unigin_train.ipynb]": 6.994051485904492, + "test/tutorials/test_hypergraph.py::test_tutorial[tutorials/hypergraph/unisage_train.ipynb]": 4.923791292007081, "test/tutorials/test_simplicial.py::test_tutorial[tutorials/simplicial/dist2cycle_train.ipynb]": 5.09599137515761, "test/tutorials/test_simplicial.py::test_tutorial[tutorials/simplicial/hsn_train.ipynb]": 4.862493500346318, "test/tutorials/test_simplicial.py::test_tutorial[tutorials/simplicial/san_train.ipynb]": 5.597147291759029,

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 literal 0 HcmV?d00001 diff --git a/tutorials/hypergraph/Cora/raw/ind.cora.x b/tutorials/hypergraph/Cora/raw/ind.cora.x new file mode 100644 index 0000000000000000000000000000000000000000..c4a91d008245403e7f26aa616b437191509793c0 GIT binary patch literal 22119 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 Date: Tue, 7 Nov 2023 14:30:24 +0000 Subject: [PATCH 18/39] checking issue with dataset --- tutorials/hypergraph/Cora/raw/ind.cora.allx | Bin 257305 -> 0 bytes tutorials/hypergraph/Cora/raw/ind.cora.ally | Bin 47959 -> 0 bytes tutorials/hypergraph/Cora/raw/ind.cora.graph | Bin 59847 -> 0 bytes .../hypergraph/Cora/raw/ind.cora.test.index | 1000 ----------------- tutorials/hypergraph/Cora/raw/ind.cora.tx | Bin 148025 -> 0 bytes tutorials/hypergraph/Cora/raw/ind.cora.ty | Bin 28135 -> 0 bytes tutorials/hypergraph/Cora/raw/ind.cora.x | Bin 22119 -> 0 bytes tutorials/hypergraph/Cora/raw/ind.cora.y | Bin 4054 -> 0 bytes 8 files changed, 1000 deletions(-) delete mode 100644 tutorials/hypergraph/Cora/raw/ind.cora.allx delete mode 100644 tutorials/hypergraph/Cora/raw/ind.cora.ally delete mode 100644 tutorials/hypergraph/Cora/raw/ind.cora.graph delete mode 100644 tutorials/hypergraph/Cora/raw/ind.cora.test.index delete mode 100644 tutorials/hypergraph/Cora/raw/ind.cora.tx delete mode 100644 tutorials/hypergraph/Cora/raw/ind.cora.ty delete mode 100644 tutorials/hypergraph/Cora/raw/ind.cora.x delete mode 100644 tutorials/hypergraph/Cora/raw/ind.cora.y diff --git a/tutorials/hypergraph/Cora/raw/ind.cora.allx b/tutorials/hypergraph/Cora/raw/ind.cora.allx deleted file mode 100644 index 44d53b1fece343538e45592caac521d73c6f98d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 257305 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 z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF z7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#bKF7#jHhhXxMY_waq6 G`Tqf}DSCbY diff --git a/tutorials/hypergraph/Cora/raw/ind.cora.ally b/tutorials/hypergraph/Cora/raw/ind.cora.ally deleted file mode 100644 index 04fbd0b083d09341fcf16b395c642329637f0542..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47959 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 My~lCyzWDTi0g%o(9smFU diff --git a/tutorials/hypergraph/Cora/raw/ind.cora.graph b/tutorials/hypergraph/Cora/raw/ind.cora.graph deleted file mode 100644 index 4d3bf85dfc8b1c105a2c995597a1b3eed6947925..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59847 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 A!vFvP diff --git a/tutorials/hypergraph/Cora/raw/ind.cora.test.index b/tutorials/hypergraph/Cora/raw/ind.cora.test.index deleted file mode 100644 index ded8092db..000000000 --- a/tutorials/hypergraph/Cora/raw/ind.cora.test.index +++ /dev/null @@ -1,1000 +0,0 @@ -2692 -2532 -2050 -1715 -2362 -2609 -2622 -1975 -2081 -1767 -2263 -1725 -2588 -2259 -2357 -1998 -2574 -2179 -2291 -2382 -1812 -1751 -2422 -1937 -2631 -2510 -2378 -2589 -2345 -1943 -1850 -2298 -1825 -2035 -2507 -2313 -1906 -1797 -2023 -2159 -2495 -1886 -2122 -2369 -2461 -1925 -2565 -1858 -2234 -2000 -1846 -2318 -1723 -2559 -2258 -1763 -1991 -1922 -2003 -2662 -2250 -2064 -2529 -1888 -2499 -2454 -2320 -2287 -2203 -2018 -2002 -2632 -2554 -2314 -2537 -1760 -2088 -2086 -2218 -2605 -1953 -2403 -1920 -2015 -2335 -2535 -1837 -2009 -1905 -2636 -1942 -2193 -2576 -2373 -1873 -2463 -2509 -1954 -2656 -2455 -2494 -2295 -2114 -2561 -2176 -2275 -2635 -2442 -2704 -2127 -2085 -2214 -2487 -1739 -2543 -1783 -2485 -2262 -2472 -2326 -1738 -2170 -2100 -2384 -2152 -2647 -2693 -2376 -1775 -1726 -2476 -2195 -1773 -1793 -2194 -2581 -1854 -2524 -1945 -1781 -1987 -2599 -1744 -2225 -2300 -1928 -2042 -2202 -1958 -1816 -1916 -2679 -2190 -1733 -2034 -2643 -2177 -1883 -1917 -1996 -2491 -2268 -2231 -2471 -1919 -1909 -2012 -2522 -1865 -2466 -2469 -2087 -2584 -2563 -1924 -2143 -1736 -1966 -2533 -2490 -2630 -1973 -2568 -1978 -2664 -2633 -2312 -2178 -1754 -2307 -2480 -1960 -1742 -1962 -2160 -2070 -2553 -2433 -1768 -2659 -2379 -2271 -1776 -2153 -1877 -2027 -2028 -2155 -2196 -2483 -2026 -2158 -2407 -1821 -2131 -2676 -2277 -2489 -2424 -1963 -1808 -1859 -2597 -2548 -2368 -1817 -2405 -2413 -2603 -2350 -2118 -2329 -1969 -2577 -2475 -2467 -2425 -1769 -2092 -2044 -2586 -2608 -1983 -2109 -2649 -1964 -2144 -1902 -2411 -2508 -2360 -1721 -2005 -2014 -2308 -2646 -1949 -1830 -2212 -2596 -1832 -1735 -1866 -2695 -1941 -2546 -2498 -2686 -2665 -1784 -2613 -1970 -2021 -2211 -2516 -2185 -2479 -2699 -2150 -1990 -2063 -2075 -1979 -2094 -1787 -2571 -2690 -1926 -2341 -2566 -1957 -1709 -1955 -2570 -2387 -1811 -2025 -2447 -2696 -2052 -2366 -1857 -2273 -2245 -2672 -2133 -2421 -1929 -2125 -2319 -2641 -2167 -2418 -1765 -1761 -1828 -2188 -1972 -1997 -2419 -2289 -2296 -2587 -2051 -2440 -2053 -2191 -1923 -2164 -1861 -2339 -2333 -2523 -2670 -2121 -1921 -1724 -2253 -2374 -1940 -2545 -2301 -2244 -2156 -1849 -2551 -2011 -2279 -2572 -1757 -2400 -2569 -2072 -2526 -2173 -2069 -2036 -1819 -1734 -1880 -2137 -2408 -2226 -2604 -1771 -2698 -2187 -2060 -1756 -2201 -2066 -2439 -1844 -1772 -2383 -2398 -1708 -1992 -1959 -1794 -2426 -2702 -2444 -1944 -1829 -2660 -2497 -2607 -2343 -1730 -2624 -1790 -1935 -1967 -2401 -2255 -2355 -2348 -1931 -2183 -2161 -2701 -1948 -2501 -2192 -2404 -2209 -2331 -1810 -2363 -2334 -1887 -2393 -2557 -1719 -1732 -1986 -2037 -2056 -1867 -2126 -1932 -2117 -1807 -1801 -1743 -2041 -1843 -2388 -2221 -1833 -2677 -1778 -2661 -2306 -2394 -2106 -2430 -2371 -2606 -2353 -2269 -2317 -2645 -2372 -2550 -2043 -1968 -2165 -2310 -1985 -2446 -1982 -2377 -2207 -1818 -1913 -1766 -1722 -1894 -2020 -1881 -2621 -2409 -2261 -2458 -2096 -1712 -2594 -2293 -2048 -2359 -1839 -2392 -2254 -1911 -2101 -2367 -1889 -1753 -2555 -2246 -2264 -2010 -2336 -2651 -2017 -2140 -1842 -2019 -1890 -2525 -2134 -2492 -2652 -2040 -2145 -2575 -2166 -1999 -2434 -1711 -2276 -2450 -2389 -2669 -2595 -1814 -2039 -2502 -1896 -2168 -2344 -2637 -2031 -1977 -2380 -1936 -2047 -2460 -2102 -1745 -2650 -2046 -2514 -1980 -2352 -2113 -1713 -2058 -2558 -1718 -1864 -1876 -2338 -1879 -1891 -2186 -2451 -2181 -2638 -2644 -2103 -2591 -2266 -2468 -1869 -2582 -2674 -2361 -2462 -1748 -2215 -2615 -2236 -2248 -2493 -2342 -2449 -2274 -1824 -1852 -1870 -2441 -2356 -1835 -2694 -2602 -2685 -1893 -2544 -2536 -1994 -1853 -1838 -1786 -1930 -2539 -1892 -2265 -2618 -2486 -2583 -2061 -1796 -1806 -2084 -1933 -2095 -2136 -2078 -1884 -2438 -2286 -2138 -1750 -2184 -1799 -2278 -2410 -2642 -2435 -1956 -2399 -1774 -2129 -1898 -1823 -1938 -2299 -1862 -2420 -2673 -1984 -2204 -1717 -2074 -2213 -2436 -2297 -2592 -2667 -2703 -2511 -1779 -1782 -2625 -2365 -2315 -2381 -1788 -1714 -2302 -1927 -2325 -2506 -2169 -2328 -2629 -2128 -2655 -2282 -2073 -2395 -2247 -2521 -2260 -1868 -1988 -2324 -2705 -2541 -1731 -2681 -2707 -2465 -1785 -2149 -2045 -2505 -2611 -2217 -2180 -1904 -2453 -2484 -1871 -2309 -2349 -2482 -2004 -1965 -2406 -2162 -1805 -2654 -2007 -1947 -1981 -2112 -2141 -1720 -1758 -2080 -2330 -2030 -2432 -2089 -2547 -1820 -1815 -2675 -1840 -2658 -2370 -2251 -1908 -2029 -2068 -2513 -2549 -2267 -2580 -2327 -2351 -2111 -2022 -2321 -2614 -2252 -2104 -1822 -2552 -2243 -1798 -2396 -2663 -2564 -2148 -2562 -2684 -2001 -2151 -2706 -2240 -2474 -2303 -2634 -2680 -2055 -2090 -2503 -2347 -2402 -2238 -1950 -2054 -2016 -1872 -2233 -1710 -2032 -2540 -2628 -1795 -2616 -1903 -2531 -2567 -1946 -1897 -2222 -2227 -2627 -1856 -2464 -2241 -2481 -2130 -2311 -2083 -2223 -2284 -2235 -2097 -1752 -2515 -2527 -2385 -2189 -2283 -2182 -2079 -2375 -2174 -2437 -1993 -2517 -2443 -2224 -2648 -2171 -2290 -2542 -2038 -1855 -1831 -1759 -1848 -2445 -1827 -2429 -2205 -2598 -2657 -1728 -2065 -1918 -2427 -2573 -2620 -2292 -1777 -2008 -1875 -2288 -2256 -2033 -2470 -2585 -2610 -2082 -2230 -1915 -1847 -2337 -2512 -2386 -2006 -2653 -2346 -1951 -2110 -2639 -2520 -1939 -2683 -2139 -2220 -1910 -2237 -1900 -1836 -2197 -1716 -1860 -2077 -2519 -2538 -2323 -1914 -1971 -1845 -2132 -1802 -1907 -2640 -2496 -2281 -2198 -2416 -2285 -1755 -2431 -2071 -2249 -2123 -1727 -2459 -2304 -2199 -1791 -1809 -1780 -2210 -2417 -1874 -1878 -2116 -1961 -1863 -2579 -2477 -2228 -2332 -2578 -2457 -2024 -1934 -2316 -1841 -1764 -1737 -2322 -2239 -2294 -1729 -2488 -1974 -2473 -2098 -2612 -1834 -2340 -2423 -2175 -2280 -2617 -2208 -2560 -1741 -2600 -2059 -1747 -2242 -2700 -2232 -2057 -2147 -2682 -1792 -1826 -2120 -1895 -2364 -2163 -1851 -2391 -2414 -2452 -1803 -1989 -2623 -2200 -2528 -2415 -1804 -2146 -2619 -2687 -1762 -2172 -2270 -2678 -2593 -2448 -1882 -2257 -2500 -1899 -2478 -2412 -2107 -1746 -2428 -2115 -1800 -1901 -2397 -2530 -1912 -2108 -2206 -2091 -1740 -2219 -1976 -2099 -2142 -2671 -2668 -2216 -2272 -2229 -2666 -2456 -2534 -2697 -2688 -2062 -2691 -2689 -2154 -2590 -2626 -2390 -1813 -2067 -1952 -2518 -2358 -1789 -2076 -2049 -2119 -2013 -2124 -2556 -2105 -2093 -1885 -2305 -2354 -2135 -2601 -1770 -1995 -2504 -1749 -2157 diff --git a/tutorials/hypergraph/Cora/raw/ind.cora.tx b/tutorials/hypergraph/Cora/raw/ind.cora.tx deleted file mode 100644 index 6e856d777401ee15dc8619db76c97d0a40ba2d60..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 148025 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