{"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":"markdown","source":"## **Importing Libraries**","metadata":{}},{"cell_type":"markdown","source":"### **System and Utility Library and Extensions**","metadata":{}},{"cell_type":"code","source":"%reload_ext autoreload\n%autoreload 2\n%matplotlib inline","metadata":{"execution":{"iopub.status.busy":"2022-06-07T15:18:06.767709Z","iopub.execute_input":"2022-06-07T15:18:06.768421Z","iopub.status.idle":"2022-06-07T15:18:06.827610Z","shell.execute_reply.started":"2022-06-07T15:18:06.768294Z","shell.execute_reply":"2022-06-07T15:18:06.826718Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport time\nimport itertools\nimport random\nfrom glob import glob\nimport shutil\nfrom tqdm.notebook import tqdm","metadata":{"execution":{"iopub.status.busy":"2022-06-07T15:18:06.829655Z","iopub.execute_input":"2022-06-07T15:18:06.830301Z","iopub.status.idle":"2022-06-07T15:18:06.970718Z","shell.execute_reply.started":"2022-06-07T15:18:06.830259Z","shell.execute_reply":"2022-06-07T15:18:06.969787Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Data Library**","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\n\nimport PIL\nfrom PIL import Image\n\nfrom sklearn.model_selection import GroupKFold\nfrom sklearn.metrics import roc_curve\nfrom sklearn import metrics\n\n","metadata":{"execution":{"iopub.status.busy":"2022-06-07T15:18:06.971958Z","iopub.execute_input":"2022-06-07T15:18:06.972471Z","iopub.status.idle":"2022-06-07T15:18:07.558971Z","shell.execute_reply.started":"2022-06-07T15:18:06.972423Z","shell.execute_reply":"2022-06-07T15:18:07.558119Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Deep Modelling Library**","metadata":{}},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.nn.init as init\nfrom torchvision.utils import make_grid\nfrom torch.utils.data import Dataset, random_split, DataLoader\n\nimport torchvision.models as models\nimport torchvision.transforms as transforms","metadata":{"execution":{"iopub.status.busy":"2022-06-07T15:18:07.560459Z","iopub.execute_input":"2022-06-07T15:18:07.560979Z","iopub.status.idle":"2022-06-07T15:18:08.278473Z","shell.execute_reply.started":"2022-06-07T15:18:07.560938Z","shell.execute_reply":"2022-06-07T15:18:08.277564Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **System Management**","metadata":{}},{"cell_type":"markdown","source":"### **Directory Management**","metadata":{}},{"cell_type":"code","source":"os.makedirs('Saved_Models', exist_ok = True)\nos.makedirs('Results', exist_ok = True)","metadata":{"execution":{"iopub.status.busy":"2022-06-07T15:18:08.281150Z","iopub.execute_input":"2022-06-07T15:18:08.281816Z","iopub.status.idle":"2022-06-07T15:18:08.326276Z","shell.execute_reply.started":"2022-06-07T15:18:08.281774Z","shell.execute_reply":"2022-06-07T15:18:08.325259Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Seed Setting**","metadata":{}},{"cell_type":"code","source":"def set_seed(seed):\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\nset_seed(1003)\n\ndevice = 'cuda' if torch.cuda.is_available() else 'cpu'","metadata":{"execution":{"iopub.status.busy":"2022-06-07T15:18:08.327551Z","iopub.execute_input":"2022-06-07T15:18:08.328705Z","iopub.status.idle":"2022-06-07T15:18:08.427236Z","shell.execute_reply.started":"2022-06-07T15:18:08.328660Z","shell.execute_reply":"2022-06-07T15:18:08.426331Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Data Import**","metadata":{}},{"cell_type":"markdown","source":"### **Image Dataset Class**","metadata":{}},{"cell_type":"code","source":"class ImageDataset(Dataset):\n    def __init__(self, monet_dir, photo_dir, size=(256, 256), normalize=True):\n        super().__init__()\n        self.monet_dir = monet_dir\n        self.photo_dir = photo_dir\n        self.monet_idx = dict()\n        self.photo_idx = dict()\n        if normalize:\n            self.transform = transforms.Compose([\n                transforms.Resize(size),\n                transforms.ToTensor(),\n                transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))                                \n            ])\n        else:\n            self.transform = transforms.Compose([\n                transforms.Resize(size),\n                transforms.ToTensor()                               \n            ])\n        for i, fl in enumerate(os.listdir(self.monet_dir)):\n            self.monet_idx[i] = fl\n        for i, fl in enumerate(os.listdir(self.photo_dir)):\n            self.photo_idx[i] = fl\n\n    def __getitem__(self, idx):\n        rand_idx = int(np.random.uniform(0, len(self.monet_idx.keys())))\n        photo_path = os.path.join(self.photo_dir, self.photo_idx[rand_idx])\n        monet_path = os.path.join(self.monet_dir, self.monet_idx[idx])\n        photo_img = Image.open(photo_path)\n        photo_img = self.transform(photo_img)\n        monet_img = Image.open(monet_path)\n        monet_img = self.transform(monet_img)\n        return photo_img, monet_img\n\n    def __len__(self):\n        return min(len(self.monet_idx.keys()), len(self.photo_idx.keys()))\n\ndata = ImageDataset('../input/gan-getting-started/monet_jpg', '../input/gan-getting-started/photo_jpg')\n","metadata":{"execution":{"iopub.status.busy":"2022-06-07T15:18:08.429260Z","iopub.execute_input":"2022-06-07T15:18:08.429915Z","iopub.status.idle":"2022-06-07T15:18:08.854425Z","shell.execute_reply.started":"2022-06-07T15:18:08.429872Z","shell.execute_reply":"2022-06-07T15:18:08.853479Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class PhotoDataset(Dataset):\n    def __init__(self, photo_dir, size=(256, 256), normalize=True):\n        super().__init__()\n        self.photo_dir = photo_dir\n        self.photo_idx = dict()\n        if normalize:\n            self.transform = transforms.Compose([\n                transforms.Resize(size),\n                transforms.ToTensor(),\n                transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))                                \n            ])\n        else:\n            self.transform = transforms.Compose([\n                transforms.Resize(size),\n                transforms.ToTensor()                               \n            ])\n        for i, fl in enumerate(os.listdir(self.photo_dir)):\n            self.photo_idx[i] = fl\n\n    def __getitem__(self, idx):\n        rand_idx = int(np.random.uniform(0, len(self.photo_idx.keys())))\n        photo_path = os.path.join(self.photo_dir, self.photo_idx[rand_idx])\n        photo_img = Image.open(photo_path)\n        photo_img = self.transform(photo_img)\n        return photo_img\n\n    def __len__(self):\n        return len(self.photo_idx.keys())\n\nphoto_data = PhotoDataset('../input/gan-getting-started/photo_jpg')\n","metadata":{"execution":{"iopub.status.busy":"2022-06-07T15:18:08.855852Z","iopub.execute_input":"2022-06-07T15:18:08.856764Z","iopub.status.idle":"2022-06-07T15:18:08.910568Z","shell.execute_reply.started":"2022-06-07T15:18:08.856719Z","shell.execute_reply":"2022-06-07T15:18:08.909399Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class PaintingDataset(Dataset):\n    def __init__(self, monet_dir, size=(256, 256), normalize=True):\n        super().__init__()\n        self.monet_dir = monet_dir\n        self.monet_idx = dict()\n        if normalize:\n            self.transform = transforms.Compose([\n                transforms.Resize(size),\n                transforms.ToTensor(),\n                transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))                                \n            ])\n        else:\n            self.transform = transforms.Compose([\n                transforms.Resize(size),\n                transforms.ToTensor()                               \n            ])\n        for i, fl in enumerate(os.listdir(self.monet_dir)):\n            self.monet_idx[i] = fl\n    def __getitem__(self, idx):\n        rand_idx = int(np.random.uniform(0, len(self.monet_idx.keys())))\n        monet_path = os.path.join(self.monet_dir, self.monet_idx[idx])\n        monet_img = Image.open(monet_path)\n        monet_img = self.transform(monet_img)\n        return monet_img\n\n    def __len__(self):\n        return len(self.monet_idx.keys())\n\nmonet_data = PaintingDataset('../input/gan-getting-started/monet_jpg')\n","metadata":{"execution":{"iopub.status.busy":"2022-06-07T15:18:08.912495Z","iopub.execute_input":"2022-06-07T15:18:08.913026Z","iopub.status.idle":"2022-06-07T15:18:08.965431Z","shell.execute_reply.started":"2022-06-07T15:18:08.912982Z","shell.execute_reply":"2022-06-07T15:18:08.964396Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Loading Data**","metadata":{}},{"cell_type":"code","source":"def load_data(data):\n    data_loaded = DataLoader(data, batch_size=1, pin_memory=True, shuffle = True)\n    return data_loaded\ndata_loaded = load_data(data)","metadata":{"execution":{"iopub.status.busy":"2022-06-07T15:18:08.969456Z","iopub.execute_input":"2022-06-07T15:18:08.969822Z","iopub.status.idle":"2022-06-07T15:18:09.015269Z","shell.execute_reply.started":"2022-06-07T15:18:08.969792Z","shell.execute_reply":"2022-06-07T15:18:09.014197Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"monet_data_loaded = load_data(monet_data)\nphoto_data_loaded = load_data(photo_data)\n","metadata":{"execution":{"iopub.status.busy":"2022-06-07T15:18:09.020078Z","iopub.execute_input":"2022-06-07T15:18:09.020999Z","iopub.status.idle":"2022-06-07T15:18:09.065254Z","shell.execute_reply.started":"2022-06-07T15:18:09.020949Z","shell.execute_reply":"2022-06-07T15:18:09.064262Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Visual Utilities**","metadata":{}},{"cell_type":"code","source":"def show_tensor_images(image_tensor, num_images=25, size=(1, 28, 28)):\n    image_tensor = (image_tensor + 1) / 2\n    image_shifted = image_tensor\n    image_unflat = image_shifted.detach().cpu().view(-1, *size)\n    image_grid = make_grid(image_unflat[:num_images], nrow=5)\n    plt.imshow(image_grid.permute(1, 2, 0).squeeze())\n    plt.show()\n\n    \n    \ndef show_example(data_loaded):\n    photo_img, monet_img = next(iter(data_loaded))\n\n    def unnorm(img, mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]):\n        for t, m, s in zip(img, mean, std):\n            t.mul_(s).add_(s)\n\n        return img\n    f = plt.figure(figsize=(8, 8))\n\n    f.add_subplot(1, 2, 1)\n    plt.title('Photo')\n    photo_img = unnorm(photo_img)\n    plt.imshow(photo_img[0].permute(1, 2, 0))\n\n    f.add_subplot(1, 2, 2)\n    plt.title('Monet')\n    monet_img = unnorm(monet_img)\n    plt.imshow(monet_img[0].permute(1, 2, 0))\n    \nshow_example(data_loaded)","metadata":{"execution":{"iopub.status.busy":"2022-06-07T15:18:09.069037Z","iopub.execute_input":"2022-06-07T15:18:09.069446Z","iopub.status.idle":"2022-06-07T15:18:12.433681Z","shell.execute_reply.started":"2022-06-07T15:18:09.069408Z","shell.execute_reply":"2022-06-07T15:18:12.432816Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Model Architecture Layers**","metadata":{}},{"cell_type":"markdown","source":"### **Residual Block**","metadata":{}},{"cell_type":"code","source":"class ResidualBlock(nn.Module):\n    def __init__(self, input_channels):\n        super(ResidualBlock, self).__init__()\n        self.conv1 = nn.Conv2d(input_channels, input_channels, kernel_size=3, padding=1, padding_mode='reflect')\n        self.conv2 = nn.Conv2d(input_channels, input_channels, kernel_size=3, padding=1, padding_mode='reflect')\n        self.instancenorm = nn.InstanceNorm2d(input_channels)\n        self.activation = nn.ReLU()\n\n    def forward(self, x):\n        original_x = x.clone()\n        x = self.conv1(x)\n        x = self.instancenorm(x)\n        x = self.activation(x)\n        x = self.conv2(x)\n        x = self.instancenorm(x)\n        return original_x + x","metadata":{"execution":{"iopub.status.busy":"2022-06-07T15:18:12.434808Z","iopub.execute_input":"2022-06-07T15:18:12.435167Z","iopub.status.idle":"2022-06-07T15:18:12.485099Z","shell.execute_reply.started":"2022-06-07T15:18:12.435133Z","shell.execute_reply":"2022-06-07T15:18:12.483868Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Contracting Block**","metadata":{}},{"cell_type":"code","source":"class ContractingBlock(nn.Module):\n    def __init__(self, input_channels, use_bn=True, kernel_size=3, activation='relu'):\n        super(ContractingBlock, self).__init__()\n        self.conv1 = nn.Conv2d(input_channels, input_channels * 2, kernel_size=kernel_size, padding=1, stride=2, padding_mode='reflect')\n        self.activation = nn.ReLU() if activation == 'relu' else nn.LeakyReLU(0.2)\n        if use_bn:\n            self.instancenorm = nn.InstanceNorm2d(input_channels * 2)\n        self.use_bn = use_bn\n\n    def forward(self, x):\n        x = self.conv1(x)\n        if self.use_bn:\n            x = self.instancenorm(x)\n        x = self.activation(x)\n        return x","metadata":{"execution":{"iopub.status.busy":"2022-06-07T15:18:12.489500Z","iopub.execute_input":"2022-06-07T15:18:12.490314Z","iopub.status.idle":"2022-06-07T15:18:12.538020Z","shell.execute_reply.started":"2022-06-07T15:18:12.490263Z","shell.execute_reply":"2022-06-07T15:18:12.536836Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Expanding Block**","metadata":{}},{"cell_type":"code","source":"class ExpandingBlock(nn.Module):\n    def __init__(self, input_channels, use_bn=True):\n        super(ExpandingBlock, self).__init__()\n        self.conv1 = nn.ConvTranspose2d(input_channels, input_channels // 2, kernel_size=3, stride=2, padding=1, output_padding=1)\n        if use_bn:\n            self.instancenorm = nn.InstanceNorm2d(input_channels // 2)\n        self.use_bn = use_bn\n        self.activation = nn.ReLU()\n\n    def forward(self, x):\n        x = self.conv1(x)\n        if self.use_bn:\n            x = self.instancenorm(x)\n        x = self.activation(x)\n        return x","metadata":{"execution":{"iopub.status.busy":"2022-06-07T15:18:12.539685Z","iopub.execute_input":"2022-06-07T15:18:12.540426Z","iopub.status.idle":"2022-06-07T15:18:12.589319Z","shell.execute_reply.started":"2022-06-07T15:18:12.540384Z","shell.execute_reply":"2022-06-07T15:18:12.588198Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Feature Mapping Block**","metadata":{}},{"cell_type":"code","source":"class FeatureMapBlock(nn.Module):\n    def __init__(self, input_channels, output_channels):\n        super(FeatureMapBlock, self).__init__()\n        self.conv = nn.Conv2d(input_channels, output_channels, kernel_size=7, padding=3, padding_mode='reflect')\n\n    def forward(self, x):\n        x = self.conv(x)\n        return x","metadata":{"execution":{"iopub.status.busy":"2022-06-07T15:18:12.591062Z","iopub.execute_input":"2022-06-07T15:18:12.591765Z","iopub.status.idle":"2022-06-07T15:18:12.638613Z","shell.execute_reply.started":"2022-06-07T15:18:12.591720Z","shell.execute_reply":"2022-06-07T15:18:12.637543Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Model Architecture(Generator and Discriminator)**","metadata":{}},{"cell_type":"markdown","source":"### **Generator Architecture**","metadata":{}},{"cell_type":"code","source":"class Generator(nn.Module):\n    def __init__(self, input_channels, output_channels, hidden_channels=64):\n        super(Generator, self).__init__()\n        self.upfeature = FeatureMapBlock(input_channels, hidden_channels)\n        self.contract1 = ContractingBlock(hidden_channels)\n        self.contract2 = ContractingBlock(hidden_channels * 2)\n        res_mult = 4\n        self.res0 = ResidualBlock(hidden_channels * res_mult)\n        self.res1 = ResidualBlock(hidden_channels * res_mult)\n        self.res2 = ResidualBlock(hidden_channels * res_mult)\n        self.res3 = ResidualBlock(hidden_channels * res_mult)\n        self.res4 = ResidualBlock(hidden_channels * res_mult)\n        self.res5 = ResidualBlock(hidden_channels * res_mult)\n        self.res6 = ResidualBlock(hidden_channels * res_mult)\n        self.res7 = ResidualBlock(hidden_channels * res_mult)\n        self.res8 = ResidualBlock(hidden_channels * res_mult)\n        self.expand2 = ExpandingBlock(hidden_channels * 4)\n        self.expand3 = ExpandingBlock(hidden_channels * 2)\n        self.downfeature = FeatureMapBlock(hidden_channels, output_channels)\n        self.tanh = torch.nn.Tanh()\n\n    def forward(self, x):\n        x0 = self.upfeature(x)\n        x1 = self.contract1(x0)\n        x2 = self.contract2(x1)\n        x3 = self.res0(x2)\n        x4 = self.res1(x3)\n        x5 = self.res2(x4)\n        x6 = self.res3(x5)\n        x7 = self.res4(x6)\n        x8 = self.res5(x7)\n        x9 = self.res6(x8)\n        x10 = self.res7(x9)\n        x11 = self.res8(x10)\n        x12 = self.expand2(x11)\n        x13 = self.expand3(x12)\n        xn = self.downfeature(x13)\n        return self.tanh(xn)","metadata":{"execution":{"iopub.status.busy":"2022-06-07T15:18:12.641153Z","iopub.execute_input":"2022-06-07T15:18:12.642475Z","iopub.status.idle":"2022-06-07T15:18:12.695351Z","shell.execute_reply.started":"2022-06-07T15:18:12.642428Z","shell.execute_reply":"2022-06-07T15:18:12.694379Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Discriminator Architecture**","metadata":{}},{"cell_type":"code","source":"class Discriminator(nn.Module):\n    def __init__(self, input_channels, hidden_channels=64):\n        super(Discriminator, self).__init__()\n        self.upfeature = FeatureMapBlock(input_channels, hidden_channels)\n        self.contract1 = ContractingBlock(hidden_channels, use_bn=False, kernel_size=4, activation='lrelu')\n        self.contract2 = ContractingBlock(hidden_channels * 2, kernel_size=4, activation='lrelu')\n        self.contract3 = ContractingBlock(hidden_channels * 4, kernel_size=4, activation='lrelu')\n        self.final = nn.Conv2d(hidden_channels * 8, 1, kernel_size=1)\n\n    def forward(self, x):\n        x0 = self.upfeature(x)\n        x1 = self.contract1(x0)\n        x2 = self.contract2(x1)\n        x3 = self.contract3(x2)\n        xn = self.final(x3)\n        return xn","metadata":{"execution":{"iopub.status.busy":"2022-06-07T15:18:12.696907Z","iopub.execute_input":"2022-06-07T15:18:12.697625Z","iopub.status.idle":"2022-06-07T15:18:12.746621Z","shell.execute_reply.started":"2022-06-07T15:18:12.697579Z","shell.execute_reply":"2022-06-07T15:18:12.745380Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Loss Analysis**","metadata":{}},{"cell_type":"markdown","source":"### **Discriminator Loss**","metadata":{}},{"cell_type":"code","source":"## Loss:\n## Discriminator Loss\n\ndef get_discriminator_loss(real_x, fake_x, disc_X, adversarial_criterion):\n    real_y = disc_X(real_x.detach())\n    real_pred_y = torch.ones_like(real_y)\n    fake_y = disc_X(fake_x.detach())\n    fake_pred_y = torch.zeros_like(fake_y)\n    real_pred_loss = adversarial_criterion(real_y, real_pred_y)\n    fake_pred_loss = adversarial_criterion(fake_y, fake_pred_y)\n    disc_loss = (real_pred_loss + fake_pred_loss) / 2.0\n    return disc_loss\n    ","metadata":{"execution":{"iopub.status.busy":"2022-06-07T15:18:12.748305Z","iopub.execute_input":"2022-06-07T15:18:12.749033Z","iopub.status.idle":"2022-06-07T15:18:12.796280Z","shell.execute_reply.started":"2022-06-07T15:18:12.748992Z","shell.execute_reply":"2022-06-07T15:18:12.795138Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Generator Loss - Adversarial Loss**","metadata":{}},{"cell_type":"code","source":"## Loss: Generator_loss - Adversarial_loss\ndef get_generator_adversarial_loss(real_x, gen_XY, disc_X, gen_adv_criterion):\n    fake_y = gen_XY(real_x)\n    fake_pred_y = disc_X(fake_y)\n    gen_adv_loss = gen_adv_criterion(fake_pred_y, torch.ones_like(fake_pred_y))\n    return gen_adv_loss, fake_y\n","metadata":{"execution":{"iopub.status.busy":"2022-06-07T15:18:12.798028Z","iopub.execute_input":"2022-06-07T15:18:12.798787Z","iopub.status.idle":"2022-06-07T15:18:12.844194Z","shell.execute_reply.started":"2022-06-07T15:18:12.798741Z","shell.execute_reply":"2022-06-07T15:18:12.843025Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Generator Loss - Cycle Consistency Loss**","metadata":{}},{"cell_type":"code","source":"## Loss: Generator_loss - Cycle_Consistency_Loss\ndef get_cycle_consistency_loss(real_x, fake_y, gen_YX, cycle_criterion):\n    real_pred_x = gen_YX(fake_y)\n    cycle_consistency_loss = cycle_criterion(real_x, real_pred_x)\n    return cycle_consistency_loss, real_pred_x\n    ","metadata":{"execution":{"iopub.status.busy":"2022-06-07T15:18:12.845596Z","iopub.execute_input":"2022-06-07T15:18:12.846648Z","iopub.status.idle":"2022-06-07T15:18:12.893307Z","shell.execute_reply.started":"2022-06-07T15:18:12.846599Z","shell.execute_reply":"2022-06-07T15:18:12.892278Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Generator Loss - Identity Loss**","metadata":{}},{"cell_type":"code","source":"## Loss: Generator_loss - Identity_Loss\n\ndef get_identity_loss(real_x, gen_YX, identity_criterion):\n    identity_x = gen_YX(real_x)\n    identity_loss = identity_criterion(real_x, identity_x)\n    return identity_loss, identity_x\n","metadata":{"execution":{"iopub.status.busy":"2022-06-07T15:18:12.897325Z","iopub.execute_input":"2022-06-07T15:18:12.898413Z","iopub.status.idle":"2022-06-07T15:18:12.942385Z","shell.execute_reply.started":"2022-06-07T15:18:12.898347Z","shell.execute_reply":"2022-06-07T15:18:12.941275Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Generator Loss Overall**","metadata":{}},{"cell_type":"code","source":"## Loss: Generator_loss\n\ndef get_generator_loss(real_A, real_B, gen_AB, gen_BA, disc_A, disc_B, adversarial_criterion, cycle_criterion, identity_criterion, lambda_adversarial = 1, lambda_cycle = 9, lambda_identity = 2.10\n                      ):\n    adversarial_loss_AB, fake_B = get_generator_adversarial_loss(real_A, gen_AB, disc_A, adversarial_criterion)\n    adversarial_loss_BA, fake_A = get_generator_adversarial_loss(real_B, gen_BA, disc_B, adversarial_criterion)\n    adversarial_loss = (adversarial_loss_AB + adversarial_loss_BA)\n    \n    cycle_loss_ABA, real_pred_A = get_cycle_consistency_loss(real_A, fake_B, gen_BA, cycle_criterion)\n    cycle_loss_BAB, real_pred_B = get_cycle_consistency_loss(real_A, fake_B, gen_BA, cycle_criterion)\n    cycle_loss = cycle_loss_ABA + cycle_loss_BAB\n    \n    identity_loss_A, identity_A = get_identity_loss(real_A, gen_BA, identity_criterion)\n    identity_loss_B, identity_B = get_identity_loss(real_B, gen_AB, identity_criterion)\n    identity_loss = identity_loss_A + identity_loss_B\n    \n    generator_loss = adversarial_loss * lambda_adversarial + cycle_loss * lambda_cycle + identity_loss * lambda_identity\n    return generator_loss, fake_A, fake_B\n    ","metadata":{"execution":{"iopub.status.busy":"2022-06-07T15:18:12.945778Z","iopub.execute_input":"2022-06-07T15:18:12.946606Z","iopub.status.idle":"2022-06-07T15:18:12.996393Z","shell.execute_reply.started":"2022-06-07T15:18:12.946558Z","shell.execute_reply":"2022-06-07T15:18:12.995035Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## **Training**","metadata":{}},{"cell_type":"markdown","source":"### **Parameters for Training**","metadata":{}},{"cell_type":"code","source":"adversarial_criterion = nn.MSELoss()\nrecon_criterion = nn.L1Loss()\n\nEPOCHS = 2\ndim_A = 3\ndim_B = 3\nDISPLAY_STEP = 200\nBATCH_SIZE = 1\nlearning_rate = 0.000197\ntarget_shape = 256\ndevice = 'cuda'","metadata":{"execution":{"iopub.status.busy":"2022-06-07T15:18:13.000755Z","iopub.execute_input":"2022-06-07T15:18:13.001313Z","iopub.status.idle":"2022-06-07T15:18:13.046643Z","shell.execute_reply.started":"2022-06-07T15:18:13.001278Z","shell.execute_reply":"2022-06-07T15:18:13.045497Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Weights Analysis**","metadata":{}},{"cell_type":"code","source":"gen_AB = Generator(dim_A, dim_B).to(device)\ngen_BA = Generator(dim_B, dim_A).to(device)\ngen_opt = torch.optim.Adam(list(gen_AB.parameters()) + list(gen_BA.parameters()), lr=learning_rate, betas=(0.5, 0.999))\ndisc_A = Discriminator(dim_A).to(device)\ndisc_A_opt = torch.optim.Adam(disc_A.parameters(), lr=learning_rate, betas=(0.5, 0.999))\ndisc_B = Discriminator(dim_B).to(device)\ndisc_B_opt = torch.optim.Adam(disc_B.parameters(), lr=learning_rate, betas=(0.5, 0.999))\n\ndef weights_init(m):\n    if isinstance(m, nn.Conv2d) or isinstance(m, nn.ConvTranspose2d):\n        torch.nn.init.normal_(m.weight, 0.0, 0.02)\n    if isinstance(m, nn.BatchNorm2d):\n        torch.nn.init.normal_(m.weight, 0.0, 0.02)\n        torch.nn.init.constant_(m.bias, 0)\n","metadata":{"execution":{"iopub.status.busy":"2022-06-07T15:18:13.048467Z","iopub.execute_input":"2022-06-07T15:18:13.049310Z","iopub.status.idle":"2022-06-07T15:18:13.414307Z","shell.execute_reply.started":"2022-06-07T15:18:13.049262Z","shell.execute_reply":"2022-06-07T15:18:13.413410Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pretrained = True # False if training from scratch\nif pretrained:\n    pre_dict = torch.load(\"../input/cyclegan-training-weights/cycleGAN_17800.pth\") ## Give the path of the presaved file\n    gen_AB.load_state_dict(pre_dict['gen_AB'])\n    gen_BA.load_state_dict(pre_dict['gen_BA'])\n    gen_opt.load_state_dict(pre_dict['gen_opt'])\n    disc_A.load_state_dict(pre_dict['disc_A'])\n    disc_A_opt.load_state_dict(pre_dict['disc_A_opt'])\n    disc_B.load_state_dict(pre_dict['disc_B'])\n    disc_B_opt.load_state_dict(pre_dict['disc_B_opt'])\nelse:\n    gen_AB = gen_AB.apply(weights_init)\n    gen_BA = gen_BA.apply(weights_init)\n    disc_A = disc_A.apply(weights_init)\n    disc_B = disc_B.apply(weights_init)","metadata":{"execution":{"iopub.status.busy":"2022-06-07T15:18:13.415830Z","iopub.execute_input":"2022-06-07T15:18:13.416257Z","iopub.status.idle":"2022-06-07T15:18:16.748754Z","shell.execute_reply.started":"2022-06-07T15:18:13.416200Z","shell.execute_reply":"2022-06-07T15:18:16.747871Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### **Model Training**","metadata":{}},{"cell_type":"code","source":"## Training\nfrom skimage import color\nplt.rcParams['figure.figsize'] = [10, 10]\n\ndef train(do_save_model = False):\n    mean_generator_loss = 0\n    mean_discriminator_loss = 0\n    dataloader = data_loaded\n    current_step = 0\n    \n    for epoch in range(EPOCHS):\n#         if epoch == (EPOCHS - 1):\n#             do_save_model = True\n            \n        for real_A, real_B in tqdm(dataloader):\n            curr_batch_size = len(real_A)\n            real_A = real_A.to(device)\n            real_B = real_B.to(device)\n            \n            disc_A_opt.zero_grad()\n            with torch.no_grad():\n                fake_A = gen_BA(real_B)\n            disc_A_loss = get_discriminator_loss(real_A, fake_A, disc_A, adversarial_criterion)\n            disc_A_loss.backward(retain_graph = True)\n            disc_A_opt.step()\n            \n            disc_B_opt.zero_grad()\n            with torch.no_grad():\n                fake_B = gen_AB(real_A)\n            disc_B_loss = get_discriminator_loss(real_B, fake_B, disc_B, adversarial_criterion)\n            disc_B_loss.backward(retain_graph = True)\n            disc_B_opt.step()\n            \n            gen_opt.zero_grad()\n            gen_loss, fake_A, fake_B = get_generator_loss(real_A, real_B, gen_AB, gen_BA, disc_A, disc_B, adversarial_criterion, recon_criterion, recon_criterion)\n            gen_loss.backward(retain_graph = True)\n            gen_opt.step()\n            \n            mean_discriminator_loss += disc_A_loss.item() / DISPLAY_STEP\n            mean_generator_loss += gen_loss.item() / DISPLAY_STEP\n            \n            ## Code for Visualization\n            if current_step % DISPLAY_STEP == 0:\n                print(f\"Epoch {epoch}: Step {current_step}: Generator (U-Net) loss: {mean_generator_loss}, Discriminator loss: {mean_discriminator_loss}\")\n                show_tensor_images(torch.cat([real_A, real_B]), size=(dim_A, target_shape, target_shape))\n                show_tensor_images(torch.cat([fake_B, fake_A]), size=(dim_B, target_shape, target_shape))\n                mean_generator_loss = 0\n                mean_discriminator_loss = 0\n                # You can change save_model to True if you'd like to save the model\n                if do_save_model:\n                    torch.save({\n                        'gen_AB': gen_AB.state_dict(),\n                        'gen_BA': gen_BA.state_dict(),\n                        'gen_opt': gen_opt.state_dict(),\n                        'disc_A': disc_A.state_dict(),\n                        'disc_A_opt': disc_A_opt.state_dict(),\n                        'disc_B': disc_B.state_dict(),\n                        'disc_B_opt': disc_B_opt.state_dict()\n                    }, f\"cycleGAN_{current_step}.pth\")\n            current_step += 1\n    return gen_AB, gen_BA\n            \n            \ngenerator_real_to_painter, generator_painter_to_real = train()","metadata":{"execution":{"iopub.status.busy":"2022-06-07T15:18:16.750268Z","iopub.execute_input":"2022-06-07T15:18:16.750639Z","iopub.status.idle":"2022-06-07T15:25:15.501290Z","shell.execute_reply.started":"2022-06-07T15:18:16.750601Z","shell.execute_reply":"2022-06-07T15:25:15.500086Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_submission():\n    data_loader = data_loaded\n    i = 1\n    for real_A in tqdm(photo_data_loaded):\n        real_A = real_A.to(device)\n        with torch.no_grad():\n            prediction = generator_real_to_painter(real_A)[0].cpu().numpy()\n        prediction = (prediction * 127.5 + 127.5).T.astype(np.uint8)\n        result_image = PIL.Image.fromarray(prediction)\n        output = result_image.rotate(270)\n        output.save(\"./Results/painted{}.jpg\".format(i))\n        torch.cuda.empty_cache()\n        i += 1\n        \n    shutil.make_archive(\"/kaggle/working/images\", 'zip', \"/kaggle/working/Results\")\n    return\n\nget_submission()","metadata":{"execution":{"iopub.status.busy":"2022-06-07T15:25:15.502985Z","iopub.execute_input":"2022-06-07T15:25:15.503664Z","iopub.status.idle":"2022-06-07T15:30:07.806941Z","shell.execute_reply.started":"2022-06-07T15:25:15.503621Z","shell.execute_reply":"2022-06-07T15:30:07.805966Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}