{ "cells": [ { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import networkx as nx \n", "from matplotlib import pyplot as plt\n", "import numpy as np\n", "import networkx as nx\n", "import torch\n", "\n", "from gsnn.models.GSNN import GSNN\n", "from gsnn.simulate.nx2pyg import nx2pyg\n", "from gsnn.simulate.simulate import simulate, simulate_sde\n", "\n", "from gsnn.interpret.extract_entity_function import extract_entity_function\n", "\n", "%load_ext autoreload\n", "%autoreload 2\n", "\n", "# for reproducibility \n", "torch.manual_seed(0)\n", "np.random.seed(0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Simulating structured data \n", "\n", "To demonstrate how the GSNN operates, and some simple capabilities, we have written a simple bayesian network simulator. We will start by defining a simple toy graph with three inputs and three outputs. " ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAoAAAAH2CAYAAADgXj1iAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/TGe4hAAAACXBIWXMAAA9hAAAPYQGoP6dpAACJZ0lEQVR4nOzdd1wT9/8H8NeFDSKIIu6997Zqq2xlOIDEvfes1Wrds9ZdtdZRra27jgRkKC6GVm3ds+69BRyAsgzkfn/4JT9RVFDIEfJ6Ph4+HnLc5d6X5J28+NwSRFEUQUREREQGQyZ1AURERESkWwyARERERAaGAZCIiIjIwDAAEhERERkYBkAiIiIiA8MASERERGRgGACJiIiIDAwDIBEREZGBYQAkIiIiMjAMgHnAunXrIAiC9p+5uTmKFSsGJycnzJkzB9HR0VKXKLnz58+jX79+qFixIiwsLGBhYYHKlStj0KBBOHnypKS1lStXDt7e3jn6mPfv34ePjw8qVKgAKysr2NjYoH79+li2bBlSU1M/uXz6e0rq5+Zts2fPRmBgYK6vZ9KkSahfvz7s7Oxgbm6OChUqYODAgbh7926WH+PZs2eYMGECatSoAUtLSxQsWBBfffUVli9fDrVa/dm1hYaGYvr06Z+9fHatWLEC69aty/X19O7dO8NnWPq/atWqZWn5cuXKZbq8IAh49epVLlf/YY8ePcL06dNx9uzZ9343ffp0CIKg+6Lw/8/X4MGD3/vdgQMHIAgCVCpVjq0v/fPkzp07OfaYJD1jqQug/7d27VpUq1YNarUa0dHROHz4MObNm4eFCxdi27ZtcHV1lbpESaxatQrDhw9H1apVMXLkSNSsWROCIODy5cvYsmULGjdujBs3bqBixYpSl5pjEhISULBgQUyZMgVlypTB69evERoaihEjRuDs2bNYs2aN1CVm2+zZsyGXy9GhQ4dcXU9sbCy6dOmC6tWrw9raGpcuXcKsWbMQHByMixcvonDhwh9d/sqVK3B3d8erV6/w/fffo3nz5khKSsLOnTsxcuRIKJVKhIaGwtLSMtu1hYaGYvny5ToLgStWrECRIkXQu3fvXF+XhYUFIiIi3puWVS1atMDChQvfm/45z3NOefToEWbMmIFy5cqhXr16GX7Xv39/tGnTRprC/uePP/7AqFGjULVqVUnrIP3EAJiH1KpVC40aNdL+7Ofnh1GjRuHrr7+Gr68vrl+/DgcHBwkr1L0jR45g6NCh8PLygkqlgqmpqfZ3zs7OGDZsGJRK5Se/aBITEyX9IsmuatWqYf369RmmeXh4IDo6GuvXr8fy5cthZmYmUXV52/LlyzP87OjoiPLly8PT0xNBQUHo27fvB5dNS0uDn58f4uPjcfz4cVSpUkX7O09PT7Rq1QqdO3fG6NGj8dtvv+XaNugjmUyGr7766rOXt7W1/aLlda1UqVIoVaqUZOtv1qwZLl26hIkTJ8Lf31+yOkh/cRdwHlemTBn8/PPPePnyJVatWqWd7ujoCEdHx/fm7927N8qVK6f9+c6dOxAEAQsWLMC8efNQrlw5WFhYwNHREdeuXYNarcb48eNRokQJ2NjYwMfH571dzum7OHfu3In69evDwsIC1atXx86dOwG82T1QvXp1WFlZoUmTJhl2O27cuBGCIODff/99r9aZM2fCxMQEjx49+uD2z549G0ZGRli1alWG8Pc2hUKBEiVKZHgOChQogAsXLsDd3R3W1tZwcXEBAOzfvx/t27dHqVKlYG5ujkqVKmHQoEF4+vRphsdM371z5swZ+Pr6omDBgrCxsUH37t0RExOTaR179uxBgwYNYGFhgWrVquHPP//84HZ9Lnt7e8hkMhgZGWV72fTn5caNG/D09ESBAgVQunRpfP/990hJSdHOl/6emT9/Pn766SeUKVMG5ubmaNSoEcLDw997zLffb+ne3T0mCAISEhKwfv167a699PdvYmIixowZg/Lly8Pc3Bx2dnZo1KgRtmzZku1t/BB7e3sAgLHxx//m3bFjBy5duoTx48dnCH/pOnXqBHd3d/zxxx948uQJgP/f5XbgwIEM86Y/j+m7YHv37q0Np2/v4kzfrSYIAoYPH45Vq1ahSpUqMDMzQ40aNbB169YMj/uhXY/v7qYrV64cLl68iIMHD2rXlf5aaTQazJo1C1WrVoWFhQVsbW1Rp04d/PLLLx99fqSS1W0G/v/zKiv9+PDhQwwcOBClS5eGqakpSpQoAblcjqioKBw4cACNGzcGAPTp00f7HKaP3mZWk0ajwfz581GtWjWYmZmhaNGi6NmzJx48eJBhPkdHR9SqVQsnTpzAN998A0tLS1SoUAFz586FRqPJ0nNiZ2eH8ePHIyAgAEePHv3k/IcPH4aLiwusra1haWmJ5s2bY9euXe/Nd/ToUbRo0QLm5uYoUaIEJkyY8MHDHrZt24ZmzZrBysoKBQoUQOvWrXHmzJkM89y6dQudO3dGiRIlYGZmBgcHB7i4uGS6W510iwFQD3h6esLIyAh///33Zz/G8uXLceTIESxfvhxr1qzBlStX0LZtW/Tr1w8xMTH4888/MX/+fISFhaF///7vLX/u3DlMmDAB48aNQ0BAAGxsbODr64tp06ZhzZo1mD17NjZv3oy4uDh4e3sjKSkJwJsvzGLFir03KpOamopVq1bBx8cnQ3h7W1paGiIjI9GoUSMUL148W9v7+vVrtGvXDs7OzggKCsKMGTMAADdv3kSzZs2wcuVK7Nu3D1OnTsWxY8fw9ddfZ/oh5+Pjg0qVKkGlUmH69OkIDAxE69at35v33Llz+P777zFq1CgEBQWhTp066Nev33uvWbly5TINTB8iiiJSU1Px4sULbNu2DevWrcP333//ySDzIWq1Gu3atYOLi4t2NGzx4sWYN2/ee/MuW7YMe/bswZIlS7Bp0ybIZDJ4eHhkGuY/5d9//4WFhQU8PT3x77//4t9//8WKFSsAAKNHj8bKlSvx7bffYs+ePdi4cSMUCgWePXv2WduYLjU1FUlJSThz5gy+++47VKlSBb6+vh9dZv/+/QDw0d3UHTp0QGpq6nuB71OmTJkCuVwOANrn4N9//83w3g4ODsbSpUsxc+ZMqFQqlC1bFl26dPms47l27NiBChUqoH79+tp17dixAwAwf/58TJ8+HV26dMGuXbuwbds29OvXD7GxsdleT7qkpCQUK1YMRkZGKFWqFIYPH47nz59nefn09/rb/7Iaht6VlX58+PAhGjdujB07dmD06NHYvXs3lixZAhsbG7x48QINGjTA2rVrAQCTJ0/WPoeZfT6mGzJkCMaNGwc3NzcEBwfjxx9/xJ49e9C8efP3/sh88uQJunXrhu7duyM4OBgeHh6YMGECNm3alOXtHDlyJEqWLIkffvjho/MdPHgQzs7OiIuLwx9//IEtW7bA2toabdu2xbZt27TzXbp0CS4uLoiNjcW6devw22+/4cyZM5g1a9Z7jzl79mx06dIFNWrUwPbt27Fx40a8fPkS33zzDS5duqSdz9PTE6dOncL8+fOxf/9+rFy5EvXr1/+i9xrlEJEkt3btWhGAeOLEiQ/O4+DgIFavXl37c6tWrcRWrVq9N1+vXr3EsmXLan++ffu2CECsW7eumJaWpp2+ZMkSEYDYrl27DMt/9913IgAxLi5OO61s2bKihYWF+ODBA+20s2fPigDE4sWLiwkJCdrpgYGBIgAxODhYO23atGmiqampGBUVpZ22bds2EYB48ODBD27zkydPRABi586d3/tdamqqqFartf80Gk2G5wCA+Oeff37wsUVRFDUajahWq8W7d++KAMSgoKAMNQMQR40alWGZzZs3iwDETZs2ZXh+zM3Nxbt372qnJSUliXZ2duKgQYMyLF+xYkWxYsWKH63rbXPmzBEBiABEQRDESZMmZWm5zN5T6c/L9u3bM8zr6ekpVq1aVftz+numRIkSYlJSknZ6fHy8aGdnJ7q6umZ4zLffb+nSn7+3WVlZib169Xpv3lq1aokdOnTI0nZl1ePHj7XPGwCxadOm4sOHDz+5XJs2bUQAYnJy8gfn2b17twhAnDdvniiKohgZGSkCECMjIzPMl/48rl27Vjtt2LBh7z0v6QCIFhYW4pMnT7TTUlNTxWrVqomVKlXSTsvsuRXF/3/Nb9++rZ1Ws2bNTD8nvL29xXr16n1wG7Nr0aJF4qJFi8R9+/aJ+/btEydNmiRaWlqK1apVE1++fPnJ5cuWLZvh9Ur/l/5+z842Z7Uf+/btK5qYmIiXLl36YF0nTpx47zVM925Nly9fFgGIQ4cOzTDfsWPHRADixIkTtdNatWolAhCPHTuWYd4aNWqIrVu3/mA9b2+jl5eXKIqi+Pvvv4sAxJCQEFEU///9qFQqtfN/9dVXYtGiRTO8FqmpqWKtWrXEUqVKaT8/O3Xq9MH34NvP871790RjY2NxxIgRGep6+fKlWKxYMbFjx46iKIri06dPRQDikiVLPrlNpHscAdQToih+0fKenp6Qyf7/5a5evToAwMvLK8N86dPv3buXYXq9evVQsmTJ9+ZzdHTMcGxd+vS3z7gcMmQIAOD333/XTlu2bBlq166Nli1bftb2NGzYECYmJtp/P//883vz+Pn5vTctOjoagwcPRunSpWFsbAwTExOULVsWAHD58uX35u/WrVuGnzt27AhjY2NERkZmmF6vXj2UKVNG+7O5uTmqVKny3pmnN27cwI0bN7K8nb1798aJEyewd+9e/PDDD1iwYAFGjBiR5eXfJQgC2rZtm2FanTp1Mj1D1tfXF+bm5tqf00cM/v77b6SlpX12De9q0qQJdu/ejfHjx+PAgQPa0eMvUaRIEZw4cQKHDx/G77//jufPn8PJyQmPHz/+4sdO78XcOAPUxcUlw3G+RkZG6NSpE27cuPHebsQv0aRJE5w7dw5Dhw7F3r17ER8f/0WPN2rUKIwaNQpubm5wc3PDrFmzsGHDBly5ciVD33/M119/jRMnTmT4N3To0M+qJyv9uHv3bjg5OWk/s75U+mfCuyfcNGnSBNWrV3/v8IlixYqhSZMmGaZ9qBc/pk+fPqhRowbGjx+f6YhpQkICjh07BrlcjgIFCminGxkZoUePHnjw4AGuXr2q3YYPvQfftnfvXqSmpqJnz54ZRmzNzc3RqlUr7ei4nZ0dKlasiAULFmDRokU4c+bMZ4/qUs5jANQDCQkJePbs2Qd3lWaFnZ1dhp/Tj6f70PTk5OQcW97BwQGdOnXCqlWrkJaWhvPnz+PQoUMYPnz4R2suUqQILCwsMv1A/Ouvv3DixAkEBwdnumz6pTveptFo4O7ujoCAAPzwww8IDw/H8ePHtcfPZBY8ihUrluFnY2NjFC5c+L3dk5mdWWpmZvbFYaZYsWJo1KgR3N3dMXfuXMycORPLli177zibrLK0tMwQ6tLrfPf1Tl93ZtNev36do5fmWLp0KcaNG4fAwEA4OTnBzs4OHTp0wPXr1z/7MY2NjdGoUSO0aNEC/fv3R0REBG7duoW5c+d+dLn00HD79u0PzpN+vFnp0qU/u74P+dBzDuCLd4m/bcKECVi4cCGOHj0KDw8PFC5cGC4uLjl62SAfHx9YWVll6fg0ALCxsUGjRo0y/Pvcz7ys9GNMTEyOnsSR/vpkdrhKiRIlcu0zw8jICLNnz8bFixffO3EMAF68eAFRFD9Y19u1P3v27KPvwXRRUVEAgMaNG2f4Q9zExATbtm3T7u4WBAHh4eFo3bo15s+fjwYNGsDe3h7ffvstXr58ma3tpJzHAKgHdu3ahbS0tAwnfZibm2c4cD/du8eZ5BUjR47E/fv3ERQUhGXLlsHW1va90bV3GRkZwdnZGSdPnnxv5KZGjRpo1KgRateunemymY3O/Pfffzh37px2FM3R0RGNGzf+6GVB0g/0T5eamopnz5598lIiuSV9xODatWu5vq53tz19mqmpqXYkISfeh1ZWVpgxYwauXLmCJ0+eYOXKlTh69Oh7I5VfolSpUihRosQnnzc3NzcA+Oj1CgMDA2FsbKztx/RA/e7z8Dm9+KHnHPj/wJAT6zM2Nsbo0aNx+vRpPH/+HFu2bMH9+/fRunVrJCYmZrvuDxFFMcOeh8+Vk89xOnt7+xwdVU1/fTIbZX706BGKFCmSY+t6V/v27dGiRQtMmzbtvT/mChUqBJlM9sG6AGhrK1y48Effg+nS51epVO+N2p44cQLHjh3Tzlu2bFntSVNXr17FqFGjsGLFCowdO/bLNpq+GANgHnfv3j2MGTMGNjY2GDRokHZ6uXLlcO3atQwfiM+ePcM///wjRZmf1LBhQzRv3hzz5s3D5s2b0bt3b1hZWX1yuQkTJiAtLQ2DBw/+ogvwAv8fCt+9fMrbZ1e/a/PmzRl+3r59O1JTUzM9A1sX0nczVapUKdfXFRAQkOHL5OXLlwgJCcE333yjPQu5XLlyiI6O1o4IAG9OwNm7d+97j5eV0Q0HBwf07t0bXbp0wdWrV3MsjKTvQv3U8+bj44MaNWpg7ty5mYbFbdu2Yd++fejfv792VCT9pJ7z589nmDez0en0996Hnofw8PAMz2VaWhq2bduGihUrakerPrS+kJCQTNf3qefc1tYWcrkcw4YNw/Pnz3PsYr8qlQqJiYk5cmmX7GxzVnl4eCAyMlK7+zMzn3q93ubs7AwA753EceLECVy+fFl7JYLcMm/ePNy/fx9Lly7NMN3KygpNmzZFQEBAhu3QaDTYtGkTSpUqpT3j3cnJ6YPvwbe1bt0axsbGuHnz5nujtun/MlOlShVMnjwZtWvXxunTp3Nq0+kz8TqAech///2nPZYiOjoahw4dwtq1a2FkZIQdO3ZoL2UBAD169MCqVavQvXt3DBgwAM+ePcP8+fPf2+2Zl4wcORKdOnWCIAhZPranRYsWWL58OUaMGIEGDRpg4MCBqFmzpvYv2vTrX2Vlu6tVq4aKFSti/PjxEEURdnZ2CAkJ0Z75mZmAgAAYGxvDzc0NFy9exJQpU1C3bl107Ngxaxv9jvQA8qnjAKdNm4aoqCi0bNkSJUuWRGxsLPbs2YPff/8dCoUCDRs2/Kz1Z4eRkRHc3NwwevRoaDQazJs3D/Hx8dozqoE3Z3lPnToVnTt3xtixY5GcnIylS5dmeoxg7dq1ceDAAYSEhKB48eKwtrZG1apV0bRpU3h7e6NOnTooVKgQLl++jI0bN6JZs2ba40vv3LmD8uXLo1evXh+9s8X58+cxatQoyOVyVKhQATKZDBcuXMDixYtRuHBhjBkz5pPb7O/vDzc3NzRr1gzff/89mjVrhpSUFISEhGD16tVo1apVhmNOixUrBldXV8yZMweFChVC2bJlER4ejoCAgEyfA+DNl7WHhweMjIxQp04d7aETRYoUgbOzM6ZMmQIrKyusWLECV65cyXApGE9PT9jZ2aFfv36YOXMmjI2NsW7dOty/fz/T9W3duhXbtm1DhQoVYG5ujtq1a6Nt27ba647a29vj7t27WLJkCcqWLYvKlStrlxcEIcMxXZm5e/cuunbtis6dO6NSpUoQBAEHDx7EkiVLULNmzY+eNZtV2dnmrJo5cyZ2796Nli1bYuLEiahdu7a2z0aPHq39vLCwsMDmzZtRvXp1FChQACVKlMh013TVqlUxcOBA/Prrr9oz5u/cuYMpU6agdOnSGDVq1Jc8BZ/UokULtG/fHkFBQe/9bs6cOXBzc4OTkxPGjBkDU1NTrFixAv/99x+2bNmi/eN48uTJCA4OhrOzM6ZOnQpLS0ssX74cCQkJGR6vXLlymDlzJiZNmoRbt26hTZs2KFSoEKKionD8+HHtqP758+cxfPhwKBQKVK5cGaampoiIiMD58+cxfvz4XH0+KAskPQWFRFH8/zPZ0v+ZmpqKRYsWFVu1aiXOnj1bjI6OznS59evXi9WrVxfNzc3FGjVqiNu2bfvgWcALFizIsGxmZ4q9XcvbZ4++fcbZ2wCIw4YNyzDtQ+sTRVFMSUkRzczMxDZt2nzyOXnX2bNnxT59+ojly5cXzczMRHNzc7FSpUpiz549xfDw8Azz9urVS7Syssr0cS5duiS6ubmJ1tbWYqFChUSFQiHeu3dPBCBOmzZNO1/6GX6nTp0S27ZtKxYoUEC0trYWu3TpkuFsZlH88POT2ZnaZcuWzfSs2XcFBweLrq6uooODg2hsbCwWKFBAbNKkibh06VJRrVZ/cvkPnQWc2fPy7tmM6a/hvHnzxBkzZoilSpUSTU1Nxfr164t79+59b/nQ0FCxXr16ooWFhVihQgVx2bJlmZ61efbsWbFFixaipaWlCED73IwfP15s1KiRWKhQIdHMzEysUKGCOGrUKPHp06faZS9cuCACEMePH//R7X7y5InYvXt3sWLFiqKlpaVoamoqVqhQQRw8eLB47969Tz5v6Z4+fSqOHz9erFatmmhubq59/pctWya+fv36vfkfP34syuVy0c7OTrSxsRG7d+8unjx58r0zSFNSUsT+/fuL9vb2oiAIGc6sTO+nFStWiBUrVhRNTEzEatWqiZs3b35vfcePHxebN28uWllZiSVLlhSnTZsmrlmz5r0zYu/cuSO6u7uL1tbWIgDte+/nn38WmzdvLhYpUkQ0NTUVy5QpI/br10+8c+eOdtmXL19+8Cz8tz1//lz08fERy5UrJ1pYWIimpqZi5cqVxR9++EGMjY3N0vP9oR76nG3OTj/ev39f7Nu3r1isWDHRxMRELFGihNixY8cMPb5lyxaxWrVqoomJSYbPicze42lpaeK8efPEKlWqiCYmJmKRIkXE7t27i/fv33+vlpo1a75X44fOqn/Xh7bx0qVLopGRUaaf7YcOHRKdnZ1FKysr0cLCQvzqq6+0Zw6/7ciRI+JXX30lmpmZicWKFRPHjh0rrl69+r3nWRTfXPXByclJLFiwoGhmZiaWLVtWlMvlYlhYmCiKohgVFSX27t1brFatmmhlZSUWKFBArFOnjrh48WIxNTX1k9tJuUsQxS88vZQoi0JCQtCuXTvs2rULnp6eUpfzUdOnT8eMGTMQExOTq8fu5EXpo20LFiz45IiZrqxYsQI//PADbt68mW/vhiMIAoYNG4Zly5ZJXQqAN7et8/b2xrlz5z54rC0R6S/uAqZcd+nSJdy9exfff/896tWrBw8PD6lLIj0TGRmJb7/9Nt+Gv7woMjISnTt3ZvgjyqcYACnXDR06FEeOHEGDBg20twIjyg6lUil1CQZnwYIFUpdARLmIu4CJiIiIDAwvA0NERERkYBgAiYiIiAwMAyARERGRgcnSSSAajQaPHj2CtbU1D+AnIiIiyoNEUcTLly9RokSJT96GMUsB8NGjR7ly43MiIiIiyln379/X3j7yQ7IUAK2trbUPmJdvNUZERERkqOLj41G6dGltbvuYLAXA9N2+BQsWZAAkIiIiysOycrgeTwIhIiIiMjAMgEREREQGhgGQiIiIyMAwABIREREZGAZAIiIiIgPDAEhERERkYBgAiYiIiAwMAyARERGRgWEAJCIiIjIwDIBEREREBoYBkIiIiMjAMAASERERGRgGQCIiIiIDwwBIREREZGAYAImIiIgMDAMgERERkYFhACQiIiIyMAyARERERAaGAZCIiIjIwDAAEhERERkYBkAiIiIiA2MsdQG6pBFFxKWkIjZZjdhkNZLT0pCmEWEkE2BuZARbcxPYmpvAxswYMkGQulwiykHsfyLDxf5/n0EEwER1Km7FJuJ2bCLUGhEAIAAQ35pHACDGvfm/iUxAeVtLVLC1hKWJQTxFRPkW+5/IcLH/P0wQRVH81Ezx8fGwsbFBXFwcChYsqIu6coQ6TYMLMfG4E5f03gv+Kenzl7OxQG37gjAx4t5yIn3C/icyXIba/9nJa/k23kYlpODk41ikpGkAZO/Ff3v+O3FJePIqBQ2L28LByixHaySi3MH+JzJc7P+s0Z9Ymw03XyTgyIPn2hf/SyWnaXDkwXPcfJGQI49HRLmH/U9kuNj/WZfvAuDNFwk4Fx2fK499Ljo+X74JiPIL9j+R4WL/Z0++CoBRCSm59uKnOxcdj6iElFxdBxFlH/ufyHCx/7Mv3wRAdZoGJx/H6mRdpx7HQp1Dw8tE9OXY/0SGi/3/efJNALwQE4/XOnpRkv93dhER5Q3sfyLDxf7/PPkiACaoU3EnLinDmT5Te/jhz9lTc22dd+KSkKhOzbXHJ6KsYf8TGa7M+h/I3c+A/NL/+eI6gP/FxOP684QMb4CXsS9gbGwCiwIFsvQYr+Ji8cdPU3AyYh8AoJGzO/pPngWrgjaZzi8AqGJnhZr2ee/5IDIkOdH/qt9+wekDYbh95SKMTUyx8cSVj87P/ifKGzLrfyB7nwHRD+5DuXIx/jt6BLFPY1CoqANatvWF3+CRMDE1fW/+vNz/2clrej8CqBFF3I5NfO/Ft7YtlOUPfwBYMmYY7ly+iMm/b8bk3zfjzuWL+OWHER+cXwRwKzYRmk/nZyLKJTnV/6mvX6NZm7Zo3blXluZn/xNJ70P9D2TvM+Dh7RsQNRoMmjEPi3dGos+E6di3bSP+Wjwn0/nzS//r/YWg41JStbd3edvUHn4oV70m+k6cicHOTeDWsTue3LuNf/bsRAEbG/gN/g7unboDAB7cvI4zhyIxZ9tOVKnbAAAw5McFmNC5LR7euoGSFSplum615s29BQuZm+TeBhLRB+VE/wNA52/HAgAiArZled3sfyJpfaj/gex9BtT/xgn1v3HSLlusdFk8vH0Te7dsQK9x0zJ9/PzQ/3o/AhibrM7SfMFrV6FirbpYuGMfWnfphd9njMeDW9cBAFfPnoSldUFt+AOAKvUawtK6IK6eOZkj6yeinJcT/a+L9RNRzstO/2X3MyDx5UtY29jm2PrzonwRAIUszNeglTPadO2N4mXLw2fAcFgXssPF4/++eYyYGNjYFXlvGRu7Ioh9GvPBxxSg/28AIn2WE/3/udj/RNLKav8D2fsMeHLvDnZv+hPunXt88PHyQ//rfQBMTkvL0n3+ylatrv2/IAiwLVIUcc+evjXt/WVEiPjYu0v83/qJSBo51f+fg/1PJK2s9j+Q9c+A51FP8OOAbmjWxhuuim4ffLz80P96HwDTPrD//13Gxhn30wsCIGreXDfI1t4esZm8EeKfP4NtYfscWT8R5byc6H9drJ+Icl52+i8rnwHPo55gWi85qtZriMEzF+To+vMivQ+ARrKsDgB/WNV6jZD4Mh7Xz5/RTrt27jQSX8ajav1Gub5+Ivo8Uvef1OsnMmQ52X/Poh5jak85yteojWGzF0Mm+3Q80vf+1/uzgM2NjCAAWR4GzkypipVR/xsnrJwyFoNnzAMArJz6Axo6un7wDGDgzd5hcyOjL1gzEX2JnOh/AIh59ACv4mLx9PFDaNLScPvyfwCAYmXKw8LKKtNl2P9E0sqp/n8e9QRTe8phX7wkeo2bivjnz7S/K2RfNNNl8kP/630AtDU3gRj35Y8zcsEy/PnTFMzs1wUA0NjZHf2n/PTRZcT/rZ+IpJFT/b916UIcCNyu/XmMjzsAYMZ6FWo1bZ7pMux/ImnlVP+fPXIQT+7expO7tzGwVcMMv/O/8ijTZfJD/+v9nUBeJKsReffLDub+Ek5li+j1dYCI9Bn7n8hwsf/fZ1B3ArExM4aJRPvhTWQCbMz0fhCVSG+x/4kMF/v/y+h9AJQJAsrbWmb5WkA5RQBQwdYSssyuH0NEOsH+JzJc7P8vo/cBEHjzQuj6ZGwRQHlbSx2vlYjexf4nMlzs/8+XLwKgpYkxytlY6HSd5WwsYGmi38O/RPkB+5/IcLH/P1++CIAAUNu+IMyNdLM55kYy1LbPWyfDEBky9j+R4WL/f558EwBNjGRoWNxWJ+tqWNwWJjp6sxHRp7H/iQwX+//z5I+t+B8HKzPULZq7ybxu0YJwsDLL1XUQUfax/4kMF/s/+/JVAASAioWscu1NULdoQVQslPldAYhIeux/IsPF/s8e/T+KMRMVC1mhgKkxTj2ORXLal9/w3fx/w8v5KfkT5VfsfyLDxf7POr2/E8jHqNM0uBATjztxSdm+X2D6/OVsLFDbvmC+2edPZCjY/0SGy1D7Pzt5LV8HwHSJ6lTcjk3ErdhEqDVvNlcAoBFFCP+7kOPbbxATmYAKtpYob2uZL071JjJk7H8iw2Vo/c8A+AEaUURcSipik9WITVYjaFcoylesiCqVK8HcyAi25iawNTeBjZmx3l/hm4gyerf/Dx75BzITEzRu2ID9T5TPvdv/Zy9ewsNHj+Di7JSv+p8BMItKliyJgQMHYtq0aVKXQkQ61q5dOwBAcHCwxJUQka7NmDEDq1evxsOHD6UuJUdlJ6/pz45tIiIiIsoRDIBEREREBoYBkIiIiMjAMAASERERGRgGQCIiIiIDwwBIREREZGAYAImIiIgMDAMgERERkYFhACQiIiIyMAyARERERAaGAZCIiIjIwDAAEhERERkYBkAiIiIiA8MASERERGRgGACJiIiIDAwDIBEREZGBYQAkIiIiMjAMgEREREQGhgGQiIiIyMAwABIREREZGAZAIiIiIgPDAEhERERkYBgAiYiIiAwMAyARERGRgWEAJCIiIjIwDIBEREREBoYBkIiIiMjAMAASERERGRgGQCIiIiIDwwBIREREZGAYAImIiIgMDAMgERERkYFhACQiIiIyMAyARERERAaGAZCIiIjIwDAAEhERERkYBkAiIiIiA8MASERERGRgGACJiIiIDAwDIBEREZGBYQAkIiIiMjAMgEREREQGhgGQiIiIyMAwABIREREZGAZAIiIiIgPDAEhERERkYBgAiYiIiAwMAyARERGRgWEAJCIiIjIwDIBEREREBoYBkIiIiMjAMAASERERGRgGQCIiIiIDwwBIREREZGAYAImIiIgMDAMgERERkYFhACQiIiIyMAyARERERAaGAZCIiIjIwDAAEhERERkYBkAiIiIiA8MASERERGRgGACJiIiIDAwDIBEREZGBYQAkIiIiMjAMgEREREQGhgGQiIiIyMAwABIREREZGAZAIiIiIgPDAEhERERkYBgAiYiIiAwMAyARERGRgWEAJCIiIjIwDIBEREREBoYBkIiIiMjAMAASERERGRgGQCIiIiIDwwBIREREZGAYAImIiIgMDAMgERERkYExiAD46NEj+Pv7Z2neFy9eYOPGjblcERHp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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Create a simple directed graph with 3 inputs, 3 outputs, and 5 function nodes\n", "G = nx.DiGraph()\n", "\n", "# Add input nodes, function nodes, and output nodes\n", "input_nodes = ['in0', 'in1', 'in2']\n", "function_nodes = ['func0', 'func1', 'func2', 'func3', 'func4']\n", "output_nodes = ['out0', 'out1', 'out2']\n", "\n", "# Add edges from input nodes to function nodes\n", "G.add_edges_from([('in0', 'func0'), ('in1', 'func1'), ('in2', 'func2')])\n", "\n", "# Add edges between function nodes\n", "G.add_edges_from([('func0', 'func3'), ('func1', 'func4'), ('func2', 'func3')])\n", "\n", "# Add edges from function nodes to output nodes\n", "G.add_edges_from([('func3', 'out0'), ('func4', 'out1'), ('func3', 'out2')])\n", "\n", "# Define positions for each node for plotting\n", "pos = {\n", " 'in0': (-2, 2), 'in1': (0, 2), 'in2': (2, 2),\n", " 'func0': (-2, 1), 'func1': (0, 1), 'func2': (2, 1),\n", " 'func3': (-1, 0), 'func4': (1, 0),\n", " 'out0': (-2, -1), 'out1': (0, -1), 'out2': (2, -1)\n", "}\n", "\n", "# Plot the graph\n", "plt.figure(figsize=(8, 6))\n", "nx.draw_networkx(G, pos, with_labels=True, node_color='lightblue', node_size=500, font_size=10, arrowstyle='->', arrowsize=20)\n", "plt.title(\"Dummy Graph: 3 Inputs, 3 Outputs, 5 Function Nodes\")\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Simulating function nodes \n", "\n", "To simulate more complex functions, we can add specific function behaviors to our network by passing the `special_functions` dict to `simulate`. This enables us to add non-linear node functions to the graph. For instance, in the example below, `func2` will exponentiate the inputs. \n", "\n", "The `simulate` function uses [pyro](https://pyro.ai/) to create a bayesian network that emualtes our graph structure. For our application, each node is modeled as a univariate standard normal distribution where the scale and location of each node is dependant on the values of the preceding nodes. \n", "\n", "NOTE: Using bayesian networks requires that no cycles exists in the graph. Notably, the GSNN can handle cycles and we plan to add more complex simulations that can create these behaviors (i.e., ODE simulations)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "special_functions = {'func1': lambda x: -np.mean(x), 'func2':lambda x: np.sum([np.exp(xx) for xx in x]), \n", " 'func0': lambda x: np.mean(([(xx)**2 for xx in x])), 'func3': lambda x: -np.mean(x) if all([xx > 0 for xx in x]) else np.mean(x)}\n", "\n", "x_train, x_test, y_train, y_test = simulate(G, n_train=500, n_test=100, input_nodes=input_nodes, output_nodes=output_nodes, \n", " special_functions=special_functions, noise_scale=0.001)\n", "\n", "device = 'cuda' if torch.cuda.is_available() else 'cpu'\n", "\n", "x_train = torch.tensor(x_train, dtype=torch.float32).to(device)\n", "y_train = torch.tensor(y_train, dtype=torch.float32).to(device)\n", "\n", "x_test = torch.tensor(x_test, dtype=torch.float32).to(device)\n", "y_test = torch.tensor(y_test, dtype=torch.float32).to(device)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Training GSNN with simulated data\n", "\n", "We can train a GSNN model using our synthetic data. Note that we have chosen the hyperparameters to demonstrate some of the inner workings of the GSNN, however, changing these hyperparameters can muddy the interpretation. " ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "n params 700\n", "iter: 999 | loss: 0.118\r" ] } ], "source": [ "data = nx2pyg(G, input_nodes, function_nodes, output_nodes)\n", "\n", "model = GSNN(data.edge_index_dict,\n", " data.node_names_dict, \n", " channels=20, \n", " layers=2,\n", " share_layers=False, \n", " bias=True,\n", " add_function_self_edges=False,\n", " checkpoint=False, \n", " norm='none', \n", " init='degree_normalized',\n", " residual=True,\n", " node_attn=False,\n", " node_mlp=False,\n", " dropout=0.).to(device)\n", "\n", "print('n params', sum([p.numel() for p in model.parameters()]))\n", "\n", "optim = torch.optim.AdamW(model.parameters(), lr=1e-2, weight_decay=1e-2)\n", "crit = torch.nn.MSELoss()\n", "\n", "losses_gsnn = []\n", "for i in range(1000): \n", " model.train()\n", " optim.zero_grad() \n", "\n", " yhat = model(x_train)\n", " loss = crit(y_train, yhat)\n", " loss.backward() \n", " optim.step()\n", "\n", " with torch.no_grad(): \n", " model.eval()\n", " yhat = model(x_test)\n", " loss = crit(y_test, yhat)\n", "\n", " print(f'iter: {i} | loss: {loss.item():.3f}',end='\\r')\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Interpreting learned functions \n", "\n", "We can also extract individual function nodes and evaluate their learned behavior. Note that function nodes that have more than one input or output will require more advanced visualization or interpretation methods (SHAP, LIME, etc.)\n", "\n", "### Interpretation limitations\n", "\n", "In most scenarios, we do not know the exact required path length and will want to use more competive architectures that make interpretation of individual function nodes more complicated. For instance, if we use a greater number of layers, then many layers may contribute to the prediction of an outcome, so the true effect a function node is an aggregate of many layers behaviors. This challenge is further exacerbated if we change `share_layers=False` as each layer will learn unique functions for each node. \n", "\n", "Additionally, in a \"chain\" of latent functions, the specific functions may be shuffled or aggregated, and the sign of individual function nodes may be flipped. For instance, in our example `func1` and `func4` may be switched but would still have good performance. In more complex networks with a greater number of outputs, this behavior is liable to converge to more accurate function specific representations." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Extract the `Func0` GSNN learned node function" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "model = model.eval() " ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "image/png": "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mEMf1+bQmzRpEjIyMrB06VKcOHECJ06cwNKlS5GZmYnJkyc7ooxERFRdZiYQHAzExEh/MzPlLpFNNBoNMjIyoFarAUiBl56e7vDOLDa36fn5+WHTpk14/PHHjbbv2LEDo0aNcuqwBbbpEZEiabVS0FU9PahWA4WFgBN6QNqTVqtFfn4+wsLC6hV41uaBzb03GzZsaHbdvJCQEHh5edl6OCIislVennHgAUBlJZCf73ahp9FonDJUQc/m05tJSUl48803UVFRYdhWUVGBRYsWYdKkSXYtHBERmREeDlRrD4NaDTi4PcwT1GnuzT179kCj0aB79+4AgO+//x63bt3Co48+iqefftqw79atW+1XUiIikmg0QEYGkJgo1fDUaiA93e1qeXKwOfSaNWuGZ555xmhbYGCg3QpERERWSEgAYmOlU5phYQw8K3FwOiA1CuflSacM+MYhInI7DhucHhMTgytXrph9wJiYGFsPJz837/ZLRETWs7mmp1KpcOnSJbRq1cpoe2lpKe69916nDlCvd03Pg7r9EhEpmd2HLJw6dcrw7zNnzuDSpUuG65WVldi5cyfuvffeOhZXJh7U7ZeIiGpndeg98MADEAQBgiCYPY3p4+ODd999166Fczh9t9/qNT12+yUi8khWh15BQQFEUUS7du1w9OhR+Pv7G27z8vJCq1atDNPJuA12+yUid8EOd3bB3puA9GZit18iclWZmcD48dJZKZVK+rHu4HXn3I21eWBz6K1fv77G28eOHWvL4eqFc28SkcdjhzurOGzuzSlTphhdv337Nm7cuAEvLy80atTIqaFHROTx2OHOrmwep/fHH38YXa5du4Zz586hb9++2LhxoyPKSESkXJxn067qtXK6Xnh4OJYsWWJSCyQionrSd7jTdxRkh7t6sfn0piVqtRoXL1601+GIiEiP82zajc2h9/nnnxtdF0URJSUleO+99xAVFWW3ghERURUaDcPODmwOvWHDhhldFwQB/v7+iImJwdtvv22vchEREdmdzaGnq96LiIiIyE3UqyOLKIpw47HtRESkMHUKvfXr16Nr167w8fGBj48PunXrhg0bNti7bERERHZl8+nN5cuXY86cOZg0aRKioqIgiiIOHjyICRMm4LfffsPLL7/siHISERHVm83TkIWGhmL+/PkmM69kZWVh3rx5KCgosGsBa8JpyIiI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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fn = 'func0'\n", "\n", "f,axes = plt.subplots(1,1, figsize=(5,5), sharey=True)\n", "plt.suptitle( fn )\n", "\n", "func, meta = extract_entity_function(node=fn, model=model, data=data, layer=0)\n", "n_inputs = func.lin_in.weight.data.shape[1]\n", "inp = torch.randn(100, n_inputs)\n", "out = func(inp)\n", "\n", "if fn in special_functions: \n", " out_true = [special_functions[fn](np.array(x)) for x in inp]\n", "else: \n", " out_true = [x for x in inp]\n", " \n", "plt.plot(inp, out_true, 'r.', label='true function')\n", "plt.plot(inp.detach().cpu().numpy().ravel(), out.detach().cpu().numpy().ravel(), 'k.', label='learned function')\n", "\n", "plt.xlabel(f'{fn} input')\n", "plt.ylabel(f'{fn} output')\n", "plt.legend()\n", "plt.show() " ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAckAAAHyCAYAAACAgjUfAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/TGe4hAAAACXBIWXMAAA9hAAAPYQGoP6dpAABOVklEQVR4nO3de1xUdf4/8NeZUcQLYAqmNTCooGVlmYKiqUTfFTNN27JsS8VIsNQ0Q13vl01NQc2yXND5qVmb6a52sbJ1E8u8jm7kpuWCgXiU1qwEb6HOnN8fpxkZmIMzODNnzszr+XjMg+ac4cwHQl58PufzeX8ESZIkEBERUQ06tRtARETkrxiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSRH7gvffewx133IGGDRtCEAQUFBSo0o5z585h0qRJ6NOnD6KioiAIAmbPnq1KW4j8AUOSSGU//fQThg4dirZt22Lr1q3Ys2cP2rVrp0pbfv75Z+Tl5aGyshKDBg1SpQ1E/qSe2g0gCnb//e9/ceXKFTz99NPo3bu3qm0xGo349ddfIQgCzpw5g1WrVqnaHiK1sSdJpKK0tDTcd999AIAnnngCgiAgOTnZ/nD2+tjYWPvzkpISCIKAnJwcLFmyBK1bt0aTJk2QlJSEvXv31vj8ffv2YcCAAWjevDlCQ0PRtm1bjB8/3n5eEAQIguDpL5NIsxiSRCqaMWMG3njjDQDA/PnzsWfPHrz55ptuX+eNN97Atm3b8Oqrr+Kdd97BhQsX0K9fP5SXl9tf89lnn6Fnz54oLS3FkiVL8Omnn2L69On43//+57GvhyjQcLiVSEVt27ZFhw4dAADx8fHo1q1bna4TFhaGLVu2QK/XAwBuueUWJCYm4tNPP8WQIUMAAKNHj0ZMTAz27duH0NBQ++eOGDHiBr8KosDFniRRAHjooYfsAQkAHTt2BAAcP34cgHzf89ixY0hPT3cISCKqHUOSKAA0b97c4XmDBg0AAJcuXQIgz6AFAIPB4NuGEWkcQ5LID4WGhqKysrLG8TNnztTpelFRUQAAURRvqF1EwYYhSeSHYmNj8d///tchKH/++Wfs3r27Ttdr164d2rZti//3//6f0/AlIuc4cYfIDw0dOhS5ubl4+umnMXLkSPz8889YtGgRwsPD63zNN954AwMGDEC3bt3w4osvIiYmBqWlpfjss8/wzjvv2F/36aef4sKFCzh37hwA4MiRI/j73/8OAOjXrx8aNWp0Y18ckYYwJIn8UI8ePbB27Vq88sorGDhwINq0aYNZs2bhk08+wY4dO+p0zdTUVHz55ZeYO3cuXnjhBfz2228wGAx4+OGHHV733HPP2Sf8AMDGjRuxceNGAEBxcbHDOk2iQCdIkiSp3QgiIiJ/xHuSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSREREChiSRERECuqp3QBfslqtOHXqFMLCwiAIgtrNISIiFUiShHPnzuGWW26BTld7XzGoQvLUqVOIjo5WuxlEROQHTpw4AYPBUOtrgiokw8LCAMjfmPDwcJVbQ0REaqioqEB0dLQ9E2oTVCFpG2INDw9nSBIRBTlXbrtx4g4REZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChqS7RBHIz5c/EhFRQGNIusNkAoxGICVF/mgyqd0iIiLyIoakq0QRyMgArFb5udUKZGayR0lEFMAYkq4qLLwWkDYWC7BxI4OSiChAMSRdFR8P6Jx8uyZM4NArEVGAYki6ymAA8vIAvb7mOQ69EhEFJIakO9LTgZISYMmSmucsFqCoyOdNIiIi72FIustgAAYPrjn0qtcDjRtzeQgRkReJooj8/HyIPvo9y5Csi+pDr3o98PTTQLduXB5CROQlJpMJRqMRKSkpMBqNMPng96wgSZLk9XfxExUVFYiIiEB5eTnCw8Nv/IKiKA+xNm4sB2TV2a96vTw0azDc+PsQEQU5URRhNBphrfJ7Vq/Xo6SkBAY3f8+6kwXsSd4IgwFITgbOn3e+PIT3KImIPKKwsNAhIAHAYrGgyMu/ZxmSnuBseYheD8TFqdMeIqIAEx8fD121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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fn = 'func1'\n", "\n", "f,axes = plt.subplots(1,1, figsize=(5,5), sharey=True)\n", "plt.suptitle( fn )\n", "\n", "func, meta = extract_entity_function(node=fn, model=model, data=data, layer=0)\n", "n_inputs = func.lin_in.weight.data.shape[1]\n", "inp = torch.randn(100, n_inputs)\n", "out = func(inp)\n", "\n", "if fn in special_functions: \n", " out_true = [special_functions[fn](np.array(x)) for x in inp]\n", "else: \n", " out_true = [x for x in inp]\n", " \n", "plt.plot(inp, out_true, 'r.', label='true function')\n", "plt.plot(inp.detach().cpu().numpy().ravel(), out.detach().cpu().numpy().ravel(), 'k.', label='learned function')\n", "\n", "plt.xlabel(f'{fn} input')\n", "plt.ylabel(f'{fn} output')\n", "plt.legend()\n", "plt.show() " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Extract the `Func2` GSNN learned node function" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/tmp/ipykernel_4829/417286389.py:12: DeprecationWarning: __array__ implementation doesn't accept a copy keyword, so passing copy=False failed. __array__ must implement 'dtype' and 'copy' keyword arguments. To learn more, see the migration guide https://numpy.org/devdocs/numpy_2_0_migration_guide.html#adapting-to-changes-in-the-copy-keyword\n", " out_true = [special_functions[fn](np.array(x)) for x in inp]\n" ] }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAckAAAHyCAYAAACAgjUfAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAARuVJREFUeJzt3XlcVOX+B/DPmaMoymJuuQyLClZqWIkmroQlXrWrdX9uNxULRa9LmZlmai5l7kuZeUHnulUu994stdJM0UxQ0TQzzcBAOYq5JSgW6Mz5/TF3RgbmwByYnc/79eKFc+bMOd8ZlQ/Pc57nOYIsyzKIiIioBI2rCyAiInJXDEkiIiIFDEkiIiIFDEkiIiIFDEkiIiIFDEkiIiIFDEkiIiIFDEkiIiIFDEkiIiIFDEkiN7B582a0bNkSvr6+EAQBJ06ccEkde/fuxUsvvYSHH34YNWvWROPGjdGnTx8cO3bMJfUQuZrAZemIXOvq1ato3LgxevTogddeew3VqlVDREQEatSo4fRa+vXrh+vXr6Nfv35o0aIFrl69isWLF+Po0aPYtWsXYmJinF4TkSsxJIlc7ODBg+jUqRM2b96M/v37u7SWK1euoH79+hbbbt++jbCwMLRq1QrffPONiyojcg12txK50LBhw9CpUycAwIABAyAIAqKjo81f1vYPDQ01P87KyoIgCFi0aBGWLFmCJk2awM/PD1FRUTh06FCJ1x8+fBjPPvss6tSpg+rVq6NZs2YYP368+fniAQkAfn5+aNGiBbKzsyv8fok8DUOSyIWmT5+OFStWAADeffddpKam4sMPP1R9nBUrVmD37t1YtmwZPv74Y+Tn56Nnz57Izc0177Nr1y507twZFy5cwJIlS/DVV19h2rRp+O2330o9dm5uLr7//nu0bNlSdV1Enq6KqwsgqsyaNWuGFi1aAADCw8PRvn37ch3H398fO3bsgCiKAIBGjRqhXbt2+OqrrzBw4EAAwJgxYxAcHIzDhw+jevXq5te++OKLpR57zJgxyM/Px9SpU8tVG5EnY0uSyAv06tXLHJAAEBERAQA4f/48AOCXX37BuXPnEB8fbxGQZZk+fTo+/vhjLF26FG3atLFv0UQegCFJ5AXq1Klj8bhatWoAgD/++AOAcQQtAGi1WpuPOWvWLLzzzjuYM2cOxo4da6dKiTwLQ5LIDVWvXh0FBQUltl+7dq1cx6tXrx4AQJIkm/afNWsWZs6ciZkzZ+LNN98s1zmJvAFDksgNhYaG4pdffrEIyuvXryMlJaVcx2vevDmaNWuGf/3rX1bDt6i3334bM2fOxLRp0zBjxoxynY/IWzAkidzQkCFDcOPGDQwePBhff/01Nm7ciKeffhoBAQHlPuaKFStw/vx5tG/fHuvXr8e+ffuwfv16vPDCC+Z9Fi9ejLfeegs9evRAr169cOjQIYsvosqGo1uJ3FDHjh2xbt06zJs3D3369EHTpk0xY8YMfPnll9i3b1+5jhkbG4tvv/0Ws2fPxssvv4w///wTWq0Wf/3rX837bN++HQCwc+dO7Ny5s8QxuPYIVTZccYeIiEgBu1uJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUMCSJiIgUVHF1Ac5kMBhw6dIl+Pv7QxAEV5dDREQuIMsybt26hUaNGkGjKb2tWKlC8tKlSwgKCnJ1GURE5Aays7Oh1WpL3adShaS/vz8A4wcTEBDg4mqIiMgV8vLyEBQUZM6E0lSqkDR1sQYEBDAkiYgqOVsuu3HgDhERkQKGJBERkQKGJBERkYJKdU3SFrIs4969e9Dr9a4uhSqpqlWrQhRFV5dBRGBIWigsLEROTg7u3Lnj6lKoEhMEAVqtFn5+fq4uhajSY0j+j8FgQGZmJkRRRKNGjeDj48MFB8jpZFnG1atXIUkSwsPD2aIkcjGG5P8UFhbCYDAgKCgINWrUcHU5VInVq1cPWVlZuHv3LkOSyMU4cKeYspYoInI09mAQuQ8mAhERkQKGJBERkQKGJFXYnTt38Le//Q0BAQEQBAE3b950WS379u1zeQ1E5D0Ykh4uOjoa48ePd2kN69atw4EDB5CSkoKcnBwEBgY65bzW3nuHDh2cWgMROZkkAcnJxu9OwJB0BCf/JZbFtECCo5w7dw6PPPIIWrVqhQYNGrh04ImPj4/LayAiB9HpgJAQICbG+F2nc/w55UokNzdXBiDn5uaWeO6PP/6QT58+Lf/xxx8VO8nq1bKs0cgyYPy+enXFjleKuLg4GYDFV2ZmppycnCwDkHfu3Cm3adNGrlq1qrx37145Li5O7tOnj8UxXnnlFblr167mxwaDQZ4/f77cpEkTuXr16nJERIT873//W7GGrl27WpzfdCwA8tatWy32DQwMlNesWSPLsixnZmbKAOT//ve/cnR0tOzr6ytHRETIKSkpFq/57rvv5C5dusi+vr5yrVq15O7du8s3btwo873//vvv5mP85z//kVu0aCH7+PjIISEh8qJFiyzOERISIs+ZM0d+8cUXZT8/PzkoKEhOTEy06e/AEez2b5HIm2Rn3//ZavoSReN2lUrLguLYkrQnSQISEgCDwfjYYABGjnRYi/K9995DVFQURowYgZycHOTk5FjcVHrSpEmYO3cuzpw5g4iICJuOOW3aNKxZswYrV67ETz/9hFdffRWDBw/G/v37re7/6aefYsSIEYiKikJOTg4+/fRTVe9h6tSpmDhxIk6cOIHmzZtj0KBB5lbviRMn0K1bN7Rs2RKpqan47rvv8Oyzz0Kv15f53k2OHTuG/v37Y+DAgfjxxx8xc+ZMTJ8+HWvXrrXYb/HixYiMjMTx48cxevRo/OMf/8DPP/+s6r0QkQOlp9//2Wqi1wMZGQ49LRcTsKfS/hLLuPt1eQQGBsLHxwc1atRAgwYNSjw/e/ZsPPPMMzYfLz8/H0uWLMHevXsRFRUFAGjatCm+++47JCYmomvXriVeU7t2bdSoUcPczanWxIkT0atXLwDArFmz0LJlS2RkZODhhx/GggULEBkZiQ8//NC8f8uWLc1/Lu29myxZsgTdunXD9OnTAQDNmzfH6dOnsXDhQgwbNsy8X8+ePTF69GgAwOTJk7F06VLs27cPDz/8sOr3REQOEB4OaDSWP2NFEQgLc+hp2ZK0J9NfYlFO+EtUEhkZqWr/06dP488//8QzzzwDPz8/89f69etx7tw5h9RYtIXbsGFDAMCVK1cA3G9JVsSZM2fQsWNHi20dO3ZEenq6xSL2ResQBAENGjQw10FEbkCrBZKSjD9TAeP3xESHNECKYkvSnkx/iSNHGluQTvpLVFKzZk2LxxqNBrIsW2y7e/eu+c+G//2G9sUXX6Bx48YW+1WrVk3VuQVBKPVcJlWrVrV4TdE6fH19VZ3TGlmWSwziKV5X8TpMtRiK9woQkWvFxwOxscbeubAwp/xsZUjam5P/En18fGy+rVe9evVw6tQpi20nTpwwB0SLFi1QrVo1XLhwwWrXqhr16tVDTk6O+XF6errqu6tERERgz549mDVrltXnbXnvLVq0wHfffWexLSUlBc2bN+e6qESeSKt1asODIekITvxLDA0NxeHDh5GVlQU/Pz/Url1bcd+YmBgsXLgQ69evR1RUFD766COcOnUKjz/+OADA398fEydOxKuvvgqDwYBOnTohLy8PKSkp8PPzQ1xcnM11xcTE4IMPPkD79u1hMBgwefLkEq21skyZMgWPPvooRo8ejVGjRsHHxwfJycno168f6tata9N7f+2119C2bVu8/fbbGDBgAFJTU/HBBx9YXOckIlLCa5IebuLEiRBFES1atEC9evVw4cIFxX1jY2Mxffp0TJo0CW3btsWtW7cwdOhQi33efvttvPXWW5g7dy4eeeQRxMbGYvv27WjSpImquhYvXoygoCB06dIFf//73zFx4kTVd1dp3rw5vv76a/zwww9o164doqKi8Pnnn6NKlSo2v/cnnngCW7ZswaZNm9CqVSu89dZbmD17tsWgHSIiJYJs7QKNl8rLy0NgYCByc3MREBBg8dyff/6JzMxMNGnSBNWrV3dRhUT8t0jkaKVlQXFsSRIRESlgSBIRESlgSBIRESlgSBIRESlgSBIRESlgSBIRESlgSBIRESlgSBIRESlgSHq46OhojB8/3tVlVIggCPjss88Un5dlGQkJCahduzYEQcCJEyecVltxWVlZLq+BiJyHa7eS29u5cyfWrl2Lffv2oWnTpqhbt65Tzjts2DDcvHnTIsCDgoKQk5PjtBqIyLUYklSmwsJC+Pj4uOz8586dQ8OGDdGhQweX1WAiimK5bi5NRJ6J3a0OIEkSkpOTIUmS089dWFiISZMmoXHjxqhZsyaefPJJ7Nu3z/z89evXMWjQIGi1WtSoUQOPPvooNm7caHGM6OhojB07FhMmTEDdunXxzDPPYN++fRAEAXv27EFkZCRq1KiBDh064OzZsxav3b59O9q0aYPq1aujadOmmDVrFu7du2d+Pj09HV26dEH16tXRokUL7N69u9T3M2zYMIwbNw4XLlyAIAgIDQ0FYLz7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na5Ro0a51xUlKi+DwYCrV6+iRo0aqFKF/z2JXI3/C4sw3XGed2cgV9JoNAgODuYvaURugCFZhCAIaNiwIerXr291nU4iZ/Dx8eG6r0RugiFphSiKvB5EREQcuENERKSEIUlERKSAIUlERKSAIUlERKSAIUlERKSAIUlERKSAIUlERKSAIUlERKSAIUlERKSAIUlERKSAIUlERKSAIUlERKSAIUlERKSAIUlERKSAIUlERKTAo0Ly4sWLGDx4MOrUqYMaNWrgsccew7Fjx1xdFhEReSmPueny77//jo4dO+Kpp57CV199hfr16+PcuXOoVauWq0sjIqKySBKQng6EhwNaraursZnHhOT8+fMRFBSENWvWmLeFhoa6riAiIrKNTgeMGAHIMiAIwKpVQHy8q6uyicd0t27btg2RkZHo168f6tevj8cffxyrVq0q9TUFBQXIy8uz+CIiIieSpPsBCRi/jxhh3O4BPCYkf/31V6xcuRLh4eHYtWsXRo0ahZdffhnr169XfM3cuXMRGBho/goKCnJixUREhJSU+wFpIstAaqpr6lFJkOXi1bsnHx8fREZGIiUlxbzt5ZdfRlpaGlIVPuyCggIUFBSYH+fl5SEoKAi5ubkICAhweM1ERJXeli3AgAHWt/fr5/x6YMyCwMBAm7LAY1qSDRs2RIsWLSy2PfLII7hw4YLia6pVq4aAgACLLyIicqIOHYzXIYvSaICoKNfUo5LHhGTHjh1x9uxZi22//PILQkJCXFQRERGVSas1DtQRReNjUQSSkjxmhKvHjG599dVX0aFDB7z77rvo378/jhw5gqSkJCQlJbm6NCIiKk18PBAbC2RkAGFhHhOQgAddkwSAHTt2YMqUKUhPT0eTJk0wYcIEjBgxwubXq+mHJiIi76QmCzwqJCuKIUlERF45cIeIiMjZGJJEREQKGJJEREQKGJJEREQKGJJEREQKGJJEREQKGJJEREQKGJJEREQKGJJEREQKGJJEREQKGJJEREQKGJJEREQKGJJEREQKGJJEREQKGJJEREQKGJJEREQKGJJEREQKGJJEREQKGJJEREQKGJJEREQKGJJEREQKGJJERFQ+kgQkJxu/eymGJBERqafTASEhQEyM8btO5+qKHIIhSURE6kgSkJAAGAzGxwYDMHKkV7YoGZJERKROevr9gDTR64GMDNfU40AMSSIi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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fn = 'func2'\n", "\n", "f,axes = plt.subplots(1,1, figsize=(5,5), sharey=True)\n", "plt.suptitle( fn )\n", "\n", "func, meta = extract_entity_function(node=fn, model=model, data=data, layer=0)\n", "n_inputs = func.lin_in.weight.data.shape[1]\n", "inp = torch.randn(100, n_inputs)\n", "out = func(inp)\n", "\n", "if fn in special_functions: \n", " out_true = [special_functions[fn](np.array(x)) for x in inp]\n", "else: \n", " out_true = [x for x in inp]\n", " \n", "plt.plot(inp, out_true, 'r.', label='true function')\n", "plt.plot(inp.detach().cpu().numpy().ravel(), out.detach().cpu().numpy().ravel(), 'k.', label='learned function')\n", "\n", "plt.xlabel(f'{fn} input')\n", "plt.ylabel(f'{fn} output')\n", "plt.legend()\n", "plt.show() " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## simulating data with stochastic differential equations " ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "ename": "KeyboardInterrupt", "evalue": "", "output_type": "error", "traceback": [ "\u001b[31m---------------------------------------------------------------------------\u001b[39m", "\u001b[31mKeyboardInterrupt\u001b[39m Traceback (most recent call last)", "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[8]\u001b[39m\u001b[32m, line 1\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m x_train, y_train, x_test, y_test = simulate_sde(\n\u001b[32m 2\u001b[39m G, n_train=\u001b[32m500\u001b[39m, n_test=\u001b[32m200\u001b[39m,\n\u001b[32m 3\u001b[39m input_nodes=input_nodes,\n\u001b[32m 4\u001b[39m output_nodes=output_nodes,\n", "\u001b[36mFile \u001b[39m\u001b[32m/home/exacloud/gscratch/mcweeney_lab/evans/GSNN/gsnn/simulate/simulate.py:253\u001b[39m, in \u001b[36msimulate_sde\u001b[39m\u001b[34m(G, n_train, n_test, input_nodes, output_nodes, noise_scale, dt, t_final, special_functions, seed, signed_edges)\u001b[39m\n\u001b[32m 250\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m np.array(x_samples), np.array(y_samples)\n\u001b[32m 252\u001b[39m \u001b[38;5;66;03m# Generate training and test samples\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m253\u001b[39m x_train, y_train = \u001b[30;43mgenerate_samples\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mn_train\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 254\u001b[39m x_test, y_test = generate_samples(n_test)\n\u001b[32m 256\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m x_train, y_train, x_test, y_test\n", "\u001b[36mFile \u001b[39m\u001b[32m/home/exacloud/gscratch/mcweeney_lab/evans/GSNN/gsnn/simulate/simulate.py:245\u001b[39m, in \u001b[36msimulate_sde..generate_samples\u001b[39m\u001b[34m(n_samples)\u001b[39m\n\u001b[32m 242\u001b[39m x_values = np.random.normal(\u001b[32m0\u001b[39m, \u001b[32m1\u001b[39m, \u001b[38;5;28mlen\u001b[39m(input_nodes))\n\u001b[32m 244\u001b[39m \u001b[38;5;66;03m# Solve the stochastic ODE system\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m245\u001b[39m y_values = \u001b[30;43msolve_sde\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mx_values\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mn_steps\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 247\u001b[39m x_samples.append(x_values)\n\u001b[32m 248\u001b[39m y_samples.append(y_values)\n", "\u001b[36mFile \u001b[39m\u001b[32m/home/exacloud/gscratch/mcweeney_lab/evans/GSNN/gsnn/simulate/simulate.py:224\u001b[39m, in \u001b[36msimulate_sde..solve_sde\u001b[39m\u001b[34m(input_values, n_steps)\u001b[39m\n\u001b[32m 222\u001b[39m \u001b[38;5;66;03m# Integrate over time\u001b[39;00m\n\u001b[32m 223\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m _ \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mrange\u001b[39m(n_steps):\n\u001b[32m--> \u001b[39m\u001b[32m224\u001b[39m y = \u001b[30;43meuler_maruyama_step\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43my\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mdt\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mnoise_scale\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 226\u001b[39m \u001b[38;5;66;03m# Extract output values\u001b[39;00m\n\u001b[32m 227\u001b[39m output_values = []\n", "\u001b[36mFile \u001b[39m\u001b[32m/home/exacloud/gscratch/mcweeney_lab/evans/GSNN/gsnn/simulate/simulate.py:200\u001b[39m, in \u001b[36msimulate_sde..euler_maruyama_step\u001b[39m\u001b[34m(y, dt, noise_scale)\u001b[39m\n\u001b[32m 196\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34meuler_maruyama_step\u001b[39m(y, dt, noise_scale):\n\u001b[32m 197\u001b[39m \u001b[38;5;250m \u001b[39m\u001b[33;03m\"\"\"\u001b[39;00m\n\u001b[32m 198\u001b[39m \u001b[33;03m Perform one step of Euler-Maruyama integration.\u001b[39;00m\n\u001b[32m 199\u001b[39m \u001b[33;03m \"\"\"\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m200\u001b[39m drift = \u001b[30;43msde_system\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43m0\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43my\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mnoise_scale\u001b[39;49m\u001b[30;43m)\u001b[39;49m \u001b[38;5;66;03m# t not used in our system\u001b[39;00m\n\u001b[32m 201\u001b[39m noise = np.random.normal(\u001b[32m0\u001b[39m, np.sqrt(dt) * noise_scale, size=y.shape)\n\u001b[32m 203\u001b[39m \u001b[38;5;66;03m# Input nodes don't get noise\u001b[39;00m\n", "\u001b[36mFile \u001b[39m\u001b[32m/home/exacloud/gscratch/mcweeney_lab/evans/GSNN/gsnn/simulate/simulate.py:183\u001b[39m, in \u001b[36msimulate_sde..sde_system\u001b[39m\u001b[34m(t, y, noise_scale)\u001b[39m\n\u001b[32m 181\u001b[39m \u001b[38;5;66;03m# Apply special function if available\u001b[39;00m\n\u001b[32m 182\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m special_functions \u001b[38;5;129;01mand\u001b[39;00m node \u001b[38;5;129;01min\u001b[39;00m special_functions:\n\u001b[32m--> \u001b[39m\u001b[32m183\u001b[39m parent_sum = \u001b[30;43mspecial_functions\u001b[39;49m\u001b[30;43m[\u001b[39;49m\u001b[30;43mnode\u001b[39;49m\u001b[30;43m]\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43mparent_values\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n\u001b[32m 184\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 185\u001b[39m \u001b[38;5;66;03m# Default: weighted sum of parents\u001b[39;00m\n\u001b[32m 186\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m parent \u001b[38;5;129;01min\u001b[39;00m parents:\n", "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[4]\u001b[39m\u001b[32m, line 1\u001b[39m, in \u001b[36m\u001b[39m\u001b[34m(x)\u001b[39m\n\u001b[32m----> \u001b[39m\u001b[32m1\u001b[39m special_functions = {'func1': lambda x: -np.mean(x), 'func2':lambda x: np.sum([np.exp(xx) for xx in x]), \n\u001b[32m 2\u001b[39m 'func0': lambda x: np.mean(([(xx)**2 for xx in x])), 'func3': lambda x: -np.mean(x) if all([xx > 0 for xx in x]) else np.mean(x)}\n", "\u001b[36mFile \u001b[39m\u001b[32m/home/exacloud/gscratch/mcweeney_lab/evans/external/miniforge3/envs/gsnn/lib/python3.11/site-packages/numpy/core/fromnumeric.py:3504\u001b[39m, in \u001b[36mmean\u001b[39m\u001b[34m(a, axis, dtype, out, keepdims, where)\u001b[39m\n\u001b[32m 3501\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m 3502\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m mean(axis=axis, dtype=dtype, out=out, **kwargs)\n\u001b[32m-> \u001b[39m\u001b[32m3504\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[30;43m_methods\u001b[39;49m\u001b[30;43m.\u001b[39;49m\u001b[30;43m_mean\u001b[39;49m\u001b[30;43m(\u001b[39;49m\u001b[30;43ma\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43maxis\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43maxis\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43mdtype\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mdtype\u001b[39;49m\u001b[30;43m,\u001b[39;49m\n\u001b[32m 3505\u001b[39m \u001b[30;43m \u001b[39;49m\u001b[30;43mout\u001b[39;49m\u001b[30;43m=\u001b[39;49m\u001b[30;43mout\u001b[39;49m\u001b[30;43m,\u001b[39;49m\u001b[30;43m \u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43m*\u001b[39;49m\u001b[30;43mkwargs\u001b[39;49m\u001b[30;43m)\u001b[39;49m\n", "\u001b[36mFile \u001b[39m\u001b[32m/home/exacloud/gscratch/mcweeney_lab/evans/external/miniforge3/envs/gsnn/lib/python3.11/site-packages/numpy/core/_methods.py:118\u001b[39m, in \u001b[36m_mean\u001b[39m\u001b[34m(a, axis, dtype, out, keepdims, where)\u001b[39m\n\u001b[32m 115\u001b[39m dtype = mu.dtype(\u001b[33m'\u001b[39m\u001b[33mf4\u001b[39m\u001b[33m'\u001b[39m)\n\u001b[32m 116\u001b[39m is_float16_result = \u001b[38;5;28;01mTrue\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m118\u001b[39m ret = umr_sum(arr, axis, dtype, out, keepdims, where=where)\n\u001b[32m 119\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(ret, mu.ndarray):\n\u001b[32m 120\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m _no_nep50_warning():\n", "\u001b[31mKeyboardInterrupt\u001b[39m: " ] } ], "source": [ "\n", "x_train, y_train, x_test, y_test = simulate_sde(\n", " G, n_train=500, n_test=200, \n", " input_nodes=input_nodes, \n", " output_nodes=output_nodes,\n", " noise_scale=0.5, # Diffusion coefficient\n", " dt=0.01, # Time step for integration \n", " t_final=10.0, # Final integration time\n", " special_functions=special_functions,\n", " seed=42 # For reproducibility\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "device = 'cuda' if torch.cuda.is_available() else 'cpu'\n", "\n", "x_train = torch.tensor(x_train, dtype=torch.float32).to(device)\n", "y_train = torch.tensor(y_train, dtype=torch.float32).to(device)\n", "\n", "x_test = torch.tensor(x_test, dtype=torch.float32).to(device)\n", "y_test = torch.tensor(y_test, dtype=torch.float32).to(device)\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "n params 17348\n", "iter: 999 | loss: 0.673\r" ] } ], "source": [ "data = nx2pyg(G, input_nodes, function_nodes, output_nodes)\n", "\n", "model = GSNN(data.edge_index_dict,\n", " data.node_names_dict, \n", " channels=30, \n", " layers=2,\n", " share_layers=False, \n", " bias=True,\n", " add_function_self_edges=False,\n", " checkpoint=False, \n", " norm='none', \n", " init='degree_normalized',\n", " residual=True,\n", " node_attn=False,\n", " dropout=0.0).to(device)\n", "\n", "print('n params', sum([p.numel() for p in model.parameters()]))\n", "\n", "optim = torch.optim.AdamW(model.parameters(), lr=1e-3, weight_decay=1e-4)\n", "crit = torch.nn.MSELoss()\n", "\n", "losses_gsnn = []\n", "for i in range(1000): \n", " model.train()\n", " optim.zero_grad() \n", "\n", " yhat = model(x_train)\n", " loss = crit(y_train, yhat)\n", " loss.backward() \n", " optim.step()\n", "\n", " with torch.no_grad(): \n", " model.eval()\n", " yhat = model(x_test)\n", " loss = crit(y_test, yhat)\n", "\n", " print(f'iter: {i} | loss: {loss.item():.3f}',end='\\r')\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "np.float64(0.8916956887319947)" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "np.corrcoef(yhat.detach().cpu().numpy().ravel(), y_test.detach().cpu().numpy().ravel())[0,1]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/tmp/ipykernel_4829/1489212564.py:12: DeprecationWarning: __array__ implementation doesn't accept a copy keyword, so passing copy=False failed. __array__ must implement 'dtype' and 'copy' keyword arguments. To learn more, see the migration guide https://numpy.org/devdocs/numpy_2_0_migration_guide.html#adapting-to-changes-in-the-copy-keyword\n", " out_true = [special_functions[fn](np.array(x)) for x in inp]\n" ] }, { "data": { "image/png": "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ERGRDAYlERGRDAYlERGRDAYlERGRDAYlERGRDAYlERGRDAYlERGRDAYlERGRDAYlERGRDAYlERGRDAYlERGRDAYlERGRDAYlERGRDAYlERGRDAYlERGRDAYlERGRDAYlERGRDAYlERGRDAYlERGRDAYlERGRDAYlERGRDAYlERGRDAYlERGRDAYlERGRDAYlERGRDAYlERGRDAYlERGRDAYlERGRDAYlERGRDAYlERGRDAYlERGRDAYlERGRDAYlERGRDAYlERGRDAYlERGRDEWD8vDhw+jbty+8vb0hSRJ27txp8LgQArNmzYK3tzdcXV3RtWtXnD9/XpliiYjIISkalHfv3kXLli2xcuVKo48vWrQIy5Ytw8qVK5GcnIz69evj2WefxZ07dyq4UiIiclRVlHzxXr16oVevXkYfE0Lgo48+wvTp0/HCCy8AAGJjY1GvXj188cUXGD16dEWWSkREDspmj1Gmp6fj2rVr6NGjh36Zs7MzunTpgmPHjpX6vLy8POTk5BjciIiIyspmg/LatWsAgHr16hksr1evnv4xY6Kjo+Hh4aG/+fr6WrVOIiKybzYblDqSJBncF0KUWFZUVFQUsrOz9bfMzExrl0hERHZM0WOUcurXrw9A27L08vLSL79+/XqJVmZRzs7OcHZ2tnp9RETkGGy2RRkQEID69etj//79+mX5+fk4dOgQQkNDFayMiIgciaItytzcXKSlpenvp6enIyUlBZ6envDz88OkSZMwf/58BAUFISgoCPPnz4ebmxteeeUVBasmIiJHomhQnjp1Ct26ddPfnzx5MgAgIiICmzZtwrvvvov79+9j7Nix+PPPP9G+fXvs27cP7u7uSpVMREQORhJCCKWLsKacnBx4eHggOzsbNWrUULocIiJSSFnzwGaPURIREdkCBiUREZEMBiUREZEMBiUREZEMBiUREZEMBiUREZEMBiUREZEMBiUREZEMBiUREZEMBiUREZEMBiUREZEMBiUREZEMBiUREZEMBiUREZEMBiUREZEMBiUREZEMBiUREZEMBqW90GiAxETtTyIishgGpT2IiQH8/YGwMO3PmBilKyIishsMyspOowFGjQIKC7X3CwuB0aPZsiQishAGZWWXmvpPSOoUFABpacrUQ0RkZxiUlV1QEKAq9t+oVgOBgcrUQ0RkZxiUlZ2PD7BunTYcAe3P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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fn = 'func0'\n", "\n", "f,axes = plt.subplots(1,1, figsize=(5,5), sharey=True)\n", "plt.suptitle( fn )\n", "\n", "func, meta = extract_entity_function(node=fn, model=model, data=data, layer=0)\n", "n_inputs = func.lin_in.weight.data.shape[1]\n", "inp = torch.randn(100, n_inputs)\n", "out = func(inp)\n", "\n", "if fn in special_functions: \n", " out_true = [special_functions[fn](np.array(x)) for x in inp]\n", "else: \n", " out_true = [x for x in inp]\n", " \n", "plt.plot(inp, out_true, 'r.', label='true function')\n", "plt.plot(inp.detach().cpu().numpy().ravel(), out.detach().cpu().numpy().ravel(), 'k.', label='learned function')\n", "\n", "plt.xlabel(f'{fn} input')\n", "plt.ylabel(f'{fn} output')\n", "plt.legend()\n", "plt.show() " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/tmp/ipykernel_4829/591615005.py:12: DeprecationWarning: __array__ implementation doesn't accept a copy keyword, so passing copy=False failed. __array__ must implement 'dtype' and 'copy' keyword arguments. To learn more, see the migration guide https://numpy.org/devdocs/numpy_2_0_migration_guide.html#adapting-to-changes-in-the-copy-keyword\n", " out_true = [special_functions[fn](np.array(x)) for x in inp]\n" ] }, { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fn = 'func1'\n", "\n", "f,axes = plt.subplots(1,1, figsize=(5,5), sharey=True)\n", "plt.suptitle( fn )\n", "\n", "func, meta = extract_entity_function(node=fn, model=model, data=data, layer=0)\n", "n_inputs = func.lin_in.weight.data.shape[1]\n", "inp = torch.randn(100, n_inputs)\n", "out = func(inp)\n", "\n", "if fn in special_functions: \n", " out_true = [special_functions[fn](np.array(x)) for x in inp]\n", "else: \n", " out_true = [x for x in inp]\n", " \n", "plt.plot(inp, out_true, 'r.', label='true function')\n", "plt.plot(inp.detach().cpu().numpy().ravel(), out.detach().cpu().numpy().ravel(), 'k.', label='learned function')\n", "\n", "plt.xlabel(f'{fn} input')\n", "plt.ylabel(f'{fn} output')\n", "plt.legend()\n", "plt.show() " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/tmp/ipykernel_4829/417286389.py:12: DeprecationWarning: __array__ implementation doesn't accept a copy keyword, so passing copy=False failed. __array__ must implement 'dtype' and 'copy' keyword arguments. To learn more, see the migration guide https://numpy.org/devdocs/numpy_2_0_migration_guide.html#adapting-to-changes-in-the-copy-keyword\n", " out_true = [special_functions[fn](np.array(x)) for x in inp]\n" ] }, { "data": { "image/png": "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7733XsydO9f0XJIkrFy5Eo888ghq166NqKgofPbZZ2bv+fHHH9G/f38EBQUhMDAQPXv2xOnTpzF37lysWbMGW7duhSRJkCQJe/futXi5dd++fejSpQtq1aqFJk2a4OWXXzb7zLGxsZg4cSJeeukl1KtXD40bNzark4jcF0PSwbRaLcLCwhAXF4ewsDBotVqXnv+ZZ57BgQMHsGHDBhw/fhxDhgxB3759kZ2dDcAweXbHjh2xfft2/PDDDxg9ejSefvppHD582Ow4a9asQY0aNXDgwAGkpKSYts+YMQNLly7FkSNHUKNGDTz77LOm13bu3ImnnnoKEydOxIkTJ5CSkoLVq1djwYIFAAyLKT/66KNQq9U4dOgQPvjgA0ybNs3q53nrrbcwf/58aDQaFBQUIDMz066fx7x58/DEE0/g+PHj6NevH4YPH45Lly4BAM6dO2cK7D179iArKwvPPvssbt26halTp+KJJ55A3759UVBQgIKCAost2XPnzqFfv37o3Lkzvv/+e7z//vvQarV47bXXKvw869Spg8OHD2PRokWYP39+pf9BICI3IHxIYWGhACAKCwsrvHb9+nVx4sQJcf369SofPz8/X6hUKgHA9FCr1SI/P786ZVvVu3dvMWnSJCGEEDk5OUKSJHHu3DmzfR544AExffp02WP069dPvPDCC2bHvPfee832SUtLEwDE119/bdr2+eefCwCmn1nPnj3FwoULzd63bt060aRJEyGEEDt37qzw8/jyyy8FALFlyxbZ+pKTk0VYWJjZtrCwMJGcnGy2rX379mLOnDmm5wDEzJkzTc+vXLkiJEkSX375pRBCiOnTp4uIiAhRUlJi8bwJCQli0KBBZttyc3MFAHH06FEhhBCvvPKKaNmypdDr9aZ9li9fLurWrStKS0uFEIafZ48ePcyO07lzZzFt2jSL53XE30UikmctC8pjn6QDZWdnQ6/Xm20rLS1FTk4ONC5YhPm7776DEALR0dFm24uLi1G/fn1TPa+//jo2btyIc+fOobi4GMXFxahTp47Zezp16mTxHO3atTN936RJEwDAxYsXERoaiqysLGRmZppajsbz3bhxA9euXcNPP/2E0NBQs59FTExM9T50JcrWW6dOHQQGBuLixYsAgGPHjqFnz552LwZd1k8//YSYmBhIkmTa1r17d1y5cgU6nQ6hoaEV6gAM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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fn = 'func2'\n", "\n", "f,axes = plt.subplots(1,1, figsize=(5,5), sharey=True)\n", "plt.suptitle( fn )\n", "\n", "func, meta = extract_entity_function(node=fn, model=model, data=data, layer=0)\n", "n_inputs = func.lin_in.weight.data.shape[1]\n", "inp = torch.randn(100, n_inputs)\n", "out = func(inp)\n", "\n", "if fn in special_functions: \n", " out_true = [special_functions[fn](np.array(x)) for x in inp]\n", "else: \n", " out_true = [x for x in inp]\n", " \n", "plt.plot(inp, out_true, 'r.', label='true function')\n", "plt.plot(inp.detach().cpu().numpy().ravel(), out.detach().cpu().numpy().ravel(), 'k.', label='learned function')\n", "\n", "plt.xlabel(f'{fn} input')\n", "plt.ylabel(f'{fn} output')\n", "plt.legend()\n", "plt.show() " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "gsnn", "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.6" } }, "nbformat": 4, "nbformat_minor": 2 }