{"cells":[{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":false},"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport torch\nimport torch.nn as nn\nimport torch.nn.parallel\nimport torch.optim as optim\nimport torch.utils.data\nimport torchvision\nimport torchvision.datasets as dset\nimport torchvision.transforms as transforms\nfrom torchvision.utils import save_image\nfrom torch.autograd import Variable\nfrom scipy.stats import truncnorm\nimport xml.etree.ElementTree as ET\nimport random\nimport numpy as np\nimport pandas as pd\nfrom tqdm import tqdm_notebook as tqdm\nimport os\nprint(os.listdir(\"../input\"))","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"# seed_everything\ndef seed_everything(seed=42):\n    random.seed(seed)\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.backends.cudnn.deterministic = True\nseed_everything()","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"# Setting some hyperparameters\nbatchSize = 48 # We set the size of the batch\nimageSize = 64 # We set the size of the generated images (64x64)\nnz = 128\nreal_label = 0.5\nfake_label = 0\nslope=0.2","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"print('Number of images: ', len(os.listdir('../input/all-dogs/all-dogs')))","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"black_list=[] # images we don't use for trainning. Not used.","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"class FullCroppedDogsFolderDataset(torchvision.datasets.vision.VisionDataset):\n    def __init__(self, root, transform=None, target_transform=None):\n        super().__init__(root, transform=transform, target_transform=target_transform)\n        self.transform = transform\n        self.target_transform = target_transform\n        \n        self.samples = self._load_subfolders_images(self.root)\n        if len(self.samples) == 0:\n            raise RuntimeError(\"Found 0 files in subfolders of: {}\".format(self.root))\n            \n    def _load_subfolders_images(self, root):\n        IMG_EXTENSIONS = ('.jpg', '.jpeg', '.png', '.ppm', '.bmp', '.pgm', '.tif', '.tiff', '.webp')\n\n        def is_valid_file(x):\n            return torchvision.datasets.folder.has_file_allowed_extension(x, IMG_EXTENSIONS)\n\n        required_transforms = torchvision.transforms.Compose([\n            torchvision.transforms.Resize(64),\n            torchvision.transforms.CenterCrop(64),\n        ])\n\n        imgs = []\n\n        paths = []\n        for root, _, fnames in sorted(os.walk(root)):\n            for fname in sorted(fnames):\n                path = os.path.join(root, fname)\n                paths.append(path)\n\n        pbar = tqdm(paths, desc='Loading cropped images')\n\n        for path in pbar:\n            file = path.split('/')[-1]\n            if is_valid_file(path) and file not in black_list:\n                # Load image\n                img = torchvision.datasets.folder.default_loader(path)\n\n                # Get bounding boxes\n                annotation_basename = os.path.splitext(os.path.basename(path))[0]\n                annotation_dirname = next(dirname for dirname in os.listdir('../input/annotation/Annotation/') if dirname.startswith(annotation_basename.split('_')[0]))\n                annotation_filename = os.path.join('../input/annotation/Annotation', annotation_dirname, annotation_basename)\n                tree = ET.parse(annotation_filename)\n                root = tree.getroot()\n                objects = root.findall('object')\n                max_dogs_per_image = 1\n                \n                if len(objects) <= max_dogs_per_image:\n                    for o in objects:\n                        bndbox = o.find('bndbox')\n                        xmin = int(bndbox.find('xmin').text)\n                        ymin = int(bndbox.find('ymin').text)\n                        xmax = int(bndbox.find('xmax').text)\n                        ymax = int(bndbox.find('ymax').text)\n\n                        w = xmax - xmin\n                        h = ymax - ymin\n                        if h > w:\n                            diff = h - w\n                            xmin = xmin - diff/2\n                            xmax = xmax + diff/2\n                            xmax = min(xmax,img.width)\n                            xmin = max(xmin,0)\n                        if w > h:\n                            diff = w - h\n                            ymin = ymin - diff/2\n                            ymax = ymax + diff/2\n                            ymax = min(ymax,img.height)\n                            ymin = max(ymin,0)\n\n                        bbox = (xmin, ymin, xmax, ymax)\n\n                        object_img = required_transforms(img.crop(bbox))\n                        imgs.append(object_img)\n                \n                pbar.set_postfix_str(\"{} cropped images loaded\".format(len(imgs)))\n\n        return imgs\n    \n    def __getitem__(self, index):\n        sample = self.samples[index]\n        target = 1\n        \n        if self.transform is not None:\n            sample = self.transform(sample)\n        if self.target_transform is not None:\n            target = self.target_transform(target)\n\n        return sample, target\n\n    def __len__(self):\n        return len(self.samples)","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"# Creating the transformations\nrandom_transforms = [transforms.RandomRotation(degrees=5)]\ntransform = transforms.Compose([transforms.Resize(imageSize), transforms.CenterCrop(imageSize), transforms.RandomHorizontalFlip(p=0.5),\n                                transforms.RandomApply(random_transforms, p=0.5), transforms.ToTensor(),\n                                transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])\n\n# Loading the dataset\nload_cropped = True\nif load_cropped:\n    dataset = FullCroppedDogsFolderDataset(root='../input/all-dogs/', transform=transform)\nelse:\n    dataset = dset.ImageFolder(root='../input/all-dogs/', transform=transform)\ndataloader = torch.utils.data.DataLoader(dataset, batch_size = batchSize, shuffle = True, num_workers = 4) # We use dataLoader to get the images of the training set batch by batch.","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"print('Number of images: ', len(dataset))","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"# Visualize some dogs. The images are dark due to the normalize. At the end we will unnormalize.\nn = 10\naxes = plt.subplots(figsize=(4*n, 4*n), ncols=n, nrows=n)[1]\nfor i, ax in enumerate(axes.flatten()):\n    ax.imshow(dataset[i][0].permute(1, 2, 0).detach().numpy()) # without permute the shape is (3, 64, 64). With permute (64, 64, 3)\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"# Decide which device we want to run on\ndevice = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\nprint(device)","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"# Defining the weights_init function that takes as input a neural network m and that will initialize all its weights.\ndef weights_init(m):\n    classname = m.__class__.__name__\n    if classname.find('Conv') != -1:\n        m.weight.data.normal_(0.0, 0.02)\n    elif classname.find('BatchNorm') != -1:\n        m.weight.data.normal_(1.0, 0.02)\n        m.bias.data.fill_(0)","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"# Defining the generator\nclass G(nn.Module): # We introduce a class to define the generator.\n\n    def __init__(self, nz=128, channels=3): # We introduce the __init__() function that will define the architecture of the generator.\n        super(G, self).__init__() # We inherit from the nn.Module tools.\n        \n        self.nz = nz\n        self.channels = channels\n        \n        self.main = nn.Sequential( # We create a meta module of a neural network that will contain a sequence of modules (convolutions, full connections, etc.).\n            nn.ConvTranspose2d(self.nz, 1024, 4, 1, 0, bias = False), # We start with an inversed convolution.\n            #Arguments: size of input of vector, number of features maps of output, size of kernel 4 by 4, stride, padding\n            nn.BatchNorm2d(1024), # We normalize all the features along the dimension of the batch.\n            nn.ReLU(True), # We apply a ReLU rectification to break the linearity.\n            \n            nn.ConvTranspose2d(1024, 512, 4, 2, 1, bias = False), # We add another inversed convolution.\n            nn.BatchNorm2d(512),\n            nn.ReLU(True),\n            nn.ConvTranspose2d(512, 256, 4, 2, 1, bias = False),\n            nn.BatchNorm2d(256),\n            nn.ReLU(True),\n            nn.ConvTranspose2d(256, 128, 4, 2, 1, bias = False),\n            nn.BatchNorm2d(128),\n            nn.ReLU(True),\n            nn.ConvTranspose2d(128, 64, 4, 2, 1, bias = False),\n            nn.BatchNorm2d(64),\n            nn.ReLU(True),\n            nn.ConvTranspose2d(64, self.channels, 3, 1, 1, bias = False),\n            nn.Tanh() # We apply a Tanh rectification to break the linearity and stay between -1 and +1.\n        )\n\n    def forward(self, input): # We define the forward function that takes as argument an input that will be fed to the neural network with randon noise, and that will return the output containing the generated images.\n        output = self.main(input) # We forward propagate the signal through the whole neural network of the generator defined by self.main.\n        return output # We return the output containing the generated images.","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"# Creating the generator\nnetG = G(nz).to(device) # We create the generator object.\nnetG.apply(weights_init) # We initialize all the weights of its neural network.","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"# Defining the discriminator\nclass D(nn.Module): # We introduce a class to define the discriminator.\n\n    def __init__(self, channels=3): # We introduce the __init__() function that will define the architecture of the discriminator.\n        super(D, self).__init__() # We inherit from the nn.Module tools.\n        \n        self.channels = channels\n        \n        self.main = nn.Sequential( # We create a meta module of a neural network that will contain a sequence of modules (convolutions, full connections, etc.).\n            nn.Conv2d(self.channels, 64, 4, 2, 1, bias = False), # We start with a convolution. 3 channels is the output of the generator. 64 feature maps. kernel: 4 x 4, stride: 2 and padding: 1\n            nn.LeakyReLU(slope, inplace = True), # We apply a LeakyReLU.\n            nn.Conv2d(64, 128, 4, 2, 1, bias = False), # We add another convolution.\n            nn.BatchNorm2d(128), # We normalize all the features along the dimension of the batch.\n            nn.LeakyReLU(slope, inplace = True),\n            nn.Conv2d(128, 256, 4, 2, 1, bias = False),\n            nn.BatchNorm2d(256),\n            nn.LeakyReLU(slope, inplace = True),\n            nn.Conv2d(256, 512, 4, 2, 1, bias = False),\n            nn.BatchNorm2d(512),\n            nn.LeakyReLU(slope, inplace = True),\n            nn.Conv2d(512, 1, 4, 1, 0, bias = False), # We add another convolution. the final output is 1\n            nn.Sigmoid() # We apply a Sigmoid rectification to break the linearity and stay between 0 and 1.\n        )\n\n    def forward(self, input): # We define the forward function that takes as argument an input that will be fed to the neural network, and that will return the output which will be a value between 0 and 1.\n        output = self.main(input) # We forward propagate the signal through the whole neural network of the discriminator defined by self.main.\n        return output.view(-1) # We return the output which will be a value between 0 and 1. view(-1) is to flatten the result","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"# Creating the discriminator\nnetD = D().to(device) # We create the discriminator object.\nnetD.apply(weights_init) # We initialize all the weights of its neural network.","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"%%time\n# Training the DCGANs\nn_epochs = 286\ncriterion = nn.BCELoss() # We create a criterion object that will measure the error between the prediction and the target. BCE means Binary Cross Entropy\noptimizerD = optim.Adam(netD.parameters(), lr = 0.0003, betas = (0.5, 0.999)) # We create the optimizer object of the discriminator.\noptimizerG = optim.Adam(netG.parameters(), lr = 0.0003, betas = (0.5, 0.999)) # We create the optimizer object of the generator.\n\nlr_schedulerD = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizerD, factor=0.9, patience=37, min_lr=0.0002) # learning rate decay\nlr_schedulerG = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizerG, factor=0.9, patience=37, min_lr=0.0002) # learning rate decay\n\nG_losses = [] # list to record the loss of the generator\nD_losses = [] # list to record the loss of the discriminator\n\nfor epoch in tqdm(range(n_epochs)): # We iterate over the epochs.\n\n    for i, data in enumerate(dataloader, 0): # We iterate over the images of the dataset.\n        \n        D_losses_epoch = 0\n        G_losses_epoch = 0\n        \n        # 1st Step: Updating the weights of the neural network of the discriminator\n        netD.zero_grad() # We initialize to 0 the gradients of the discriminator with respect to the weights.\n        \n        # Training the discriminator with a real image of the dataset\n        input = data[0].to(device) # We get a real image of the dataset which will be used to train the discriminator. data is the mini batch, it has the images and labels\n        \n        batch_size = input.size(0)\n        target = torch.full((batch_size, 1), real_label, device=device)\n        output = netD(input) # We forward propagate this real image into the neural network of the discriminator to get the prediction (a value between 0 and 1).\n        errD_real = criterion(output, target) # We compute the loss between the predictions (output) and the target.\n        \n        # Training the discriminator with a fake image generated by the generator\n        noise = Variable(torch.randn(batch_size, nz, 1, 1, device=device)) # We make a random input vector (noise) of the generator.\n        target = torch.full((batch_size, 1), fake_label, device=device)\n        fake = netG(noise) # We forward propagate this random input vector into the neural network of the generator to get some fake generated images.        \n        output = netD(fake.detach()) # We forward propagate the fake generated images into the neural network of the discriminator to get the prediction.\n        errD_fake = criterion(output, target) # We compute the loss between the prediction (output) and the target.\n        \n        # Backpropagating the total error\n        errD = errD_real + errD_fake # We compute the total error of the discriminator.\n        errD.backward() # We backpropagate the loss error by computing the gradients of the total error with respect to the weights of the discriminator.\n        optimizerD.step() # We apply the optimizer to update the weights according to how much they are responsible for the loss error of the discriminator.\n        D_losses_epoch += errD.item()\n        \n        # 2nd Step: Updating the weights of the neural network of the generator\n        netG.zero_grad() # We initialize to 0 the gradients of the generator with respect to the weights.\n        target = torch.full((batch_size, 1), real_label, device=device)\n        output = netD(fake) # We forward propagate the fake generated images into the neural network of the discriminator to get the prediction (a value between 0 and 1).\n        errG = criterion(output, target) # We compute the loss between the prediction (output between 0 and 1) and the target.\n        errG.backward() # We backpropagate the loss error by computing the gradients of the total error with respect to the weights of the generator.\n        optimizerG.step() # We apply the optimizer to update the weights according to how much they are responsible for the loss error of the generator.\n        G_losses_epoch += errG.item()\n        \n        # Saving losses for plotting later\n        D_losses.append(errD.item())\n        G_losses.append(errG.item())\n        \n    lr_schedulerD.step(D_losses_epoch)\n    lr_schedulerG.step(G_losses_epoch)\n    \n    if epoch % 37 == 0: # code to print the current learning rate\n        for param_group in optimizerD.param_groups:\n            print('epoch', epoch, 'lr D:', param_group['lr'])\n        for param_group in optimizerG.param_groups:\n            print('epoch', epoch, 'lr G:', param_group['lr'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"# Plotting the losses\nplt.figure(figsize=(10,5))\nplt.title(\"Generator and Discriminator Loss During Training\")\nplt.plot(G_losses,label=\"G\")\nplt.plot(D_losses,label=\"D\")\nplt.xlabel(\"iterations\")\nplt.ylabel(\"Loss\")\nplt.legend()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"def truncated_normal(size, threshold=1):\n    values = truncnorm.rvs(-threshold, threshold, size=size)\n    return values","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"# Creating 10000 images\nif not os.path.exists('../output_images'):\n    os.mkdir('../output_images')\nim_batch_size = 50\nn_images=10000\n\nfor i_batch in range(0, n_images, im_batch_size):\n        \n    # Images generation without truncnorm\n    #noise = Variable(torch.randn(im_batch_size, nz, 1, 1, device=device))\n    #gen_images = netG(noise)\n    \n    # Images generation with truncnorm\n    z = truncated_normal((im_batch_size, nz, 1, 1), threshold=1)\n    gen_z = torch.from_numpy(z).float().to(device)\n    gen_images = netG(gen_z)\n    \n    gen_images.mul_(0.5).add_(0.5) # unnormalize\n    images = gen_images.to('cpu').clone().detach()\n    images = images.numpy().transpose(0, 2, 3, 1)\n    \n    for i_image in range(gen_images.size(0)):\n        save_image(gen_images[i_image, :, :, :], os.path.join('../output_images', f'image_{i_batch+i_image:05d}.png'))\n# Zip folder\nimport shutil\nshutil.make_archive('images', 'zip', '../output_images')","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"# Displaing 32 images\nfig = plt.figure(figsize=(25, 16))\nfor i, j in enumerate(images[:32]):\n    ax = fig.add_subplot(4, 8, i + 1, xticks=[], yticks=[])\n    plt.imshow(j)","execution_count":null,"outputs":[]},{"metadata":{"trusted":false},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.6.6"},"widgets":{"application/vnd.jupyter.widget-state+json":{"state":{"0c21cc096d6942f4954aac2e7277130c":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"161bae5de837432ba0f4e3801a99bdfe":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_a12b0b6e379644899effe233bb6d8d1a","IPY_MODEL_8f23297cf7ba4139b3e64a20e3d0bb95"],"layout":"IPY_MODEL_33aabff4b95d49ab89fd97ed2dce2132"}},"1b471a37fe604494bdcf10ef31acf3e5":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_54e9b27b52b642139a2d5a8e0618b551","placeholder":"​","style":"IPY_MODEL_a56a403ae8c9479fb26c7832db2981f8","value":"100% 286/286 [2:28:23&lt;00:00, 31.12s/it]"}},"33aabff4b95d49ab89fd97ed2dce2132":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"3ad4479c236f4624aed3bb62ff86d6aa":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HBoxModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HBoxView","box_style":"","children":["IPY_MODEL_4a5e160640fb4d20a587a054ed501126","IPY_MODEL_1b471a37fe604494bdcf10ef31acf3e5"],"layout":"IPY_MODEL_0c21cc096d6942f4954aac2e7277130c"}},"494d289016de49c5a8a4aa4d8411630e":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"4a5e160640fb4d20a587a054ed501126":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"IntProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"IntProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ProgressView","bar_style":"success","description":"","description_tooltip":null,"layout":"IPY_MODEL_c94ca2735b574372adfd8f85f217ac6f","max":286,"min":0,"orientation":"horizontal","style":"IPY_MODEL_bc30c2e0f9304d3a82f2e40c85d88368","value":286}},"54e9b27b52b642139a2d5a8e0618b551":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"641ea527e15843d595cc5c8ea9333386":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","bar_color":null,"description_width":"initial"}},"8f23297cf7ba4139b3e64a20e3d0bb95":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"HTMLModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_494d289016de49c5a8a4aa4d8411630e","placeholder":"​","style":"IPY_MODEL_a41f87fcc6004d5688858dd724c088f8","value":" 30% 6099/20579 [00:43&lt;01:35, 151.30it/s, 5669 cropped images loaded]"}},"a12b0b6e379644899effe233bb6d8d1a":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"IntProgressModel","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"IntProgressModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ProgressView","bar_style":"","description":"Loading cropped images","description_tooltip":null,"layout":"IPY_MODEL_dbb2bd7562eb48cea8a81364f0f55285","max":20579,"min":0,"orientation":"horizontal","style":"IPY_MODEL_641ea527e15843d595cc5c8ea9333386","value":6099}},"a41f87fcc6004d5688858dd724c088f8":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"a56a403ae8c9479fb26c7832db2981f8":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"DescriptionStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"bc30c2e0f9304d3a82f2e40c85d88368":{"model_module":"@jupyter-widgets/controls","model_module_version":"1.5.0","model_name":"ProgressStyleModel","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ProgressStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","bar_color":null,"description_width":""}},"c94ca2735b574372adfd8f85f217ac6f":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"dbb2bd7562eb48cea8a81364f0f55285":{"model_module":"@jupyter-widgets/base","model_module_version":"1.2.0","model_name":"LayoutModel","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}}},"version_major":2,"version_minor":0}}},"nbformat":4,"nbformat_minor":1}