{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Interaction Network GNN\n",
"\n",
"Now we will look at graph neural networks using the PyTorch Geometric library: . See {cite:p}`PyTorchGeometric` for more details."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"# For Colab\n",
"!pip install torch_geometric\n",
"!pip install torch_sparse\n",
"!pip install torch_scatter\n",
"\n",
"import torch\n",
"import torch_geometric\n",
"\n",
"device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n",
"from tqdm.notebook import tqdm\n",
"import numpy as np\n",
"\n",
"local = False"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# For Colab\n",
"\n",
"!pip install wget\n",
"import wget\n",
"\n",
"!pip install -U PyYAML\n",
"!pip install uproot\n",
"!pip install awkward\n",
"!pip install mplhep"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [],
"source": [
"import yaml\n",
"import os.path\n",
"\n",
"# WGET for colab\n",
"if not os.path.exists(\"definitions.yml\"):\n",
" url = \"https://raw.githubusercontent.com/jmduarte/iaifi-summer-school/main/book/definitions.yml\"\n",
" definitionsFile = wget.download(url)\n",
"\n",
"with open(\"definitions.yml\") as file:\n",
" # The FullLoader parameter handles the conversion from YAML\n",
" # scalar values to Python the dictionary format\n",
" definitions = yaml.load(file, Loader=yaml.FullLoader)\n",
"\n",
"\n",
"# You can test with using only 4-vectors by using:\n",
"# if not os.path.exists(\"definitions_lorentz.yml\"):\n",
"# url = \"https://raw.githubusercontent.com/jmduarte/iaifi-summer-school/main/book/definitions_lorentz.yml\"\n",
"# definitionsFile = wget.download(url)\n",
"# with open('definitions_lorentz.yml') as file:\n",
"# # The FullLoader parameter handles the conversion from YAML\n",
"# # scalar values to Python the dictionary format\n",
"# definitions = yaml.load(file, Loader=yaml.FullLoader)\n",
"\n",
"features = definitions[\"features\"]\n",
"spectators = definitions[\"spectators\"]\n",
"labels = definitions[\"labels\"]\n",
"\n",
"nfeatures = definitions[\"nfeatures\"]\n",
"nspectators = definitions[\"nspectators\"]\n",
"nlabels = definitions[\"nlabels\"]\n",
"ntracks = definitions[\"ntracks\"]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Graph datasets\n",
"Here we have to define the graph dataset. We do this in a separate class following this example: https://pytorch-geometric.readthedocs.io/en/latest/notes/create_dataset.html#creating-larger-datasets\n",
"\n",
"Formally, a graph is represented by a triplet $\\mathcal G = (\\mathbf{u}, V, E)$, consisting of a graph-level, or *global*, feature vector $\\mathbf{u}$, a set of $N^v$ nodes $V$, and a set of $N^e$ edges $E$.\n",
"The nodes are given by $V = \\{\\mathbf{v}_i\\}_{i=1:N^v}$, where $\\mathbf{v}_i$ represents the $i$th node's attributes.\n",
"The edges connect pairs of nodes and are given by $E = \\{\\left(\\mathbf{e}_k, r_k, s_k\\right)\\}_{k=1:N^e}$, where $\\mathbf{e}_k$ represents the $k$th edge's attributes, and $r_k$ and $s_k$ are the indices of the \"receiver\" and \n",
"\"sender\" nodes, respectively, connected by the $k$th edge (from the sender node to the receiver node).\n",
"The receiver and sender index vectors are an alternative way of encoding the directed adjacency matrix.\n",
"\n",
""
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [],
"source": [
"# If in colab\n",
"if not os.path.exists(\"GraphDataset.py\"):\n",
" urlDSD = \"https://raw.githubusercontent.com/jmduarte/iaifi-summer-school/main/book/GraphDataset.py\"\n",
" DSD = wget.download(urlDSD)\n",
"if not os.path.exists(\"utils.py\"):\n",
" urlUtils = \"https://raw.githubusercontent.com/jmduarte/iaifi-summer-school/main/book/utils.py\"\n",
" utils = wget.download(urlUtils)\n",
"\n",
"\n",
"from GraphDataset import GraphDataset\n",
"\n",
"\n",
"# For Colab\n",
"if not os.path.exists(\"ntuple_merged_90.root\"):\n",
" urlFILE = \"http://opendata.cern.ch/eos/opendata/cms/datascience/HiggsToBBNtupleProducerTool/HiggsToBBNTuple_HiggsToBB_QCD_RunII_13TeV_MC/train/ntuple_merged_90.root\"\n",
" dataFILE = wget.download(urlFILE)\n",
"file_names = [\"ntuple_merged_90.root\"]\n",
"\n",
"##If you pulled github locally\n",
"# if local:\n",
"# file_names = [\n",
"# \"/teams/DSC180A_FA20_A00/b06particlephysics/train/ntuple_merged_10.root\"\n",
"# ]\n",
"# file_names_test = [\n",
"# \"/teams/DSC180A_FA20_A00/b06particlephysics/test/ntuple_merged_0.root\"\n",
"# ]\n",
"# else:\n",
"# file_names = [\n",
"# \"root://eospublic.cern.ch//eos/opendata/cms/datascience/HiggsToBBNtupleProducerTool/HiggsToBBNTuple_HiggsToBB_QCD_RunII_13TeV_MC/train/ntuple_merged_10.root\"\n",
"# ]\n",
"# file_names_test = [\n",
"# \"root://eospublic.cern.ch//eos/opendata/cms/datascience/HiggsToBBNtupleProducerTool/HiggsToBBNTuple_HiggsToBB_QCD_RunII_13TeV_MC/test/ntuple_merged_0.root\"\n",
"# ]\n",
"\n",
"graph_dataset = GraphDataset(\n",
" \"gdata_train\",\n",
" features,\n",
" labels,\n",
" spectators,\n",
" start_event=0,\n",
" stop_event=8000,\n",
" n_events_merge=1,\n",
" file_names=file_names,\n",
")\n",
"\n",
"test_dataset = GraphDataset(\n",
" \"gdata_test\",\n",
" features,\n",
" labels,\n",
" spectators,\n",
" start_event=8001,\n",
" stop_event=10001,\n",
" n_events_merge=1,\n",
" file_names=file_names,\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Graph neural network\n",
"\n",
"Here, we recapitulate the \"graph network\" (GN) formalism {cite:p}`battaglia2018relational`, which generalizes various GNNs and other similar methods.\n",
"GNs are graph-to-graph mappings, whose output graphs have the same node and edge structure as the input. \n",
"Formally, a GN block contains three \"update\" functions, $\\phi$, and three \"aggregation\" functions, $\\rho$.\n",
"The stages of processing in a single GN block are:\n",
"\n",
"$\n",
"\\begin{align}\n",
" \\mathbf{e}'_k &= \\phi^e\\left(\\mathbf{e}_k, \\mathbf{v}_{r_k}, \\mathbf{v}_{s_k}, \\mathbf{u} \\right) & \\mathbf{\\bar{e}}'_i &= \\rho^{e \\rightarrow v}\\left(E'_i\\right) & \\text{(Edge block),}\\\\\n",
" \\mathbf{v}'_i &= \\phi^v\\left(\\mathbf{\\bar{e}}'_i, \\mathbf{v}_i, \\mathbf{u}\\right) & \n",
" \\mathbf{\\bar{e}}' &= \\rho^{e \\rightarrow u}\\left(E'\\right) & \\text{(Node block),}\\\\\n",
" \\mathbf{u}' &= \\phi^u\\left(\\mathbf{\\bar{e}}', \\mathbf{\\bar{v}}', \\mathbf{u}\\right) & \n",
" \\mathbf{\\bar{v}}' &= \\rho^{v \\rightarrow u}\\left(V'\\right) &\\text{(Global block).}\n",
" \\label{eq:gn-functions}\n",
"\\end{align}\n",
"$\n",
"\n",
"where $E'_i = \\left\\{\\left(\\mathbf{e}'_k, r_k, s_k \\right)\\right\\}_{r_k=i,\\; k=1:N^e}$ contains the updated edge features for edges whose receiver node is the $i$th node, $E' = \\bigcup_i E_i' = \\left\\{\\left(\\mathbf{e}'_k, r_k, s_k \\right)\\right\\}_{k=1:N^e}$ is the set of updated edges, and $V'=\\left\\{\\mathbf{v}'_i\\right\\}_{i=1:N^v}$ is the set of updated nodes.\n",
"\n",
"\n",
"\n",
"We will define an interaction network model similar to Ref. {cite:p}`Moreno:2019neq`, but just modeling the particle-particle interactions. It will take as input all of the tracks (with 48 features) without truncating or zero-padding. Another modification is the use of batch normalization {cite:p}`bn` layers to improve the stability of the training."
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
"import torch.nn as nn\n",
"import torch.nn.functional as F\n",
"import torch_geometric.transforms as T\n",
"from torch_geometric.nn import EdgeConv, global_mean_pool\n",
"from torch.nn import Sequential as Seq, Linear as Lin, ReLU, BatchNorm1d\n",
"from torch_scatter import scatter_mean\n",
"from torch_geometric.nn import MetaLayer\n",
"\n",
"inputs = 48\n",
"hidden = 128\n",
"outputs = 2\n",
"\n",
"\n",
"class EdgeBlock(torch.nn.Module):\n",
" def __init__(self):\n",
" super(EdgeBlock, self).__init__()\n",
" self.edge_mlp = Seq(\n",
" Lin(inputs * 2, hidden), BatchNorm1d(hidden), ReLU(), Lin(hidden, hidden)\n",
" )\n",
"\n",
" def forward(self, src, dest, edge_attr, u, batch):\n",
" out = torch.cat([src, dest], 1)\n",
" return self.edge_mlp(out)\n",
"\n",
"\n",
"class NodeBlock(torch.nn.Module):\n",
" def __init__(self):\n",
" super(NodeBlock, self).__init__()\n",
" self.node_mlp_1 = Seq(\n",
" Lin(inputs + hidden, hidden),\n",
" BatchNorm1d(hidden),\n",
" ReLU(),\n",
" Lin(hidden, hidden),\n",
" )\n",
" self.node_mlp_2 = Seq(\n",
" Lin(inputs + hidden, hidden),\n",
" BatchNorm1d(hidden),\n",
" ReLU(),\n",
" Lin(hidden, hidden),\n",
" )\n",
"\n",
" def forward(self, x, edge_index, edge_attr, u, batch):\n",
" row, col = edge_index\n",
" out = torch.cat([x[row], edge_attr], dim=1)\n",
" out = self.node_mlp_1(out)\n",
" out = scatter_mean(out, col, dim=0, dim_size=x.size(0))\n",
" out = torch.cat([x, out], dim=1)\n",
" return self.node_mlp_2(out)\n",
"\n",
"\n",
"class GlobalBlock(torch.nn.Module):\n",
" def __init__(self):\n",
" super(GlobalBlock, self).__init__()\n",
" self.global_mlp = Seq(\n",
" Lin(hidden, hidden), BatchNorm1d(hidden), ReLU(), Lin(hidden, outputs)\n",
" )\n",
"\n",
" def forward(self, x, edge_index, edge_attr, u, batch):\n",
" out = scatter_mean(x, batch, dim=0)\n",
" return self.global_mlp(out)\n",
"\n",
"\n",
"class InteractionNetwork(torch.nn.Module):\n",
" def __init__(self):\n",
" super(InteractionNetwork, self).__init__()\n",
" self.interactionnetwork = MetaLayer(EdgeBlock(), NodeBlock(), GlobalBlock())\n",
" self.bn = BatchNorm1d(inputs)\n",
"\n",
" def forward(self, x, edge_index, batch):\n",
"\n",
" x = self.bn(x)\n",
" x, edge_attr, u = self.interactionnetwork(x, edge_index, None, None, batch)\n",
" return u\n",
"\n",
"\n",
"model = InteractionNetwork().to(device)\n",
"optimizer = torch.optim.Adam(model.parameters(), lr=1e-2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Define training loop"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [],
"source": [
"@torch.no_grad()\n",
"def test(model, loader, total, batch_size, leave=False):\n",
" model.eval()\n",
"\n",
" xentropy = nn.CrossEntropyLoss(reduction=\"mean\")\n",
"\n",
" sum_loss = 0.0\n",
" t = tqdm(enumerate(loader), total=total / batch_size, leave=leave)\n",
" for i, data in t:\n",
" data = data.to(device)\n",
" y = torch.argmax(data.y, dim=1)\n",
" batch_output = model(data.x, data.edge_index, data.batch)\n",
" batch_loss_item = xentropy(batch_output, y).item()\n",
" sum_loss += batch_loss_item\n",
" t.set_description(\"loss = %.5f\" % (batch_loss_item))\n",
" t.refresh() # to show immediately the update\n",
"\n",
" return sum_loss / (i + 1)\n",
"\n",
"\n",
"def train(model, optimizer, loader, total, batch_size, leave=False):\n",
" model.train()\n",
"\n",
" xentropy = nn.CrossEntropyLoss(reduction=\"mean\")\n",
"\n",
" sum_loss = 0.0\n",
" t = tqdm(enumerate(loader), total=total / batch_size, leave=leave)\n",
" for i, data in t:\n",
" data = data.to(device)\n",
" y = torch.argmax(data.y, dim=1)\n",
" optimizer.zero_grad()\n",
" batch_output = model(data.x, data.edge_index, data.batch)\n",
" batch_loss = xentropy(batch_output, y)\n",
" batch_loss.backward()\n",
" batch_loss_item = batch_loss.item()\n",
" t.set_description(\"loss = %.5f\" % batch_loss_item)\n",
" t.refresh() # to show immediately the update\n",
" sum_loss += batch_loss_item\n",
" optimizer.step()\n",
"\n",
" return sum_loss / (i + 1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Define training, validation, testing data generators"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"7501\n",
"6001\n",
"1500\n",
"1886\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/wmccorma/miniconda3/envs/ml-iaifi/lib/python3.9/site-packages/torch_geometric/deprecation.py:12: UserWarning: 'data.DataListLoader' is deprecated, use 'loader.DataListLoader' instead\n",
" warnings.warn(out)\n"
]
}
],
"source": [
"from torch_geometric.data import Data, DataListLoader, Batch\n",
"from torch.utils.data import random_split\n",
"\n",
"\n",
"def collate(items):\n",
" l = sum(items, [])\n",
" return Batch.from_data_list(l)\n",
"\n",
"\n",
"torch.manual_seed(0)\n",
"valid_frac = 0.20\n",
"full_length = len(graph_dataset)\n",
"valid_num = int(valid_frac * full_length)\n",
"batch_size = 32\n",
"\n",
"train_dataset, valid_dataset = random_split(\n",
" graph_dataset, [full_length - valid_num, valid_num]\n",
")\n",
"\n",
"train_loader = DataListLoader(\n",
" train_dataset, batch_size=batch_size, pin_memory=True, shuffle=True\n",
")\n",
"train_loader.collate_fn = collate\n",
"valid_loader = DataListLoader(\n",
" valid_dataset, batch_size=batch_size, pin_memory=True, shuffle=False\n",
")\n",
"valid_loader.collate_fn = collate\n",
"test_loader = DataListLoader(\n",
" test_dataset, batch_size=batch_size, pin_memory=True, shuffle=False\n",
")\n",
"test_loader.collate_fn = collate\n",
"\n",
"\n",
"train_samples = len(train_dataset)\n",
"valid_samples = len(valid_dataset)\n",
"test_samples = len(test_dataset)\n",
"print(full_length)\n",
"print(train_samples)\n",
"print(valid_samples)\n",
"print(test_samples)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Train"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "413e118e0e9041beb711de477240779e",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
" 0%| | 0/10 [00:00, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
" 0%| | 0/187.53125 [00:00, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
" 0%| | 0/46.875 [00:00, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch: 00, Training Loss: 0.2342\n",
" Validation Loss: 0.1417\n",
"New best model saved to: interactionnetwork_best.pth\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
" 0%| | 0/187.53125 [00:00, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
" 0%| | 0/46.875 [00:00, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch: 01, Training Loss: 0.1757\n",
" Validation Loss: 0.1430\n",
"Stale epoch\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
" 0%| | 0/187.53125 [00:00, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
" 0%| | 0/46.875 [00:00, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch: 02, Training Loss: 0.1666\n",
" Validation Loss: 0.1561\n",
"Stale epoch\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
" 0%| | 0/187.53125 [00:00, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
" 0%| | 0/46.875 [00:00, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch: 03, Training Loss: 0.1511\n",
" Validation Loss: 0.1233\n",
"New best model saved to: interactionnetwork_best.pth\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
" 0%| | 0/187.53125 [00:00, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
" 0%| | 0/46.875 [00:00, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch: 04, Training Loss: 0.1496\n",
" Validation Loss: 0.1160\n",
"New best model saved to: interactionnetwork_best.pth\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
" 0%| | 0/187.53125 [00:00, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
" 0%| | 0/46.875 [00:00, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch: 05, Training Loss: 0.1427\n",
" Validation Loss: 0.1227\n",
"Stale epoch\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
" 0%| | 0/187.53125 [00:00, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
" 0%| | 0/46.875 [00:00, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch: 06, Training Loss: 0.1476\n",
" Validation Loss: 0.1659\n",
"Stale epoch\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
" 0%| | 0/187.53125 [00:00, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
" 0%| | 0/46.875 [00:00, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch: 07, Training Loss: 0.1377\n",
" Validation Loss: 0.1193\n",
"Stale epoch\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
" 0%| | 0/187.53125 [00:00, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
" 0%| | 0/46.875 [00:00, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch: 08, Training Loss: 0.1410\n",
" Validation Loss: 0.1422\n",
"Stale epoch\n"
]
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "733d0be83d4e44868317a63e48abf3bc",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
" 0%| | 0/187.53125 [00:00, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "ad07b289ae6440cf905aa2a483113210",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
" 0%| | 0/46.875 [00:00, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Epoch: 09, Training Loss: 0.1299\n",
" Validation Loss: 0.1091\n",
"New best model saved to: interactionnetwork_best.pth\n"
]
}
],
"source": [
"import os.path as osp\n",
"\n",
"n_epochs = 10\n",
"stale_epochs = 0\n",
"best_valid_loss = 99999\n",
"patience = 5\n",
"t = tqdm(range(0, n_epochs))\n",
"\n",
"for epoch in t:\n",
" loss = train(\n",
" model,\n",
" optimizer,\n",
" train_loader,\n",
" train_samples,\n",
" batch_size,\n",
" leave=bool(epoch == n_epochs - 1),\n",
" )\n",
" valid_loss = test(\n",
" model,\n",
" valid_loader,\n",
" valid_samples,\n",
" batch_size,\n",
" leave=bool(epoch == n_epochs - 1),\n",
" )\n",
" print(\"Epoch: {:02d}, Training Loss: {:.4f}\".format(epoch, loss))\n",
" print(\" Validation Loss: {:.4f}\".format(valid_loss))\n",
"\n",
" if valid_loss < best_valid_loss:\n",
" best_valid_loss = valid_loss\n",
" modpath = osp.join(\"interactionnetwork_best.pth\")\n",
" print(\"New best model saved to:\", modpath)\n",
" torch.save(model.state_dict(), modpath)\n",
" stale_epochs = 0\n",
" else:\n",
" print(\"Stale epoch\")\n",
" stale_epochs += 1\n",
" if stale_epochs >= patience:\n",
" print(\"Early stopping after %i stale epochs\" % patience)\n",
" break"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Evaluate on testing data"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "d5d757e6dcf445f1b35aa3b7f219fdb3",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
" 0%| | 0/58.9375 [00:00, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# In case you need to load the model from a pth file\n",
"# Trained on all possible inputs (as above in notebook)\n",
"# urlPTH = \"https://raw.githubusercontent.com/jmduarte/iaifi-summer-school/main/book/interactionnetwork_best_Aug1_AllTraining.pth\"\n",
"# pthFile = wget.download(urlPTH)\n",
"# model.load_state_dict(torch.load(\"interactionnetwork_best_Aug1_AllTraining.pth\"))\n",
"# Trained on 4 vector input (different setup)\n",
"# urlPTH = \"https://raw.githubusercontent.com/jmduarte/iaifi-summer-school/main/book/interactionnetwork_best_Aug1_4vec.pth\"\n",
"# pthFile = wget.download(urlPTH)\n",
"# model.load_state_dict(torch.load(\"interactionnetwork_best_Aug1_4vec.pth\"))\n",
"\n",
"model.eval()\n",
"t = tqdm(enumerate(test_loader), total=test_samples / batch_size)\n",
"y_test = []\n",
"y_predict = []\n",
"for i, data in t:\n",
" data = data.to(device)\n",
" batch_output = model(data.x, data.edge_index, data.batch)\n",
" y_predict.append(batch_output.detach().cpu().numpy())\n",
" y_test.append(data.y.cpu().numpy())\n",
"y_test = np.concatenate(y_test)\n",
"y_predict = np.concatenate(y_predict)"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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++4DADz00EPIzc0Nul+fPn1w6aWXAkDU7aiqqoqvkSG8++67eOCBB3D33XfjnHPOAQC0tLRg586d6NOnT9BrF+39/vOf/4Q9/tatWwEAgweHX1mjtrYWubm5yMvL82/r0KEDjj32WNTU1Pi3/frXv0Z9fT1uv/32sMdMBYnKjpIjk/Ozr6V0Ds4xcbUcV0VThQI4B1YvZAuALwB8HPD1bgA7ADT4vj4CYDaAY9yuhlPxBvZYhhVJj6WqaktLi/bo0UMBaF1dnX/7p59+quPHj1cA2q1bN50wYYL27t3bf92m81rGaPb/8MMPFYBed911euyxx2p2draeeuqpWlRUpABURPQnP/lJq+Nff/31CkC/+c1vRn3afsGCBZqTk6MiokOHDtXTTjtNO3XqpAD0K1/5ijY0NKiq6qOPPqqTJk1SANqnTx+dMmWKPvroo1G9VjBTp05VAFpeXq6qqosXLw55baRqfD2W//znPxWATpw4MWy76urqtLKyUg8cOBDFu1E9ePBgVPtH4osvvtBBgwbp6NGj9fDhw/7ttbW1esMNN7T5/2BbtmxZyGsfna666ioFoCtXrtSf/OQnetlll+lNN92kTz75ZKv/+6qqL774ogLQhx56yL/Nzs3eVlNTowUFBfr444/H8pY9kYjsKHkyMb9gp71T9TrK9iBBPZbRFk8v+YrGVwHk+Lb9yFdETvF93cW3rQXAfW43OFVvdkA33nhjm9urr74aWcppLtLCUlV19OjRCkA3bNjg3/bd735XAej111+vX3zxhX/7k08+qVlZWVpYWKiff/55TPuvWrXK/yErKSlpdSq2vLxc8/LytEOHDrpx40b/9vfee087dOigAHT48OH64IMP6vr167WlpaXd9/bxxx9rly5d9Pjjj9d//etf/u27d+/WcePGKQB98MEH23zf3DoV/tlnn2lOTo4ef/zx/oKpvr5e8/LyNCsrSz/++OM2z4mnsJw/f74C0FtuucWV9gezb98+1495//33KwB96623In5OS0uLXnDBBQpAn3jiibD7n3766QpAjznmmDaDcgYOHKirV6/273vkyBH/NcglJSX+a1YHDhzo//999913a1FRkVGnJxORHSVPJuVnF5QmnvZ+9dVX29QmiSoso13ScYSvIfeqaqNv2+8B3Afr2solqloP4CciMhTA3SLyF1V9L8rXMdbc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AP0B1MMaBX4EwNd820fANxk6gFkA7gbwX98+T7k94igVb+B0Q2FFOkG6PVL2hRdeaPXcrKwsHT9+fNBR14sWLdKpU6fq3//+95j237x5s39aocCR6LYHH3xQAehVV13l33bCCSdox44ddd26dSHfT1VVlQLQXr16+bddd911CkDfeOONNvs3NDToN77xDb3hhhtavXe4MCrcfo89evRoNX1OoC+++EK7dOnSZkT+Z599pgA0Ly8v6Khx21e/+tWgI6JnzZrln0qpqakp6HM//fRTPeGEExSALl68OOz7sY8Z7hbNqG57qqAbb7yx3f3OPffciCc2D2X58uX+70kwd911lwLQuXPntnucs846S6dNm9ZqW/fu3dss57h69WoFoH/+859jbnMimDSCndoyLb91uz9rM6o7lZddTKSAusXdeijqJ1inwT/yFZKXBmyfi6PzVx7x/fsTACe63ehUvLGwDC+aJR2HDx/eZm5IewnCO++8s1Vx8u9//1uPO+44zcnJ0f3798e0f+B60aNHj25VPL322mvatWtXzcrKalVs2Sus9O/fX1955ZU276eiosK/itAdd9zh375p0ybNzs7W4uJiXb9+vX97bW2tfwqI2267rc33berUqaG/uRGwC7GZM2e2u9+0adOCrhxjryJ06qmn6tq1a1s9Vl1drbfccosC0OLiYq2pqWn1eF1dnfbr108B6Pjx41tN26RqFb32OuLnn39+2CmbnNxaVu5///d/FYA+++yzIffZtm2bioiOHDkyrtc6cuSIFhcXKwB99NFHW73nF198UXNycnTAgAHtrp3+xhtvaHZ2dpvv5/nnn6/HHnusf3tjY6Necskl2qFDB62srIyr3W7jkoBmMyW/9qYKyqRiMlDKFJb+JwLdAHQL+DoLwG0AVgBYC+DpTCkqlYVlROwCqXPnzq3WYj733HO1b9++/v/kxcXFum3btjbPr6ys1NLSUgWgxx13nJ5xxhlaWFjo72kM7OGMdn+7bWPGjNGePXtqTk6OjhkzRgcMGOBv16xZs9q06dprr/U/XlBQoKeddpqeeeaZOnDgQP/2iy++WJubm1s9b/bs2ZqVlaUdOnTQk046SUePHu2fE3PMmDGtJseuqalRAJqbm6sXX3yx/upXv/I/Nm3aNJ0yZYouXbo07Pd/yJAhCsDfSxvKc889pwB0wIABrbYfOnRIJ0+e7H9fAwYM0EmTJulJJ52kOTk5CkD79u2ra9asCXrc/fv365QpU/zPP/744/XMM8/UQYMG+d/7qaeeqnv37g37XhKlpKREAeiuXbtC7vPSSy8pYK0d3t4a4w888ID/OUuXLtUpU6boNddc0+pYq1at8n/vTjzxRP3Sl76kJ554ov//7PLly0O2o6WlRU8++eSgfyisX79eO3XqpDk5Oa0WBrjzzjuj/6YQGS5UL2WmFpS2lCsseWNhGS27eAt269q1q44aNUp/9rOftZrM3OmLL77Qu+66S8eNG6d5eXnar18/veSSS1pNJB3L/kuXLvWfbt69e7deccUVWlxcrD169NDzzz8/aI+kbeXKlXr55ZfrySefrN26ddPu3bvrKaecopdddlm7p2Hfeustvfjii7V///7+9//www9rfX19m30feugh7dGjh3bp0kW///3v+7d3795dAejChQtDvo7q0dOgPXr0aFPkOtXW1vqLnXfffbfN4+Xl5XrxxRfrsGHDtEuXLtqvXz+dPHmyzp49u93eNVWrGJo3b55OnjxZTzjhBM3JydFBgwbplClTdP78+VGvYGT76KOPYnpeIPv/54knntjufo888khEp+C/8Y1v+J9jTzAfrLe+oqLC//+tc+fOOnLkSJ05c2bYiaefffZZ7dy5c8hLE9atW6fnnnuuduvWTYcNG6aPP/541D3ByeBGduSdVMsvcP1u+8ZeyuASVViKdezIiMh8X0NuUdXD4fbPJCJiVZdRfD8pdezatQtFRUWYMWMGFixY4HVzonLllVdiypQpuPLKK71uChGRZ9bvqcHUJ95ud59Xvn0GB+X42NPNqaqE2TUqWVHufxmAawG4u4QGkcfseS9NU11djdWrV/un9MlUFRUVXjeBYsTszJZK+c1Z1vrn+LjiAv9tckkhi8okiXa6obcAXABgLIDNrrcmDcycObPNtmBLKVFqCTUxeqobO3Yspk2bhrFjx3rdFE+1N4URpTZmZ7ZUyW/9nppW0wexiGytvLwc5eXlSXmtaE+FDwLwDoDDAE5W1epENcw0PBVutjfffBPnnHOOkafCyVp5JtN7bU3F7MzmZX6hJjifXFKI+TPGtPNMAhJ3KjzaHstPAVwM4DkA20TkaQDrAewD0BjqSar6r1gbSJQM7a3OQ6kvcEJ2MguzM5sX+YWb4PzWyWaegUoX0RaWgT2UAuB7ETxHY3gdoqTq0KEDe5sNVllZ6V/+k8zC7MyW7PxCDdDhOt6pI9qCbzesQpEorRQWFnrdBIoD8zMXszNbMvJrb01vLr+YeqIqLFWVo8EpLdXU1KBLly5eN4NixPzMxezMloz8Qp325gCd1MRT1EQAf7EZjvmZi9mZLZH52T2Vq3ZavZRdc7MxrFc+T3mnOBaWRACam5u9bgLFgfmZi9mZLZH5OXsqxxYVcLS3AVhYEgFoaWnxugkUB+ZnLmZntkTlFzgvZdfcbIwtKuBob0OwsCQCkJub63UTKA7Mz1zMzmxu5xdsKiH2VJqFhSURgNraWuTn53vdDIoR8zMXszObW/m1NzcleyrNEtXKOxQaV94xW0NDA3tODMb8zMXszBZrfoFTCAFoM40QwKmEEi1VVt4hSkt79+7lCiAGY37mYnZmiya/9uajDMSC0mzssXQJeyzNpqr+v97IPMzPXMzObJHmF2rFHMBaNQcApxFKskT1WGa5eTCiSDU1NWHevHmYMmUK+vTpg9zcXBQXF+Occ87BI488grq6uqDPu++++yAiOOGEE3DgQOi/eI8cOQIRQXFx6zn9i4uLISK44YYbWm3ftGlTq6/nz58PEcF9990X4zsM3qYTTjgBIoIuXbrg4MGDIff93e9+BxHBtdde2+4x//nPf0JEcPbZZwd9XFWxaNEiXHTRRejXrx86d+6MgQMH4vzzz8cLL7zg6R9CjY2NuO+++zBhwgTk5+dj5MiRuP7667Ft27ag+9fV1eHHP/4xRo0ahby8PAwYMACXXXYZPvjggzb5RfK648aNQ7du3VBUVISLL74YK1asCLr/G2+8gZtvvhnXXnstnn/++ZDHLS8vR6dOnbB169aI20JtP3tklkjyC1ZUjisuwOSSQrzy7TOw6KYJWHTTBMyfMYZFZTpQ1ZhuAL4MYA6AdwFsAvCxb3s/AN8E0CnWY5t4g7XUpd54441tbq+++qrSUe+//74OHjxY7e/ZscceqxMnTtSSkhLt2LGjf9vf//73Ns+dNWuW/3kzZswI+RrNzc0KQIuKilptLyoq8j//zTffDPn8p59+WgHorFmzYn6fTkuWLPG/NgB95plnQu67cOHCsO9RVfWtt95SAHrWWWe1eay6ulrPPPNM/+v17NlTzzzzTB0wYID6etj1zDPP1EOHDsX93qL1ySefaGlpqQLQ7t276+mnn669evVSANqjRw9dsWJFq/0PHjyoJSUlCkALCgp04sSJOmTIEAWgHTp00L/97W8Rve6hQ4d0xIgRCkC7du2q48eP9/9fzMrK0l/84het9r/nnntaZQZAp0+f3ua4R44c0eHDh+u3v/3t2L8pRGlm3e7P9LoFq7T/nX9pdVu/+zOvm5ZxXn311Ta1if0zTd2uh6J+AtAVwGsAjvhuLb7bEd/jp/q+3gqgyO0Gp+otICBqx/bt27V79+7+YqiioqLV4//973/1+9//vgLQvLw8Xb16davHAwtLAEGLT9XICsvBgwf7i6qPPvqo1X6JKCyvvvpqBaDnnHOOAtALLrgg5L7xFpbNzc166qmnKgAdO3asbtq0qdXja9eu1VGjRikAvfbaa2N/UzH65je/qQD0hhtuaFXYPvHEEyoiWlJS0mr/22+/XQHoFVdcofX19f7tixcv1qysLC0sLNSWlpawr/vAAw8oAP3yl7+sn332mX/70qVLtWvXrtqxY0d9//33VVV15cqVKiJ60UUX6c6dO7Wqqsr/w/jFF19sddwFCxboMccco1VVVbF8OzKa87NHZmkvPxaVqS0lCktYg33eCigoywHc6SgsTwSwx7dtF4BctxudijcWlpH5+te/rgD0pptu0iNHjoTc7/7771cAevHFF7fabheWX/3qVxWADhw4sFWhYQtXWNrP/8EPfhD09d0uLOvr67Vr166ak5Oje/bs0c6dO2vHjh21uro66P7xFpa//e1vFYCeffbZIXskKysrtVu3bgpAd+zYEdP7isUnn3yiAHTQoEHa1NTU5nG7AP/HP/7h3zZmzBgFoB9//HGb/c866ywFoJs3bw772kOHDtWsrCzdsmVLm8d+8YtfKAC95557VNX6v9axY0etra3179Pc3Ky9e/fW6667zr+toaFB+/Xrpz/+8Y/Dvj5Rpli3+zN/MTn83iV63YJVLCpTTKIKy2ivsfwGgC8BaAQwRVXLVPWhwB1UdQ+AUgD/AdAXwM1RvgalqX/961946aWX0LNnTzzyyCPIygr93+/73/8+vv71r6Njx45obGxs8/jUqVNxySWXYNu2bbj//vujbsuvf/1r5OfnY/bs2diwYQM2btwY9TGi8Ze//AUHDx7ExRdfjL59++LCCy/E4cOH8cc//tH112pqavJfG/rQQw+F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\n",
"text/plain": [
"