{"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":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\n# for dirname, _, filenames in os.walk('/kaggle/input'):\n#     for filename in filenames:\n#         print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session\n# Directory\ndirectory = \"images\"\n  \n# Parent Directory path\nparent_dir = \"/kaggle/working/\"\n  \n# Path\npath = os.path.join(parent_dir, directory)\n  \n# Create the directory\n# 'GeeksForGeeks' in\n# '/home / User / Documents'\nif not os.path.exists(path):\n    os.mkdir(path)\n\nif os.path.exists('/kaggle/working/images.zip'):\n    os.remove('/kaggle/working/images.zip')\n\n\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-07-30T09:18:06.970552Z","iopub.execute_input":"2021-07-30T09:18:06.970958Z","iopub.status.idle":"2021-07-30T09:18:06.984585Z","shell.execute_reply.started":"2021-07-30T09:18:06.970875Z","shell.execute_reply":"2021-07-30T09:18:06.983155Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Config params**","metadata":{}},{"cell_type":"code","source":"import torch\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2\n\nDEVICE = \"cuda\" if torch.cuda.is_available() else \"cpu\"\nBASE_DIR = \"/kaggle/input/gan-getting-started\"\nOUTPUT_DIR = \"/kaggle/working/images\"\nTRAIN_DIR = BASE_DIR+\"/data/train\"\nVAL_DIR = BASE_DIR+\"/data/val\"\nBATCH_SIZE = 8\nLEARNING_RATE = 0.0002\nLAMBDA_IDENTITY = 0.1\nLAMBDA_CYCLE = 10\nNUM_WORKERS = 2\nNUM_EPOCHS = 120\nLOAD_MODEL = False\nSAVE_MODEL = False\nCHECKPOINT_GEN_H = \"genh.pth.tar\"\nCHECKPOINT_GEN_Z = \"genz.pth.tar\"\nCHECKPOINT_CRITIC_H = \"critich.pth.tar\"\nCHECKPOINT_CRITIC_Z = \"criticz.pth.tar\"\n\n","metadata":{"execution":{"iopub.status.busy":"2021-07-30T09:18:06.986215Z","iopub.execute_input":"2021-07-30T09:18:06.986668Z","iopub.status.idle":"2021-07-30T09:18:10.187594Z","shell.execute_reply.started":"2021-07-30T09:18:06.98663Z","shell.execute_reply":"2021-07-30T09:18:10.186591Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **transforms**","metadata":{}},{"cell_type":"code","source":"transforms = A.Compose(\n    [\n        A.Resize(width=256, height=256),\n        A.HorizontalFlip(p=0.5),\n        A.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5], max_pixel_value=255),\n        ToTensorV2(),\n     ],\n    additional_targets={\"image0\": \"image\"},\n)\n\ntransforms_val = A.Compose(\n    [\n        A.Resize(width=256, height=256),\n        A.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5], max_pixel_value=255),\n        ToTensorV2(),\n     ],\n    additional_targets={\"image0\": \"image\"},\n)\ntransforms_2 = A.Compose(\n    [\n        A.Resize(width=256, height=256),\n        A.RandomCrop(224,224),\n        A.OneOf([\n            A.MotionBlur(p=1),\n            A.OpticalDistortion(p=1),\n            A.GaussNoise(p=1)\n        ], p=0.1),\n        A.OneOf([\n            A.HorizontalFlip(p=1),\n            A.RandomRotate90(p=1),\n            A.VerticalFlip(p=1)\n        ], p=0.3),\n        A.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5], max_pixel_value=255),\n        ToTensorV2(),\n     ],\n    additional_targets={\"image0\": \"image\"},\n)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\n\nclass Block(nn.Module):\n    def __init__(self, in_channels, out_channels, stride):\n        super().__init__()\n        self.conv = nn.Sequential(\n            nn.Conv2d(in_channels, out_channels, 4, stride, 1, bias=True, padding_mode=\"reflect\"),\n            nn.InstanceNorm2d(out_channels),\n            nn.LeakyReLU(0.2, inplace=True),\n        )\n\n    def forward(self, x):\n        return self.conv(x)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Discriminator(nn.Module):\n    def __init__(self, in_channels=3, features=[64, 128, 256, 512]):\n        super().__init__()\n        self.initial = nn.Sequential(\n            nn.Conv2d(\n                in_channels,\n                features[0],\n                kernel_size=4,\n                stride=2,\n                padding=1,\n                padding_mode=\"reflect\",\n            ),\n            nn.LeakyReLU(0.2, inplace=True),\n        )\n\n        layers = []\n        in_channels = features[0]\n        for feature in features[1:]:\n            layers.append(Block(in_channels, feature, stride=1 if feature==features[-1] else 2))\n            in_channels = feature\n        layers.append(nn.Conv2d(in_channels, 1, kernel_size=4, stride=1, padding=1, padding_mode=\"reflect\"))\n        self.model = nn.Sequential(*layers)\n\n    def forward(self, x):\n        x = self.initial(x)\n        return torch.sigmoid(self.model(x))","metadata":{"execution":{"iopub.status.busy":"2021-07-30T09:18:10.191568Z","iopub.execute_input":"2021-07-30T09:18:10.191839Z","iopub.status.idle":"2021-07-30T09:18:10.916871Z","shell.execute_reply.started":"2021-07-30T09:18:10.191813Z","shell.execute_reply":"2021-07-30T09:18:10.915894Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\n\nclass ConvBlock(nn.Module):\n    def __init__(self, in_channels, out_channels, down=True, use_act=True, **kwargs):\n        super().__init__()\n        self.conv = nn.Sequential(\n            nn.Conv2d(in_channels, out_channels, padding_mode=\"reflect\", **kwargs)\n            if down\n            else nn.ConvTranspose2d(in_channels, out_channels, **kwargs),\n            nn.InstanceNorm2d(out_channels),\n            nn.ReLU(inplace=True) if use_act else nn.Identity()\n        )\n\n    def forward(self, x):\n        return self.conv(x)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class ResidualBlock(nn.Module):\n    def __init__(self, channels):\n        super().__init__()\n        self.block = nn.Sequential(\n            ConvBlock(channels, channels, kernel_size=3, padding=1),\n            ConvBlock(channels, channels, use_act=False, kernel_size=3, padding=1),\n        )\n\n    def forward(self, x):\n        return x + self.block(x)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Generator(nn.Module):\n    def __init__(self, img_channels, num_features = 64, num_residuals=9):\n        super().__init__()\n        self.initial = nn.Sequential(\n            nn.Conv2d(img_channels, num_features, kernel_size=7, stride=1, padding=3, padding_mode=\"reflect\"),\n            nn.InstanceNorm2d(num_features),\n            nn.ReLU(inplace=True),\n        )\n        self.down_blocks = nn.ModuleList(\n            [\n                ConvBlock(num_features, num_features*2, kernel_size=3, stride=2, padding=1),\n                ConvBlock(num_features*2, num_features*4, kernel_size=3, stride=2, padding=1),\n            ]\n        )\n        self.res_blocks = nn.Sequential(\n            *[ResidualBlock(num_features*4) for _ in range(num_residuals)]\n        )\n        self.up_blocks = nn.ModuleList(\n            [\n                ConvBlock(num_features*4, num_features*2, down=False, kernel_size=3, stride=2, padding=1, output_padding=1),\n                ConvBlock(num_features*2, num_features*1, down=False, kernel_size=3, stride=2, padding=1, output_padding=1),\n            ]\n        )\n\n        self.last = nn.Conv2d(num_features*1, img_channels, kernel_size=7, stride=1, padding=3, padding_mode=\"reflect\")\n\n    def forward(self, x):\n        x = self.initial(x)\n        for layer in self.down_blocks:\n            x = layer(x)\n        x = self.res_blocks(x)\n        for layer in self.up_blocks:\n            x = layer(x)\n        return torch.tanh(self.last(x))\n\n","metadata":{"execution":{"iopub.status.busy":"2021-07-30T09:18:10.918759Z","iopub.execute_input":"2021-07-30T09:18:10.919159Z","iopub.status.idle":"2021-07-30T09:18:11.224983Z","shell.execute_reply.started":"2021-07-30T09:18:10.919116Z","shell.execute_reply":"2021-07-30T09:18:11.224062Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from PIL import Image\nimport os\nfrom torch.utils.data import Dataset\nimport numpy as np\n\nclass PhotoMonetDataset(Dataset):\n    def __init__(self, root_photo, root_monet, transform=None, photo_len=300, monet_len=30):\n        self.root_photo = root_photo\n        self.root_monet = root_monet\n        self.transform = transform\n\n        self.photo_images = os.listdir(root_photo)[:photo_len]\n        self.monet_images = os.listdir(root_monet)[:monet_len]\n        self.photo_len = photo_len\n        self.monet_len = monet_len\n        self.length_dataset = max(self.photo_len, self.monet_len) # 1500, 300\n#         self.photo_len = len(self.photo_images)\n#         self.monet_len = len(self.monet_images)\n        # self.all_monet_images = []\n        # self.all_photo_images = []\n        \n#         for x in self.monet_images:\n#             self.all_monet_images.append(self.transform(image=np.array(Image.open(os.path.join(self.root_monet, x)).convert(\"RGB\")))[\"image\"])\n            \n#         for x in self.photo_images:\n#             self.all_photo_images.append(self.transform(image=np.array(Image.open(os.path.join(self.root_photo, x)).convert(\"RGB\")))[\"image\"])\n\n    def __len__(self):\n        return self.length_dataset\n\n    def __getitem__(self, index):\n#         photo_img = self.all_photo_images[index % self.photo_len]\n#         monet_img = self.all_monet_images[index % self.monet_len]\n#         return photo_img, monet_img\n        photo_img = self.photo_images[index % self.photo_len]\n        monet_img = self.monet_images[index % self.monet_len]\n\n        photo_path = os.path.join(self.root_photo, photo_img)\n        monet_path = os.path.join(self.root_monet, monet_img)\n\n        photo_img = np.array(Image.open(photo_path).convert(\"RGB\"))\n        monet_img = np.array(Image.open(monet_path).convert(\"RGB\"))\n\n        if self.transform:\n            augmentations = self.transform(image=photo_img, image0=monet_img)\n            photo_img = augmentations[\"image\"]\n            monet_img = augmentations[\"image0\"]\n\n        return photo_img, monet_img","metadata":{"execution":{"iopub.status.busy":"2021-07-30T09:18:11.226312Z","iopub.execute_input":"2021-07-30T09:18:11.226822Z","iopub.status.idle":"2021-07-30T09:18:11.237589Z","shell.execute_reply.started":"2021-07-30T09:18:11.226783Z","shell.execute_reply":"2021-07-30T09:18:11.236753Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import random, torch, os, numpy as np\nimport sys\n\nimport torch.nn as nn\n\nimport copy\n\ndef save_checkpoint(model, optimizer, filename=\"my_checkpoint.pth.tar\"):\n    print(\"=> Saving checkpoint\")\n    checkpoint = {\n        \"state_dict\": model.state_dict(),\n        \"optimizer\": optimizer.state_dict(),\n    }\n    torch.save(checkpoint, filename)\n\n\ndef load_checkpoint(checkpoint_file, model, optimizer, lr):\n    print(\"=> Loading checkpoint\")\n    checkpoint = torch.load(checkpoint_file, map_location=DEVICE)\n    model.load_state_dict(checkpoint[\"state_dict\"])\n    optimizer.load_state_dict(checkpoint[\"optimizer\"])\n\n    # If we don't do this then it will just have learning rate of old checkpoint\n    # and it will lead to many hours of debugging \\:\n    for param_group in optimizer.param_groups:\n        param_group[\"lr\"] = lr\n\n\ndef seed_everything(seed=42):\n    os.environ[\"PYTHONHASHSEED\"] = str(seed)\n    random.seed(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.cuda.manual_seed_all(seed)\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = False\n\n\nclass LambdaLR():\n    def __init__(self, n_epochs, offset, decay_start_epoch):\n        assert ((n_epochs - decay_start_epoch) > 0), \"Decay must start before the training session ends!\"\n        self.n_epochs = n_epochs\n        self.offset = offset\n        self.decay_start_epoch = decay_start_epoch\n\n    def step(self, epoch):\n        return 1.0 - max(0, epoch + self.offset - self.decay_start_epoch)/(self.n_epochs - self.decay_start_epoch)\n\n\n","metadata":{"execution":{"iopub.status.busy":"2021-07-30T09:18:11.238825Z","iopub.execute_input":"2021-07-30T09:18:11.239187Z","iopub.status.idle":"2021-07-30T09:18:11.254216Z","shell.execute_reply.started":"2021-07-30T09:18:11.239146Z","shell.execute_reply":"2021-07-30T09:18:11.252913Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy\nimport numpy as np\nimport torch\nimport matplotlib.pyplot as plt\nimport sys\nfrom torch.utils.data import DataLoader\nimport torch.nn as nn\nimport torch.optim as optim\n\nfrom tqdm import tqdm\nfrom torchvision.utils import save_image\n\n\n\ndef train_fn(disc_M, disc_P, gen_P, gen_M, loader, opt_disc, opt_gen, l1, mse, d_scaler, g_scaler):\n    M_reals = 0\n    M_fakes = 0\n    loop = tqdm(loader, leave=True)\n\n    ret_D_loss = [0]\n    ret_loss_G_P = [0]\n    ret_loss_G_H = [0]\n    ret_cycle_photo_loss = [0]\n    ret_cycle_monet_loss = [0]\n    ret_identity_monet_loss = [0]\n    ret_identity_photo_loss = [0]\n    ret_G_loss = [0]\n    \n    for idx, (photo, monet) in enumerate(loop):\n        photo = photo.to(DEVICE)\n        monet = monet.to(DEVICE)\n\n        # Train Discriminators H and Z\n        with torch.cuda.amp.autocast():\n            fake_monet = gen_M(photo)\n            D_M_real = disc_M(monet)\n            D_M_fake = disc_M(fake_monet.detach())\n            M_reals += D_M_real.mean().item()\n            M_fakes += D_M_fake.mean().item()\n            D_M_real_loss = mse(D_M_real, torch.ones_like(D_M_real))\n            D_M_fake_loss = mse(D_M_fake, torch.zeros_like(D_M_fake))\n            D_M_loss = D_M_real_loss + D_M_fake_loss\n\n            fake_photo = gen_P(monet)\n            D_P_real = disc_P(photo)\n            D_P_fake = disc_P(fake_photo.detach())\n            D_P_real_loss = mse(D_P_real, torch.ones_like(D_P_real))\n            D_P_fake_loss = mse(D_P_fake, torch.zeros_like(D_P_fake))\n            D_P_loss = D_P_real_loss + D_P_fake_loss\n\n            # put it togethor\n            D_loss = (D_M_loss + D_P_loss) / 2\n\n        opt_disc.zero_grad()\n        d_scaler.scale(D_loss).backward()\n        d_scaler.step(opt_disc)\n        d_scaler.update()\n\n        # Train Generators H and Z\n        with torch.cuda.amp.autocast():\n            # adversarial loss for both generators\n            D_H_fake = disc_M(fake_monet)\n            D_P_fake = disc_P(fake_photo)\n            loss_G_H = mse(D_H_fake, torch.ones_like(D_H_fake))\n            loss_G_P = mse(D_P_fake, torch.ones_like(D_P_fake))\n\n            # cycle loss\n            cycle_photo = gen_P(fake_monet)\n            cycle_monet = gen_M(fake_photo)\n            cycle_photo_loss = l1(photo, cycle_photo)\n            cycle_monet_loss = l1(monet, cycle_monet)\n\n            # identity loss (remove these for efficiency if you set lambda_identity=0)\n            identity_photo = gen_P(photo)\n            identity_monet = gen_M(monet)\n            identity_photo_loss = l1(photo, identity_photo)\n            identity_monet_loss = l1(monet, identity_monet)\n\n            # add all togethor\n            G_loss = (\n                    loss_G_P\n                    + loss_G_H\n                    + cycle_photo_loss * LAMBDA_CYCLE\n                    + cycle_monet_loss * LAMBDA_CYCLE\n                    + identity_monet_loss * LAMBDA_IDENTITY\n                    + identity_photo_loss * LAMBDA_IDENTITY\n            )\n\n        opt_gen.zero_grad()\n        g_scaler.scale(G_loss).backward()\n        g_scaler.step(opt_gen)\n        g_scaler.update()\n        \n        ret_D_loss[0]=float(D_loss)\n        ret_loss_G_P[0]=float(loss_G_P)\n        ret_loss_G_H[0]= float(loss_G_H)\n        ret_cycle_photo_loss[0]= float(cycle_photo_loss)\n        ret_cycle_monet_loss[0]=float(cycle_monet_loss)\n        ret_identity_monet_loss[0]= float(identity_monet_loss)\n        ret_identity_photo_loss[0]=float(identity_photo_loss)\n        ret_G_loss[0]=float(G_loss)\n        \n#         if idx % 400 == 0:\n#             save_image(fake_monet * 0.5 + 0.5, OUTPUT_DIR + f\"/fakehorse_{idx}.png\")\n#             save_image(photo * 0.5 + 0.5, OUTPUT_DIR + f\"/zebra_{idx}.png\")\n\n        loop.set_postfix(M_real=M_reals / (idx + 1), M_fake=M_fakes / (idx + 1))\n\n    return {\"D_loss\": ret_D_loss, \"loss_G_P\": ret_loss_G_P,\n            \"loss_G_H\": ret_loss_G_H,\n            \"cycle_photo_loss\": ret_cycle_photo_loss,\n            \"cycle_monet_loss\": ret_cycle_monet_loss,\n            \"identity_monet_loss\": ret_identity_monet_loss,\n            \"identity_photo_loss\": ret_identity_photo_loss, \"G_loss\": ret_G_loss}","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def val_fn(gen_H, loader):\n    H_reals = 0\n    H_fakes = 0\n    loop = tqdm(loader, leave=True)\n\n    for idx, (zebra, horse) in enumerate(loop):\n        zebra = zebra.to(DEVICE)\n        horse = horse.to(DEVICE)\n\n        # Train Discriminators H and Z\n        with torch.cuda.amp.autocast():\n            fake_horse = gen_H(zebra)\n        \n        save_image(fake_horse * 0.5 + 0.5, OUTPUT_DIR + f\"/fakehorse_{idx}.png\")\n\n#         loop.set_postfix(H_real=H_reals / (idx + 1), H_fake=H_fakes / (idx + 1))","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"disc_M = Discriminator(in_channels=3).to(DEVICE)\ndisc_P = Discriminator(in_channels=3).to(DEVICE)\ngen_P = Generator(img_channels=3, num_residuals=4).to(DEVICE)\ngen_M = Generator(img_channels=3, num_residuals=4).to(DEVICE)\n\nopt_disc = optim.Adam(\n    list(disc_M.parameters()) + list(disc_P.parameters()),\n    lr=LEARNING_RATE,\n    betas=(0.5, 0.999),\n)\n\nopt_gen = optim.Adam(\n    list(gen_P.parameters()) + list(gen_M.parameters()),\n    lr=LEARNING_RATE,\n    betas=(0.5, 0.999),\n)\n\nlr_scheduler_G = torch.optim.lr_scheduler.LambdaLR(opt_gen, lr_lambda=LambdaLR(NUM_EPOCHS, 0,\n                                                                               NUM_EPOCHS / 2).step)\nlr_scheduler_D = torch.optim.lr_scheduler.LambdaLR(opt_disc, lr_lambda=LambdaLR(NUM_EPOCHS, 0,\n                                                                                NUM_EPOCHS / 2).step)\nL1 = nn.L1Loss()\nmse = nn.MSELoss()\n","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if LOAD_MODEL:\n    load_checkpoint(\n        CHECKPOINT_GEN_H, gen_M, opt_gen, LEARNING_RATE,\n    )\n    load_checkpoint(\n        CHECKPOINT_GEN_Z, gen_P, opt_gen, LEARNING_RATE,\n    )\n    load_checkpoint(\n        CHECKPOINT_CRITIC_H, disc_M, opt_disc, LEARNING_RATE,\n    )\n    load_checkpoint(\n        CHECKPOINT_CRITIC_Z, disc_P, opt_disc, LEARNING_RATE,\n    )","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset = PhotoMonetDataset(\n    root_monet=BASE_DIR + \"/monet_jpg\", root_photo=BASE_DIR + \"/photo_jpg\",\n    transform=transforms_2\n)\n\nloader = DataLoader(\n    dataset,\n    batch_size=BATCH_SIZE,\n    shuffle=True,\n    num_workers=NUM_WORKERS,\n    pin_memory=True\n)\n\ng_scaler = torch.cuda.amp.GradScaler()\nd_scaler = torch.cuda.amp.GradScaler()\n\nlosses = {\"D_loss\": [], \"loss_G_P\": [],\n          \"loss_G_H\": [],\n          \"cycle_photo_loss\": [],\n          \"cycle_monet_loss\": [],\n          \"identity_monet_loss\": [],\n          \"identity_photo_loss\": [],\n          \"G_loss\": []}\n\nfor epoch in range(NUM_EPOCHS):\n    print(\"-\" * 4 + \"Epoch number: \" + str(epoch) + \"-\" * 4)\n    d = train_fn(disc_M, disc_P, gen_P, gen_M, loader, opt_disc, opt_gen, L1, mse, d_scaler, g_scaler)\n\n#         for key, val in d.items():\n#             print(\"key: \" + key + \". \" + \"val: \" + str(val))\n#             losses[key] = losses[key] + val\n#             plt.title(key)\n#             plt.xlabel(\"epoch\")\n#             plt.ylabel(key)\n#             plt.plot( np.array(range(epoch+1)),np.array(losses[key]))\n#             plt.show()\n\n    lr_scheduler_G.step()\n    lr_scheduler_D.step()\n\n    if SAVE_MODEL:\n        save_checkpoint(gen_M, opt_gen,\n                        filename=str(LEARNING_RATE) + \"_\" + str(LAMBDA_IDENTITY) + \"_\" + str(\n                            LAMBDA_CYCLE) + CHECKPOINT_GEN_H)\n        save_checkpoint(gen_P, opt_gen,\n                        filename=str(LEARNING_RATE) + \"_\" + str(LAMBDA_IDENTITY) + \"_\" + str(\n                            LAMBDA_CYCLE) + CHECKPOINT_GEN_Z)\n        save_checkpoint(disc_M, opt_disc,\n                        filename=str(LEARNING_RATE) + \"_\" + str(LAMBDA_IDENTITY) + \"_\" + str(\n                            LAMBDA_CYCLE) + CHECKPOINT_CRITIC_H)\n        save_checkpoint(disc_P, opt_disc,\n                        filename=str(LEARNING_RATE) + \"_\" + str(LAMBDA_IDENTITY) + \"_\" + str(\n                            LAMBDA_CYCLE) + CHECKPOINT_CRITIC_Z)\n\n\n\nval_dataset = PhotoMonetDataset(\n    root_monet=BASE_DIR + \"/monet_jpg\", root_photo=BASE_DIR + \"/photo_jpg\",\n    transform=transforms_val,photo_len=7000\n)\nval_loader = DataLoader(\n    val_dataset,\n    batch_size=1,\n    shuffle=False,\n    pin_memory=True,\n)\n\nval_fn(gen_M, val_loader)\n\n\n","metadata":{"execution":{"iopub.status.busy":"2021-07-30T09:18:11.25589Z","iopub.execute_input":"2021-07-30T09:18:11.256413Z","iopub.status.idle":"2021-07-30T09:18:50.080514Z","shell.execute_reply.started":"2021-07-30T09:18:11.256373Z","shell.execute_reply":"2021-07-30T09:18:50.078335Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from zipfile import ZipFile\nfrom os.path import basename\n\n# create a ZipFile object\nwith ZipFile('images.zip', 'w') as zipObj:\n   # Iterate over all the files in directory\n   for folderName, subfolders, filenames in os.walk(\"/kaggle/working/images\"):\n       for filename in filenames:\n           #create complete filepath of file in directory\n           filePath = os.path.join(folderName, filename)\n           # Add file to zip\n           zipObj.write(filePath, basename(filePath))\n        \n        \nfor dirname, _, filenames in os.walk('/kaggle/working/images'):\n    for filename in filenames:\n        os.remove(os.path.join(dirname, filename))\n        print(os.path.join(dirname, filename))\n        \nos.rmdir('/kaggle/working/images')\n# os.remove('/kaggle/working/images.zip')","metadata":{"execution":{"iopub.status.busy":"2021-07-30T09:18:50.081867Z","iopub.status.idle":"2021-07-30T09:18:50.082575Z"},"trusted":true},"execution_count":null,"outputs":[]}]}