{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "**Important: This notebook will only work with fastai-0.7.x. Do not try to run any fastai-1.x code from this path in the repository because it will load fastai-0.7.x**" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%matplotlib inline\n", "%reload_ext autoreload\n", "%autoreload 2" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from fastai.conv_learner import *\n", "from fastai.dataset import *\n", "from fastai.models.resnet import vgg_resnet50\n", "\n", "import json" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "torch.cuda.set_device(2)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "torch.backends.cudnn.benchmark=True" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Data" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "PATH = Path('data/carvana')\n", "MASKS_FN = 'train_masks.csv'\n", "META_FN = 'metadata.csv'\n", "masks_csv = pd.read_csv(PATH/MASKS_FN)\n", "meta_csv = pd.read_csv(PATH/META_FN)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def show_img(im, figsize=None, ax=None, alpha=None):\n", " if not ax: fig,ax = plt.subplots(figsize=figsize)\n", " ax.imshow(im, alpha=alpha)\n", " ax.set_axis_off()\n", " return ax" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "TRAIN_DN = 'train-128'\n", "MASKS_DN = 'train_masks-128'\n", "sz = 128\n", "bs = 64\n", "nw = 16" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "TRAIN_DN = 'train'\n", "MASKS_DN = 'train_masks_png'\n", "sz = 128\n", "bs = 64\n", "nw = 16" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class MatchedFilesDataset(FilesDataset):\n", " def __init__(self, fnames, y, transform, path):\n", " self.y=y\n", " assert(len(fnames)==len(y))\n", " super().__init__(fnames, transform, path)\n", " def get_y(self, i): return open_image(os.path.join(self.path, self.y[i]))\n", " def get_c(self): return 0" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x_names = np.array([Path(TRAIN_DN)/o for o in masks_csv['img']])\n", "y_names = np.array([Path(MASKS_DN)/f'{o[:-4]}_mask.png' for o in masks_csv['img']])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "val_idxs = list(range(1008))\n", "((val_x,trn_x),(val_y,trn_y)) = split_by_idx(val_idxs, x_names, y_names)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "aug_tfms = [RandomRotate(4, tfm_y=TfmType.CLASS),\n", " RandomFlip(tfm_y=TfmType.CLASS),\n", " RandomLighting(0.05, 0.05, tfm_y=TfmType.CLASS)]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "tfms = tfms_from_model(resnet34, sz, crop_type=CropType.NO, tfm_y=TfmType.CLASS, aug_tfms=aug_tfms)\n", "datasets = ImageData.get_ds(MatchedFilesDataset, (trn_x,trn_y), (val_x,val_y), tfms, path=PATH)\n", "md = ImageData(PATH, datasets, bs, num_workers=16, classes=None)\n", "denorm = md.trn_ds.denorm" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x,y = next(iter(md.trn_dl))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(torch.Size([64, 3, 128, 128]), torch.Size([64, 128, 128]))" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "x.shape,y.shape" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Simple upsample" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "f = resnet34\n", "cut,lr_cut = model_meta[f]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def get_base():\n", " layers = cut_model(f(True), cut)\n", " return nn.Sequential(*layers)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def dice(pred, targs):\n", " pred = (pred>0).float()\n", " return 2. * (pred*targs).sum() / (pred+targs).sum()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class StdUpsample(nn.Module):\n", " def __init__(self, nin, nout):\n", " super().__init__()\n", " self.conv = nn.ConvTranspose2d(nin, nout, 2, stride=2)\n", " self.bn = nn.BatchNorm2d(nout)\n", " \n", " def forward(self, x): return self.bn(F.relu(self.conv(x)))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class Upsample34(nn.Module):\n", " def __init__(self, rn):\n", " super().__init__()\n", " self.rn = rn\n", " self.features = nn.Sequential(\n", " rn, nn.ReLU(),\n", " StdUpsample(512,256),\n", " StdUpsample(256,256),\n", " StdUpsample(256,256),\n", " StdUpsample(256,256),\n", " nn.ConvTranspose2d(256, 1, 2, stride=2))\n", " \n", " def forward(self,x): return self.features(x)[:,0]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class UpsampleModel():\n", " def __init__(self,model,name='upsample'):\n", " self.model,self.name = model,name\n", "\n", " def get_layer_groups(self, precompute):\n", " lgs = list(split_by_idxs(children(self.model.rn), [lr_cut]))\n", " return lgs + [children(self.model.features)[1:]]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m_base = get_base()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m = to_gpu(Upsample34(m_base))\n", "models = UpsampleModel(m)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn = ConvLearner(md, models)\n", "learn.opt_fn=optim.Adam\n", "learn.crit=nn.BCEWithLogitsLoss()\n", "learn.metrics=[accuracy_thresh(0.5),dice]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn.freeze_to(1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "e4667e9fa899453da7cbf0a0524fb426", "version_major": 2, "version_minor": 0 }, "text/html": [ "

Failed to display Jupyter Widget of type HBox.

\n", "

\n", " If you're reading this message in the Jupyter Notebook or JupyterLab Notebook, it may mean\n", " that the widgets JavaScript is still loading. If this message persists, it\n", " likely means that the widgets JavaScript library is either not installed or\n", " not enabled. See the Jupyter\n", " Widgets Documentation for setup instructions.\n", "

\n", "

\n", " If you're reading this message in another frontend (for example, a static\n", " rendering on GitHub or NBViewer),\n", " it may mean that your frontend doesn't currently support widgets.\n", "

\n" ], "text/plain": [ "HBox(children=(IntProgress(value=0, description='Epoch', max=1), HTML(value='')))" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ " 86%|█████████████████████████████████████████████████████████████ | 55/64 [00:22<00:03, 2.46it/s, loss=3.21]" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "learn.lr_find()\n", "learn.sched.plot()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "lr=4e-2\n", "wd=1e-7\n", "lrs = np.array([lr/100,lr/10,lr])/2" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "0dfb71a3eb494433bd0f58647124a177", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(IntProgress(value=0, description='Epoch', max=4), HTML(value='')))" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ " 0%| | 0/64 [00:00 dice \n", " 0 0.216882 0.133512 0.938017 0.855221 \n", " 1 0.169544 0.115158 0.946518 0.878381 \n", " 2 0.153114 0.099104 0.957748 0.903353 \n", " 3 0.144105 0.093337 0.964404 0.915084 \n", "\n" ] }, { "data": { "text/plain": [ "[0.09333742126112893, 0.9644036065964472, 0.9150839788573129]" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "learn.fit(lr,1, wds=wd, cycle_len=4,use_clr=(20,8))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn.save('tmp')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn.load('tmp')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn.unfreeze()\n", "learn.bn_freeze(True)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "f8176783850a4cf48c3ba20494fac24e", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(IntProgress(value=0, description='Epoch', max=4), HTML(value='')))" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "epoch trn_loss val_loss dice \n", " 0 0.174897 0.061603 0.976321 0.94382 \n", " 1 0.122911 0.053625 0.982206 0.957624 \n", " 2 0.106837 0.046653 0.985577 0.965792 \n", " 3 0.099075 0.042291 0.986519 0.968925 \n", "\n" ] }, { "data": { "text/plain": [ "[0.042291240323157536, 0.986519161670927, 0.9689251193924556]" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "learn.fit(lrs,1,cycle_len=4,use_clr=(20,8))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn.save('128')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x,y = next(iter(md.val_dl))\n", "py = to_np(learn.model(V(x)))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAQUAAAD8CAYAAAB+fLH0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAABA5JREFUeJzt3dtt02AAhuG06hSZIkugTMCUTFCxRKfoGISrSH0L6dGJf9vPc4ki4V709edD4O50Ou0Azu7nPgBgLKIAhCgAIQpAiAIQogCEKAAhCkCIAhAPcx/Abrfb/bj/6bVKuLLff37dfeRzlgIQogCEKAAhCkCIAhCiAIQoACEKQIgCEKIAhCgAIQpAiAIQogCEKAAhCkCIAhCiAIQoACEKQIgCEKIAhCgAIQpAiAIQogCEKAAhCkCIAhCiAIQoACEKQIgCEKIAhCgAIQpAiAIQogCEKAAhCkCIAhCiAIQoACEKQIgCEKIAhCgAIQpAiAIQogCEKAAhCkCIAhCiAIQoACEKQIgCEKIAhCgAIQpAiAIQogCEKAAhCkCIAhCiAIQoACEKQIgCEKIAhCgAIQpAiAIQogCEKAAhCkCIAhAPcx8Ay/b4/LQ77g///Nklrz/LeCwFICwFLnrrjP+Vz136rPUwFksBCEthgz5zZr8F62EsorAho8XgLS+PVSBuy+UDEKKwEUtaCcxLFIBwT2Hl1rAQzj+Dewu3YSkAYSms1BoWwmsWw21YCivz+Py0yiC8tPafb26iAIQosEhbWERzEQUgRIFFsximJwor4peDKYgCEKKwAia0lTQlUQBCFIDwmvOCmczlNehpWApAiMJCWQlciygAIQqsjke03yMKQIgCEB5JLoxZzLVZCkCIwsIc9wcv53BVogCEewoL454C12YpsFreV/gaUQDC5cNCOONxK5YCEKLA6llZnyMKQIgCEKKwAOYvtyQKQIgCEKIAhJeXBuZewnT88+8fZykAIQpAiAKb4puT7xMFIEQBCE8fBmTeMidLAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIDw3YeB+M4DI7AUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFNgkL4pdJgpAiAIQogCEKAAhCkCIAhCiAIQoACEKQIgCEKIAhCiwScf9Ye5DGJYoACEKQIgCEKIAhCgAIQpAiAIQojCQ4/7g+TmzEwUgRAEIUQDiYe4DgFtyz+Z9osAmiMHHuXwAQhSAEAUgRAEIUQDC04cBne+U++/Sv8cTh68RBVZDBKbh8gEIS2Fg/zvzvXVJ8d6Zci2XIxbBdVkKQFgKC/Odm5BTnmGnXB3O/GMRhYWa+xdp7r+f63H5AIQoACEKQIgCEKIAhCgAIQpAiAIQogCEKAAhCkCIAhCiAIQoACEKQIgCEKIAhCgAIQpAiAIQogCEKAAhCkCIAhCiAIQoACEKQIgCEKIAhCgAcXc6neY+BmAglgIQogCEKAAhCkCIAhCiAIQoACEKQIgCEKIAhCgAIQpAiAIQogCEKAAhCkCIAhCiAIQoACEKQIgCEKIAhCgA8RefEJKlJ3LAMQAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_img(py[0]>0);" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAQUAAAD8CAYAAAB+fLH0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAABA5JREFUeJzt3dFN22AARtFQMQVTsETFBJ2yE6AuwRSM0fQJNbdqCAE79m+f81hVyCDl+rOdwN3xeDwAvPm29AEA6yIKQIgCEKIAhCgAIQpAiAIQogCEKABxv/QBHA6Hw/dvP7ytEmb26/fPu4/8P0sBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAGI+6UPgHV5fn2Z9es/PTzO+vX5OksBCEthR+ZeAVMeg0WxHEsBCFFglZ5fX1axbPZIFHZi1BfYqMc9MlEAQhSAEAUgPJLcuC1ck799Dx5T3oalAIQoMAyPKW/D5cNGefHwWZYCEKIAhCgAIQobs4ebcVv//pYmCkCIAhCiwJD2cJm0FFEAQhQ2xJmTKYgCEKIAhM8+DMBlwXX+/Xn5yPV1LAUgLAWGdvoLWM4tqtN/txousxSAsBRW7NK9hLeznnsOTEkUBiYGf/lZTMflAxCWwoqd3hRzJuRWLAUgLIVB/O9RmvVQHjdOw1IYlCAwF1EAQhTYDL94ZRqiAIQbjYNxJrzMH6T9GksBCEthEBbC9SyGz7EU2DxBvY4oACEKA3Cm45ZEAQhRAMLThxVz2TAdTyI+zlIAQhSAEAUgRIFd8UnKy0QBCFEAQhSAEAUgvHlphdwIY0mWAhCiAIQosEsu0c4TBSBEAQhRAEIUgPA+hRVx84s1sBSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFFbk6eHx8PTwuPRhsHOiAIQoACEKQIgCu+TezXmiAIQoACEKK+TRJEsSBSBEAQhRAEIUgLhf+gA47/Rm4/Pry4JHsh1u4F5mKQBhKQzivTOcFfE+6+A6lgIQlsIGzH0mXOMScfafjyhwkRfgvrh8AEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAuDsej0sfA7AilgIQogCEKAAhCkCIAhCiAIQoACEKQIgCEKIAhCgAIQpAiAIQogCEKAAhCkCIAhCiAIQoACEKQIgCEKIAhCgA8QfWQY8SR/FLYgAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_img(y[0]);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## U-net (ish)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class SaveFeatures():\n", " features=None\n", " def __init__(self, m): self.hook = m.register_forward_hook(self.hook_fn)\n", " def hook_fn(self, module, input, output): self.features = output\n", " def remove(self): self.hook.remove()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class UnetBlock(nn.Module):\n", " def __init__(self, up_in, x_in, n_out):\n", " super().__init__()\n", " up_out = x_out = n_out//2\n", " self.x_conv = nn.Conv2d(x_in, x_out, 1)\n", " self.tr_conv = nn.ConvTranspose2d(up_in, up_out, 2, stride=2)\n", " self.bn = nn.BatchNorm2d(n_out)\n", " \n", " def forward(self, up_p, x_p):\n", " up_p = self.tr_conv(up_p)\n", " x_p = self.x_conv(x_p)\n", " cat_p = torch.cat([up_p,x_p], dim=1)\n", " return self.bn(F.relu(cat_p))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class Unet34(nn.Module):\n", " def __init__(self, rn):\n", " super().__init__()\n", " self.rn = rn\n", " self.sfs = [SaveFeatures(rn[i]) for i in [2,4,5,6]]\n", " self.up1 = UnetBlock(512,256,256)\n", " self.up2 = UnetBlock(256,128,256)\n", " self.up3 = UnetBlock(256,64,256)\n", " self.up4 = UnetBlock(256,64,256)\n", " self.up5 = nn.ConvTranspose2d(256, 1, 2, stride=2)\n", " \n", " def forward(self,x):\n", " x = F.relu(self.rn(x))\n", " x = self.up1(x, self.sfs[3].features)\n", " x = self.up2(x, self.sfs[2].features)\n", " x = self.up3(x, self.sfs[1].features)\n", " x = self.up4(x, self.sfs[0].features)\n", " x = self.up5(x)\n", " return x[:,0]\n", " \n", " def close(self):\n", " for sf in self.sfs: sf.remove()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class UnetModel():\n", " def __init__(self,model,name='unet'):\n", " self.model,self.name = model,name\n", "\n", " def get_layer_groups(self, precompute):\n", " lgs = list(split_by_idxs(children(self.model.rn), [lr_cut]))\n", " return lgs + [children(self.model)[1:]]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m_base = get_base()\n", "m = to_gpu(Unet34(m_base))\n", "models = UnetModel(m)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn = ConvLearner(md, models)\n", "learn.opt_fn=optim.Adam\n", "learn.crit=nn.BCEWithLogitsLoss()\n", "learn.metrics=[accuracy_thresh(0.5),dice]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "OrderedDict([('Conv2d-1',\n", " OrderedDict([('input_shape', [-1, 3, 128, 128]),\n", " ('output_shape', [-1, 64, 64, 64]),\n", " ('trainable', False),\n", " ('nb_params', 9408)])),\n", " ('BatchNorm2d-2',\n", " OrderedDict([('input_shape', [-1, 64, 64, 64]),\n", " ('output_shape', [-1, 64, 64, 64]),\n", " ('trainable', False),\n", " ('nb_params', 128)])),\n", " ('ReLU-3',\n", " OrderedDict([('input_shape', [-1, 64, 64, 64]),\n", " ('output_shape', [-1, 64, 64, 64]),\n", " ('nb_params', 0)])),\n", " ('MaxPool2d-4',\n", " OrderedDict([('input_shape', [-1, 64, 64, 64]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-5',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', 36864)])),\n", " ('BatchNorm2d-6',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', 128)])),\n", " ('ReLU-7',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-8',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', 36864)])),\n", " ('BatchNorm2d-9',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', 128)])),\n", " ('ReLU-10',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-11',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-12',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', 36864)])),\n", " ('BatchNorm2d-13',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', 128)])),\n", " ('ReLU-14',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-15',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', 36864)])),\n", " ('BatchNorm2d-16',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', 128)])),\n", " ('ReLU-17',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-18',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-19',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', 36864)])),\n", " ('BatchNorm2d-20',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', 128)])),\n", " ('ReLU-21',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-22',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', 36864)])),\n", " ('BatchNorm2d-23',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', 128)])),\n", " ('ReLU-24',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-25',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-26',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', 73728)])),\n", " ('BatchNorm2d-27',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', 256)])),\n", " ('ReLU-28',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-29',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', 147456)])),\n", " ('BatchNorm2d-30',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', 256)])),\n", " ('Conv2d-31',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', 8192)])),\n", " ('BatchNorm2d-32',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', 256)])),\n", " ('ReLU-33',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-34',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-35',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', 147456)])),\n", " ('BatchNorm2d-36',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', 256)])),\n", " ('ReLU-37',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-38',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', 147456)])),\n", " ('BatchNorm2d-39',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', 256)])),\n", " ('ReLU-40',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-41',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-42',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', 147456)])),\n", " ('BatchNorm2d-43',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', 256)])),\n", " ('ReLU-44',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-45',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', 147456)])),\n", " ('BatchNorm2d-46',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', 256)])),\n", " ('ReLU-47',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-48',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-49',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', 147456)])),\n", " ('BatchNorm2d-50',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', 256)])),\n", " ('ReLU-51',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-52',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', 147456)])),\n", " ('BatchNorm2d-53',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', 256)])),\n", " ('ReLU-54',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-55',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-56',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', 294912)])),\n", " ('BatchNorm2d-57',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', 512)])),\n", " ('ReLU-58',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-59',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', 589824)])),\n", " ('BatchNorm2d-60',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', 512)])),\n", " ('Conv2d-61',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', 32768)])),\n", " ('BatchNorm2d-62',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', 512)])),\n", " ('ReLU-63',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-64',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-65',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', 589824)])),\n", " ('BatchNorm2d-66',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', 512)])),\n", " ('ReLU-67',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-68',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', 589824)])),\n", " ('BatchNorm2d-69',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', 512)])),\n", " ('ReLU-70',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-71',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-72',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', 589824)])),\n", " ('BatchNorm2d-73',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', 512)])),\n", " ('ReLU-74',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-75',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', 589824)])),\n", " ('BatchNorm2d-76',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', 512)])),\n", " ('ReLU-77',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-78',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-79',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', 589824)])),\n", " ('BatchNorm2d-80',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', 512)])),\n", " ('ReLU-81',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-82',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', 589824)])),\n", " ('BatchNorm2d-83',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', 512)])),\n", " ('ReLU-84',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-85',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-86',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', 589824)])),\n", " ('BatchNorm2d-87',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', 512)])),\n", " ('ReLU-88',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-89',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', 589824)])),\n", " ('BatchNorm2d-90',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', 512)])),\n", " ('ReLU-91',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-92',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-93',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', 589824)])),\n", " ('BatchNorm2d-94',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', 512)])),\n", " ('ReLU-95',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-96',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', 589824)])),\n", " ('BatchNorm2d-97',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', 512)])),\n", " ('ReLU-98',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-99',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-100',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', 1179648)])),\n", " ('BatchNorm2d-101',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', 1024)])),\n", " ('ReLU-102',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-103',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', 2359296)])),\n", " ('BatchNorm2d-104',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', 1024)])),\n", " ('Conv2d-105',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', 131072)])),\n", " ('BatchNorm2d-106',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', 1024)])),\n", " ('ReLU-107',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-108',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-109',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', 2359296)])),\n", " ('BatchNorm2d-110',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', 1024)])),\n", " ('ReLU-111',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-112',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', 2359296)])),\n", " ('BatchNorm2d-113',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', 1024)])),\n", " ('ReLU-114',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-115',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-116',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', 2359296)])),\n", " ('BatchNorm2d-117',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', 1024)])),\n", " ('ReLU-118',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-119',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', 2359296)])),\n", " ('BatchNorm2d-120',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', 1024)])),\n", " ('ReLU-121',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-122',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('nb_params', 0)])),\n", " ('ConvTranspose2d-123',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 128, 8, 8]),\n", " ('trainable', True),\n", " ('nb_params', 262272)])),\n", " ('Conv2d-124',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 128, 8, 8]),\n", " ('trainable', True),\n", " ('nb_params', 32896)])),\n", " ('BatchNorm2d-125',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', True),\n", " ('nb_params', 512)])),\n", " ('UnetBlock-126',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('ConvTranspose2d-127',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', True),\n", " ('nb_params', 131200)])),\n", " ('Conv2d-128',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', True),\n", " ('nb_params', 16512)])),\n", " ('BatchNorm2d-129',\n", " OrderedDict([('input_shape', [-1, 256, 16, 16]),\n", " ('output_shape', [-1, 256, 16, 16]),\n", " ('trainable', True),\n", " ('nb_params', 512)])),\n", " ('UnetBlock-130',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('ConvTranspose2d-131',\n", " OrderedDict([('input_shape', [-1, 256, 16, 16]),\n", " ('output_shape', [-1, 128, 32, 32]),\n", " ('trainable', True),\n", " ('nb_params', 131200)])),\n", " ('Conv2d-132',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 128, 32, 32]),\n", " ('trainable', True),\n", " ('nb_params', 8320)])),\n", " ('BatchNorm2d-133',\n", " OrderedDict([('input_shape', [-1, 256, 32, 32]),\n", " ('output_shape', [-1, 256, 32, 32]),\n", " ('trainable', True),\n", " ('nb_params', 512)])),\n", " ('UnetBlock-134',\n", " OrderedDict([('input_shape', [-1, 256, 16, 16]),\n", " ('output_shape', [-1, 256, 32, 32]),\n", " ('nb_params', 0)])),\n", " ('ConvTranspose2d-135',\n", " OrderedDict([('input_shape', [-1, 256, 32, 32]),\n", " ('output_shape', [-1, 128, 64, 64]),\n", " ('trainable', True),\n", " ('nb_params', 131200)])),\n", " ('Conv2d-136',\n", " OrderedDict([('input_shape', [-1, 64, 64, 64]),\n", " ('output_shape', [-1, 128, 64, 64]),\n", " ('trainable', True),\n", " ('nb_params', 8320)])),\n", " ('BatchNorm2d-137',\n", " OrderedDict([('input_shape', [-1, 256, 64, 64]),\n", " ('output_shape', [-1, 256, 64, 64]),\n", " ('trainable', True),\n", " ('nb_params', 512)])),\n", " ('UnetBlock-138',\n", " OrderedDict([('input_shape', [-1, 256, 32, 32]),\n", " ('output_shape', [-1, 256, 64, 64]),\n", " ('nb_params', 0)])),\n", " ('ConvTranspose2d-139',\n", " OrderedDict([('input_shape', [-1, 256, 64, 64]),\n", " ('output_shape', [-1, 1, 128, 128]),\n", " ('trainable', True),\n", " ('nb_params', 1025)]))])" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "learn.summary()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[torch.Size([3, 64, 64, 64]),\n", " torch.Size([3, 64, 32, 32]),\n", " torch.Size([3, 128, 16, 16]),\n", " torch.Size([3, 256, 8, 8])]" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "[o.features.size() for o in m.sfs]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn.freeze_to(1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "a2661ed6f2c049098c0b37f13ac2e03e", "version_major": 2, "version_minor": 0 }, "text/html": [ "

Failed to display Jupyter Widget of type HBox.

\n", "

\n", " If you're reading this message in the Jupyter Notebook or JupyterLab Notebook, it may mean\n", " that the widgets JavaScript is still loading. If this message persists, it\n", " likely means that the widgets JavaScript library is either not installed or\n", " not enabled. See the Jupyter\n", " Widgets Documentation for setup instructions.\n", "

\n", "

\n", " If you're reading this message in another frontend (for example, a static\n", " rendering on GitHub or NBViewer),\n", " it may mean that your frontend doesn't currently support widgets.\n", "

\n" ], "text/plain": [ "HBox(children=(IntProgress(value=0, description='Epoch', max=1), HTML(value='')))" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ " 0%| | 0/64 [00:00" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "learn.lr_find()\n", "learn.sched.plot()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "lr=4e-2\n", "wd=1e-7\n", "\n", "lrs = np.array([lr/100,lr/10,lr])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "dce9710ec3314546b8d1dfc8e1d250f6", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(IntProgress(value=0, description='Epoch', max=8), HTML(value='')))" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "epoch trn_loss val_loss dice \n", " 0 0.12936 0.03934 0.988571 0.971385 \n", " 1 0.098401 0.039252 0.990438 0.974921 \n", " 2 0.087789 0.02539 0.990961 0.978927 \n", " 3 0.082625 0.027984 0.988483 0.975948 \n", " 4 0.079509 0.025003 0.99171 0.981221 \n", " 5 0.076984 0.022514 0.992462 0.981881 \n", " 6 0.076822 0.023203 0.992484 0.982321 \n", " 7 0.075488 0.021956 0.992327 0.982704 \n", "\n" ] }, { "data": { "text/plain": [ "[0.021955982234979434, 0.9923273126284281, 0.9827044502137199]" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "learn.fit(lr,1,wds=wd,cycle_len=8,use_clr=(5,8))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn.save('128urn-tmp')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn.load('128urn-tmp')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn.unfreeze()\n", "learn.bn_freeze(True)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "86aa94831fa840b7ae471989af971594", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(IntProgress(value=0, description='Epoch', max=20), HTML(value='')))" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ " 0%| | 0/64 [00:00 dice \n", " 0 0.073786 0.023418 0.99297 0.98283 \n", " 1 0.073561 0.020853 0.992142 0.982725 \n", " 2 0.075227 0.023357 0.991076 0.980879 \n", " 3 0.074245 0.02352 0.993108 0.983659 \n", " 4 0.073434 0.021508 0.993024 0.983609 \n", " 5 0.073092 0.020956 0.993188 0.983333 \n", " 6 0.073617 0.019666 0.993035 0.984102 \n", " 7 0.072786 0.019844 0.993196 0.98435 \n", " 8 0.072256 0.018479 0.993282 0.984277 \n", " 9 0.072052 0.019479 0.993164 0.984147 \n", " 10 0.071361 0.019402 0.993344 0.984541 \n", " 11 0.070969 0.018904 0.993139 0.984499 \n", " 12 0.071588 0.018027 0.9935 0.984543 \n", " 13 0.070709 0.018345 0.993491 0.98489 \n", " 14 0.072238 0.019096 0.993594 0.984825 \n", " 15 0.071407 0.018967 0.993446 0.984919 \n", " 16 0.071047 0.01966 0.993366 0.984952 \n", " 17 0.072024 0.018133 0.993505 0.98497 \n", " 18 0.071517 0.018464 0.993602 0.985192 \n", " 19 0.070109 0.018337 0.993614 0.9852 \n", "\n" ] }, { "data": { "text/plain": [ "[0.018336569653853538, 0.9936137114252362, 0.9852004420189631]" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "learn.fit(lrs/4, 1, wds=wd, cycle_len=20,use_clr=(20,10))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn.save('128urn-0')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn.load('128urn-0')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x,y = next(iter(md.val_dl))\n", "py = to_np(learn.model(V(x)))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAQUAAAD8CAYAAAB+fLH0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAABA5JREFUeJzt3dFN21AAhtFQMQVTsETFBJ2yE6AuwRSM0fQpEl9VwNBg32uf8wZCwqDw+Xewkpvz+XwCuPi29QEAYxEFIEQBCFEAQhSAEAUgRAEIUQBCFIC43foATqfT6fu3H26rhC/26/fPmyVfZykAIQpAiAIQogCEKAAhCkCIAhCiAIQoACEKQIgCEKIAhCgAIQpAiAIQogCEKAAhCkCIAhCiAIQoACEKQIgCEKIAhCgAIQpAiAIQogCEKAAhCkCIAhCiAIQoACEKQIgCEKIAhCgAIQpAiAIQogCEKAAhCkCIAhCiAIQoACEKQIgCEKIAhCgAIQpAiAIQogCEKAAhCkCIAhCiAIQoACEKQIgCEKIAhCgAIQpAiAIQogCEKAAhCkCIAhCiAIQoACEKQIgCEKIAhCgAIQpAiAIQogCEKABxu/UBMJbH56fVvtfD3f1q34vlLAUgLIUDWnMNvOWt47AitmMpAGEpHMgoC2GJl8dqNazLUjiImYLAtkQBCJcPO7eHhXD5GVxGrMNSAEIUmMbj89Muls/oRAEIUQBCFHZqz1N7rz/XKEQBCFFgSnteQlsTBSDcvLQzzp78L0sBCFEAQhSYmiccr08UgBAFdsFauB5R2JGj/2G4lLgOUQDCfQoTeO3sd3nREWfH+tfvwwu0LGcpAGEpTMxC4CtYCkBYCgOzBNiCpTCwh7t7T5CxOlEAQhQmYC2wJlEAQhQm43mGj/P7+hj/fZiEBzZrsRSAsBTYLevqcywFICyFybjLcTlvYf85lgIQlsIkLATWYimwe4L6MaIAhCgAIQpAiMIEXBOzJlHgELwnxHKiAIT7FAbmzHZ97nJ8n6UAhCgAIQpAiAIQogCEKAAhCkCIAhCiwCG5Mex17mgckAcsW7IUgBAFIEQBCFEAQhSAEAUgRAEIUQDCzUsDcdMSI7AUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQhYE83N1741M2JwpAiAIQogCEKAAhCkCIAhCiAIQoACEKQIgCEKIAhCgAIQpAiAIQogCEKAAhCkCIAhCiwCF52bvXicKAvFYjWxIFIEQBCFEAQhSAEAUgbrc+AFiT/+q8TxQG9vIB/Pj8lM9dPmYZMVjO5QMQlsIk/j7TvXbmO/KCsAauw1IAwlLYmbfOlrOuCAtgXaJwIP64WMLlAxCiAIQoACEKQIgCEKIAhCgAIQpAiAIQogCEKAAhCkCIAhCiAIQoACEKQIgCEKIAhCgAIQpAiAIQogCEKAAhCkCIAhCiAIQoACEKQIgCEKIAxM35fN76GICBWApAiAIQogCEKAAhCkCIAhCiAIQoACEKQIgCEKIAhCgAIQpAiAIQogCEKAAhCkCIAhCiAIQoACEKQIgCEKIAxB8Zg4ZPO/0D6QAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_img(py[0]>0);" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAQUAAAD8CAYAAAB+fLH0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAABA5JREFUeJzt3dFN22AARtFQMQVTsETFBJ2yE6AuwRSM0fQJNbdqCAE79m+f81hVyCDl+rOdwN3xeDwAvPm29AEA6yIKQIgCEKIAhCgAIQpAiAIQogCEKABxv/QBHA6Hw/dvP7ytEmb26/fPu4/8P0sBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAGI+6UPgHV5fn2Z9es/PTzO+vX5OksBCEthR+ZeAVMeg0WxHEsBCFFglZ5fX1axbPZIFHZi1BfYqMc9MlEAQhSAEAUgPJLcuC1ck799Dx5T3oalAIQoMAyPKW/D5cNGefHwWZYCEKIAhCgAIQobs4ebcVv//pYmCkCIAhCiwJD2cJm0FFEAQhQ2xJmTKYgCEKIAhM8+DMBlwXX+/Xn5yPV1LAUgLAWGdvoLWM4tqtN/txousxSAsBRW7NK9hLeznnsOTEkUBiYGf/lZTMflAxCWwoqd3hRzJuRWLAUgLIVB/O9RmvVQHjdOw1IYlCAwF1EAQhTYDL94ZRqiAIQbjYNxJrzMH6T9GksBCEthEBbC9SyGz7EU2DxBvY4oACEKA3Cm45ZEAQhRAMLThxVz2TAdTyI+zlIAQhSAEAUgRIFd8UnKy0QBCFEAQhSAEAUgvHlphdwIY0mWAhCiAIQosEsu0c4TBSBEAQhRAEIUgPA+hRVx84s1sBSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFFbk6eHx8PTwuPRhsHOiAIQoACEKQIgCu+TezXmiAIQoACEKK+TRJEsSBSBEAQhRAEIUgLhf+gA47/Rm4/Pry4JHsh1u4F5mKQBhKQzivTOcFfE+6+A6lgIQlsIGzH0mXOMScfafjyhwkRfgvrh8AEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAuDsej0sfA7AilgIQogCEKAAhCkCIAhCiAIQoACEKQIgCEKIAhCgAIQpAiAIQogCEKAAhCkCIAhCiAIQoACEKQIgCEKIAhCgA8QfWQY8SR/FLYgAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_img(y[0]);" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m.close()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 512x512" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sz=512\n", "bs=16" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "tfms = tfms_from_model(resnet34, sz, crop_type=CropType.NO, tfm_y=TfmType.CLASS, aug_tfms=aug_tfms)\n", "datasets = ImageData.get_ds(MatchedFilesDataset, (trn_x,trn_y), (val_x,val_y), tfms, path=PATH)\n", "md = ImageData(PATH, datasets, bs, num_workers=4, classes=None)\n", "denorm = md.trn_ds.denorm" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m_base = get_base()\n", "m = to_gpu(Unet34(m_base))\n", "models = UnetModel(m)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn = ConvLearner(md, models)\n", "learn.opt_fn=optim.Adam\n", "learn.crit=nn.BCEWithLogitsLoss()\n", "learn.metrics=[accuracy_thresh(0.5),dice]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn.freeze_to(1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn.load('128urn-0')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "2cd9f452b7dc40b58895f0ca5b876936", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(IntProgress(value=0, description='Epoch', max=5), HTML(value='')))" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "epoch trn_loss val_loss dice \n", " 0 0.071421 0.02362 0.996459 0.991772 \n", " 1 0.070373 0.014013 0.996558 0.992602 \n", " 2 0.067895 0.011482 0.996705 0.992883 \n", " 3 0.070653 0.014256 0.996695 0.992771 \n", " 4 0.068621 0.013195 0.996993 0.993359 \n", "\n" ] }, { "data": { "text/plain": [ "[0.013194938530288046, 0.996993034604996, 0.993358936574724]" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "learn.fit(lr,1,wds=wd, cycle_len=5,use_clr=(5,5))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn.save('512urn-tmp')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn.unfreeze()\n", "learn.bn_freeze(True)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn.load('512urn-tmp')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "8768382fe1fe4b8e94e6647899e20575", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(IntProgress(value=0, description='Epoch', max=8), HTML(value='')))" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "epoch trn_loss val_loss dice \n", " 0 0.06605 0.013602 0.997 0.993014 \n", " 1 0.066885 0.011252 0.997248 0.993563 \n", " 2 0.065796 0.009802 0.997223 0.993817 \n", " 3 0.065089 0.009668 0.997296 0.993744 \n", " 4 0.064552 0.011683 0.997269 0.993835 \n", " 5 0.065089 0.010553 0.997415 0.993827 \n", " 6 0.064303 0.009472 0.997431 0.994046 \n", " 7 0.062506 0.009623 0.997441 0.994118 \n", "\n" ] }, { "data": { "text/plain": [ "[0.009623114736602894, 0.9974409020136273, 0.9941179137381296]" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "learn.fit(lrs/4,1,wds=wd, cycle_len=8,use_clr=(20,8))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn.save('512urn')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn.load('512urn')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x,y = next(iter(md.val_dl))\n", "py = to_np(learn.model(V(x)))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAQYAAAD8CAYAAACVSwr3AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAABIxJREFUeJzt3NFt40YUQFF64SpUhZsIXEGqTAVCmnAVLiPKR7CA4LsbS7IsDofn/BkwoCFB3nmmJT2dTqcF4NyPtRcAjEcYgBAGIIQBCGEAQhiAEAYghAEIYQDiee0FLMuy/PHjT2+/hG/29z9/PV36uyYGIIQBCGEAQhiAEAYghAEIYQBCGIAQBiCEAQhhAEIYgBAGIIQBCGEAQhiAEAYghAEIYQBCGIAQBiCEAQhhAEIYgBAGIIQBCGEAQhiAEAYghAEIYQBCGIAQBiCEAQhhAEIYgBAGIIQBCGEAQhiAEAYghAEIYQBCGIAQBiCEAQhhAEIYgBAGIIQBCGEAQhiAEAYghAEIYQBCGIAQBiCEAQhhAEIYgBAGIIQBCGEAQhiAEAYghAEIYQBCGIAQBiCEAQhhAEIYgBAGIIQBCGEAQhiAEAYgntdeAOs5vr8tr4eX5fj+9rDXfD28POy1uJ0w7NB5CB4Zhc9eTzTGIQw78ugIXOvn+gRifZ4x7MToUTi3pbXOShgYkjisSxh2YKs32VbXPQNhmJybi1sIAxDCMLEZpoUZjmGLhIHhicPjCQMQwjCp2XbZ2Y5ndMIAhDBMyO7KVwkDmyF4jyMMQAjDZGbfVWc/vlEIAxDCMJG97KZ7Oc41CQMQwjAJuyj3JAxACMME9jgt7PGYH8mXwW7Ax5vAl6Xy3UwMg/vVznh8f7NjLr+fGpyfrzMxDMzFfZ2P5+v8Z1PWdUwMQAgDu2D6uo4wbJi/pd3w38UzBjZPHO7PxDAwD8xYi4lhcOdxsDPeTmSvIwwbIhKXez28LMf3N0G4kTAwjY8REIXbecawQaYFvpswbIwo/J5zcz/CwFTE4T6EYUNc9DyKMDAdAf06YdgIFzuPJAwbIArX8zmSrxEGpiYOtxGGwbmwWYMwDEwUWIswMD2BvZ4wACEMQAjDoIy/9+V8XkcYgBAGIIQBCGFgNzxnuJwwACEMA7KzsTZhYFdE9zLCAIQwDMaOxgiEAQhhAEIYgBAGdsdznM8JAxDCAIQwACEMQAgDEMIAhDAAIQxACAMQwgCEMAAhDAPxHn5GIQxACAMQwjCQ18PL2kuAZVmEAfgFYQBCGIAQBiCEAQhhAEIYgBAGIIQBCGEAQhiAEAYghAEIYRiIL2phFMIwEB+7ZhTCMBATA6MQhoGYGBiFMAAhDEAIA7vjT7bPCQMQwjAYuxkjEAYghIFdMZFdRhiAEIYB2dVYmzAAIQyDMjWwJmEYmDjcl/N5uee1F8D/O7+YffrydqJwHWHYkEsubvH4jxB8jTBM5rMbYqZwuPm/jzDszKg3089gvR5eluP727Dr3AthYAjnIRCF9fmvBBDCAIQwACEMQAgDEMIAhDAAIQxACAMQwgCEMAAhDEAIAxDCAIQwACEMQAgDEMIAhDAAIQxACAMQwgCEMAAhDEAIAxDCAIQwACEMQAgDEMIAxNPpdFp7DcBgTAxACAMQwgCEMAAhDEAIAxDCAIQwACEMQAgDEMIAhDAAIQxACAMQwgCEMAAhDEAIAxDCAIQwACEMQAgDEMIAxL+fjtP4pEiy4gAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_img(py[0]>0);" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAQYAAAD8CAYAAACVSwr3AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAABF9JREFUeJzt3NFtG0cUQFHJUBWuwk0EriBVpgIhTagKlRHmIwgi+MYSSe16Z2bP+TNgyMPBzp1HyuDj5XJ5AHjry9ELAMYjDEAIAxDCAIQwACEMQAgDEMIAhDAA8XT0Ah4eHh5++/K7/34JO/vzrz8er/27JgYghAEIYQBCGIAQBiCEAQhhAEIYgBAGIIQBCGEAQhiAEAYghAEIYQBCGIAQBiCEAQhhAEIYgBAGIIQBCGEAQhiAEAYghAEIYQBCGIAQBiCEAQhhAEIYgBAGIIQBCGEAQhiAEAYghAEIYQBCGIAQBiCEAQhhAEIYgBAGIIQBCGEAQhiAEAYghAEIYQBCGIAQBiCEAQhhAEIYgBAGIIQBCGEAQhiAEAYghAEIYQBCGIAQBiCEAQhhAEIYgBAGIIQBCGEAQhiAEAYghAEIYQBCGIAQBiCejl4A43h+fdntZ3//+m23n832hOFk9jz8W/y7AjIGbyVO5Kgo3OL59WWKda5OGE7CYeMWwsCQhOxYwnACsx6yWde9AmEAQhgWN/utO/v6ZyUMC3OouJcwMDyB+/WEAQhhWNRqt+xqr2d0wgCEMCxo1dt11dc1ImEAQhgWs/qtuvrrG4UwACEMTMfUsD9hWIgDw1aEAQhhWIRpgS0JA1MSwn0JwwIcErbmW6IH97ND79uU/9kb+7APE8PA3psETAn/799vmbY/n2NiYBk/xuDHP5surmdimNzZb8azv/69CAMQwsD0TA3bE4aJORD/sRfbEoaB+bCMo/itxODexsGteD+RvY0wTEQkbiMG9xMGliEE2/EZw4RMC+xNGIAQhsmYFn7O3mxHGFiKOGxDGCbiob+Offo8YZiEh/029utzhGECHvL72Lf7CQNLE4f7CMPgPNgcQRiAEIaBmRa2YR9vJwxACAOnYGq4jTAMyoPMkYQBCGHgNExh1xMGIIRhQG42jiYMQAgDp2Iau44wACEMg3GjMQJh4HTE92PCAIQwACEMQAgDEMIAhDAAIQwD8Ws0RiEMQAgDp2Q6e58wACEMQAgDEMIAhDAAIQxACAMQwgCEMAAhDEAIAxDCAIQwACEMQAgDEMIAhDAAIQxACAMQwgCEMAAhDEAIA6f0/eu3o5cwNGEAQhiAEAYghGEg3vcyCmEAQhiAEAYghAEIYRiMDyD3Z48/JgxACAMQwgCEMAzIe+D92NvrCAMQwjAoNxtHEoaBicO27Of1no5eAO97+zA/v74cuJK5icJthGEi7z3colFicD9hWMQth2DViAjBdoThhBwgPuLDRyCEAQhhAEIYgBAGIIQBCGEAQhiAEAYghAEIYQBCGIAQBiCEAQhhAEIYgBAGIIQBCGEAQhiAEAYghAEIYQBCGIAQBiCEAQhhAEIYgBAGIIQBCGEA4vFyuRy9BmAwJgYghAEIYQBCGIAQBiCEAQhhAEIYgBAGIIQBCGEAQhiAEAYghAEIYQBCGIAQBiCEAQhhAEIYgBAGIIQBCGEA4m/jpL5hSyL6CwAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_img(y[0]);" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m.close()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1024x1024" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sz=1024\n", "bs=4" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "tfms = tfms_from_model(resnet34, sz, crop_type=CropType.NO, tfm_y=TfmType.CLASS)\n", "datasets = ImageData.get_ds(MatchedFilesDataset, (trn_x,trn_y), (val_x,val_y), tfms, path=PATH)\n", "md = ImageData(PATH, datasets, bs, num_workers=16, classes=None)\n", "denorm = md.trn_ds.denorm" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m_base = get_base()\n", "m = to_gpu(Unet34(m_base))\n", "models = UnetModel(m)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn = ConvLearner(md, models)\n", "learn.opt_fn=optim.Adam\n", "learn.crit=nn.BCEWithLogitsLoss()\n", "learn.metrics=[accuracy_thresh(0.5),dice]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn.load('512urn')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn.freeze_to(1)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "a864769b63b7438fa112cf68e2835a0e", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(IntProgress(value=0, description='Epoch', max=2), HTML(value='')))" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "epoch trn_loss val_loss dice \n", " 0 0.007656 0.008155 0.997247 0.99353 \n", " 1 0.004706 0.00509 0.998039 0.995437 \n", "\n" ] }, { "data": { "text/plain": [ "[0.005090427414942828, 0.9980387706605215, 0.995437301104031]" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "learn.fit(lr,1, wds=wd, cycle_len=2,use_clr=(5,4))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn.save('1024urn-tmp')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn.load('1024urn-tmp')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn.unfreeze()\n", "learn.bn_freeze(True)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "lrs = np.array([lr/200,lr/30,lr])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(IntProgress(value=0, description='Epoch', max=4), HTML(value='')))" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "epoch trn_loss val_loss dice \n", " 0 0.005688 0.006135 0.997616 0.994616 \n", " 1 0.004412 0.005223 0.997983 0.995349 \n", " 2 0.004186 0.004975 0.99806 0.99554 \n", " 3 0.004016 0.004899 0.99812 0.995627 \n", "\n" ] }, { "data": { "text/plain": [ "[0.004898778487196458, 0.9981196409180051, 0.9956271404784823]" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "learn.fit(lrs/10,1, wds=wd,cycle_len=4,use_clr=(20,8))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "6ba1a0b69230449da669623edfd3f6c1", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(IntProgress(value=0, description='Epoch', max=4), HTML(value='')))" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "epoch trn_loss val_loss dice \n", " 0 0.004169 0.004962 0.998049 0.995517 \n", " 1 0.004022 0.004595 0.99823 0.995818 \n", " 2 0.003772 0.004497 0.998215 0.995916 \n", " 3 0.003618 0.004435 0.998291 0.995991 \n", "\n" ] }, { "data": { "text/plain": [ "[0.004434524739663753, 0.9982911745707194, 0.9959913929776539]" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "learn.fit(lrs/10,1, wds=wd,cycle_len=4,use_clr=(20,8))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYoAAAD8CAYAAABpcuN4AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAIABJREFUeJztnXl8FOX9xz/fPbJJOCUEBAKE+74UEbwFDxAq1nqg1Z9WW63V2tZahXrUixa1VVurba1irTfVahEUL0TBg0vlBgmXcoebBHLs7vP7Y+aZfWZ2ZnZ2s5tNst/364XOzjwz8+wkeb7zvUkIAYZhGIZxwpftCTAMwzANGxYUDMMwjCssKBiGYRhXWFAwDMMwrrCgYBiGYVxhQcEwDMO4woKCYRiGcYUFBcMwDOMKCwqGYRjGlUC2J5AO2rZtK0pLS7M9DYZhmEbF0qVL9wghihONaxKCorS0FEuWLMn2NBiGYRoVRLTFyzg2PTEMwzCusKBgGIZhXGFBwTAMw7jCgoJhGIZxhQUFwzAM4woLCoZhGMYVFhQMwzCMKywoPPDxN+VYvvVAtqfBMAyTFZpEwl2muWr6IgDA5mnjszwThmGY+oc1ikbEjoNH8X/TF+FQVW22p8IwTA7BgiIJIlGR1fv/5cP1+OSbcsz8entW58EwTG7BgiIJaiPRrN5/057KrN6fYZjcJKcFRdnuCqzdecjz+GxrFF9s3JfV+zMMk5vktKCYOns1bnttuefx4Uh2BYUknGXNhmGY3CKnBYWPCFHhffGvjTaMBXrq22uyPQWGYXKInBYUREAya//zn3sq3Z5xahuIZsMwTG6Q44KCkMyS++cP12Phxr0Zm08ihnZuDQC46cyeWZsDwzC5R04LCh8BIgnTEwDsPFSVodkkpm3zEAAg4KeszYFhmNwjxwVFcj4KANhbUZOh2STGp8uHbIfpMgyTW7CgSNLcf9+s1ZmZTBI4RV+t3HYQG8or6nk2DMM0dXK61hMRktYosomcaY2DRjHh8QUAuCYVwzDpJec1imTlxKXDO2dmMknApieGYeqTnBYUXjWKoOI89mXxicmpNpTEP4ZhcoOcFhReNQq/LyYosl3GA3A2PTEMw2QC9lF4kBTqkIawRv/3y20gEG4f2wftWuZnezoMwzRxWKPwoCCoQ8JZLeMRm8nrX27FKQ9+lMW5MAyTK+S4oPCqUcTG1IQbgEqhwyYohmHqgxwXFN4S7tQh2RQU1qm2axHKzkQYhskpclpQkMeEO3VIQ3qLL6+oxo+fW4yt+48g2gCc7AzDNE1y3pntpdaTOqY6zRrFoapaDL7nPdw/cQCuHFWa1LlCAB+s2Y38oB+DOrVK67wYhmEkOa1RaEUBE48zaRRpFhS79SKDz3koYe401XBE4OvvDqRxVgzDMDFyWqNIxUeR/qzouleCDUejWL3de0tXhmGYZPCkURDRWCJaR0RlRDTZ5niIiF7Vjy8kolLl2BR9/zoiOtdynp+IviKiWTbXfJyIMlrhLpWigJlyZidrAlOpjQhsP1iVcBzDMEwqJBQUROQH8ASAcQD6A7iMiPpbhl0LYL8QoieARwE8qJ/bH8AkAAMAjAXwpH49yS8AxPX1JKLhAFon/W2SxEvCnXXRXb+7AkIIPDhnLe6ZucrTfbbsrUTp5NlYumW/3R2U/6ZGOBrF4JKYj6KqtuE43BmGafx40ShGACgTQmwUQtQAeAXARMuYiQCe07dfAzCGiEjf/4oQoloIsQlAmX49EFEJgPEAnlYvpAuShwHcltpX8o6XhDt5/Jdn9TL2fbfvKP42bwP+9dlmT/eZu3Y3AOClhd/GHQtLlaYOkqI2IpDnj/0oD1fVpn4xhmEYC14ERScA3ymft+r7bMcIIcIADgIoSnDuY9CEgfX19yYAM4UQOzzMrU54SbiTR0nxJdQmmZ1dURUGoGVTW0mmwJ86slPrAmN7z+Fq1Co2tD1ZbK7EMEzTw4ugsPO2Wlc3pzG2+4loAoDdQoilposQdQRwMYDHE06K6DoiWkJES8rLyxMNd7qGZ9MTEYy39l/PWJbUff70/jeOx6RGsXFPJQ4c8b7Aq/Pu17ElwoqT/UhNOKn5MQzDuOFFUGwFoDZhKAGw3WkMEQUAtAKwz+XckwGcT0SboZmyRhPRCwCGAegJoEw/VkhEZXaTEkI8JYQYLoQYXlxc7OFrxEMewmNjGgUwtIvmNvl235GU7meHusD//u04dw2+2XXYGKPO1UcxGTx7+Q5sO3A0dk1OvmMYJo14ERSLAfQiom5ElAfNOT3TMmYmgKv07YsAzBXaq/hMAJP0qKhuAHoBWCSEmCKEKBFClOrXmyuEuEIIMVsIcawQolQ/dkR3kGeEZHwUPh8hFNAe177K5Ew7EwZ3cDymOp7X7zYHeT05rwznPPoJpr2zNuE9DhyJ+SW4XwXDMOkkoaDQfQ43AXgXWoTSDCHEKiK6j4jO14c9A6BIf/u/BcBk/dxVAGYAWA1gDoAbhRCR9H+N1PDio1CPS0GRLGq0k9UstGr7QWP7q2/NSXMPzVkHAHh6waa4a5JL+sUhdmYzDJNGPK18Qoi3hRC9hRA9hBBT9X13CyFm6ttVQoiLhRA9hRAjhBAblXOn6uf1EUK8Y3PteUKICQ73bZ7a1/KGW8LdH95Zg9LJs43PREBeAkHx7KebsHTLPhw8al6odyg5Dos3m0Nk/+BBW5B41RN+9uKXnq/JMAyTiJzOzHYrCviPjzVZJ+UIgUwhqFZqwlHc+9ZqAJrT+5up4/Dlt/sxtMScDuJWvK9zmwLT52FdWsdpGRKfjUqhaUiOl2cYhkmJnK/1BLhnMstQWCJg4jBrVHBs4a8OxyxqNZEopi/YhAuf/AzTPzWbjVoVBh3v1TwUO1YdjhhhtZcO7xw3T7sigPlBf9w+hmGYupLTgkLmRri9hdfqJTsIwMhuRXHHZdnx5VsPmvbfN0vTLsp2e69CogqbPnfOMZzbqnlsWJfWWPfAWPQ5tkXc+UdqGoz7h2GYJkROCwpPGkUklkcR9Mebe2TZ8R8+vdD2/I17KtGlTSHat9SaDNVaakV1LSqMXcuh9Ia1EGEo4IffV/diggzDMF7IbUHhs9coHlES5OQiTSDbxTlRkUAfAZGoQIFuFrI2Pup8jCIoFI1CFUq1EYGt+49g/vo9cceLmuWZrlfcIoSz+rV3nRPDMEwy5LSgkP5ga+TTXz5cb2wbgoI057fVoZ2o413rgjyEo1EU5AVM15NELKU31u86jEhUGJqMvMcNL2iRTBvLKwHEnNnFSjvUnu2aI+AjfLBmF1eQZRgmbeS2oNB9FG5raq0lec1qfkqkUQwvPUbXKHy246NCYGCnlsbnsx/9BF9s3GuZQ9TIv5AC4I2vtgEA1u48bIzzUSwU98l5G1znxTAM45WcFhT/WarVK1y946DjGLmwk/4GH7BqFAkExQOz1yAcFSjIk6Yns+ARAmgRMkdCrdlhbkJUE47GSok4zAMAjtbGTFdS82AYhqkrOS0o5GKqvpVbkYuv1COsyXQ14Siqat2jjSIRgYJgwBhvOiYEfJafwgOzzTWfaiNRI9tOmsvsssTVoraJ5sQwDOOVnBYUkpXbnNuIVuomH6eSGTWRCKb8d4Xr9VWNQvVRrNh6EEu37EdFdcQ163vx5v3YuEcTanIadoJC9UtsP3jU9nj6W7kyDNPUYUEB4OVF8Q2FJLLeklVO9Oug+RWqw1F8tmEP3IhEBQr1qCe1oOBjH2jRVcu+O4B8j3WkpCgIBWLJdY9dOhQA8PsLBxn77DK6//zhevS6452MtXNlGKZpwoIiAdJf4LOExm7Xy3rXhKPYdaja9Rpa1JO2sD/87jpjv3pNO5+DHRHdxyGvBwAXDOuEzdPG44w+7bDy3lhb8rBFe3hO78h34Cg3NmIYxjssKDxi1Sikr8LL23lUmBd2SUARFF4T6CK6eemu8f1sjzcPxcp3Ldt6EPPXx5o6yZBaayQXwzCMGzldFDApHJwUifIoJAU2dZhU4eB3qxuuIJsSFbcIYcLgDph0QhfHsT/422cAgM3TxgOIfQU2PTEMkww5rVH89ry+AMxv9k44jfC66AYV09JrS7Xe2f4UNAo1XPevlx+HU3q1TXjOUaMGlNQoWFAwDOOdnBYUl5/YFQDwizG9Eo51jHryKChUF8St/1mm74td1BoiCwDXntINU8b19XR9N2SoLGsUDMOkQk4LCqlJ+C3Z1mpZjNF92wGIZXE/c9VwAMB9Ewdo/9erxCbi1cXfOd4fsM8OP6NPsW2V2GSRhQvl7byayxiGYYAcFxTSuWttJlTcPISz+rVDp9YFcW/jY/q1x6I7xuACvTeF19LeG2wypfdWxKKP+toIhOFd25hMVl75zbl9TJ9lsUEp7FijYBgmGXJaUEjTj/UFW0DzAYSCPuNtXNU52rXINxUHPHdA4mqt5/SPjZHJdf07xmo8PTZpGO44LxbJdOXIrijI87v2xnZiiKWrnlWjYB8FwzDJkNOCQi6cEWGtvyTgIyDo82G/niBnXbBVQRGJ2msEKucP7Whsd2iVD8Ds4G4eCmB0v3bGZ+NYCpGsVr+47HMh60SxRsEwTDLktKAgIq3PtMX0FBUCPiKs23VYKZ1hXn3VZLlV2w8aYasqPziuxNge2DHWuvSYQq2HhJRPp/UuBmBuZSpLn1sv27Nd84Tfa2+lOaGuKmw2n23XK8wyDMN4IacFBaCZn6waRVTE/BcSNxPQjoNVppant57TG69eNxJDu2gmoMtGdEFp22ZYfs85aJEfQKsCrVrsrsPagv3UlccDgG0ZD2FRKdoU5sWNsdKlTaHp8+/+t8r0He56c2XCazAMw0hyXlD4iGw1CmvihJc8BzmmV/sWOLF7kVGkb+1OrQxIy/wg+h7bwjD9vLRQqzElNQk7jSKV/kNDOpt9FKtlGRJF2lnLezAMwziR84LC7yNTlzkAgI1GYScoJgzuYPo8Rg+llYv7l1v2AzAX6Av6fY7OZLUirCyzYe2+VxekJgMAR9JQhnz3YTZhMUwuwIKC7ExPmjP7J6d2M/ZZBQcA3HhmT2P7shFdEDDyMbTr2ZUOzwv4HPMY1MKAMqS1W9tmAIDxUiilEAUFAIs378PyrbEGTQeP1LqMTsxnG/ZgxNQP8d6qnXW6DsMwDZ+cFxQ+n53pSRMMw7ocY+yz0yh6FMccy0TAPecPwBUju2B0Xy0Utm3zUNw5Qb/PNero4YsGa9fTJULXomZY9rtz8MeLhuC4Lq1x94T+SXy7GJ9vMLdXnbEkPgEwGdbs0Jo9Xff80rhjX2zcy42TGKYJkfOCQjqz1+w4hHnrdgPQNAoiYPX2Q6ZxVoJ+MhzEBC2/4oELBhmaxJm6Keqvlw8zznHTKADg7P7t0a9DS/zszB7GvlYFQRTk+fHfn52MgZ1aOZ6rMqp7kenz/iPmSKjH55Z5uo4TwsEkdu9bqzDpqS9wxxvsMGeYpkLOCwofESJRYNyf5+PqZxfjaE0EW/drvSbUSCa76q5EZPgV7ExTJ5S2wZd3nY0Jg2M5FKEEGkXrwjy884tTTdpKKrx83Ug8eukQ4/Ozn26u0/W8Iu/z5bf76+V+DMNknpwXFH5fLCoIAB77UOs6986KnRjRrY0yzt45IDvNOYXPtmlmDmdVndmtCoK4dHjnlOeeiO8PK0k8KEUS+dgrq8MZuzfDMPULCwoiLPsuFpUks5iP1kZwjlKaw9rhTuKmUdiRF4hpFNGoQGEovk9FQ2bV9oPYfuBowmgsrzWwGIZp+OS8oLAKALUTXckxscQ1p8ZCuw+7t0G1Eo4K7D9Si70V1aiJRE2lQOoDtS6V2v3OK+P/sgAnTZtrm4muahGVNaxRMExTwdMqRURjiWgdEZUR0WSb4yEielU/vpCISpVjU/T964joXMt5fiL6iohmKfte1MeuJKLpRBREBrGalJyqtdr1izAd96hRvLxIS7K7+3+rUBuJplQdti4M7RyL5LrymUV412N464qtBxOO/eN7sX7gaUz/YBgmyyRcpYjID+AJAOMA9AdwGRFZYzSvBbBfCNETwKMAHtTP7Q9gEoABAMYCeFK/nuQXANZYrvUigL4ABgEoAPDjJL9TUlg1BadonkACSZFslddP1pcjKpwFU6b4sZIbApiTAZ2orA7je39dgOuVUNhiJfRXhhcnq10xDNM48LJKjQBQJoTYKISoAfAKgImWMRMBPKdvvwZgDGmlSicCeEUIUS2E2ASgTL8eiKgEwHgAT6sXEkK8LXQALAKQOY8s4k1PTmGjiQSBx06m+GzyaADA+UO0SKhgIMUMOo9Mv3q46bNVMHnJ/LYmJAIwmZ5qo5rPZV9FTdw4hmEaP14ERScAanbWVn2f7RghRBjAQQBFCc59DMBtAGxjRXWT05UA5niYY8o4+R6sFATtnc7/N0prp0oer9OxdYEpYzuYyKZVR2TynxPhSGJBYU1IBIBwNPZjm/z6CqzfdRjH6uXTGYZpWnhZpexWQOvK4TTGdj8RTQCwWwgRn9Yb40kAnwgh5ttOiug6IlpCREvKy5N3ykq8FPsDgAFKkyGV3Yc0c0tcvSgX8vw+Iyoo6M+sRpEITxqFnaBQBMwbX23D9S8sxcjubeLGMQzT+PEiKLYCUIP9SwBsdxpDRAEArQDsczn3ZADnE9FmaKas0UT0ghxERL8DUAzgFqdJCSGeEkIMF0IMLy4u9vA17PFadM9JY5ijO3gXrN/j+Z55AR8q9AihQD36KO75Xnz5Dy8Czmp6yg/6bM87XMWRTgzTFPGySi0G0IuIuhFRHjTn9EzLmJkArtK3LwIwV/cxzAQwSY+K6gagF4BFQogpQogSIUSpfr25QogrAICIfgzgXACXCSEyXgt77c7DtvsvHGa1rrlj7RvhRtBP2KQ3RGqRH0jqPnXh6pM1R/Z9EwcY+1RfQ004ih89uwgrtx00nRe1/BT8RIZfQuWB2da4hIbFym0H8cXGvYkHMgxjIqGg0H0ONwF4F1qE0gwhxCoiuo+IzteHPQOgiIjKoGkBk/VzVwGYAWA1NF/DjUKIRJlYfwfQHsDnRPQ1Ed2dwveqM3eM75d4UIrsOlRtlAcpzKs/QSE5s0+s5eqq7TGhsG7nYXy0rhy3v77cNN6qUVTWRIzERImdvlXXCrXpZsLjCzDpqS/w5lfbsj0VhmlUeFqlhBBvA3jbsu9uZbsKwMUO504FMNXl2vMAzFM+1//KaUOicFgr1lapXgnZlCLPNKozXS09Hgpq+6sttagiNg5va4kOOwve7sNVaFWY0TSYlPjlq1+jsiaMH57YNdtTYZhGQYNYlBsiyQYj2fWe8IKaCZ4pZt50sqn3tlM2uBR1ZbsrUDp5NgDgnV+cauq8J6mwCAq7suKLN+9Hr/YtUprzk/PKULa7Ao9cMjSl8xOxRqnvlQ4iUYHKmjBa5jc8wcgwdSXnS3g44TXT+vlrRwAArhyV2tvpsS0zH1I6uKQ1hirtUaXmIJGO6VobzWH28h22jutXFpv7WWw/GN/trmVB6u8hD81Zh/9+uQ37KjOTm3FSj7Zpvd6fP1yPwfe8h0NVDcvcxjDpgAWFA17DZk/tVYxFd4zBxcenlhfYuU1h4kFpxqpRXPfvJQDMuRGSmkjUFBlm7cftRjIhw07sOtQ42q2+tUwLBNzD2elME4QFhQPS3DL75lPwkN51zol2LfI9J9w1BKwhuR+u1Ro2zbcJ8Y1EhbHg//2K43Dz6J5xY6w89APtebn13XBDdYJnqgqtU9/yVJHC160pFcM0VlhQJGBAx1a4JIM9IxoK1eEIHn53Xdx+VVD4iOL8Fa0KzDb5oJ9wRt9i/ZqpLZrPfb7ZdP90UVoU096sUVt1RfqoUhWODNOQYUHBAHBOlnt31U4jwsnvixcUVgvdLWf3MZo5SUFxpCZsWwbEiXzFh2JnDksV1cxXneY3f5lhz4KCaYqwoMgCRXrXu77HphYRlAmcOtLtOFiF+2atBqAVULSWHLGa3GYt326E/FaHI6ioDqP/3e/ij++tc6zMa0Wtq+WlFpVX1NtX20Rp1QVDo2DTE9ME4fBYGzpkuLjdnF+ehhXbDmBEt6KM3icZ3HwBsoe4nyjOtm/VKE7rXWzY66tro4YAenLeBjw5bwOW3HkW2iolyu0IKYIinaanRZv2GdvpXtBlVV7WKJimCGsUNjz4A3fndV0pbhHC6L7t0TzUcOR0TTiKCYM72B6TwiHgI/Q9NlYccdW95+L2sX1NY289pw98PkKe34eaSBQBiySRGeluqOat/UfSEx47d+0uk3BI94IeYh8F04RhQWFDNrKls011OOpYrUpqGz4foVkogM3TxmPztPFoFgrgYoujX4YV10SimPn19rgwYy8aQp5i3rplxrIkvoUzXysNmoJ+StnR7oQ0PdnlojBMYyf3VkQPWJsZNUVm/fwU9O8Q0w5qwtH44vEWnHJLxg081nb/tgNH4/bZ9dpOZUxdyPP70v7mL81t0z/dhD+8vQZnP/KxqY4WwzRmWFAoSL9sDsgJDOzUCpeeENMG9lZWY/aKHa7nOGWrt9Gd8yrd2zZD5zYFcTWgIh6imBYrvoR00VIJ480LpF9QSHPZ0i378Y9PNmL97gpc/PfP03oPhskWLCgUehQ3B+C9W11jR3VgT3tnbcLxThqFnaA4rusxtsUEE0UxRaMCz32+JeFckqW3UnMqFPCjOpzeqCe7eliZShZkmPom5wXFTWfGMo1lW1SvdZ4aO2oPjT0ViUtPWB3Tkp+e3iNuX37QZ+v3SGRW8tpIKlmkb+TRS4dkVKNgmKZIzguKX5/TGwDQpU1hTpmeAHNegeqE/evlw2zHOwnQZjbRW3l+P2rC0bjcicSCwvUwAOD5zzejdPLspBb7F77QtJROrQsRCvjSHh6biwEQTO6Q87/dRITnrhmB1346yjCtpNpboqkwYXBH2/3JvO0HA2Sb/ZwoQ/vLb/cnvPajH6wHgKQqtcp6VgeO1CAv4Et7CY9c0UKZ3CTnBQUAnN67GO1a5huCIlPmj4ZGsmtbMm1bQ34faiPxpqf3Vu90Pe+ON1YY26VFhbb+DxlhlEphP7+PNNNTmjWKZFrhMkxjgwWFgnRiW1t/NlXs3oJnXD/KcXzXomaerx30+yBEvPP67RXugmJDeaWxfXzXNkY5j6raiKGNBAOp11Xy+QihDGgUDNOUYUGhIPO8kilg15j5wXElGNCxJU7tFWviM7iklbE9sFNL3HGe1jtcHWPHDWf0wI9OLjU+W6up/ubcPo7nCiFQOnk2/vSeuXptXoBQE9H8HH3vmoPJ/9V6eQf9qSe3DezYCnkBf9qLAjJMU6bh1JBoAMg37ByREyhuEcLsm0/F819sMXpRyEV47f1j4fcRFpRp+xOFDFtLeRi1jyJaiKjMYxjTt13cuUf1An2Pzy0z7ZeJcd/t0xL3ZizZiocuGpKS6emsfu2xeW8liluEMpJwpyqhLfMDOORQjZdhGiOsUSjEBEWOSAqdQiW0U/pp8oN+BP0+VOm5AIVJhn+W6+G2+yo1hzMB6FHczDaMVAoCK0HdzyH9Ca0LNWET0FW/ZARFJBpFod6fPBT0pT2PQuWyE7sAMJdLZ5jGDGsUCj797zpXTE+SgrzEQsCX5Jp3WI9I2lAeKwKYH/Sjyqa8t8xxaNMsDweO1Bgancx3UBsnAarpybugCEeFkQeyevshbNpTiUNVtWiZH0xwZvL8+uw+2FReiS17j6T92gyTDfiVR0F2a8uFWk8qmah4On6QFmIr3+KJdEFh8yYvF3wfEcYN1CrYfnDLaQj6fQhHhXFcanqxkt7eBXptJGq0gN20R3OYP/r+N5iz0t257hU5ExlV1SwUwJFaNj8xTQMWFArTLhyM28b2wYnd2mR7KvVK0O/8ayBdE8mWNZFaylHddEUg5Ad9qLKJNlq8WavtVFFdi4Cf0LWoED3btTAc4tKHITWLVHwUtRFhnCd59tPN+OkLS+PGfrfvCN74aqvna6t8edfZADSN6rt9R7GvMj1l0t2Y8Ph8PPFRWeKBDJMiLCgUjmmWh5+d0TNnaj1J8lyyikf3bY/LT+yC332vf1LXlGGtar2j/IC96emB2WsAAFW1UQgRMzHJbGfZ/Ei6jlJpOxqORA3fRiIu/Ntn+NWryzx35FMnJ7XSD9ZoCX7H3f++Y/fAdLFy2yHbfucMky5YUDBx7U1V8gI+/P77g9CuRXJd/6QjV2oDhukpQQvSqBCGFiO1kgpDUGiLccCIqEpOowh4dLSUH9Yc8cl213N6v3jqk41JXYdhGhosKBijam46URPlJCEH05OKEDAKqMhrVOihpjIRMi+FtqO1kairQLTjf19vT2q8E68u/i4t12GYbMGCgkHnNoVpv2Z+ntn0RNAW/kQahYAwTE8ylFZqFFGr6SnJqCfpiymyKQtix6//4727nlX3mDIullcy1qGxUzr4bl/2Iqs+/qYc222aUzFNDxYUTEaQ2kDSpqdozIQjzVfvrd6lH7NGPSWnUUgfxcMXe++JnoyfQtVXxiv9x9NdV0rl1Ic+yti13ThUVYurpi/CSdPmZuX+TP3CgoLJCEG/D34fGVFPgLbwVyVY3MNRAb/uS8gPaMJmkaXjXTCQoulJv+7ovu1NyXBuwuC8vyzA6u2HEl7feolQIJabUpuB8ONsM33BpmxPgalHWFAwAID7Jg7AAxcMTOs1C4J+HKnRzEYEQn7Aj4iSFyG5YGisrHl1OGKYlkKWzOZwVGDhxr2Gj2L++vKEGgoA7DxYhV2Hqk1RT6qv5PONex3PXbPjEM77y/yE9wDMIcSqIEqlym1DJ8dyUnMeT4KCiMYS0ToiKiOiyTbHQ0T0qn58IRGVKsem6PvXEdG5lvP8RPQVEc1S9nXTr7Fev6Y3gzJTJ/5vVCmuGNk1rddsFvKjslrVKOw1BLW235GaiJFBrb6VSy596gtj+6N15bh/1uqE87jimYUAnEuzHDxi7mthzbdIBbVUSSrFCxs6PdulPwCCabgk/IsgIj+AJwCMA9AfwGVEZA2qvxbAfiFETwCPAnhQP7c/gEkABgAYC+BJ/XqSXwBYY7nWgwAeFUL0ArBfvzbTCGkeChilPEDApxu0AoM2QHt+AAAgAElEQVQ/fHqhaZxaMqWyOmyEsTrldyzfesDY/mbX4YTz2HmwCoBzuKt1b0mbgrgxiVrFWvtRqG1jm2KvCvn1uhalPxCCaXh4eXUaAaBMCLFRCFED4BUAEy1jJgJ4Tt9+DcAY0vTwiQBeEUJUCyE2ASjTrwciKgEwHsDT8iL6OaP1a0C/5gWpfDEm+zTPD+JwtTQ9AfPWlduOUxfwIzWRhIlxX34bExS7D7sv4M9+usmImpqxxD7b2m8p2WKneAx/4APX+wBmZ7Zqhoo2PcuTgRfTH9P48SIoOgFQA8G36vtsxwghwgAOAihKcO5jAG4DoP4ZFQE4oF/D6V5MI6FFKIDDVbGs6qnfj/lAhBB4ZsEmHDxaa2oUdaQmbCTUdWtr3yhJDW9NVHjv3rcSm6aspiZHzcPF6W136LIRnQEAlTWZycxONiEwncjvmygvhmkaeBEUdq931t9QpzG2+4loAoDdQghroR0v99IGEl1HREuIaEl5uf2bKpNd8oN+I8t5+qeb0LZ5yDj2adle3D9rNe59a5XJ9FRRHUbQZ64Sa0UVIKf2aoups1djWx3i+astUUlOC3Cihdmamf3ABYMAAPPX78mIQzsTxRyThTWK3MCLoNgKoLPyuQSANWXVGENEAQCtAOxzOfdkAOcT0WZopqzRRPQCgD0AWuvXcLoXAEAI8ZQQYrgQYnhxcbGHr8HUN2rU0rb9R012e/mWvaG80qRRVNUmrsmk+gvmr9+Df87fhJPrEM9v7U3h5PRO1imtmrSOelhQr/3XYpROnu1ZU2gIfVOsQpZpmngRFIsB9NKjkfKgOadnWsbMBHCVvn0RgLlC09NnApikR0V1A9ALwCIhxBQhRIkQolS/3lwhxBX6OR/p14B+zf/V4fsxWSSkOKOJgFN7aQK9U+sCQ3Vc9t2BuIXRrZotAGx2MDf9+/PNrudJUxAAPHLJEGPb+mbutFC7Jc4lWrK9vHl/uFYrJNjjt28nHAtkt7d79kUUU58kFBS6v+AmAO9Ci1CaIYRYRUT3EdH5+rBnABQRURmAWwBM1s9dBWAGgNUA5gC4UQiR6C/mdgC36Ncq0q/NNELU8FYirU/Dqb3aorhFyDAV9WzXPO7NWBUUr/10lOf73f2/VabP1gVf/XzhcSXGtvWt2FmjcH97JhvL6R8v1gRSVY39ubsPV+FITRhvLUu+rpTgl3mmnvDU4U4I8TaAty377la2qwBc7HDuVABTXa49D8A85fNG6JFRTONG1ShuObs3AE0IRKLCcDLn6Z8HdmqJldu0DOjZy3fg0UuHAgCGl6beG+S9VeamREM6t7Yd59VH4eYTcHq5t5YykVTVRlBZHcaIqR9iQMeWWOUh+9tKNk1PSZVgZxo9nJnNZAxVUJygL/gBH5nezH0+LXy0eSj2zpKu2kg3vPil6fPlI7rYjrP6KCJRgeO7HhM37kii6CUb10pBnvYMZHMmyYVPfobj9ZDbVIQEkF3TE5NbsKBgMoYqKGTSmWxvKlm57RC+2X04LpchVeat2+14zKkhVXWt1fQEDClpjStGmgXLoarkw1xlhvadb6407V+9w104eOnb3hCc2UDTLFHCmGFBwWSMkFLGok/7FgCAzzbsQdnuCtO4A0dqjdLidrx10yk4o4+3yLarn11su/+kHkVx+17+yUgA9qYnvw8YXGI2Vb351TbH+zplXxcozyCZvAe73uJx92wYcsKUKc80TVhQMBlDahSXDC8xkuj2W+oqSdw0ikElrXDx8Z3j9g918DnY2c+HdYkfO6pHEVrkB0ympxVbD+JobQQ+IhzXxWx++vfnWxznCNgnAamOeXkfLz0k1Kq7Tlg1Ci/nZIIf/O3zrNzXiaraCPtQ0gwLCiZjSEHhJf9AzbG4ZHhJ3HE7hWNEN3tH9w69tpNKuUOpj1DAb9IoLn9aKzpYWRNGz3bN8YcLB7nOOxGqFiEX8sfnrk94XqJy7Oq1j9OF4L4jNalMMSUa6jpcUR1G37vm4NH3v8n2VJoULCiYjFGYpzmo1S5oM663D3f1EWHWz08BAPx8dK+4492L48t5tCoI2l7LrpmOU52nUMBn8lFIDUCa3QvzYqajcQ6d6o7WRPDOip22x9TugTLyKeChOq2XvAu5WMvn3BAytbNNpV7X6y9zy7I8k6aFp/BYhkkFWYxvoVJWfNeh+Ld9QDM9DezUCpunjbc93vfYlnH7WhfaCwo7fnZGD9v9oaDP5A/YV6m9lYd1SaHmghzj0EL11v8sw7cO5qQ2yjly8fdSxtyLoJCmJ9n7IluC4uSe8f6fbBFIU1AEY4Y1CiZjnN5bc0B3Vsp22zmVAcDn4Q980R1jcOnwmK9CdRQnYpTDfUMBP6ptFmUZmSWFHQBs3lNpe43ZK3a43lsKi32Vmn/Gy2LmVGzv0n98jttfWw4gZnqSQQOZFBQ3v/wVSifPNj5L531hnh+7DrlX8GUaPywomIwhW5aGFR+FNJMAwJCSVsa23yXqSdKuRT4evGgw5t92JpbceZaroDjvz+audE5v8aGAz7ZekczlUB3Pn21w7oTnxlS9c+Al/9Ccvm6Oe2neshNegKadvbpEK8g8Vy/5sa+ixjTnTDBTzxxfue2gaf+RmkhcFFs24dySzMCCgskYsqWpGmevFvwb1uUYdGyVD8B98bTSuU0h2jYP2Tq4JdY8BSeNxUlQSNNTUfO6N1gMW8Ji3ZYyWVokUXisEAIPzNZ6fq3TmzfVh+lJFmS0rscNJcqogUyjycGCgskYLfM1H8IPlLpKqtklEhWG1uGWR+HEwaP2obbJkB/02woKGak16QT7bO5kCFk69bktqtLfcM2/luABlzavG8pjZjCpLWVSo5A88ZG9kzibvTFUGkoSYlODBQWTMfKDfqy5byxuH9vX2KdmRwsIQ3Ck0qa6TbNYf4u/Xj4spTlqUU/xb+9SC3JqxyrxIqzU8iSAuz9Gzbt4esEml6vGFkQ5x0xoFN2nzDb5JhZv3m87zi4kORs0EHnV5GBBwWSUgjy/48IohJaVDSRnepKM7tsOJ3Zrgw9uOR3n9LcPXZU4lS4PBf3GAqtGGqnmslk/P8Wo/fTiQi3pbsH6PdhQXoHyw4kXyJHdzY707pbOfV2LCvHT07WorHYtQqZjh6rsBZEqcG8a3RMAMGelfYhuXXBaeK0v7s+4CLXtB46idPJszF+f+QZjt85YlvF75CIsKJisERUCe/Vw1FQsBn4f4dXrR6Fnu+aOguamM3virgn9TY5zFdVHcUDJGlcd8AM7tcLSLdqb9B1vaDWbrnhmIcb86WPY52Ob8fkIZ/YpNsqYyO/63DUj0LZ5Hl776Um4fWwfbPj9eaZwWsA50kqdX2mRJnhe/9I+VyQV7pm5yqRJSM7q1852/L8+2+xoUpMlPp5PkNmeDj7fmFrAAeMOCwomawzsFFu8K+tYfsJJISlqnodrT+nmWBBQExQ2picXG4aqeZz1yMee5tcsFDC0FHnpvse2wJI7z0ZxixCICH4fGUUEJU4CVM00zw+m/8/4X59ttt0v/U5201q787DtOTIXhbvhNV5YUDBZQy37nUrjHhUiwvqp47Dx9+eZ9icyaWl5FNoCFo7GFrLH9H4YdjySQnmIUMBvCBjpcLWTXXGOb4fr/exFrd384JJW6NAqlqeS6R7Wal4JANw1ob+x7eTQlqbH+nY0h7mqbdpgQcFkDae3/FQJ+n1x/pBE0VShYMz0JM05j1wyBN0sfoT5t51pbDvVjXKjXcsQyiuqUVUbMRZMu7lZn4mTOUeWPJ88ri+KFb/GsPvejxsbjQq8uvhb3PzyV5iz0j05EHAXNpWWnhxn92tvbE94fAFufvmruOKEMkemviOj6iMKLFdgQcFkFSffQbpIrFH4UBOJIhoVxiJot4B3blOIy0/UNKD2LfOTnkeP4uaojQjsOlRl9JrwkmSYaGm1JhL27xhf6uT1L7fi9tdXYOay7fjpC1/GHbfiVt22QhdQwkErmrlsO+7+n7n3hk+fYr0LCjZ1pQ0WFExWKbZE+aSbRHWVpP28JhLFI+9pJqV3HN66ZSZ4KuYd6UeoDkcNH4WX3JFE1hprNFdXpQihJNl8k8ufXuh4bNnWg47HJNa6V74saRROZVCY5GFBwdQ7o/u2w0XHa0l4V44qBRBrIpRu5n3jHpIpfQLVtVEj69hpgXn2Uy0EdIZeQsOKNV9CJV8XSK8v3YqNe7SSF+Thry/R4mrN87AbnWzocSLT2oEjNa6ajnVOUoNassU+ByOdqD1Kpr2zJuP3yxVYUDD1zvSrT8AfLx4CQCscuHnaeMeifXWlU+sC1+Mh/U2/KhwxSm04Fe27W3fcDrYxl917/gDMvfX0hPf5xycb8cIX3wLwplHsTpCnITUKqTm9YdOFL90VVXcqFYDtvsKEwR1Mn99dlf78DifUYIA3v65bgAQTgwUF0+RQ3+zPHdDeZWSsX/aJv//QECqn9mprO/YEvVFSXiC+GGHv9i3QroWz7yJkc46X9fuml75yPS4XRrWGlrXfdiiJKrtu9GzXHICu5bioFKoPefHmfXhOz5+ojwrgnJidGVhQME2Ot/QGSEBis8veypiZ5b3VuwAA5wywz/KWPopKS4goANtcDBW7XIeAr+5/flKjULUTa7SPNeQ2VdrqBRIrq2Pf1S5yTfpwln13ABf/PdYmlctrNF5YUDBNjm5tm6GX/vabSFCoZc8l6tu5ikyGs3MOFzVzd8rbaRRBh/skomV+bM7SH6Cu12W7K/DPTzYaCX5O5UuSRWpqVqF44bBOps8y3HjiE5+m5b7JIlvD9j22Bbbstc9sZ5KDBQXTJJELZyJBcekJneP2OUVKSY3C2n9h1s9PwaAEYb52b/Ve80hk1z3J1Sd3M7aNEFvlbX3C4wsw9e01eOqTjQDiy5zXOuQX1EaiGHbfe47zkIKyujZqNC4CgEcuHYpFd4wxPifSrjKK0IRn9+JmWLvzME5/eF725tKEYEHBNEnIQw0mACiyaW/q9AZekGdv61dLkTgRrIP5Jy53QTnWskB7y79jfL+48x5+dx3mrt2FSNQsGOT1rBw4Uov9Sr0r+WYukf3DVdOWnEtx8xB+fIomwNxKddRH3woCmYQ9Z2jXHRYUTJPEeNFOsC4REcYPMkfpWOstSepi629d4L2/t5VyS7MgVRGRWsmkEfZ9M6751xJTAUHAuSKtsJQuv+aUbqbj0kxXHY7EPVciwp0T+qNFKGAECKh9SCSZzpaW30Et8PjFxn1OwxmPsKBgmjReXmC/N6Sj6bOTucrOVPTSj0/0NI9mLjkWifhYzwWRX4VA+HTyaHxwi3M4rsr2A+YQ29Mfnocrn1kY93av5mz4CBg/qAOe/dEJxj4pQA8djWkk1keilURxNj3VR7Y0kTmEl6k7LCiYJolc1IWHgEknm30iFv12DE7qaR9KWxeseQ+lRVq2tVo2o1PrAiNcNRGPfhBfxHD++j1xPSRUzcNHBCLCmX3aGQ5z6aP53cxVjvfaU1GDFxd+i6M1EVPZcxl67GSWqo1EMWv59joLErsXgzSXFMso0xdswpT/rsj2NOJgQcE0SaSJ2otG0a9DfH2kRDx00WC0S6Hmk2TcQOdGS3N+eSqmfn+g8VmG48Y0ivQge25LVLOQGm4rHeaFio/GqaS45P01u0yfR/fV+lg4CYpRf/gQN730FV5aWPeeFVbB0IjkBO6btRovL/oWOxtIx0AJCwqmSfLE5cfh6pNK0d+DEFDfzGUnOydkVraXgn5uXK93tLOfTwv88MSueO9XpwEA3lqu1Z6y81GkE/VtXr2HVHAKQzFBIftVOAUNHLVUmZXnOmkMeyq0yK41O9wFUCKkMFVriDXG/I1fvfp1tqdgwpOgIKKxRLSOiMqIaLLN8RARvaofX0hEpcqxKfr+dUR0rr4vn4gWEdEyIlpFRPcq48cQ0ZdE9DURLSCinnX/mkyu0bWoGe45f4Brf2o7EsXdL9eL4qXS1vO5a0bggQsG4t1fnmaqSeSEzAVZtElzxkozmlNYbdvmdSuwqNZiUu8gn2GiAosq1pDcwqB9DoaVqjSE1hLIVK+qJpLFcN0kUDPqj2a4r0iyJPzJE5EfwBMAxgHoD+AyIupvGXYtgP1CiJ4AHgXwoH5ufwCTAAwAMBbAk/r1qgGMFkIMATAUwFgiklXh/gbgh0KIoQBeAnBn3b4iwyTmRd0p/YcLB7uOk3LnutOcNQInTu9djCtGdkWfY1t4Gh/fm8J9/BdTRhvZ06nw17nrje1DSgitdO4nU1wwvoyIttRUVIWx35IXolLXxkt24bfVSVaRPXikNiumn5+/HCvXYs2dyTZeXhFGACgTQmwUQtQAeAXARMuYiQCe07dfAzCGtN/yiQBeEUJUCyE2ASgDMEJoyKyloP5P/oQFAGkvaAWAK3sxGefknm2x6Q/n4ez+7rWhWhdqC3H7lpktjy65cmRXo4+2XAOdigkG/D7H0N66IM1sdoIiHLVfhK0ahQwtnvTUFxh2f3xzJcm7q3Y5HvMKETBlXF/jc7IhuWMe+Rgj//BhneeRLLNXxMrbH9syH6WTZ+O3bzQMx7YXQdEJgFpXeau+z3aMECIM4CCAIrdzichPRF8D2A3gfSGELIL/YwBvE9FWAFcCmJbMF2KYVPGSKf2ni4dgUKdWhsDINKGAz3jLjpmenMc3sylJIvn7Fce53uvKkV1t9+/V325rwlGcN8jshK+N2Ks5X317wPT5sK6hSAFiffNPVz0qyflDYyHPyfbqluXm6xs1n2eTbgJ9aeG3WZmLFS8/HbtfS+tvh9MYx3OFEBHdvFQCYAQRyTCPXwE4TwhRAuBZAI/YToroOiJaQkRLysuTtxczTCqc2bcd3vr5KUn3eEgVtVWr4cx2Gb/JxccydqA5sbBPe7MJLFEU1yfr9+DtFeaS4U5ZzzOVHujrHhhrqk8FxC/eyS7mTsiFqUOrAqOsSLqunWnKFQElKwackoHw61TwIii2AlAL4pQg3hxkjCGiADST0T4v5wohDgCYB81PUQxgiKJdvArgJLtJCSGeEkIMF0IMLy4u9vA1GKbxkR/wIxIVqI1EY+GxLpJixvWjPF973a7D+N/Xsf4VVr+ClZoUHc2hgB8TLEmN6uL9zS5zpFOieXi+r1/Wpkpt3uqzqQ9O7x1bxxqacPMiKBYD6EVE3YgoD5pzeqZlzEwAV+nbFwGYKzTdciaASXpUVDcAvQAsIqJiImoNAERUAOAsAGsB7AfQioh669c6GwC3qWJylpDSQjVW68lZUgzt3BrzbzsTn08Z7en6v3glFoaZaH22q7RrTfpziowKWkqqq2Gy5zz6ielYXRZJ1aIln12qZUN+85/ljsdqwlHszZCJqlmeP87cmG0S1hUQQoSJ6CYA7wLwA5guhFhFRPcBWCKEmAngGQDPE1EZNE1ikn7uKiKaAWA1gDCAG4UQESLqAOA5PQLKB2CGEGIWABDRTwC8TkRRaILjmjR/Z4ZpNEjn9O5DVWir5wYkcqV0tumb7UZNOIq8gA8RZZW1Swj89Tm90at9czw0Zx0AYPzgDnF+nZN7FuGjdTFT8HWndQcANLeYntyy4atqI7YFGJdvPYDlWw/iCgdfikTOSQqtVLO9VQEz+k/zcMHQTrh5TC8AQO873wEA3HBGD3xvcEc0DwXQrmWoTsEEsoRKfjAmKBxiBeodTx4kIcTbQojeQogeQoip+r67dSEBIUSVEOJiIURPIcQIIcRG5dyp+nl9hBDv6PuWCyGGCSEGCyEGCiHuU8a/IYQYJIQYIoQ4Q70Ww+Qachke88jH2H7gaFLn/t+o+AX1g1tOi9u3WfdrSJPPT07thid/GO/4blkQNFXbtRZTBICp3x9kvvYe7dpWn45b+KdTLsX5f/0Ud765Et/tO+J4rvr+7fNpVWTroqF8+a2WW7KxvBKPvB9fCuVv8zbgvL/Mx2kPf4QbXlia8n2AmKNfC2DQ5vzVd5nvM+4FzsxmmAbMQplsJ4Cxj80H4N00c9/EWBmQ6/U3+57tWmDztPFGSXAAqNBLhER1jeJnZ/S0jQDL8/tMDZjOsxEUrQvNVXKdDCcTHl/gOO+qBHkP//hkg+txdeahgC/pPAqVb/cewcbyisQDAZMmlQpf6gmPAX+ssGKiZ1FfsKBgmAZM9+L4wn+phEzePrav6XOeEo4qF1Jp+nDKZg/4yDivuUM13MK8QJ0jwhIl3e2tcElGs4TdHq4OY/qnmxwG26MmLQb9Ptz55sqkzk+VBWV7AACHq2obXNkRFhQM04D5pW4TV9mWpAkKiF/81eQuaYt/URdA1oV+xvWj8MMTu8DvI3yqL2YVNn3DJWq58kQiY+7aWILdWf20woGJBMWxrdzDeO18OF4rBL+1bLtRdwrQ2tV+tmGvp3PThdo8CgBWbz9Ur/e3gwUFwzRgkq1VZeXV60bGaRNWZPjoJt2fYL3liG5tMPX7g0BEON8S5pqIkItz99OyPbjmX0uMz9d46JAHmAv+ecVraZB/zje7RLfujxfKbl36Ig1NFUgTLCgYpoEjk65Gdm8DALj/goFuw02c2L0IN5wRX5dqyrhY69SDR81vsE4lQgB4ykhXS6TLXhp2yAKL2nz6GhFDdov60ZrYPhl1ZYfTMu01esga3nvfrNVxY47UOAud+23G15UnPipL+zWThQUFwzRwZK5CcYt8dG/bzLHURjKo4ae/eW256S3ZTVC4mZwkPzyxKzZPG49/XzPCCCe148E5a43t/KAf+QEpKOJX9ZcWeffL2M3+j+85CxcV+RQKHfqjA/GCVUWWX08nQX/2O2qwoGCYBo5cfJZ9dyBtvSisb84vL4qVZHNzRh/XJXF5dMlpvYsRVO6z8LdjMO/WM2zH5gd9hvCy6+mdqPy7xGoVkt0Cn/9iiyc/hQxRbWXT4zxfT+BzExRWjtSEsWD9Hs/jrd0NAaBXe2/VhjMJCwqGaeDInt7f7jticrTWhTxLET61SqmboJBhswUpJJa1b5mP0rbNbI/lB/1GtJFdjsWZeoc8L6ihvaqZLuxQwFBF5pLYfb8W+UFc/s8vMO7P8x3PP00vw7FlbyVmLPkOU/67Alc8szChoDuiN3r60cmlccf2V9ZgV5Z7gLOgYJgGjrp4JPM260ZdqrW+eePJmHvr6Smff2K3NrbzkSVCpr2zFldNX2Q6bjWHSVPZC19sweg/zcPRmgiu+/cSrNh20DSud/tYeLGXUh6yt/ewLvGdDqtqI44RUAM7aZ0RRpRq553+8Dzc9tpyrNNbxlojmaz85jWtXMg/58eH8j69YBNO/H39lz1XYUHBMA2c/ED6e0wEHWoyXTq8s+1+laGdW6NDq4KU723XbjYU9Js0mY+/Kce9b60yPlsLBT6zQFtQ73xzJTaWV+KKZxbivdVaqK0qUvL8sWfnxb8yXF/of3p697hjbqYro1yIRWuR5UMSmb027E6c1Oc1xDcTsKBgmAaOtI2nE6eupv06ZN4e3swmWc/ONv/sp5uN7ajF+fDAbHOt0B0OuSVqLcLfv524vqi8TXubXA2n3huAFhab5/fFLeYygitRvSkZRqxWkLXixXSWKVhQMEwDx+pPSAct8+OdtQDgT6IvdqrYRRS5pR+s2HoQ8xKUx9iutC5VrVR9j21pbNvlRMTPQ5uInwjNLPO05kiowq06HEXQT6i1CISjHgVFRI/fDfoJb954MgBgSEkr05jaLFYIZEHBMA2cjoqZZ+mdZ6Xlmu1a5uO5a0bg+tO7m0xB/nSFVblg14XPKYmtOhzB9/66AM9/sQWA2efgJYlONWdZF3GVSFTg/lmrsUMXOESwrWCroprvaiNRBAPxGoWMolq9wz27+sRuRQCAcwYci6GdW2PztPH4302nmK/FGgXDME7I7GwioKh5+np1n967GFPG9cPJShc1OxNQuilqHp+0ZxeOCgB97pxj+vzYpcOM7b53zbEOBxAfIvv6DVrvs1N7OXeLW7x5H55ZsMkIRfYRmSLM1CKKAHDL2b1N+Q01kSiCfp/ho5DHZAvYh991z+Poc6xm8jupR5HjGKdugvUBCwqGaQQ8fNFgvPfL+BLh6UCNgKqPFq9n9IkPdbWLMrKjf8eWCcdYo5uO73oM8vw+157obkmGLfMDcdrFzWN6IU8JMqgJR00+imQDEKRZK+BzXpJrs1gehAUFwzQCLh7eOWOJV+qbcX0ICr+PcFa/9rbHrH4BO6xv91bs/AGFIb+RqwBoZiv1c8CS/azKjUNVYcxdu9v4fPPongDMArY2IhD0k/HWXxhKTlCEjcq95v1/njQ0NoY1CoZhsoWapV0fggLQ3tLtcHvrlyRy7tu5Ow4cqcW/P99iCIdTH/oI/e9+N3ZNixPfR4SLjy8xPkvTEAC00utdqfOoDWumJxkZ1dbGRLj9wFEcdMiniDpoFBOHdordg30UDMNki7Bi0qgvQSHf4L83pCP+ceXxccftFlqJUw6IxBpKq/LYB+sBAOWHzf2urecQzMJB7b+Rp8/dzkchGw7tsemnfdK0uTj1obm285I/A7vnL4tChjnqiWGYbPGQ4mitL0Fx9Und0CIUwB3n9cO5A2L9ueXdf31Ob8dzExXJi7gICllK3Yq1ORERoYWu9Qzt3BrjBsa6+UlNQtUoaiJRtC4MGhnYuw7FCwpAM2NV1Ubw2tKtpkgvGR5r9/xlS1uOemIYJmv86qzYolwf4bGA5pRece+58U2I9Nu3aRYfGSULCiYqY2Ln8+3SRit3frQmgifnxcp2y/LlaslzQOvJMaCjlsfwo5NLMapHkSGg5Nv/ym2xkFchtHpV1Q79vlUe/eAb3PqfZfhgTczvId0PdlFnUoMKszObYZhs0b5lzMzjbwAlrYF4QfH13WcbBQUTNTayy8mQNZzW7jxk6mehOqlViAgDO7XCV3edbfgJxvTVHPAy5NWKlnAXu3evdvFtbAHgc6gR1GcAAA1GSURBVL1elCrwDusVc+00CmmmY2c2wzBZI6A6s+tJo3BC3t0qKNQ8C/XN+o7z+sGKVTsAYsLQ+lK+dMt+AEAHh/aqxyjz6KuXNzniUDNq055KrNt1GGV63SankNv1u7TjqkB7ct4GAPbPXwoPdmYzDJM1RirVXMs8FKfLJDLqSRUM15/W3RQNpWZkO5Utt3LL2X0AAMMtBQmnf6oVF5wwuEPcOVZkhrxdraqR3dvgG10AvLpYa7K0btdh2+tIx7mdK8Wu9W3M9MQaBcMwWaJdy9jbtJdS3Jmkq946VY1suvXcPqYxauE8rwUTZV6DrDBr7NfzNrz0Jr/o+BI89IPBRm9v2T+8Z7vmmH71Cca4vXo/Dacsd5mUVxuNYvnWA/hsg3tjI3md1dvdy4BkEvtgZoZhcpKz+9snwtUX068+AYs27UOrgiB+c24fDOvcOi4c9vwhHVG2uwLvrNyJk3uYy3KM7N4Gl9iUSi+ycY4DwE9P1/qJuwRKGfh8hEtOiF173MBjMXPZdvQobobCvACahwKoqA4bxQfbNg9hp03DIWn+emjOOk/9RQ7oY/7wzlq0yA/i4uElCUOE0w1rFAzDGLRvaW+rry/aNg/hvEGaGejGM3vipJ7x9ZmICL8+pw8+uOV0+HyEcxTh9sp1o3DhcSW259gh/R1ORQndCOnajHSu/+HCQQCARZv2AQCaJcjOtgqJ1oX29a7Uoo2/fWMFet3xjhGtVV+woGAYxqA+igKmm8cvH5Z4kIVJJ3RGXkBLkNtbUY1/f74l6WuE9HpO1bWaoLAKhkKbKrluONV5sisJ75QPkilYUDAMY9AYBUUohQ6Ak8f1hY+AvRU1OP6BDxKG3NrfV2oU2tu9tXz6r87uhUcuGYI5vzzV0/WuO829hpXKgjL3/hzphgUFwzAG9ZWZnQ0uG9HF2C7I86OqNorXlm5N+Xoyie8cPbPcGg01um97XHhcial5kht+l8qxVh6c4162PN2wM5thGAMvRfkaK785tw9eXqSFrlqLAKZCu5b5WHnvuUbFW7vOfcmQTE9sa7e9TMOCgmEY3D9xAF5c+G22p5FR2jTLw9r7x0KI9AlEtVhgc5v8Cis+cm77mqhdajbxJFaJaCwRrSOiMiKabHM8RESv6scXElGpcmyKvn8dEZ2r78snokVEtIyIVhHRvcp4IqKpRPQNEa0hopvr/jUZhnHjylGlmJOhxkgNifyg37XF6ayfn4L7LxiY0rULFUHx8k9G2o5xUwSSMfvJsN76IqGgICI/gCcAjAPQH8BlRNTfMuxaAPuFED0BPArgQf3c/gAmARgAYCyAJ/XrVQMYLYQYAmAogLFEJJ/s1QA6A+grhOgH4JU6fUOGYZo83xvSEROHdkzqnEGdWsXtG9ipFa4c2TWlORQEYwJolEtLUyfUKrpWiluYy66/v3pnvdZ+8mJ6GgGgTAixEQCI6BUAEwGsVsZMBHCPvv0agL+SpttNBPCKEKIawCYiKgMwQgjxOQBZKyCo/5Oy9gYAlwshogAghLCv2sUwDKPz+GXJh8iu2BZfE6ou+H2EW87ujTP6FCcerDC86zEY1aMIPR2KCAJA1zaFph4aG8or8bd5G/DzMb1Snm8yeDE9dQLwnfJ5q77PdowQIgzgIIAit3OJyE9EXwPYDeB9IcRCfUwPAJcS0RIieoeI6udJMAyT07ybBtPbzWN6YXBJ67j9y353Dpbfcw7G2mgNr91wEn59Tp+4/Sq3j+sLwFwS/k/vf4P73lrtdEpa8SIo7AxnVkub0xjHc4UQESHEUAAlAEYQkTQMhgBUCSGGA/gngOm2kyK6ThcmS8rL6zemmGGYxs/rN4wytkd1LzJ1tEs3rQqCaJkfxOcb96Z0/gmlbbB52nj84izze7MsaphpvAiKrdB8BpISANudxhBRAEArAPu8nCuEOABgHjQfhrzW6/r2GwAG201KCPGUEGK4EGJ4cXFyqh7DMEyn1oXG9r+uOcFlZPo4rku8ttEY8CIoFgPoRUTdiCgPmnN6pmXMTABX6dsXAZgrtOIpMwFM0qOiugHoBWARERUTUWsAIKICAGcBWKuf/yaA0fr26QC+Se2rMQzDOCNbmeYHfSlld6dCwJK/8f6v6m7u2nbgaJ2vkYiEzmwhRJiIbgLwLgA/gOlCiFVEdB+AJUKImQCeAfC87qzeB02YQB83A5rjOwzgRiFEhIg6AHhOj4DyAZghhJil33IagBeJ6FfQHN4/TucXZhiGAWJ5D7cm8A+kE1kiZfygDvjxqd3Qq33dzV0VDh330omnhDshxNsA3rbsu1vZrgJwscO5UwFMtexbDsA2TEE3RY33Mi+GYZhUyQv4sHla/S41UjiNH9wBw7ock2B0w4EzsxmGYeqJO8b3Q/P8AEb3bZe2a2bSCS9hQcEwDFNPtC7Mw+++NyDb00garh7LMAzDuMKCgmEYphEhO+kBwGeTR7uMTB8sKBiGYRoRal+Njq0L6uWe7KNgGIZpZDx3zQgcsvTcziQsKBiGYRoZp/eu32oUbHpiGIZhXGFBwTAMw7jCgoJhGIZxhQUFwzAM4woLCoZhGMYVFhQMwzCMKywoGIZhGFdYUDAMwzCukNaIrnFDROUAtqRwalsAe9I8nXTQEOfVEOcENMx58Zy80xDn1RDnBGRmXl2FEAmz95qEoEgVIloihBie7XlYaYjzaohzAhrmvHhO3mmI82qIcwKyOy82PTEMwzCusKBgGIZhXMl1QfFUtifgQEOcV0OcE9Aw58Vz8k5DnFdDnBOQxXnltI+CYRiGSUyuaxQMwzBMAnJWUBDRWCJaR0RlRDS5nu+9mYhWENHXRLRE39eGiN4novX6/4/R9xMR/UWf53IiOi6N85hORLuJaKWyL+l5ENFV+vj1RHRVBuZ0DxFt05/X10R0nnJsij6ndUR0rrI/bT9fIupMRB8R0RoiWkVEv9D3Z/tZOc0ra8+LiPKJaBERLdPndK++vxsRLdS/96tElKfvD+mfy/TjpYnmmuZ5/YuINinPaqi+v15+hvr1/ET0FRHN0j9n9VnZIoTIuX8A/AA2AOgOIA/AMgD96/H+mwG0tex7CMBkfXsygAf17fMAvAOAAIwEsDCN8zgNwHEAVqY6DwBtAGzU/3+Mvn1Mmud0D4Bbbcb21392IQDd9J+pP90/XwAdABynb7cA8I1+72w/K6d5Ze156d+5ub4dBLBQfwYzAEzS9/8dwA369s8A/F3fngTgVbe51uFZOc3rXwAushlfLz9D/Zq3AHgJwCz9c1afld2/XNUoRgAoE0JsFELUAHgFwMQsz2kigOf07ecAXKDs/7fQ+AJAayLqkI4bCiE+AbCvjvM4F8D7Qoh9Qoj9AN4HMDbNc3JiIoBXhBDVQohNAMqg/WzT+vMVQuwQQnypbx8GsAZAJ2T/WTnNy4mMPy/9O1foH4P6PwFgNIDX9P3WZyWf4WsAxhARucw1JVzm5US9/AyJqATAeABP658JWX5WduSqoOgE4Dvl81a4/4GlGwHgPSJaSkTX6fvaCyF2ANoCAKCdvr++55rsPOprfjfpJoDp0sSTjTnp6v4waG+kDeZZWeYFZPF56aaUrwHshraQbgBwQAgRtrm+cW/9+EEARemek928hBDyWU3Vn9WjRBSyzsty/3TP6zEAtwGI6p+L0ACelZVcFRRks68+w79OFkIcB2AcgBuJ6DSXsdmeq8RpHvUxv78B6AFgKIAdAP6UjTkRUXMArwP4pRDikNvQLM8rq89LCBERQgwFUALtzbafy/Xr7VlZ50VEAwFMAdAXwAnQzEm319e8iGgCgN1CiKXqbpfrZ+1vMFcFxVYAnZXPJQC219fNhRDb9f/vBvAGtD+mXdKkpP9/d5bmmuw8Mj4/IcQu/Y88CuCfiKnV9TYnIgpCW4xfFEL8V9+d9WdlN6+G8Lz0eRwAMA+ajb81EQVsrm/cWz/eCprpMWO/V8q8xurmOyGEqAbwLOr3WZ0M4Hwi2gzN3DcamobRYJ6VQTodHo3lH4AANCdUN8ScdwPq6d7NALRQtj+DZuN8GGbH6EP69niYnWqL0jyfUpgdx0nNA9pb2CZojr1j9O02aZ5TB2X7V9DssQAwAGYn3kZojtm0/nz17/xvAI9Z9mf1WbnMK2vPC0AxgNb6dgGA+QAmAPgPzA7an+nbN8LsoJ3hNtc6PCuneXVQnuVjAKbV9++7ft0zEHNmZ/VZ2c4vnRdrTP+gRTV8A81+ekc93re7/kNdBmCVvDc0W+OHANbr/2+j7ycAT+jzXAFgeBrn8jI000QttLeSa1OZB4BroDnQygD8KANzel6/53IAM2FeCO/Q57QOwLhM/HwBnAJNlV8O4Gv933kN4Fk5zStrzwvAYABf6fdeCeBu5fd+kf69/wMgpO/P1z+X6ce7J5prmuc1V39WKwG8gFhkVL38DJVrnoGYoMjqs7L7x5nZDMMwjCu56qNgGIZhPMKCgmEYhnGFBQXDMAzjCgsKhmEYxhUWFAzDMIwrLCgYhmEYV1hQMAzDMK6woGAYhmFc+X99JBjOVeFOIwAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "learn.sched.plot_loss()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn.save('1024urn')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn.load('1024urn')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x,y = next(iter(md.val_dl))\n", "py = to_np(learn.model(V(x)))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAQ8AAAD8CAYAAABpXiE9AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAABIlJREFUeJzt3dFN21AYgNGAmIIpWKJigk7ZCVCXYArGaPpQkBBQCF/s2Nc+5z3K1VX+z9chJFfH4/EA8F3XSy8AGJN4AIl4AIl4AIl4AIl4AIl4AIl4AIl4AMnN0gv4zI/rnz7+CjP7/efXVXmckweQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQiAeQ3Cy9ANbl4elxkee9v71b5HnpxIPD4bBcNE59fnFZH7ctLB6OU4ywxr0Rj50baShHWuseiMeOjTiMI655q8SD4QjIOojHThlAziUeDEn8liceO2TwmIJ4MCwRXJZ47IyBYyriwdDEcDniASTisSOu0kxJPBieKC5DPHbCgDE18QAS8WATnKwuTzx2wGAxB/FgM0TyssRj4wwUcxEPIBEPNsVJ63J8e/rAPhqU198ybpCYk3gM6LMoPDw97v5nCt7uwVeRpXHbwi49PD06mZ1JPDbKYPxjH+YjHhtkYE5nrzrxYJNeouC9jfl4w5TNcqqYl5PHgFxNp2MvO/EY1P3tnRc+i3LbMri3AXFU/5zgTkc82DzBmIfbFiARjw1xy8IlicdGCMf/2Zt5iMcGGI6v2aPpicfgDMXp7NW0xGNghoEliQe74l/xpyMegzIA57F/5xMPIBEPIBGPATlyT8M+nkc8gEQ8gEQ8BuOoPS372YkHkIgHu+f00YjHQLzIWRPxABLxABLxABLxGIT3O+Zlf79PPIBEPIBEPIBEPIBEPIBEPIBEPAbgz4iskXjAM5H+HvEAEvEAEvEAEvEAEvEAEvEAEvEAEvEAEvEAEvEAEvEAEvEAEvEAEvEAEvEAEvEAEvEAEvEAEvEAEvEAEvEAEvEYwP3t3dJLgHfEA0jEA0jEA0jEA0jEYwB+BpE1Eg8gEQ8gEY8B+JwHayQeQCIeQCIe8Mzt4feIB5CIxyBcFVkb8QAS8QAS8YCD28JCPIBEPAbi6siaiMdgBIS1EI8B3d/eiciE7GVzs/QC6F6/6H3nRyMcnXhsxEdDICjvicV0xGPDTh2U15F5eczI4RGIyxAPPhw2A8hXvGEKJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJFfH43HpNQADcvIAEvEAEvEAEvEAEvEAEvEAEvEAEvEAEvEAEvEAEvEAEvEAEvEAEvEAEvEAEvEAEvEAEvEAEvEAEvEAEvEAEvEAEvEAkr87r79YklPCmgAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_img(py[0]>0);" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAQ8AAAD8CAYAAABpXiE9AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAABIRJREFUeJzt3NFRE0EAgOHgUAVV0IRDBVZpBYxNUAVlGB/QGRVR8+eOu937vkdmCJud23/3kpCb8/l8ArjUh60HAIxJPIBEPIBEPIBEPIBEPIBEPIBEPIBEPIDkdusB/M3HD598/BVW9uXr55vye04eQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQCIeQHK79QDYv8fnp9Ue++HufrXHZl3iwel0WjcQS/xdkdkfty1sFo5LjDDGoxGPgxtpUY401iMQD4YiIPshHgc26kIcddyzEY+DsgC5lngwJPHbnngckIXHEsSDYYngtsQDSMTjYGbbrWd7PiMRDyARjwOZdZee9XntnXgAiXgchN2ZpYkHUxDH9yceQCIeB3CUXfkoz3MvxANIxGNydmPWIh5MRSzfj3hMzEJiTb49fVB/CoNvGOc9iceA3jpR/Pj50SPy+Pz0yxwI7TrctnBIj89PbuuuJB6TsjBe/GsezFMnHkxJFNYnHkAiHhOy674wD+sSjwF5p2A55rITj0E93N278NmUz3kM7veAOKr/neAuRzyYmlisx23LRJw6XjMn6xEPIBGPSdhh32Zu1iEeE7A4/s0cLU88BmdRsBXxGJhwXMZ/0i5LPDgcAVmGeAzKAriO+bueeACJeACJeAzIkXsZ5vE64gEk4gEk4jEYR+1lmc9OPIBEPIBEPAbiiL0O89qIB5CIB5CIB5zcuhTiMQgXN3sjHkAiHkAiHkAiHkAiHvCdF6UvIx5AIh5AIh4DcJxmj8QDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMRjAA9391sPAV4RD/hOpC8jHkAiHkAiHkAiHoNwP87eiAeQiAecnOwK8QAS8RiI3ZE9EY/BCMjyzGkjHgN6uLt3wS/EPHa3Ww+A7ucL//H5acORjEk4riMek3hrIYjKrwRjOeIxubJYZgqOWKxHPHjFguN/eMEUSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSMQDSG7O5/PWYwAG5OQBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJOIBJN8ANEq7NH8OpbAAAAAASUVORK5CYII=\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_img(y[0]);" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" } }, "nbformat": 4, "nbformat_minor": 2 }