diff --git a/Building_GCN.ipynb b/Building_GCN.ipynb deleted file mode 100644 index 795259e..0000000 --- a/Building_GCN.ipynb +++ /dev/null @@ -1,416 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "

Building Feed-Forward Graph Convolutional Networks (GCN)

\n", - "

Based on paper by Thomas Kipf and Max Welling (2017)

\n", - "

Implemented using NetworkX and Numpy

\n", - "\n", - "\n", - "**************************************************************************************************************" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "

Initializing the Graph G

" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Graph Nodes: [(0, {'name': 0}), (1, {'name': 1}), (2, {'name': 2}), (3, {'name': 3}), (4, {'name': 4}), (5, {'name': 5})]\n" - ] - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAb4AAAEuCAYAAADx63eqAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAAIABJREFUeJzt3XlYlOX+BvB7YNgXQSXQNJdIsAwQDDFTMbey1PRoLiCuaZo40+mcY+XpLHU6dSyTRXDBfUs86C/XNM2lNE0DwTQRl0xQUcCFdQZm5v39oXAgdhnmmeX+XBdX+c4w3lpz3TzPvO/3lUmSJIGIiMhCWIkOQEREZEgsPiIisigsPiIisigsPiIisigsPiIisigsPiIisigsPiIisigsPiIisigsPiIisigsPiIisigsPiIisigsPiIisigsPiIisigsPiIisihy0QGIjF1uoRpJyVlIz85HvkoDV3s5fL1cMSaoHVo524mOR0SNJOP9+IhqlpZ5D3GHL+FIRg4AQK3RVTxmL7eCBCDUxwOz+3nDv72boJRE1FgsPqIabDhxFR/vSYdKo0Vd7xCZDLCXW2P+UF+Eh3Q0WD4ienTc6iT6nQeldx4lZbp6nytJQEmZFh/vOQ8ALD8iE8AVH1ElaZn3MC7hBErKtBXH8k9tR+GZ/SjLvQZIOrToPR5ufcKqfa+DjTUSZ4TArx23PYmMGc/qJKok7vAlqDTaKsdKsy/Byt4Z1i6t6/xelUaL+MOXmjMeEekBi4/oodxCNY5k5FT7TK/1sHfgFfYpbD071/n9kgQcupCDvEJ1M6YkoqZi8RE9lJSc1eTXkAFISmn66xBR8+HJLUQPpWfnV7lk4VGoNDrsP/ULumivwcXFpeLL2dkZzs7OsLLiz5pEorH4iB7KV2n08joXrlzDP3f+FwUFBSgsLERBQQEKCgpQXFwMBweHaoVY+deNOe7k5MQiJXoELD6ih1zt9fN2GNi3NxbFvVXtuE6nQ1FRUbVCrPxVfvzmzZvIyMiodrzyV0lJCRwdHZtcoJWLVCaT6eXvgMiYJx6x+Ige8vVyhZ08u9p2Z0HaPqgzf0HprcsAgOKLJ6C5fxuOXULg2KVXlefay63g28alxte3srKqKBl9qFyktRVo+df169frLNGCggKoVKqKIm1KgZYfZ5FapronHmVj0YEM4ROPeB0f0UO5hWr0/s/BasWXu2sRis5+W+35NV3PZye3wg/zXhT+E+2j0Gq1NRZpfavT2o6rVCo4OTnpbWvX0dGRRWrkTGXiEYuPqJIZ63/C/vO36nzT1kYmA4Y87Yml4T30H8wEabXaKuVYW1E2tFzVanVFEepja9fBwYFFqkeNmXhUzsHGCvOHdjV4+bH4iCqpaXJLQ3FyS/PSaDQVRfioq9DKX6WlpXop0PLjllykNb1v8vbEQHX9F2jzcyGztoFt2y5w7z8Fth4dq3yviPcNi4/od0zpJ1d6dBqNRm8lWlBQAI1GU60Ym1Ks9vb2JlOkNe2U/Pbpq7Bt6wNbjw4ouZoG7f1bsHZphcdnJkAmt614noidEp7cQvQ75eXVoM8qIEHSlOKPQ55h6ZkYuVwOd3d3uLu76+X1ysrKaizFmo7dvn273q1fjUajlwIt/7Kzs2uWIq1t4pHX5CjYeXkDADT3buH60mnQFuShNPdaxXGg6sQjQ302zuIjqkF4SEf4tXND/OFLOHQhBzI8uDi9XPn9+Pr7eODeD1twdPV2vBG6VlheEs/GxkavRVpaWlqtHGsry9u3b9e7OtXpdHrd2i0v0tomHlUpN93Da2RlVrB2blntueUTj2b2fVIvf3f1YfER1cKvnRuWhvdAXqEaSSlZSL9ZgHxVGVztbeDbxgWjAx9cj1Q0sisCAwOxZcsWvP7666Jjk5mwtbVFy5Yt0bJl9aJ4FKWlpQ0+0Sg7O7velaskSQ+KcPAcyDr1rPX31ZWWIG93FADANfg1yGsoPpVGh/SbBXr5czYEP+Mj0oOffvoJr7zyCn766Se0b99edByiZqdWq1FQUIDI/57D8WuFNT5HW3wft7f8A6XZF+HsPwQtX5pT63brAN/HsHLSc80ZuQLnHRHpQY8ePaBQKBAREQGttvFnhBKZGjs7O7Ru3RqeLV1rfFxz/zayN/wFpdkX4dprDFq9HFnnZ4yu9jbNFbUaFh+RnsybNw9arRYLFy4UHYXIYHy9XGFrXf149vo/QXPnOqxdPSCVqXHnwHLcObAc6hsXqj23rolHzYGf8RHpibW1NdavX4/nnnsOAwcORGBgoOhIRM1Gp9Nh9+7d+HLxMqj9pkMmr7pi0xbeefDP/BwU/LSj4rjtY51h19anynMlAKMD2zV75nL8jI9IzzZt2oSPPvoIycnJcHR0FB2HSK/y8/OxZs0axMTEwN3dHQqFAke0XXDgQvVLGhpCxHV83Ook0rMJEyYgMDAQf/7zn0VHIdKby5cvQ6lUomPHjjh69CjWrl2LkydPIjw8HHNe7AJ7eQ37nQ1gL7fG7FDv+p+oRyw+omYQFxeH3bt3Y/fu3aKjED0ySZJw8OBBjBgxAj179oS9vT1SU1OxZcsW9O7du+JkFf/2bpg/1BcONo2rlAcTj3wNPuaPW51EzeS7777DuHHjcPr0aXh6eoqOQ9RgJSUl2LRpE6Kjo6HRaKBQKBAeHg4nJ6c6v493ZyAivP/++0hLS8OuXbtMZu4iWa4bN24gPj4eCQkJCAoKglKpxKBBgxr1/+6ZrHsNmng0O9Rb2EB3Fh9RMyotLUXv3r0xZcoUzJ49W3QcohqdPHkS0dHR2LNnD8LCwhAZGQkfH5/6v7EO9U08EonFR9TMMjIy0Lt3b3z33Xfo2rWr6DhEAB4M1d62bRuioqJw8+ZNREZGYtq0aXBzM//barH4iAxg+fLlWLp0KU6cOAFbW9v6v4GomeTl5SEhIQFxcXHo3LkzFAoFhg8fDrncci7r5lmdRAbwxhtv4IknnsAHH3wgOgpZqHPnzmHGjBnw9vZGeno6duzYgSNHjmDUqFEWVXoAJ7cQGYRMJkNCQgICAgLw0ksvoX///qIjkQXQ6XTYs2cPoqOjcfbsWcyaNQvp6ekWf5YxtzqJDGjv3r2YMWMG0tLS9HbfNqLfKygowJo1axAbGwsXFxcolUq8/vrrsLMTe1KJsWDxERmYQqFAdnY2Nm/ezEscSK+uXLmCxYsXY+3atejfvz+USmWVC83pAX7GR2Rgn376Kc6dO4f169eLjkJmQJIkHD58GCNHjkRwcDDkcjlSUlKQlJSEF154gaVXA674iAQ4c+YMBgwYgJMnT6JTp06i45AJUqlU+PLLLxEdHQ21Wo25c+ciIiKi3ukqxOIjEuaLL77A1q1bceTIEYs7q44e3c2bN7FkyRIsW7YMgYGBUCgUGDx4MKysuIHXUPybIhJEqVTC0dERn3zyiegoZAJ++uknhIeH4+mnn0Zubi6OHDmCr7/+Gi+99BJLr5G44iMS6Pr16wgMDMT27dsREhIiOg4ZGY1Gg23btiE6OhpZWVmYM2cOpk+fzjOCm4jFRyTY1q1bMW/ePJw+fRouLi6i45ARuHPnTsV0lQ4dOkCpVGLEiBHcEtcTFh+REZg2bRoAYOXKlYKTkEi//PILYmJikJiYiGHDhkGhUCAoKEh0LLPDjWEiIxAdHY0jR45g27ZtoqOQgZVPVxkyZAhefPFFeHl54fz581i3bh1Lr5lwxUdkJH788UcMHz4cKSkpePzxx0XHoWZWWFiItWvXIiYmBk5OTlAoFBg3bhynqxgAi4/IiHz44Yf4/vvvsW/fPp6pZ6auXr2KxYsXY/Xq1QgNDYVCoUCfPn14obkB8Z1FZETef/99FBcXIyoqSnQU0iNJkvDdd99h1KhRFduXycnJ2Lp1K/r27cvSMzCu+IiMzJUrV9CzZ08cOHAA/v7+ouNQE6jVamzevBlRUVEoLi7G3LlzMWnSJDg7O4uOZtFYfERGaN26dViwYAFOnToFBwcH0XGokbKzsyumq/j7+0OpVGLIkCHcvjYS/K9AZIQmTpyIZ555Bu+++67oKNQIycnJiIiIQNeuXXHr1i0cPHgQ+/btw8svv8zSMyJc8REZqbt378Lf3x8JCQkYMmSI6DhUC41Gg6+++grR0dH47bffKqartGzZUnQ0qgWLj8iIHTp0COHh4UhNTYWHh4foOFTJ3bt3sWLFCixevBjt2rWDUqnEyJEjOV3FBHDtTWTE+vfvj7CwMEyfPh38GdU4pKenY/bs2ejcuTPOnDmDrVu34tixYxgzZgxLz0Sw+IiM3EcffYRr164hISFBdBSLpdPpsHfvXrz88svo168fWrdujV9++QXr169Hjx49RMejRuJWJ5EJOH/+PPr27Ytjx46hS5cuouNYjKKiIqxbtw7R0dGwt7eHQqHA+PHjYW9vLzoaNQGLj8hExMfHY/Xq1fjhhx9gY2MjOo5Z++233yqmq/Tp0wdKpZIXmpsRbnUSmYhZs2bB09MT//jHP0RHMUuSJOHo0aMYPXo0AgMDodVqcfLkSfzf//0f+vXrx9IzI1zxEZmQW7duISAgAImJiejbt6/oOGZBrVYjMTER0dHRyM/Ph0KhwKRJk3hvRDPG4iMyMbt27cKcOXOQmpoKNzc30XFM1q1bt7B06VIsXboU3bp1g1Kp5IXmFoL/hYlMzKuvvoqhQ4firbfeEh3FJJ0+fRqTJ0+Gr68vbty4gQMHDmD//v145ZVXWHoWgv+ViUzQ559/jpSUFGzatEl0FJOg1Wqxbds29OvXD8OHD4evry8uXbqEZcuW4ZlnnhEdjwyMW51EJur06dMYMmQITp06hQ4dOoiOY5Tu3buHlStXIjY2Fm3btoVCocCoUaN4VqyF44qPyER1794df/rTnzBx4kRotVrRcYxKRkYG5syZg06dOiElJQVbtmzBDz/8gLFjx7L0iMVHZMreeecdWFtbY8GCBaKjCCdJEr755hsMHToUL7zwAtzc3HDu3Dls3LgRwcHBouOREeFWJ5GJy8zMRFBQEPbs2WOR47OKioqwfv16xMTEQC6XQ6FQYMKECbyPIdWKxUdkBhITE/G3v/0NKSkpcHJyEh3HIK5du4a4uDisWrUKzz//PJRKJUJDQ3mhOdWLW51EZmDs2LHo2bMn/vjHP4qO0qwkScKxY8fw+uuvIyAgAKWlpThx4gS2b9+O/v37s/SoQbjiIzIT+fn5CAgIwKJFizBixAjRcfSqtLQUW7ZsQXR0NO7evYu5c+di8uTJcHV1FR2NTBCLj8iMHDt2DH/4wx+QmpoKLy8v0XGa7Pbt21i2bBmWLFmCp59+GgqFAkOHDoW1tbXoaGTCuNVJZEZ69+6NGTNmYPLkydDpdKLjPLK0tDRMnToVPj4+uHbtGvbt24cDBw5g2LBhLD1qMhYfkZn54IMPcPfuXSxevFh0lEbRarX46quvEBoaildeeQXe3t64ePEiEhIS8Oyzz4qOR2aEW51EZujSpUvo1asXDh06hG7duomOU6f79+9j5cqVWLx4MR577DEoFAqMHj2aF5pTs+GKj8gMeXt749NPP0VYWBjUarXoODW6ePEiIiMj0alTJ5w6dQqbNm3CiRMnMH78eJYeNSsWH5GZmjp1Kry9vfH++++LjlJBkiTs378fr776Knr37g1XV1f8/PPP+PLLLxESEiI6HlkIbnUSmbG8vDz4+/tjzZo1GDhwoLAcxcXF2LBhA2JiYiCTyaBQKBAWFsbpKiQEi4/IzO3fvx9Tp05FamoqWrVqZdDfOysrC3FxcVixYgV69eoFhUKBF198kReak1Dc6iQyc4MGDcKYMWMwc+ZMGOLnXEmScPz4cYwbNw5+fn4oLi7G8ePHsWPHDgwYMIClR8JxxUdkAVQqFYKDg6FUKjF16lQAQG6hGknJWUjPzke+SgNXezl8vVwxJqgdWjnbNfr3KC0tRVJSEqKiopCXl4fIyEhMmTIFLVq00Pcfh6hJWHxEFuLs2bPo378/Vu84iB2X1DiSkQMAUGv+d6G7vdwKEoBQHw/M7ucN//Zu9b5uTk5OxXQVHx8fKBQKvPrqq7zQnIwWi4/Igkz992ocvOcGmdwWdb3zZTLAXm6N+UN9ER7SscbnnDlzBtHR0di2bRtGjRoFhUIBPz+/5glOpEdy0QGIyDA2nLiKH1RegLWuztIDAEkCSsq0+HjPeQCoKD+tVotdu3YhOjoaFy5cwOzZs5GRkQEPD49mTk+kP1zxEVmAtMx7GJdwAiVl2opjkqYUdw+uQlH695BKS2Dr+STcB0yHXVufKt/rYGONVWHP4sev/4vY2Fi0atUKSqUSo0ePhq2traH/KERNxuIjsgAz1v+E/edvVVnp5e1djMLUvbDx6ACb1h1QfP57yGzt8fibK2DtWOmEFEmHsl+T0UeWDoVCgZCQEJ6ZSSaNW51EZi638MGJLJVLT1t0D4VnDgAyK3iO+xjWTm7ItbJG0blDKEjeBbc+Yf97sswKTk8FI+7d9x7pbE8iY8Pr+IjMXFJyVrVjZbnXAJ0G1q4esHZ6cOamrZc3AKD09q/Vnm8lkyEppfrrEJkiFh+RmUvPzq9yyQIAaIvuAgCsbO0rjske/nv5Y5WpNDqk3yxoxpREhsPiIzJz+SpNtWPWTu4AAF2pquKY9PDfyx+r/jplzZCOyPBYfERmztW++kf5Nq3bA1ZyaPNzKlZ46psZAADbxzrV8jq8VRCZB57cQmTmfL1cYSfPrrLdae3kDudnB6AwbR9ufTkfNh4dUHz+KGS2DnAJerXaa9jLreDbxsWQsYmaDVd8RGZudFC7Go+7D5wB58BXoC26h+KME7B73AeeYz+seinDQxKA0YE1vw6RqeF1fEQWoKbr+BpKJgOGPO2JpeE99B+MSACu+IgswFuh3rCXP9rQaHu5NWaHeus5EZE4LD4iC+Df3g3zh/rCXt64t7yDjRXmD/WFX7v679JAZCpYfEQWIjykIzrcSYaVpEF9E8dksgczOucP7Vrr3RmITBXP6iSyEDt37sTFr1dh096jWHPyBg5dyIEMDy5OL1d+P77+Ph6YHerNlR6ZJZ7cQmQBcnJy4O/vj8TERPTp0wcAkFeoRlJKFtJvFiBfVQZXexv4tnHB6MBHuwM7kalg8RGZOUmSMHr0aHTu3BmfffaZ6DhEwnGrk8jMbdy4ERcuXMDGjRtFRyEyClzxEZmxzMxMBAUFYd++fejevbvoOERGgWd1EpkpnU6HqVOnQqFQsPSIKmHxEZmpJUuWoKCgAPPmzRMdhciocKuTyAxlZGTg+eefx7Fjx+Dj4yM6DpFR4YqPyMxoNBpERETgH//4B0uPqAYsPiIzs2DBAjg7O2P27NmioxAZJW51EpmR06dPY8iQIUhOTkb79u1FxyEySlzxEZkJlUqFiIgILFy4kKVHVAeu+IjMxF/+8hdcvnwZSUlJkNU3hZrIgnFyC5EZOHr0KNavX48zZ86w9Ijqwa1OIhNXUFCASZMmYenSpfDw8BAdh8jocauTyMTNnDkTZWVlWLVqlegoRCaBW51EJmzPnj3Yt28fzpw5IzoKkcngio/IROXl5cHPzw8bNmxA//79RcchMhksPiITNW7cOLRp0waLFi0SHYXIpHCrk8gEbd68GWlpaVi9erXoKEQmhys+IhNz48YNdO/eHbt370aPHj1ExyEyObycgciESJKEadOmYdasWSw9okfE4iMyIcuXL0dOTg7mz58vOgqRyeJWJ5GJuHz5MkJCQvDdd9+ha9euouMQmSyu+IhMgFarxaRJkzB//nyWHlETsfiITMDChQthY2ODuXPnio5CZPK41Ulk5M6cOYMBAwbg1KlT6Nixo+g4RCaPKz4iI1ZaWoqIiAgsWLCApUekJ1zxERmx+fPn4+zZs/jqq694uyEiPeHkFiIjdfz4caxcuRJpaWksPSI94lYnkREqKipCREQE4uLi4OnpKToOkVnhVieREXrrrbdQUFCAdevWiY5CZHa41UlkZL755hvs3LmT99gjaiYsPiIjcvfuXUybNg2rV6+Gm5ub6DhEZolbnURGJDw8HO7u7oiNjRUdhchsccVHZCSSkpJw6tQpnD59WnQUIrPGFR+REcjOzkZAQAC2b9+Onj17io5DZNZYfESCSZKE4cOHw9/fH//6179ExyEye9zqJBJs1apVyMrKwtatW0VHIbIIXPERCfTrr78iODgYhw4dQrdu3UTHIbIInNxCJIhOp8PkyZMxb948lh6RAbH4iASJioqCJEl4++23RUchsijc6iQS4Ny5cwgNDcWPP/6Izp07i45DZFG44iMysLKyMkRERODf//43S49IABYfkYH961//gpeXF6ZPny46CpFF4lYnkQGdPHkSw4YNQ2pqKtq0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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import networkx as nx\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "from scipy.linalg import fractional_matrix_power\n", - "\n", - "import warnings\n", - "warnings.filterwarnings(\"ignore\", category=UserWarning)\n", - "\n", - "\n", - "#Initialize the graph\n", - "G = nx.Graph()\n", - "\n", - "#Create nodes\n", - "#In this example, the graph will consist of 6 nodes.\n", - "#Each node is assigned node feature which corresponds to the node name\n", - "for i in range(6):\n", - " G.add_node(i, name=i)\n", - "\n", - "\n", - "#Define the edges and the edges to the graph\n", - "edges = [(0,1),(0,2),(1,2),(0,3),(3,4),(3,5),(4,5)]\n", - "G.add_edges_from(edges)\n", - "\n", - "#Inspect the node features\n", - "print('Graph Nodes: ', G.nodes.data())\n", - "\n", - "#Plot the graph\n", - "nx.draw(G, with_labels=True, font_weight='bold')\n", - "plt.show()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - "

Inserting Adjacency Matrix (A) to Forward Pass Equation

" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Shape of A: (6, 6)\n", - "\n", - "Shape of X: (6, 1)\n", - "\n", - "Adjacency Matrix (A): [[0. 1. 1. 1. 0. 0.]\n", - " [1. 0. 1. 0. 0. 0.]\n", - " [1. 1. 0. 0. 0. 0.]\n", - " [1. 0. 0. 0. 1. 1.]\n", - " [0. 0. 0. 1. 0. 1.]\n", - " [0. 0. 0. 1. 1. 0.]]\n", - "\n", - "Node Features Matrix (X): [[0]\n", - " [1]\n", - " [2]\n", - " [3]\n", - " [4]\n", - " [5]]\n" - ] - } - ], - "source": [ - "#Get the Adjacency Matrix (A) and Node Features Matrix (X) as numpy array\n", - "A = np.array(nx.attr_matrix(G, node_attr='name')[0])\n", - "X = np.array(nx.attr_matrix(G, node_attr='name')[1])\n", - "X = np.expand_dims(X,axis=1)\n", - "\n", - "print('Shape of A: ', A.shape)\n", - "print('\\nShape of X: ', X.shape)\n", - "print('\\nAdjacency Matrix (A): ', A)\n", - "print('\\nNode Features Matrix (X): ', X)" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Dot product of A and X (AX):\n", - " [[6.]\n", - " [2.]\n", - " [1.]\n", - " [9.]\n", - " [8.]\n", - " [7.]]\n" - ] - } - ], - "source": [ - "#Dot product Adjacency Matrix (A) and Node Features (X)\n", - "AX = np.dot(A,X)\n", - "print(\"Dot product of A and X (AX):\\n\", AX)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - "

Adding Self-Loops and Normalizing A

" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Edges of G with self-loops:\n", - " [(0, 1), (0, 2), (0, 3), (0, 0), (1, 2), (1, 1), (2, 2), (3, 4), (3, 5), (3, 3), (4, 5), (4, 4), (5, 5)]\n", - "Adjacency Matrix of added self-loops G (A_hat):\n", - " [[1. 1. 1. 1. 0. 0.]\n", - " [1. 1. 1. 0. 0. 0.]\n", - " [1. 1. 1. 0. 0. 0.]\n", - " [1. 0. 0. 1. 1. 1.]\n", - " [0. 0. 0. 1. 1. 1.]\n", - " [0. 0. 0. 1. 1. 1.]]\n", - "AX:\n", - " [[ 6.]\n", - " [ 3.]\n", - " [ 3.]\n", - " [12.]\n", - " [12.]\n", - " [12.]]\n" - ] - } - ], - "source": [ - "#Add Self Loops\n", - "G_self_loops = G.copy()\n", - "\n", - "self_loops = []\n", - "num_of_nodes = len(list(G.nodes))\n", - "for i in range(num_of_nodes):\n", - " self_loops.append((i,i))\n", - "\n", - "G_self_loops.add_edges_from(self_loops)\n", - "\n", - "#Check the edges of G_self_loops after adding the self loops\n", - "print('Edges of G with self-loops:\\n', G_self_loops.edges)\n", - "\n", - "#Get the Adjacency Matrix (A) and Node Features Matrix (X) of added self-lopps graph\n", - "A_hat = np.array(nx.attr_matrix(G_self_loops, node_attr='name')[0])\n", - "print('Adjacency Matrix of added self-loops G (A_hat):\\n', A_hat)\n", - "\n", - "#Calculate the dot product of A_hat and X (AX)\n", - "AX = np.dot(A_hat, X)\n", - "print('AX:\\n', AX)" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Degree Matrix of added self-loops G (D): [(0, 5), (1, 4), (2, 4), (3, 5), (4, 4), (5, 4)]\n", - "Degree Matrix of added self-loops G as numpy array (D): [[5 0 0 0 0 0]\n", - " [0 4 0 0 0 0]\n", - " [0 0 4 0 0 0]\n", - " [0 0 0 5 0 0]\n", - " [0 0 0 0 4 0]\n", - " [0 0 0 0 0 4]]\n", - "Inverse of D:\n", - " [[0.2 0. 0. 0. 0. 0. ]\n", - " [0. 0.25 0. 0. 0. 0. ]\n", - " [0. 0. 0.25 0. 0. 0. ]\n", - " [0. 0. 0. 0.2 0. 0. ]\n", - " [0. 0. 0. 0. 0.25 0. ]\n", - " [0. 0. 0. 0. 0. 0.25]]\n", - "DAX:\n", - " [[1.2 ]\n", - " [0.75]\n", - " [0.75]\n", - " [2.4 ]\n", - " [3. ]\n", - " [3. ]]\n" - ] - } - ], - "source": [ - "#Get the Degree Matrix of the added self-loops graph\n", - "Deg_Mat = G_self_loops.degree()\n", - "print('Degree Matrix of added self-loops G (D): ', Deg_Mat)\n", - "\n", - "#Convert the Degree Matrix to a N x N matrix where N is the number of nodes\n", - "D = np.diag([deg for (n,deg) in list(Deg_Mat)])\n", - "print('Degree Matrix of added self-loops G as numpy array (D): ', D)\n", - "\n", - "#Find the inverse of Degree Matrix (D)\n", - "D_inv = np.linalg.inv(D)\n", - "print('Inverse of D:\\n', D_inv)\n", - "\n", - "#Dot product of D and AX for normalization\n", - "DAX = np.dot(D_inv,AX)\n", - "print('DAX:\\n', DAX)" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "DADX:\n", - " [[1.27082039]\n", - " [0.75 ]\n", - " [0.75 ]\n", - " [2.61246118]\n", - " [2.92082039]\n", - " [2.92082039]]\n" - ] - } - ], - "source": [ - "#Symmetrically-normalization\n", - "D_half_norm = fractional_matrix_power(D, -0.5)\n", - "DADX = D_half_norm.dot(A_hat).dot(D_half_norm).dot(X)\n", - "print('DADX:\\n', DADX)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - "

Adding Weights and Activation Function

" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Features Representation from GCN output:\n", - " [[0.00027758 0. ]\n", - " [0.00017298 0. ]\n", - " [0.00017298 0. ]\n", - " [0.00053017 0. ]\n", - " [0.00054097 0. ]\n", - " [0.00054097 0. ]]\n" - ] - } - ], - "source": [ - "#Initialize the weights\n", - "np.random.seed(77777)\n", - "n_h = 4 #number of neurons in the hidden layer\n", - "n_y = 2 #number of neurons in the output layer\n", - "W0 = np.random.randn(X.shape[1],n_h) * 0.01\n", - "W1 = np.random.randn(n_h,n_y) * 0.01\n", - "\n", - "#Implement ReLu as activation function\n", - "def relu(x):\n", - " return np.maximum(0,x)\n", - "\n", - "#Build GCN layer\n", - "#In this function, we implement numpy to simplify\n", - "def gcn(A,H,W):\n", - " I = np.identity(A.shape[0]) #create Identity Matrix of A\n", - " A_hat = A + I #add self-loop to A\n", - " D = np.diag(np.sum(A_hat, axis=0)) #create Degree Matrix of A\n", - " D_half_norm = fractional_matrix_power(D, -0.5) #calculate D to the power of -0.5\n", - " eq = D_half_norm.dot(A_hat).dot(D_half_norm).dot(H).dot(W)\n", - " return relu(eq)\n", - "\n", - "\n", - "#Do forward propagation\n", - "H1 = gcn(A,X,W0)\n", - "H2 = gcn(A,H1,W1)\n", - "print('Features Representation from GCN output:\\n', H2)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - "

Plotting the Features Representations

" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "def plot_features(H2):\n", - " #Plot the features representation\n", - " x = H2[:,0]\n", - " y = H2[:,1]\n", - "\n", - " size = 1000\n", - "\n", - " plt.scatter(x,y,size)\n", - " plt.xlim([np.min(x)*0.9, np.max(x)*1.1])\n", - " plt.ylim([-1, 1])\n", - " plt.xlabel('Feature Representation Dimension 0')\n", - " plt.ylabel('Feature Representation Dimension 1')\n", - " plt.title('Feature Representation')\n", - "\n", - " for i,row in enumerate(H2):\n", - " str = \"{}\".format(i)\n", - " plt.annotate(str, (row[0],row[1]),fontsize=18, fontweight='bold')\n", - "\n", - " plt.show()\n", - "\n", - "\n", - "plot_features(H2)" - ] - } - ], - "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.6.9" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -}