{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"from IPython.core.display import HTML\nHTML(\"\"\"\n<style>\n.output_png {\n    display: table-cell;\n    text-align: center;\n    vertical-align: middle;\n    horizontal-align: middle;\n}\nh1 {\n    text-align: center;\n    background-color: blue;\n    padding: 20px;\n    margin: 0;\n    color: white;\n    font-family: ariel;\n    border-radius: 80px\n}\n\nh2,h3{\n    text-align: center;\n    background-color: white;\n    border-style: solid;\n    border-width: 3px;\n    padding: 12px;\n    margin: 0;\n    color: black;\n    font-family: ariel;\n    border-radius: 80px;\n    border-color: gold;\n}\n\nbody, p {\n    font-size: 15px;\n    color: charcoal;\n}\ndiv {\n    font-size: 14px;\n    margin: 0;\n\n}\n\nh4 {\n    padding: 0px;\n    margin: 0;\n    font-family: ariel;\n    color: purple;\n}\nli\n{\n    font-size: 15px;\n    color: charcoal;\n}\n</style>\n\"\"\")","metadata":{"_kg_hide-input":true,"jupyter":{"source_hidden":true},"execution":{"iopub.status.busy":"2022-09-28T13:03:43.925559Z","iopub.execute_input":"2022-09-28T13:03:43.926377Z","iopub.status.idle":"2022-09-28T13:03:43.964302Z","shell.execute_reply.started":"2022-09-28T13:03:43.926102Z","shell.execute_reply":"2022-09-28T13:03:43.962236Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h1 align = \"center\"> 🌈 Image Colorization with Conditional GAN 🎭 </h1>","metadata":{}},{"cell_type":"markdown","source":"## 🧠 Introduction","metadata":{}},{"cell_type":"markdown","source":"<p>Here, in this notebook, I have tried to implement the famous <b>pix2pix</b> research paper for the <b>Image colorization</b> task with <b>additional pretraining</b> to the Generator in terms of replacing it's backbone with a resnet pretrained on ImageNet followed by additional pretraining for colorization in a supervised manner using L1 loss. This pretraining has been done to deal with the fact that we will be using a much <b>smaller dataset</b> than the original paper.\n\npix2pix, proposed a general solution to many image-to-image tasks in deep learning which one of those was colorization. In this approach two losses are used: L1 loss, which makes it a regression task, and an adversarial (GAN) loss, which helps to solve the problem in an unsupervised manner.</p>\n\n**Loss Function to be optimized**\n\n$G^*=\\arg \\min _G \\max _D \\mathcal{L}_{c G A N}(G, D)+\\lambda \\mathcal{L}_{L 1}(G)$\n\n**L1 loss** \n\n$\\mathcal{L}_{L 1}(G)=\\mathbb{E}_{x, y, z}\\left[\\|y-G(x, z)\\|_1\\right]$\n\n**GAN Loss**\n\n$\\begin{aligned} \\mathcal{L}_{c G A N}(G, D)=& \\mathbb{E}_{x, y}[\\log D(x, y)]+\\\\ & \\mathbb{E}_{x, z}[\\log (1-D(x, G(x, z))]\\end{aligned}$\n\n* x -> grayscale image (the condition introduced)\n* y -> 2 channel output of generator\n* z -> input noise of generator\n* G -> Generator Model\n* D -> Discriminator Model\n\n---","metadata":{}},{"cell_type":"markdown","source":"<h1 align = \"center\"> 📚 Theory </h1>\n\n## 💡 Basics of GANs\n\n<p>2 types of models involved, <b>a generative model and a discriminative model</b></p>\n\n* The generative model tries to find the joint probability P(X,Y) or P(X) when there are no labels where X is the set of data instances and Y is the set of labels. Then the joint probability can be used to find P(Y|X) or P(X|Y).\n* The discriminative model tries to find the conditional probability P(Y|X) directly.\n\n<p>Discriminative models try to draw boundaries in the data space, while generative models try to model how data is placed throughout the space.</p>\n\n\n## 👨‍🏭 Basic Working of GANs\n\n<p>Both the generator and the discriminator are neural networks. The generator output is connected directly to the discriminator input. Through backpropagation, the discriminator's classification provides a signal that the generator uses to update its weights.\n\nA generative adversarial network (GAN) has two parts:</p>\n\n* The generator learns to generate plausible data. The generated instances become negative training examples for the discriminator.\n* The discriminator learns to distinguish the generator's fake data from real data. The discriminator penalizes the generator for producing implausible results.\n\n## ✔ The Discriminator\n\n<p>The discriminator in a GAN is simply a classifier. It tries to distinguish real data from the data created by the generator. It could use any network architecture appropriate to the type of data it's classifying.</p> \n\n![](https://developers.google.com/static/machine-learning/gan/images/gan_diagram_discriminator.svg)\n\n### Training process for the Discriminator\n\n* The Training data for the discriminator include Real data (positive examples) and Fake data (negative examples generated by the generator). \n\n* During discriminator training the generator does not train. Its weights remain constant while it produces examples for the discriminator to train on. The discriminator connects to two loss functions. During discriminator training, the discriminator ignores the generator loss and just uses the discriminator loss.\n\n1. The discriminator classifies both real data and fake data from the generator.\n2. The discriminator loss penalizes the discriminator for misclassifying a real instance as fake or a fake instance as real.\n3. The discriminator updates its weights through backpropagation from the discriminator loss through the discriminator network.\n\n## ⚗ The Generator\n\n<p>The generator part of a GAN learns to create fake data by incorporating feedback from the discriminator. It learns to make the discriminator classify its output as real.</p>\n\n![](https://developers.google.com/static/machine-learning/gan/images/gan_diagram_generator.svg)\n\nThe generator training includes:\n* Random input noise to the generator.\n* The generator network that generates the new data instances.\n* The discriminator network the classifies the generator output.\n* The generator loss that penalizes the generator for failing to fool the generator.\n\n\nThe Steps involved are:\n1. Sample Random Noise \n2. Produce generaator output from the sampled random noise\n3. Get the discriminator classification for the generator output\n4. Calculate loss from discriminator output.\n5. Backpropogate through both discriminator and generator and obtain the gradients, only updating the generator weights.\n\n## GAN Training\n\n<p>The GAN has to juggle the training of 2 networks and the convergence is hard to identify.\n\nThe training proceeds in the following manner:</p>\n1. The discriminator trains for one or more epochs\n2. The generator trains for one or more epochs\n3. Repeat steps 1 and 2\n\n## 📉 Loss Functions\n\n<p>GANs try to replicate a probability distribution. They should therefore use loss functions that reflect the distance between the distribution of the data generated by the GAN and the distribution of the real data.</p>\n\n### Minimax Loss\n\nIn the paper that introduced GANs, the generator tries to minimize the following function while the discriminator tries to maximize it:\n\n$\\begin{aligned} \\mathcal{L}_{G A N}(G, D)=& \\mathbb{E}_{x}[\\log D(x)]+\\\\ & \\mathbb{E}_{z}[\\log (1-D(G(z))]\\end{aligned}$\n\nIn this function:\n\n* D(x) is the discriminator's estimate of the probability that real data instance x is real.\n* Ex is the expected value over all real data instances.\n* G(z) is the generator's output when given noise z.\n* D(G(z)) is the discriminator's estimate of the probability that a fake instance is real.\n* Ez is the expected value over all random inputs to the generator (in effect, the expected value over all generated fake instances G(z)).\n\nThe original GAN paper notes that the above minimax loss function can cause the GAN to get stuck in the early stages of GAN training when the discriminator's job is very easy. The paper therefore suggests modifying the generator loss so that the generator tries to maximize log D(G(z)). (**Modified Minimax Loss**)\n\nThere are other loss functions too like the **Wasserstein Loss**.\n\n## 🥼 LAB color space\n\nLAB is a color space just like RGB but here the 3 dimensions represent Lightness(L), Green-Redness (a) and Yellow-blueness (b) of each pixel\n\nThe main advantages of using this color space over RGB for the Image Colorization task are:\n* Here, the L channel can straight away be used as the grayscale input of the image.\n* The model only needs to output 2 channels.\n* But if you use RGB, you have to first convert your image to grayscale, feed the grayscale image to the model and hope it will predict 3 numbers for you which is a way more difficult and unstable task due to the many more possible combinations of 3 numbers compared to two numbers.\n\n---","metadata":{"_uuid":"051d70d956493feee0c6d64651c6a088724dca2a","_execution_state":"idle"}},{"cell_type":"markdown","source":"# 📃 Config Class","metadata":{}},{"cell_type":"code","source":"class Config:\n    external_data_size = 10000\n    train_size = 8000\n    image_size_1 = 256\n    image_size_2 = 256\n    batch_size = 32\n    LeakyReLU_slope = 0.2\n    dropout = 0.5\n    kernel_size = 4\n    stride = 2\n    padding = 1\n    gen_lr = 2e-4\n    disc_lr = 2e-4\n    beta1 = 0.5\n    beta2 = 0.999\n    lambda_l1 = 100\n    gan_mode = 'vanilla'\n    layers_to_cut = -2\n    epochs = 20\n    pretrain_lr = 1e-4","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h1>📦 Importing Packages</h1>","metadata":{}},{"cell_type":"code","source":"!pip install --upgrade torch torchvision","metadata":{"_kg_hide-output":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nfrom pathlib import Path\nimport glob\nimport time\nimport numpy as np\nimport matplotlib.pyplot as plt\n%matplotlib inline\nfrom tqdm import tqdm\n\nimport PIL\nfrom PIL import Image\nfrom skimage.color import rgb2lab, lab2rgb\n\nimport torch\nfrom torch import nn, optim\nfrom torchvision import transforms\nfrom torchvision.models.resnet import resnet18\nfrom torchvision.models.vgg import vgg19\nfrom torch.utils.data import Dataset, DataLoader\n\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")","metadata":{"_kg_hide-output":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## FastAI imports + Loading in the Data\n\nThe data is a small sample of the COCO dataset for object detection and is loaded in through the external data functionality of fastai. The actual paper uses the entire ImageNet dataset while we only use 8000 training images.","metadata":{}},{"cell_type":"code","source":"!pip install fastai==2.4\nfrom fastai.vision.learner import create_body\nfrom fastai.vision.models.unet import DynamicUnet\nfrom fastai.data.external import untar_data, URLs\n\npath = untar_data(URLs.COCO_SAMPLE)\npath = str(path) + \"/train_sample\"\npaths = glob.glob(path + \"/*.jpg\")","metadata":{"_kg_hide-output":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Train test split\nnp.random.seed(42)\npaths_subset = np.random.choice(paths, Config.external_data_size, replace=False) # choosing 10000 images randomly\nrandom_idxs = np.random.permutation(Config.external_data_size) \ntrain_idxs = random_idxs[:Config.train_size] # choosing the first 8000 as training set\nval_idxs = random_idxs[Config.train_size:] # choosing last 2000 as validation set\ntrain_paths = paths_subset[train_idxs]\nval_paths = paths_subset[val_idxs]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Taking a look at the training dataset\n_, axes = plt.subplots(4, 4, figsize=(10, 10))\nfor ax, img_path in zip(axes.flatten(), train_paths):\n    ax.imshow(Image.open(img_path))\n    ax.axis(\"off\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class ImageDataset(Dataset):\n    ''' \n    \n    Class that deals with the Data Loading and preprocessing steps such as image resizing, data augmentation (horizontal flip) \n    and conversion of RGB image to LAB color space with standardization.\n    \n    '''\n    \n    def __init__(self,paths,train = True):\n        if train == True:\n            self.transforms = transforms.Compose([transforms.Resize((Config.image_size_1,Config.image_size_2)),\n                                                 transforms.RandomHorizontalFlip()]) # Basic Data Augmentation\n        elif train == False:\n            self.transforms = transforms.Compose([transforms.Resize((Config.image_size_1,Config.image_size_2))])\n            \n        self.train = train\n        self.paths = paths\n        \n    def __len__(self):\n        return len(self.paths)\n    \n    def __getitem__(self,idx):\n        img = Image.open(self.paths[idx]).convert(\"RGB\")\n        img = self.transforms(img)\n        img = np.array(img)\n        lab = rgb2lab(img).astype(\"float32\")\n        lab = transforms.ToTensor()(lab)\n        L = lab[[0],...]/50 - 1 # Standardizing L space\n        ab = lab[[1,2],...]/128 # Standardizing ab space\n        \n        return {'L': L,\n                'ab': ab}","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"batch_size = Config.batch_size\n\n#train dataset\ntrain_data = ImageDataset(paths = train_paths, train=True)\n# validation dataset\nvalid_data = ImageDataset(paths = val_paths, train=False)\n# train data loader\ntrain_loader = DataLoader(train_data, batch_size=batch_size,shuffle=True,pin_memory = True)\n# validation data loader\nvalid_loader = DataLoader(valid_data, batch_size=batch_size,shuffle=False,pin_memory = True)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 🧰 Utility Functions\n\n","metadata":{}},{"cell_type":"code","source":"# Credits: https://github.com/junyanz/pytorch-CycleGAN-and-pix2pix\n\nclass AverageMeter:\n    '''\n    \n    Computes and stores the average and current value for the various losses involved.\n    \n    '''\n    \n    def __init__(self):\n        self.reset()\n        \n    def reset(self):\n        self.count, self.avg, self.sum = [0.] * 3\n    \n    def update(self, val, count=1):\n        self.count += count\n        self.sum += count * val\n        self.avg = self.sum / self.count\n\ndef create_loss_meters():\n    disc_loss_gen = AverageMeter()\n    disc_loss_real = AverageMeter()\n    disc_loss = AverageMeter()\n    loss_G_GAN = AverageMeter()\n    loss_G_L1 = AverageMeter()\n    loss_G = AverageMeter()\n    \n    return {'disc_loss_gen': disc_loss_gen,\n            'disc_loss_real': disc_loss_real,\n            'disc_loss': disc_loss,\n            'loss_G_GAN': loss_G_GAN,\n            'loss_G_L1': loss_G_L1,\n            'loss_G': loss_G}\n\ndef update_losses(model, loss_meter_dict, count):\n    for loss_name, loss_meter in loss_meter_dict.items():\n        loss = getattr(model, loss_name)\n        loss_meter.update(loss.item(), count=count)\n        \n\n\ndef lab_to_rgb(L, ab):\n    \"\"\"\n    \n    Takes a batch of images and converts from LAB space to RGB\n    \n    \"\"\"\n    \n    L = (L + 1.) * 50\n    ab = ab * 128\n    Lab = torch.cat([L, ab], dim=1).permute(0, 2, 3, 1).cpu().numpy()\n    rgb_imgs = []\n    for img in Lab:\n        img_rgb = lab2rgb(img)\n        rgb_imgs.append(img_rgb)\n    return np.stack(rgb_imgs, axis=0)\n    \ndef visualize(model, data, save=True):\n    '''\n    \n    Function which helps visualize and see the difference between the input image (grayscale), generated image \n    and the Real image.\n    \n    '''\n    \n    model.generator.eval()\n    with torch.no_grad():\n        model.prepare_input(data)\n        model.forward()\n#     model.generator.train()\n    fake_color = model.gen_output.detach()\n    real_color = model.ab\n    L = model.L\n    fake_imgs = lab_to_rgb(L, fake_color)\n    real_imgs = lab_to_rgb(L, real_color)\n    fig = plt.figure(figsize=(15, 8))\n    for i in range(5):\n        ax = plt.subplot(3, 5, i + 1)\n        ax.imshow(L[i][0].cpu(), cmap='gray')\n        ax.axis(\"off\")\n        ax = plt.subplot(3, 5, i + 1 + 5)\n        ax.imshow(fake_imgs[i])\n        ax.axis(\"off\")\n        ax = plt.subplot(3, 5, i + 1 + 10)\n        ax.imshow(real_imgs[i])\n        ax.axis(\"off\")\n    plt.show()\n    if save:\n        fig.savefig(f\"colorization_{time.time()}.png\")\n        \ndef log_results(loss_meter_dict):\n    for loss_name, loss_meter in loss_meter_dict.items():\n        print(f\"{loss_name}: {loss_meter.avg:.5f}\")\n        \n\nclass GANLoss(nn.Module):\n    '''\n    \n    Class that defines the GAN loss.\n    \n    '''\n    \n    def __init__(self, gan_mode='vanilla', real_label=1.0, fake_label=0.0):\n        super().__init__()\n        self.register_buffer('real_label', torch.tensor(real_label))\n        self.register_buffer('fake_label', torch.tensor(fake_label))\n        if gan_mode == 'vanilla':\n            self.loss = nn.BCEWithLogitsLoss()\n        elif gan_mode == 'lsgan':\n            self.loss = nn.MSELoss()\n    \n    def get_labels(self, preds, target_is_real):\n        if target_is_real:\n            labels = self.real_label\n        else:\n            labels = self.fake_label\n        return labels.expand_as(preds)\n    \n    def __call__(self, preds, target_is_real):\n        labels = self.get_labels(preds, target_is_real)\n        loss = self.loss(preds, labels)\n        return loss","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h1 align = 'center'> 🖼 The Generator</h1>\n\n<p>This code implements a U-Net to be used as the generator of our GAN. The code is designed in a manner where we first build the middle part of the U-Net and then build the downsampling and upsampling modules around it. In our Final Modified implementation of this paper we use a resnet as the backbone of our generator in the downsampling module.</p>","metadata":{}},{"cell_type":"markdown","source":"![unet.png](attachment:e94dc1be-b691-4f41-be74-d5c8a94ae308.png)","metadata":{},"attachments":{"e94dc1be-b691-4f41-be74-d5c8a94ae308.png":{"image/png":"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7lDeL+HJDsErVFfNvbXzzjvPmw4CLHt3ycZokbC4Jt9+++311lvPy3pxXcnvuecezXIx4aUKCzdPKAmpgQDDAqPr4x133KG+y+qrr66r/FFHHaU7n/J9EfHVRGi8rq4u/ELDbLvtthMmTAiFK/ClyndT3Xe33357LaJLpAqHa58olo0b707YKeV4aMaMGXP22WeH98SM7lWHHXbYa6+9Vio0byWliTJGjRqVs98Ah9ScADd5HDocHXCfnNqcxj0SKBb578svv3zIIYf4n9UDq6222uDBg/2cyrh8+IBH7v4O8P8EeOH/HWDVUWhZIjQTDV19YvTo0WeeeWboiJtll11WV7N33nnHZULh8BVoBLg9uBY++uijlVcu/R1g3UTUKKZOnVr4KzrF4aRJkyYXkWjpRqMr4W9+8xvdZVzedOnSZcCAAY888oiFSiW1oFaeyBPghfx3gCdOnPjNb37Tm95ggw3GjRunrZfX14wZMyR+N998cygW2HLLLW+99VaVmT59usqrWrXsX//611Xz9REs4bCbfAX6i8Ih+WLoHPPqq68efvjhodUb1cigQYPCH36rKeGCLHT90VVXAdhg1cl55plnPEtlVNKFQ3mhHA11Rv34xz8uxv4/evbsqQu7iy0Q5euHdECAYcHQ9fSSSy6p+KiDrqf+13pfrTR03/Guu+7ydVZXN3dNDjzwwOLVrNnLTeGCV7zA6crYuXPnNdZY443iJw18HRctLBsL4Qhop4TGvctCl3UdtC222KJ4XP/H9ttv/9BDD6mwyvg4GC9VQYJPgH08a02x3gqVNbvs73KV5hV7P+eee+66667r8IxaysEHH+y3HkShzsrO4fwK8P8+grWQBdiVUqineTXlceECulLdcsstm266qY98QD3X8ifVKu/mJngC3CG4CiTA4Z/2dtlllwkTJkhi1XaETMlmpcugtPb+++//9re/7ZKBDTfc8Kqrrqqvr1fNqrCX0lBrRoBrgSoo/B3gXr16yZF0Q/G/UygMtabnnntu//33d5eg/Pm8Ws2IESNmzZql+lVNibwKsGJ22DoPMyLADql4tyl1xsTEiRPVLvzUNKBe1kEHHRTuULXGgXlEww8//NCfnbcAK5jLL788FHP8Lik86fGLLrpo6aWXDguanXfeOexs9XhbpQlICQQYFgxdKJdaailfboLWSlP9YWdfSnzNmjlzZt++fUNJjxx55JEuFi5k5Sjfv2vV/VXmpvL+WZpX6EXacIHLFNoR7YJ3J4x71ssvv7zffvtVvDe75ppr/va3vw3fzQ4LekQ4vxz1llL4CvQX8gTYqNY84nyd6g888MDWW29dfjMW3/rWt+677z715r2sllJ3UCPhHTMEuEb4OBu3FOer873XXntVPP3o2bPnlVdeaYkSobyX1QgC3CH4YJYLsG4QdXV1foQrO9JlX0Kl69Urr7zy4x//2I+GAiussMKJJ5742muvqXKlFrblsKBWjgDXAt16ttlmG296gw020KTqS+iiJ78966yzgs0aackBBxzw7LPPynt1N1fV+B8pcvwEWDE77KwJsPCkKmLIkCHbb799xR1qiy22uOuuu3yHEqF87QhRhZGBAwc6GP9+Yd999/XlNxQIV29PaqjL9RJLLKHCau+hyYsW/oZwCxS3U/MdhwyCAMMCoCtR+LttupIKf89z3XXXdffRlxJfsKQE/nGdrlDhsnvEEUcU19SKx5566qkqvPPOO+vGqcmwWqERl4ka7Ui5+qoXqE52xd+JUU/isMMOe/PNN10moGXVBfSyTR4NBLhGaCvqSej4e+hMxaDOergfO7bVVlvt3HPPLf9nCw21iNGkcxDgWqBjq4OsOtJIaCmjR48+44wzVlxxRR9w8+Uvf1ld8HfLvjtaXkEacSYC3CG4IsoF2K9AS2KDU73//vty1/B7V9OtW7d+/foNHTpUTiVDVkndF4QW1H1HWiW0cgS4Fnz88cdbbrmlN73eeuupvtQuVIm///3vG7+ppJybb75ZVaNqkvFqRJXlCirW2CQEeKERjuRbb711+OGHV7y1pzuU2rvq0WV0nfS/6oalaoc24UurO4E6tzfaaCOFJAFWR7F79+7Dhg0rFixcjTUsD0mdmYsuusgfe/cTYOHupXYwLLhAaP3lm4B0QIBhAdC9apdddglXnDBy9NFH64ani0i4gKqn4j+It8MOO2y33Xah5B577OEbXgtXnNtuu22ppZZSJ8l6o5Lqy3pk4Vyga035jui4qScR3jEL6D76wAMP+AYgbFxapALPrUB3FF6BrgWuAt22fedW7+GCCy4Iv3L3Gb744ourh/ryyy97ERGWanwaI8A1Qoc3qK+uRU2+89y3b99HH33U5YXbmhfRUPXlcYEAdwg+nuUCrKuchEqeIDWSI91///077rijZ4VbjDrHl1122cSJE3Xj0KXMxuvyRhqsSa0cAa4Fqq8gwJtsssmECRP+8pe/HHzwwc4JrLHG6qeffvro0aNnzpwp6fWTeTlw+BcK5yDAC5OKO5Rbh+zxgAMO0O2mVKisd+H72kJA2yq/3kpcw4fxhM638IcSylGxffbZRwWWW265H//4x+Fdbu+XTip/LXVBKVRehGcdtB8EGBYA3av2339/XWv8b3XFi0/hR1kVVytdT8844wwVUN9Fd+5777039LHKpaVJZIO6uqm8NFiTvjD56hyGxYIRo12wC6nfpt6Mn6IHdLu66KKLwj/NurDuTN59o3wNmzsUCHCN0FbsRULn/LbbbutIAttss4068eoCurwqKNSaK8sjHhcIcC0IR1uoS6TOekUTU8/p8ssvV2/VZUL/L9ROGHEBBLhD0FHVsFyA+/XrpwpqaGiQ3x577LHhkY5Zfvnl/c6zGp1cQvpUblNC109rFQJcO1Rf3/rWt7zpDTbY4JJLLql451kN/MADD3z++eenT5/++efTVSOupuKwVEH6z/9mgQAvNNRwwj8nBTbffPP77rtvRvGLLUF3HXy4tTmzdngrvsCGGIYOHRpeWxO9evU67bTTHnrooaeffnrIkCG//e1v99xzT/86TMV0simz4sdiAwYMaNsBdzylCUgJBBgWAF0mrr/+el9u5LfLLrusevAvvvhiaXYRlVHnUgXWXHPNZ599VjnygfC9PnVQ1KdxSVF+3dHNY+DAgd26ddMN9corr/SscH3MGbr0awelpnvvvbePjFhmmWUOPfTQ8K8JKuCDUDFuKibL4SvQNaJYCSW5eu+990KXVKy++urlX9F0PB6WU5GTYwEe9IU+ARY+1NOmTZNl+SALNbGjjz46/KwgVJNHTMWk4CvQHYKPqoQqfAW6X/8BdePGN3z2+bRpDUf+9Chnii5du/XfdbdHH31s6rRPZ86crZOq9COISTIpnWOF8clTCiMaFkemat0IcC34+OOPwwtKm2yy8SWXXOpxs9nmW9z++zsmfDRx9py5U6c1uI5C7ajWJk+Z9smkya4ypc8+m54/ARYOO1MC/P777+u24mBEjx49dB0bM2aM56pnJcqP9kI78qGiFYBvpmb06NHqAfbs2TOYrZrz4osvHl7eVhMYPHiwd+E3v/mNctQLNRpXTpt3YaHtO2QKBBgWjPHjx4cO5b777vvKK6+E5126k/3rX/867rjjNGu55ZYr/6Sqrlmhr7/EEkucd955dXV1njV79uy33nrr3nvv9R89WmmllfzsV+T1qqT90nV/VvFLSDqA3bt3147vsMMODz74oG4JLtMeeAJcI7QVV5A3d+ONNyoM3Z6///3vl7/zXD0IcIfjxuUR5zz77LP+db36po8//nh5l6tKeALcIbhGygW4/667j//oY50t0z+f+dbb736t1wbK3GDDjS+7/MqPJn4ya/bcaZ9+VnF2NZe0bgS4FkiAw9836rPJJqNGjd73u9/T+Gqrr/nLX5393shRn02f+elnn1dUR3MplwKsmB12pgRY/P73v1ckckjdoV566SVn2ns7pKfRBnygNNR1WEN1/zQUnivGjh37pz/96ec//3nfvn233HLLrbfeescddzzqqKPuueee0GmcPHly6IWqyRtd2z13QakIANIBAYYF5s0339xvv/38HYINNthAGnzqqaeefvrpujGvsMIKytxkk03+8Ic/uLCuLO5xqt+ji1r4xzzdU0844YSBAwcedthha665pjP32Wcf3R29oJbygvlD++V/+/TItddeqx62+hlhbhi2DQS4RoST2ZubOHHiWWeddcMNN3iyUJ1lX3iuBl6B7nBUF64OjwiNn3feeRdddJG6TcUi/ytTJQhwh+BjPr8A7/bh2HGy3I8/mfxpw/Tbbr/jqKOPfePNt2fMnK1TSJkaVpxdzSWtGwGuBeVPgDfcYIOpU6cNe/zJnx51jIaqJtVd9f9IoYQAL0ymTJlyxhlnqF2U/ypHQ0WrkRD2wsQb1datvrZxB+PYquHFF1+s+LnEhhtu2La/ACwKAUV41kH7QYChLeimddddd33/+9+XhJSuQEXkw4MHDw5XonC19fVFl7whQ4aceOKJKlZaoMi66657+OGH33PPPf5pistrWeEF84d2TUfD94BSVnHHNfRea+jMNqDeEl+BrgXeSnk1FbNLaFKoTkvTVYAA1wJXhEZUR25HHpqQWT0IcIfgSpEA9+hREuCdd+lXN268Tnu5rs4cqdTUaQ2fTZ9RfG92SvX2q6R1I8C1QAK89dZbe9O9e/caP378pw3TGz77XEO/8+y6qzIhwAuHxocx/Ju7Z2m4oJfBjqJ8uw4mRFWIr0jj+JUTygwaNEhHuFPxz3D6/eeTTjrJ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"}}},{"cell_type":"code","source":"# Code help for model architecture and training loop: https://github.com/junyanz/pytorch-CycleGAN-and-pix2pix\n\nclass UnetBlock(nn.Module):\n    '''\n    \n    Class that helps define the various different types of blocks used in the Generator architecture\n    \n    '''\n    \n    def __init__(self, nf, ni, submodule=None, input_channels=None, dropout=False,innermost=False, outermost=False):\n        super().__init__()\n        self.outermost = outermost\n        if input_channels is None: \n            input_channels = nf\n        downconv = nn.Conv2d(input_channels, ni, kernel_size=Config.kernel_size, stride=Config.stride, padding=Config.padding, bias=False)\n        downrelu = nn.LeakyReLU(Config.LeakyReLU_slope, True)\n        downnorm = nn.BatchNorm2d(ni)\n        uprelu = nn.ReLU(True)\n        upnorm = nn.BatchNorm2d(nf)\n        \n        if outermost:\n            upconv = nn.ConvTranspose2d(ni * 2, nf,kernel_size=Config.kernel_size, stride=Config.stride, padding=Config.padding)\n            down = [downconv]\n            up = [uprelu, upconv, nn.Tanh()]\n            model = down + [submodule] + up\n        elif innermost:\n            upconv = nn.ConvTranspose2d(ni, nf, kernel_size=Config.kernel_size, stride=Config.stride, padding=Config.padding, bias=False)\n            down = [downrelu, downconv]\n            up = [uprelu, upconv, upnorm]\n            model = down + up\n        else:\n            upconv = nn.ConvTranspose2d(ni * 2, nf, kernel_size=Config.kernel_size, stride=Config.stride, padding=Config.padding, bias=False)\n            down = [downrelu, downconv, downnorm]\n            up = [uprelu, upconv, upnorm]\n            if dropout: up += [nn.Dropout(Config.dropout)]\n            model = down + [submodule] + up\n        self.model = nn.Sequential(*model)\n    \n    def forward(self, x):\n        if self.outermost:\n            return self.model(x)\n        else:\n            return torch.cat([x, self.model(x)], 1)\n\nclass Unet(nn.Module):\n    '''\n    \n    The Generator Model Class\n    \n    '''\n    \n    def __init__(self, input_channels=1, output_channels=2, n_down=8, num_filters=64):\n        super().__init__()\n        unet_block = UnetBlock(num_filters * 8, num_filters * 8, innermost=True)\n        for _ in range(n_down - 5):\n            unet_block = UnetBlock(num_filters * 8, num_filters * 8, submodule=unet_block, dropout=True)\n        out_filters = num_filters * 8\n        for _ in range(3):\n            unet_block = UnetBlock(out_filters // 2, out_filters, submodule=unet_block)\n            out_filters //= 2\n        self.model = UnetBlock(output_channels, out_filters, input_channels=input_channels, submodule=unet_block, outermost=True)\n    \n    def forward(self, x):\n        return self.model(x)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h1 align = 'center'> 🎭 The Discriminator</h1>\n\n<p>The discriminator being used here is working on small patches of the images instead of the image as a whole. This code implements a model by stacking blocks of Conv-BatchNorm-LeackyReLU to decide whether the input image is fake or real. </p>","metadata":{}},{"cell_type":"code","source":"class Discriminator(nn.Module):\n    '''\n    \n    The Discriminator Model Class\n    \n    '''\n    \n    def __init__(self,input_channels,num_filters=64, n_down=3):\n        super().__init__()\n        model = [self.get_layers(input_channels,num_filters,norm = False)]\n        model += [self.get_layers(num_filters * 2 ** i, num_filters * 2 ** (i + 1), stride=1 if i == (n_down-1) else 2) for i in range(n_down)]\n        model += [self.get_layers(num_filters * 2 ** n_down, 1, stride=1, norm=False, activation=False)] \n        self.model = nn.Sequential(*model)\n    \n    def get_layers(self, ni, nf, kernel_size=Config.kernel_size, stride=Config.stride, padding=Config.padding, norm=True, activation=True): \n        layers = [nn.Conv2d(ni, nf, kernel_size, stride, padding, bias=not norm)]          \n        if norm: \n            layers += [nn.BatchNorm2d(nf)]\n        if activation:\n            layers += [nn.LeakyReLU(Config.LeakyReLU_slope, True)]\n        return nn.Sequential(*layers)\n    \n    def forward(self, x):\n        return self.model(x)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Normal Weight Initialization with mean = 0, std = 0.02\n\ndef init_weights(net, init='norm', gain=0.02):\n    \n    def init_func(m):\n        classname = m.__class__.__name__\n        if hasattr(m, 'weight') and 'Conv' in classname:\n            if init == 'norm':\n                nn.init.normal_(m.weight.data, mean=0.0, std=gain)\n            elif init == 'xavier':\n                nn.init.xavier_normal_(m.weight.data, gain=gain)\n            elif init == 'kaiming':\n                nn.init.kaiming_normal_(m.weight.data, a=0, mode='fan_in')\n            \n            if hasattr(m, 'bias') and m.bias is not None:\n                nn.init.constant_(m.bias.data, 0.0)\n        elif 'BatchNorm2d' in classname:\n            nn.init.normal_(m.weight.data, 1., gain)\n            nn.init.constant_(m.bias.data, 0.)\n            \n    net.apply(init_func)\n    print(f\"model initialized with {init} initialization\")\n    return net\n\ndef init_model(model, device):\n    model = model.to(device)\n    model = init_weights(model)\n    return model","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h1 align = \"center\"> 🎨 The Main Model </h1>\n\n<p>This is where it all comes together. First we have the functions that help us apply our modifications to this research paper. Next comes the Main Model class. First, we train the discriminator where we feed it the generated images from the generator as well as the real images and take the average of these 2 losses and apply backpropagation. Coming next to the training of the Generator model, we feed the discriminator model the fake generated images and try to fool it, and then we compute the adversarial loss. We also calculate the L1 loss which computes the distance between the predicted two channels and the target two channels and multiply this loss by a coefficient (which is 100 in our case) to balance the two losses and then add this loss to the adversarial loss. Then we call the backward method of the loss.</p>","metadata":{}},{"cell_type":"code","source":"def build_backbone_unet(input_channels=1, output_channels=2, size=Config.image_size_1):\n    '''\n    \n    Function that helps build the generator backbone using another pretrained model trained on imagenet for image classification\n    \n    '''\n    \n    device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n    body = create_body(resnet18, pretrained=True, n_in=input_channels, cut=Config.layers_to_cut)\n    generator = DynamicUnet(body, output_channels, (size, size)).to(device)\n    return generator\n\ndef pretrain_generator(generator, train_dl, opt, criterion, epochs):\n    '''\n    \n    Function to pretrain the generator in a supervised manner on the colorization task using L1 Loss.\n    \n    '''\n    \n    for e in range(epochs):\n        loss_meter = AverageMeter()\n        for data in tqdm(train_dl):\n            L, ab = data['L'].to(device), data['ab'].to(device)\n            preds = generator(L)\n            loss = criterion(preds, ab)\n            opt.zero_grad()\n            loss.backward()\n            opt.step()\n            \n            loss_meter.update(loss.item(), L.size(0))\n            \n        print(f\"Epoch {e + 1}/{epochs}\")\n        print(f\"L1 Loss: {loss_meter.avg:.5f}\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class MainModel(nn.Module):\n    '''\n    \n    The Class where it all comes together.\n    \n    '''\n    \n    def __init__(self,generator = None,gen_lr =Config.gen_lr,disc_lr = Config.disc_lr, beta1 = Config.beta1,beta2 = Config.beta2, lambda_l1 = Config.lambda_l1):\n        super().__init__()\n        self.device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n        self.lambda_l1 = lambda_l1\n        \n        if generator is None:\n            self.generator = init_model(Unet(input_channels=1, output_channels=2, n_down=8, num_filters=64),self.device)\n        else:\n            self.generator = generator.to(self.device)\n        self.discriminator = init_model(Discriminator(input_channels = 3,num_filters = 64,n_down = 3),self.device)\n        self.GANloss = GANLoss(gan_mode=Config.gan_mode).to(self.device)\n        self.L1loss = nn.L1Loss()\n        self.gen_optim = optim.Adam(self.generator.parameters(), lr=gen_lr, betas=(beta1, beta2))\n        self.disc_optim= optim.Adam(self.discriminator.parameters(), lr=disc_lr, betas=(beta1, beta2))\n        \n    def requires_grad(self,model,requires_grad = True):\n        for p in model.parameters():\n            p.requires_grad = requires_grad\n            \n    def prepare_input(self,data):\n        self.L = data['L'].to(self.device)\n        self.ab = data['ab'].to(self.device)\n        \n    def forward(self):\n        self.gen_output = self.generator(self.L)\n        \n    def disc_backward(self):\n        gen_image = torch.cat([self.L, self.gen_output], dim=1)\n        gen_image_preds = self.discriminator(gen_image.detach())\n        self.disc_loss_gen = self.GANloss(gen_image_preds, False)\n        real_image = torch.cat([self.L, self.ab], dim=1)\n        real_preds = self.discriminator(real_image)\n        self.disc_loss_real = self.GANloss(real_preds, True)\n        self.disc_loss = (self.disc_loss_gen + self.disc_loss_real) * 0.5\n        self.disc_loss.backward()\n    \n    def gen_backward(self):\n        gen_image = torch.cat([self.L, self.gen_output], dim=1)\n        gen_image_preds = self.discriminator(gen_image)\n        self.loss_G_GAN = self.GANloss(gen_image_preds, True)\n        self.loss_G_L1 = self.L1loss(self.gen_output, self.ab) * self.lambda_l1\n        self.loss_G = self.loss_G_GAN + self.loss_G_L1\n        self.loss_G.backward()\n    \n    def optimize(self):\n        self.forward()\n        self.discriminator.train()\n        self.requires_grad(self.discriminator, True)\n        self.disc_optim.zero_grad()\n        self.disc_backward()\n        self.disc_optim.step()\n        \n        self.generator.train()\n        self.requires_grad(self.discriminator, False) \n        self.gen_optim.zero_grad()\n        self.gen_backward()\n        self.gen_optim.step()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h1> 🚂 Training Function</h1>","metadata":{}},{"cell_type":"code","source":"def train_model(model, train_loader, epochs, display=100):\n    data = next(iter(train_loader)) \n    for epoch in range(epochs):\n        loss_meter_dict = create_loss_meters() \n        i=0\n        for data in tqdm(train_loader):\n            model.prepare_input(data) \n            model.optimize()\n            update_losses(model, loss_meter_dict, count=data['L'].size(0)) \n            i+=1\n            if i % display == 0:\n                print(f\"\\nEpoch {epoch+1}/{epochs}\")\n                print(f\"Iteration {i}/{len(train_loader)}\")\n                log_results(loss_meter_dict) \n                visualize(model, data, save=False) ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 🔥 Let's Go","metadata":{}},{"cell_type":"code","source":"generator = build_backbone_unet(input_channels=1, output_channels=2, size=Config.image_size_1)\nopt = optim.Adam(generator.parameters(), lr=Config.pretrain_lr)\nloss = nn.L1Loss()        \npretrain_generator(generator, train_loader, opt, loss, Config.epochs)\ntorch.save(generator.state_dict(), \"res18-unet.pt\")\ngenerator.load_state_dict(torch.load(\"res18-unet.pt\", map_location=device))\nmodel = MainModel(generator=generator)\ntrain_model(model, train_loader, Config.epochs)\ntorch.save(model.state_dict(), \"main-model.pt\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 🧪 Model Inference","metadata":{}},{"cell_type":"code","source":"path = \"Path to Image\"\nimg = PIL.Image.open(path)\nimg = img.resize((256, 256))\nimg = transforms.ToTensor()(img)[:1] * 2. - 1.\nmodel.eval()\nwith torch.no_grad():\n    preds = model.generator(img.unsqueeze(0).to(device))\n    gen_output = lab_to_rgb(img.unsqueeze(0), preds.cpu())[0]\nplt.imshow(img)\nplt.imshow(gen_output)","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}