From 6e222a479c1ed123b94f25add8b078ad30422205 Mon Sep 17 00:00:00 2001 From: mminici Date: Thu, 3 Sep 2020 11:48:40 +0200 Subject: [PATCH 1/2] add renormalization trick option + benchmark notebook --- ...ici-renorm_trick_test-0.1-checkpoint.ipynb | 618 ++++++++++++++++++ notebooks/mminici-renorm_trick_test-0.1.ipynb | 618 ++++++++++++++++++ pygcn/utils.py | 20 +- 3 files changed, 1250 insertions(+), 6 deletions(-) create mode 100644 notebooks/.ipynb_checkpoints/mminici-renorm_trick_test-0.1-checkpoint.ipynb create mode 100644 notebooks/mminici-renorm_trick_test-0.1.ipynb diff --git a/notebooks/.ipynb_checkpoints/mminici-renorm_trick_test-0.1-checkpoint.ipynb b/notebooks/.ipynb_checkpoints/mminici-renorm_trick_test-0.1-checkpoint.ipynb new file mode 100644 index 0000000..00e160a --- /dev/null +++ b/notebooks/.ipynb_checkpoints/mminici-renorm_trick_test-0.1-checkpoint.ipynb @@ -0,0 +1,618 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This notebook is largely inspired by this [other notebook](https://colab.research.google.com/drive/18EyozusBSgxa5oUBmlzXrp9fEbPyOUoC#scrollTo=_37NFK0iqCFx) originally published by IAML (Italian Association for Machine Learning)." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# Add the codebase to the path\n", + "import sys\n", + "sys.path.insert(0,'../')" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# Some useful imports\n", + "import numpy as np\n", + "\n", + "import torch\n", + "from torch import nn, optim\n", + "from torch.utils import data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Load the Dataset" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Loading cora dataset...\n" + ] + } + ], + "source": [ + "from pygcn.utils import load_data\n", + "symmetric_norm_flag = False\n", + "\n", + "adj, features, labels, idx_train, idx_val, idx_test = load_data(path='../../pygcn/data/cora/', symm_norm=symmetric_norm_flag)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "torch.Size([2708, 1433])" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "features.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "torch.Size([2708])\n", + "tensor(6)\n" + ] + } + ], + "source": [ + "print(labels.shape)\n", + "print(torch.max(labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "torch.Size([2708, 2708])" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "adj.shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Baseline model (without any info on the graph)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "# Feedforward Neural Network with a single hidden layer\n", + "net = nn.Sequential(nn.Linear(1433, 100), nn.ReLU(), nn.Linear(100, 7))" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "from pygcn.utils import accuracy\n", + "def test(model):\n", + " # Test the model on the test set\n", + " y_pred = model(features[idx_test])\n", + " acc_test = accuracy(y_pred, labels[idx_test])\n", + " print(\"Accuracy:\",\n", + " \"accuracy= {:.4f}\".format(acc_test.item()))" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: accuracy= 0.0720\n" + ] + } + ], + "source": [ + "# Accuracy without training\n", + "test(net)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "criterion = nn.CrossEntropyLoss()\n", + "optimizer = optim.Adam(net.parameters())" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 1000/1000 [00:01<00:00, 612.32it/s]\n" + ] + } + ], + "source": [ + "import tqdm\n", + "loss_history = np.zeros(1000)\n", + "\n", + "for epoch in tqdm.trange(1000):\n", + "\n", + " optimizer.zero_grad()\n", + " outputs = net(features[idx_train])\n", + " loss = criterion(outputs, labels[idx_train])\n", + " loss.backward()\n", + " optimizer.step()\n", + "\n", + " loss_history[epoch] = loss.detach().numpy()" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "plt.plot(loss_history)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: accuracy= 0.5060\n" + ] + } + ], + "source": [ + "test(net)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Graph Convolutional Network" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "# Taken (and simplified) from:\n", + "# https://github.com/tkipf/pygcn/blob/master/pygcn/layers.py\n", + "\n", + "import math\n", + "\n", + "import torch\n", + "\n", + "from torch.nn.parameter import Parameter\n", + "from torch.nn.modules.module import Module\n", + "\n", + "\n", + "class GraphConvolution(Module):\n", + " \"\"\"\n", + " Simple GCN layer, similar to https://arxiv.org/abs/1609.02907\n", + " \"\"\"\n", + "\n", + " def __init__(self, in_features, out_features):\n", + " super(GraphConvolution, self).__init__()\n", + " self.weight = Parameter(torch.FloatTensor(in_features, out_features))\n", + " self.bias = Parameter(torch.FloatTensor(out_features))\n", + " self.reset_parameters()\n", + "\n", + " def reset_parameters(self):\n", + " stdv = 1. / math.sqrt(self.weight.size(1))\n", + " self.weight.data.uniform_(-stdv, stdv)\n", + " self.bias.data.uniform_(-stdv, stdv)\n", + "\n", + " def forward(self, input, adj):\n", + " support = torch.mm(input, self.weight) \n", + " output = torch.spmm(adj, support) \n", + " return output + self.bias" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "# Taken (and simplified) from:\n", + "# https://github.com/tkipf/pygcn/blob/master/pygcn/models.py\n", + "\n", + "import torch.nn.functional as F\n", + "\n", + "class GCN(nn.Module):\n", + " def __init__(self, nfeat, nhid, nclass):\n", + " super(GCN, self).__init__()\n", + " self.gc1 = GraphConvolution(nfeat, nhid)\n", + " self.gc2 = GraphConvolution(nhid, nclass)\n", + "\n", + " def forward(self, x, adj):\n", + " x = F.relu(self.gc1(x, adj))\n", + " x = self.gc2(x, adj)\n", + " return F.log_softmax(x, dim=1)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "gcn = GCN(1433, 50, 7)\n", + "optimizer_gcn = optim.Adam(gcn.parameters())" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "def test(model):\n", + " y_pred = model(features, adj) # Using the whole dataset\n", + " acc_test = accuracy(y_pred[idx_test], labels[idx_test]) # Masking on the test set\n", + " print(\"Accuracy:\",\n", + " \"accuracy= {:.4f}\".format(acc_test.item()))" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: accuracy= 0.1230\n" + ] + } + ], + "source": [ + "# Testing without training\n", + "test(gcn)" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 2500/2500 [00:25<00:00, 96.29it/s]\n" + ] + } + ], + "source": [ + "import tqdm\n", + "loss_history = np.zeros(2500) \n", + "\n", + "for epoch in tqdm.trange(2500): \n", + " \n", + " optimizer_gcn.zero_grad()\n", + " outputs = gcn(features, adj) # Usiamo tutto il dataset\n", + " loss = criterion(outputs[idx_train], labels[idx_train]) # Mascheriamo sulla parte di training\n", + " loss.backward()\n", + " optimizer_gcn.step()\n", + "\n", + " loss_history[epoch] = loss.detach().numpy()" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "plt.plot(loss_history)\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: accuracy= 0.7940\n" + ] + } + ], + "source": [ + "test(gcn)" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "First model parameters: 144107\n", + "Second model parameters: 72057\n" + ] + } + ], + "source": [ + "# Snippet taken from: https://stackoverflow.com/questions/49201236/check-the-total-number-of-parameters-in-a-pytorch-model\n", + "net_params = sum(p.numel() for p in net.parameters() if p.requires_grad) \n", + "gcn_params = sum(p.numel() for p in gcn.parameters() if p.requires_grad)\n", + "\n", + "print('First model parameters: ', net_params)\n", + "print('Second model parameters: ', gcn_params)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "What if... we make use of the $D^{-\\frac{1}{2}} A D^{-\\frac{1}{2}}$ normalization formula?" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Loading cora dataset...\n" + ] + } + ], + "source": [ + "from pygcn.utils import load_data\n", + "symmetric_norm_flag = True # change this flag to enable the D^-1/2 A D^-1/2 formula\n", + "\n", + "adj, features, labels, idx_train, idx_val, idx_test = load_data(path='../../pygcn/data/cora/', symm_norm=symmetric_norm_flag)" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [], + "source": [ + "gcn = GCN(1433, 50, 7)\n", + "optimizer_gcn = optim.Adam(gcn.parameters())" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: accuracy= 0.1360\n" + ] + } + ], + "source": [ + "# Testing without training\n", + "test(gcn)" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 5000/5000 [00:48<00:00, 102.92it/s]\n" + ] + } + ], + "source": [ + "import tqdm\n", + "loss_history = np.zeros(5000) \n", + "\n", + "for epoch in tqdm.trange(5000): \n", + " \n", + " optimizer_gcn.zero_grad()\n", + " outputs = gcn(features, adj) # Usiamo tutto il dataset\n", + " loss = criterion(outputs[idx_train], labels[idx_train]) # Mascheriamo sulla parte di training\n", + " loss.backward()\n", + " optimizer_gcn.step()\n", + "\n", + " loss_history[epoch] = loss.detach().numpy()" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "plt.plot(loss_history)\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: accuracy= 0.5040\n" + ] + } + ], + "source": [ + "test(gcn)" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "First model parameters: 144107\n", + "Second model parameters: 72057\n" + ] + } + ], + "source": [ + "# Snippet taken from: https://stackoverflow.com/questions/49201236/check-the-total-number-of-parameters-in-a-pytorch-model\n", + "net_params = sum(p.numel() for p in net.parameters() if p.requires_grad) \n", + "gcn_params = sum(p.numel() for p in gcn.parameters() if p.requires_grad)\n", + "\n", + "print('First model parameters: ', net_params)\n", + "print('Second model parameters: ', gcn_params)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.7.7" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebooks/mminici-renorm_trick_test-0.1.ipynb b/notebooks/mminici-renorm_trick_test-0.1.ipynb new file mode 100644 index 0000000..00e160a --- /dev/null +++ b/notebooks/mminici-renorm_trick_test-0.1.ipynb @@ -0,0 +1,618 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This notebook is largely inspired by this [other notebook](https://colab.research.google.com/drive/18EyozusBSgxa5oUBmlzXrp9fEbPyOUoC#scrollTo=_37NFK0iqCFx) originally published by IAML (Italian Association for Machine Learning)." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# Add the codebase to the path\n", + "import sys\n", + "sys.path.insert(0,'../')" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# Some useful imports\n", + "import numpy as np\n", + "\n", + "import torch\n", + "from torch import nn, optim\n", + "from torch.utils import data" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Load the Dataset" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Loading cora dataset...\n" + ] + } + ], + "source": [ + "from pygcn.utils import load_data\n", + "symmetric_norm_flag = False\n", + "\n", + "adj, features, labels, idx_train, idx_val, idx_test = load_data(path='../../pygcn/data/cora/', symm_norm=symmetric_norm_flag)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "torch.Size([2708, 1433])" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "features.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "torch.Size([2708])\n", + "tensor(6)\n" + ] + } + ], + "source": [ + "print(labels.shape)\n", + "print(torch.max(labels))" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "torch.Size([2708, 2708])" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "adj.shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Baseline model (without any info on the graph)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "# Feedforward Neural Network with a single hidden layer\n", + "net = nn.Sequential(nn.Linear(1433, 100), nn.ReLU(), nn.Linear(100, 7))" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "from pygcn.utils import accuracy\n", + "def test(model):\n", + " # Test the model on the test set\n", + " y_pred = model(features[idx_test])\n", + " acc_test = accuracy(y_pred, labels[idx_test])\n", + " print(\"Accuracy:\",\n", + " \"accuracy= {:.4f}\".format(acc_test.item()))" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: accuracy= 0.0720\n" + ] + } + ], + "source": [ + "# Accuracy without training\n", + "test(net)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "criterion = nn.CrossEntropyLoss()\n", + "optimizer = optim.Adam(net.parameters())" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 1000/1000 [00:01<00:00, 612.32it/s]\n" + ] + } + ], + "source": [ + "import tqdm\n", + "loss_history = np.zeros(1000)\n", + "\n", + "for epoch in tqdm.trange(1000):\n", + "\n", + " optimizer.zero_grad()\n", + " outputs = net(features[idx_train])\n", + " loss = criterion(outputs, labels[idx_train])\n", + " loss.backward()\n", + " optimizer.step()\n", + "\n", + " loss_history[epoch] = loss.detach().numpy()" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "plt.plot(loss_history)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: accuracy= 0.5060\n" + ] + } + ], + "source": [ + "test(net)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Graph Convolutional Network" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "# Taken (and simplified) from:\n", + "# https://github.com/tkipf/pygcn/blob/master/pygcn/layers.py\n", + "\n", + "import math\n", + "\n", + "import torch\n", + "\n", + "from torch.nn.parameter import Parameter\n", + "from torch.nn.modules.module import Module\n", + "\n", + "\n", + "class GraphConvolution(Module):\n", + " \"\"\"\n", + " Simple GCN layer, similar to https://arxiv.org/abs/1609.02907\n", + " \"\"\"\n", + "\n", + " def __init__(self, in_features, out_features):\n", + " super(GraphConvolution, self).__init__()\n", + " self.weight = Parameter(torch.FloatTensor(in_features, out_features))\n", + " self.bias = Parameter(torch.FloatTensor(out_features))\n", + " self.reset_parameters()\n", + "\n", + " def reset_parameters(self):\n", + " stdv = 1. / math.sqrt(self.weight.size(1))\n", + " self.weight.data.uniform_(-stdv, stdv)\n", + " self.bias.data.uniform_(-stdv, stdv)\n", + "\n", + " def forward(self, input, adj):\n", + " support = torch.mm(input, self.weight) \n", + " output = torch.spmm(adj, support) \n", + " return output + self.bias" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "# Taken (and simplified) from:\n", + "# https://github.com/tkipf/pygcn/blob/master/pygcn/models.py\n", + "\n", + "import torch.nn.functional as F\n", + "\n", + "class GCN(nn.Module):\n", + " def __init__(self, nfeat, nhid, nclass):\n", + " super(GCN, self).__init__()\n", + " self.gc1 = GraphConvolution(nfeat, nhid)\n", + " self.gc2 = GraphConvolution(nhid, nclass)\n", + "\n", + " def forward(self, x, adj):\n", + " x = F.relu(self.gc1(x, adj))\n", + " x = self.gc2(x, adj)\n", + " return F.log_softmax(x, dim=1)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "gcn = GCN(1433, 50, 7)\n", + "optimizer_gcn = optim.Adam(gcn.parameters())" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "def test(model):\n", + " y_pred = model(features, adj) # Using the whole dataset\n", + " acc_test = accuracy(y_pred[idx_test], labels[idx_test]) # Masking on the test set\n", + " print(\"Accuracy:\",\n", + " \"accuracy= {:.4f}\".format(acc_test.item()))" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: accuracy= 0.1230\n" + ] + } + ], + "source": [ + "# Testing without training\n", + "test(gcn)" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 2500/2500 [00:25<00:00, 96.29it/s]\n" + ] + } + ], + "source": [ + "import tqdm\n", + "loss_history = np.zeros(2500) \n", + "\n", + "for epoch in tqdm.trange(2500): \n", + " \n", + " optimizer_gcn.zero_grad()\n", + " outputs = gcn(features, adj) # Usiamo tutto il dataset\n", + " loss = criterion(outputs[idx_train], labels[idx_train]) # Mascheriamo sulla parte di training\n", + " loss.backward()\n", + " optimizer_gcn.step()\n", + "\n", + " loss_history[epoch] = loss.detach().numpy()" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "plt.plot(loss_history)\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: accuracy= 0.7940\n" + ] + } + ], + "source": [ + "test(gcn)" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "First model parameters: 144107\n", + "Second model parameters: 72057\n" + ] + } + ], + "source": [ + "# Snippet taken from: https://stackoverflow.com/questions/49201236/check-the-total-number-of-parameters-in-a-pytorch-model\n", + "net_params = sum(p.numel() for p in net.parameters() if p.requires_grad) \n", + "gcn_params = sum(p.numel() for p in gcn.parameters() if p.requires_grad)\n", + "\n", + "print('First model parameters: ', net_params)\n", + "print('Second model parameters: ', gcn_params)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "What if... we make use of the $D^{-\\frac{1}{2}} A D^{-\\frac{1}{2}}$ normalization formula?" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Loading cora dataset...\n" + ] + } + ], + "source": [ + "from pygcn.utils import load_data\n", + "symmetric_norm_flag = True # change this flag to enable the D^-1/2 A D^-1/2 formula\n", + "\n", + "adj, features, labels, idx_train, idx_val, idx_test = load_data(path='../../pygcn/data/cora/', symm_norm=symmetric_norm_flag)" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [], + "source": [ + "gcn = GCN(1433, 50, 7)\n", + "optimizer_gcn = optim.Adam(gcn.parameters())" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: accuracy= 0.1360\n" + ] + } + ], + "source": [ + "# Testing without training\n", + "test(gcn)" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 5000/5000 [00:48<00:00, 102.92it/s]\n" + ] + } + ], + "source": [ + "import tqdm\n", + "loss_history = np.zeros(5000) \n", + "\n", + "for epoch in tqdm.trange(5000): \n", + " \n", + " optimizer_gcn.zero_grad()\n", + " outputs = gcn(features, adj) # Usiamo tutto il dataset\n", + " loss = criterion(outputs[idx_train], labels[idx_train]) # Mascheriamo sulla parte di training\n", + " loss.backward()\n", + " optimizer_gcn.step()\n", + "\n", + " loss_history[epoch] = loss.detach().numpy()" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "plt.plot(loss_history)\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Accuracy: accuracy= 0.5040\n" + ] + } + ], + "source": [ + "test(gcn)" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "First model parameters: 144107\n", + "Second model parameters: 72057\n" + ] + } + ], + "source": [ + "# Snippet taken from: https://stackoverflow.com/questions/49201236/check-the-total-number-of-parameters-in-a-pytorch-model\n", + "net_params = sum(p.numel() for p in net.parameters() if p.requires_grad) \n", + "gcn_params = sum(p.numel() for p in gcn.parameters() if p.requires_grad)\n", + "\n", + "print('First model parameters: ', net_params)\n", + "print('Second model parameters: ', gcn_params)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "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.7.7" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/pygcn/utils.py b/pygcn/utils.py index 9b53c5b..87a0420 100644 --- a/pygcn/utils.py +++ b/pygcn/utils.py @@ -1,6 +1,7 @@ import numpy as np import scipy.sparse as sp import torch +from scipy.linalg import fractional_matrix_power as matrix_frac_power def encode_onehot(labels): @@ -12,7 +13,7 @@ def encode_onehot(labels): return labels_onehot -def load_data(path="../data/cora/", dataset="cora"): +def load_data(path="../data/cora/", dataset="cora", symm_norm = False): """Load citation network dataset (cora only for now)""" print('Loading {} dataset...'.format(dataset)) @@ -32,12 +33,19 @@ def load_data(path="../data/cora/", dataset="cora"): shape=(labels.shape[0], labels.shape[0]), dtype=np.float32) - # build symmetric adjacency matrix - adj = adj + adj.T.multiply(adj.T > adj) - adj.multiply(adj.T > adj) - + if not symm_norm: + # use the D^-1A formula + adj = adj + adj.T.multiply(adj.T > adj) - adj.multiply(adj.T > adj) + adj = normalize(adj + sp.eye(adj.shape[0])) + else: + # use the D^-1/2AD^-1/2 formula + adj = adj + sp.eye(adj.shape[0]) # add self loop + D = np.diag(np.array(adj.sum(axis=0)).flatten()) # build degree matrix + D_prime = matrix_frac_power(D,-0.5) + D_prime = sp.coo_matrix(D_prime, shape=(adj.shape[0],adj.shape[0]),dtype=np.float32) # convert to sparse format + adj = D_prime @ adj @ D_prime # compute the normalized symmetric version + features = normalize(features) - adj = normalize(adj + sp.eye(adj.shape[0])) - idx_train = range(140) idx_val = range(200, 500) idx_test = range(500, 1500) From 83a1a1140c1f4b112fc060d7aca591504471c00f Mon Sep 17 00:00:00 2001 From: mminici Date: Sun, 20 Sep 2020 20:23:32 +0200 Subject: [PATCH 2/2] switched axis when computing degree matrix --- ...ici-renorm_trick_test-0.1-checkpoint.ipynb | 36 +++++++++---------- notebooks/mminici-renorm_trick_test-0.1.ipynb | 36 +++++++++---------- pygcn/utils.py | 2 +- 3 files changed, 37 insertions(+), 37 deletions(-) diff --git a/notebooks/.ipynb_checkpoints/mminici-renorm_trick_test-0.1-checkpoint.ipynb b/notebooks/.ipynb_checkpoints/mminici-renorm_trick_test-0.1-checkpoint.ipynb index 00e160a..138ed4f 100644 --- a/notebooks/.ipynb_checkpoints/mminici-renorm_trick_test-0.1-checkpoint.ipynb +++ b/notebooks/.ipynb_checkpoints/mminici-renorm_trick_test-0.1-checkpoint.ipynb @@ -159,7 +159,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Accuracy: accuracy= 0.0720\n" + "Accuracy: accuracy= 0.1460\n" ] } ], @@ -187,7 +187,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "100%|██████████| 1000/1000 [00:01<00:00, 612.32it/s]\n" + "100%|██████████| 1000/1000 [00:01<00:00, 557.19it/s]\n" ] } ], @@ -214,7 +214,7 @@ { "data": { "text/plain": [ - "[]" + "[]" ] }, "execution_count": 12, @@ -236,7 +236,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Accuracy: accuracy= 0.5060\n" + "Accuracy: accuracy= 0.4890\n" ] } ], @@ -345,7 +345,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Accuracy: accuracy= 0.1230\n" + "Accuracy: accuracy= 0.1390\n" ] } ], @@ -363,7 +363,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "100%|██████████| 2500/2500 [00:25<00:00, 96.29it/s]\n" + "100%|██████████| 2500/2500 [00:26<00:00, 96.07it/s]\n" ] } ], @@ -389,7 +389,7 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -415,7 +415,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Accuracy: accuracy= 0.7940\n" + "Accuracy: accuracy= 0.7930\n" ] } ], @@ -475,7 +475,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 24, "metadata": {}, "outputs": [], "source": [ @@ -485,14 +485,14 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Accuracy: accuracy= 0.1360\n" + "Accuracy: accuracy= 0.1590\n" ] } ], @@ -503,14 +503,14 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "100%|██████████| 5000/5000 [00:48<00:00, 102.92it/s]\n" + "100%|██████████| 5000/5000 [00:47<00:00, 104.21it/s]\n" ] } ], @@ -531,12 +531,12 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 27, "metadata": {}, "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -555,14 +555,14 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Accuracy: accuracy= 0.5040\n" + "Accuracy: accuracy= 0.6160\n" ] } ], @@ -572,7 +572,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 29, "metadata": {}, "outputs": [ { diff --git a/notebooks/mminici-renorm_trick_test-0.1.ipynb b/notebooks/mminici-renorm_trick_test-0.1.ipynb index 00e160a..138ed4f 100644 --- a/notebooks/mminici-renorm_trick_test-0.1.ipynb +++ b/notebooks/mminici-renorm_trick_test-0.1.ipynb @@ -159,7 +159,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Accuracy: accuracy= 0.0720\n" + "Accuracy: accuracy= 0.1460\n" ] } ], @@ -187,7 +187,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "100%|██████████| 1000/1000 [00:01<00:00, 612.32it/s]\n" + "100%|██████████| 1000/1000 [00:01<00:00, 557.19it/s]\n" ] } ], @@ -214,7 +214,7 @@ { "data": { "text/plain": [ - "[]" + "[]" ] }, "execution_count": 12, @@ -236,7 +236,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Accuracy: accuracy= 0.5060\n" + "Accuracy: accuracy= 0.4890\n" ] } ], @@ -345,7 +345,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Accuracy: accuracy= 0.1230\n" + "Accuracy: accuracy= 0.1390\n" ] } ], @@ -363,7 +363,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "100%|██████████| 2500/2500 [00:25<00:00, 96.29it/s]\n" + "100%|██████████| 2500/2500 [00:26<00:00, 96.07it/s]\n" ] } ], @@ -389,7 +389,7 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -415,7 +415,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Accuracy: accuracy= 0.7940\n" + "Accuracy: accuracy= 0.7930\n" ] } ], @@ -475,7 +475,7 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 24, "metadata": {}, "outputs": [], "source": [ @@ -485,14 +485,14 @@ }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Accuracy: accuracy= 0.1360\n" + "Accuracy: accuracy= 0.1590\n" ] } ], @@ -503,14 +503,14 @@ }, { "cell_type": "code", - "execution_count": 32, + "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "100%|██████████| 5000/5000 [00:48<00:00, 102.92it/s]\n" + "100%|██████████| 5000/5000 [00:47<00:00, 104.21it/s]\n" ] } ], @@ -531,12 +531,12 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 27, "metadata": {}, "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -555,14 +555,14 @@ }, { "cell_type": "code", - "execution_count": 35, + "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Accuracy: accuracy= 0.5040\n" + "Accuracy: accuracy= 0.6160\n" ] } ], @@ -572,7 +572,7 @@ }, { "cell_type": "code", - "execution_count": 36, + "execution_count": 29, "metadata": {}, "outputs": [ { diff --git a/pygcn/utils.py b/pygcn/utils.py index 87a0420..02db573 100644 --- a/pygcn/utils.py +++ b/pygcn/utils.py @@ -40,7 +40,7 @@ def load_data(path="../data/cora/", dataset="cora", symm_norm = False): else: # use the D^-1/2AD^-1/2 formula adj = adj + sp.eye(adj.shape[0]) # add self loop - D = np.diag(np.array(adj.sum(axis=0)).flatten()) # build degree matrix + D = np.diag(np.array(adj.sum(axis=1)).flatten()) # build degree matrix D_prime = matrix_frac_power(D,-0.5) D_prime = sp.coo_matrix(D_prime, shape=(adj.shape[0],adj.shape[0]),dtype=np.float32) # convert to sparse format adj = D_prime @ adj @ D_prime # compute the normalized symmetric version