{"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":"CycleGAN base on <a href=\"https://www.kaggle.com/code/amyjang/monet-cyclegan-tutorial/notebook\">Amy Jang's notebook</a>. Tried to replicated the same UNet in pytorch.\nTraining is **super** slow... Had to cap the number of input pics... And it doesn't work correctly (look at version 13). This is my first submission here so any help would be appreciated...","metadata":{}},{"cell_type":"markdown","source":"# Importing stuff\n","metadata":{"execution":{"iopub.status.busy":"2022-05-15T17:17:56.642565Z","iopub.execute_input":"2022-05-15T17:17:56.643668Z","iopub.status.idle":"2022-05-15T17:17:56.651483Z","shell.execute_reply.started":"2022-05-15T17:17:56.643609Z","shell.execute_reply":"2022-05-15T17:17:56.650001Z"}}},{"cell_type":"code","source":"import random\nimport os\n\nimport torch\n#import torch_xla\n#import torch_xla.core.xla_model as xm\nimport torch.nn as nn\nimport matplotlib.pyplot as plt\nfrom tqdm import tqdm\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision import transforms\nfrom PIL import Image\nimport numpy as np","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:17:06.891531Z","iopub.execute_input":"2022-05-16T16:17:06.892298Z","iopub.status.idle":"2022-05-16T16:17:06.897674Z","shell.execute_reply.started":"2022-05-16T16:17:06.892256Z","shell.execute_reply":"2022-05-16T16:17:06.896819Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(torch.__version__)","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:17:06.911285Z","iopub.execute_input":"2022-05-16T16:17:06.911526Z","iopub.status.idle":"2022-05-16T16:17:06.916346Z","shell.execute_reply.started":"2022-05-16T16:17:06.911495Z","shell.execute_reply":"2022-05-16T16:17:06.915656Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Defining input/output shapes and device","metadata":{}},{"cell_type":"code","source":"NUM_CHANNELS = 3\nOUTPUT_CHANNELS = 3\n\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n#device = xm.xla_device()","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-05-16T16:17:06.92614Z","iopub.execute_input":"2022-05-16T16:17:06.926601Z","iopub.status.idle":"2022-05-16T16:17:06.93067Z","shell.execute_reply.started":"2022-05-16T16:17:06.926572Z","shell.execute_reply":"2022-05-16T16:17:06.929777Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Downsampling unit","metadata":{}},{"cell_type":"code","source":"class Dsample(nn.Module):\n    def __init__(self, in_channels, out_channels, kernel_size, normalize=True):\n        super(Dsample, self).__init__()\n        self.normalize = normalize\n\n        self.conv = nn.Conv2d(in_channels=in_channels, out_channels=out_channels, kernel_size=kernel_size, padding=1, stride=2, bias=False)\n\n        if self.normalize:\n            self.norm = nn.InstanceNorm2d(out_channels, affine=True)\n        \n        self.activation = nn.LeakyReLU()\n        self._weight_init()\n    \n    def _weight_init(self):\n        for layer in self.children():\n           for name, param in layer.named_parameters(recurse=False):\n                if name == 'bias':\n                    layer.bias = torch.nn.init.zeros_(layer.bias)\n                else:\n                    layer.weight = torch.nn.init.normal_(layer.weight, mean=0.0, std=0.02)\n        return\n    \n    def forward(self, x):\n        x = self.conv(x)\n        if self.normalize:\n            x = self.norm(x)\n        return self.activation(x)","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:17:06.945513Z","iopub.execute_input":"2022-05-16T16:17:06.94594Z","iopub.status.idle":"2022-05-16T16:17:06.954565Z","shell.execute_reply.started":"2022-05-16T16:17:06.945913Z","shell.execute_reply":"2022-05-16T16:17:06.95362Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Upsampling unit","metadata":{}},{"cell_type":"code","source":"class Usample(nn.Module):\n    def __init__(self, in_channels, out_channels, kernel_size, dropout=False):\n        super(Usample, self).__init__()\n        self.dropout = dropout\n\n        self.conv = nn.ConvTranspose2d(in_channels=in_channels, out_channels=out_channels, kernel_size=kernel_size, padding=1, stride=2, bias=False)\n\n        self.norm = nn.InstanceNorm2d(out_channels, affine=True)\n        \n        if self.dropout:\n            #self.drop = nn.Dropout2d(0.5)\n            self.drop = nn.Dropout(0.5)\n        \n        self.activation = nn.ReLU()\n        self._weight_init()\n    \n    def _weight_init(self):\n        for layer in self.children():\n           for name, param in layer.named_parameters(recurse=False):\n                if name == 'bias':\n                    layer.bias = torch.nn.init.zeros_(layer.bias)\n                else:\n                    layer.weight = torch.nn.init.normal_(layer.weight, mean=0.0, std=0.02)\n        return\n    \n    def forward(self, x):\n        x = self.conv(x)\n        x = self.norm(x)\n        if self.dropout:\n            x = self.drop(x)\n        return self.activation(x)","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:17:06.96183Z","iopub.execute_input":"2022-05-16T16:17:06.962288Z","iopub.status.idle":"2022-05-16T16:17:06.974205Z","shell.execute_reply.started":"2022-05-16T16:17:06.962258Z","shell.execute_reply":"2022-05-16T16:17:06.973312Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Generator unit","metadata":{}},{"cell_type":"code","source":"class GNet(nn.Module):\n    def __init__(self):\n        super(GNet, self).__init__()\n\n        self.d1 = Dsample(NUM_CHANNELS, 64, 4, False)\n        self.d2 = Dsample(64, 128, 4)\n        self.d3 = Dsample(128, 256, 4)\n        self.d4 = Dsample(256, 512, 4)\n        self.d5 = Dsample(512, 512, 4)\n        self.d6 = Dsample(512, 512, 4)\n        self.d7 = Dsample(512, 512, 4)\n        self.d8 = Dsample(512, 512, 4, False)\n\n        self.u1 = Usample(512, 512, 4, True)\n        self.u2 = Usample(1024, 512, 4, True) # has skip connections coming in 512 + 512\n        self.u3 = Usample(1024, 512, 4, True) # has skip connections coming in 512 + 512\n        self.u4 = Usample(1024, 512, 4) # has skip\n        self.u5 = Usample(1024, 256, 4) # has skip\n        self.u6 = Usample(512, 128, 4) # has skip\n        self.u7 = Usample(256, 64, 4) # has skip\n\n        self.outlayer = nn.ConvTranspose2d(in_channels = 128, out_channels = OUTPUT_CHANNELS, kernel_size = 4, padding = 1, stride = 2)\n        self.activation = nn.Tanh()\n        self._weight_init()\n    \n\n    def _weight_init(self):\n        for layer in self.children():\n           for name, param in layer.named_parameters(recurse=False):\n                if name == 'bias':\n                    layer.bias = torch.nn.init.zeros_(layer.bias)\n                else:\n                    layer.weight = torch.nn.init.normal_(layer.weight, mean=0.0, std=0.02)\n        return\n    \n    def forward(self, x):\n        skips = []\n        \n        # Downsampling\n        x = self.d1(x)\n        skips.append(x)\n        x = self.d2(x)\n        skips.append(x)\n        x = self.d3(x)\n        skips.append(x)\n        x = self.d4(x)\n        skips.append(x)\n        x = self.d5(x)\n        skips.append(x)\n        x = self.d6(x)\n        skips.append(x)\n        x = self.d7(x)\n        skips.append(x)\n        x = self.d8(x)\n\n        skips = skips[::-1]\n\n        #Upsampling\n        x = self.u1(x)\n        x = torch.cat((x, skips[0]), dim=1)\n        x = self.u2(x)\n        x = torch.cat((x, skips[1]), dim=1)\n        x = self.u3(x)\n        x = torch.cat((x, skips[2]), dim=1)\n        x = self.u4(x)\n        x = torch.cat((x, skips[3]), dim=1)\n        x = self.u5(x)\n        x = torch.cat((x, skips[4]), dim=1)\n        x = self.u6(x)\n        x = torch.cat((x, skips[5]), dim=1)\n        x = self.u7(x)\n        x = torch.cat((x, skips[6]), dim=1)\n\n        x = self.outlayer(x)\n        return self.activation(x)","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:17:06.978386Z","iopub.execute_input":"2022-05-16T16:17:06.978953Z","iopub.status.idle":"2022-05-16T16:17:06.998903Z","shell.execute_reply.started":"2022-05-16T16:17:06.978915Z","shell.execute_reply":"2022-05-16T16:17:06.998116Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Discriminator unit","metadata":{}},{"cell_type":"code","source":"class DNet(nn.Module):\n    def __init__(self):\n        super(DNet, self).__init__()\n        \n        self.d1 = Dsample(NUM_CHANNELS, 64, 4, False)\n        self.d2 = Dsample(64, 128, 4)\n        self.d3 = Dsample(128, 256, 4)\n        self.zpad1 = nn.ZeroPad2d(1)\n        self.conv1 = nn.Conv2d(256, 512, 4, stride=1, bias=False)\n        self.norm = nn.InstanceNorm2d(512, affine=True)\n        self.activation = nn.LeakyReLU()\n        self.zpad2 = nn.ZeroPad2d(1)\n        self.conv2 = nn.Conv2d(512, 1, 4, stride=1)\n        self._weight_init()\n\n    \n    def _weight_init(self):\n        for layer in self.children():\n           for name, param in layer.named_parameters(recurse=False):\n                if name == 'bias':\n                    layer.bias = torch.nn.init.zeros_(layer.bias)\n                else:\n                    layer.weight = torch.nn.init.normal_(layer.weight, mean=0.0, std=0.02)\n        return\n\n    def forward(self, x):\n        x = self.d1(x)\n        x = self.d2(x)\n        x = self.d3(x)\n        x = self.zpad1(x)\n        x = self.conv1(x)\n        x = self.norm(x)\n        x = self.activation(x)\n        x = self.zpad2(x)\n        x = self.conv2(x)\n        return x","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:17:07.046636Z","iopub.execute_input":"2022-05-16T16:17:07.046829Z","iopub.status.idle":"2022-05-16T16:17:07.057882Z","shell.execute_reply.started":"2022-05-16T16:17:07.046805Z","shell.execute_reply":"2022-05-16T16:17:07.056173Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Photo-to-Monet GAN","metadata":{}},{"cell_type":"code","source":"class MonetGAN(nn.Module):\n    def __init__(self):\n        super(MonetGAN, self).__init__()\n        self._dev = device\n        self.gen = GNet().to(self._dev)\n        self.disc = DNet().to(self._dev)\n\n    def _get_loss_d(self, monet_real, photo):\n        gen_data = self.disc(self.gen(photo))\n        gen_label = torch.zeros(gen_data.shape, device=self._dev)\n        real_data = self.disc(monet_real)\n        real_label = torch.ones(real_data.shape, device=self._dev)\n        labels = torch.cat((real_label, gen_label))\n        full_data = torch.cat((real_data, gen_data))\n        return torch.nn.BCEWithLogitsLoss(reduction='none')(full_data.mean(dim=1), labels.mean(dim=1))\n    \n    def _get_loss_g(self, photo):\n        gen_data = self.disc(self.gen(photo))\n        gen_label = torch.ones(gen_data.shape, device=self._dev)\n        return torch.nn.BCEWithLogitsLoss(reduction='none')(gen_data.mean(dim=1), gen_label.mean(dim=1))","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:17:07.067654Z","iopub.execute_input":"2022-05-16T16:17:07.067846Z","iopub.status.idle":"2022-05-16T16:17:07.07709Z","shell.execute_reply.started":"2022-05-16T16:17:07.067822Z","shell.execute_reply":"2022-05-16T16:17:07.07611Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Monet-to-Photo GAN","metadata":{}},{"cell_type":"code","source":"class PhotoGAN(nn.Module):\n    def __init__(self):\n        super(PhotoGAN, self).__init__()\n        self._dev = device\n        self.gen = GNet().to(self._dev)\n        self.disc = DNet().to(self._dev)\n\n    def _get_loss_d(self, photo_real, monet):\n        gen_data = self.disc(self.gen(monet))\n        gen_label = torch.zeros(gen_data.shape, device=self._dev)\n        real_data = self.disc(photo_real)\n        real_label = torch.ones(real_data.shape, device=self._dev)\n        labels = torch.cat((real_label, gen_label))\n        full_data = torch.cat((real_data, gen_data))\n        return torch.nn.BCEWithLogitsLoss(reduction='none')(full_data.mean(dim=1), labels.mean(dim=1))\n    \n    def _get_loss_g(self, monet):\n        gen_data = self.disc(self.gen(monet))\n        gen_label = torch.ones(gen_data.shape, device=self._dev)\n        return torch.nn.BCEWithLogitsLoss(reduction='none')(gen_data.mean(dim=1), gen_label.mean(dim=1))","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:17:07.079052Z","iopub.execute_input":"2022-05-16T16:17:07.079734Z","iopub.status.idle":"2022-05-16T16:17:07.090649Z","shell.execute_reply.started":"2022-05-16T16:17:07.079692Z","shell.execute_reply":"2022-05-16T16:17:07.089682Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Complete CycleGAN unit","metadata":{}},{"cell_type":"code","source":"class CycleGAN(nn.Module):\n    def __init__(self, plambda=10):\n        super(CycleGAN, self).__init__()\n        self._dev = device\n        self.mGAN = MonetGAN().to(self._dev)\n        self.pGAN = PhotoGAN().to(self._dev)\n        self.plambda = plambda\n\n    def _cycle_loss_monet(self, monet, plambda):\n        fake_photo = self.mGAN.gen(monet)\n        cycled_monet = self.pGAN.gen(fake_photo)\n        cycle_loss = torch.nn.L1Loss(reduction='mean')(monet, cycled_monet)\n        return plambda * cycle_loss\n\n    def _cycle_loss_photo(self, photo, plambda):\n        fake_monet = self.pGAN.gen(photo)\n        cycled_photo = self.mGAN.gen(fake_monet)\n        cycle_loss = torch.nn.L1Loss(reduction='mean')(photo, cycled_photo)\n        return plambda * cycle_loss\n    \n    def _identity_loss_monet(self, monet, plambda):\n        monet_back = self.mGAN.gen(monet)\n        iden_loss = torch.nn.L1Loss(reduction='mean')(monet, monet_back)\n        return plambda * iden_loss\n    \n    def _identity_loss_photo(self, photo, plambda):\n        photo_back = self.pGAN.gen(photo)\n        iden_loss = torch.nn.L1Loss(reduction='mean')(photo, photo_back)\n        return plambda * iden_loss\n\n    def _total_loss_D(self, photo, monet):\n        return self.mGAN._get_loss_d(monet, photo) + self.pGAN._get_loss_d(photo, monet)\n    \n    def _total_loss_G(self, photo, monet, mode):\n      if mode == 'm':\n        #input is photo\n        return self.mGAN._get_loss_g(photo) + self._cycle_loss_monet(monet, self.plambda) + self._cycle_loss_photo(photo, self.plambda) +\\\n               self._identity_loss_monet(monet, 0.5*self.plambda)\n      elif mode == 'p':\n        #input is monet\n        return self.pGAN._get_loss_g(monet) + self._cycle_loss_monet(monet, self.plambda) + self._cycle_loss_photo(photo, self.plambda) +\\\n               self._identity_loss_photo(photo, 0.5*self.plambda)\n      else:\n        raise RuntimeError(\"Wrong mode selected.\")\n\n    \n\n    def train(self, in_data, iter_d=1, iter_g=1, n_epochs=100, lr=0.0002):\n\n        optG_M = torch.optim.Adam(list(self.mGAN.gen.parameters()), lr=lr, betas=(0.5, 0.99))\n        optG_M.zero_grad(set_to_none=True)\n        \n        optD_M = torch.optim.Adam(list(self.mGAN.disc.parameters()), lr=lr, betas=(0.5, 0.99))\n        optD_M.zero_grad(set_to_none=True)\n\n        optG_P = torch.optim.Adam(list(self.pGAN.gen.parameters()), lr=lr, betas=(0.5, 0.99))\n        optG_P.zero_grad(set_to_none=True)\n        \n        optD_P = torch.optim.Adam(list(self.pGAN.disc.parameters()), lr=lr, betas=(0.5, 0.99))\n        optD_P.zero_grad(set_to_none=True)\n\n        for epoch in tqdm(range(n_epochs)):\n            for batch_idx, data in enumerate(in_data):\n                photo, monet = data['photo'].to(self._dev), data['monet'].to(self._dev)\n                \n                optG_M.zero_grad(set_to_none=True)\n                loss_G_M = self._total_loss_G(photo, monet, 'm')\n                loss_G_M.backward(torch.ones_like(loss_G_M))\n                optG_M.step()\n                #xm.optimizer_step(optG_M, barrier=True)\n                optG_M.zero_grad(set_to_none=True)\n                \n                optD_M.zero_grad(set_to_none=True)\n                loss_D_M = self.mGAN._get_loss_d(monet, photo)\n                loss_D_M.backward(torch.ones_like(loss_D_M))\n                optD_M.step()\n                #xm.optimizer_step(optD_M, barrier=True)\n                optD_M.zero_grad(set_to_none=True)\n                \n                optG_P.zero_grad(set_to_none=True)\n                loss_G_P = self._total_loss_G(photo, monet, 'p')\n                loss_G_P.backward(torch.ones_like(loss_G_P))\n                optG_P.step()\n                #xm.optimizer_step(optG_P, barrier=True)\n                optG_P.zero_grad(set_to_none=True)\n                \n                optD_P.zero_grad(set_to_none=True)\n                loss_D_P = self.pGAN._get_loss_d(monet, photo)\n                loss_D_P.backward(torch.ones_like(loss_D_P))\n                optD_P.step()\n                #xm.optimizer_step(optD_P, barrier=True)\n                optD_P.zero_grad(set_to_none=True)\n                \n                with torch.no_grad():\n                  if ((epoch % 10 == 0) & (epoch != 0)):\n                    torch.save(CGAN_inst.state_dict(), \"./weights.pt\")\n\n\n            with torch.no_grad():\n                print(f\"E: {epoch}; mDLoss: {loss_D_M.mean().item()}; mGLoss: {loss_G_M.mean().item()}; pDLoss: {loss_D_P.mean().item()}; pGLoss: {loss_G_P.mean().item()}\")\n","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:17:07.102221Z","iopub.execute_input":"2022-05-16T16:17:07.10243Z","iopub.status.idle":"2022-05-16T16:17:07.127095Z","shell.execute_reply.started":"2022-05-16T16:17:07.102407Z","shell.execute_reply":"2022-05-16T16:17:07.126435Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Input Pipeline","metadata":{}},{"cell_type":"code","source":"class MonetDataset(Dataset):\n    def __init__(self, data_dir, transform=None):\n        super(MonetDataset, self).__init__()\n        self.transform = transform\n        self._dev = device\n\n        self.monet_dir = data_dir + \"/monet_jpg/\"\n        self.photo_dir = data_dir + \"/photo_jpg/\"\n        self.monet_list = os.listdir(self.monet_dir)\n        self.photo_list = os.listdir(self.photo_dir)\n    \n\n    def __len__(self):\n        return 1000#max(len(self.monet_list), len(self.photo_list))\n    \n    def __getitem__(self, idx):\n        if torch.is_tensor(idx):\n            idx = idx.tolist()\n\n        monet = Image.open(self.monet_dir+self.monet_list[idx % len(self.monet_list)]).convert('RGB')\n        photo = Image.open(self.photo_dir+self.photo_list[idx % len(self.photo_list)]).convert('RGB')\n        \n        monet = self.transform(monet)\n        photo = self.transform(photo)\n        \n        sample = {'monet': monet, 'photo': photo}\n\n        return sample","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:17:07.128417Z","iopub.execute_input":"2022-05-16T16:17:07.130856Z","iopub.status.idle":"2022-05-16T16:17:07.140814Z","shell.execute_reply.started":"2022-05-16T16:17:07.130791Z","shell.execute_reply":"2022-05-16T16:17:07.140138Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"transform = transforms.Compose([\n    transforms.Resize(256),\n    transforms.ToTensor(),\n    transforms.Normalize(0.5, 0.5)\n])","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:17:07.141946Z","iopub.execute_input":"2022-05-16T16:17:07.142557Z","iopub.status.idle":"2022-05-16T16:17:07.149969Z","shell.execute_reply.started":"2022-05-16T16:17:07.142522Z","shell.execute_reply":"2022-05-16T16:17:07.149272Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_dir = '../input/gan-getting-started'\n\nds = MonetDataset(data_dir, transform=transform)\ndsloader = DataLoader(ds, batch_size=1, shuffle=True, num_workers=2)","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:17:07.153157Z","iopub.execute_input":"2022-05-16T16:17:07.153582Z","iopub.status.idle":"2022-05-16T16:17:07.16425Z","shell.execute_reply.started":"2022-05-16T16:17:07.153547Z","shell.execute_reply":"2022-05-16T16:17:07.163578Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Instantiate CycleGAN","metadata":{}},{"cell_type":"code","source":"CGAN_inst = CycleGAN()\n#load_path = \"./weights.pt\"\n#CGAN_inst.load_state_dict(torch.load(load_path))","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:17:07.16712Z","iopub.execute_input":"2022-05-16T16:17:07.168575Z","iopub.status.idle":"2022-05-16T16:17:09.17186Z","shell.execute_reply.started":"2022-05-16T16:17:07.168535Z","shell.execute_reply":"2022-05-16T16:17:09.171133Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Check Output Before Training","metadata":{}},{"cell_type":"code","source":"_, ax = plt.subplots(1, 2, figsize=(5, 2), dpi=150)\nfor i, img in enumerate(dsloader):\n    example_photo = img['photo']\n    example_photo_toplot = np.transpose(example_photo[0].detach().cpu().numpy(), [1, 2, 0])\n    img = (example_photo_toplot * 127.5 + 127.5).astype(np.uint8)\n    prediction = CGAN_inst.mGAN.gen(example_photo.to(device))[0].detach().cpu().numpy()\n    prediction = (prediction * 127.5 + 127.5).astype(np.uint8)\n    prediction = np.transpose(prediction, [1, 2, 0])\n\n    ax[0].imshow(img)\n    ax[1].imshow(prediction)\n    ax[0].set_title(\"Input Photo\")\n    ax[1].set_title(\"Monet-esque\")\n    ax[0].axis(\"off\")\n    ax[1].axis(\"off\")\n    break\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:17:09.175465Z","iopub.execute_input":"2022-05-16T16:17:09.176527Z","iopub.status.idle":"2022-05-16T16:17:09.567873Z","shell.execute_reply.started":"2022-05-16T16:17:09.17608Z","shell.execute_reply":"2022-05-16T16:17:09.564143Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Train","metadata":{}},{"cell_type":"code","source":"CGAN_inst.train(dsloader, n_epochs=8)","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:17:09.569328Z","iopub.execute_input":"2022-05-16T16:17:09.570148Z","iopub.status.idle":"2022-05-16T16:33:34.87639Z","shell.execute_reply.started":"2022-05-16T16:17:09.570099Z","shell.execute_reply":"2022-05-16T16:33:34.875144Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Save Weights","metadata":{}},{"cell_type":"code","source":"torch.save(CGAN_inst.state_dict(), './weights.pt')","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:33:34.879902Z","iopub.execute_input":"2022-05-16T16:33:34.880113Z","iopub.status.idle":"2022-05-16T16:33:35.67807Z","shell.execute_reply.started":"2022-05-16T16:33:34.880085Z","shell.execute_reply":"2022-05-16T16:33:35.677327Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Check Output","metadata":{}},{"cell_type":"code","source":"_, ax = plt.subplots(5, 2, figsize=(6, 12), dpi=150)\nfor i, img in enumerate(dsloader):\n    example_photo = img['photo']\n    example_photo_toplot = np.transpose(example_photo[0].detach().cpu().numpy(), [1, 2, 0])\n    im = (example_photo_toplot * 127.5 + 127.5).astype(np.uint8)\n    prediction = CGAN_inst.mGAN.gen(example_photo.to(device))[0].detach().cpu().numpy()\n    prediction = (prediction * 127.5 + 127.5).astype(np.uint8)\n    prediction = np.transpose(prediction, [1, 2, 0])\n\n    ax[i, 0].imshow(im)\n    ax[i, 1].imshow(prediction)\n    ax[i, 0].set_title(\"Input Photo\")\n    ax[i, 1].set_title(\"Monet-esque\")\n    ax[i, 0].axis(\"off\")\n    ax[i, 1].axis(\"off\")\n    if i == 4:\n      break\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:33:42.607164Z","iopub.execute_input":"2022-05-16T16:33:42.607355Z","iopub.status.idle":"2022-05-16T16:33:43.588151Z","shell.execute_reply.started":"2022-05-16T16:33:42.60733Z","shell.execute_reply":"2022-05-16T16:33:43.587445Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Prepare submission ZIP","metadata":{}},{"cell_type":"code","source":"! mkdir ../images\n\nfor i, img in enumerate(dsloader):\n    photo = img['photo']\n    photo_toplot = np.transpose(example_photo[0].detach().cpu().numpy(), [1, 2, 0])\n    im = (photo_toplot * 127.5 + 127.5).astype(np.uint8)\n    prediction = CGAN_inst.mGAN.gen(example_photo.to(device))[0].detach().cpu().numpy()\n    prediction = (prediction * 127.5 + 127.5).astype(np.uint8)\n    prediction = np.transpose(prediction, [1, 2, 0])\n    im = Image.fromarray(prediction)\n    im.save(\"../images/\" + str(i+1) + \".jpg\")","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:33:36.631142Z","iopub.execute_input":"2022-05-16T16:33:36.632648Z","iopub.status.idle":"2022-05-16T16:33:42.490895Z","shell.execute_reply.started":"2022-05-16T16:33:36.632605Z","shell.execute_reply":"2022-05-16T16:33:42.48996Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import shutil\nshutil.make_archive(\"/kaggle/working/images\", 'zip', \"/kaggle/images\")","metadata":{"execution":{"iopub.status.busy":"2022-05-16T16:33:42.492859Z","iopub.execute_input":"2022-05-16T16:33:42.493128Z","iopub.status.idle":"2022-05-16T16:33:42.604224Z","shell.execute_reply.started":"2022-05-16T16:33:42.493091Z","shell.execute_reply":"2022-05-16T16:33:42.603425Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}