Skip to content

Instantly share code, notes, and snippets.

@rkube
Created September 21, 2022 20:47
Show Gist options
  • Save rkube/dfe6847198c4ca6b21425c4824d76ae9 to your computer and use it in GitHub Desktop.
Save rkube/dfe6847198c4ca6b21425c4824d76ae9 to your computer and use it in GitHub Desktop.
AE_pred_LSTMtest_1723xx.ipynb
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "b2cea2eb",
"metadata": {},
"outputs": [],
"source": [
"%load_ext autoreload\n",
"%autoreload 2"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "2cb09a0b",
"metadata": {},
"outputs": [],
"source": [
"import sys\n",
"# USe the D3D loader to fetch and prepare data\n",
"# https://github.com/PlasmaControl/d3d_loaders\n",
"sys.path.append(\"/home/rkube/repos/d3d_loaders\")\n",
"\n",
"from os.path import join\n",
"\n",
"import numpy as np\n",
"import torch\n",
"import torch.nn as nn\n",
"import torch.nn.functional as F\n",
"from torch.autograd import Variable\n",
"\n",
"\n",
"from torch.utils.data import ConcatDataset\n",
"import matplotlib.pyplot as plt\n",
"\n",
"from matplotlib.ticker import MultipleLocator\n",
"import logging"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "cee5f538",
"metadata": {},
"outputs": [],
"source": [
"from d3d_loaders.d3d_loaders import D3D_dataset\n",
"from d3d_loaders.samplers import SequentialSequenceSampler, RandomSequenceSampler, collate_fn_randseq"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "18e5a535",
"metadata": {},
"outputs": [],
"source": [
"# Set up a shot and define the time-interval for prediction\n",
"shot_list_train = [172337, 172339, 172341, 172342]\n",
"shot_list_valid = [172340]\n",
"tstart = 110.0 # Time of first sample for upper triangularity is 100.0\n",
"tend = 1000.0\n",
"# Define re-sampling paramters\n",
"t_params = {\"tstart\": tstart, \"tend\": tend, \"tsample\": 10.0}\n",
"t_shift = 10.0\n",
"\n",
"device = torch.device(\"cuda:1\" if torch.cuda.is_available() else \"cpu\")\n",
"\n",
"seq_length = 10\n",
"batch_size = (seq_length + 1) * 16"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "a13dfa29",
"metadata": {},
"outputs": [],
"source": [
"# Create exhaustive list of predictors, as in https://doi.org/10.1088/1741-4326/abe08d\n",
"# In that paper, there are 5 profiles\n",
"# and 10 scalars defined\n",
"# We have 13-1 scalars\n",
"# 10 + neutronsrate + ae_prob + echpwrc - doutl (not available)\n",
"pred_list = [\"pinj\", # Injected power\n",
" \"tinj\", # Injected torque\n",
" \"neutronsrate\", # MEasured neutron rate\n",
" \"iptipp\", # Target current\n",
" \"dstdenp\", # Target density\n",
" \"doutu\", # Top triangularity\n",
" # \"doutl\", # Bottom triangularity not available\n",
" # \"elongm\", # Plasma elongation - data not available\n",
" #\"vout\", # Plasma volume - data not available\n",
" # \"ali\", # Internal inductance - THis data is just zero\n",
" # \"echpwrc\", # Total ECH power - No ECH in this show\n",
" \"dssdenest\", # Line-averaged density\n",
" \"ae_prob\"] # AE mode probability\n",
"\n",
"# Set the list of targets, see \n",
"targ_list = [\"ae_prob\"]\n",
"\n",
"# Instantiate a dataset. For multiple shots, use https://pytorch.org/docs/stable/data.html#torch.utils.data.ConcatDataset\n",
"# At this stage, the data needs to be downloaded using https://github.com/PlasmaControl/d3d_loaders/blob/main/d3d_loaders/downloading.py\n",
"ds_list_train = []\n",
"for shotnr in shot_list_train:\n",
" ds = D3D_dataset(shotnr, t_params,\n",
" predictors=pred_list,\n",
" targets=targ_list,\n",
" shift_targets={\"ae_prob\": t_shift},\n",
" datapath=\"/projects/EKOLEMEN/d3dloader/test\",\n",
" device=device)\n",
" ds_list_train.append(ds)\n",
"ds_train = ConcatDataset(ds_list_train)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "7fff4bf7",
"metadata": {},
"outputs": [],
"source": [
"ds_list_valid = []\n",
"for shotnr in shot_list_valid:\n",
" ds = D3D_dataset(shotnr, {\"tstart\": tstart, \"tend\": tend, \"tsample\": 10.0},\n",
" predictors=pred_list,\n",
" targets=targ_list,\n",
" shift_targets={\"ae_prob\": 10.0},\n",
" datapath=\"/projects/EKOLEMEN/d3dloader/test\",\n",
" device=device)\n",
" ds_list_valid.append(ds)\n",
"ds_valid = ConcatDataset(ds_list_valid)"
]
},
{
"cell_type": "markdown",
"id": "220ff11d",
"metadata": {},
"source": [
"When running loader_train in standard fashion, we get something like\n",
"x.shape = [16, 12], and y.shape = [16, 5].\n",
"The first dimension is the batch size, the second dimension is the feature length\n",
"\n",
"An LSTM expect dimensions of [L, N, H], where L is the sequence length. N is the batch size. And H is the hidden size.\n",
"\n",
"To achieve this, we can use random sequence sampler:\n"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "fc0432cc",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(10, 176)"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"seq_length, batch_size"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "b34c59f4",
"metadata": {},
"outputs": [],
"source": [
"# Bad hack to get collate_fn_seq, appropriate for current sequence size:\n",
"\n",
"class collate_functor():\n",
" def __init__(self, seq_length):\n",
" self.seq_length = seq_length\n",
" \n",
" def __call__(self, x):\n",
" return collate_fn_randseq(x, self.seq_length)\n",
" \n",
" \n",
"my_collate_fn = collate_functor(seq_length)"
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "f5a12aa4",
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"torch.Size([10, 16, 12]) torch.Size([1, 16, 5])\n"
]
}
],
"source": [
"loader_train = torch.utils.data.DataLoader(ds_train, batch_size=batch_size, num_workers=0,\n",
" sampler=RandomSequenceSampler(range(len(ds_train)), seq_length=seq_length),\n",
" collate_fn=my_collate_fn)\n",
"\n",
"loader_valid = torch.utils.data.DataLoader(ds_valid, batch_size=batch_size, num_workers=0,\n",
" sampler=RandomSequenceSampler(range(len(ds_valid)), seq_length=seq_length),\n",
" collate_fn=my_collate_fn)\n",
"\n",
"x, y = next(iter(loader_train))\n",
"print(x.shape, y.shape)"
]
},
{
"cell_type": "code",
"execution_count": 21,
"id": "a62e00e8",
"metadata": {},
"outputs": [],
"source": [
"class my_lstm(nn.Module):\n",
" def __init__(self, num_classes, input_size, hidden_size, seq_length, num_layers=2, device=\"cpu\"):\n",
" super(my_lstm, self).__init__()\n",
" self.num_classes = num_classes # Number of output features\n",
" self.input_size = input_size # Number of features in the input x\n",
" self.hidden_size = hidden_size # Number of features in hidden state h\n",
" self.seq_length = seq_length \n",
" self.num_layers = num_layers\n",
" self.device = device\n",
" \n",
" self.lstm = nn.LSTM(input_size=self.input_size, \n",
" hidden_size=self.hidden_size,\n",
" num_layers=self.num_layers, \n",
" batch_first=False).to(device) #lstm\n",
" self.fc_1 = nn.Linear(hidden_size, 128).to(device) #fully connected 1\n",
" self.fc = nn.Linear(128, num_classes).to(device) #fully connected last layer\n",
"\n",
" self.relu = nn.ReLU()\n",
" \n",
" def forward(self, x):\n",
" h_0 = Variable(torch.zeros(self.num_layers, x.size(1), self.hidden_size)).to(self.device) #hidden state\n",
" c_0 = Variable(torch.zeros(self.num_layers, x.size(1), self.hidden_size)).to(self.device) #internal state\n",
" # Propagate input through LSTM\n",
" output, (hn, cn) = self.lstm(x, (h_0, c_0)) #lstm with input, hidden, and internal state\n",
" \n",
" hn = hn[-1, ...] # Take output of the last hidden recurrent layer\n",
" out = self.relu(hn)\n",
" out = self.fc_1(out) #first Dense\n",
" out = self.relu(out) #relu\n",
" out = self.fc(out) # Final Output\n",
" return out"
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "65ae6d08",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/rkube/.conda/envs/ml202205/lib/python3.10/site-packages/torch/backends/cudnn/__init__.py:73: UserWarning: PyTorch was compiled without cuDNN/MIOpen support. To use cuDNN/MIOpen, rebuild PyTorch making sure the library is visible to the build system.\n",
" warnings.warn(\n"
]
}
],
"source": [
"model = my_lstm(5, 12, hidden_size=64, seq_length=seq_length, device=device)\n",
"\n",
"loss_fn = nn.MSELoss()\n",
"optimizer = torch.optim.Adam(model.parameters(), lr=1e-3)"
]
},
{
"cell_type": "code",
"execution_count": 23,
"id": "a3e1482b",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/rkube/.conda/envs/ml202205/lib/python3.10/site-packages/torch/nn/modules/loss.py:530: UserWarning: Using a target size (torch.Size([1, 16, 5])) that is different to the input size (torch.Size([16, 5])). This will likely lead to incorrect results due to broadcasting. Please ensure they have the same size.\n",
" return F.mse_loss(input, target, reduction=self.reduction)\n",
"/home/rkube/.conda/envs/ml202205/lib/python3.10/site-packages/torch/nn/modules/loss.py:530: UserWarning: Using a target size (torch.Size([1, 10, 5])) that is different to the input size (torch.Size([10, 5])). This will likely lead to incorrect results due to broadcasting. Please ensure they have the same size.\n",
" return F.mse_loss(input, target, reduction=self.reduction)\n",
"/home/rkube/.conda/envs/ml202205/lib/python3.10/site-packages/torch/nn/modules/loss.py:530: UserWarning: Using a target size (torch.Size([1, 15, 5])) that is different to the input size (torch.Size([15, 5])). This will likely lead to incorrect results due to broadcasting. Please ensure they have the same size.\n",
" return F.mse_loss(input, target, reduction=self.reduction)\n"
]
}
],
"source": [
"num_epochs = 10\n",
"\n",
"losses_train_epoch = np.zeros(num_epochs)\n",
"losses_valid_epoch = np.zeros(num_epochs)\n",
"\n",
"for epoch in range(num_epochs):\n",
" model.train()\n",
"\n",
" loss_train = 0.0\n",
" loss_valid = 0.0\n",
" for i, (data, target) in enumerate(loader_train):\n",
" optimizer.zero_grad()\n",
"\n",
" outputs = model(data)\n",
"\n",
" loss = loss_fn(outputs, target)\n",
" loss.backward()\n",
" optimizer.step()\n",
"\n",
" loss_train += loss.item()\n",
" #print(f\"batch {i}: loss = {loss.item()}\")\n",
" \n",
" with torch.no_grad():\n",
" for i, (data, target) in enumerate(loader_valid):\n",
" outputs = model(data)\n",
" loss_valid += loss_fn(outputs, target).item()\n",
" \n",
" losses_train_epoch[epoch] = loss_train / len(loader_train) / batch_size\n",
" losses_valid_epoch[epoch] = loss_valid / len(loader_valid) / batch_size"
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "97849d26",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x2008bcd43cd0>]"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAYAAAAD4CAYAAADlwTGnAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAk9UlEQVR4nO3deXhc9X3v8fdXo9WbbMuyLbzUFtiAE7AhxhbQkJKEXpukMTQhLClbaFwXSJM0fVqa5z7PTdvblpsmacItgbBDQyBmu3FSt5RSEkKCDQJsgwEHY4MtS9jyInnRLn3vH+dIGo3H0sgaeZbzeT3PeWbOOb9z5jeToI/P73sWc3dERCR6CjLdARERyQwFgIhIRCkAREQiSgEgIhJRCgARkYgqzHQHhmPKlCk+Z86cTHdDRCSnvPLKK3vdvTJxeU4FwJw5c6itrc10N0REcoqZvZ9suYaAREQiSgEgIhJRCgARkYhSAIiIRJQCQEQkohQAIiIRpQAQEYmoSATAc1v28INfbM10N0REskokAuDFd/fxvWfeoa2zO9NdERHJGpEIgJrqyXR09/DqjgOZ7oqISNaIRAAsnjOZAoN12/ZnuisiIlkjEgEwobSID51Uzrpt+zLdFRGRrBGJAIBgGGjDjibVAUREQhEKgArVAURE4kQmAHrrAOtVBxARASIUAOVlqgOIiMSLTABAUAd4bafqACIiELkAqKCjq4fXdjRluisiIhkXqQDovx5Aw0AiIpEKANUBRET6RSoAQHUAEZFeEQwA1QFERCCCAaA6gIhIIHIBoDqAiEggcgEAsHSu6gAiIikFgJktM7MtZrbVzG5Jst7M7LZw/SYzOztcXmpmL5nZRjPbbGZ/E7fNZDN7xszeCV8npe9rDU51ABGRFALAzGLA7cByYAFwpZktSGi2HJgXTiuBO8Ll7cDH3X0hsAhYZmY14bpbgGfdfR7wbDh/QpwzdzKmOoCIRFwqRwBLgK3uvs3dO4BHgRUJbVYAD3lgHTDRzKrC+cNhm6Jw8rhtHgzfPwhcMoLvMSxBHWAC67crAEQkulIJgBnAzrj5unBZSm3MLGZmG4A9wDPuvj5sM83dGwDC16nJPtzMVppZrZnVNjY2ptDd1NTMreBVPR9ARCIslQCwJMs81Tbu3u3ui4CZwBIz+/BwOujud7n7YndfXFlZOZxNB9VbB9iwsylt+xQRySWpBEAdMCtufiZQP9w27t4E/AJYFi7abWZVAOHrnlQ7nQ6qA4hI1KUSAC8D88xsrpkVA1cAaxLarAGuCc8GqgGa3b3BzCrNbCKAmZUBnwTejtvm2vD9tcBPR/ZVhqe3DqAAEJGoKhyqgbt3mdnNwNNADLjP3Teb2apw/Z3AWuBiYCvQAlwfbl4FPBieSVQArHb3n4frbgVWm9kNwA7gsvR9rdTUzK3goXXv09bZTWlR7ER/vIhIRg0ZAADuvpbgj3z8sjvj3jtwU5LtNgFnHWOf+4BPDKez6VZTXcE9L2xnw84maqorMtkVEZETLpJXAvdSHUBEoizSAaA6gIhEWaQDAHQ9gIhEV+QDYKmuBxCRiIp8ACyZozqAiERT5AOgfEwRC6pUBxCR6Il8AEBwOuhrqgOISMQoAAgCoL2rh42qA4hIhCgAiK8D7M90V0REThgFAKoDiEg0KQBCNdUVvLrjgOoAIhIZCoCQ6gAiEjUKgJDqACISNQqAkOoAIhI1CoA4qgOISJQoAOKoDiAiUaIAiKM6gIhEiQIgTvmYIk6frjqAiESDAiBBbx2gvUt1ABHJbwqABDXVk8M6QHOmuyIiMqoUAAmW6DnBIhIRCoAEE8cUqw4gIpGQUgCY2TIz22JmW83sliTrzcxuC9dvMrOzw+WzzOw5M3vLzDab2Vfitvmmme0ysw3hdHH6vtbI1FRX8Mr7qgOISH4bMgDMLAbcDiwHFgBXmtmChGbLgXnhtBK4I1zeBXzd3U8HaoCbErb9Z3dfFE5rR/ZV0kd1ABGJglSOAJYAW919m7t3AI8CKxLarAAe8sA6YKKZVbl7g7u/CuDuh4C3gBlp7P+oUB1ARKIglQCYAeyMm6/j6D/iQ7YxsznAWcD6uMU3h0NG95nZpGQfbmYrzazWzGobGxtT6O7IqQ4gIlGQSgBYkmU+nDZmNg54Aviqux8MF98BnAwsAhqA7yT7cHe/y90Xu/viysrKFLqbHqoDiEi+SyUA6oBZcfMzgfpU25hZEcEf/4fd/cneBu6+29273b0HuJtgqClrqA4gIvkulQB4GZhnZnPNrBi4AliT0GYNcE14NlAN0OzuDWZmwL3AW+7+3fgNzKwqbvZS4I3j/hajQHUAEcl3QwaAu3cBNwNPExRxV7v7ZjNbZWarwmZrgW3AVoJ/zd8YLj8fuBr4eJLTPb9lZq+b2SbgQuBraftWaaA6gIjku8JUGoWnaK5NWHZn3HsHbkqy3Qskrw/g7lcPq6cZsLR6Mj9ev4P2rm5KCmOZ7o6ISFrpSuBB9D8fQHUAEck/CoBBLA3rAOs1DCQieUgBMIiJY4o5bfoE1m1XAIhI/lEADKGmerKuBxCRvKQAGEJNdQVtnT1sqlMdQETyiwJgCL11gHXvahhIRPKLAmAIqgOISL5SAKRAdQARyUcKgBSoDiAi+UgBkALVAUQkHykAUqA6gIjkIwVAilQHEJF8owBI0dK5qgOISH5RAKRo6dzJgOoAIpI/FAApmjS2mNOmj2f99v2Z7oqISFooAIahprqC2vf309HVk+muiIiMmAJgGPqvB2jKdFdEREZMATAMfXUAPR9ARPKAAmAYeusA67apDiAiuU8BMEyqA4hIvlAADJPqACKSLxQAw6Q6gIjki5QCwMyWmdkWM9tqZrckWW9mdlu4fpOZnR0un2Vmz5nZW2a22cy+ErfNZDN7xszeCV8npe9rjR7VAUQkXwwZAGYWA24HlgMLgCvNbEFCs+XAvHBaCdwRLu8Cvu7upwM1wE1x294CPOvu84Bnw/mcoDqAiOSDVI4AlgBb3X2bu3cAjwIrEtqsAB7ywDpgoplVuXuDu78K4O6HgLeAGXHbPBi+fxC4ZGRf5cRRHUBE8kEqATAD2Bk3X0f/H/GU25jZHOAsYH24aJq7NwCEr1OTfbiZrTSzWjOrbWxsTKG7o2+J6gAikgdSCQBLssyH08bMxgFPAF9194Opdw/c/S53X+zuiysrK4ez6aiZrDqAiOSBVAKgDpgVNz8TqE+1jZkVEfzxf9jdn4xrs9vMqsI2VcCe4XU9s2qqK3jl/QOqA4hIzkolAF4G5pnZXDMrBq4A1iS0WQNcE54NVAM0u3uDmRlwL/CWu383yTbXhu+vBX563N8iA2qqJ9Pa2c3ru5oy3RURkeMyZAC4exdwM/A0QRF3tbtvNrNVZrYqbLYW2AZsBe4GbgyXnw9cDXzczDaE08XhuluBi8zsHeCicD5nLJlbAaBhIBHJWYWpNHL3tQR/5OOX3Rn33oGbkmz3AsnrA7j7PuATw+lsNumvA+zjpgtPyXR3RESGTVcCj0BNdQW176kOICK5SQEwAqoDiEguUwCMgOoAIpLLFAAjEF8HEBHJNQqAEVIdQERylQJghFQHEJFcpQAYIdUBRCRXKQBGSHUAEclVCoA0WDp3MrXvHaCzW3UAEckdCoA0qKmuoLWzm011zZnuiohIyhQAaaDnA4hILlIApEHFuBJOnaY6gIjkFgVAmtRUqw4gIrlFAZAmqgOISK5RAKSJ6gAikmsUAGmiOoCI5BoFQBqpDiAiuUQBkEaqA4hILlEApJHqACKSSxQAaaQ6gIjkEgVAmqkOICK5QgGQZktVBxCRHJFSAJjZMjPbYmZbzeyWJOvNzG4L128ys7Pj1t1nZnvM7I2Ebb5pZrvMbEM4XTzyr5N5vXWA9ds1DCQi2W3IADCzGHA7sBxYAFxpZgsSmi0H5oXTSuCOuHUPAMuOsft/dvdF4bR2mH3PSlPGlTB/2jg9IEZEsl4qRwBLgK3uvs3dO4BHgRUJbVYAD3lgHTDRzKoA3P15IFJ/DYPnBO9XHUBEsloqATAD2Bk3XxcuG26bZG4Oh4zuM7NJyRqY2UozqzWz2sbGxhR2mXk11RW0dHTz+i7VAUQke6USAJZkmR9Hm0R3ACcDi4AG4DvJGrn7Xe6+2N0XV1ZWDrHL7KDrAUQkF6QSAHXArLj5mUD9cbQZwN13u3u3u/cAdxMMNeUF1QFEJBekEgAvA/PMbK6ZFQNXAGsS2qwBrgnPBqoBmt29YbCd9tYIQpcCbxyrbS5SHUBEst2QAeDuXcDNwNPAW8Bqd99sZqvMbFXYbC2wDdhK8K/5G3u3N7NHgBeBU82szsxuCFd9y8xeN7NNwIXA19L1pbKB6gAiku0KU2kUnqK5NmHZnXHvHbjpGNteeYzlV6fezdwTXwc4e3bS+raISEbpSuBRojqAiGQ7BcAoUh1ARLKZAmAUqQ4gItlMATCKdD2AiGQzBcAomjKuhHlTx7FedQARyULRCICD9fDOf2Xko1UHEJFsFY0AeOZ/wSOXwxtPnvCPrqmu4EhHN2+oDiAiWSYaAfCp78DMc+CJG2DDIyf0o5dW99YBNAwkItklGgFQOgH+6AmY81H4f6ug9r4T9tG9dQAVgkUk20QjAACKx8JVq2He/4Cffw1e/MEJ+2jVAUQkG0UnAACKSuHyH8Hpn4Gn/xp+lfQO1GmnOoCIZKNoBQBAYTF87n444zJ49m/hv/83+FCPLhgZ1QFEJBtFLwAAYoVw6Q/hrKvh+X+C//yfoxoCqgOISDZK6W6geakgBn9wGxSVwYv/Al1tsPyfoGB0MrGmuoInX62js7uHolg0c1dEsku0/xIVFMDyb8F5fwYv3wNrvgw93aPyUaoDiEi2ie4RQC8zuOhvoWgM/PJW6GoNhodiRWn9mPg6wFl6PoCIZIFoHwH0MoML/xo++U144wl47Droak/rR/TWAVbX7qShuTWt+xYROR4KgHi/+7VgSOjtn8OjX4DO9P6h/psVH6LxUDuX3v4b3qw/mNZ9i4gMlwIg0dI/gT/4Pmz9L3j4Mmg/nLZdn3fyFB5bdS4An//hizz/28a07VtEZLgUAMl85LqgDvD+r+FHn4W29BVuT6+awFM3ncfMSWV88YGXWV27M237FhEZDgXAsSy8PLhgbFctPLQCWtJ3EVdVeRmPrTqXc0+u4C8f38R3n/ktPsoXo4mIJFIADOZDl8DlD8PuzfDgH8Dh9A3ZjC8t4r7rzuGyj8zktmff4euPbaSjS/cKEpETJ6UAMLNlZrbFzLaa2S1J1puZ3Rau32RmZ8etu8/M9pjZGwnbTDazZ8zsnfA1O8+NPHUZXPUT2PcuPHAxHGxI266LYgV863Nn8ucXzefJV3dx3f0vcbCtM237FxEZzJABYGYx4HZgObAAuNLMFiQ0Ww7MC6eVwB1x6x4AliXZ9S3As+4+D3g2nM9OJ388uJ30wXq4fzk07Ujbrs2MP/vEPL592UJe2r6fy+54kfomnSYqIqMvlSOAJcBWd9/m7h3Ao8CKhDYrgIc8sA6YaGZVAO7+PJBsAH0F8GD4/kHgkuPo/4kz53y45qfQuh/uvzg4Ikijz31kJg9+cQn1Ta1c+oNfs7leVwyLyOhKJQBmAPGnqtSFy4bbJtE0d28ACF+nJmtkZivNrNbMahsbM3za5MzFcO3PoONIEAKNW9K6+/NPmcJjf3ouBWZ8/s4X+cWWPWndv4hIvFQCwJIsSzxlJZU2x8Xd73L3xe6+uLKyMh27HJmqhXDdv4H3BCHwwetp3f1p0yfw1I3nM7tiLDc8WMujL6VvuElEJF4qAVAHzIqbnwnUH0ebRLt7h4nC19z55+60BXD9v0NhCTzwadj1Slp3P728lMdWncv5p0zhlidf59tPb9FpoiKSdqkEwMvAPDOba2bFwBXAmoQ2a4BrwrOBaoDm3uGdQawBrg3fXwv8dBj9zrwpp8D1a4PnDT+4At5/Ma27H1dSyL3XLuaKc2bxL89t5c9X6zRREUmvIQPA3buAm4GngbeA1e6+2cxWmdmqsNlaYBuwFbgbuLF3ezN7BHgRONXM6szshnDVrcBFZvYOcFE4n1smzYHr/wPGT4Mf/SFs+2Vad18UK+Af//AM/uL35/PUa7u49r6XaG7VaaIikh6WS0MLixcv9tra2kx342iHdgdXC+/fFjxzeP7vp/0jnnqtjr98fBNzKsZy//XnMHPSmLR/hojkJzN7xd0XJy7XlcDpMH5aUBiuPBUevQre+lnaP+LSs4LTRD842MalP/iNHiwjIiOmAEiXsRXBKaInLYLV18Lrj6f9I847eQpP/Ol5FMcK+PwPX+S5t3Onbi4i2UcBkE5lE+Hqp2B2DTzxx/Dqv6b9I+ZPG89TN55HdeVY/vihWn68XqeJisjxUQCkW8l4+MLjUP17sOZmeOnutH/E1Aml/GTluVwwbwrfeOp1vvUfb9PTkzu1HBHJDgqA0VA8Bq58FOYvh7V/Ab/5v2n/iLElhdx9zWKuWjqbH/ziXb76kw20d43OA+1FJD8pAEZLUSl8/iFYcAn85/+EX34L0nzGVWGsgL+/5MP81bLTWLOxnqvvfYmmlo60foaI5C8FwGgqLIbP3gtnXgHP/T08+7dpDwEz409/72S+f8UiNuxo4rN3/Iad+1vS+hkikp8UAKMtVgiX3BE8ZvKF78Lqa2D789CT3qt6Vyyawb/esCR46PwPfs2muqa07l9E8o8C4EQoKIBPfw8+9lfw7nPB08W+vxCe+4fg4rE0WVpdwZM3nkdpUYzLf7iO/3pzd9r2LSL5R1cCn2gdLfD2v8GGh2HbLwCH2efBoquCR1CWjB/xR+w51MYND9Syub6Zv/nMh7j63Dkj3qeI5K5jXQmsAMik5jrY9BPY8GPYtxWKxsDpn4FFV8KcC4Ijh+PU0tHFl3/8Gs++vYc/uaCav1p2GgUFye7aLSL5TgGQzdyh7uXgqOCNp6C9GcpnwcIrYOGVUHHyce22q7uHb/5sMz9at4NPnVnFdy5bSGlRLM2dF5FspwDIFZ2t4RDRj2Hbc8GDZ2bV9A8RlZYPa3fuzl3Pb+Mf//1tzpkzibuuXsykscWj03cRyUoKgFx0sL5/iGjvb6GwDE7/dBAGcz8GBan/a/5nG+v5+uqNzJxUxgPXL2F2he4mKhIVCoBc5h48dWzDj+GNx6GtGSbMCIeIrgoeTpOCl7bv50sP1VJYYPyfz57Jx0+bqrqASAQoAPJFZxtsWRuEwbvPBkNEM5eEQ0SXBjekG8S7jYe54YGXeW9fC/OmjuNLF1SzYtFJlBSqNiCSrxQA+ehgA7y+OgiDxrehsBRO+1QQBtUXHnOIqKOrh397vZ4f/nIbb39wiKnjS7ju/Dl8YcnvUD6m6AR/CREZbQqAfOYO9a8FQfD6Y9DWBOOr4MzLgzCoPPUYmzm/emcvd/9qG796Zy9ji2Ncfs5svvi7c/TEMZE8ogCIiq522PLvsPEReOcZ8G6YsTgIgg//IZRNSrrZ5vpm7vnVdn62sR4HPnVGFSsvqObDM4Z31pGIZB8FQBQd2t0/RLTnTYiVwGkXw6IvBGcRFR59Omh9Uyv3vbCdR17awZGObs4/pYIvfbSaj82vxEwFY5FcpACIMndo2BgOEa2G1gNQUARTT4eqhf3TtA8HzzIAmls7efSlHdz36+3sPtjOqdPG86ULqvnMwpMoLtQtpERyiQJAAl3tsPVZqHspCIX6DdC6P1hnBTBl/oBQ6JjyIdZsOcLdz29jy+5DTJtQwvXnz+WqpbOZUKqCsUguGFEAmNky4PtADLjH3W9NWG/h+ouBFuA6d391sG3N7JvAl4DGcDffcPe1g/VDATAK3OHgriAMGjZCw6bg9VB9f5tJc/GqhWwvOoXVuyazum4yHSWTueKcWXzxd+dy0sSyzPVfRIZ03AFgZjHgt8BFQB3wMnClu78Z1+Zi4MsEAbAU+L67Lx1s2zAADrv7t1P9EgqAE+jwnjAMNgSB8MEmOPBe3+oDhZXUdszmzZ45jJ3zES742CeZf8p8UJ1AJOscKwAKU9h2CbDV3beFO3oUWAG8GddmBfCQB2myzswmmlkVMCeFbSUbjZsK8z4ZTL1aD8AHr0PDRiY1bOT36l7jkweexOqegIe/wcGCcrqmncmkk8/BeoeRJs1RKIhkqVQCYAawM26+juBf+UO1mZHCtjeb2TVALfB1dz+Q+OFmthJYCTB79uwUuiujpmwSzL0gmIAigPbDHN6xkVfX/4Kmd2s5Zde7TGj4DYWED6gvKYeqMwcWmytOGdZ9jERkdKQSAMn++ZY4bnSsNoNtewfwd+H83wHfAb54VGP3u4C7IBgCSqG/ciKVjGPcvPO5YN75tHd189MN9fzFL9+mYO/bnD92FyumNHJq+zZiL98DXW3BNkVjYPoZwTR+ehAs8VPpxOC1ZMKInokgIoNLJQDqgFlx8zOB+hTbFB9rW3fve16hmd0N/DzlXktWKimM8fnFs/jc2TP55W8Xctfz2/jhu/sYX1LIF5acxA2ndVJ5aEt/wXnTamg/eOwdWkF/GJRNCu5zlBgW8YER3y6mM5REhpJKALwMzDOzucAu4ArgqoQ2awiGcx4lGOJpdvcGM2s81rZmVuXuDeH2lwJvjPjbSFYoKDAuPG0qF542lU11Tdz9q+3c9cIO7vm18ZlFp/Olj36K05dPCBp3tUNrU1Bf6J3aEuZ7p5b9sO/dsE0zRx+Ixikelzw0jgqLcBpTAWMmQ2HJqP8+Itki1dNALwa+R3Aq533u/vdmtgrA3e8MTwP9F2AZwWmg17t77bG2DZf/K7CI4L/i94A/iQuEpHQWUO7aub+Fe1/YzuranbR0dHPB/EpWfrSac0+uIHY8t6Tu6Q5CYEBgNMUFRlPyEGk9AD2dx95v8XgYWxEGQpJp7JSB86UTNUwlWU8XgklWaGrp4OH1O7j/1++x93A7Y4pjnDGjnEWzJ3LWrIksmjWJ6eWlo9cBd+hsOfrIonU/tOyDI/uC15Z90LI3WNeyL9gmGSuAsslxAREfGPFhMbk/PIrG6MwoOaEUAJJV2jq7eebN3dS+t58NO5t4s+Egnd3B/xenTShhURgGi2ZN5MyZ5YwtSWW0chR1tMQFw74wGPYOXDYgPPYFN+JLprA0DIfJCUcWU4LTb8dNG/iqeoaMkAJAslp7Vzdv1h9kw86mvun9fcG/ugsM5k0dH4TC7IksmjWR+dPGH9/Q0YnS0wPtzf1HEC374EhCYCSGR3tz8n2NqUgIhfgpLijKJunIQpJSAEjOOXCkgw11TWzYEQTCxrommlqC8fu+oaNZE/uCoao8x29J0dUORxrh8O7gTq6HdwdXZB/ePXA6tBu624/ePlZ8dCiMm54QHOH7olEcZpOsowCQnOfuvL+vZcBRwpv1B+no7gH6h44WhqFw5syJjMv00NFocA9Onz28Bw59kBAUe+DwB/3zR/aS9Gyp0vIkRxFx8+Or+q/R0FFFzlMASF5q7+rmrYZDbNhxIDxKaGb73iNA8Hdr/tTxLJxV3ldPmD9tHIWxCJ21090V1CoGHFUkO7LYAx2Hj94+VgLjp/UHwrjpwev4qoHLSycqKLKYAkAio6mlY8BRwsadTRwIh47KimKcMbOcs+KOFKrKS/WwG4D2w3AkPKromxrC8GjoX5bs4r1YSVwwTI+bqoKjir6gKFdQZIACQCLL3dmxPxg6em3H0UNHU8aVMGNSGVUTSpleXkpVefA6fUIpVeVlTJ1QQmmR7l3Up+NIfxgcjguKAcHxAXQcOnrbwtKBQXGsI4qSCQqKNFIAiMTp6OrhrYbgrKPN9c00NLfxQTgdau86qv3kscVhIJQyrbw0LizKmF5ewvTysvysN4xE++Gjjx7i3x/+AA42QOeRo7ctGgNjK4N6xNjK4DTZsZUwdmrc+8r+s590c8FBjeR20CJ5p7iwgIXhMFCiw+1dfWHQ0NwavD/YO9/Gazub2H+k46jtxpcUBuHQd/RQGjdfRlV5KRPHFEVnuKlkXDBVnDx4u/ZDQX2iLxzC1yN7grOimnbArleCgnayayusILyWojcoEkIjMUSKx47O981BCgCRBONKCjll6jhOmTrumG3aOrvZc7A9CIi4cPiguY2Gg228s3svew610ZNwgF1SWNA3vDQ9HGoKjiaCoabysqK+qSgqxeqS8cE05ZTB2/X0BFduH2kMpz1BKPTN7w2K2b1hkWwICqBobMJRRGX/+8RpzOS8PrpQAIgch9KiGLMrxjC7Yswx23R199B4uJ2G5jZ29wbEwba++Vd3HGB3c3tfLSLRmOJYXxhMiAuG3mnimGOvy8vwKCgIbrUxtgI4bej2na0Dw+FIYxAQ8aHRXAf1rw5+dNF3s8BkV2/H3eqj99YfxWNzpn6hABAZJYWxAqrKywa9QK2nx9nf0sEHzW00HmqnubXzqKmppZODrZ3s2NfSt6y18xi3mQgNFR7xU+L64sI8CY+iMpg4O5iG0tMT3FSwLyR6Q2PPwNt/7HsXdr40+K0+YiVJ7gs1SICUTYbC4rR+9VQpAEQyqKDAmDKuhCnjhncb6o6ungEhcTBJcMRPO/e38HrL8MMj2RFHeVkR5WOK+5fHBUlW355jMAUF4R/nyVB56tDt3YO70R51S4+9cfeKCm8o2LQjeN92jFt9QHDW01F3nk2Yn7kkGK5KIwWASA4qLiygcnwJleOH//yCVMOj98jj/fDIo6m1g7bO5MNVvcaXFiYPjLLiYywvonxMEeNLCnOrOG4WPmti4tBF7l7dnQPvDZV4x9neADnUALs3B+t6n6IH8IUnBj6jOw0UACIRM5LwaO/qDgKiZWBQHOvI44PmQzS3dnGwtfOYtQ4Ibvg3MBSKKSsqoLCggMKYBa8FRmHMKIoVEOt9XxC8L4oZhbGwTUHc+1j/dsn2URQuD973ftbAfZUUxSgtLBj5FeSxovBah2mpb9NxpD8cJleP7POTUACISMpKCmNMHR9j6vjh3UzO3Wnr7KGptaMvQJoSjkDig6SptZM9B7vp6nG6unvo7Ha6e5yunuB9V3dPsK4nWH4iFMWM0qJYOBVQ1vc+nAoLKCuOUVoYo6w4RklRQd/7vnVFMUqSLCstjFFaXEBpUYyyolh/Eb94bDClUsc4DgoAERl1ZkZZcYyy4sGL4sfD3cOgcDp7eugOX7vC0OjsDYvu/gDp7g2WHqe7L1SC9X2v4TbtXd20dvTQ1tVNa0c37V3dtHX20NrRTVtXN22dwVHRns5uWjuD+bbOHlo7u+noGnzI7FhiBdYXEL2B8Q+XnsGSuZPT+tspAEQkp5kFQzlFMSgju87Z7+lx2rt6+oIhPiDaEsKibcDUc1Tb0bjSXAEgIjJKCgp6j3yyK5h65ckJvyIiMlwKABGRiEopAMxsmZltMbOtZnZLkvVmZreF6zeZ2dlDbWtmk83sGTN7J3ydlJ6vJCIiqRgyAMwsBtwOLAcWAFea2YKEZsuBeeG0ErgjhW1vAZ5193nAs+G8iIicIKkcASwBtrr7NnfvAB4FViS0WQE85IF1wEQzqxpi2xXAg+H7B4FLRvZVRERkOFIJgBnAzrj5unBZKm0G23aauzcAhK9TU++2iIiMVCoBkOwGHYmX3h2rTSrbDv7hZivNrNbMahsbG4ezqYiIDCKVAKgDZsXNzwTqU2wz2La7w2Eiwtc9yT7c3e9y98XuvriyMr13whMRibJULgR7GZhnZnOBXcAVwFUJbdYAN5vZo8BSoNndG8yscZBt1wDXAreGrz8dqiOvvPLKXjN7P4U+JzMF2Huc2+Yj/R799FsMpN9joHz4PX4n2cIhA8Ddu8zsZuBpIAbc5+6bzWxVuP5OYC1wMbAVaAGuH2zbcNe3AqvN7AZgB3BZCn057kMAM6tN9lDkqNLv0U+/xUD6PQbK59/D3E/MnfQyLZ//Rzwe+j366bcYSL/HQPn8e+hKYBGRiIpSANyV6Q5kGf0e/fRbDKTfY6C8/T0iMwQkIiIDRekIQERE4igAREQiKhIBMNTdTKPCzGaZ2XNm9paZbTazr2S6T9nAzGJm9pqZ/TzTfck0M5toZo+b2dvh/0/OzXSfMsXMvhb+d/KGmT1iZsN7EHIOyPsASPFuplHRBXzd3U8HaoCbIvxbxPsK8FamO5Elvg/8h7ufBiwkor+Lmc0A/gxY7O4fJriO6YrM9ir98j4ASO1uppHg7g3u/mr4/hDBf9yJN/aLFDObCXwKuCfTfck0M5sAXADcC+DuHe7elNFOZVYhUGZmhcAYjr4FTs6LQgCkcjfTyDGzOcBZwPoMdyXTvgf8JdCT4X5kg2qgEbg/HBK7x8zGZrpTmeDuu4BvE9yloIHg9jb/mdlepV8UAmDEdyTNN2Y2DngC+Kq7H8x0fzLFzD4N7HH3VzLdlyxRCJwN3OHuZwFHiOiDmsInFK4A5gInAWPN7I8y26v0i0IApHI308gwsyKCP/4Pu/uTme5Php0PfMbM3iMYGvy4mf0os13KqDqgzt17jwofJwiEKPoksN3dG929E3gSOC/DfUq7KARA391MzayYoJCzJsN9yggzM4Lx3bfc/buZ7k+muftfu/tMd59D8P+L/3b3vPtXXqrc/QNgp5mdGi76BPBmBruUSTuAGjMbE/538wnysCCeyu2gc9oQdySNmvOBq4HXzWxDuOwb7r42c12SLPNl4OHwH0vbCO/sGzXuvt7MHgdeJTh77jXy8JYQuhWEiEhERWEISEREklAAiIhElAJARCSiFAAiIhGlABARiSgFgIhIRCkAREQi6v8DO+wIDEqK8+EAAAAASUVORK5CYII=\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"plt.plot(losses_train_epoch)\n",
"plt.plot(losses_valid_epoch)"
]
},
{
"cell_type": "code",
"execution_count": 26,
"id": "a14fc739",
"metadata": {},
"outputs": [],
"source": [
"# Instantiate data loader that processes entire shot in-order\n",
"loader_rcr = torch.utils.data.DataLoader(ds_valid, batch_size=batch_size, num_workers=0,\n",
" sampler=RandomSequenceSampler(range(len(ds_valid)), seq_length=seq_length),\n",
" collate_fn=my_collate_fn)"
]
},
{
"cell_type": "code",
"execution_count": 27,
"id": "007d22d3",
"metadata": {},
"outputs": [],
"source": [
"ds = ds_list_valid[0]\n",
"\n",
"mean = ds.predictors[\"ae_prob\"].data_mean.cpu()\n",
"std = ds.predictors[\"ae_prob\"].data_std.cpu()"
]
},
{
"cell_type": "code",
"execution_count": 28,
"id": "66836a91",
"metadata": {},
"outputs": [],
"source": [
"# Compile sequential output for an entire shot.\n",
"\n",
"output_list = []\n",
"target_list = []\n",
"\n",
"for i, (data, target) in enumerate(loader_rcr):\n",
" with torch.no_grad():\n",
" output_list.append(model(data).cpu() * std + mean)\n",
" target_list.append(target.cpu() * std + mean)\n",
" \n",
"targets = torch.cat([t[0, :, :] for t in target_list])\n",
"outputs = torch.cat(output_list)"
]
},
{
"cell_type": "code",
"execution_count": 29,
"id": "809527b7",
"metadata": {},
"outputs": [],
"source": [
"def make_pred_plots(outputs, targets, epoch=None):\n",
" \"\"\"Plots predicted vs true change in AE probability.\"\"\"\n",
" ax_dx, ax_dy = 0.15, 0.15\n",
"\n",
" fig_vs = plt.figure(figsize=(12, 6))\n",
" ax_list = []\n",
" # Plot\n",
" for i in range(5):\n",
" ax_list.append(fig_vs.add_axes([0.1 + i * ax_dx, 0.1, ax_dx, ax_dy]))\n",
" ax_list[i].plot([0.0, 1.0], [0.0, 1.0], 'k', alpha=0.5)\n",
" ax_list[i].plot(outputs[:, i].cpu(), targets[:, i].cpu(), '.', ms=1)\n",
" ax_list[i].set_xlim((0.0, 1.0))\n",
" ax_list[i].set_ylim((0.0, 1.0))\n",
"\n",
" # Pretty-fy\n",
" for i, ax in enumerate(ax_list):\n",
" ax.xaxis.set_major_locator(MultipleLocator(0.25))\n",
" ax.xaxis.set_minor_locator(MultipleLocator(0.05))\n",
" \n",
" ax.yaxis.set_major_locator(MultipleLocator(0.25))\n",
" ax.yaxis.set_minor_locator(MultipleLocator(0.05))\n",
" \n",
" ax.set_xlabel(\"predicted\")\n",
" ax.set_title(f\"AE mode {i}\")\n",
" \n",
" for ax in ax_list[1:4]:\n",
" ax.yaxis.set_ticklabels([])\n",
"\n",
" ax_list[0].set_ylabel(\"True\")\n",
" ax_list[4].yaxis.tick_right()\n",
"\n",
" try:\n",
" fig_vs.text(0.5, 0.3, f\"epoch {epoch:03d}: d(Probability of AE modes) / dt\", ha=\"center\")\n",
" except TypeError: # When epoch is None\n",
" fig_vs.text(0.5, 0.3, f\"Probability of AE modes: True vs. predicted\", ha=\"center\")\n",
"\n",
" return fig_vs"
]
},
{
"cell_type": "code",
"execution_count": 31,
"id": "c80fc854",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 864x432 with 5 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"res = make_pred_plots(outputs, targets);"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"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.10.4"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment