{ "cells": [ { "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(3)" ] }, { "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'\n", "MASKS_DN = 'train_masks_png'\n", "sz = 128\n", "bs = 64\n", "nw = 16" ] }, { "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": [ "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": [ { "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', tensor(9408))])),\n", " ('Conv2d-2',\n", " OrderedDict([('input_shape', [-1, 3, 128, 128]),\n", " ('output_shape', [-1, 64, 64, 64]),\n", " ('trainable', False),\n", " ('nb_params', tensor(9408))])),\n", " ('BatchNorm2d-3',\n", " OrderedDict([('input_shape', [-1, 64, 64, 64]),\n", " ('output_shape', [-1, 64, 64, 64]),\n", " ('trainable', False),\n", " ('nb_params', tensor(128))])),\n", " ('BatchNorm2d-4',\n", " OrderedDict([('input_shape', [-1, 64, 64, 64]),\n", " ('output_shape', [-1, 64, 64, 64]),\n", " ('trainable', False),\n", " ('nb_params', tensor(128))])),\n", " ('ReLU-5',\n", " OrderedDict([('input_shape', [-1, 64, 64, 64]),\n", " ('output_shape', [-1, 64, 64, 64]),\n", " ('nb_params', 0)])),\n", " ('ReLU-6',\n", " OrderedDict([('input_shape', [-1, 64, 64, 64]),\n", " ('output_shape', [-1, 64, 64, 64]),\n", " ('nb_params', 0)])),\n", " ('MaxPool2d-7',\n", " OrderedDict([('input_shape', [-1, 64, 64, 64]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('nb_params', 0)])),\n", " ('MaxPool2d-8',\n", " OrderedDict([('input_shape', [-1, 64, 64, 64]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-9',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', tensor(36864))])),\n", " ('Conv2d-10',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', tensor(36864))])),\n", " ('BatchNorm2d-11',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', tensor(128))])),\n", " ('BatchNorm2d-12',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', tensor(128))])),\n", " ('ReLU-13',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('nb_params', 0)])),\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', tensor(36864))])),\n", " ('Conv2d-16',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', tensor(36864))])),\n", " ('BatchNorm2d-17',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', tensor(128))])),\n", " ('BatchNorm2d-18',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', tensor(128))])),\n", " ('ReLU-19',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('nb_params', 0)])),\n", " ('ReLU-20',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-21',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-22',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-23',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', tensor(36864))])),\n", " ('Conv2d-24',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', tensor(36864))])),\n", " ('BatchNorm2d-25',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', tensor(128))])),\n", " ('BatchNorm2d-26',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', tensor(128))])),\n", " ('ReLU-27',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('nb_params', 0)])),\n", " ('ReLU-28',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-29',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', tensor(36864))])),\n", " ('Conv2d-30',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', tensor(36864))])),\n", " ('BatchNorm2d-31',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', tensor(128))])),\n", " ('BatchNorm2d-32',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', tensor(128))])),\n", " ('ReLU-33',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('nb_params', 0)])),\n", " ('ReLU-34',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-35',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-36',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-37',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', tensor(36864))])),\n", " ('Conv2d-38',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', tensor(36864))])),\n", " ('BatchNorm2d-39',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', tensor(128))])),\n", " ('BatchNorm2d-40',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', tensor(128))])),\n", " ('ReLU-41',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('nb_params', 0)])),\n", " ('ReLU-42',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-43',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', tensor(36864))])),\n", " ('Conv2d-44',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', tensor(36864))])),\n", " ('BatchNorm2d-45',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', tensor(128))])),\n", " ('BatchNorm2d-46',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('trainable', False),\n", " ('nb_params', tensor(128))])),\n", " ('ReLU-47',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('nb_params', 0)])),\n", " ('ReLU-48',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-49',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-50',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 64, 32, 32]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-51',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(73728))])),\n", " ('Conv2d-52',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(73728))])),\n", " ('BatchNorm2d-53',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(256))])),\n", " ('BatchNorm2d-54',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(256))])),\n", " ('ReLU-55',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('ReLU-56',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-57',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1.4746e+05))])),\n", " ('Conv2d-58',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1.4746e+05))])),\n", " ('BatchNorm2d-59',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(256))])),\n", " ('BatchNorm2d-60',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(256))])),\n", " ('Conv2d-61',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(8192))])),\n", " ('Conv2d-62',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(8192))])),\n", " ('BatchNorm2d-63',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(256))])),\n", " ('BatchNorm2d-64',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(256))])),\n", " ('ReLU-65',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('ReLU-66',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-67',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-68',\n", " OrderedDict([('input_shape', [-1, 64, 32, 32]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-69',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1.4746e+05))])),\n", " ('Conv2d-70',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1.4746e+05))])),\n", " ('BatchNorm2d-71',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(256))])),\n", " ('BatchNorm2d-72',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(256))])),\n", " ('ReLU-73',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('ReLU-74',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-75',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1.4746e+05))])),\n", " ('Conv2d-76',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1.4746e+05))])),\n", " ('BatchNorm2d-77',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(256))])),\n", " ('BatchNorm2d-78',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(256))])),\n", " ('ReLU-79',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('ReLU-80',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-81',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-82',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-83',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1.4746e+05))])),\n", " ('Conv2d-84',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1.4746e+05))])),\n", " ('BatchNorm2d-85',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(256))])),\n", " ('BatchNorm2d-86',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(256))])),\n", " ('ReLU-87',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('ReLU-88',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-89',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1.4746e+05))])),\n", " ('Conv2d-90',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1.4746e+05))])),\n", " ('BatchNorm2d-91',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(256))])),\n", " ('BatchNorm2d-92',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(256))])),\n", " ('ReLU-93',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('ReLU-94',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-95',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-96',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-97',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1.4746e+05))])),\n", " ('Conv2d-98',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1.4746e+05))])),\n", " ('BatchNorm2d-99',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(256))])),\n", " ('BatchNorm2d-100',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(256))])),\n", " ('ReLU-101',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('ReLU-102',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-103',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1.4746e+05))])),\n", " ('Conv2d-104',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1.4746e+05))])),\n", " ('BatchNorm2d-105',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(256))])),\n", " ('BatchNorm2d-106',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('trainable', False),\n", " ('nb_params', tensor(256))])),\n", " ('ReLU-107',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('ReLU-108',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-109',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-110',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 128, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-111',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(2.9491e+05))])),\n", " ('Conv2d-112',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(2.9491e+05))])),\n", " ('BatchNorm2d-113',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(512))])),\n", " ('BatchNorm2d-114',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(512))])),\n", " ('ReLU-115',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('ReLU-116',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-117',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(5.8982e+05))])),\n", " ('Conv2d-118',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(5.8982e+05))])),\n", " ('BatchNorm2d-119',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(512))])),\n", " ('BatchNorm2d-120',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(512))])),\n", " ('Conv2d-121',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(32768))])),\n", " ('Conv2d-122',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(32768))])),\n", " ('BatchNorm2d-123',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(512))])),\n", " ('BatchNorm2d-124',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(512))])),\n", " ('ReLU-125',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('ReLU-126',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-127',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-128',\n", " OrderedDict([('input_shape', [-1, 128, 16, 16]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-129',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(5.8982e+05))])),\n", " ('Conv2d-130',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(5.8982e+05))])),\n", " ('BatchNorm2d-131',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(512))])),\n", " ('BatchNorm2d-132',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(512))])),\n", " ('ReLU-133',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('ReLU-134',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-135',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(5.8982e+05))])),\n", " ('Conv2d-136',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(5.8982e+05))])),\n", " ('BatchNorm2d-137',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(512))])),\n", " ('BatchNorm2d-138',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(512))])),\n", " ('ReLU-139',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('ReLU-140',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-141',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-142',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-143',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(5.8982e+05))])),\n", " ('Conv2d-144',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(5.8982e+05))])),\n", " ('BatchNorm2d-145',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(512))])),\n", " ('BatchNorm2d-146',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(512))])),\n", " ('ReLU-147',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('ReLU-148',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-149',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(5.8982e+05))])),\n", " ('Conv2d-150',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(5.8982e+05))])),\n", " ('BatchNorm2d-151',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(512))])),\n", " ('BatchNorm2d-152',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(512))])),\n", " ('ReLU-153',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('ReLU-154',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-155',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-156',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-157',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(5.8982e+05))])),\n", " ('Conv2d-158',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(5.8982e+05))])),\n", " ('BatchNorm2d-159',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(512))])),\n", " ('BatchNorm2d-160',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(512))])),\n", " ('ReLU-161',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('ReLU-162',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-163',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(5.8982e+05))])),\n", " ('Conv2d-164',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(5.8982e+05))])),\n", " ('BatchNorm2d-165',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(512))])),\n", " ('BatchNorm2d-166',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(512))])),\n", " ('ReLU-167',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('ReLU-168',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-169',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-170',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-171',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(5.8982e+05))])),\n", " ('Conv2d-172',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(5.8982e+05))])),\n", " ('BatchNorm2d-173',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(512))])),\n", " ('BatchNorm2d-174',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(512))])),\n", " ('ReLU-175',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('ReLU-176',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-177',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(5.8982e+05))])),\n", " ('Conv2d-178',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(5.8982e+05))])),\n", " ('BatchNorm2d-179',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(512))])),\n", " ('BatchNorm2d-180',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(512))])),\n", " ('ReLU-181',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('ReLU-182',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-183',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-184',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-185',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(5.8982e+05))])),\n", " ('Conv2d-186',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(5.8982e+05))])),\n", " ('BatchNorm2d-187',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(512))])),\n", " ('BatchNorm2d-188',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(512))])),\n", " ('ReLU-189',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('ReLU-190',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-191',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(5.8982e+05))])),\n", " ('Conv2d-192',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(5.8982e+05))])),\n", " ('BatchNorm2d-193',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(512))])),\n", " ('BatchNorm2d-194',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', False),\n", " ('nb_params', tensor(512))])),\n", " ('ReLU-195',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('ReLU-196',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-197',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-198',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-199',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1.1796e+06))])),\n", " ('Conv2d-200',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1.1796e+06))])),\n", " ('BatchNorm2d-201',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1024))])),\n", " ('BatchNorm2d-202',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1024))])),\n", " ('ReLU-203',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('nb_params', 0)])),\n", " ('ReLU-204',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-205',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', tensor(2.3593e+06))])),\n", " ('Conv2d-206',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', tensor(2.3593e+06))])),\n", " ('BatchNorm2d-207',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1024))])),\n", " ('BatchNorm2d-208',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1024))])),\n", " ('Conv2d-209',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1.3107e+05))])),\n", " ('Conv2d-210',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1.3107e+05))])),\n", " ('BatchNorm2d-211',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1024))])),\n", " ('BatchNorm2d-212',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1024))])),\n", " ('ReLU-213',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('nb_params', 0)])),\n", " ('ReLU-214',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-215',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-216',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-217',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', tensor(2.3593e+06))])),\n", " ('Conv2d-218',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', tensor(2.3593e+06))])),\n", " ('BatchNorm2d-219',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1024))])),\n", " ('BatchNorm2d-220',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1024))])),\n", " ('ReLU-221',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('nb_params', 0)])),\n", " ('ReLU-222',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-223',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', tensor(2.3593e+06))])),\n", " ('Conv2d-224',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', tensor(2.3593e+06))])),\n", " ('BatchNorm2d-225',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1024))])),\n", " ('BatchNorm2d-226',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1024))])),\n", " ('ReLU-227',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('nb_params', 0)])),\n", " ('ReLU-228',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-229',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-230',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-231',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', tensor(2.3593e+06))])),\n", " ('Conv2d-232',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', tensor(2.3593e+06))])),\n", " ('BatchNorm2d-233',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1024))])),\n", " ('BatchNorm2d-234',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1024))])),\n", " ('ReLU-235',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('nb_params', 0)])),\n", " ('ReLU-236',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('nb_params', 0)])),\n", " ('Conv2d-237',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', tensor(2.3593e+06))])),\n", " ('Conv2d-238',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', tensor(2.3593e+06))])),\n", " ('BatchNorm2d-239',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1024))])),\n", " ('BatchNorm2d-240',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('trainable', False),\n", " ('nb_params', tensor(1024))])),\n", " ('ReLU-241',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('nb_params', 0)])),\n", " ('ReLU-242',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-243',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('nb_params', 0)])),\n", " ('BasicBlock-244',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('nb_params', 0)])),\n", " ('ReLU-245',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 512, 4, 4]),\n", " ('nb_params', 0)])),\n", " ('ConvTranspose2d-246',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', True),\n", " ('nb_params', tensor(5.2454e+05))])),\n", " ('BatchNorm2d-247',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('trainable', True),\n", " ('nb_params', tensor(512))])),\n", " ('StdUpsample-248',\n", " OrderedDict([('input_shape', [-1, 512, 4, 4]),\n", " ('output_shape', [-1, 256, 8, 8]),\n", " ('nb_params', 0)])),\n", " ('ConvTranspose2d-249',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 16, 16]),\n", " ('trainable', True),\n", " ('nb_params', tensor(2.6240e+05))])),\n", " ('BatchNorm2d-250',\n", " OrderedDict([('input_shape', [-1, 256, 16, 16]),\n", " ('output_shape', [-1, 256, 16, 16]),\n", " ('trainable', True),\n", " ('nb_params', tensor(512))])),\n", " ('StdUpsample-251',\n", " OrderedDict([('input_shape', [-1, 256, 8, 8]),\n", " ('output_shape', [-1, 256, 16, 16]),\n", " ('nb_params', 0)])),\n", " ('ConvTranspose2d-252',\n", " OrderedDict([('input_shape', [-1, 256, 16, 16]),\n", " ('output_shape', [-1, 256, 32, 32]),\n", " ('trainable', True),\n", " ('nb_params', tensor(2.6240e+05))])),\n", " ('BatchNorm2d-253',\n", " OrderedDict([('input_shape', [-1, 256, 32, 32]),\n", " ('output_shape', [-1, 256, 32, 32]),\n", " ('trainable', True),\n", " ('nb_params', tensor(512))])),\n", " ('StdUpsample-254',\n", " OrderedDict([('input_shape', [-1, 256, 16, 16]),\n", " ('output_shape', [-1, 256, 32, 32]),\n", " ('nb_params', 0)])),\n", " ('ConvTranspose2d-255',\n", " OrderedDict([('input_shape', [-1, 256, 32, 32]),\n", " ('output_shape', [-1, 256, 64, 64]),\n", " ('trainable', True),\n", " ('nb_params', tensor(2.6240e+05))])),\n", " ('BatchNorm2d-256',\n", " OrderedDict([('input_shape', [-1, 256, 64, 64]),\n", " ('output_shape', [-1, 256, 64, 64]),\n", " ('trainable', True),\n", " ('nb_params', tensor(512))])),\n", " ('StdUpsample-257',\n", " OrderedDict([('input_shape', [-1, 256, 32, 32]),\n", " ('output_shape', [-1, 256, 64, 64]),\n", " ('nb_params', 0)])),\n", " ('ConvTranspose2d-258',\n", " OrderedDict([('input_shape', [-1, 256, 64, 64]),\n", " ('output_shape', [-1, 1, 128, 128]),\n", " ('trainable', True),\n", " ('nb_params', tensor(1025))]))])" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "learn.summary()" ] }, { "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 = UnetBlock(256,3,16)\n", " self.up6 = nn.ConvTranspose2d(16, 1, 1)\n", " \n", " def forward(self,x):\n", " inp = 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, inp)\n", " x = self.up6(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()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "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": [ "[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": "e780adff2688489c9489dd8e03f9bb51", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(IntProgress(value=0, description='Epoch', max=1), HTML(value='')))" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ " 9%|▉ | 6/64 [00:05<00:50, 1.14it/s, loss=0.669]\n", " 91%|█████████ | 58/64 [00:13<00:01, 4.39it/s, loss=1.57] " ] }, { "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", "\n", "lrs = np.array([lr/200,lr/20,lr])/2" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "36115a7f3cf8435bb659daed3ae54a6c", "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.142851 0.038569 0.988547 0.971717 \n", " 1 0.101173 0.03713 0.988605 0.975992 \n", " 2 0.08908 0.039838 0.986759 0.972326 \n", " 3 0.081489 0.029241 0.992063 0.979739 \n", " 4 0.079016 0.028968 0.991646 0.97719 \n", " 5 0.076655 0.023804 0.992451 0.982042 \n", " 6 0.07636 0.024756 0.992738 0.983401 \n", " 7 0.07495 0.028137 0.993225 0.983095 \n", "\n" ] }, { "data": { "text/plain": [ "[0.028136500290461948, 0.993224613250248, 0.9830952419175042]" ] }, "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": "55d3f172690042b3a9e2d04bbc9fe760", "version_major": 2, "version_minor": 0 }, "text/plain": [ "HBox(children=(IntProgress(value=0, description='Epoch', max=10), HTML(value='')))" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "epoch trn_loss val_loss dice \n", " 0 0.074118 0.020005 0.993274 0.983666 \n", " 1 0.073695 0.021194 0.993121 0.984339 \n", " 2 0.073121 0.024444 0.993327 0.984351 \n", " 3 0.071765 0.021549 0.993588 0.984733 \n", " 4 0.072239 0.019336 0.993528 0.985078 \n", " 5 0.071364 0.01934 0.993351 0.985128 \n", " 6 0.071399 0.018902 0.993654 0.985341 \n", " 7 0.071632 0.020567 0.993527 0.985378 \n", " 8 0.070797 0.019375 0.993866 0.985641 \n", " 9 0.070172 0.019292 0.993802 0.985716 \n", "\n" ] }, { "data": { "text/plain": [ "[0.019291689264632407, 0.9938022683537195, 0.9857159994897389]" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "learn.fit(lrs/2, 1, wds=wd, cycle_len=10,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/UCwAABAVJREFUeJzt3dlNGwEARdEBUQVV0EREBakyFaA0QRWUEfMRWcllkT3eZjvnOx8jK77zZgHudrvdALB3P/UBAPMiCkCIAhCiAIQoACEKQIgCEKIAhCgA8TD1AQzDMPy4/+m1Sriy339+3R3z7ywFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgHqY+AG7v5e116kP41vPj09SHsHmWAhCWwkbMeR38b3+cFsN0LAUgRIFZenl7Xcy6WRtRWLmlf7mWfOxLJQpAiAIQogCER5Ir5VqcU1kKQIgCs7f0JyhLIwoshjjchigA4UbjyjiTci5LAQhRYHGsoesShRXxZeESRAEIUQBCFIAQBRbJi0zX4z2FFfDl4JIsBSAshRmzAA475jPym6HHsRSAEAVWz+IaRxSAEAUgRAEIUQDCI8kZ++pRmptm43kkOY6lAISlsDD7s57F8JlFcBmisDBiwLW5fABCFFgNP059GaIAhHsKC+EMyK1YCkCIAqvj3sJ5RAEIUQBCFBbAFOaWRAEIjyRnzEI4z/7z8zMR41gKQIgCEKLA6rkMG0cUgHCjcYac2ZiSpcAmePX5eKIAhMuHGXEmYw4sBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAU2xevOh3mjkU3xW5gOsxSAEAU2xeXDYaIAhCgAIQpAiAIQogCEKAAhCkCIAhCiAIQoACEKQIgCEKIAhCgAIQpAiAIQogCEKAAhCkCIAhCiAIQoACEKQIgCEKIAhCgAIQpAiAIQogCEKADxMPUB8M/z49MwDIM/lX5F+8+Y71kKQIgCEKIAhCgAIQpAiAIQHknO0MfHZh5Rns+jyOOJwgIc+x9aPP76+L6HIIzj8gEIS2FFvjojrmE9nHqmtxBOYykAYSms3Clny2PWxSVWiTP5PIkCn5jr2+byAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEA4m632019DMCMWApAiAIQogCEKAAhCkCIAhCiAIQoACEKQIgCEKIAhCgAIQpAiAIQogCEKAAhCkCIAhCiAIQoACEKQIgCEKIAxDsxF5DyKVUZEwAAAABJRU5ErkJggg==\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/UCwAAA/xJREFUeJzt3NFN22AARlGDmIIpWKJigk7ZCaIukSkYo+lLo/a2UHBI4t/OOc88WJZy/dkOuTscDhPA0f3SBwCMRRSAEAUgRAEIUQBCFIAQBSBEAQhRAOJh6QOYpmn6cv/V1yrhwr7/+Hb3kb+zFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgHhY+gC4nt3LfulDeNPz49PSh8AvlgIQlsKNGHklTNO/x2c5LMdSAEIUGNLuZT/8utkqtw8b54PFXJYCEKLA0Cyd6xMFIDxT2ChXWE5lKQAhCgzP68nrcvuwMT48fJalAIQosBpuI65DFIAQBSBEYUNMa85BFIAQBVbHIrosUQDCl5c2wJWTcxKFFXjtQ+83DLkUtw9AWAoD+99twe5lf9Nr4XhujufgvVuoWz5Xc1kKQFgKK+YBI5dgKQBhKbBq1tL5WQpAiAIQbh8G9tprNHN5Pq8j57EUgLAUVuajX9a5NdbA+VgKK+N3Cl/nnJyPKAAhCkCIAhAeNK6Ee+b3/f2fk5zGUgBCFFbASpjHG5rPEQU2SxxOIwpAeNA4MFc5lmApACEKbJ7FNY8oACEKQHjQOCBzlyVZCkCIAjfBF5k+ThSAEAUgPGgciHnLCCwFIESBm+KB4/tEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBiIelD4Dfnh+fpmmapt3LfuEj2a7jOeZtlgIQogCEKAAhCkCIAhCiMKDnxydPyVmMV5ID+zMMXlOeTmDnsRSAsBRW4tSr3S0uDMvgcywFICyFjXPVZC5LAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAuDscDksfAzAQSwEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSAEAUgRAEIUQBCFIAQBSBEAQhRAEIUgBAFIEQBCFEAQhSA+AnTkYdhcXKRmgAAAABJRU5ErkJggg==\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": [ "TRAIN_DN = 'train'\n", "MASKS_DN = 'train_masks_png'" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sz=512\n", "bs=8" ] }, { "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": [ "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": [ "lr=2e-2\n", "wd=1e-7\n", "\n", "lrs = np.array([lr/200,lr/20,lr])/2" ] }, { "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": "4578d3f60dcc4d2cafd7c62582ab19f3", "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.072306 0.024262 0.995649 0.990836 \n", " 1 0.070101 0.018257 0.996652 0.992687 \n", " 2 0.068719 0.013143 0.996877 0.992726 \n", " 3 0.067462 0.01673 0.997156 0.993161 \n", " 4 0.069176 0.010519 0.997248 0.993573 \n", "\n" ] }, { "data": { "text/plain": [ "[0.010519474116523587, 0.9972476694318984, 0.9935726703159393]" ] }, "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": "8d12dfb5b6fd499092869025343e105e", "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.066793 0.009628 0.997183 0.993656 \n", " 1 0.064545 0.010879 0.997386 0.993893 \n", " 2 0.06125 0.010519 0.997421 0.994018 \n", " 3 0.06288 0.01147 0.997403 0.99407 \n", " 4 0.064336 0.008862 0.997411 0.994132 \n", " 5 0.063767 0.009989 0.997463 0.994194 \n", " 6 0.063922 0.009927 0.997504 0.994277 \n", " 7 0.06392 0.008977 0.997514 0.994242 \n", "\n" ] }, { "data": { "text/plain": [ "[0.00897712022110465, 0.9975136726621597, 0.9942418502436744]" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "learn.fit(lrs/2,1,wds=wd, cycle_len=8,use_clr=(20,8))" ] }, { "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/2,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": "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\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 }