{ "cells": [ { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The autoreload extension is already loaded. To reload it, use:\n", " %reload_ext autoreload\n" ] } ], "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": 60, "metadata": {}, "outputs": [ { "data": { "image/png": "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oYCpMU49jkVy2pff8N38f8PL+Sn5E+VX7H8iw8X+zzq9vxPIx6jTNLgQE487cUnZvl9g+vzlbCxQ275gvtnnT2Qo2P9EhstQ+z87eS1fB8B0iepU3I5NxK3YRKg1bzZXAKARRQj/u5Dj228QE5mACraWKG9rmS9O9SYyZOx/IsNlaP3PAPgBGlFEXEoqYpPViE1WI2hXKMpXrIgqlSvB3MgItuYmsDU3gY2Zsd5f4ZuIMnq3/w8e+QcyExM0btiA/U+Uz73b/2cvXsLDR4/g4uyUr/qfATCLSpYsiYEDB2LatGlSl0JEOtauXTsAQHBwsMSVEJGuzZgxA6tXr8bDhw+lLiVHZSev6c+ObSIiIiLKEQyARERERAaGAZCIiIjIwDAAEhERERkYBkAiIiIiA8MASERERGRgGACJiIiIDAwDIBEREZGBYQAkIiIiMjAMgEREREQGhgGQiIiIyMAwABIREREZGAZAIiIiIgPDAEhERERkYBgAiYiIiAwMAyARERGRgWEAJCIiIjIwDIBEREREBoYBkIiIiMjAMAASERERGRgGQCIiIiIDwwBIREREZGAYAImIiIgMDAMgERERkYFhACQiIiIyMAyARERERAaGAZCIiIjIwDAAEhERERkYBkAiIiIiA8MASERERGRgGACJiIiIDAwDIBEREZGBYQAkIiIiMjAMgEREREQGhgGQiIiIyMAwABIREREZGAZAIiIiIgPDAEhERERkYBgAiYiIiAwMAyARERGRgWEAJCIiIjIwDIBEREREBoYBkIiIiMjAMAASERERGRgGQCIiIiIDwwBIREREZGAYAImIiIgMDAMgERERkYFhACQiIiIyMAyARERERAaGAZCIiIjIwDAAEhERERkYBkAiIiIiA8MASERERGRgGACJiIiIDAwDIBEREZGBYQAkIiIiMjAMgEREREQGhgGQiIiIyMAwABIREREZGAZAIiIiIgPDAEhERERkYBgAiYiIiAwMAyARERGRgWEAJCIiIjIwDIBEREREBoYBkIiIiMjAMAASERERGRgGQCIiIiIDwwBIREREZGAYAImIiIgMDAMgERERkYFhACQiIiIyMAyARERERAaGAZCIiIjIwDAAEhERERkYBkAiIiIiA8MASERERGRgGACJiIiIDAwDIBEREZGBMYgA+OjRI/j7+2dp3hcvXmDjxo25XBER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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": 61, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/tmp/ipykernel_4829/2730712319.py:1: DeprecationWarning: __array_wrap__ must accept context and return_scalar arguments (positionally) in the future. (Deprecated NumPy 2.0)\n", " special_functions = {'func1': lambda x: -np.mean(x), 'func2':lambda x: np.sum([np.exp(xx) for xx in x]),\n" ] } ], "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": 97, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "n params 11276\n", "iter: 999 | loss: 0.062\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", " 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": 98, "metadata": {}, "outputs": [], "source": [ "model = model.eval() " ] }, { "cell_type": "code", "execution_count": 99, "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": "iVBORw0KGgoAAAANSUhEUgAAAb0AAAHyCAYAAAB/IBD9AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAT+xJREFUeJzt3Xtc0/X+B/DXdzMQFfF41wbzAlZmmCkJGMqhk5iXo3aOl44Z1g5gamnmJUtLLUPDS3bRA7aft05eOqmVpzRLNBNUtMxMq2EgfhOPZQlqhbp9f3/MTcY23GDbd9v39Xw8eOC+3+++ezOBN5/b+yNIkiSBiIhIAVRyB0BEROQrTHpERKQYTHpERKQYTHpERKQYTHpERKQYTHpERKQYTHpERKQYTHpERKQYTHpERKQYTHpEXrJhwwbcfvvtCAsLgyAIOHz4sGyxXLx4EZMmTULbtm1Rv3593HnnnVi/fr1s8RDJpZ7cARAFo59++gmjR49Gv379sGzZMoSGhqJTp06yxfPAAw+gsLAQ8+fPR6dOnfD222/jwQcfhMlkwj/+8Q/Z4iLyNYG1N4k8b+/evbjnnnuwYcMGDB8+XNZYPvzwQwwYMMCa6Cz69u2Lb775BqWlpVCr1TJGSOQ77N4k8rAxY8bgnnvuAQCMGDECgiAgOTnZ+uHo+nbt2lkfl5SUQBAELFy4EIsXL0b79u3RqFEjJCQkYN++fXbP379/PwYNGoRmzZqhfv366NixIyZNmmQ9v3nzZjRq1AjDhg2zed4jjzyC06dPY//+/R75uokCAZMekYfNmjULb7zxBgDgpZdeQkFBAZYtW+b2fd544w3s2LEDr7zyCv7973/j0qVL6N+/P8rLy63XbN++HUlJSSgtLcXixYvx0UcfYebMmfjf//5nvebo0aO47bbbUK+e7WhGbGys9TyRUnBMj8jDOnbsiM6dOwMAYmJiEB8fX6v7hIeHY+vWrdaux7Zt2+Luu+/GRx99hJEjRwIAxo8fj6ioKOzfvx/169e3PveRRx6x/vvcuXPo0KGD3f2bNm1qPU+kFGzpEfmpAQMG2Iy1WVpmJ0+eBAB8//33OHHiBHQ6nU3Cc0QQhFqdIwo2THpEfqpZs2Y2j0NDQwEAv//+OwDzDFEA0Gg0N7yPo9bcL7/8AuB6i49ICZj0iHykfv36qKystDv+888/1+p+LVq0AACIoljjdXfccQeOHz+Oq1ev2hz/+uuvAQBdunSp1esTBSImPSIfadeuHb7//nubxHfu3Dnk5+fX6n6dOnVCx44d8X//938Ok6nF0KFDcfHiRbz77rs2x1evXo22bduiZ8+etXp9okDEiSxEPjJ69Gjk5OTgoYceQnp6Os6dO4eXX34ZjRs3rvU933jjDQwaNAjx8fF48sknERUVhdLSUmzfvh3//ve/AQD3338/7rvvPjz22GOoqKhAdHQ01q1bh23btuGtt97iGj1SFLb0iHykV69eWL16Nb755hsMHjwYL774ImbMmOFw7Z6rUlNT8dlnn6FNmzZ44okn0K9fP8ydOxetWrWyuW7Tpk0YPXo0nnvuOfTr1w/79+/HunXrMGrUqDp+VUSBhRVZiIhIMdjSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixWDSIyIixagndwB1YTKZcPr0aYSHh0MQBLnDISIimUiShAsXLqBt27ZQqZy35wI66Z0+fRqRkZFyh0FERH7i1KlT0Gg0Ts8HdNILDw8HYP4iGzduLHM0REQkl4qKCkRGRlrzgjMBnfQsXZqNGzdm0iMiohsOdXEiCxERKQaTHhERKYbsSe/HH3/EQw89hGbNmqFBgwa48847cejQIbnDIiKiICTrmN6vv/6KXr164c9//jM++ugjtGzZEidOnECTJk089hqSJOHq1aswGo0euyeRO9RqNerVq8dlNUR+QNakt2DBAkRGRmLlypXWY+3atfPY/S9fvoyysjL89ttvHrsnUW00aNAAbdq0QUhIiNyhECmaIEmSJNeLd+7cGampqRBFEbt378bNN9+McePGIT093eH1lZWVqKystD62TFEtLy+3m71pMplgMBigVqvRokULhISE8C9t8jlJknD58mX89NNPMBqNiImJqXHhLBHVTkVFBSIiIhzmg6pkben98MMP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j/33v/+VAFjft6SkJOmll16yed7atWulNm3aSJIkSdu3b7d7Pz766CMJgLR582an8S1ZskTSarU2x7RarbRkyRKbY127dpWef/5562MA0syZM62PL168KAmCIH300UeSJEnSjBkzpPbt20uXL192+LppaWnS4MGDbY4VFxdLAKQvv/xSkiRJeuaZZ6RbbrlFMplM1mveeOMNqVGjRpLRaJQkyfx+3nPPPTb3iYuLk6ZPn+7wdT31/UhEjtWUD6rimN4NGAwGmEwmm2NGoxFFRUXQ+GBT2S+++AKSJKFTp042xysrK9GsWTNrPPPnz8eGDRvw448/orKyEpWVlWjYsKHNc3r06OHwNWJjY63/btOmDQDg7NmziIqKwqFDh1BYWGht2Vle748//sBvv/2G48ePIyoqyua9SEhIqNsXfQNV423YsCHCw8Nx9uxZAOZd45OSktze3Laq48ePIyEhAYIgWI/16tULFy9ehCiKiIqKsosDML93ljiIyD8x6d1ATEwMVCqVTeJTq9WIjo72yeubTCao1WocOnQIarXa5lyjRo0AmDd3XbJkCV555RXccccdaNiwISZNmoTLly/bXF89CVpUTRCWX/SWr9dkMmHOnDl44IEH7J5Xv359SA62Y6yaLNyhUqns7nflypUa47W8niXesLCwWr12VZIk2X0NlriqHq8pDiLyT0x6N6DRaJCbm4vMzEwYjUao1Wrk5OT4pJUHAN26dYPRaMTZs2eRlJTk8Jo9e/Zg8ODBeOihhwCYE5XBYMBtt91W59e/66678N133zlN8p07d0ZpaSlOnz6Ntm3bAgAKCgpq9VotWrRAWVmZ9XFFRQWKi4vdukdsbCxWr16NK1euOGzthYSEwGg01niPzp07491337VJfvn5+QgPD8fNN9/sVjxE5F84kcUFOp0OJSUlyMvLQ0lJCXQ6nc9eu1OnThg1ahQefvhhbNq0CcXFxSgsLMSCBQvw4YcfAgCio6OxY8cO5Ofn4/jx48jMzMSZM2c88vrPPfcc1qxZg9mzZ+Obb77B8ePHsWHDBsycORMA8Je//AW33HILHn74YXz11VfYs2cPnn322Vq9VkpKCtauXYs9e/bg6NGjSEtLs2vd3siECRNQUVGBkSNH4uDBgzAYDFi7dq11Rmq7du1w5MgRfPfdd/j5558dtiTHjRuHU6dO4fHHH8e3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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": 100, "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": "iVBORw0KGgoAAAANSUhEUgAAAckAAAHyCAYAAACAgjUfAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAATCxJREFUeJzt3XtcVGX+B/DPmVFQDDEvlTYwqIyVmWXeUkMRd8NVK93Ny26pFAmW1xQ118pLFy+gZlYGOqvk7qa22UXLzFU084qmuaXZ4A/EI7hmJXgp0Jnz++PsjAzMGWZgZs5cPu/XixfOmWHmOwV8eJ7znO8jSJIkgYiIiKrRqF0AERGRv2JIEhERKWBIEhERKWBIEhERKWBIEhERKWBIEhERKWBIEhERKWBIEhERKWBIEhERKWBIEvmB9evX4+6770bDhg0hCAKOHj2qSh2XLl3C9OnT8dBDD6FFixYQBAFz5sxRpRYif8CQJFLZjz/+iJEjR6Jt27b4/PPPsW/fPrRr106VWn766SdkZ2ejvLwcgwcPVqUGIn9ST+0CiELdDz/8gGvXruGJJ55Anz59VK1Fr9fjl19+gSAIuHDhAlatWqVqPURq40iSSEXJycl48MEHAQDDhw+HIAhISEiwfTh6fGxsrO12YWEhBEFAZmYmlixZgtatW+Omm25Cjx49sH///mpff+DAATz88MNo1qwZGjRogLZt22Ly5Mm2+wVBgCAInn6bRAGLIUmkohdffBFvvfUWAOC1117Dvn378Pbbb7v9PG+99Ra2bduG119/Hf/4xz9w5coVDBgwAKWlpbbHbN26FfHx8SgqKsKSJUuwZcsWvPDCC/jvf//rsfdDFGw43UqkorZt26J9+/YAAIPBgAceeKBWzxMZGYnNmzdDq9UCAFq1aoVu3bphy5YtGDFiBABg3LhxiImJwYEDB9CgQQPb1z755JN1fBdEwYsjSaIgMHDgQFtAAkDHjh0BAKdPnwYgn/c8deoUUlJS7AKSiJxjSBIFgWbNmtndDg8PBwD8+uuvAOQVtACg0+l8WxhRgGNIEvmhBg0aoLy8vNrxCxcu1Or5WrRoAQAQRbFOdRGFGoYkkR+KjY3FDz/8YBeUP/30E/bu3Vur52vXrh3atm2Lv/3tbw7Dl4gc48IdIj80cuRIZGVl4YknnsCYMWPw008/YdGiRWjcuHGtn/Ott97Cww8/jAceeADPPfccYmJiUFRUhK1bt+If//iH7XFbtmzBlStXcOnSJQDA8ePH8a9//QsAMGDAAERERNTtzREFEIYkkR/q1asXcnJysGDBAjz66KNo06YNZs+ejc8++ww7d+6s1XMmJSXhyy+/xLx58zBx4kT89ttv0Ol0eOSRR+we98wzz9gW/ADA+++/j/fffx8AUFBQYHedJlGwEyRJktQugoiIyB/xnCQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZEChiQREZGCemoX4EsWiwXFxcWIjIyEIAhql0NERCqQJAmXLl1Cq1atoNE4HyuGVEgWFxcjOjpa7TKIiMgPnDlzBjqdzuljQiokIyMjAcj/YRo3bqxyNUREpIaysjJER0fbMsGZkApJ6xRr48aNGZJERCHOldNuXLhDRESkgCFJRESkgCFJRESkgCFJRESkgCFJRESkgCFJRESkgCFJRESkgCFJRESkgCFJRESkgCFJRESkgCFJRESkgCFJREQBQxRF5ObmQhRFn7weQ5KIiAKC0WiEXq9HYmIi9Ho9jEaj11+TIUlERH4vLy8PqampsFgsAACLxYK0tDSvjygZkkRE5NeMRiO6d+9uC0grs9mM/Px8r742Q5KIiPyWKIpITU2FJEnV7tNqtYiLi/Pq6zMkiYjIb5lMpmojSADQaDTIysqCTqfz6uvX8+qzExER1YHBYIBGo7ELSo1Gg/3796Nr165ef32OJImIyG/pdDpkZ2dDq9UCkKdYs7OzfRKQACBIjiZ6g1RZWRmioqJQWlqKxo0bq10OERG5SBRF5OfnIy4urs5TrO5kAadbiYjI7+l0Oq+ff3QkYKdb58+fD0EQMHnyZLVLISKiIBWQIZmXl4fs7Gx07NhR7VKIiCiIBVxIXr58GY8//jhWrlyJm2++We1yiIgoiAVcSI4bNw4DBw7E7373uxof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OHr0KPr164e7774b+/btw1dffYWHH34YZrO5xvdudfjwYQwbNgwjRozAf/7zH8yZMwcvvviiLaytFi9ejC5duuDIkSN49tln8cwzz+D777936734m4Cbbi0vL0f37t3xzTff4MiRI7jvvvvULomIPMlkuhGQVmYzkJ/vlWnXqKgohIWFISIiwuEU47x58/D73//e5ee7cuUKlixZgh07dqBHjx4AgDZt2uCrr75CVlYW+vTpU+1rmjZtioiIiFpPc6anp2PgwIEAgLlz5+Luu+9Gfn4+7rzzTixatAhdunTB22+/bXv83Xffbfu3s/dutWTJEvTr1w8vvvgiAKBdu3Y4fvw4MjIykJycbHvcgAED8OyzzwIAZsyYgaVLl2Lnzp2488473X5P/iLgRpLTp09Hq1at1C6DiLzFYACqtrPTagGVNgzv0qWLW48/fvw4fvvtN/z+97/HTTfdZPt49913cerUKa/UWHmE27JlSwDA+fPnAdwYSdbFiRMn0KtXL7tjvXr1gslksrtYv3IdgiDgtttus9URqAJqJLllyxZ88cUX+OCDD7Blyxa1yyEib9DpgOxseYrVbJYDMitLtcU7jRo1srut0WhQdRvea9eu2f5tbez+6aef4vbbb7d7XHh4uFuvLQiC09eyqtx2zXoRvbWOhg0buvWajkiSVO3ifEdbEVdt/yYIQsA3ug+YkPzvf/+LMWPG4KOPPnK5J2R5eTnKy8ttt8vKyrxVHhF5UkoKkJQkT7HGxXk9IMPCwlxuX9aiRQt8++23dseOHj1qC4j27dsjPDwcRUVFDqdW3dGiRQuUlJTYbptMJly9etWt5+jYsSO2b9+OuXPnOrzflffevn17fPXVV3bH9u7di3bt2kGr1bpVT6AJiOlWSZKQnJyMsWPHujX1MX/+fERFRdk+HJ2QJiI/pdMBCQk+GUHGxsbiwIEDKCwsxIULF5yOfhITE3Ho0CG8++67MJlMmD17tl1oRkZGIj09Hc899xxycnJw6tQpHDlyBG+99RZycnLcqisxMRFvvvkmvv76axw6dAhjx451u1n3zJkzkZeXh2effRbHjh3D999/jxUrVuDChQsuv/epU6di+/btePnll/HDDz8gJycHb775JtLT092qJRCpGpJz5syxLTtW+jh06BCWL1+OsrIyzJw5063nnzlzJkpLS20fZ86c8dI7IaJAlp6eDq1Wi/bt26NFixYoKipSfGxSUhJefPFFTJ8+HV27dsWlS5cwatQou8e8/PLLeOmllzB//nzcddddSEpKwqZNm9C6dWu36lq8eDGio6PRu3dv/OUvf0F6errbu6u0a9cOX3zxBb755ht069YNPXr0wMcff2y73tOV937//fdjw4YNWLduHTp06ICXXnoJ8+bNs1u0E6wEydHEso9cuHDB9teMktjYWIwYMQKbNm2ymxM3m83QarV4/PHHXf7rrKysDFFRUSgtLUXjxo3rVDsRVffbb7+hoKAArVu3RoMGDdQuh0KYs+9Fd7JA1XOSzZs3R/PmzWt83BtvvIFXXnnFdru4uBhJSUlYv349unfv7s0SiYgohAXEwp2YmBi72zfddBMAoG3bttD5QbsqIiIKTgGxcIeIiEgNATGSrCo2NtbhNTpERESexJEkERGRAoYkERGRAoYkERGRAoYkERGRAoYkERGRAoYkEYW8hIQETJ48We0y6kQQBHz00UeK90uShNTUVDRt2hSCIODo0aM+q62qwsJC1WtwVUBeAkJERO75/PPPsWbNGuzcuRNt2rRxqduZJyQnJ+PixYt2AR4dHY2SkhKf1VAXDEki8kuiKMJkMsFgMARFZ62KigqEhYWp9vqnTp1Cy5Yt0bNnT9VqsNJqtbjtttvULsMlnG4lIr9jNBqh1+uRmJgIvV4Po9Ho09evqKjA9OnTcfvtt6NRo0bo3r07du7cabv/p59+wp///GfodDpERETgnnvuwXvvvWf3HAkJCRg/fjymTJmC5s2b4/e//z127twJQRCwfft2dOnSBREREejZsydOnjxp97WbNm1C586d0aBBA7Rp0wZz587F9evXbfebTCb07t0bDRo0QPv27bFt2zan7yc5ORkTJkxAUVERBEFAbGwsALkxy+uvv2732Pvuuw9z5syx3RYEAatWrcKQIUMQEREBg8GATz75xO5rvvvuOwwcOBCNGzdGZGQk4uPjcerUKcyZMwc5OTn4+OOPbTs77dy50+F0665du9CtWzeEh4ejZcuWeP755+3ec0JCAiZOnIjp06ejadOmuO222+zq9BaGJBH5FVEUkZqaatvX0GKxIC0tDaIo+qyGJ598Env27MG6detw7NgxDB06FP3794fJZAIg7zDRuXNnbN68Gd9++y1SU1MxcuRIHDhwwO55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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": 101, "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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48YW+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": 52, "metadata": {}, "outputs": [], "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": 53, "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": 54, "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": 55, "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": 56, "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": 57, "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": 58, "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": [] } ], "metadata": { "kernelspec": { "display_name": "gsnn-mds", "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.12.11" } }, "nbformat": 4, "nbformat_minor": 2 }