├── fig ├── demo.png ├── model1.png ├── model2.png ├── transition1.png └── transition2.png ├── .gitignore ├── README.md ├── vae_generate_lidar.ipynb └── cGAN_generate_lidar.ipynb /fig/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjuite/radar-navigation/HEAD/fig/demo.png -------------------------------------------------------------------------------- /fig/model1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjuite/radar-navigation/HEAD/fig/model1.png -------------------------------------------------------------------------------- /fig/model2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjuite/radar-navigation/HEAD/fig/model2.png -------------------------------------------------------------------------------- /fig/transition1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjuite/radar-navigation/HEAD/fig/transition1.png -------------------------------------------------------------------------------- /fig/transition2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huangjuite/radar-navigation/HEAD/fig/transition2.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | devel/ 3 | result* 4 | *.egg-info 5 | *.pyc 6 | .catkin_workspace 7 | log 8 | .vscode/ 9 | procman/bot2-procman/lcmtypes/c/* 10 | procman/bot2-procman/lcmtypes/cpp/* 11 | procman/bot2-procman/pod-build/* 12 | procman/bot2-procman/python/src/bot_procman/build_prefix.py 13 | .ipynb_checkpoints/ 14 | *.pkl 15 | bags/*/ 16 | __pycache__ 17 | events.* 18 | *.pth -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Enabling Learning-based Navigation in Obscurants with Lightweight, Low-cost Millimeter Wave Radar Using Cross-modal Contrastive Learning of Representations 2 | 3 | ## Intro 4 | This repo demonstrate using generative model to reconstruct mmWave radar range data to dense range data closer to LiDAR ground truth. 5 | 6 | The reconstructed range data can be used as signals for control policys. 7 | Futher details please refer to our [website](https://ARG-NCTU.github.io/projects/deeprl-mmWave.html). 8 | 9 | 11 | 12 | 13 | ## Dataset 14 | [dataset on our google drive](https://drive.google.com/drive/u/0/folders/1FMkjvJl070_LxqcNBFeBedPsZFoy0VNe) 15 | 16 | To run the inference model on colab. Please create a short cut of the dataset to your own google drive 17 | 18 | 20 | 22 | 23 | ## inference model 24 | [pretrained model on our google drive](https://drive.google.com/drive/u/2/folders/1oz7vF7SROx8Q85B1cLGpNItQHwsZkCKr) 25 | 26 | To run the inference model on colab. Please also create a short cut of pretrained models to your own google drive 27 | 28 | 30 | 32 | 33 | 34 | ## run colab 35 | - cGAN generate 36 | - [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huangjuite/radar-navigation/blob/master/cGAN_generate_lidar.ipynb) 37 | 38 | - VAE generate 39 | - [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/huangjuite/radar-navigation/blob/master/vae_generate_lidar.ipynb) 40 | 41 | 42 | -------------------------------------------------------------------------------- /vae_generate_lidar.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "kernelspec": { 6 | "display_name": "Python 3", 7 | "language": "python", 8 | "name": "python3" 9 | }, 10 | "language_info": { 11 | "codemirror_mode": { 12 | "name": "ipython", 13 | "version": 3 14 | }, 15 | "file_extension": ".py", 16 | "mimetype": "text/x-python", 17 | "name": "python", 18 | "nbconvert_exporter": "python", 19 | "pygments_lexer": "ipython3", 20 | "version": "3.6.9" 21 | }, 22 | "colab": { 23 | "name": "vae_generate_lidar.ipynb", 24 | "provenance": [] 25 | }, 26 | "accelerator": "GPU" 27 | }, 28 | "cells": [ 29 | { 30 | "cell_type": "code", 31 | "metadata": { 32 | "id": "UJLg_uaFqf2V" 33 | }, 34 | "source": [ 35 | "import os\n", 36 | "import io\n", 37 | "import cv2\n", 38 | "import copy\n", 39 | "import math\n", 40 | "import random\n", 41 | "import numpy as np\n", 42 | "import pickle as pkl\n", 43 | "from tqdm import tqdm, trange\n", 44 | "from typing import Deque, Dict, List, Tuple\n", 45 | "import matplotlib.pyplot as plt\n", 46 | "\n", 47 | "\n", 48 | "import torch\n", 49 | "import torch.nn as nn\n", 50 | "import torch.nn.functional as F\n", 51 | "import torch.optim as optim\n", 52 | "from torch.utils.data.dataset import Dataset\n", 53 | "from torch.utils.data import DataLoader, random_split\n", 54 | "\n" 55 | ], 56 | "execution_count": 1, 57 | "outputs": [] 58 | }, 59 | { 60 | "cell_type": "markdown", 61 | "metadata": { 62 | "id": "Ca4eB4Gxqf2Z" 63 | }, 64 | "source": [ 65 | "## dataset\n", 66 | "\n", 67 | " Load dataset from your google drive.\n", 68 | " Please add a short cut of our dataset on google drive to your own google drive.\n", 69 | " Change the \"main_path\" of the dataset if necessary." 70 | ] 71 | }, 72 | { 73 | "cell_type": "code", 74 | "metadata": { 75 | "id": "VtEy0lUxqp6M", 76 | "outputId": "d2c4be62-2d5f-499c-a26a-fd37109077c4", 77 | "colab": { 78 | "base_uri": "https://localhost:8080/", 79 | "height": 35 80 | } 81 | }, 82 | "source": [ 83 | "from google.colab import drive\n", 84 | "drive.mount('/content/gdrive')" 85 | ], 86 | "execution_count": 2, 87 | "outputs": [ 88 | { 89 | "output_type": "stream", 90 | "text": [ 91 | "Mounted at /content/gdrive\n" 92 | ], 93 | "name": "stdout" 94 | } 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "metadata": { 100 | "scrolled": true, 101 | "id": "7vg8gr-Yqf2Z", 102 | "outputId": "5ac148d7-1f83-4df6-ee9d-0fa25bb29adc", 103 | "colab": { 104 | "base_uri": "https://localhost:8080/", 105 | "height": 35 106 | } 107 | }, 108 | "source": [ 109 | "paths = []\n", 110 | "main_path = '/content/gdrive/My Drive/transitions/'\n", 111 | "dirs = os.listdir(main_path)\n", 112 | "dirs.sort()\n", 113 | "for d in dirs:\n", 114 | " dirs1 = os.listdir(main_path+'/'+d)\n", 115 | " dirs1.sort()\n", 116 | " for p in dirs1:\n", 117 | " paths.append(main_path+'/'+d+'/'+p)\n", 118 | " # print(paths[-1])\n", 119 | "print('%d episodes'%len(paths))\n" 120 | ], 121 | "execution_count": 3, 122 | "outputs": [ 123 | { 124 | "output_type": "stream", 125 | "text": [ 126 | "228 episodes\n" 127 | ], 128 | "name": "stdout" 129 | } 130 | ] 131 | }, 132 | { 133 | "cell_type": "code", 134 | "metadata": { 135 | "id": "pgYz_jarqf2d", 136 | "outputId": "3b6ced08-2a0e-4ac9-c6b1-d834c6e8edf0", 137 | "colab": { 138 | "base_uri": "https://localhost:8080/", 139 | "height": 35 140 | } 141 | }, 142 | "source": [ 143 | "class MMDataset(Dataset):\n", 144 | " def __init__(self, paths):\n", 145 | " self.transitions = []\n", 146 | "\n", 147 | " for p in tqdm(paths):\n", 148 | " with open(p, \"rb\") as f:\n", 149 | " demo = pkl.load(f, encoding=\"bytes\")\n", 150 | " self.transitions.extend(demo)\n", 151 | " \n", 152 | " def __getitem__(self,index):\n", 153 | " mm_scan = self.transitions[index][b'mm_scan']\n", 154 | " laser_scan = self.transitions[index][b'laser_scan']\n", 155 | " mm_scan = torch.Tensor(mm_scan).reshape(1,-1)\n", 156 | " laser_scan = torch.Tensor(laser_scan).reshape(1,-1)\n", 157 | " \n", 158 | " return mm_scan, laser_scan\n", 159 | " \n", 160 | " def __len__(self):\n", 161 | " return len(self.transitions)\n", 162 | "\n", 163 | " \n", 164 | "batch_size = 16\n", 165 | "mm_dataset = MMDataset(paths)\n", 166 | "\n", 167 | "loader = DataLoader(dataset=mm_dataset,\n", 168 | " batch_size=batch_size,\n", 169 | " shuffle=True,\n", 170 | " num_workers=4)\n" 171 | ], 172 | "execution_count": 4, 173 | "outputs": [ 174 | { 175 | "output_type": "stream", 176 | "text": [ 177 | "100%|██████████| 228/228 [02:25<00:00, 1.57it/s]\n" 178 | ], 179 | "name": "stderr" 180 | } 181 | ] 182 | }, 183 | { 184 | "cell_type": "markdown", 185 | "metadata": { 186 | "id": "xqmER4KDqf2g" 187 | }, 188 | "source": [ 189 | "## hyper parameters" 190 | ] 191 | }, 192 | { 193 | "cell_type": "code", 194 | "metadata": { 195 | "id": "_w0mwItAqf2h" 196 | }, 197 | "source": [ 198 | "hyper_parameter = dict(\n", 199 | " kernel=3,\n", 200 | " stride=2,\n", 201 | " padding=2,\n", 202 | " latent=128,\n", 203 | " deconv_dim=32,\n", 204 | " deconv_channel=128,\n", 205 | " adjust_linear=235,\n", 206 | " epoch=100,\n", 207 | " learning_rate=0.001,\n", 208 | ")\n", 209 | "class Struct:\n", 210 | " def __init__(self, **entries):\n", 211 | " self.__dict__.update(entries)\n", 212 | "config = Struct(**hyper_parameter)" 213 | ], 214 | "execution_count": 5, 215 | "outputs": [] 216 | }, 217 | { 218 | "cell_type": "markdown", 219 | "metadata": { 220 | "id": "8oKinQAWqf2j" 221 | }, 222 | "source": [ 223 | "## model" 224 | ] 225 | }, 226 | { 227 | "cell_type": "code", 228 | "metadata": { 229 | "id": "HSCKIfJfqf2k" 230 | }, 231 | "source": [ 232 | "class MMvae(nn.Module):\n", 233 | " def __init__(self):\n", 234 | " super(MMvae, self).__init__()\n", 235 | " kernel = 3\n", 236 | " stride = 2\n", 237 | " self.conv = nn.Sequential(\n", 238 | " nn.Conv1d(1, 64, kernel_size=kernel, stride=stride),\n", 239 | " nn.ReLU(),\n", 240 | " nn.Conv1d(64, 64, kernel_size=kernel, stride=stride),\n", 241 | " nn.ReLU()\n", 242 | " )\n", 243 | " \n", 244 | " dim = 64*59\n", 245 | " self.linear1=nn.Sequential(\n", 246 | " nn.Linear(dim,512),\n", 247 | " nn.ReLU()\n", 248 | " )\n", 249 | " self.en_fc1=nn.Linear(512,config.latent)\n", 250 | " self.en_fc2=nn.Linear(512,config.latent)\n", 251 | " \n", 252 | " self.de_fc1=nn.Sequential(\n", 253 | " nn.Linear(config.latent,config.deconv_channel*config.deconv_dim),\n", 254 | " nn.ReLU()\n", 255 | " )\n", 256 | " \n", 257 | " self.de_conv =nn.Sequential(\n", 258 | " nn.ConvTranspose1d(config.deconv_channel, config.deconv_channel//2, kernel, stride=stride, padding=config.padding),\n", 259 | "# nn.ReLU(),\n", 260 | " nn.ConvTranspose1d(config.deconv_channel//2, config.deconv_channel//4, kernel, stride=stride, padding=config.padding),\n", 261 | "# nn.ReLU(),\n", 262 | " nn.ConvTranspose1d(config.deconv_channel//4, 1, kernel, stride=stride, padding=config.padding),\n", 263 | "# nn.ReLU(),\n", 264 | " )\n", 265 | " self.adjust_linear=nn.Sequential(\n", 266 | " nn.Linear(config.adjust_linear,241),\n", 267 | " nn.ReLU()\n", 268 | " )\n", 269 | "\n", 270 | " \n", 271 | " def encoder(self,x):\n", 272 | " x = self.conv(x)\n", 273 | " x = x.view(x.size(0),-1)\n", 274 | " x = self.linear1(x)\n", 275 | " mean = self.en_fc1(x)\n", 276 | " logvar = self.en_fc2(x)\n", 277 | " return mean, logvar\n", 278 | "\n", 279 | " def reparameter(self, mean, logvar):\n", 280 | " std = torch.exp(0.5*logvar)\n", 281 | " eps = torch.randn_like(std)\n", 282 | " return mean + eps*std\n", 283 | "\n", 284 | " def decoder(self,x):\n", 285 | " x = self.de_fc1(x)\n", 286 | " x = x.view(-1, config.deconv_channel, config.deconv_dim)\n", 287 | " x = self.de_conv(x)\n", 288 | " x = self.adjust_linear(x)\n", 289 | " return x\n", 290 | "\n", 291 | " def forward(self,x):\n", 292 | " mean, logvar = self.encoder(x)\n", 293 | " x = self.reparameter(mean, logvar)\n", 294 | " x = self.decoder(x)\n", 295 | " return x ,mean ,logvar" 296 | ], 297 | "execution_count": 6, 298 | "outputs": [] 299 | }, 300 | { 301 | "cell_type": "markdown", 302 | "metadata": { 303 | "id": "M9p8UDYFqf2n" 304 | }, 305 | "source": [ 306 | "## load model\n", 307 | "\n", 308 | " Load model from your google drive.\n", 309 | " Please add a short cut of our inference model on google drive to your own google drive.\n", 310 | " Change the \"model_path\" of the dataset if necessary. " 311 | ] 312 | }, 313 | { 314 | "cell_type": "code", 315 | "metadata": { 316 | "scrolled": false, 317 | "id": "_-OT3hAEqf2n", 318 | "outputId": "157db66c-0138-47b8-9de1-e71d45dac4fe", 319 | "colab": { 320 | "base_uri": "https://localhost:8080/", 321 | "height": 54 322 | } 323 | }, 324 | "source": [ 325 | "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n", 326 | "print('device, ',device)\n", 327 | "model = MMvae()\n", 328 | "model.to(device)\n", 329 | "model_path = '/content/gdrive/My Drive/deploy_model/vae/0726_1557.pth'\n", 330 | "model.load_state_dict(torch.load(model_path))" 331 | ], 332 | "execution_count": 7, 333 | "outputs": [ 334 | { 335 | "output_type": "stream", 336 | "text": [ 337 | "device, cuda:0\n" 338 | ], 339 | "name": "stdout" 340 | }, 341 | { 342 | "output_type": "execute_result", 343 | "data": { 344 | "text/plain": [ 345 | "" 346 | ] 347 | }, 348 | "metadata": { 349 | "tags": [] 350 | }, 351 | "execution_count": 7 352 | } 353 | ] 354 | }, 355 | { 356 | "cell_type": "markdown", 357 | "metadata": { 358 | "id": "Cv74SaEpqf2r" 359 | }, 360 | "source": [ 361 | "## visualize examples" 362 | ] 363 | }, 364 | { 365 | "cell_type": "code", 366 | "metadata": { 367 | "id": "FVdIzAeGqf2s" 368 | }, 369 | "source": [ 370 | "def laser_visual(lasers=[], show=False, range_limit=6):\n", 371 | " colors = ['#3483EB','#FFA500','#15B01D']\n", 372 | " fig = plt.figure(figsize=(8, 8))\n", 373 | " for i, l in enumerate(lasers):\n", 374 | " # fig = plt.figure(figsize=(8, 8))\n", 375 | " angle = 120\n", 376 | " xp = []\n", 377 | " yp = []\n", 378 | " for r in l:\n", 379 | " if r <= range_limit:\n", 380 | " yp.append(r * math.cos(math.radians(angle)))\n", 381 | " xp.append(r * math.sin(math.radians(angle)))\n", 382 | " angle -= 1\n", 383 | " plt.xlim(-6, 6)\n", 384 | " plt.ylim(-6, 6)\n", 385 | " # plt.axis('off')\n", 386 | " plt.plot(xp, yp, 'x', color=colors[i])\n", 387 | " plt.show()\n" 388 | ], 389 | "execution_count": 8, 390 | "outputs": [] 391 | }, 392 | { 393 | "cell_type": "code", 394 | "metadata": { 395 | "id": "ewAqFzV3qf2v", 396 | "outputId": "461b16d2-3dc1-4cdc-85dc-195cc88a11f0", 397 | "colab": { 398 | "base_uri": "https://localhost:8080/", 399 | "height": 487 400 | } 401 | }, 402 | "source": [ 403 | "data1 = None\n", 404 | "for mm_scan, laser_scan in loader:\n", 405 | " mm_scan = mm_scan.to(device)\n", 406 | " \n", 407 | " x_hat ,mean ,logvar = model(mm_scan)\n", 408 | " \n", 409 | " x = x_hat.detach().cpu().numpy().reshape(batch_size,-1)[0]\n", 410 | " laser = laser_scan.numpy().reshape(batch_size,-1)[0]\n", 411 | " mm = mm_scan.detach().cpu().numpy().reshape(batch_size,-1)[0]\n", 412 | " \n", 413 | " laser_visual([laser, x, mm], show=True, range_limit=4.9)\n", 414 | " data1 = [laser, x, mm]\n", 415 | " break" 416 | ], 417 | "execution_count": 9, 418 | "outputs": [ 419 | { 420 | "output_type": "display_data", 421 | "data": { 422 | "image/png": "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\n", 423 | "text/plain": [ 424 | "
" 425 | ] 426 | }, 427 | "metadata": { 428 | "tags": [], 429 | "needs_background": "light" 430 | } 431 | } 432 | ] 433 | } 434 | ] 435 | } -------------------------------------------------------------------------------- /cGAN_generate_lidar.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "nbformat": 4, 3 | "nbformat_minor": 0, 4 | "metadata": { 5 | "kernelspec": { 6 | "display_name": "Python 3", 7 | "language": "python", 8 | "name": "python3" 9 | }, 10 | "language_info": { 11 | "codemirror_mode": { 12 | "name": "ipython", 13 | "version": 3 14 | }, 15 | "file_extension": ".py", 16 | "mimetype": "text/x-python", 17 | "name": "python", 18 | "nbconvert_exporter": "python", 19 | "pygments_lexer": "ipython3", 20 | "version": "3.6.9" 21 | }, 22 | "colab": { 23 | "name": "cGAN_generate_lidar.ipynb", 24 | "provenance": [] 25 | }, 26 | "accelerator": "GPU" 27 | }, 28 | "cells": [ 29 | { 30 | "cell_type": "markdown", 31 | "metadata": { 32 | "id": "P_VunP7mcLdF" 33 | }, 34 | "source": [ 35 | "## cGAN generate LiDAR" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "metadata": { 41 | "id": "jXbqhZBHcLdG" 42 | }, 43 | "source": [ 44 | "import os\n", 45 | "import io\n", 46 | "import cv2\n", 47 | "import copy\n", 48 | "import math\n", 49 | "import random\n", 50 | "import numpy as np\n", 51 | "import pickle as pkl\n", 52 | "from tqdm import tqdm, trange\n", 53 | "from typing import Deque, Dict, List, Tuple\n", 54 | "import matplotlib.pyplot as plt\n", 55 | "\n", 56 | "\n", 57 | "import torch\n", 58 | "import torch.nn as nn\n", 59 | "import torch.nn.functional as F\n", 60 | "import torch.optim as optim\n", 61 | "from torch.autograd import Variable\n", 62 | "from torch.utils.data.dataset import Dataset\n", 63 | "from torch.utils.data import DataLoader, random_split\n", 64 | "\n" 65 | ], 66 | "execution_count": 1, 67 | "outputs": [] 68 | }, 69 | { 70 | "cell_type": "markdown", 71 | "metadata": { 72 | "id": "f1qtyFZicLdK" 73 | }, 74 | "source": [ 75 | "## dataset\n", 76 | "\n", 77 | " Load dataset from your google drive.\n", 78 | " Please add a short cut of our dataset on google drive to your own google drive.\n", 79 | " Change the \"main_path\" of the dataset if necessary." 80 | ] 81 | }, 82 | { 83 | "cell_type": "code", 84 | "metadata": { 85 | "id": "79mIlikZiu92", 86 | "outputId": "0d709ee2-7966-48ec-86b1-1026c2401595", 87 | "colab": { 88 | "base_uri": "https://localhost:8080/", 89 | "height": 35 90 | } 91 | }, 92 | "source": [ 93 | "from google.colab import drive\n", 94 | "drive.mount('/content/gdrive')" 95 | ], 96 | "execution_count": 2, 97 | "outputs": [ 98 | { 99 | "output_type": "stream", 100 | "text": [ 101 | "Drive already mounted at /content/gdrive; to attempt to forcibly remount, call drive.mount(\"/content/gdrive\", force_remount=True).\n" 102 | ], 103 | "name": "stdout" 104 | } 105 | ] 106 | }, 107 | { 108 | "cell_type": "code", 109 | "metadata": { 110 | "scrolled": true, 111 | "id": "YqeNMpGCcLdK", 112 | "outputId": "1e762023-ed41-41cd-f3c5-c6b5617462ae", 113 | "colab": { 114 | "base_uri": "https://localhost:8080/", 115 | "height": 35 116 | } 117 | }, 118 | "source": [ 119 | "paths = []\n", 120 | "main_path = '/content/gdrive/My Drive/transitions/'\n", 121 | "dirs = os.listdir(main_path)\n", 122 | "dirs.sort()\n", 123 | "for d in dirs:\n", 124 | " dirs1 = os.listdir(main_path+'/'+d)\n", 125 | " dirs1.sort()\n", 126 | " for p in dirs1:\n", 127 | " paths.append(main_path+'/'+d+'/'+p)\n", 128 | " # print(paths[-1])\n", 129 | "print('%d episodes'%len(paths))\n" 130 | ], 131 | "execution_count": 3, 132 | "outputs": [ 133 | { 134 | "output_type": "stream", 135 | "text": [ 136 | "228 episodes\n" 137 | ], 138 | "name": "stdout" 139 | } 140 | ] 141 | }, 142 | { 143 | "cell_type": "code", 144 | "metadata": { 145 | "id": "14HAQLFucLdO", 146 | "outputId": "7338d1ce-f233-4a77-9db5-3f73f6c0b310", 147 | "colab": { 148 | "base_uri": "https://localhost:8080/", 149 | "height": 35 150 | } 151 | }, 152 | "source": [ 153 | "class MMDataset(Dataset):\n", 154 | " def __init__(self, paths):\n", 155 | " self.transitions = []\n", 156 | "\n", 157 | " for p in tqdm(paths):\n", 158 | " with open(p, \"rb\") as f:\n", 159 | " demo = pkl.load(f, encoding=\"bytes\")\n", 160 | " self.transitions.extend(demo)\n", 161 | " \n", 162 | " def __getitem__(self,index):\n", 163 | " mm_scan = self.transitions[index][b'mm_scan']\n", 164 | " laser_scan = self.transitions[index][b'laser_scan']\n", 165 | " mm_scan = torch.Tensor(mm_scan).reshape(1,-1)\n", 166 | " laser_scan = torch.Tensor(laser_scan).reshape(1,-1)\n", 167 | " \n", 168 | " return mm_scan, laser_scan\n", 169 | " \n", 170 | " def __len__(self):\n", 171 | " return len(self.transitions)\n", 172 | "\n", 173 | " \n", 174 | "batch_size = 16\n", 175 | "mm_dataset = MMDataset(paths)\n", 176 | "\n", 177 | "loader = DataLoader(dataset=mm_dataset,\n", 178 | " batch_size=batch_size,\n", 179 | " shuffle=True,\n", 180 | " num_workers=4)\n" 181 | ], 182 | "execution_count": 4, 183 | "outputs": [ 184 | { 185 | "output_type": "stream", 186 | "text": [ 187 | "100%|██████████| 228/228 [00:05<00:00, 40.39it/s]\n" 188 | ], 189 | "name": "stderr" 190 | } 191 | ] 192 | }, 193 | { 194 | "cell_type": "markdown", 195 | "metadata": { 196 | "id": "vR_682nicLdR" 197 | }, 198 | "source": [ 199 | "## hyper parameters" 200 | ] 201 | }, 202 | { 203 | "cell_type": "code", 204 | "metadata": { 205 | "id": "Y9F8bdeOcLdR" 206 | }, 207 | "source": [ 208 | "hyper_parameter = dict(\n", 209 | " kernel=3,\n", 210 | " stride=2,\n", 211 | " padding=2,\n", 212 | " deconv_dim=32,\n", 213 | " deconv_channel=128,\n", 214 | " adjust_linear=235,\n", 215 | " epoch=500,\n", 216 | " beta1=0.5,\n", 217 | " learning_rate=0.0002,\n", 218 | " nz=100,\n", 219 | " lambda_l1=100,\n", 220 | ")\n", 221 | "class Struct:\n", 222 | " def __init__(self, **entries):\n", 223 | " self.__dict__.update(entries)\n", 224 | "config = Struct(**hyper_parameter)" 225 | ], 226 | "execution_count": 5, 227 | "outputs": [] 228 | }, 229 | { 230 | "cell_type": "markdown", 231 | "metadata": { 232 | "id": "85dWFlDCcLdU" 233 | }, 234 | "source": [ 235 | "## model" 236 | ] 237 | }, 238 | { 239 | "cell_type": "code", 240 | "metadata": { 241 | "id": "yNAlrgJXcLdU" 242 | }, 243 | "source": [ 244 | "class Generator(nn.Module):\n", 245 | " def __init__(self):\n", 246 | " super(Generator, self).__init__()\n", 247 | " kernel = 3\n", 248 | " stride = 2\n", 249 | " self.conv = nn.Sequential(\n", 250 | " nn.Conv1d(1, 64, kernel_size=kernel, stride=stride),\n", 251 | " nn.ReLU(),\n", 252 | " nn.Conv1d(64, 64, kernel_size=kernel, stride=stride),\n", 253 | " nn.ReLU()\n", 254 | " )\n", 255 | " \n", 256 | " dim = 64*59\n", 257 | " self.linear=nn.Sequential(\n", 258 | " nn.Linear(dim,512),\n", 259 | " nn.ReLU(),\n", 260 | " nn.Linear(512,128)\n", 261 | " )\n", 262 | " \n", 263 | "# self.n_fc1=nn.Linear(config.nz, 128)\n", 264 | "# self.n_fc2=nn.Linear(128, 128)\n", 265 | " \n", 266 | "# self.fc_combine=nn.Linear(128*2, 128)\n", 267 | " \n", 268 | " self.de_fc1=nn.Sequential(\n", 269 | " nn.Linear(128,config.deconv_channel*config.deconv_dim),\n", 270 | " nn.ReLU()\n", 271 | " )\n", 272 | " \n", 273 | " self.de_conv =nn.Sequential(\n", 274 | " nn.ConvTranspose1d(config.deconv_channel, config.deconv_channel//2, kernel, stride=stride, padding=config.padding),\n", 275 | " nn.ConvTranspose1d(config.deconv_channel//2, config.deconv_channel//4, kernel, stride=stride, padding=config.padding),\n", 276 | " nn.ConvTranspose1d(config.deconv_channel//4, 1, kernel, stride=stride, padding=config.padding),\n", 277 | " )\n", 278 | " self.adjust_linear=nn.Sequential(\n", 279 | " nn.Linear(config.adjust_linear,241),\n", 280 | " nn.ReLU()\n", 281 | " )\n", 282 | "\n", 283 | " \n", 284 | " def encoder(self,x):\n", 285 | " x = self.conv(x)\n", 286 | " x = x.view(x.size(0),-1)\n", 287 | " x = self.linear(x)\n", 288 | " return x\n", 289 | "\n", 290 | " def decoder(self,x):\n", 291 | " x = self.de_fc1(x)\n", 292 | " x = x.view(-1, config.deconv_channel, config.deconv_dim)\n", 293 | " x = self.de_conv(x)\n", 294 | " x = self.adjust_linear(x)\n", 295 | " return x\n", 296 | "\n", 297 | " def forward(self, x):\n", 298 | " x = self.encoder(x)\n", 299 | "# n = self.n_fc1(n)\n", 300 | "# n = self.n_fc2(n)\n", 301 | " \n", 302 | "# x = torch.cat((x,n),dim=-1)\n", 303 | "# x = self.fc_combine(x)\n", 304 | " \n", 305 | " x = self.decoder(x)\n", 306 | " return x" 307 | ], 308 | "execution_count": 6, 309 | "outputs": [] 310 | }, 311 | { 312 | "cell_type": "code", 313 | "metadata": { 314 | "id": "sTNajyBWcLdX" 315 | }, 316 | "source": [ 317 | "class Discriminator(nn.Module):\n", 318 | " def __init__(self):\n", 319 | " super(Discriminator, self).__init__()\n", 320 | " kernel = 3\n", 321 | " stride = 2\n", 322 | " self.conv = nn.Sequential(\n", 323 | " nn.Conv1d(2, 64, kernel_size=kernel, stride=stride),\n", 324 | " nn.ReLU(),\n", 325 | " nn.Conv1d(64, 64, kernel_size=kernel, stride=stride),\n", 326 | " nn.ReLU()\n", 327 | " )\n", 328 | " \n", 329 | " dim = 64*59\n", 330 | " self.linear=nn.Sequential(\n", 331 | " nn.Linear(dim,512),\n", 332 | " nn.ReLU(),\n", 333 | " nn.Linear(512,128),\n", 334 | " nn.ReLU(),\n", 335 | " nn.Linear(128, 1),\n", 336 | " nn.Sigmoid(),\n", 337 | " )\n", 338 | "\n", 339 | " def forward(self, x):\n", 340 | " \n", 341 | " x = self.conv(x)\n", 342 | " x = x.view(x.size(0),-1)\n", 343 | " x = self.linear(x)\n", 344 | " \n", 345 | " return x" 346 | ], 347 | "execution_count": 7, 348 | "outputs": [] 349 | }, 350 | { 351 | "cell_type": "markdown", 352 | "metadata": { 353 | "id": "npt_JqzGcLda" 354 | }, 355 | "source": [ 356 | "## load model\n", 357 | "\n", 358 | " Load model from your google drive.\n", 359 | " Please add a short cut of our inference model on google drive to your own google drive.\n", 360 | " Change the \"model_path\" of the dataset if necessary. " 361 | ] 362 | }, 363 | { 364 | "cell_type": "code", 365 | "metadata": { 366 | "id": "1r_OdviacLda", 367 | "outputId": "a1bcb9f9-da76-4e28-c727-ef894d360881", 368 | "colab": { 369 | "base_uri": "https://localhost:8080/", 370 | "height": 508 371 | } 372 | }, 373 | "source": [ 374 | "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n", 375 | "print('device, ',device)\n", 376 | "model = Generator()\n", 377 | "\n", 378 | "# bce logits loss L1:0.1163\n", 379 | "model_path = '/content/gdrive/My Drive/deploy_model/cgan/0827_1851.pth'\n", 380 | "\n", 381 | "model.load_state_dict(torch.load(model_path))\n", 382 | "model.to(device)\n" 383 | ], 384 | "execution_count": 8, 385 | "outputs": [ 386 | { 387 | "output_type": "stream", 388 | "text": [ 389 | "device, cuda:0\n" 390 | ], 391 | "name": "stdout" 392 | }, 393 | { 394 | "output_type": "execute_result", 395 | "data": { 396 | "text/plain": [ 397 | "Generator(\n", 398 | " (conv): Sequential(\n", 399 | " (0): Conv1d(1, 64, kernel_size=(3,), stride=(2,))\n", 400 | " (1): ReLU()\n", 401 | " (2): Conv1d(64, 64, kernel_size=(3,), stride=(2,))\n", 402 | " (3): ReLU()\n", 403 | " )\n", 404 | " (linear): Sequential(\n", 405 | " (0): Linear(in_features=3776, out_features=512, bias=True)\n", 406 | " (1): ReLU()\n", 407 | " (2): Linear(in_features=512, out_features=128, bias=True)\n", 408 | " )\n", 409 | " (de_fc1): Sequential(\n", 410 | " (0): Linear(in_features=128, out_features=4096, bias=True)\n", 411 | " (1): ReLU()\n", 412 | " )\n", 413 | " (de_conv): Sequential(\n", 414 | " (0): ConvTranspose1d(128, 64, kernel_size=(3,), stride=(2,), padding=(2,))\n", 415 | " (1): ConvTranspose1d(64, 32, kernel_size=(3,), stride=(2,), padding=(2,))\n", 416 | " (2): ConvTranspose1d(32, 1, kernel_size=(3,), stride=(2,), padding=(2,))\n", 417 | " )\n", 418 | " (adjust_linear): Sequential(\n", 419 | " (0): Linear(in_features=235, out_features=241, bias=True)\n", 420 | " (1): ReLU()\n", 421 | " )\n", 422 | ")" 423 | ] 424 | }, 425 | "metadata": { 426 | "tags": [] 427 | }, 428 | "execution_count": 8 429 | } 430 | ] 431 | }, 432 | { 433 | "cell_type": "markdown", 434 | "metadata": { 435 | "id": "fofwexSxcLdd" 436 | }, 437 | "source": [ 438 | "## visualize" 439 | ] 440 | }, 441 | { 442 | "cell_type": "code", 443 | "metadata": { 444 | "id": "T0ZBUAA3cLde" 445 | }, 446 | "source": [ 447 | "def laser_visual(lasers=[], show=False, range_limit=6):\n", 448 | " colors = ['#3483EB','#FFA500','#15B01D']\n", 449 | " fig = plt.figure(figsize=(8, 8))\n", 450 | " for i, l in enumerate(lasers):\n", 451 | " # fig = plt.figure(figsize=(8, 8))\n", 452 | " angle = 120\n", 453 | " xp = []\n", 454 | " yp = []\n", 455 | " for r in l:\n", 456 | " if r <= range_limit:\n", 457 | " yp.append(r * math.cos(math.radians(angle)))\n", 458 | " xp.append(r * math.sin(math.radians(angle)))\n", 459 | " angle -= 1\n", 460 | " plt.xlim(-6, 6)\n", 461 | " plt.ylim(-6, 6)\n", 462 | " # plt.axis('off')\n", 463 | " plt.plot(xp, yp, 'x', color=colors[i])\n", 464 | " plt.show()\n" 465 | ], 466 | "execution_count": 9, 467 | "outputs": [] 468 | }, 469 | { 470 | "cell_type": "code", 471 | "metadata": { 472 | "scrolled": false, 473 | "id": "IFUUegxMcLdg", 474 | "outputId": "a56a43ef-4603-454f-fe7b-5e57fd3d9542", 475 | "colab": { 476 | "base_uri": "https://localhost:8080/", 477 | "height": 487 478 | } 479 | }, 480 | "source": [ 481 | "data1 = None\n", 482 | "for mm_scan, laser_scan in loader:\n", 483 | " mm_scan = mm_scan.to(device)\n", 484 | " x_hat = model(mm_scan)\n", 485 | " \n", 486 | " x = x_hat.detach().cpu().numpy().reshape(batch_size,-1)[0]\n", 487 | " laser = laser_scan.numpy().reshape(batch_size,-1)[0]\n", 488 | " mm = mm_scan.detach().cpu().numpy().reshape(batch_size,-1)[0]\n", 489 | " \n", 490 | " laser_visual([laser, x, mm], show=True, range_limit=4.9)\n", 491 | " data1 = [laser, x, mm]\n", 492 | " \n", 493 | " break" 494 | ], 495 | "execution_count": 15, 496 | "outputs": [ 497 | { 498 | "output_type": "display_data", 499 | "data": { 500 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAeUAAAHWCAYAAABJ3pFhAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nOzde1xUdf7H8deZGa4KXpAwtaLSNMpMHS8peUmz63axtW2ztN3Ust0um2XaL9vtpmXZVlZWWKmlW5Z2Wcuyi9WSlY53I00tLLMQ8QLIbWb4/v4YQFBEzIE5Du/n4+ED5szhzBfwMW++t8+xjDGIiIhI6DlC3QAREREJUCiLiIjYhEJZRETEJhTKIiIiNqFQFhERsQmFsoiIiE0EJZQty2pqWdablmWttyzrO8uyzgrGdUVERBoSV5Cu8yTwgTHmj5ZlRQKxQbquiIhIg2EdafEQy7KaAKuAk4wqkYiIiPxuwRi+PhHIBl62LGulZVnTLctqFITrioiINCjB6Cm7ga+B3saYbyzLehLINcZM2O+8UcAogEaNGnXt0KHDEb2uiIjI0WL58uU7jDGJhzovGKHcEvjaGJNc9vhsYJwx5qKDfY3b7TYej+eIXldERORoYVnWcmOM+1DnHfHwtTHmN+Bny7Lalx0aAGQc6XVFREQammCtvr4ZmF228voH4C9Buq6IiEiDEZRQNsasAg7ZLRcREZGDU0UvERERm1Aoi4iI2IRCWURExCYUyiIiIjahUBYREbEJhbKIiIhNKJRFRERsQqEsIiJiEwplERERm1Aoi4iI2IRCWURExCYUyiIiIjahUBYREbEJhbKIiIhNKJRFRERsQqEsIiJiEwplERERm1Aoi4iI2IRCWURExCYUyiIiIjahUBYREbEJhbKIiIhNKJRFRERsQqEsIiJiEwplERERm1Aoi4iI2IRCWURExCYUyiIiIjahUBYREbEJhbKIiIhNKJRFRERsQqEsIiJiEwplERERm1Aoi4iI2IRCWURExCYUyiIiIjahUBYREbEJhbKIiIhNKJRFRERsQqEsIiJiEwplERERm1Aoi4iI2IRCWURExCYUyiJifxmTIWtx1WNZiwPHRcKIQlmkJgoDe0joBulX7vtdZC0OPE7oFtp2iQSZQlmkJgoDe0jqD6lzAz/7NfcGPqbODRwXCSOuUDdAxNYqh0G70bBxmsIgVJL6B34H6x6A0yfodyBhST1lkUOpHAbtRisMQiVrceCPotMnBD7uP60gEgYUyiKHojAIvfJpg9S5cMb9+0Yv9LuQMKNQFqmJwsAecpZVnTYon1bIWRbadokEmeaURWpSUxhoGLv+pIw98FhSf/0OJOyopyxSk5SxB77xJ/WvPiSkTi1f+CAbVi+qcmzD6kUsX/hgiFokEnwKZRE5KjRu1Z2ktVdXBPOG1YtIWns1jVt1D3HLRIJHw9ciclRo32kQG5hD0tqr8WwZQdvc6WR1nEP7ToNC3TSRoFFPWaQmquhlK+07DWJT/Ajc+Y+wKX6EAlnCjkJZpCaq6GUrG1Yvom3udDyN76Jt7vQD5phFjnYKZZGaqLyjbZTPIWd1nIP7kofJ6jinyhyzSDhQKIsciip62UL+tqVV5pDbdxpEVsc55G9bGuKWiQSPZYyp9xd1u93G4/HU++uK/C7lQ9aqfS0iv5NlWcuNMe5DnaeeskhNVNHLPrToThoAhbJITVTe0T606E4aAA1fi8jRQ1MJcpTS8LWIhI1ZSwrwZJZUWXS3LXEUszb3CHXTRIJKoSwitpfSysX4+XmB7U8bp7Gtzd3E/vQ8PRqlh7ppIkEVtFC2LMtpWdZKy7IWBOuaIiIA7uRInh6wnKS1V/Nu45kM99we2B61aagW3UlYCWZP+VbguyBeT8QetOrXFtpHrOKLxFk8sKw7V3SJDuxX1qI7CTNBCWXLstoAFwHTg3E9EVvRql9b8MTextRve3B9agzzVhTtm2PWbTQljASrp/wEMBYoPdgJlmWNsizLY1mWJzs7O0gvK1IPVGoz5DyZJaz88CGeHrCcG/s1YtLguH1zzBqxkDByxKFsWdbFwHZjzPKazjPGvGCMcRtj3ImJiUf6siL1S6U2Qypjm48+PXtXzCGXzzGf8N1QjVhIWAnG/ZR7A5dYlnUhEA3EW5b1qjHmmiBcW8QeshYH9sWePiHwMam/grkeDesVCwyClnMr9im33zQN+mvEQsLLEfeUjTHjjTFtjDHJwFXApwpkCSsqtWkfGrGQMKd9yiKHolKbIVdRPKTSiIV3/TQ+/GRhqJsmElTBGL6uYIz5DPgsmNcUCbnqVvdq+LpepbRy8dqC9+l0zEgi+s7FU9ib17Z3YRLDIEtD2BI+ghrKIiJ1wZ0cScvOGYxfmUbb77ozb0UekwZfSERM2YiFQlnChEJZRI4KbXrfTVvvXl5ML+T61BjcyZGARiwkvGhOWUSOClu/nMimdR9VLR6iymoSZhTKIrWhUpsh5cks4YmVKUw6ZiQ3nrqUSYPjeG3B+3g/V2U1CS8KZZHaUKnNkMrY5uOqiy8kom9gO5o790EmHTOSTxNmafhawormlEVqo3KpzXajA9tyVGqz3gSKhwDs26cccfoEzjvjgpC2SyTY1FMWqS0VrggZ7VOWhkKhLFJb+5faVEWvelO+T9n7eaCymif+HsZvT+OcnGH6PUhY0fC1SG1ULrVZXjhEd4uqN9qnLA2FQlmkNspKbc7a3IOUwhLcyftKbXoKe5OxzVdp3lPqgvYpS0Og4WuR2kgZC0n9SWnlYvz8vMD8ZlJ/PLG3MX5+Himt9PdtXdM+ZWkI9E4ichjcyZFMGhzH+Pl5XNElmnkripg0OK6s1yZ1xZNZwmtl+5QjTp2LO7l3lVrYIuFCPWWR2iorIOJOjuSKLtG8mF7Izad9g7vgiVC3LOxpn7I0FAplkdoqKyCyYfUi5q0oYkK3pfTJHsYG75mhblnYG9YrNjAaUWlbWkSH0Zw3QPuUJbwolEVqadbmHnzcfBZJa69mpvtxLskfjqf1K4z4oEtgflPqRMUeZajYlratzd0UZWhbmoQfhbJILaW0cnHf0m783HwkrbZOZFviKB5Z2Z0b+8aSsc0X6uaFrfLFdRtWLwqMVLSdzXDP7Ww5dXbV0qciYcAyxtT7i7rdbuPxeOr9dUWO1IbVi0haezWb4kfQNnc6WR3n0L7ToFA3K+x5MktY+eFDJCX3YOq3PfYtrstaHNiuljI21E0UqZFlWcuNMe5DnaeeskhtZS2m/aahfJE4i9Fr7uCLxFm03zRUPbV64C54gqTkHjywrDtXdIlWIEvYUiiL1FbOMja0nc3Ub3twfWoMU7/twYa2swPBIHVqg/dM+mQPY0K3pcxbUVQxlK27dEm4USiL1JIn9jb+/klXJg2O48Z+jZg0OI6/f9IVT+xtoW5aWPNklvD3T7qS1XEOl+QPZ6b7cZLWXh34g0jboSTMKJRFaumXJQ9zV+elFYVC3MmR3NV5Kb8seTjELQtvr3xVyHW9YgJz9+1G02rrRH5uPpJnM3qEumkiQadQFqmlDqf1xP3LtYGhUwKLvty/XEuH03qGuGXh7dqzYpixpDDwcy/bDnXczjRuSvkm1E0TCTqFskgtte80iKyOc0haezWed8eRtPZqrb6uB+7kSJ4esJyktVfzbuOZDPfcHvi5a5GdhCGFsshhaN9pEJviR+DOf4RN8SMUyPWkfcQqvkicVbH6un2nQRV36RIJJwplkcOwYfUi2uZOx9P4LtrmTq8Yypa65Ym9rWLVe8UdopL6azuUhB2FskgtlRcOyeo4B/clD1cMZSuY61Z54ZCnByyvWPVeUeFLt22UMKNQFqml/G1Lq8whl88x529bGuKWhbeMbT769OxdMYdcPsd8wndDtU9Zwo5CWaSWul5wD+0jVlVZXNS+0yC6dumtHlsdy2vSLzCHnH4lrLmXkzYM5fNE3bZRwo9CWeRwlN2+sSKYsxarslQdK78hhaewd8VtG1/fPZyEkweEumkiQadQFjkcSf2r9NhIvzLwWD22OuNOjmTS4DheW/A+hRnP8mr+GP7UdCbumC9D3TSRoFMoixyupP4VPTbajVYg1wN3zJc80GIE/9g6nfxT7iOi71zdtlHCkkJZ5DBNXXkH6Zueh9MnwMZpkLWY9OwlTN04LdRNC08Zk8leN5sJO6ZzpvvcwA0pfvNCm8HapyxhR6EscjiW3kDnzS8xMqoF6ceeD6lzSf/fFYz8+lo6N+0U6taFpdkbTyNi29uMPDuWG/s1ClT3WnM1s3+7RPuUJey4Qt0AkaOKgVRTSlq7vzHScxPDE89mpiuWtCadSU3sFerWhaUtrj78a+d0Ht0wFKzRnLRhGnfunM4xzfuEumkiQWcZY+r9Rd1ut/F4PPX+uiJBUbbi+uEWPXl892pub30p49xTQ92qsObJLGH9oru5pvEUXs0fQ4dBEyvu1iVyNLAsa7kxxn2o8zR8LXK4kvqT3uYyZu5awajojszM/h/p2UuAQHjMWlIQ4gaGH3fMl1wRP4Ppu8ZwRfwMrbyWsKVQFjlM//7wCUb8+gEPx53PHdnfcG+zv3LdN6MZ/d+PGT8/j5RWmhUKqm9uwPfZ5UzYMR3fafcFPn52OXxzQ6hbJhJ0evcQORxLb8CRNx/3rjtpfeZtZLX4E39YM4SffH15xb+KGYP7aFg1yLLz/cR4DSPPjqV9p0ZsaBZL0VpDYb6fxFA3TiTIFMoih8PArcbLhu5n8vf5edx8mo/WFrQrasrfTx2tQA6yWUsK2Fr0b67oeGWg9nXZQq+5cXPwx/RnWKgbKBJkGr4WAaZunFYxL1yu2r3HPZ6HPm/RftNQJrV9lLO3D2N89ky2nzpt3y0FJWhSWrlYvKEkUPu6UonN9p3OZViv2FA3TyToFMoiQOemnRjpuakimNOzlzDSc1P1e4+T+rMtcRTu/Ed4O/861vnOxp0cUXFLQQVz8KjEpjQ02hIlUqY8iIcnX8vMzFdIcz974N7jjMn8tBvif5jMupjr6eF/iV/b3MmHa/fS+bz/C5yyzadeXDB9cwPFP7zGrb/M5Ez3udx46lL44nI4/k+BkQuRo4C2RIkcptTEXgxPvpbHv3+S4cnXVl8MxHJxXOY4ck8aS+oVjxDRcTzHZ47jvI6NyNjmw50cqUAOollLCti43YvXDxd2jGTeiiI+ziiixGfACnXrRIJPoSxSJj17CTMzX+H2U25lZuYrB8wxA2B8WJ0f4/hfH2X1e+Pxrp0EnR/j+KYwrFes9ikHmdMBQ1dP5uvWr3FJ/nAe7/AYXbdeyxctX4Pu6iVL+FEoi7Bv6DrN/SzjTh1DmvvZKnPMEOi1eWJv4y+/uHin6SV02vMwc3YOZ+IPI3mxtAeD//uE9ikHmb8Ubh0YyyMru+OJuJ6Oux9ma8JItkX1DXXTROqE3j1EgJW7V1eZQ05N7EWa+1lW7l5dcewc8wRPLEjhzPaljM1bxJ7467jCn8Yz27/nnqJM2vz6CNMGx2lbVBCVTwXE7fmMk7dPx9PkLtyF0+nYdRCgW2ZK+FEoiwA3txt9wLHUxF4VgTxrSQE9Grt5OPFKirIM2bH3cnfxdLZERzHbtYJe227h3NNVOCTYli98ECwXfXY8xhfHzGLqtz14OKUpZ3x6MRHnLNC9rCXsaPhapBZSWrn4+ydd2dXij0Q4IfnXXxnh383UyGha7rmAO48v0T7lOrAruiun7niAzS3u4JLzLuSuzks5Kfsx1jSboHspS1hSKIuUqamASPl+2StXPMKc3SPpkPA0M1yNabZ9JBvivuHbE8/WPuU6sC2qL0tav8nJOx7D8+443L9cy/I2r/Bt/C26l7KEJYWySJlDFRBp+ctjXB7zLC2bzOLayONIK9nDLV6YGJPKPd/fzOr8r5g0OI6Mbb5QfhthZVivWAb2v4BN8SNw5z/CpvgRDOx/gbadSdjSnLJImfLFXQcrILI+y+Lvzf7Jja4rSNx2Pe27rGFg6Tg81kQePGUq6b+t5vqBfTWvHExlxVra5k7HE38XbXOn89OS5hzfFPWUJSyppyxSycEKiEx8L49NWUVsPfFhXnB+xttn/I/4zZP5JPohup3g4PrT+/LywFtC3Prw8/F6P21+DBRrcV/yMLknjaXNj+P4eL0/1E0TqRMKZZFKaiogYgGFjc6EdqNptXUi7+69jiznGaFrbAPgwMeze+7j2K2Pwpp7OXbrozy75z4caIpAwpOGr0XKVC4gkprYi9QWZ1U8btPsTFrF9qT12iEUO+GN/DFc1SQNCtIg4e1QNz1snTN4AvGZJby+aA/XrHuA1/PH0PPCuzRFIGFLPWWRMjUVEElp5eKDb4txOqDEB22aOinxg0P1l+vU8oUPcsy2J7gifgbTd43hivgZHLPticD+ZZEwpJ6ySJlDFRBxtl3H7etmcmHSEv7gm8za5uMClaVylqmIRR1JbBJJmx/HMW3PfThPu52XMpow2j8OTnw41E0TqRMKZZFa8GSWsHKLl0tOyKBn0Ut8FjGWM3em8dPmZoGVwFInHMbHtD33MTTuSTbl7qVt3HSm7bmPS43mlCU8afhapBZe+aqQExOjOa/kHjKajeGhn8fiiR3DcZnjwNLftnXlU+s2elx4F5ualO1TbjKCHhfexafWbaFumkid0LuJSC10PzGC75YV0azdRHrvncLjHXJpk5PGisSJdFWvrc6ctudxyHVxcqV9ypvXN+U04wPuCXXzRIJOPWWRWlj6o5fTW7v4z6YOFbcQzIi9niU7Twt108Kb5aJzzt1sbnEH7kseZnOLO+icc7dGJyRs6X+2SC1ce1YMry3oyIPNh+PdA59FjcVd+Bw9Ip6HhLdC3bzwZXysTJhYVvt6N21zp7OyxUTQ6ISEKfWURWrBnRzJ+adF4fWD0wGbsv1EusDlMEDNN7OQI9P42C5Val83PrZLqJskUmcUyiK1MPG9PBr/MIX06LuYs3skI5pN4T+7R/KxcxxkPHrIm1nI79O4VXdarxlCh9xpeBrfRYfcabReM4TGrbqHumkideKIh68tyzoOmAUkAQZ4wRjz5JFet0HImAwJ3arucc1aDBmPQsqdBx4vv39sdV+Ts0wF+uuQp/RF1ngHMb34ISKaw8w9Y2gV/xJr/U4Gpsw95M0s5AhYBN5ZKPuogi0SxoLRU/YBY4wxKUBP4G+WZaUE4brhI2NyIDgry1oM+Zsh/cp9z2UtDjxuObD64wndAv8O9tzBXidjct1+fw3ARSd25stjXuYrhxOAzZHbuTkmli5m340RDnYzC/l9Zi0pwLnhMXae9H+sbzIad/4jeKJv5OvYcTT6YUqomydSJ464p2yM+RX4tezzPMuyvgNaAxlHeu2j1v494IRu8MVlcMJV0P35fUGaOjdwLP1KaDcaNk4LHEvqD807V38cAp8f7Lny6yb1r/o6B+uVq4d9SLOWFJC1qwtpkS0Y7fTTNfck1jT/hFtLzyU2rkNgZCOp/wE3s0htcZaC+QiktHLx3IqbmOgfTnN/YHFd16LniHJB5DmqNy7hKahzypZlJQOdgW+Ced2jzv69WQAs2PIarLm3anAm9Q+E67oHAh/LQ/Ngx2t6Lqn/vsDe/3Vq6mFLjVJauVi8oQRXo7sZXrybxfEZnJHXkeuL36Jb/sOQcmeVm1mMO3VMxVD2/ou/pPbKF9cV+wKL67bu8hPlghI/bPjNG+rmidSJoIWyZVmNgXnAbcaY3GqeH2VZlseyLE92dnawXtY+Kg8dl4fjF5fBJ2VD0X3egva3HhikWYsDvd3TJwQ+Vg7N6o4f6rnfE9j7t7/y6zTwoe+pG6dR1MjDdb1iWPbjNGZHRnJ5SQlfxW/gc5z4fV7Y8lqNN7OQ32f5wgdJ2DGXN2NnM3vXSK5pPIXcFhfzfdRg8rctDXXzROpEUELZsqwIAoE82xgzv7pzjDEvGGPcxhh3YmJiMF7WXqrrHZf6IOuTQDjCgUFaeXj5jPv3heZ3j1d/vKavqU2Y19T7PlRPuoGGdvmq6lk/v8iLzb/lxqJiPo2IZXzxDv4W25TPrCgwgZtZ7D9UnZrYq9qbXEjtNG7VnROL/ktB1kqGJszgw71DaL79P7RofSpdL1A1LwlPljHm0GfVdAHLsoCZwE5jTK0K0rrdbuPxeI7odW2pPMjajYYNTwEm0Dsu/7zP21XnetsMhuSrgrf6ujxYq5tTrvy4urno/du///MHu9b+1whD6dlLuHrJNSTmdmZ33FpeLvqZ9hFd2OBdzteNOxLT/q90btqpSiinZy9h5e7VCuUjsPXLiXi+3cgljWayMeZPJO39iM8K/8Af4ufi7L8g7P/fSXixLGu5McZ9qPOC0VPuDVwLnGNZ1qqyfxcG4bpHn8o90dKSQAifcT8c/yeq7OMoH0qOO/nAN5ak/tD//eqPp4wN/DvYcznLqoZk+evkLDt0D3v/9lc3j13d8Hf5tSsLgx505WIgXyztSNvdA/g5fhkd/XnEW5eSVLyEs0phbOH3dDZGe5TrwFtbOnJR3Fy2RvWjfdFrZDU+l/PjF/BO6d37/kAVCTNHHMrGmHRjjGWMOcMYc2bZv/eD0bijTvnQcdIAcETuO97j+cCccuU3kvIgDabfG9j7t7+6oe/yr9k/tMNoAVnlIC4ftp62KY15efeyMe5TorFY63SSU7qQwtIYfMYJiWeT6suvWNj18HdTKhZ8aeX1kTmr13k8v2scbYo/Y1tEL9oVvM70nbdwfK87tWNAwpYqegVL5Z7ogI8DIVw5rOoihA9HTYENtepJf/jJQrzr94X2h58sZPaPPfiw6ayKHrT38ysDj5P6H3Xz0JWrcqUm9uKWdn/jX98+yK8x71JqOXmxII/phbv5e0xjnvGejdPpguz/QUI37VGuA45lN3Bd/GN8VPBHWnmX8FHBH7ku/jEcy24IddNE6oxCOVhq0xO1s0O1P2sx5+QMY/z2NDzx90DqXPpmDyM9fRE7GvWt6EHPzhkeeAwVvejZ77zHxPfyqvSiPZklzFpSEJrvdT/lPeTKVbluWn4bj6x/jNPjU/DhZUhECscUnETf0gLuyk0iqvFXLMwbTHbzIZCz7IA9ytoKdeQswGl89G30IdN3jaFvow9xGp8KeklYUygHy6F6onZ3qPbnLCOi71yuuvhCxs/P47nvunPPjjRGnb6OlZ5FFGY8y6v5Y7iq2UxWehbhySyBpP5saDubi3KH0/rn+/B+HuiJewp7s/LDh+jRKL3q64WoF71/D7n/Mf14c+t8kqKT2FLwE392dGGBby17Gn3LdF838mI28WfackmjGWSWtCU9MVV7lOvA9uZXYjldeP2QFO/A6wfL6WJ78ytD3TSROnPEq69/j7Bdfd1APPfZXl5ML+T61BhuPHUphYuH8I+t0znTfS43nroU7+dXMn57Gm1PP5d5K4qY6X6cVlsn8mr+GPJPuY95K4p4esBy2m8aapvV3OWLs845ph9vbn2LPi1S+WJHOjGWk3tdF3HCnllcH90Ml+Xjsb0OLuVnfo69kOPb92VqRJxWX9eBX946j7k/p9IhIY8LrEdZaO5kfU4cVx6XTuvLPwx180QOS21XX+t+ynJYPJklzFtRxPWpMcxbUUSPoi+ZvSMQyPNWFOFO7o2771z+uPRLbk5PZUK3pbTKfgFOn8AVGc/yD08qV7jPpX2nQdCymnKh5cPl9VwONDWxF+cc0483ts6nY5PTOb7RcfyLXkzZuYwHS97mNE7Bb/3KJT7DZdbPfFd8Bq35BhLu4OZq/ohITeyleeUjtC7+Nka3uAqvH/7LnfTjefq3gM/jX6N1qBsnUkc0fC215sksYfz8PCYNjuPGfo24rlcMN3hupLN7EDf2a8SkwXGMn5/H7B97MGHjaCZ0W0qf7GFsaDsbT/w9TNgxnX+3GcGmdR9VDG/bZTV3evYS3vt1IUPaDGbL3i288/MbdIxuyQxvHi1MIt/EZnGhz89TJdvYyQkc6/qFpTFjjp41A0ehxJ1zMaU+XE7Iyi3F5QRT6iNx59xQN02kziiUpdYytvmYNDgOd3Jgu5e/FG4dGIu/NPC8OzmS63rF8NznBUwaHMclx60jq+McblzUlTveyOWqiy8kpv8b3NY5g/Hz89iwetGBW7BCsB+6fOj61R4v80zXJ5iRNACwuO7nN5nq6sgWK5vBPi9fuBx84GiJ5c/nM+c/GGgePyq3fh0tLMBvXHyx9zxGNJvCF3vPw29cWuglYU3D11Jrw3rF1vgYAkH97z/FlwX3WNoD527NAyg71p82Sf15uvEiTvhuKPSvdGOOynPK5T3o0ycc+g5YR2jl7tWkJfYhtbQYMiaT2iiZGd48/hmVyGLf91zq9fGc9zc+drTgb1HRXJR3GfdG/5ufjh3L8TnLVFmqjiyMfYr07Sfxt6b/ZFtEL86NfZNndt9HXvPb6BzqxonUEYWyBFV1QX33RXEHHGsfsWpfIMOBW7Aq96DLQ3v/W1a2GXxgA37H/PPN3jxolBy4dsp4yJgETTqyOf97hpT6+TTCwQfeBHp4DRfnXUzL+LfwRIxhb2YRx199b61fRw7P+QW3cEqT+axxXcmZ3tdZ5foTf2nyGN8X/AC8HOrmidQJhbKERnWhWU2P+MPsszjn8yuJ6DuXWZt7MDBxFK3WPcAH3MmJ0QM57tMhvBU7k6GXXsSKN/5Cinc+8xrN4dj1D3BO71Rmf13Asf4VfB11Gyf4vqBD5ErWN7sdf2ngVoA9i5+gFBe9iifzbdM7SP/2UXxWAi/lb+DF4hIG+HfwuPNYboiJ4bLtF/Nwkzf4MmIMGb8UkdDtrvr9mTUwjaIsIr0+Ti5ZGFjo5X+eSKePRlEawJbwpTllsZf9ipgknDyA8dvT2LrpK3o0Sid2y/PMyh1DP8fLTPusgPFZ07kodzhr3x/PKcXz8flh6Y9e3v25IyWfXsaleVeTt2MjcZlPMDjvSnYVOtm57BFa/fYku/b05Zs9HnoXPMiHeX+g064HKPJG8IQzn5FFXgb4d/C2OY7nI5302tOT1k3f4vnsW8n4pYiCk++omEuXOpAxmfzIUyj2u3A6Agu9Ihw+TKmfn+OGhLp1InVGPWWxl/160O7kSLj4QmIpuhQAACAASURBVJ5YAA+0uJq7d05nZUkqTU88h395h/GvndNZFX09/XY/zGeRY3nn17O4L2EEq6Kvp7gIXE6Itor4W9N/ssz1V7runUJk80tJLXyZrIhUHoj10CS3C6Mbz+Q9cwyzYv2MKfKSFh3BtsJ2LIgt5OIdF3NP1BvM3H4rDny8lnczT6VEVSx4kzqQ0I3TV13MQtfd7Ni5ixHNplBYGsMHzglYvy4DLgh1C0XqhEJZbM+dHInvhHX8Y0NgP3R74IH07kzoNotRcW9ybN67/Jc7SfW/SG6HvmwqHkG//Ef4L3eStauUEc2msCHmKk7Jf5v11kBSeZnvTF/+7P2cGGd3/i/+B34rbskbURaP7vVzEdls3NuZWY130HtPl0Ag7wkE8tr4fxBV5GfRt8UK5bqUs4x1zScwIHsSUU29FJbG4LAsSndvoLDzc6FunUid0fC12J4ns4QJG0dzpvtcXl9WxGvLAtXEFq8voVXeu7zdaAYPbBnL27EzOCf7z3TYM43PIsbSj+cZ2iyNWbljSMr/iC2RAznL8To/0JPTHJ/xk6Mng4u/YXCxk+eiXQwudnIueUwsuoTFjbI5e09nVjbOYETuWBzGR87xY8jM8TPi7BgWbygJ7LWWupHQjZSdk4h2FhNpFbKKSygpdXFBk3fY+cMnoW6dSJ1RKIutVS5Y4k6OwGCwsIiLtmgfuZJ/5kxn5uae3DowljVbfWDgk8LLeHvbWUS5Alu0PEWpvJJ7K2f45vKDsz8n8TU/OPtzfOnXzPafyvwoP8MKo5kXZbiu5EJeSVjBxTsu5py8M4nb8hRftnyVl0t78odO0UwaHMeMJYVc1yuGjG2+UP94wlfOMvIj2+M0xWwyZ9HDmstKxx9ZuOdSUpuvDnXrROqMQllsLWObjy6p/6GokYeMbT4eGxLPo0Pi+O+WL/mxayJJ7QYwKCWKoT1j+cNxa3knfg7ftn6aS45bS+Q5b/NO3Bz+0vodrm/+JCsj/8pxpd+wMf56TvR/xuuRqTwYt4d7vSdzv9nJHRGXsaTZ11xQ2puTS45hdu7NDDy2F/39U/A1yuCON3IBmDQ4Dn9p9du/JEgsFy1KPHxv9aOt9RXfmb6k8jKOpu2ZsevmULdOpM7ohhRie+UVt9Lcz5Ka2OuAx4eUMTlQeStn2b6PloupW/5D58RUUmOOrTie7mrMgu8/Jd56mUGn7VvM5cksYdG3xbRp5lQY14fFF/LTbos2BQv5gZ6cxNes5XzyC0rI7PguQ3vqdyBHl9rekEKhLEeF8iAennwtMzNfqX0gy9Hpu8cxK+9gA33pwGd8W9qPU63PedfxAIv5O0/+uUmoWyhyWGobyhq+lqNCamIvhidfy+PfP8nw5GsVyOHut4/5OeYCTjGfs8mcxanW56zlfBLzF9P9xIhQt06kziiU5aiQnr2EmZmvcPsptzIz8xXSs5eEuklSlywnxxUu5Hurb8Wcckc+oEkjF0t/9Ia6dSJ1RqEstld5DnncqWNIcz/LSM9NCuZwFtuKJyOast3xdUVP2Uck/y2K5LuIl0LdOpE6o1AW21u5e3WVOeTUxF6kuZ9l5W5tjQlbBjr5/YyKSuA35wp8RPCFI4q0Zt9yclTHULdOpM6oopfY3s3tRh9wLDWxl+aVw8TUjdPo3LRTld/ngq1f82pENH/z5jMyOoFrSgp5JSKWawsjKWq7HhgYugaL1CH1lEUkpDo37VRlOiI9ewm3RxTSx1/As5GNOLO4MU9GNeYcfyGvxPrZ8mP7ELdYpO6opywiIVU+HVF5y9tLrlh6+Lz4zV4ejHLQ3edlniuWG/Y6aX9y71A3WaTOqKcsIiG3/5a39gURpDsieCaqMVf49rLUFcnl3iL+E1ugBX4S1hTKIhJy+295m+PowTqHxS0le/jYGc8/SvbweUQk53p7UBSTEermitQZhbKIhNQBW94S+/CM4z1KS108FdGEP/hz6en38WzhHj6KXM71ndykZy9h6sZpoW66SNAplEUkpA7Y8nbc5aQVZfNRREueKcrjcl8BN0U35WerC2P2JPHC+rcY6bmJzk07hbjlIsGn2tciYjv57/agUd5SvLjwmwi+djq5KSaewbRkjsPHK2dN05Y4Oaqo9rWIHDWmbpxGevYSZi0pwJNZgtO/h3RnFM9HxpBpOtHDV8pwbz5pVjY3tBumQJawpVAWkZAr36v8Vc4S7nwjjzeLExkVnUAnv5dTnV+zNAJmuOK42p+s2ucS1hTKEjLlvaPKtICnYSrfq/yRNYYTW13GQ1E/8vfC7pztLyLdEcXo6KY8VppAl5YfqPa5hDWFsoRMdZWctICn4UpN7MUxjvYsaLyFa70FjPAvpMRE8pYrlgt9hZxf9C0XFN6i2ucS1lTRS0KmukpOlVfhSsOSnr2En7zrsEqjeDHS0Ke0AD8u3nPG8lzxHpyWH1fO/wDVPpfwpZ6yhNT+lZz0RtswlY+SnF38JMdkPoUxFtdEt2BEdFPuyjuGs0pLsYBmMXrLkvCm/+ESUvtXctI8YcNUvlfZl9OV6L3dSPFbFFoOzvB7+YtrJQ5TQrorjqlW9W9ZWp8g4UKhLCFzQCUnLeBpsG5uN5rUxF40irI4oflLrHf5iTaGNc5I0h1RfO10MjIyns7xp1b79VqfIOFCoSwhc0AlJy3gafCS265k1bHT+MeuExni3YsPGBrdgr9EJ5BWtAMaHVdt77fy+oSHv5tS8ceepkPkaKNQlpAp7x1VlprYi5vbjQ5RiyTU/rt5JWf+OpqREcu42FeCAQotB538JWC5GLnt3YP2frU+QcKBQllEbOPY3Ovo49/LhuLTcVo+XECMKcXjjOK6qKakNe180LDV+gQJBwplEbGNdkku2rh+JCd2PaOiE5hZtIM/FUVRaDnw1vB1Wp8g4UKhLCK28JePn2Lt3q85JWoda50O0opy+LS0NXOji7mtJI8IDG8V/lrt12p9goQLhbKI2EJqy0582/RO3jHHcbM3j7WOSJ6JLeHOklzGe3fzb98xvF+0rdrer9YnSLhQRS8RsYXrT+/L8szHSWs2moKSNsyONPyrZDc3evNZU+TmfNbS7JiLWbl7tRZxSdhST1lEbOOnzZ05fnc/0mIsbvTmMdqXTykWZ0R7cFgWqVEJ6v1KWFMoi4htFDX2sLXpp/yjJJeZEY35whHFs5GNSXdG4cRXcZ6qdUm4UihLvVI5RDmYF9d9zrqmd3JHbkvGlezhfG8Rf41ugcsYRkUnkG65SC/OYcyqcarWJWFLc8pSL6ZunEbnpp0qyiGmuZ8F4K1f3uX9Xz+oeCwNV/pvqzllx2TOcDzGZnMKg51b+G9ENJscEbxQlMN10S3w7lpGRN53zOiepnllCUsKZakXlcM4zf0s1y0didf4iLBceoMVAF4eeAsTi/O4faWbhcd34GR/MS8X5TAqOoFE48cLFGIYfdJf9f9FwpaGr6VeVK5NnL7jK7zGR6G/kBF6g5VKsvNKuabJVHb7EwBI9Rcz3JvP45FNALjdGadqXRLWFMpSbyrXJsYYlUOUA2zd5aeN60eOi/gRH07SnVFMj2hMjCklAkNqk1NVrUvCmkJZ6k169hKm//ASMY5oIhwRpLY4S2+wUsWO/FIALEr52uliZHQCl/oKebVoBzOKdzNy90oAVeuSsKVQlnpRXpv40tZ/YHbPGczonsZIz02A3mBln6saTSXT2w6Dg1WOSKYX5fBo8S5WOSIBi7SmnSuKh3Ru2kmr9iXsaKGX1Iv9axPDvjCurkSiNEwnxmRyluttdviP4e/eX7AsMECyrwkjY0tJK97Bze1GV7kBhUg4UShLvaiuClNqYi+FsRwggmKOdeVSCjjLjp1vsmiWcBkjdy1j+HdTmJn5ygF/5ImEAw1fi4htHGetxWUFbtL4bGQcnzuiAXDgIzWqGee0vpTHv3+S4cnXKpAlLCmURcQ28knEYQUWe3X2l3BjdHP+54zC4OD+Xzfx5ta3GNJmsFbtS9hSKIuIbbRy/ohV9nlqaTEvFOVwQ3QCoyJa8rTZyL9Ou4dnuj5R46p9lXKVo5lCWURsw0Q0rfK4vHjIgigHZ/nbMrrtyMDxsmI01a3aL68eVx7M5YvCVCtbjgYKZRGxjWznaZRW9JUh3RnFjIjG3FqcT4ZzS5UecGpir4MuICzvST/83ZSKVdqag5ajgUJZRGyjOO8XHBgA0h1RjIxOIK0oh7EluTwe05mRXw2t1Vxy5epxWhQmRxOFsojYRhNHDl4TAcDKsuIhqf5ickubcXHOfNKadWPlhqcOeZ307CXMzHxFpVzlqKN9yiJiGy2TknDtXMGaoq7cxEqcVikGaObcwbKS80nd9j6p/f5b4zUqFxZJTexFaouzNIQtR42g9JQtyzrfsqwNlmVtsixrXDCuKSINz7ZdPt7dex3tor7DQSlFpVFYZVPM7ogPIGkAZDxa4zX2rx5X06Kw30Oru6UuHXEoW5blBJ4BLgBSgD9blpVypNcVkYZnuuMNSktLceJnm7cNUVYxJaUuHBb4rSjY9i60HFjjNaor23qwRWG/h1Z3S10KRk+5O7DJGPODMaYEeA24NAjXFZGj1OH0Jiufu7uglK3eZNK83Zgfu4e80jgiHT58xoGLYohNBuOrj2/hoLS6W+pSMEK5NfBzpcdby45VYVnWKMuyPJZlebKzs4PwsiJiV4fTm6x87uZsP2m+nkxtmsmJ3hjiHHkUlUbiskqxcEFBJlihXwqj1d1SV+rtf7cx5gXgBQC3223q63VFpP5V7k0OT7622htITN04jc5NO1U513l8L7KjPmZyXjMucq4lrzSeeGcuJaUuIhw+rIimIe8pw4Gru1NbnKVglqAIRk/5F+C4So/blB0TkQbsUL3Jyj3k1MRenHNMP7bHLiA2dwBdvBFMdcWxOqKYIn8kkQ4fBkj3FzJ116rQfENlKq/uHnfqmBpLfoocrmCE8jKgnWVZJ1qWFQlcBbwbhOuKyFHsUHuFK/eQb1p+G29ufYsmey7CxH/MiggfnU0JI6MT8ERYlBpY4ohiZPQxdC7YGqLvKKCuV3dLw2YZc+QjyZZlXQg8QeD2py8ZYx6q6Xy32208Hs8Rv66I2NP+e4X3f1xZIJDn88c2g8leei9dIofzXMJKxhbl8oPTxTsRsYzw5jE9Io5L/cVc3vE+VlpW0FZTi9QHy7KWG2PchzovKPuUjTHvG2NOMcacfKhAFpHwV9veZHr2Et7/dSF/bDOYxds/Y4v/G9qXNKOXr4SHo+M52XjxAo9HNqEIi99ij2fk909o+5GEraD0lA+XesoiUl1vesgXN9Lrt2u4tfk/+WtMc3xY+LAoKfuaWCxe7f2aFlXJUadee8oiIoerut50ux2TWet00NXn4PaSXAqwKLEsnACWhSE0GzdUxUvqi0JZREKiuspb0Xu7cU5+W2IchWx2RBBZFsJ+YIh3LxFYvPVL/a8jVRUvqS+h34UvIlLmtFYuzt79FunOKN5xxWKASGNwUcqHrhjGuOKY8kvghhRTzny43tpVm33XIsGgnrKI2M48Z2OMMfT1FxFNKWNLcjEYFpQ2h9KikLRJVbykPiiURcQ2dhWUss2XzK97+3Kpr4jR3nxmFOUwNTKeQb4iVpf+yKWRLeu1l1xO92iW+qBQFhHbOCXJxezcm3mENVzu38uo6AQAhnn3Mi+iEQ7g8phj671dquIl9UVzyiJiKy4nNHHsJNlfzAtFOQyPTsCHRYwpJQKg5Tn13qaa9l1rGFuCSaEsIrbRppmTG/vGsmd9c5o5c/CVuijEgc+yuL1kD1390Yzc/AK3OCLwGV+9VfWq7nVSE3spkCXoNHwtIrYxrFcsx26bwlZvMsWlUSyIjCQSQ4wpZXpEHJHs5ZaW5/HI+se0HUnCknrKImIrrV0/0jrmG26OaMlil49Xi3ZggOuiExga3Qzrp9f5T6856qVKWFJPWUTs5YSriKSQeGculBUPSfUXM8hXQollcYqrkQJZwpZCWURs5eWfX+BTZzMeK97FjKIcRkQn8MfoY5jniuYSr2Gb8WrVs4QthXJ1MiZD1uKqx7IWB45LvZi1pABPZkmVYxPfy2Pie3k1Hpu1pIDZXxcwa0lBxTU8mSXMWlIAUOVzsaeLTzmH22JcpDujSC0t5jS/l/+5oujjL+KfBTGk9Zih7UgSthTK1UnoBulX7gvmrMWBxwndQtuuBiSllYvx8/MqgtmTWcKijGI+yiip8ZjTAU9+XIDTEbjG8oUP8eo777N1l5/ZXxcwfn4eHX/5G9mfjMCTWcI7c+5nw+pFzH7nPTbNHQRZi8n+ZAQb3v0rnswSPvxk4b4/0vRHWb1IbXIqLxTtZFR0AjdFNuN/zij6+ApZ54jiS2fUQW8DKRIOtNCrOkn9IXVuIIjbjYaN0wKPk/oH3pgTugU+L5e1GHKWQcrY0LU5zLiTI5k0OI7x8/O4oks081YU8diQeICDHnug3TRWbjmdWwcOYsaSQq7oEo3PuJiUMJTXil7nyY97MrH3MjpmzafoV3h13cVcfEY3Wq8dQmsDM/PuoPUnl9G0tJCmzgg8n25lQOw3/BTzf7RcfRmRJ1+l33V92PIaZ/n99PcW8WZkY/7ozeeZ4l184Yjmr7FRtMleou1IErbUUz6YpP6BQF73QOBjeQirF11v3MmRXNElmhfTAwHrTo7EXfAEN5/2TdVjMV/yQLtpzNhwOg+0GMHQE7/hii7RrPJ8xPXNn2RF03u4rOA6Jp/yKO5fruX9Zv/hnpyZ/Kv5CJrmfR5YS2TBaS3y8fnBSwSm1EfP6I9wlO4lafO9lBogrn3gd2251GuuS41PZqbpyfsRMfzRm89iVwzpzij6lBbx57zz1EOWsKZQPpisxYEe8ukTAh/LQ7hyL3rNvYGP5b3ocpqT/v0q/ew8mSXMW1HEhG5LcW6YjCezhA3eM+mTPYwJ3ZYyb0URG1Yvwvv5lby55XTOdJ/LhB3TKVp8JY2//yf/bjOC8VnTuee7UWxuMoJ+vsmsirqeB5Z1p0Onc9nUZATu/EdY32Q06+NH0883mXcLRzJnz2girRJKceHAT6SjmHwrETImQcr4wMf8TFh8YWh/VmEq3dWYxxpvZkbRTp4p3kVaUQ6johP43BnDML6pt4IhIqGgUK5Oee83dS6ccf++EC4Li1mbe7AtcVSVXnSVBUS16U2HY3Af6nuqzfdc9rPbsHoR4+fn8fSA5VySP5w+PXtzxxu53LioK1kd53BJ/nBmuh8nac3VjP01jasuvpAb+zWis3sQr+YM55rGU9jV6gZWl5xNp8j/0anoRdY2HUenohe5KeVr1q/+iLZ7puNpfBcd9kyjQ+40PnON5ZKYNP4Un8Z7eUNwGB8ApUALsxlccYFAPm4IbHoOWg6su59lA7Zy+xc8UNSCPv5CvMZFamkx0wp3ssbhosSVGOrmidQphXJ1cpZV7f2W945zlgHQo1E6sT89z7Y2d8PGaRUBktLKVfX8Sr3pD5vOwlPYe99rJHTD+/mVgYVEcEBwV6w+3q/nOGtJwcHD+3CCvi7OPdQfI7X5Y6XsZ3fCd0OZ6X6c9puGQupc2ncaxKCUKM5NiaR9p0HQbjSttk5kXez1JLYdgDs5EoAWez/nmoSZrG4yjubbXmBm7xd59NiRzI2awe3r72B5m1f4c9FQHkwYzr92Tmd3XF+wAAPf7miM0wFOfPSPfY9CE0txaSQOAsHM3h8BRyCQOz8Gp95+4M9KjtjNqa/R1tkFr4nCZflYUdiTPqVF3FBSgjei/m9GIVKfFMrVSRlbdTgaAo9TxkLWYtpvGkpWxzkM99zOu41nkrT2ap4esLwiGCrOrzQnnXDygKqriQt7M357GufkDKt2GLx89fEG75lVeo49GqUfEGQVAV4p9CpWDpede8AWo/3+KPjwk4V4P6963Yo/Amo7j36oof3aDP2XnRedEgjdyvP5d18Ux90XxVWZWkjlJe52eyradd7uYUT3n0uniyYR3X8ux/98HxEdx+NP7M+kwXEM7H8BWxpfQeGxQ7jm0gvZ++syfun4Bu/Ez+G8Fv/jZcereIpScVp+nts5jhITzZqirlhY4IiG4u3QKFmBXA+8JooP9g6hS8zXfLB3CF4TFeomidQ9Y0y9/+vatas5an37iDG/fWqMMWba4nzjfiDbvPPBe4Hjlf32qTFvtjBm9YTAx98+Nct+LDYDp+ww0xbnm4FTdphlPxYHnp9N4ON+ys9/54P3zK5XEswvn99dca3qzlv2Y7Exv31qSl5vYV55fowpeX3fuVXOKXs8ZupbgXNWTzAlr7cwY6a+VeX5yudX9/0cVA3fU62er+m1yp8rP1b5caXfTZXz9//d1OC2/+w2Tz51r7nh0bfMk0/da6Y8eb/ZOSvBrJl9QaDNb58Y+PjN6FpfUw7fJ/PuN089fb/ZNSvBLHvnLrNrVoJ56un7zSfz7g9100R+F8BjapGPCuXfqdqALVdDcJQH+bTF+bUKuvLzl71zV41BVrk9rzw/ptpzD/VHQY3fkzGHDtPK3+vBvqfaPl9d6BoTlOCtyUMLcs1ZE7ON+4HAvyefute8Oe06UzrbMiZjSuCkb0YHfg7ljyXoXn17gdk1K8GsX/WhMcaY9as+NLtmJZhX314Q4paJ/D61DWUNX/8OnswSxs/PY9LgOG7s16hiP23F8PBB5qS3bvqKeSuKuD41hk3rPgoMFx9kMVn565SvPm6bO71iDvuA+V32bR9a5fmIK+JnHLhqnGq2GMV8WWWFuTvmywO2IFU42Gr0yg6xQO6Qz9fwsyufz69xaiFInA6IcAY+fy3/ZlpF/Mwn0Q/tG7Lu/ix0ngK/fRy015SqOkSuJOuMOYH1A0D7ToPIOmMOHSJXhrhlInWsNskd7H9He0955pd7D+hFLvux2Mz8cu9Bv2b/4eCf0x+qMlxsjKnS4ys/f/2qD415s4VZv+rDKo+rG8IeM/UtU/CfhH3X3a+XWbknXDF0XalHWj6EfUBP+VC913KH6sXWcS83GB5akGtSH842/SYHfk79Ju8wqQ9nm4cW5Ia6aSJyFKOWPWUrcG79crvdxuPx1PvrhtKsJQWktHJV6X16MkvI2OZjWK/Yg59f8ERFBbGK80/+pkpVqfKe+8s9nqdN27MCi8jKevLumC8hZxme2Nv2HUuOZOuXE3liZQpXXXwh7uRIPJklvLbgfW7rnEGb3ndXGQ2o3IYKYVrZauJ7eXyUUcKjQ+Iqfi53vpHHuSmRgUVmIiK/g2VZy40x7kOep1A++tUm8A91zuH+0RCu9HMQkbqgUBYREbGJ2oayFnqJiIjYhEJZRETEJhTKIiIiNqFQFhERsQmFsoiIiE0olEVERGxCoSwiImITCmURERGbUCiLiIjYhEJZRETEJhTKIiIiNqFQFhERsQmFsoiIiE0olEVERGxCoSwiImITCmURERGbUCiLiIjYhEJZRETEJhTKIiIiNqFQFhERsQmFsoiIiE0olEVERGxCoSwiImITCmURERGbUCiLiIjYhEJZRETEJhTKIiIiNqFQFhERsQmFsoiIiE0olEVERGxCoSwiImITCmURERGbUCiLiIjYhEJZRETEJhTKIiIiNnFEoWxZ1qOWZa23LGuNZVlvWZbVNFgNExERaWiOtKf8EXC6MeYM4Htg/JE3SUREpGE6olA2xiwyxvjKHn4NtDnyJomIiDRMwZxT/iuwMIjXExERaVBchzrBsqyPgZbVPPV/xph3ys75P8AHzK7hOqOAUQDHH3/872qsiIhIODtkKBtjBtb0vGVZ1wEXAwOMMaaG67wAvADgdrsPep6IiEhDdchQrollWecDY4G+xpiC4DRJRESkYTrSOeWngTjgI8uyVlmW9VwQ2iQiItIgHVFP2RjTNlgNERERaehU0UtERMQmFMoiIiI2oVAWERGxCYWyiIiITSiURUREbEKhLCIiYhMKZREREZtQKIuIiNiEQllERMQmFMoiIiI2oVAWERGxCYWyiIiITSiURUREbEKhLCIiYhMKZREREZtQKIuIiNiEQllERMQmFMoiIiI2oVAWERGxCYWyiIiITSiURUREbEKhLCIiYhMKZREREZtQKIuIiNiEQllERMQmFMoiIiI2oVAWERGxCYWyiIiITSiURUREbEKhLCIiYhMKZREREZtQKIuIiNiEQllERMQmFMoiIiI2oVAWERGxCYWyiIiITSiURUREbEKhLCIiYhMKZREREZtQKIuIiNiEQllERMQmFMoiIiI2oVAWERGxCYWyiIiITSiURUREbEKhLCIiYhMKZREREZtQKIuIiNiEQllERMQmFMoiIiI2oVAWERGxCYWyiIiITSiURUREbEKhLCIiYhMKZREREZtQKIuIiNiEQllERMQmFMoiIiI2oVAWERGxCYWyiIiITSiURUREbEKhLCIiYhMKZREREZtQKIuIiNhEUELZsqwxlmUZy7JaBON6IiIiDdERh7JlWccBg4Cfjrw5IiIi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\n", 501 | "text/plain": [ 502 | "
" 503 | ] 504 | }, 505 | "metadata": { 506 | "tags": [], 507 | "needs_background": "light" 508 | } 509 | } 510 | ] 511 | }, 512 | { 513 | "cell_type": "code", 514 | "metadata": { 515 | "id": "rNiHJNispA6U" 516 | }, 517 | "source": [ 518 | "" 519 | ], 520 | "execution_count": 10, 521 | "outputs": [] 522 | } 523 | ] 524 | } --------------------------------------------------------------------------------