{"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":"import glob\nimport os\nimport shutil\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pytorch_lightning as L\nimport torch\nimport torch.nn.functional as F\nimport torchvision.transforms as T\nfrom pytorch_lightning.trainer.supporters import CombinedLoader\nfrom torch import nn\nfrom torch.utils.data import DataLoader, Dataset\nfrom torchvision.io import read_image\nfrom torchvision.utils import make_grid, save_image\n\n_ = L.seed_everything(0, workers=True)","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","papermill":{"duration":12.994572,"end_time":"2023-03-19T01:57:44.984673","exception":false,"start_time":"2023-03-19T01:57:31.990101","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-29T15:09:43.388380Z","iopub.execute_input":"2023-03-29T15:09:43.388657Z","iopub.status.idle":"2023-03-29T15:09:52.072663Z","shell.execute_reply.started":"2023-03-29T15:09:43.388630Z","shell.execute_reply":"2023-03-29T15:09:52.071500Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def show_img(img_tensor, nrow, title=\"\"):\n    img_tensor = img_tensor.detach().cpu()*0.5 + 0.5\n    img_grid = make_grid(img_tensor, nrow=nrow).permute(1, 2, 0)\n    plt.figure(figsize=(18, 8))\n    plt.imshow(img_grid)\n    plt.axis(\"off\")\n    plt.title(title)\n    plt.show()","metadata":{"_kg_hide-input":false,"papermill":{"duration":0.020996,"end_time":"2023-03-19T01:57:45.062727","exception":false,"start_time":"2023-03-19T01:57:45.041731","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-29T15:09:52.074994Z","iopub.execute_input":"2023-03-29T15:09:52.075372Z","iopub.status.idle":"2023-03-29T15:09:52.082735Z","shell.execute_reply.started":"2023-03-29T15:09:52.075329Z","shell.execute_reply":"2023-03-29T15:09:52.081612Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CustomTransform(object):\n    def __init__(self, img_dim=256):\n        self.transform = T.Compose([\n            T.RandomResizedCrop((img_dim, img_dim),\n                                scale=(0.8, 1.0), ratio=(0.9, 1.1)),\n            T.RandomHorizontalFlip(p=0.5),\n        ])\n        \n    def __call__(self, img, stage=\"fit\"):\n        if stage == \"fit\":\n            img = self.transform(img)\n        return img/127.5 - 1","metadata":{"papermill":{"duration":0.021699,"end_time":"2023-03-19T01:57:45.140105","exception":false,"start_time":"2023-03-19T01:57:45.118406","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-29T15:09:52.084048Z","iopub.execute_input":"2023-03-29T15:09:52.084897Z","iopub.status.idle":"2023-03-29T15:09:52.098798Z","shell.execute_reply.started":"2023-03-29T15:09:52.084861Z","shell.execute_reply":"2023-03-29T15:09:52.097523Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CustomDataset(Dataset):\n    def __init__(self, filenames, transform, stage):\n        self.filenames = filenames\n        self.transform = transform\n        self.stage = stage\n        \n    def __len__(self):\n        return len(self.filenames)\n    \n    def __getitem__(self, idx):\n        img_name = self.filenames[idx]\n        img = read_image(img_name)\n        return self.transform(img, stage=self.stage)","metadata":{"papermill":{"duration":0.025818,"end_time":"2023-03-19T01:57:45.221633","exception":false,"start_time":"2023-03-19T01:57:45.195815","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-29T15:09:52.102063Z","iopub.execute_input":"2023-03-29T15:09:52.102444Z","iopub.status.idle":"2023-03-29T15:09:52.111112Z","shell.execute_reply.started":"2023-03-29T15:09:52.102409Z","shell.execute_reply":"2023-03-29T15:09:52.110032Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"MONET_DIR = \"/kaggle/input/gan-getting-started/monet_jpg/*.jpg\"\nPHOTO_DIR = \"/kaggle/input/gan-getting-started/photo_jpg/*.jpg\"\nLOADER_CONFIG = {\n    \"batch_size\": 8,\n    \"num_workers\": os.cpu_count(),\n    \"pin_memory\": torch.cuda.is_available(),\n}\ntransform = CustomTransform()","metadata":{"papermill":{"duration":0.019339,"end_time":"2023-03-19T01:57:45.297921","exception":false,"start_time":"2023-03-19T01:57:45.278582","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-29T15:09:52.112785Z","iopub.execute_input":"2023-03-29T15:09:52.113154Z","iopub.status.idle":"2023-03-29T15:09:52.195156Z","shell.execute_reply.started":"2023-03-29T15:09:52.113105Z","shell.execute_reply":"2023-03-29T15:09:52.194156Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CustomDataModule(L.LightningDataModule):\n    def __init__(\n        self, \n        monet_dir=MONET_DIR,\n        photo_dir=PHOTO_DIR,\n        loader_config=LOADER_CONFIG,\n        transform=transform,\n        mode=\"max_size_cycle\",\n    ):\n        super().__init__()\n        self.monet_filenames = sorted(glob.glob(monet_dir))\n        self.photo_filenames = sorted(glob.glob(photo_dir))\n        self.loader_config = loader_config\n        self.transform = transform\n        self.mode = mode\n        \n    def setup(self, stage):\n        if stage == \"fit\":\n            self.train_monet = CustomDataset(self.monet_filenames, self.transform, stage)\n            self.train_photo = CustomDataset(self.photo_filenames, self.transform, stage)\n        \n        elif stage == \"predict\":\n            self.predict = CustomDataset(self.photo_filenames, self.transform, stage)\n            \n    def train_dataloader(self):\n        loader_monet = DataLoader(\n            self.train_monet, \n            shuffle=True, \n            drop_last=True, \n            **self.loader_config,\n        )\n        loader_photo = DataLoader(\n            self.train_photo, \n            shuffle=True,\n            drop_last=True,\n            **self.loader_config,\n        )\n        loaders = {\"monet\": loader_monet, \"photo\": loader_photo}\n        return CombinedLoader(loaders, mode=self.mode)\n    \n    def predict_dataloader(self):\n        return DataLoader(self.predict, shuffle=False, **self.loader_config)","metadata":{"papermill":{"duration":0.022601,"end_time":"2023-03-19T01:57:45.331838","exception":false,"start_time":"2023-03-19T01:57:45.309237","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-29T15:09:52.197180Z","iopub.execute_input":"2023-03-29T15:09:52.197977Z","iopub.status.idle":"2023-03-29T15:09:52.209215Z","shell.execute_reply.started":"2023-03-29T15:09:52.197940Z","shell.execute_reply":"2023-03-29T15:09:52.208085Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"SAMPLE_SIZE=5\ndm_sample = CustomDataModule(loader_config={\"batch_size\": SAMPLE_SIZE})\n\ndm_sample.setup(\"fit\")\ntrain_loader = dm_sample.train_dataloader()\nmonet_samples = next(iter(train_loader))[\"monet\"]\n\ndm_sample.setup(\"predict\")\npredict_loader = dm_sample.predict_dataloader()\nphoto_samples = next(iter(predict_loader))\n\nshow_img(monet_samples, nrow=SAMPLE_SIZE, title=\"Samples of Monet Paintings\")\nshow_img(photo_samples, nrow=SAMPLE_SIZE, title=\"Samples of Photos\")","metadata":{"papermill":{"duration":1.301484,"end_time":"2023-03-19T01:57:46.667097","exception":false,"start_time":"2023-03-19T01:57:45.365613","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-29T15:09:52.211063Z","iopub.execute_input":"2023-03-29T15:09:52.211912Z","iopub.status.idle":"2023-03-29T15:09:53.921283Z","shell.execute_reply.started":"2023-03-29T15:09:52.211875Z","shell.execute_reply":"2023-03-29T15:09:53.920377Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Downsampling(nn.Module):\n    def __init__(\n        self,\n        in_channels,\n        out_channels,\n        norm=True,\n        kernel_size=4,\n        stride=2,\n        padding=1,\n    ):\n        super().__init__()\n        self.block = nn.Sequential(\n            nn.Conv2d(in_channels, out_channels, kernel_size=kernel_size,\n                      stride=stride, padding=padding, bias=False)\n        )\n        if norm:\n            self.block.append(nn.InstanceNorm2d(out_channels, affine=True))\n        self.block.append(nn.LeakyReLU(0.2))\n        \n    def forward(self, x):\n        return self.block(x)","metadata":{"papermill":{"duration":0.044778,"end_time":"2023-03-19T01:57:47.150705","exception":false,"start_time":"2023-03-19T01:57:47.105927","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-29T15:09:53.922919Z","iopub.execute_input":"2023-03-29T15:09:53.923609Z","iopub.status.idle":"2023-03-29T15:09:53.931623Z","shell.execute_reply.started":"2023-03-29T15:09:53.923571Z","shell.execute_reply":"2023-03-29T15:09:53.930341Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Upsampling(nn.Module):\n    def __init__(\n        self,\n        in_channels,\n        out_channels,\n        dropout=False,\n        kernel_size=4,\n        stride=2,\n        padding=1,\n        output_padding=0,\n    ):\n        super().__init__()\n        self.block = nn.Sequential(\n            nn.ConvTranspose2d(in_channels, out_channels, kernel_size=kernel_size, stride=stride, \n                               padding=padding, output_padding=output_padding, bias=False),\n            nn.InstanceNorm2d(out_channels, affine=True),\n        )\n        if dropout:\n            self.block.append(nn.Dropout(0.5))\n        self.block.append(nn.ReLU())\n        \n    def forward(self, x):\n        return self.block(x)","metadata":{"papermill":{"duration":0.044362,"end_time":"2023-03-19T01:57:47.359186","exception":false,"start_time":"2023-03-19T01:57:47.314824","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-29T15:09:53.933302Z","iopub.execute_input":"2023-03-29T15:09:53.933988Z","iopub.status.idle":"2023-03-29T15:09:53.947890Z","shell.execute_reply.started":"2023-03-29T15:09:53.933949Z","shell.execute_reply":"2023-03-29T15:09:53.946677Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Generator(nn.Module):\n    def __init__(self, in_channels, out_channels, hid_channels):\n        super().__init__()\n        self.downsampling_blocks = nn.Sequential(\n            Downsampling(in_channels, hid_channels, norm=False), # 64x128x128\n            Downsampling(hid_channels, hid_channels*2), # 128x64x64\n            Downsampling(hid_channels*2, hid_channels*4), # 256x32x32\n            Downsampling(hid_channels*4, hid_channels*8), # 512x16x16\n            Downsampling(hid_channels*8, hid_channels*8), # 512x8x8\n            Downsampling(hid_channels*8, hid_channels*8), # 512x4x4\n            Downsampling(hid_channels*8, hid_channels*8), # 512x2x2\n            Downsampling(hid_channels*8, hid_channels*8, norm=False), # 512x1x1\n        )\n        self.upsampling_blocks = nn.Sequential(\n            Upsampling(hid_channels*8, hid_channels*8, dropout=True), # (512+512)x2x2\n            Upsampling(hid_channels*16, hid_channels*8, dropout=True), # (512+512)x4x4\n            Upsampling(hid_channels*16, hid_channels*8, dropout=True), # (512+512)x8x8\n            Upsampling(hid_channels*16, hid_channels*8), # (512+512)x16x16\n            Upsampling(hid_channels*16, hid_channels*4), # (256+256)x32x32\n            Upsampling(hid_channels*8, hid_channels*2), # (128+128)x64x64\n            Upsampling(hid_channels*4, hid_channels), # (64+64)x128x128\n        )\n        self.feature_block = nn.Sequential(\n            nn.ConvTranspose2d(hid_channels*2, out_channels,\n                               kernel_size=4, stride=2, padding=1), # 3x256x256\n            nn.Tanh(),\n        )\n        \n    def forward(self, x):\n        skips = []\n        for down in self.downsampling_blocks:\n            x = down(x)\n            skips.append(x)\n        skips = reversed(skips[:-1])\n        \n        for up, skip in zip(self.upsampling_blocks, skips):\n            x = up(x)\n            x = torch.cat([x, skip], dim=1)\n        return self.feature_block(x)","metadata":{"papermill":{"duration":0.047175,"end_time":"2023-03-19T01:57:48.061105","exception":false,"start_time":"2023-03-19T01:57:48.01393","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-29T15:09:53.953029Z","iopub.execute_input":"2023-03-29T15:09:53.953871Z","iopub.status.idle":"2023-03-29T15:09:53.965552Z","shell.execute_reply.started":"2023-03-29T15:09:53.953833Z","shell.execute_reply":"2023-03-29T15:09:53.964458Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Discriminator(nn.Module):\n    def __init__(self, in_channels, hid_channels):\n        super().__init__()\n        self.block = nn.Sequential(\n            Downsampling(in_channels, hid_channels, norm=False), # 64x128x128\n            Downsampling(hid_channels, hid_channels*2), # 128x64x64\n            Downsampling(hid_channels*2, hid_channels*4), # 256x32x32\n            Downsampling(hid_channels*4, hid_channels*8, stride=1), # 512x31x31\n            nn.Conv2d(hid_channels*8, 1, kernel_size=4, padding=1), # 1x30x30\n        )\n        \n    def forward(self, x):\n        return self.block(x)","metadata":{"papermill":{"duration":0.043903,"end_time":"2023-03-19T01:57:48.343071","exception":false,"start_time":"2023-03-19T01:57:48.299168","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-29T15:09:53.966829Z","iopub.execute_input":"2023-03-29T15:09:53.967764Z","iopub.status.idle":"2023-03-29T15:09:53.978537Z","shell.execute_reply.started":"2023-03-29T15:09:53.967725Z","shell.execute_reply":"2023-03-29T15:09:53.977691Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IN_CHANNELS = 3\nOUT_CHANNELS = 3\nHID_CHANNELS = 64\nLR = 2e-4\nBETAS = (0.5, 0.999)\nLAMBDA = 10\nDISPLAY_EPOCHS = 5","metadata":{"papermill":{"duration":0.042883,"end_time":"2023-03-19T01:57:48.564164","exception":false,"start_time":"2023-03-19T01:57:48.521281","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-29T15:09:53.980428Z","iopub.execute_input":"2023-03-29T15:09:53.980827Z","iopub.status.idle":"2023-03-29T15:09:53.992814Z","shell.execute_reply.started":"2023-03-29T15:09:53.980791Z","shell.execute_reply":"2023-03-29T15:09:53.991693Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CycleGAN(L.LightningModule):\n    def __init__(\n        self, \n        in_channels=IN_CHANNELS,\n        out_channels=OUT_CHANNELS, \n        hid_channels=HID_CHANNELS,\n        lr=LR,\n        betas=BETAS,\n        lambda_w=LAMBDA,\n        display_epochs=DISPLAY_EPOCHS,\n        photo_samples=photo_samples,\n    ):\n        super().__init__()\n        self.lr = lr\n        self.betas = betas\n        self.lambda_w = lambda_w\n        self.display_epochs = display_epochs\n        self.photo_samples = photo_samples\n        self.loss_history = []\n        self.epoch_count = 0\n        \n        self.gen_PM = Generator(in_channels, out_channels, hid_channels)\n        self.gen_MP = Generator(in_channels, out_channels, hid_channels)\n        self.disc_M = Discriminator(in_channels, hid_channels)\n        self.disc_P = Discriminator(in_channels, hid_channels)\n        self.reset_parameters()\n        \n    def forward(self, z):\n        return self.gen_PM(z)\n    \n    def weights_init(self, m):\n        if isinstance(m, (nn.Conv2d, nn.ConvTranspose2d, nn.InstanceNorm2d)):\n            nn.init.normal_(m.weight, 0., 0.02)\n            if m.bias is not None:\n                nn.init.constant_(m.bias, 0.)\n                \n    def reset_parameters(self):\n        self.gen_PM = self.gen_PM.apply(self.weights_init)\n        self.gen_MP = self.gen_MP.apply(self.weights_init)\n        self.disc_M = self.disc_M.apply(self.weights_init)\n        self.disc_P = self.disc_P.apply(self.weights_init)\n        \n    def adv_criterion(self, y_hat, y):\n        return F.binary_cross_entropy_with_logits(y_hat, y)\n    \n    def recon_criterion(self, y_hat, y):\n        return F.l1_loss(y_hat, y)\n    \n    def adv_loss(self, fake_Y, disc_Y):\n        fake_Y_hat = disc_Y(fake_Y)\n        valid = torch.ones_like(fake_Y_hat)\n        adv_loss_XY = self.adv_criterion(fake_Y_hat, valid)\n        return adv_loss_XY\n    \n    def id_loss(self, real_Y, gen_XY):\n        id_Y = gen_XY(real_Y)\n        id_loss_Y = self.recon_criterion(id_Y, real_Y)\n        return 0.5 * self.lambda_w * id_loss_Y\n    \n    def cycle_loss(self, real_Y, fake_X, gen_XY):\n        cycle_Y = gen_XY(fake_X)\n        cycle_loss_Y = self.recon_criterion(cycle_Y, real_Y)\n        return self.lambda_w * cycle_loss_Y\n        \n    def gen_loss(self, real_X, real_Y, gen_XY, gen_YX, disc_Y):\n        adv_loss_XY = self.adv_loss(gen_XY(real_X), disc_Y)\n\n        id_loss_Y = self.id_loss(real_Y, gen_XY)\n        \n        cycle_loss_Y = self.cycle_loss(real_Y, gen_YX(real_Y), gen_XY)\n        cycle_loss_X = self.cycle_loss(real_X, gen_XY(real_X), gen_YX)\n        total_cycle_loss = cycle_loss_X + cycle_loss_Y\n        \n        gen_loss_XY = adv_loss_XY + id_loss_Y + total_cycle_loss\n        return gen_loss_XY\n    \n    def disc_loss(self, real_Y, fake_Y, disc_Y, smooth=0.9):\n        real_Y_hat = disc_Y(real_Y)\n        valid = torch.full_like(real_Y_hat, fill_value=smooth)\n        real_loss_Y = self.adv_criterion(real_Y_hat, valid)\n        \n        fake_Y_hat = disc_Y(fake_Y.detach())\n        fake = torch.zeros_like(fake_Y_hat)\n        fake_loss_Y = self.adv_criterion(fake_Y_hat, fake)\n        \n        disc_loss_Y = (fake_loss_Y+real_loss_Y) * 0.5\n        return disc_loss_Y\n    \n    def configure_optimizers(self):\n        params = {\n            \"lr\": self.lr,\n            \"betas\": self.betas,\n        }\n        opt_gen_PM = torch.optim.Adam(self.gen_PM.parameters(), **params)\n        opt_gen_MP = torch.optim.Adam(self.gen_MP.parameters(), **params)\n        opt_disc_M = torch.optim.Adam(self.disc_M.parameters(), **params)\n        opt_disc_P = torch.optim.Adam(self.disc_P.parameters(), **params)\n        \n        return [opt_gen_PM, opt_gen_MP, opt_disc_M, opt_disc_P], []\n    \n    def training_step(self, batch, batch_idx, optimizer_idx):\n        real_M = batch[\"monet\"]\n        real_P = batch[\"photo\"]\n        if optimizer_idx == 0:\n            gen_loss_PM = self.gen_loss(real_P, real_M, \n                                        self.gen_PM, self.gen_MP, self.disc_M)\n            return gen_loss_PM\n        \n        if optimizer_idx == 1:\n            gen_loss_MP = self.gen_loss(real_M, real_P,\n                                        self.gen_MP, self.gen_PM, self.disc_P)\n            return gen_loss_MP\n        \n        if optimizer_idx == 2:\n            disc_loss_M = self.disc_loss(real_M, self.gen_PM(real_P), self.disc_M)\n            return disc_loss_M\n        \n        if optimizer_idx == 3:\n            disc_loss_P = self.disc_loss(real_P, self.gen_MP(real_M), self.disc_P)\n            return disc_loss_P\n    \n    def training_epoch_end(self, outputs):\n        self.epoch_count += 1\n        \n        losses = []\n        for j in range(4):\n            loss = np.mean([out[j][\"loss\"].item() for out in outputs])\n            losses.append(loss)\n        self.loss_history.append(losses)\n        print(\n            f\"Epoch {self.epoch_count} -\",\n            f\"gen_loss_PM: {losses[0]:.5f} -\",\n            f\"gen_loss_MP: {losses[1]:.5f} -\",\n            f\"disc_loss_M: {losses[2]:.5f} -\",\n            f\"disc_loss_P: {losses[3]:.5f}\",\n        )\n        \n        if self.epoch_count%self.display_epochs==0 or self.epoch_count==1:\n            gen_monets = self(self.photo_samples.to(self.device)).detach().cpu()\n            show_img(\n                torch.cat([self.photo_samples, gen_monets]),\n                nrow=len(self.photo_samples),\n                title=f\"Epoch {self.epoch_count}: Photo-to-Monet Translation\",\n            )\n            \n    def predict_step(self, batch, batch_idx):\n        return self(batch)\n    \n    def loss_curves(self):\n        labels = [\"gen_loss_PM\", \"gen_loss_MP\", \"disc_loss_M\", \"disc_loss_P\"]\n        titles = [\"Generator Loss Curves\", \"Discriminator Loss Curves\"]\n        num_epochs = len(self.loss_history)\n        plt.figure(figsize=(18, 4.5))\n        for j in range(4):\n            if j%2 == 0:\n                plt.subplot(1, 2, (j//2)+1)\n                plt.title(titles[j//2])\n                plt.ylabel(\"Loss\")\n                plt.xlabel(\"Epoch\")\n            plt.plot(\n                np.arange(1, num_epochs+1),\n                [losses[j] for losses in self.loss_history],\n                label=labels[j],\n            )\n            plt.legend(loc=\"upper right\")","metadata":{"papermill":{"duration":0.064437,"end_time":"2023-03-19T01:57:48.661507","exception":false,"start_time":"2023-03-19T01:57:48.59707","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-29T15:09:53.994593Z","iopub.execute_input":"2023-03-29T15:09:53.994982Z","iopub.status.idle":"2023-03-29T15:09:54.025495Z","shell.execute_reply.started":"2023-03-29T15:09:53.994911Z","shell.execute_reply":"2023-03-29T15:09:54.024351Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"TRAIN_CONFIG = {\n    \"accelerator\": \"gpu\" if torch.cuda.is_available() else \"cpu\",\n    \"devices\": 1,\n    \"logger\": False,\n    \"enable_checkpointing\": torch.cuda.is_available(),\n    \"max_epochs\": 20,\n}","metadata":{"execution":{"iopub.status.busy":"2023-03-29T15:09:54.026995Z","iopub.execute_input":"2023-03-29T15:09:54.027608Z","iopub.status.idle":"2023-03-29T15:09:54.039321Z","shell.execute_reply.started":"2023-03-29T15:09:54.027569Z","shell.execute_reply":"2023-03-29T15:09:54.038344Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dm = CustomDataModule()\nmodel = CycleGAN()\ntrainer = L.Trainer(**TRAIN_CONFIG)\n\ntrainer.fit(model, datamodule=dm)","metadata":{"papermill":{"duration":15422.135167,"end_time":"2023-03-19T06:14:51.028526","exception":false,"start_time":"2023-03-19T01:57:48.893359","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-29T15:09:54.041048Z","iopub.execute_input":"2023-03-29T15:09:54.041468Z","iopub.status.idle":"2023-03-29T19:40:14.653905Z","shell.execute_reply.started":"2023-03-29T15:09:54.041422Z","shell.execute_reply":"2023-03-29T19:40:14.652663Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.loss_curves()","metadata":{"papermill":{"duration":0.651238,"end_time":"2023-03-19T06:14:52.570658","exception":false,"start_time":"2023-03-19T06:14:51.91942","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-29T19:40:14.656817Z","iopub.execute_input":"2023-03-29T19:40:14.657180Z","iopub.status.idle":"2023-03-29T19:40:15.049242Z","shell.execute_reply.started":"2023-03-29T19:40:14.657126Z","shell.execute_reply":"2023-03-29T19:40:15.048128Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictions = trainer.predict(model, datamodule=dm)","metadata":{"papermill":{"duration":126.035671,"end_time":"2023-03-19T06:16:59.658291","exception":false,"start_time":"2023-03-19T06:14:53.62262","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-29T19:40:15.050794Z","iopub.execute_input":"2023-03-29T19:40:15.051170Z","iopub.status.idle":"2023-03-29T19:40:46.372648Z","shell.execute_reply.started":"2023-03-29T19:40:15.051115Z","shell.execute_reply":"2023-03-29T19:40:46.371505Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.makedirs(\"../images\", exist_ok=True)\n\nidx = 0\nfor tensor in predictions:\n    for monet in tensor:\n        save_image((monet.squeeze()*0.5+0.5), fp=f\"../images/{idx}.jpg\")\n        idx += 1\n\nshutil.make_archive(\"/kaggle/working/images\", \"zip\", \"/kaggle/images\")","metadata":{"papermill":{"duration":31.787796,"end_time":"2023-03-19T06:17:31.88707","exception":false,"start_time":"2023-03-19T06:17:00.099274","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2023-03-29T19:40:46.374484Z","iopub.execute_input":"2023-03-29T19:40:46.374882Z","iopub.status.idle":"2023-03-29T19:41:20.173420Z","shell.execute_reply.started":"2023-03-29T19:40:46.374827Z","shell.execute_reply":"2023-03-29T19:41:20.172438Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":" ---","metadata":{"papermill":{"duration":0.149773,"end_time":"2023-03-19T06:17:32.198249","exception":false,"start_time":"2023-03-19T06:17:32.048476","status":"completed"},"tags":[]}}]}