diff --git a/anp-rnn_1d_regression.ipynb b/anp-rnn_1d_regression.ipynb deleted file mode 100644 index 62a35c4..0000000 --- a/anp-rnn_1d_regression.ipynb +++ /dev/null @@ -1,1174 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "This notebook tests various neural processes on a toy 1d regression problem. The problem is from the [deep mind papers](https://github.com/deepmind/neural-processes).\n", - "\n", - "Results:\n", - "\n", - "|model|val_loss|\n", - "|-----|---------|\n", - "|ANP-RNN| -0.62|\n", - "| ANP-RNN(impr)| -1.3217|\n", - "| ANP| -0.4228|\n", - "| ANP(impr)| -0.3182|\n", - "| NP| |" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": { - "ExecuteTime": { - "end_time": "2020-03-15T07:26:29.324576Z", - "start_time": "2020-03-15T07:26:29.284683Z" - } - }, - "outputs": [], - "source": [ - "%matplotlib inline\n", - "%reload_ext autoreload" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": { - "ExecuteTime": { - "end_time": "2020-03-15T07:26:29.596545Z", - "start_time": "2020-03-15T07:26:29.587472Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Populating the interactive namespace from numpy and matplotlib\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/wassname/.pyenv/versions/3.7.2/envs/jup3.7.2/lib/python3.7/site-packages/IPython/core/magics/pylab.py:160: UserWarning: pylab import has clobbered these variables: ['test', 'plt']\n", - "`%matplotlib` prevents importing * from pylab and numpy\n", - " \"\\n`%matplotlib` prevents importing * from pylab and numpy\"\n" - ] - } - ], - "source": [ - "import pandas as pd\n", - "import numpy as np\n", - "import matplotlib as plt\n", - "import collections\n", - "from tqdm.auto import tqdm\n", - "from tensorboardX import SummaryWriter\n", - "\n", - "import math\n", - "%pylab inline" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": { - "ExecuteTime": { - "end_time": "2020-03-15T07:26:29.837313Z", - "start_time": "2020-03-15T07:26:29.833007Z" - } - }, - "outputs": [], - "source": [ - "import torch\n", - "from torch import nn\n", - "import torch.nn.functional as F\n", - "from torch.utils.data import TensorDataset, DataLoader" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": { - "ExecuteTime": { - "end_time": "2020-03-15T07:26:30.086442Z", - "start_time": "2020-03-15T07:26:30.081435Z" - } - }, - "outputs": [], - "source": [ - "from neural_processes.data.gp_curves import GPCurvesReader\n", - "from neural_processes.models.model import LatentModel" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Util" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": { - "ExecuteTime": { - "end_time": "2020-03-15T07:26:31.166314Z", - "start_time": "2020-03-15T07:26:31.161096Z" - } - }, - "outputs": [], - "source": [ - "def set_seed(n=42):\n", - " np.random.seed(n)\n", - " torch.manual_seed(n)\n", - "# torch.backends.cudnn.deterministic = True\n", - "# torch.backends.cudnn.benchmark = False" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": { - "ExecuteTime": { - "end_time": "2020-03-15T07:26:31.355499Z", - "start_time": "2020-03-15T07:26:31.343493Z" - } - }, - "outputs": [], - "source": [ - "def plot_functions(target_x, target_y, context_x, context_y, pred_y, std):\n", - " \"\"\"Plots the predicted mean and variance and the context points.\n", - " \n", - " Args: \n", - " target_x: An array of shape [B,num_targets,1] that contains the\n", - " x values of the target points.\n", - " target_y: An array of shape [B,num_targets,1] that contains the\n", - " y values of the target points.\n", - " context_x: An array of shape [B,num_contexts,1] that contains \n", - " the x values of the context points.\n", - " context_y: An array of shape [B,num_contexts,1] that contains \n", - " the y values of the context points.\n", - " pred_y: An array of shape [B,num_targets,1] that contains the\n", - " predicted means of the y values at the target points in target_x.\n", - " std: An array of shape [B,num_targets,1] that contains the\n", - " predicted std dev of the y values at the target points in target_x.\n", - " \"\"\"\n", - " # Plot everything\n", - " plt.plot(target_x[0], pred_y[0], 'b', linewidth=2)\n", - " plt.plot(target_x[0], target_y[0], 'k:', linewidth=2)\n", - " plt.plot(context_x[0], context_y[0], 'ko', markersize=10)\n", - " plt.fill_between(\n", - " target_x[0, :, 0],\n", - " pred_y[0, :, 0] - std[0, :, 0],\n", - " pred_y[0, :, 0] + std[0, :, 0],\n", - " alpha=0.25,\n", - " facecolor='blue',\n", - " interpolate=True)\n", - "\n", - " # Make the plot pretty\n", - " plt.yticks([-2, 0, 2], fontsize=16)\n", - " plt.xticks([-2, 0, 2], fontsize=16)\n", - " plt.ylim([-2, 2])\n", - " plt.grid('off')\n", - " ax = plt.gca()" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "metadata": { - "ExecuteTime": { - "end_time": "2020-03-15T07:31:27.293507Z", - "start_time": "2020-03-15T07:31:27.270845Z" - } - }, - "outputs": [], - "source": [ - "def test(model, dataset_test, writer=None, plot=False, global_step=None, seed=42, title=''):\n", - " model.eval()\n", - " with torch.no_grad():\n", - " data_test = dataset_test.generate_curves()\n", - "\n", - " (context_x, context_y), target_x = data_test.query\n", - " target_y = data_test.target_y\n", - "\n", - " context_x = context_x.cuda()\n", - " context_y = context_y.cuda()\n", - " target_x = target_x.cuda()\n", - " target_y = target_y.cuda()\n", - "\n", - "# y_pred, kl, loss, mse_loss, y_std\n", - " y_pred, losses, extra = model(context_x, context_y, target_x, target_y)\n", - " y_std = extra['dist'].scale\n", - "\n", - " # Lets order the result, for plotting\n", - " target_inds = torch.argsort(target_x[0, :, 0])\n", - " target_x = target_x[:, target_inds, :]\n", - " target_y = target_y[:, target_inds, :]\n", - " context_inds = torch.argsort(context_x[0, :, 0])\n", - " context_y = context_y[:, context_inds, :]\n", - " context_x = context_x[:, context_inds, :]\n", - " y_pred = y_pred[:, target_inds, :]\n", - " y_std = y_std[:, target_inds, :]\n", - " \n", - " if writer is not None:\n", - " writer.add_scalar('val/loss', losses[\"loss\"], global_step=global_step)\n", - " writer.add_scalar('val/y_std', y_std.mean(), global_step=global_step)\n", - " writer.add_scalar('val/mse_loss', losses[\"loss_mse\"], global_step=global_step)\n", - " writer.add_scalar('val/kl', losses[\"loss_kl\"].mean(), global_step=global_step)\n", - " \n", - " if plot:\n", - " set_seed(seed)\n", - " fig = plt.figure()\n", - " plt.title(f\"{title}. Iter {global_step}\") \n", - " plot_functions(target_x.detach().cpu().numpy(),\n", - " target_y.detach().cpu().numpy(),\n", - " context_x.detach().cpu().numpy(),\n", - " context_y.detach().cpu().numpy(),\n", - " y_pred.detach().cpu().numpy(),\n", - " y_std.detach().cpu().numpy())\n", - " \n", - " writer.add_figure('test', fig, global_step=global_step, close=False)\n", - " plt.show()\n", - " \n", - " return y_pred, losses[\"loss_kl\"], losses[\"loss\"], y_std" - ] - }, - { - "cell_type": "code", - "execution_count": 33, - "metadata": { - "ExecuteTime": { - "end_time": "2020-03-15T07:31:27.470761Z", - "start_time": "2020-03-15T07:31:27.465244Z" - } - }, - "outputs": [], - "source": [ - "def evaluate(model, dataset_test, n=100):\n", - " return torch.stack([\n", - " test(model, dataset_test)[2] for _ in tqdm(range(n))\n", - " ]).mean().cpu()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Init" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "metadata": { - "ExecuteTime": { - "end_time": "2020-03-15T07:31:27.808592Z", - "start_time": "2020-03-15T07:31:27.796659Z" - } - }, - "outputs": [], - "source": [ - "MAX_CONTEXT_POINTS = 50\n", - "random_kernel_parameters = True\n", - "\n", - "dataset_train = GPCurvesReader(\n", - " batch_size=16,\n", - " max_num_context=MAX_CONTEXT_POINTS,\n", - " random_kernel_parameters=random_kernel_parameters,\n", - " sequential=True,\n", - ")\n", - "\n", - "dataset_test = GPCurvesReader(\n", - " batch_size=1,\n", - " max_num_context=MAX_CONTEXT_POINTS,\n", - " testing=True,\n", - " random_kernel_parameters=random_kernel_parameters,\n", - " sequential=True,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Replicate ANP paper" - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "metadata": { - "ExecuteTime": { - "end_time": "2020-03-15T07:31:28.071408Z", - "start_time": "2020-03-15T07:31:28.066209Z" - } - }, - "outputs": [], - "source": [ - "epochs = 100000\n", - "PLOT_AFTER = sorted(set([100, 200, 400, 1000, 2000, 4000, 8000] + list(range(0, epochs+1, 10000))))\n", - "PRINT_AFTER = 1000" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "ExecuteTime": { - "end_time": "2020-02-15T07:19:07.054039Z", - "start_time": "2020-02-15T07:19:07.044472Z" - } - }, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 36, - "metadata": { - "ExecuteTime": { - "end_time": "2020-03-15T07:31:46.700930Z", - "start_time": "2020-03-15T07:31:28.464980Z" - }, - "scrolled": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "runs/Mar15_15-31-28_mjcdesktop-anp-rnn_1d_reg\n" - ] - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "ebe1609e16714bff9edd1a17fdaed5ce", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "HBox(children=(FloatProgress(value=0.0, max=100000.0), HTML(value='')))" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "86e7dbfceaee4232b28d8a3d6c9487ef", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "HBox(children=(FloatProgress(value=0.0), HTML(value='')))" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "train: 0 loss= 1.219 val_loss= 0.9614\n" - ] - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - }, - { - "ename": "KeyboardInterrupt", - "evalue": "", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 35\u001b[0m \u001b[0my_std\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mextra\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'dist'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mscale\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 36\u001b[0m \u001b[0mloss\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlosses\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'loss'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 37\u001b[0;31m \u001b[0mloss\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbackward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 38\u001b[0m \u001b[0moptim\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstep\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 39\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/.pyenv/versions/3.7.2/envs/jup3.7.2/lib/python3.7/site-packages/torch/tensor.py\u001b[0m in \u001b[0;36mbackward\u001b[0;34m(self, gradient, retain_graph, create_graph)\u001b[0m\n\u001b[1;32m 164\u001b[0m \u001b[0mproducts\u001b[0m\u001b[0;34m.\u001b[0m \u001b[0mDefaults\u001b[0m \u001b[0mto\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m`\u001b[0m\u001b[0;31m`\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;31m`\u001b[0m\u001b[0;31m`\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 165\u001b[0m \"\"\"\n\u001b[0;32m--> 166\u001b[0;31m \u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mautograd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbackward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mgradient\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mretain_graph\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcreate_graph\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 167\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 168\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mregister_hook\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mhook\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/.pyenv/versions/3.7.2/envs/jup3.7.2/lib/python3.7/site-packages/torch/autograd/__init__.py\u001b[0m in \u001b[0;36mbackward\u001b[0;34m(tensors, grad_tensors, retain_graph, create_graph, grad_variables)\u001b[0m\n\u001b[1;32m 97\u001b[0m Variable._execution_engine.run_backward(\n\u001b[1;32m 98\u001b[0m \u001b[0mtensors\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mgrad_tensors\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mretain_graph\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcreate_graph\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 99\u001b[0;31m allow_unreachable=True) # allow_unreachable flag\n\u001b[0m\u001b[1;32m 100\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 101\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mKeyboardInterrupt\u001b[0m: " - ] - } - ], - "source": [ - "\n", - "\n", - "writer = SummaryWriter(comment='-anp-rnn_1d_reg')\n", - "print(writer.logdir)\n", - "\n", - "hparams = dict(\n", - " x_dim=1,\n", - " y_dim=1,\n", - " hidden_dim=128,\n", - " latent_dim=128,\n", - " latent_enc_self_attn_type=\"uniform\",\n", - " det_enc_self_attn_type=\"uniform\",\n", - " det_enc_cross_attn_type=\"multihead\",\n", - " use_rnn=True)\n", - "model = LatentModel(**hparams).cuda()\n", - "\n", - "optim = torch.optim.Adam(model.parameters(), lr=1e-4)\n", - "\n", - "for n_iter in tqdm(range(epochs)):\n", - " model.train()\n", - "\n", - " data_train = dataset_train.generate_curves()\n", - "\n", - " (context_x, context_y), target_x = data_train.query\n", - " target_y = data_train.target_y\n", - "\n", - " context_x = context_x.cuda()\n", - " context_y = context_y.cuda()\n", - " target_x = target_x.cuda()\n", - " target_y = target_y.cuda()\n", - "\n", - " optim.zero_grad()\n", - " y_pred, losses, extra = model(context_x, context_y, target_x,\n", - " target_y)\n", - " y_std = extra['dist'].scale\n", - " loss = losses['loss']\n", - " loss.backward()\n", - " optim.step()\n", - "\n", - " writer.add_scalar('train/loss', loss, n_iter)\n", - " writer.add_scalar('train/mse', losses['loss_mse'], n_iter)\n", - " writer.add_scalar('train/y_std', y_std.mean(), n_iter)\n", - " writer.add_scalar('train/kl', losses['loss_kl'].mean(), n_iter)\n", - "\n", - " if n_iter % PRINT_AFTER == 0:\n", - " y_pred, kl, val_loss, y_std = test(\n", - " model, dataset_test, writer, plot=False, global_step=n_iter)\n", - " val_loss = evaluate(model, dataset_test, 100)\n", - " writer.add_scalar('val/loss_mean', val_loss, n_iter)\n", - " print(\n", - " f\"train: {n_iter} loss={loss.item(): 4.4g} val_loss={val_loss.item(): 4.4g}\"\n", - " )\n", - "\n", - " if n_iter in PLOT_AFTER:\n", - " test(model, dataset_test, writer, plot=True, global_step=n_iter, title='test')\n", - " \n", - " test(model, dataset_train, writer, plot=True, global_step=n_iter, seed=n_iter, title='train')\n", - " \n", - " # Final validation\n", - "val_loss = evaluate(model, dataset_test, 300)\n", - "print('val loss (n=300)', loss)\n", - "writer.add_hparams(hparams, dict(val_loss=loss))\n", - "\n", - "for i in range(3):\n", - " set_seed(i)\n", - " test(model, dataset_test, writer, plot=True, global_step=-1, seed=i, title='test_final')\n", - " \n", - "for i in range(3):\n", - " test(model, dataset_train, writer, plot=True, global_step=-1, seed=i, title='train_final')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "ExecuteTime": { - "end_time": "2020-02-15T07:11:03.866882Z", - "start_time": "2020-02-15T07:09:00.100Z" - } - }, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "ExecuteTime": { - "end_time": "2020-02-15T07:11:03.868460Z", - "start_time": "2020-02-15T07:09:00.100Z" - }, - "scrolled": true - }, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": { - "ExecuteTime": { - "end_time": "2020-02-01T03:26:03.797075Z", - "start_time": "2020-02-01T03:19:32.800Z" - } - }, - "source": [ - "## Improved\n", - "\n", - "These have no tbeen extensively tested:" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "metadata": { - "ExecuteTime": { - "end_time": "2020-03-15T07:31:49.606656Z", - "start_time": "2020-03-15T07:31:49.420978Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "runs/Mar15_15-31-49_mjcdesktop-anp-rnn_1d_impr\n" - ] - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "7008497847134666929acfcaa114da71", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "HBox(children=(FloatProgress(value=0.0, max=100000.0), HTML(value='')))" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "ename": "ValueError", - "evalue": "not enough values to unpack (expected 5, got 3)", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 37\u001b[0m \u001b[0moptim\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mzero_grad\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 38\u001b[0m y_pred, kl, loss, mse_loss, y_std = model(context_x, context_y, target_x,\n\u001b[0;32m---> 39\u001b[0;31m target_y)\n\u001b[0m\u001b[1;32m 40\u001b[0m \u001b[0mloss\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbackward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 41\u001b[0m \u001b[0moptim\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstep\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mValueError\u001b[0m: not enough values to unpack (expected 5, got 3)" - ] - } - ], - "source": [ - "writer = SummaryWriter(comment='-anp-rnn_1d_impr')\n", - "print(writer.logdir)\n", - " \n", - "hparams = dict(\n", - " x_dim=1,\n", - " y_dim=1,\n", - " hidden_dim=128,\n", - " latent_dim=128,\n", - " latent_enc_self_attn_type=\"ptmultihead\",\n", - " det_enc_self_attn_type=\"uniform\",\n", - " det_enc_cross_attn_type=\"uniform\",\n", - " use_rnn=True,\n", - " min_std=1e-3,\n", - " use_lvar=True,\n", - " use_self_attn=True,\n", - "# attention_dropout=0.3,\n", - "# dropout=0.3,\n", - "# batchnorm=True,\n", - ")\n", - "model = LatentModel(**hparams).cuda()\n", - "\n", - "optim = torch.optim.AdamW(model.parameters(), lr=1e-4)\n", - "\n", - "for n_iter in tqdm(range(epochs)):\n", - " model.train()\n", - "\n", - " data_train = dataset_train.generate_curves()\n", - "\n", - " (context_x, context_y), target_x = data_train.query\n", - " target_y = data_train.target_y\n", - "\n", - " context_x = context_x.cuda()\n", - " context_y = context_y.cuda()\n", - " target_x = target_x.cuda()\n", - " target_y = target_y.cuda()\n", - "\n", - " optim.zero_grad()\n", - " y_pred, losses, extra = model(context_x, context_y, target_x,\n", - " target_y)\n", - " y_std = extra['dist'].scale\n", - " loss = losses['loss']\n", - " loss.backward()\n", - " optim.step()\n", - "\n", - " writer.add_scalar('train/loss', loss, n_iter)\n", - " writer.add_scalar('train/mse', losses['loss_mse'], n_iter)\n", - " writer.add_scalar('train/y_std', y_std.mean(), n_iter)\n", - " writer.add_scalar('train/kl', losses['loss_kl'].mean(), n_iter)\n", - "\n", - " if n_iter % PRINT_AFTER == 0:\n", - " y_pred, kl, val_loss, y_std = test(\n", - " model, dataset_test, writer, plot=False, global_step=n_iter)\n", - " val_loss = evaluate(model, dataset_test, 100)\n", - " writer.add_scalar('val/loss_mean', val_loss, n_iter)\n", - " print(\n", - " f\"train: {n_iter} loss={loss.item(): 4.4g} val_loss={val_loss.item(): 4.4g}\"\n", - " )\n", - "\n", - " if n_iter in PLOT_AFTER:\n", - " test(model, dataset_test, writer, plot=True, global_step=n_iter, title='test')\n", - " \n", - " test(model, dataset_train, writer, plot=True, global_step=n_iter, seed=n_iter, title='train')\n", - " \n", - " # Final validation\n", - "val_loss = evaluate(model, dataset_test, 300)\n", - "print('val loss (n=300)', loss)\n", - "writer.add_hparams(hparams, dict(val_loss=loss))\n", - "\n", - "for i in range(3):\n", - " set_seed(i)\n", - " test(model, dataset_test, writer, plot=True, global_step=-1, seed=i, title='test_final')\n", - " \n", - "for i in range(3):\n", - " test(model, dataset_train, writer, plot=True, global_step=-1, seed=i, title='train_final')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": { - "ExecuteTime": { - "end_time": "2020-02-15T07:11:03.881881Z", - "start_time": "2020-02-15T07:11:00.000Z" - } - }, - "source": [ - "# ANP" - ] - }, - { - "cell_type": "code", - "execution_count": 39, - "metadata": { - "ExecuteTime": { - "end_time": "2020-03-15T07:32:41.919168Z", - "start_time": "2020-03-15T07:32:41.748195Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "runs/Mar15_15-32-41_mjcdesktop-anp_1d\n" - ] - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "cab4131fc33b4b5887f5fed9e8b8eaee", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "HBox(children=(FloatProgress(value=0.0, max=100000.0), HTML(value='')))" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "ename": "NameError", - "evalue": "name 'mse_loss' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 37\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 38\u001b[0m \u001b[0mwriter\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_scalar\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'train/loss'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mloss\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn_iter\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 39\u001b[0;31m \u001b[0mwriter\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_scalar\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'train/mse_loss'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmse_loss\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn_iter\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 40\u001b[0m \u001b[0mwriter\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_scalar\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'train/y_std'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my_std\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmean\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn_iter\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 41\u001b[0m \u001b[0mwriter\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_scalar\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'train/kl'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkl\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmean\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn_iter\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mNameError\u001b[0m: name 'mse_loss' is not defined" - ] - } - ], - "source": [ - "writer = SummaryWriter(comment='-anp_1d')\n", - "print(writer.logdir)\n", - " \n", - "hparams = dict(\n", - " x_dim=1,\n", - " y_dim=1,\n", - " hidden_dim=128,\n", - " latent_dim=128,\n", - " latent_enc_self_attn_type=\"multihead\",\n", - " det_enc_self_attn_type=\"multihead\",\n", - " det_enc_cross_attn_type=\"multihead\",\n", - " use_rnn=False)\n", - "model = LatentModel(**hparams).cuda()\n", - "\n", - "optim = torch.optim.AdamW(model.parameters(), lr=1e-4)\n", - "\n", - "for n_iter in tqdm(range(epochs)):\n", - " model.train()\n", - "\n", - " data_train = dataset_train.generate_curves()\n", - "\n", - " (context_x, context_y), target_x = data_train.query\n", - " target_y = data_train.target_y\n", - "\n", - " context_x = context_x.cuda()\n", - " context_y = context_y.cuda()\n", - " target_x = target_x.cuda()\n", - " target_y = target_y.cuda()\n", - "\n", - " optim.zero_grad()\n", - " y_pred, losses, extra = model(context_x, context_y, target_x,\n", - " target_y)\n", - " y_std = extra['dist'].scale\n", - " loss = losses['loss']\n", - " loss.backward()\n", - " optim.step()\n", - "\n", - " writer.add_scalar('train/loss', loss, n_iter)\n", - " writer.add_scalar('train/mse', losses['loss_mse'], n_iter)\n", - " writer.add_scalar('train/y_std', y_std.mean(), n_iter)\n", - " writer.add_scalar('train/kl', losses['loss_kl'].mean(), n_iter)\n", - "\n", - " if n_iter % PRINT_AFTER == 0:\n", - " y_pred, kl, val_loss, y_std = test(\n", - " model, dataset_test, writer, plot=False, global_step=n_iter)\n", - " val_loss = evaluate(model, dataset_test, 100)\n", - " writer.add_scalar('val/loss_mean', val_loss, n_iter)\n", - " print(\n", - " f\"train: {n_iter} loss={loss.item(): 4.4g} val_loss={val_loss.item(): 4.4g}\"\n", - " )\n", - "\n", - " if n_iter in PLOT_AFTER:\n", - " test(model, dataset_test, writer, plot=True, global_step=n_iter, title='test')\n", - " \n", - " test(model, dataset_train, writer, plot=True, global_step=n_iter, seed=n_iter, title='train')\n", - " \n", - " # Final validation\n", - "val_loss = evaluate(model, dataset_test, 300)\n", - "print('val loss (n=300)', loss)\n", - "writer.add_hparams(hparams, dict(val_loss=loss))\n", - "\n", - "for i in range(3):\n", - " set_seed(i)\n", - " test(model, dataset_test, writer, plot=True, global_step=-1, seed=i, title='test_final')\n", - " \n", - "for i in range(3):\n", - " test(model, dataset_train, writer, plot=True, global_step=-1, seed=i, title='train_final')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 38, - "metadata": { - "ExecuteTime": { - "end_time": "2020-03-15T07:32:36.664221Z", - "start_time": "2020-03-15T07:32:36.471985Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "runs/Mar15_15-32-36_mjcdesktop-anp_1d_impr\n" - ] - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "ab86ce89f8854dec89db5277bbdf4638", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "HBox(children=(FloatProgress(value=0.0, max=100000.0), HTML(value='')))" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "ename": "NameError", - "evalue": "name 'mse_loss' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 38\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 39\u001b[0m \u001b[0mwriter\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_scalar\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'train/loss'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mloss\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn_iter\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 40\u001b[0;31m \u001b[0mwriter\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_scalar\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'train/mse_loss'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmse_loss\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn_iter\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 41\u001b[0m \u001b[0mwriter\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_scalar\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'train/y_std'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0my_std\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmean\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn_iter\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 42\u001b[0m \u001b[0mwriter\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd_scalar\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'train/kl'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkl\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmean\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn_iter\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mNameError\u001b[0m: name 'mse_loss' is not defined" - ] - } - ], - "source": [ - "writer = SummaryWriter(comment='-anp_1d_impr')\n", - "print(writer.logdir)\n", - " \n", - "hparams = dict(\n", - " x_dim=1,\n", - " y_dim=1,\n", - " hidden_dim=128,\n", - " latent_dim=128,\n", - " latent_enc_self_attn_type=\"ptmultihead\",\n", - " det_enc_self_attn_type=\"ptmultihead\",\n", - " det_enc_cross_attn_type=\"ptmultihead\",\n", - " use_lvar=True,\n", - " use_rnn=False)\n", - "model = LatentModel(**hparams).cuda()\n", - "\n", - "optim = torch.optim.AdamW(model.parameters(), lr=1e-4)\n", - "\n", - "for n_iter in tqdm(range(epochs)):\n", - " model.train()\n", - "\n", - " data_train = dataset_train.generate_curves()\n", - "\n", - " (context_x, context_y), target_x = data_train.query\n", - " target_y = data_train.target_y\n", - "\n", - " context_x = context_x.cuda()\n", - " context_y = context_y.cuda()\n", - " target_x = target_x.cuda()\n", - " target_y = target_y.cuda()\n", - "\n", - " optim.zero_grad()\n", - " y_pred, losses, extra = model(context_x, context_y, target_x,\n", - " target_y)\n", - " y_std = extra['dist'].scale\n", - " loss = losses['loss']\n", - " loss.backward()\n", - " optim.step()\n", - "\n", - " writer.add_scalar('train/loss', loss, n_iter)\n", - " writer.add_scalar('train/mse', losses['loss_mse'], n_iter)\n", - " writer.add_scalar('train/y_std', y_std.mean(), n_iter)\n", - " writer.add_scalar('train/kl', losses['loss_kl'].mean(), n_iter)\n", - "\n", - " if n_iter % PRINT_AFTER == 0:\n", - " y_pred, kl, val_loss, y_std = test(\n", - " model, dataset_test, writer, plot=False, global_step=n_iter)\n", - " val_loss = evaluate(model, dataset_test, 100)\n", - " writer.add_scalar('val/loss_mean', val_loss, n_iter)\n", - " print(\n", - " f\"train: {n_iter} loss={loss.item(): 4.4g} val_loss={val_loss.item(): 4.4g}\"\n", - " )\n", - "\n", - " if n_iter in PLOT_AFTER:\n", - " test(model, dataset_test, writer, plot=True, global_step=n_iter, title='test')\n", - " \n", - " test(model, dataset_train, writer, plot=True, global_step=n_iter, seed=n_iter, title='train')\n", - " \n", - " # Final validation\n", - "val_loss = evaluate(model, dataset_test, 300)\n", - "print('val loss (n=300)', loss)\n", - "writer.add_hparams(hparams, dict(val_loss=loss))\n", - "\n", - "for i in range(3):\n", - " set_seed(i)\n", - " test(model, dataset_test, writer, plot=True, global_step=-1, seed=i, title='test_final')\n", - " \n", - "for i in range(3):\n", - " test(model, dataset_train, writer, plot=True, global_step=-1, seed=i, title='train_final')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "markdown", - "metadata": { - "ExecuteTime": { - "end_time": "2020-02-15T07:12:16.785888Z", - "start_time": "2020-02-15T07:12:16.782565Z" - } - }, - "source": [ - "# NP" - ] - }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": { - "ExecuteTime": { - "end_time": "2020-03-15T07:33:23.822594Z", - "start_time": "2020-03-15T07:33:17.220214Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "runs/Mar15_15-33-17_mjcdesktop-np_1d\n" - ] - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "cdb23cbdb35f4eb68d6d1450b67d174a", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "HBox(children=(FloatProgress(value=0.0, max=100000.0), HTML(value='')))" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "application/vnd.jupyter.widget-view+json": { - "model_id": "04d16e8da8ab40e8accbcd649afe19f8", - "version_major": 2, - "version_minor": 0 - }, - "text/plain": [ - "HBox(children=(FloatProgress(value=0.0), HTML(value='')))" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "train: 0 loss= 0.8093 val_loss= 0.8741\n" - ] - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAX4AAAENCAYAAAAIbA6TAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjAsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+17YcXAAAgAElEQVR4nO3de3wU9b3/8dcnm5AL4aZyECnKRcWC4g3x1lZE8FL10FpE6wGtSBGp/IpSLVqqKeDR9hRTW1FPxR5RPKcVjlYppeKF2KMCFYtQQbEGFY0CcjEQkpBk8/39sdlkk+wmu8lespn38/GYx87OzuUb2H3PzPf7nRlzziEiIt6RkeoCiIhIcin4RUQ8RsEvIuIxCn4REY9R8IuIeIyCX0TEYxT84jlm9oiZ/TTV5RBJFQW/pBUz+8jMxrRnHc65ac65eXEqjzOzY+vGC8xsSTzW22Qbt5jZDjPbb2a/M7PseG9DvEXBL52KmWWmugxtFa7sZnYRMBu4ADgGGAT8LMlFk05GwS9pw8yeBI4GlptZmZndbmYD6o66bzCz7cArdfMurTtKLjWzv5rZsJD1PG5m8+vGR5nZp2Y2y8x2mdnnZnZ9G8p2MXAncFVd2TbWTe9hZo/VrbfEzOabma/us++Z2etmVmhme4CCMKu+DnjMObfZObcPmAd8L9byiYRS8EvacM5NArYDlzvn8p1zvwj5+Dzgq8BFde9XAscB/wL8HXiqhVUfCfQA+gE3AAvNrFeMZfsL8O/AH+rKdnLdR48DNcCxwKnAhcCUkEXPBLYBfYB7wqx6GLAx5P1GoI+ZHR5L+URCKfilsyhwzh10zlUAOOd+55w74Jw7ROBI+mQz6xFh2WpgrnOu2jn3Z6AMGNLeAplZH+CbwMy6su0CCoGrQ2b7zDn3G+dcTbDsTeQDpSHvg+Pd2ls+8a60rQ8VaeKT4EhdVco9wJVAb6C27qMjaByiQXucczUh78sJBG57HQNkAZ+bWXBaRmhZm4yHUwZ0D3kfHD8Qh/KJR+mIX9JNpNvJhk6/BhgHjCFQhTOgbrqRWE3L9glwCDjCOdezbujunBvWwjJNbQZODnl/MrDTOben/cUVr1LwS7rZSaBnS0u6EQjcPUAegbr3ZNgJDDCzDADn3OfAKmCBmXU3swwzG2xm58WwzieAG8xsqJn1BOYQaDcQaTMFv6Sbe4E5Zvalmf0owjxPAB8DJcAWYG1bN2Zmd5rZyihnX1r3usfM/l43fi3Qpa4c+4BlQN9ot1/XaPwLYDWBhu2PgbujXV4kHEvUg1jMbDzwXWAEgZ4V24FngH93zql+UkQkRRIZ/GsJhP1zwKcEurIVAO8B5zjnaiMvLSIiiZLI4O/tnPuiybRrgcXABc65VxKyYRERaVHC6vibhn6dN+te+yVquyIi0rJkN+4GezO8m+TtiohInYRV9TTbkFk/YAOw0Tk3NsI8U4GpALm5uaf3798/pm3U1taSkaGOSpIa+v5JqoR+995///3dzrneLc2flOA3s3ygCDgKGOmc+7S1ZUaMGOHWr18f03aKiooYNWpUW4oo0m76/kmqhH73zOwt59yIluZP+C0bzCwXWE7gopvzogl9ERFJnIQGv5llEbhgZQQw1jn3j0RuT0REWpew4K+7bP0pYDRwmXOuzVdPiohI/CTyiH8hgbsj3gMcNLOzQj77VFU+IiKpkcguCJfUvf4EWNNkmBJpIRERSayEHfE75wYkat0iItJ26nQsIuIxCn4REY9R8IuIeIyCX0TEYxT8IiIeo+AXEfEYBb+IiMco+EVEPEbBLyLiMQp+ERGPUfCLiHiMgl9ExGMU/CIiHqPgFxHxGAW/iIjHKPhFRDxGwS8i4jEKfhERj1Hwi4h4jIJfRMRjFPwiIh6j4BcR8RgFv4iIxyj4RUQ8RsEvIuIxCn4REY9R8IuIeIyCX0TEYxT8IiIeo+AXEfEYBb+IiMco+EVEPEbBLyLiMQp+ERGPUfCLiHiMgl9ExGMU/CIiHqPgFxHxGAW/iIjHKPhFRDxGwS8i4jEKfhERj1Hwi4h4jIJfRMRjFPwiIh6j4BcR8RgFv4iIxyj4RUQ8RsEvIuIxCn4REY9R8IuIeIyCX0TEYxT8IiIeo+AXEfGYzFQXIN6cg/37wQwyMhoPodPMUl1SEZHU6HTBX1MDGza0Pl9wJ9DaDqK16e2Z1+cLvIqIJFOnC/5oOQd+f6pLERBuZ9DWaT4fZGY2jIcOIiLg4eDvSGprA0MiBc82QncEkXYQmZmBISur+bh2ICLpT8HvEcEznPae5WRkNN4RRHoNN01EOgb9HCUmtbVQVRUYYmEW+Uwi9Cwj3FlI6JmK2kTEucavLYnUicPrnTsU/JIUzkF1dWCoqGjfupq2bzTtrRXtuFlDAER6jXaaWaBjwa5dbV9HOE3naRp6zjUMtbWNXyNNCx1C19HaeCzzhluutdeWxmMJ+1i09v8f/I6EDk2/Q6191yJ99yK9dusWOCBKJAW/pJ14VFklQmUlbNmS6lJILBK1Q2mP4cPhsMMSuw2dOIuIeIyCX0TEYxT8IiIeo+AXEfEYBb+IiMco+EVEPEbBLyLiMQp+ERGPUfCLiHiMgl9ExGMU/CIiHqPgFxHxGAW/iIjHKPhFRDxGwS8i4jEKfhERj1Hwi4h4jIJfRMRjOk3wFxcXU1hYyOGHd2f06AwuvbQ7hYXTKSkpTnXRREQ6lE4R/CtXrmT48OGsWLGCAwcO4JyjvPwAK1YsYsqU4axbtzLVRRQR6TDSPviLi4sZP3485eXl+Js8gdvvr6ayspyCgvFtPvIvKSmmsHA6l16qMwkR6RzSPvgXLFhAdXV1i/NUV1ezdGlhzOtet24lU6YMZ8WKRZSX60xCRDqHtA/+JUuWtBr8fn81q1YtprR0D7W1tVGtt6SkmIKC8VRWluP3N15/PM4kRERSJe2Dv6ysLKr5KirK+Na3jmDz5jfqpxUVLWXevO/y2mt/bDTfO++8weLFBQk7kxARSaW0D/78/Pyo5svI8JGf35OePf+lftp77/2NV175Pdu3v1c/bdu2fzBjxrm8/PJ/NzvSb8rvr+bFF59sW8FFRFIk7YN/4sSJZGVltTiPz5fF5ZdPY/nyffTvf3z99AsvvJY773ySs8++rH6aWQZf/eqZUVcJVVQEzjjUCCwi6SLtg3/WrFmtBn9WVhZXXnlLs+mDBp3E2LETGTjwxPppQ4eeyUMPrSUvr1tU28/JyVMjsEga2LHj42Y9/7wq7YN/8ODBLFu2jLy8PHw+X6PPfL4scnLyKChYRr9+g2Na75gxE/H5Wt6hQKC65+671Qgs0pF9+OFmpk8fyc9//r368N+z53P++MeH2Lt3R4pLl3xpH/wAl1xyCZs2beKyyy6je/fumGWQl9edyy6byqJFmzjzzEtiXueECa2fSfh8mRxzzDBqatQILNKRHTxYSmVlOfv27aw/QCsqWsoDD/yAX/1qeopLl3ydIvghcOQ/c+ZMdu8u5ZVX/KxYUcrMmQ/GfKQf1K/fYAoKlpGTk9fsyD94JnHPPc9TUvJPNQJLm6hdKHlOPPEcHnjgr8yf/xxduuQAcPTRJ3DOOZdzwQXX1M+3bds/+OEPz+OFF55IVVGTIjPVBYin8nIfl14KBw9CVlbjoUuXlt+Hm9ajxyXcddcmXn65kDfeeJLKyjJyc/MZPXoSEybcQv/+g+sbd1sT7XziDevWraSgYDzV1dX1Bw7BdqFVqxZTULCsTWeq0uCDDzZSVVXJ0KFnAnDccac2+vyMMy7kjDMubDStqGgpmzb9laOPPoGLLro2aWVNNnPOpboMYY0YMcKtX78+pmWeeeYNvvOdcxJUouYyMqC2tjtwoNV5fb7ufO1rpY12MtnZgdf2Dk2aNiRFysqKyM8f1ep8JSXFTJkynMrK8ojz5OTksWjRpjafsXpdSckHTJ9+Jn5/Db/5zRsMHDis2Ty1tVBTA35/w1BaWsqbby7nyCOHcvTRp+H3Q1VVDc5l4FwGtbWB+WprwbnAuHMN70NfQ4emy4SOB98Hh9694YYbYNCg6P/eoqIiRo0aBYCZveWcG9HS/J3qiD8/v4bly+Htt6G6umGoqmr8Pty0aOZpOi3Q43MisAhoqbonC79/Eq++mpi/2+cL7AByciA3t+E1dDwnp/nnkebr2hXy8wPrlPh7+unobzMyc+aDSSpVYvj9zX9D4X5Poa/BIdLnoa81NeFfq6sHUF19AbW1ldx227HU1jZ87vcHXsMf8/Yg8JsOegGYCRQAVyX+H6zO178eW/DHqlMFf5cutZx/fiC0Ei24t96+fRbTpy/m0KHIP+SsrCxuvvkW8vMDX7hwX/KWhkOHmv8YQj/z+6GiIjDs2xe/vzErK/BvGdwRhI537Rp+PHSevDydjYTz0ktLom4Ximfw+/2B70tlZeA1OAS/R03fN30NN3+48dDvapSXwyRAJvAU4Dh0KPIRTGZm4DsafA0OwfcVFR+zd+975OY+Rv/+V5GR0TCPWeCsPyMjMN70fXA8OIQuExz3+RreB+c78kgYODDx/zoJY2b9gUJgLGDAS8BM59z2RG43GcwCX45Bgwbzs58ta1ZfG+TzZTJv3jLOPDMxp+zBHVDwxxfcAVRUBH7gLb1GGi8vh7KywA93376WdibFwAJgCVAG5BM4WpoFBP7e3NzGO4fMzGJ2717Azp1LqKkpIysrnyFDJnLWWbPo23dw/ZlJsBostM0lMzMwLTOz4YdplpB/1hYFT+VDT9P9fjhwIIuqqsZVB01P9f1+KC+Prr2nvLyMlSsblms4mm1+EFBdHfj/C/0/Dh0qKgLzJJtZ87a0cO1q4V6DQ7jPg+OZmQ3va2oO8Le/PcqYMTPIzs4iKysLn6/huxM6BIO2te+P3z+ZF17IZOzYibTSyS9uhg+Hww5L7DYSVsdvZnnARuAQMAdwwHwgDxjunDvY0vJtqeMvKiri3HNH8frrbStze5SUFLN0aSEvvvgkFRVl5OTk8ZWvHM/s2YsZNOjE1lfQwTgXCJSyskBjeVlZw3DwIGzZspIXXxxPbW01zoUmShaQRXb2MqqqLmlyOr0SGE+gWqz5MrAMiK1BM9xRVfAHHXoUFW4waxzi4UI6dDy0HrZ9omsXCsw3ERgHXNjKvK0za6jyC7YxBXew4cZD26Ci/Tx0WlZWcnfOhYU38fzzj3DRRdcxe/bjydloArQl+DtSHf/3gUHAEOfcB3UF2gT8E7gRuD+B2066fv0GM3Pmg2lfJxtk1vBDPvzwxp+VlBTz0EPj8fvDNU4GQt1sPE88sYmePQdz8CB8+GExd989nqqqlpa5gpNPfgfnBjc6kg090g0ONTXxDOLYhe5kGnY21WRmZjWbHroD8vngiy8m8uWXLbcLmWWRl9efgwcfom/f3Zx++oWNjm5Dj3yzsxteQ9tzmrbldOmSmjOkZBk1agIbNqzmqqt+lJD1V1VV8sEHG+t7CaWzRAb/vwJrg6EP4Jz70MxeJ3AI06mCvyU1NdVs3bqeYcPOTnVR4iLaxsnFi+9m9OirOeqowaxZ85tW67WdqyQnZyb33rs8qnI07SURbgj3WWivi6ZnBqFhHSm4I1URlJW93mKvnurqKkpLd3Po0CymTFlMZWXkf4/s7CzuvfcR3n67iCFDzmDkSNi+/T2ee+5hpk0rJCOj01yCEzennno+//Vfm5tdwR8PpaV7uPHG0zhwYB9PPVVMz569476NZEpk8A8DngszfTNwZQK326FUVpYzY8a5fPzxuzz22KZGN4lLJyUlxTz99AJeemkJ5eWtV1P4/dW8+uoyXnrpKa65ZnZUDZoAa9f+iZKS4qi6MQazLx0akKuqKrnrru+wffu7PPDAXykoCN8u5PMF6qYLCpZx0klf46STvgYEDh5mz/4mn3/+IX37DmT8+Jn1y+za9Qm3334xRx01iFmzfsvhh/dN+t+XSvv27aJXr8BddxMR+gA9ehzOgAHD+OKLT9m7d4eCvwWHAeGaBfcCvcItYGZTgakAffr0oaioKKYNlpWV8dprRRxssfUg+Y455kj27Svh4Yen8Pbbb1FZWUFOTi6jRo3h29+eQN++/VJdxBatX7+O++4roKamOqabXFVXVzFixFn07l0b0wVs//M/s5g2bWbrM3Ywfn8ZZWVFYT8rLz/I3r3bKCvbw44df2HYsGP59a9/y3PPLWX16hepqKggNzeX888fy7hxV9K3b26zdf3gBzezcuXzjBo1hLKyInbt2kl2djZ5eXl065bFmjV/YufOF8jOHpDwv7Wj2LjxLebOvZNrr/0+48aNT+i2/t//u5GuXfPx+fZE/H+Ohw0bYj+YKSsriykvE9m4WwXc75yb3WT6fGC2c67FnU66Ne62pKhoGffdd11dcIY/uuuoV2lGc7FRJHl53VmxohSASy/tHtWZQtPl0klrF3Dt37+XvXt3MGDA0HZva/36FykouJKTTz6P+fP/yN69O9iyZS1f//q36+epra2NWCXknMM6QYX/Y4/NYcmSe5g8eR6TJs1JdXHiIhmNu4msKNxH+CP7SGcCnVJJSTE///l1HDqUPnfvDL2HzMSJx7Yp9H2+LMaOnVT/fsyYiS3M3Vhnub1FWdmXrFjxWP377t0Pi0voA/TvPwQAM+PQoQoOP7xvo9B/662XuemmkXzyyfthl58//xqmTTuDLVvWxaU8qXLDDfMpLFzNd7/746Rts6KijP/8zx+za9cncV1vMm8Zncjg30ygnr+pocCWBG63Q4nlKs2OoOmzBdqq6TMQJkyYFfWyztWm/U3L/H4/t912Eb/85RSefXZh3Nffp8/R/Pa3f2fevGfJyclr9Jlzjscfv5v333+L1av/EHb5zZvXsHXrerp27V4/7emnFzBt2hmsXv103MsbT4WF03n22QfZseNjAE45ZRSZmUnqZA88/PCP+P3vf8HChc2f8dFWtbW1zJhxLgsX3sr+/fvjtt5IEhn8zwNnmVn9hcdmNgA4t+4zT4jlKs1Ua+kB89GK9AyEfv0Gc9ZZl0a9nnR/mI3P5+OKK2bQv//xnHPO5QnZxlFHDQpbXWNm3HvvCiZPnse//dsdQGBH9Morf6h/styiRRspLFzNV77S0NngnXfeYOvW9VRVVdZPe/vtIqZNO4M//OGXCfkbQvn9fsrKGqr4Skt3M336WXzve43PkoqL3+bXv57Bww9HfzART5MmzeHUU8/nmmvuiNs6N29ew7vvruPVV5fSJQn3Sklk8D8KfAQ8Z2bjzOxfCfTy+QT4zwRut0NJl7t3lpQUM2fOuDZV6wS19gyEm29+gC5dcmNaZ0etDovG2LETWbRoE336HJ30befn92DSpDn4fIGmtK1b32TevKuZP/+a+s9POWVUo14wt9/+OwoLVzNy5MX107ZsWcvWrevZubPhYvv9+/cybdoZLFx4a5vK9uWXX7B58xp27Pioftq6dSv55jfzue++60L+hl4UF2/k44/fbbRDuP76ufz853/hJz9Z0qbtt1fv3l/h/vtfYciQ0+O2zpNOOpdHH93Aj360iJycnLitN5KEBX/dlbmjgfeBJwncOONDYLRzrnNU4kYhNze6GwdFO18iBKt3Pvpoc5uW9/myGDfuB60+A6Ffv8HMnfu/YZ9x0JqOVB0Wya5dO7j11gvqqyAAunTJTmGJGrz55ip8vsxG7S5NBXcGwa6RAOPGTaewcDWXX35j/bR//vPvbN26ni1b1jRa/qc//TaFhTdRVvZl/bTHHy/gzjsv57PPttVPW7r0fm6++RxWrWo4yz388KOoqqrkwIG99dN8Ph+//vX/8cwzOxtVSZ1++hhGjryo/r76qbZ37842Lxt6dnXssacwcuRF8ShSqxJ6FYhzbrtz7jvOue7OuW7OuW855z5K5DY7mmgf4ZiqXj2h1TttFemZxuGceeYlLFq0icsum0peXuBpadHoKNVhLXn88d+yYcMrPPLIbakuSjOTJs1h2bLPOPvs6KvbALp27c4pp4xqdFvjoUPPprBwNZMnz6+fduDAPl577Y/85S+PNzqIefvtItas+ROff/5h/bT+/U9gyJARdO/ecEn4wIHDWL78Sx544K+Ntj9kyAh69fqXDtkDyTnHI4/cxtVXH0Nx8aaYl9+5cztXXtmP3/3upyT79vid6u6cHdGECbNYtWpxi3XmGRkZXH/93CSWqkE0jc+RhHZHjeW+8U1vbzF6dEZUX/z2NDYnww9+cCs9ex7P1Kn3pboozWRkZMTtoqPc3K6ccsqoRtNycrpSWLiaL774tL56CWDixJ8wfvxMBg8eXj/t4ouv4+KLr2u0vM+XSX5+j7iUL1nMjKqqSvz+ajZt+r9Gf2M0Xn/9Ofbv38tnn21L+o5NwZ9gwUc4tnSV5h13PFl/RW9FxUFKS7/gyCMHJKV80V5RG85ll03lyitvaffDQnJz86MMdccll+Rz6FA5ubn5jBkzkQkTZqX0YSV79+6gV68+mBldu+Zz662PpKwsqZSV1aXZzgBgxIixyS9MEk2ePJ+LL76e448/LeZlr7hiBiecMDIlVwHrhh9JEK56I7Qh9BvfuAIInDoWFt7ElCmn8Le/vZCUsrWnUbk9zzQOFejjH90RT2XlwQ7T4+f99//O9defyBNPzEvJ9iX18vN7NAr9WKtshg49k6OOSuATVyJQ8CdJsHpjxYrID4Ovrq6ivHw/NTVV9O79lYSXaf/+vW1uVB4wIH63mg708Y+9jjPVPX4+/3wbZWX7eO+9v+H31yR9+9KxbNmyjptvPqdRe0Y4zzzzGz74YGOSShWegr8D6dIlm3nznuXhh99s1JiWiK6eS5bcw1VX9eeMMy6KuYcNwIwZD8StLIGdX9vrOCsry5kz51tJD//zzhvPf/zHi8yd+0yjem3xpkcfnc2WLWt57rmHG02vDblv+MGD+1m48BZ++MOvU1q6O9lFrKfg72DMrFHov/XWS3z3uwNZs+ZPcd1OaekeKivLOfLIAWTF+Gih66//GaedNjqu5cnLa1931o8+eicp1T4bNqxu1DXxtNNGk5WlhxMLzJv3LNdcM5sbbgj0dtqx4yOmTj2dm24aWT9P167dGTToJK67roAePY5IVVEV/B3dSy89RWnpbt577812rae0dDeffvrP+veTJ8/lV796lWnT/oOCgmVR9a0fMOBEFix4mWuvvatdZQkn2m6vLUl0tc8//vEaP/7xJdx662j27duVkG1I+srP78n3v39v/YFAr1592LZtE9u2beLQoYr6+e67789MmNC2i9/iReenHdxttz3G6aeP5fzzr6qfFuudFbdsWccdd3yTI48cyEMPrcPn85Gbm8/JJ38DaGh8Dn10ZG5uPmPHTopLr51oRNPtNRrBC70S8SS0wYNP5thjT+G4405L6dGapIfs7FwefPANjj76BLKzG65Y7wjPS9ARfweXkZHBmDHX1F9aX1FxkFtuOb++10/onTQj3dhs4MBh5OR0pVu3Xo2uqgwVTeNzIgW7vbblqt5QibzQKy+vGwsWvMzMmQv1BCyJygknnEFeXrdUF6MZHfGnmeXLH2HjxlcpLd2N31/N3LlXNbo+INjN8c9/foy5c/+Xs8++jNzcfB58cA1HHHFUh7wCMijcmUd2dh7V1ZUx9ZqJZ2P4Cy88QUnJB0yeHLjALje3a9zWLZIqCv40M378LVRVHeK4406NeKuF4E7grru+w+OPb6Ffv8H07t2xn/IVFO6h9evWrYzpthLxuu/Rzp3b+eUvp1BTU82IEWMZPvzrcVmvSKrpfDXNZGRkMHHinbzxxvJWb7VQW1vb4W9sFo3gmUC01w7Eq8dRnz5Hc8cdT3Djjb9Q6EunouBPU9HcaqG2tqbD39gsWv36DWb+/D82e+hIOMOHf6Nd2wptBxk9+mquvrrj3XRNpD0U/GkqXe7zH08tNQD7fFlkZ+cxceKcRncKdc5F1QAenHfx4p8xefJJrV59KZLOVMefpqK9sVkq7/OfCLF0Pf3ii0+ZOfM8du/+DL/f36gB/PnnH+H55x8GjLy8wA3frrhiBuvXv8iePZ+xdet6+vYdmKK/UiSxFPxpasyYiaxYsajF6p6mDzzvLMI1AIfz6KM/aXSVbWOu/jXYE2rVqsXMnv0EublzGj2FSqSzUVVPmpowYVart1qI5QEpnVFOTm5MD3qprCznvvuupV+/4xJcMpHUUvCnqdbqu8M98NxrXn75v3GutvUZQ6TDIx5F2kvBn8Zau89/qh7n2FG0pWE7HR7xKNJequNPc9HWd3tR9E/2aqwz9YSS1DCDjAzw+WIf8pPQH0PBL51WNA3g4XS2nlASnllD2DYN6dD3LQV4pOU6+q2cFPzSabXljp+dtSdUOgsN6NaGaI+yMzI6fjgnUqcLfjPIy4Pa2sDgXONx8Y6WHnQfidd7QrWXGWRmti2MWxokvjpd8GdmwsiR4T9zrvmOINx4S5/FMt7atND3khhNL/gK1PkHnmcQ+mBsny+LrKwsT/eECh5ZZ2Y2DE3fh5sW+l4hnR46XfC3xKyh0aWjCd0ZhNtBRJoWOt3vb3iNNB46zStnQE0bwEtKilP60JlECR5tt3VQaHuHp4K/I0tFnaNz4XcMNTUN04PjTV8jDemwM0l2T6jgwUa4IbS+ubXPVCUi8aLg97DQI8R4abojiLSjCE4PdwbTtE0mWEXXdDzc39PS+9BpwddIoRtLQAeH9esD1YxN5+3Az74Rj1LwS1x5+cgzIyPQsUCko+uAtd0iIpJICn4REY9R8IuIeIyCX0TEYxT8IiIeo+AXEfEYBb+IiMco+EVEPEbBLyLiMQp+ERGPUfCLiHiMgl9ExGMU/CIiHqPgFxHxGAW/iIjHKPhFRDxGwS8i4jEKfhERj1Hwi4h4jIJfRMRjFPwiIh6j4BcR8RgFv4iIxyj4RUQ8RsEvIuIxCn4REY9R8IuIeIyCX0TEYxT8IiIeo+AXEfEYBb+IiMco+EVEPEbBLyLiMQp+ERGPUfCLiHiMgl9ExGMU/CIiHqPgFxHxGAW/iIjHKPhFRDxGwS8i4jEKfhERj1Hwi4h4jIJfRMRjFPwiIh6j4BcR8RgFv4iIxyj4RUQ8RsEvIuIxCn4REY9R8G8kRhkAAAQcSURBVIuIeIyCX0TEYxT8IiIeo+AXEfEYBb+IiMco+EVEPEbBLyLiMQp+ERGPUfCLiHiMgl9ExGMU/CIiHqPgFxHxGAW/iIjHKPhFRDxGwS8i4jEKfhERj1Hwi4h4jIJfRMRjEhL8Zna8mT1gZpvMrMzMPjez583s5ERsT0REopeoI/4LgfOBxcDlwHSgN7DWzE5P0DZFRCQKmQla7++Bhc45F5xgZq8AHwE/BK5N0HZFRKQVCQl+59zuMNNKzex9oF8itikiItFJWuOumR0GnAi8m6xtiohIc4mq6gnnN4ABv4o0g5lNBabWvS0zs60xbuMIoNnZhkiS6PsnqRL63TumtZktpBo+8kxmY4AXo9j4q865UWGWvwP4d+AG59zvolhPm5jZeufciEStX6Ql+v5JqsT63Yv2iP8N4KtRzFcepkDTCIT+nESGvoiIRCeq4HfOlQPvxbpyM5sEPAQscM7dE+vyIiISfwlr3DWzbwP/BSxyzv0oUdtp4rdJ2o5IOPr+SarE9N2Lqo4/Vmb2DWAVsBmYAdSGfHzIObch7hsVEZGoJKpXz2ggGzgNeL3JZx8DAxK0XRERaUVCjvhFRKTj6pR359RN4iRZzKy/mS0zs1Iz229mz5jZ0akul3RuZjbezP7XzD42swoz22pm95pZt6iW74xH/GZ2M4ELwRYDfwd6ArcDpwBfc869lcLiSSdhZnnARuAQMAdwwHwgDxjunDuYwuJJJ2Zma4HtwHPAp8CpQAGB3pfnOOdqIy/deYP/CGBPk5vE9SBwk7jlzjndJE7azcx+CNwPDHHOfVA3bSDwT+B259z9qSyfdF5m1ts590WTadcSONi9wDn3SkvLd8qqHufcbtdkj+acKwV0kziJp38F1gZDH8A59yGBDg3jUlYq6fSahn6dN+teW824Thn84egmcZIAw4B3wkzfDAxNcllEzqt7bTXjPBP8RHGTOJEYHQbsCzN9L9AryWURDzOzfsBc4CXn3PrW5k+L4DezMWbmohiKIix/B3ANcHPoabmISLozs3wCjbw1wPXRLJPM2zK3h24SJx3RPsIf2Uc6ExCJKzPLBZYDg4DznHOfRrNcWgS/bhInHdRmAvX8TQ0FtiS5LOIxZpYFLANGAGOdc/+Idtm0qOppixTdJE685XngLDMbFJxgZgOAc+s+E0kIM8sAniJwe5xvOefWxrR8J+3Hr5vEScKZWVcCF3BV0HAB1zygG4ELuMpSWDzpxMzsYWAacA/wpyYff9palU9nDf4C4O4IH3/snBuQvNJIZ1Z3e4ZCYCyBXmMvAzOdcx+lslzSuZnZR0R+xOLPnHMFLS7fGYNfREQi67R1/CIiEp6CX0TEYxT8IiIeo+AXEfEYBb+IiMco+EVEPEbBLyLiMQp+ERGP+f9izzqVqfui+gAAAABJRU5ErkJggg==\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - }, - { - "ename": "KeyboardInterrupt", - "evalue": "", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 18\u001b[0m \u001b[0mmodel\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtrain\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 19\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 20\u001b[0;31m \u001b[0mdata_train\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdataset_train\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgenerate_curves\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 21\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 22\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mcontext_x\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcontext_y\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtarget_x\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mdata_train\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mquery\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m/media/wassname/Storage5/projects2/3ST/attentive-neural-processes/src/data/gp_curves.py\u001b[0m in \u001b[0;36mgenerate_curves\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 157\u001b[0m \u001b[0;31m# Pass the x_values through the Gaussian kernel\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 158\u001b[0m \u001b[0;31m# [batch_size, y_size, num_total_points, num_total_points]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 159\u001b[0;31m \u001b[0mkernel\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_gaussian_kernel\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx_values\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0ml1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msigma_f\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 160\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 161\u001b[0m \u001b[0;31m# Calculate Cholesky, using double precision for better stability:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m/media/wassname/Storage5/projects2/3ST/attentive-neural-processes/src/data/gp_curves.py\u001b[0m in \u001b[0;36m_gaussian_kernel\u001b[0;34m(self, xdata, l1, sigma_f, sigma_noise)\u001b[0m\n\u001b[1;32m 96\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 97\u001b[0m \u001b[0;31m# [B, y_size, num_total_points, num_total_points]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 98\u001b[0;31m \u001b[0mkernel\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msigma_f\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m**\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m:\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexp\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m0.5\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0mnorm\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 99\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 100\u001b[0m \u001b[0;31m# Add some noise to the diagonal to make the cholesky work.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mKeyboardInterrupt\u001b[0m: " - ] - } - ], - "source": [ - "writer = SummaryWriter(comment='-np_1d')\n", - "print(writer.logdir)\n", - " \n", - "hparams = dict(\n", - " x_dim=1,\n", - " y_dim=1,\n", - " hidden_dim=128,\n", - " latent_dim=128,\n", - " latent_enc_self_attn_type=\"uniform\",\n", - " det_enc_self_attn_type=\"uniform\",\n", - " det_enc_cross_attn_type=\"uniform\",\n", - " use_rnn=False)\n", - "model = LatentModel(**hparams).cuda()\n", - "\n", - "optim = torch.optim.AdamW(model.parameters(), lr=1e-4)\n", - "\n", - "for n_iter in tqdm(range(epochs)):\n", - " model.train()\n", - "\n", - " data_train = dataset_train.generate_curves()\n", - "\n", - " (context_x, context_y), target_x = data_train.query\n", - " target_y = data_train.target_y\n", - "\n", - " context_x = context_x.cuda()\n", - " context_y = context_y.cuda()\n", - " target_x = target_x.cuda()\n", - " target_y = target_y.cuda()\n", - "\n", - " optim.zero_grad()\n", - " y_pred, losses, extra = model(context_x, context_y, target_x,\n", - " target_y)\n", - " y_std = extra['dist'].scale\n", - " loss = losses['loss']\n", - " loss.backward()\n", - " optim.step()\n", - "\n", - " writer.add_scalar('train/loss', loss, n_iter)\n", - " writer.add_scalar('train/mse', losses['loss_mse'], n_iter)\n", - " writer.add_scalar('train/y_std', y_std.mean(), n_iter)\n", - " writer.add_scalar('train/kl', losses['loss_kl'].mean(), n_iter)\n", - "\n", - " if n_iter in PLOT_AFTER:\n", - " y_pred, kl, val_loss, y_std = test(\n", - " model, dataset_test, writer, plot=False, global_step=n_iter)\n", - " val_loss = evaluate(model, dataset_test, 100)\n", - " writer.add_scalar('val/loss_mean', val_loss, n_iter)\n", - " print(\n", - " f\"train: {n_iter} loss={loss.item(): 4.4g} val_loss={val_loss.item(): 4.4g}\"\n", - " )\n", - "\n", - " if n_iter in PLOT_AFTER:\n", - " test(model, dataset_test, writer, plot=True, global_step=n_iter, title='test')\n", - " test(model, dataset_train, writer, plot=True, global_step=n_iter, seed=n_iter, title='train')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "ExecuteTime": { - "end_time": "2020-03-15T07:26:17.857048Z", - "start_time": "2020-03-15T07:26:05.700Z" - } - }, - "outputs": [], - "source": [ - "# Final validation\n", - "val_loss = evaluate(model, dataset_test, 300)\n", - "print('val loss (n=300)', loss)\n", - "writer.add_hparams(hparams, dict(val_loss=loss))\n", - "\n", - "for i in range(3):\n", - " set_seed(i)\n", - " test(model, dataset_test, writer, plot=True, global_step=-1, seed=i, title='test_final')\n", - " \n", - "for i in range(3):\n", - " test(model, dataset_train, writer, plot=True, global_step=-1, seed=i, title='train_final')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "jup3.7.2", - "language": "python", - "name": "jup3.7.2" - }, - "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.7.2" - }, - "toc": { - "base_numbering": 1, - "nav_menu": {}, - "number_sections": true, - "sideBar": true, - "skip_h1_title": false, - "title_cell": "Table of Contents", - "title_sidebar": "Contents", - "toc_cell": false, - "toc_position": { - "height": "calc(100% - 180px)", - "left": "10px", - "top": "150px", - "width": "384px" - }, - "toc_section_display": true, - "toc_window_display": true - } - }, - "nbformat": 4, - "nbformat_minor": 2 -}