{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":21755,"databundleVersionId":1475600,"sourceType":"competition"},{"sourceId":7546495,"sourceType":"datasetVersion","datasetId":4394949}],"dockerImageVersionId":30646,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# I am something of a painter myself\n`pytorch`, `CycleGAN`, `GPU`","metadata":{}},{"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\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport os ","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:46:58.507101Z","iopub.execute_input":"2024-05-22T13:46:58.507916Z","iopub.status.idle":"2024-05-22T13:46:58.855212Z","shell.execute_reply.started":"2024-05-22T13:46:58.507881Z","shell.execute_reply":"2024-05-22T13:46:58.854331Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Data Preparation","metadata":{}},{"cell_type":"markdown","source":"### Loading Image","metadata":{}},{"cell_type":"code","source":"# Input data files are available in the read-only \"../input/\" directory\ndata_dir = '../input/gan-getting-started/'\nprint(os.listdir(data_dir))\n\nmonet_files = data_dir + 'monet_jpg'\nprint('Monet JPG Files:', len(monet_files))\nphoto_files = data_dir + 'photo_jpg'\nprint('Photo JPG Files:', len(photo_files))\n\n#input external photos\n# my_photos = '../input/my-photos/CycleGAN MyPhoto'\n# print('My Photos Files:', len(my_photos))","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:46:58.856723Z","iopub.execute_input":"2024-05-22T13:46:58.857065Z","iopub.status.idle":"2024-05-22T13:46:58.864208Z","shell.execute_reply.started":"2024-05-22T13:46:58.857041Z","shell.execute_reply":"2024-05-22T13:46:58.863272Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"##locating file \n# print(os.listdir(monet_files)[251])\n# os.listdir('../input/my-photos/CycleGAN MyPhoto')","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:46:58.865211Z","iopub.execute_input":"2024-05-22T13:46:58.865475Z","iopub.status.idle":"2024-05-22T13:46:58.881319Z","shell.execute_reply.started":"2024-05-22T13:46:58.865453Z","shell.execute_reply":"2024-05-22T13:46:58.880550Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from PIL import Image\nimport matplotlib.pyplot as plt ","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:46:58.883462Z","iopub.execute_input":"2024-05-22T13:46:58.883713Z","iopub.status.idle":"2024-05-22T13:46:58.892832Z","shell.execute_reply.started":"2024-05-22T13:46:58.883691Z","shell.execute_reply":"2024-05-22T13:46:58.892021Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"## viewing image\n# image_path = monet_files+\"/26b66eb819.jpg\"\n# image = Image.open(image_path)\n# plt.imshow(image)\n# plt.axis('on')  # Hide axes\n# plt.show()","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:46:58.893854Z","iopub.execute_input":"2024-05-22T13:46:58.894423Z","iopub.status.idle":"2024-05-22T13:46:58.909493Z","shell.execute_reply.started":"2024-05-22T13:46:58.894393Z","shell.execute_reply":"2024-05-22T13:46:58.908700Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from torch.utils.data import Dataset\nfrom torch.utils.data import DataLoader\nfrom torchvision.datasets.folder import default_loader\nimport torchvision.transforms as T","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:46:58.910745Z","iopub.execute_input":"2024-05-22T13:46:58.910995Z","iopub.status.idle":"2024-05-22T13:47:09.035595Z","shell.execute_reply.started":"2024-05-22T13:46:58.910973Z","shell.execute_reply":"2024-05-22T13:47:09.034633Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_size = 256 #pixels 256x256\nbatch_size = 4\nstats = (0.5, 0.5, 0.5), (0.5, 0.5, 0.5) #mean and standard deviation for model to normalize images","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:09.036819Z","iopub.execute_input":"2024-05-22T13:47:09.037542Z","iopub.status.idle":"2024-05-22T13:47:09.042519Z","shell.execute_reply.started":"2024-05-22T13:47:09.037509Z","shell.execute_reply":"2024-05-22T13:47:09.041666Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CustomImageDataset(Dataset):\n    def __init__(self, root, max_images= None,transform=None, class_index=0): #30\n        self.root = root\n        self.transform = transform\n        self.class_index = class_index\n\n        # List all image files in the root directory\n        self.image_files = os.listdir(root)\n        \n        # Slice the list to limit the number of images\n        if max_images is not None:\n            self.image_files = self.image_files[:max_images]\n\n    def __len__(self):\n        return len(self.image_files)\n\n    def __getitem__(self, idx):\n        img_path = os.path.join(self.root, self.image_files[idx])\n        img = default_loader(img_path)\n\n        if self.transform:\n            img = self.transform(img)\n\n        return img, self.class_index","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:09.043730Z","iopub.execute_input":"2024-05-22T13:47:09.044071Z","iopub.status.idle":"2024-05-22T13:47:09.056994Z","shell.execute_reply.started":"2024-05-22T13:47:09.044042Z","shell.execute_reply":"2024-05-22T13:47:09.056173Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":" def load_data(data_dir,max_images):\n    ds = CustomImageDataset(data_dir,max_images, transform=T.Compose([\n        T.Resize((256, 256)),\n        T.RandomCrop(256, padding=2, padding_mode='reflect'), \n        T.RandomHorizontalFlip(), \n        T.ToTensor(),\n        T.Normalize(*stats)]))\n\n    dl = DataLoader(ds, batch_size, shuffle=True, num_workers=3, pin_memory=True)\n    return dl","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:09.058069Z","iopub.execute_input":"2024-05-22T13:47:09.058321Z","iopub.status.idle":"2024-05-22T13:47:09.076197Z","shell.execute_reply.started":"2024-05-22T13:47:09.058299Z","shell.execute_reply":"2024-05-22T13:47:09.075412Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"monet_dl = load_data(monet_files, max_images =36)\nphoto_dl = load_data(photo_files, max_images = None)\n# myphotos_dl  = load_data(my_photos, max_images = None)","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:09.079820Z","iopub.execute_input":"2024-05-22T13:47:09.080060Z","iopub.status.idle":"2024-05-22T13:47:09.372943Z","shell.execute_reply.started":"2024-05-22T13:47:09.080040Z","shell.execute_reply":"2024-05-22T13:47:09.372265Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#loading batches\nfor monets, _ in monet_dl:\n    print(len(monets),end = \" \")","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:09.373975Z","iopub.execute_input":"2024-05-22T13:47:09.374280Z","iopub.status.idle":"2024-05-22T13:47:09.974419Z","shell.execute_reply.started":"2024-05-22T13:47:09.374250Z","shell.execute_reply":"2024-05-22T13:47:09.973334Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nfrom torchvision.utils import make_grid","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:09.975797Z","iopub.execute_input":"2024-05-22T13:47:09.976101Z","iopub.status.idle":"2024-05-22T13:47:09.980446Z","shell.execute_reply.started":"2024-05-22T13:47:09.976072Z","shell.execute_reply":"2024-05-22T13:47:09.979588Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def denorm(img_tensors):\n    return img_tensors * stats[1][0] + stats[0][0]","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:09.981720Z","iopub.execute_input":"2024-05-22T13:47:09.982291Z","iopub.status.idle":"2024-05-22T13:47:09.993556Z","shell.execute_reply.started":"2024-05-22T13:47:09.982260Z","shell.execute_reply":"2024-05-22T13:47:09.992736Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def show_images(images, nmax=16):\n    \"\"\" using make grid function from pytorch to display images\"\"\"\n    fig, ax = plt.subplots(figsize=(8, 8))\n    ax.set_xticks([]); ax.set_yticks([])\n    ax.imshow(make_grid(denorm(images.detach()[:nmax]), nrow=4).permute(1, 2, 0))\n\ndef show_batch(dl, nmax=25):\n    \"\"\"Function to plot batch of images\"\"\"\n    for images, _ in dl:\n        show_images(images, nmax)\n        break","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:09.994558Z","iopub.execute_input":"2024-05-22T13:47:09.994854Z","iopub.status.idle":"2024-05-22T13:47:10.005487Z","shell.execute_reply.started":"2024-05-22T13:47:09.994832Z","shell.execute_reply":"2024-05-22T13:47:10.004805Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"show_batch(monet_dl)\n# show_batch(photo_dl)\n# show_batch(myphotos_dl)","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:10.006452Z","iopub.execute_input":"2024-05-22T13:47:10.006706Z","iopub.status.idle":"2024-05-22T13:47:10.432790Z","shell.execute_reply.started":"2024-05-22T13:47:10.006685Z","shell.execute_reply":"2024-05-22T13:47:10.431768Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# for image, label in monet_dl:\n#     print(label)\n#     show_images(image,nmax=4)\n#     break\n# for image, label in photo_dl:\n#     print(label)\n#     show_images(image,nmax=4) #use image.cpu() after moving data to device\n#     break","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:10.434078Z","iopub.execute_input":"2024-05-22T13:47:10.434382Z","iopub.status.idle":"2024-05-22T13:47:10.438791Z","shell.execute_reply.started":"2024-05-22T13:47:10.434338Z","shell.execute_reply":"2024-05-22T13:47:10.437839Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Using a GPU\n\nTo seamlessly use a GPU, if one is available, we define a couple of helper functions (`get_default_device` & `to_device`) and a helper class `DeviceDataLoader` to move our model & data to the GPU, if one is available.","metadata":{}},{"cell_type":"code","source":"def get_default_device():\n    \"\"\"Pick GPU if available, else CPU\"\"\"\n    if torch.cuda.is_available():\n        return torch.device('cuda')\n    else:\n        return torch.device('cpu')\n    \ndef to_device(data, device):\n    \"\"\"Move tensor(s) to chosen device\"\"\"\n    if isinstance(data, (list,tuple)):\n        return [to_device(x, device) for x in data]\n    return data.to(device, non_blocking=True)\n\nclass DeviceDataLoader():\n    \"\"\"Wrap a dataloader to move data to a device\"\"\"\n    def __init__(self, dl, device):\n        self.dl = dl\n        self.device = device\n        \n    def __iter__(self):\n        \"\"\"Yield a batch of data after moving it to device\"\"\"\n        for b in self.dl: \n            yield to_device(b, self.device)\n\n    def __len__(self):\n        \"\"\"Number of batches\"\"\"\n        return len(self.dl)","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:10.439988Z","iopub.execute_input":"2024-05-22T13:47:10.440315Z","iopub.status.idle":"2024-05-22T13:47:10.451003Z","shell.execute_reply.started":"2024-05-22T13:47:10.440285Z","shell.execute_reply":"2024-05-22T13:47:10.450139Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# select GPU as Accelerator for running notebook\ndevice = get_default_device()\ndevice","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:10.452084Z","iopub.execute_input":"2024-05-22T13:47:10.452360Z","iopub.status.idle":"2024-05-22T13:47:10.463459Z","shell.execute_reply.started":"2024-05-22T13:47:10.452338Z","shell.execute_reply":"2024-05-22T13:47:10.462624Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#moving data to GPU\n# monet_dl = DeviceDataLoader(monet_dl, device)\n# photo_dl = DeviceDataLoader(photo_dl, device)\n\n# import torch\n# torch.cuda.memory_stats(device)\n# print(torch.cuda.memory_summary(device=torch.device('cuda:0')))\n# print(torch.cuda.is_available())\n# print(torch.cuda.device_count())\n# print(torch.cuda.get_device_name(0))\n# print(torch.cuda.get_device_name(1))","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:10.464434Z","iopub.execute_input":"2024-05-22T13:47:10.464685Z","iopub.status.idle":"2024-05-22T13:47:10.477230Z","shell.execute_reply.started":"2024-05-22T13:47:10.464663Z","shell.execute_reply":"2024-05-22T13:47:10.476561Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Generator Code\nWe'll be using a UNET architecture for our CycleGAN. To build our generator, let's first define our downsample and upsample methods.","metadata":{}},{"cell_type":"code","source":"import torch.nn as nn\nimport torch.nn.functional as F","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:10.478135Z","iopub.execute_input":"2024-05-22T13:47:10.478451Z","iopub.status.idle":"2024-05-22T13:47:10.488183Z","shell.execute_reply.started":"2024-05-22T13:47:10.478428Z","shell.execute_reply":"2024-05-22T13:47:10.487529Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"The `downsample`, as the name suggests, reduces the 2D dimensions, the width and height, of the image by the stride. The stride is the length of the step the filter takes. Since the stride is 2, the filter is applied to every other pixel, hence reducing the weight and height by 2.","metadata":{}},{"cell_type":"code","source":"def downsample(in_channels, out_channels, kernel_size, apply_instancenorm=True):\n    layers = [\n        nn.Conv2d(in_channels, out_channels, kernel_size, stride=2, padding=1, bias=False)\n    ]\n    if apply_instancenorm:\n        layers.append(nn.InstanceNorm2d(out_channels))\n    layers.append(nn.LeakyReLU(0.2, inplace=True))\n    return nn.Sequential(*layers)\n","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:10.489185Z","iopub.execute_input":"2024-05-22T13:47:10.489459Z","iopub.status.idle":"2024-05-22T13:47:10.502913Z","shell.execute_reply.started":"2024-05-22T13:47:10.489438Z","shell.execute_reply":"2024-05-22T13:47:10.502032Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"`Upsample` does the opposite of downsample and increases the dimensions of the of the image. `ConvTranspose2D` does basically the opposite of a `Conv2D` layer.","metadata":{}},{"cell_type":"code","source":"def upsample(in_channels,out_channels,kernel_size,stride=2,padding=1,apply_dropout=False):\n    layers = [\n        nn.ConvTranspose2d(in_channels,out_channels,kernel_size,stride=stride,padding=padding, bias=False),\n        nn.InstanceNorm2d(out_channels)\n    ]\n    if apply_dropout:\n        layers.append(nn.Dropout(p=0.2))\n    layers.append(nn.LeakyReLU(0.2, inplace=True))\n    return nn.Sequential(*layers)","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:10.504041Z","iopub.execute_input":"2024-05-22T13:47:10.504393Z","iopub.status.idle":"2024-05-22T13:47:10.517797Z","shell.execute_reply.started":"2024-05-22T13:47:10.504325Z","shell.execute_reply":"2024-05-22T13:47:10.517073Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Let's build our generator!\n\nThe generator first downsamples the input image and then upsample while establishing long skip connections. Skip connections are a way to help bypass the vanishing gradient problem by concatenating the output of a layer to multiple layers instead of only one. Here we concatenate the output of the downsample layer to the upsample layer in a symmetrical fashion.","metadata":{}},{"cell_type":"code","source":"class Generator(nn.Module):\n    def __init__(self):\n        super().__init__()\n        self.down_stack = nn.ModuleList([\n        downsample(3, 64, 4, apply_instancenorm=False), # (bs, 128, 128, 64)\n        downsample(64, 128, 4), # (bs, 64, 64, 128)\n        downsample(128, 256, 4), # (bs, 32, 32, 256)\n        downsample(256,512, 4), # (bs, 16, 16, 512)\n        downsample(512,512, 4), # (bs, 8, 8, 512)\n        downsample(512,512, 4), # (bs, 4, 4, 512)\n        downsample(512,512, 4), # (bs, 2, 2, 512)\n        downsample(512,512, 4, apply_instancenorm=False), # (bs, 1, 1, 512)\n        ])\n        self.up_stack = nn.ModuleList([\n        upsample(512,512, 4, apply_dropout=True), # (bs, 2, 2, 1024)\n        upsample(1024,512, 4, apply_dropout=True), # (bs, 4, 4, 1024)1536\n        upsample(1024,512, 4, apply_dropout=True), # (bs, 8, 8, 1024)\n        upsample(1024,512, 4), # (bs, 16, 16, 1024)\n        upsample(1024,256, 4), # (bs, 32, 32, 512)\n        upsample(512,128, 4), # (bs, 64, 64, 256)\n        upsample(256,64, 4), # (bs, 128, 128, 128)\n        ])\n        self.last = nn.Sequential(\n            nn.ConvTranspose2d(128, 3, kernel_size=4, stride=2, padding=1, bias=False),\n            nn.Tanh()) # (bs, 256, 256, 3)\n                                  \n    def forward(self, x):\n        skips = []\n        for down in self.down_stack:                  \n            x = down(x)\n#             print(\"Shape after downsampling:\", x.shape)\n            skips.append(x)                          \n        skips = list(reversed(skips[:-1]))\n        \n        for up,skip in zip(self.up_stack, skips):\n            x = up(x)\n#             print(\"Shape after upsampling:\", x.shape)  # Print shape after each upsampling\n#             print(\"Shape of skip connection feature map:\", skip.shape)\n            x = torch.cat([x,skip], dim=1)\n#             print(\"Shape after concatenation:\", x.shape) \n        x = self.last(x)\n        return x       \n    \ndef test():\n    img_channels = 3\n    img_size = 256\n    x = torch.randn((5, img_channels, img_size, img_size))\n    gen = Generator()\n    fake_images = gen(x)\n    print(fake_images.shape)\n    show_images(fake_images)","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:10.518798Z","iopub.execute_input":"2024-05-22T13:47:10.519060Z","iopub.status.idle":"2024-05-22T13:47:10.539653Z","shell.execute_reply.started":"2024-05-22T13:47:10.519039Z","shell.execute_reply":"2024-05-22T13:47:10.538823Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test()","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:10.540710Z","iopub.execute_input":"2024-05-22T13:47:10.541030Z","iopub.status.idle":"2024-05-22T13:47:12.557183Z","shell.execute_reply.started":"2024-05-22T13:47:10.541001Z","shell.execute_reply":"2024-05-22T13:47:12.556296Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Discriminator Code","metadata":{}},{"cell_type":"code","source":"class Discriminator(nn.Module):\n    def __init__(self):\n        super().__init__()\n        \n        self.downsample = nn.ModuleList([\n            downsample(3, 64, 4, apply_instancenorm=False), # (bs, 128, 128, 64)\n            downsample(64, 128, 4), # (bs, 64, 64, 128)\n            downsample(128, 256, 4)]) # (bs, 32, 32, 256)\n      \n\n        self.conv = nn.Sequential(\n            nn.ZeroPad2d(1), # (bs, 34, 34, 256)\n            nn.Conv2d(256, 512, 4, 1, 0, bias=False), # (bs, 31, 31, 512)\n            nn.InstanceNorm2d(512),\n            nn.LeakyReLU(0.2, inplace=True),\n            nn.ZeroPad2d(1), # (bs, 33, 33, 512)\n            nn.Conv2d(512, 1, 4, 1, 0, bias=False) # (bs, 30, 30, 1)\n        )\n\n    def forward(self, x):\n        for down in self.downsample:\n            x= down(x)\n        x = self.conv(x)\n        return x\n    \ndef disc_test():\n    x = torch.randn((5, 3, 256, 256))\n    model = Discriminator()\n    preds = model(x)\n    print(preds.shape)\n    show_images(preds)","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:12.558469Z","iopub.execute_input":"2024-05-22T13:47:12.558910Z","iopub.status.idle":"2024-05-22T13:47:12.569413Z","shell.execute_reply.started":"2024-05-22T13:47:12.558866Z","shell.execute_reply":"2024-05-22T13:47:12.568567Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"disc_test()","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:12.570669Z","iopub.execute_input":"2024-05-22T13:47:12.571274Z","iopub.status.idle":"2024-05-22T13:47:13.073871Z","shell.execute_reply.started":"2024-05-22T13:47:12.571243Z","shell.execute_reply":"2024-05-22T13:47:13.072968Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"monet_generator = Generator() # transforms photos to Monet-esque paintings\nphoto_generator = Generator() # transforms Monet paintings to be more like photos\n\nmonet_discriminator = Discriminator() # differentiates real Monet paintings and generated Monet paintings\nphoto_discriminator = Discriminator() # differentiates real photos and generated photos","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:13.075265Z","iopub.execute_input":"2024-05-22T13:47:13.075660Z","iopub.status.idle":"2024-05-22T13:47:14.112968Z","shell.execute_reply.started":"2024-05-22T13:47:13.075627Z","shell.execute_reply":"2024-05-22T13:47:14.112199Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for images, labels in photo_dl:\n    show_images(images.cpu(),nmax=4)\n    to_monet = monet_generator(images)\n    show_images(to_monet.cpu(),nmax = 4)\n    break","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:14.118569Z","iopub.execute_input":"2024-05-22T13:47:14.118853Z","iopub.status.idle":"2024-05-22T13:47:15.441806Z","shell.execute_reply.started":"2024-05-22T13:47:14.118828Z","shell.execute_reply":"2024-05-22T13:47:15.440776Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## CycleGAN Model","metadata":{}},{"cell_type":"code","source":"class CycleGan(nn.Module):\n    def __init__(self,monet_generator, photo_generator, \n                 monet_discriminator, photo_discriminator,\n                 generator_loss,discriminator_loss,\n                 calc_cycle_loss,identity_loss,lambda_cycle=10.0):\n        super(CycleGan, self).__init__()\n        self.m_gen = monet_generator\n        self.p_gen = photo_generator\n        self.m_disc = monet_discriminator\n        self.p_disc = photo_discriminator\n        self.lambda_cycle = lambda_cycle\n        \n        self.gen_loss_fn = generator_loss\n        self.disc_loss_fn = discriminator_loss\n        self.cycle_loss_fn = calc_cycle_loss\n        self.identity_loss_fn = identity_loss\n        \n    def train_step(self, real_monet, real_photo, m_gen_optimizer, p_gen_optimizer,\n                                                m_disc_optimizer, p_disc_optimizer):\n        # generate fake images\n        fake_monet = self.m_gen(real_photo)\n        fake_photo = self.p_gen(real_monet)\n        \n        #generate cycled images\n        cycled_monet = self.m_gen(fake_photo)\n        cycled_photo = self.p_gen(fake_monet)\n\n        # generate itself\n        same_monet = self.m_gen(real_monet)\n        same_photo = self.p_gen(real_photo)\n\n        # discriminator used to check, inputing real images\n        disc_real_monet = self.m_disc(real_monet)\n        disc_real_photo = self.p_disc(real_photo)\n\n        # discriminator used to check, inputing fake images\n        disc_fake_monet = self.m_disc(fake_monet)\n        disc_fake_photo = self.p_disc(fake_photo)\n        \n        # evaluates generator loss\n        monet_gen_loss = self.gen_loss_fn(disc_fake_monet)\n        photo_gen_loss = self.gen_loss_fn(disc_fake_photo)\n\n        # evaluates total cycle consistency loss\n        total_cycle_loss = self.cycle_loss_fn(real_monet, cycled_monet, self.lambda_cycle) + self.cycle_loss_fn(real_photo, cycled_photo, self.lambda_cycle)\n\n        # evaluates total generator loss\n        total_monet_gen_loss = monet_gen_loss + total_cycle_loss + self.identity_loss_fn(real_monet, same_monet, self.lambda_cycle)\n        total_photo_gen_loss = photo_gen_loss + total_cycle_loss + self.identity_loss_fn(real_photo, same_photo, self.lambda_cycle)\n\n        # evaluates discriminator loss\n        monet_disc_loss = self.disc_loss_fn(disc_real_monet, disc_fake_monet)\n        photo_disc_loss = self.disc_loss_fn(disc_real_photo, disc_fake_photo)\n        \n        # Calculate the gradients for generator and discriminator\n        total_monet_gen_loss.backward(retain_graph=True)\n        total_photo_gen_loss.backward(retain_graph=True)\n        monet_disc_loss.backward(retain_graph=True)\n        photo_disc_loss.backward(retain_graph=True)\n        \n        grad_clip = 0.1 #Gradient Clipping\n        nn.utils.clip_grad_value_(monet_generator.parameters(), grad_clip)\n        nn.utils.clip_grad_value_(photo_generator.parameters(), grad_clip)\n        nn.utils.clip_grad_value_(monet_discriminator.parameters(), grad_clip)\n        nn.utils.clip_grad_value_(photo_discriminator.parameters(), grad_clip)\n\n        return {\n            \"monet_gen_loss\": total_monet_gen_loss,\n            \"photo_gen_loss\": total_photo_gen_loss,\n            \"monet_disc_loss\": monet_disc_loss,\n            \"photo_disc_loss\": photo_disc_loss\n        }","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:15.443403Z","iopub.execute_input":"2024-05-22T13:47:15.443806Z","iopub.status.idle":"2024-05-22T13:47:15.460287Z","shell.execute_reply.started":"2024-05-22T13:47:15.443768Z","shell.execute_reply":"2024-05-22T13:47:15.459438Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Loss Functions","metadata":{}},{"cell_type":"code","source":"#pass torch.ones through device first  \n#outputs from disc is of size 30, 30; hence targets should be of that size as well\ndef generator_loss(generated):\n    real_targets = torch.ones(generated.size(0), 1, 30, 30, device=device)\n    return F.binary_cross_entropy_with_logits(generated,real_targets)\n    \n# real_targets = torch.ones(real_images.size(0), 1, device=device)\n# fake_targets = torch.zeros(fake_images.size(0), 1, device=device)","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:15.461657Z","iopub.execute_input":"2024-05-22T13:47:15.462269Z","iopub.status.idle":"2024-05-22T13:47:15.481162Z","shell.execute_reply.started":"2024-05-22T13:47:15.462238Z","shell.execute_reply":"2024-05-22T13:47:15.480324Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def discriminator_loss(real, generated):\n    #outputs from disc is of size 30, 30; hence targets should be of that size as well\n    real_targets = torch.ones(real.size(0), 1, 30, 30,device=device)\n    fake_targets = torch.zeros(generated.size(0), 1, 30, 30, device=device)\n    \n    real_loss = F.binary_cross_entropy_with_logits(real,real_targets)\n    generated_loss = F.binary_cross_entropy_with_logits(generated,fake_targets)\n    total_disc_loss = real_loss + generated_loss\n    return total_disc_loss * 0.5\n","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:15.482277Z","iopub.execute_input":"2024-05-22T13:47:15.482605Z","iopub.status.idle":"2024-05-22T13:47:15.494932Z","shell.execute_reply.started":"2024-05-22T13:47:15.482573Z","shell.execute_reply":"2024-05-22T13:47:15.494084Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def calc_cycle_loss(real_image, cycled_image, LAMBDA):\n    loss1 = torch.mean(torch.abs(real_image - cycled_image))\n    return LAMBDA * loss1\n# lambda_value = LAMBDA\n# lambda_func = lambda x: x * lambda_value\n# return lambda_function(loss1)\n\n# def cycle_loss_fn(real_image, fake_image, lambda_cycle):\n#     return torch.mean(torch.abs(real_image - fake_image)) + lambda_cycle * torch.mean(torch.abs(fake_image - real_image))\n","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:15.495865Z","iopub.execute_input":"2024-05-22T13:47:15.496122Z","iopub.status.idle":"2024-05-22T13:47:15.514838Z","shell.execute_reply.started":"2024-05-22T13:47:15.496100Z","shell.execute_reply":"2024-05-22T13:47:15.513962Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def identity_loss(real_image, same_image, LAMBDA):\n    loss = torch.mean(torch.abs(real_image - same_image))\n    return LAMBDA * 0.5 * loss\n    ","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:15.515982Z","iopub.execute_input":"2024-05-22T13:47:15.516245Z","iopub.status.idle":"2024-05-22T13:47:15.527254Z","shell.execute_reply.started":"2024-05-22T13:47:15.516222Z","shell.execute_reply":"2024-05-22T13:47:15.526589Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# from torchvision.utils import save_image\n\n# sample_dir = \"../images\"\n# os.makedirs(sample_dir, exist_ok = True)","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:15.528336Z","iopub.execute_input":"2024-05-22T13:47:15.528669Z","iopub.status.idle":"2024-05-22T13:47:15.539616Z","shell.execute_reply.started":"2024-05-22T13:47:15.528639Z","shell.execute_reply":"2024-05-22T13:47:15.538766Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# fixed_latent = torch.randn(64, 3, 256, 256, device=device)\n\n# def save_samples(index, latent_tensors, show=True):\n#     fake_images = monet_generator(latent_tensors)\n#     fake_fname = 'generated-images-{0:0=4d}.png'.format(index)\n#     save_image(denorm(fake_images), os.path.join(sample_dir, fake_fname), nrow=8)\n#     print('Saving', fake_fname)\n#     if show:\n#         fig, ax = plt.subplots(figsize=(8, 8))\n#         ax.set_xticks([]); ax.set_yticks([])\n#         ax.imshow(make_grid(fake_images.cpu().detach(), nrow=8).permute(1, 2, 0))","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:15.540707Z","iopub.execute_input":"2024-05-22T13:47:15.540975Z","iopub.status.idle":"2024-05-22T13:47:15.550828Z","shell.execute_reply.started":"2024-05-22T13:47:15.540954Z","shell.execute_reply":"2024-05-22T13:47:15.550001Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# photo_images = []\n\n# for batch in photo_dl:\n#     images,_ = batch\n#     photo_images.append(images)","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:15.551817Z","iopub.execute_input":"2024-05-22T13:47:15.552044Z","iopub.status.idle":"2024-05-22T13:47:15.561570Z","shell.execute_reply.started":"2024-05-22T13:47:15.552024Z","shell.execute_reply":"2024-05-22T13:47:15.560873Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# save_samples(0, photo_images) # try after moving generator to GPU","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:15.562574Z","iopub.execute_input":"2024-05-22T13:47:15.562828Z","iopub.status.idle":"2024-05-22T13:47:15.572740Z","shell.execute_reply.started":"2024-05-22T13:47:15.562807Z","shell.execute_reply":"2024-05-22T13:47:15.572026Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Train CycleGAN","metadata":{}},{"cell_type":"code","source":"#trying to combine both datalaoders to feed into cyclegan at same time for training\n# combined_dl = zip(monet_dl,photo_dl)\n# for batch_idx, (real_images_monet, real_images_photo) in enumerate(combined_dl):\n#     real_monets, _ = real_images_monet\n#     real_photos, _ = real_images_photo\n#     print(len(real_monets))\n#     print(real_monets.size())\n#     print(len(real_photos))\n#     print(real_photos.size())\n    \n# for batch in monet_dl:\n#     real_monets, _ = batch\n#     print(len(real_monets))\n#     print(real_monets.size())\n# for real_monets, _ in tqdm(monet_dl):\n# #     print(real_monets[:1])\n#     print(len(real_monets))\n#     print(real_monets.size())\n\n# for real_photos, _ in tqdm(photo_dl):\n#     print(len(real_photos))\n#     print(real_photos.size())","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:15.573775Z","iopub.execute_input":"2024-05-22T13:47:15.574051Z","iopub.status.idle":"2024-05-22T13:47:15.584069Z","shell.execute_reply.started":"2024-05-22T13:47:15.574030Z","shell.execute_reply":"2024-05-22T13:47:15.583266Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tqdm.notebook import tqdm\nimport gc\n\naccumulation_steps = 4 #gradients accumulation for 4 training loop\n\ndef get_lr(optimizer):\n    for param_group in optimizer.param_groups:\n        return param_group['lr']\n\ndef fit_one_cycle(epochs, max_lr, cycle_gan_model, monet_dl, photo_dl,\n                  weight_decay =0,start_idx = 1):\n    gc.collect()\n    torch.cuda.empty_cache()\n    history = {}\n    \n    # Losses & scores\n    monet_gen_losses,photo_gen_losses,monet_disc_losses,photo_disc_losses = [],[],[],[]\n    \n    # one cycle learning rates \n    m_gen_lrs,p_gen_lrs,m_disc_lrs,p_disc_lrs = [],[],[],[]\n    \n    # Set up optimizers for generators and discriminators\n    m_gen_optimizer = torch.optim.Adam(monet_generator.parameters(), max_lr, weight_decay = weight_decay, betas=(0.5, 0.999))\n    p_gen_optimizer = torch.optim.Adam(photo_generator.parameters(), max_lr, weight_decay = weight_decay, betas=(0.5, 0.999))\n    m_disc_optimizer = torch.optim.Adam(monet_discriminator.parameters(), max_lr, weight_decay = weight_decay, betas=(0.5, 0.999))\n    p_disc_optimizer = torch.optim.Adam(photo_discriminator.parameters(), max_lr, weight_decay = weight_decay, betas=(0.5, 0.999))\n    \n    # Set up one-cycle learning rate scheduler for each optimizer\n    m_gen_sched = torch.optim.lr_scheduler.OneCycleLR(m_gen_optimizer, max_lr, epochs=epochs, steps_per_epoch=len(monet_dl))\n    p_gen_sched = torch.optim.lr_scheduler.OneCycleLR(p_gen_optimizer, max_lr, epochs=epochs, steps_per_epoch=len(photo_dl))\n    m_disc_sched = torch.optim.lr_scheduler.OneCycleLR(m_disc_optimizer, max_lr, epochs=epochs, steps_per_epoch=len(monet_dl))\n    p_disc_sched = torch.optim.lr_scheduler.OneCycleLR(p_disc_optimizer, max_lr, epochs=epochs, steps_per_epoch=len(photo_dl))\n  \n    for epoch in range(epochs):\n        gc.collect()\n        torch.cuda.empty_cache()\n        combined_dl = zip(monet_dl,photo_dl)\n        for batch_idx, (real_images_monet, real_images_photo) in enumerate(combined_dl):\n            real_monets, _ = real_images_monet\n            real_photos, _ = real_images_photo\n            print(len(real_monets))\n            print(real_monets.size())\n    \n            # train CycleGan model\n            losses = cycle_gan_model.train_step(real_monets, real_photos, m_gen_optimizer, p_gen_optimizer,\n                                                m_disc_optimizer, p_disc_optimizer)\n            \n            total_monet_gen_loss = losses[\"monet_gen_loss\"]\n            total_photo_gen_loss = losses[\"photo_gen_loss\"]\n            monet_disc_loss = losses[\"monet_disc_loss\"]\n            photo_disc_loss = losses[\"photo_disc_loss\"]\n            \n            if (batch_idx + 1) % accumulation_steps == 0:\n                # Update generator and discriminator parameters\n                m_gen_optimizer.step()\n                p_gen_optimizer.step()\n                m_disc_optimizer.step()\n                p_disc_optimizer.step()\n\n                # Reset gradients for generator and discriminator\n                m_gen_optimizer.zero_grad()\n                p_gen_optimizer.zero_grad()\n                m_disc_optimizer.zero_grad()\n                p_disc_optimizer.zero_grad()\n                \n                # Record & update learning rate\n                m_gen_lrs.append(get_lr(m_gen_optimizer))\n                p_gen_lrs.append(get_lr(p_gen_optimizer))\n                m_disc_lrs.append(get_lr(m_disc_optimizer))\n                p_disc_lrs.append(get_lr(p_disc_optimizer))\n\n                m_gen_sched.step()\n                p_gen_sched.step()\n                m_disc_sched.step()\n                p_disc_sched.step()\n        \n            # Record losses & scores\n            monet_gen_losses.append(total_monet_gen_loss)\n            photo_gen_losses.append(total_photo_gen_loss)\n            monet_disc_losses.append(monet_disc_loss)\n            photo_disc_losses.append(photo_disc_loss)\n\n            \n#           history[\"train_loss\"] = torch.stack(losses).mean().item()\n            history[\"m_gen_lrs\"] = m_gen_lrs\n            history[\"p_gen_lrs\"] = p_gen_lrs\n            history[\"m_disc_lrs\"] = m_disc_lrs\n            history[\"p_disc_lrs\"] = p_disc_lrs\n\n            # Log losses & scores (last batch)\n            print(\"Epoch [{}/{}], total_monet_gen_loss: {:.4f}, total_photo_gen_loss: {:.4f}, monet_disc_loss: {:.4f}, photo_disc_loss: {:.4f}\".format(\n                epoch+1, epochs, total_monet_gen_loss, total_photo_gen_loss, monet_disc_loss, photo_disc_loss))\n\n            # Save generated images\n#             save_samples(epoch+start_idx, fixed_latent, show=False)\n        \n#         del losses\n#         gc.collect()\n    \n    return history","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:15.585314Z","iopub.execute_input":"2024-05-22T13:47:15.585603Z","iopub.status.idle":"2024-05-22T13:47:15.611250Z","shell.execute_reply.started":"2024-05-22T13:47:15.585581Z","shell.execute_reply":"2024-05-22T13:47:15.610407Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"monet_dl = DeviceDataLoader(monet_dl, device)\nphoto_dl = DeviceDataLoader(photo_dl, device)\n# myphotos_dl = DeviceDataLoader(myphotos_dl, device)","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:15.612343Z","iopub.execute_input":"2024-05-22T13:47:15.612619Z","iopub.status.idle":"2024-05-22T13:47:15.630630Z","shell.execute_reply.started":"2024-05-22T13:47:15.612598Z","shell.execute_reply":"2024-05-22T13:47:15.629898Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import torch.nn.parallel as nn_parallel\n\ncycle_gan_model = CycleGan(monet_generator, photo_generator, \n                 monet_discriminator, photo_discriminator,\n                 generator_loss,discriminator_loss,\n                 calc_cycle_loss,identity_loss)\n\n# Create the DataParallel object\n# device_ids = [0, 1]\n# my_model_parallel = nn_parallel.DataParallel(cycle_gan_model, device_ids=device_ids)\nto_device(cycle_gan_model, device)","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:15.631741Z","iopub.execute_input":"2024-05-22T13:47:15.632089Z","iopub.status.idle":"2024-05-22T13:47:15.772639Z","shell.execute_reply.started":"2024-05-22T13:47:15.632060Z","shell.execute_reply":"2024-05-22T13:47:15.771770Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"epochs = 1\nmax_lr = 0.02\n# grad_clip = 0.1\nweight_decay = 1e-4","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:15.773617Z","iopub.execute_input":"2024-05-22T13:47:15.773880Z","iopub.status.idle":"2024-05-22T13:47:15.777598Z","shell.execute_reply.started":"2024-05-22T13:47:15.773858Z","shell.execute_reply":"2024-05-22T13:47:15.776711Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# gc.collect()\n# torch.cuda.empty_cache()\n# history = fit_one_cycle(epochs, max_lr, cycle_gan_model,\n#                         monet_dl, photo_dl, weight_decay=weight_decay)","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:15.778681Z","iopub.execute_input":"2024-05-22T13:47:15.778959Z","iopub.status.idle":"2024-05-22T13:47:15.789314Z","shell.execute_reply.started":"2024-05-22T13:47:15.778931Z","shell.execute_reply":"2024-05-22T13:47:15.788500Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#alternating the gpus for each epoch.\nranks = [0,1]*6 #equalling 12 epochs\n\n#to train with different set of random images each time // train with same dataset for better training results\nmonet_dl = load_data(monet_files, max_images =36)\nphoto_dl = load_data(photo_files, max_images = None)\n\nfor i in ranks:\n    device = torch.device(f'cuda:{i}')\n    monet_dl = DeviceDataLoader(monet_dl, device)\n    photo_dl = DeviceDataLoader(photo_dl, device)\n    to_device(cycle_gan_model, device)\n    \n    gc.collect()\n    torch.cuda.empty_cache()\n    history = fit_one_cycle(epochs, max_lr, cycle_gan_model,\n                        monet_dl, photo_dl, weight_decay=weight_decay)","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:47:15.790412Z","iopub.execute_input":"2024-05-22T13:47:15.790743Z","iopub.status.idle":"2024-05-22T13:49:43.486182Z","shell.execute_reply.started":"2024-05-22T13:47:15.790715Z","shell.execute_reply":"2024-05-22T13:49:43.484998Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for images, labels in photo_dl:\n    show_images(images.cpu(),nmax=4)\n    to_monet = monet_generator(images)\n    show_images(to_monet.cpu(),nmax = 4)\n    break","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:49:43.491904Z","iopub.execute_input":"2024-05-22T13:49:43.492208Z","iopub.status.idle":"2024-05-22T13:49:44.137229Z","shell.execute_reply.started":"2024-05-22T13:49:43.492180Z","shell.execute_reply":"2024-05-22T13:49:44.136146Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# history","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:49:44.138629Z","iopub.execute_input":"2024-05-22T13:49:44.138950Z","iopub.status.idle":"2024-05-22T13:49:44.143381Z","shell.execute_reply.started":"2024-05-22T13:49:44.138920Z","shell.execute_reply":"2024-05-22T13:49:44.142494Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Save the generated monet file for submission\n\nrecreate photo_dl again to contain all the images using customs data loader(change max_files = None)\noptionally changing batch size to 128","metadata":{}},{"cell_type":"code","source":"from torchvision.utils import save_image\n\nsample_dir = \"../images\"\nos.makedirs(sample_dir, exist_ok = True)","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:49:44.144699Z","iopub.execute_input":"2024-05-22T13:49:44.144981Z","iopub.status.idle":"2024-05-22T13:49:44.157718Z","shell.execute_reply.started":"2024-05-22T13:49:44.144957Z","shell.execute_reply":"2024-05-22T13:49:44.156932Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i, (images, _) in enumerate(photo_dl, 1):\n    fake_images = monet_generator(images)\n    fake_fname = '{}.jpg'.format(i)\n    save_image(denorm(fake_images), os.path.join(sample_dir, fake_fname), nrow=1)\n#     print('Saving', fake_fname, end = \" \")","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:49:44.158957Z","iopub.execute_input":"2024-05-22T13:49:44.159247Z","iopub.status.idle":"2024-05-22T13:51:14.593730Z","shell.execute_reply.started":"2024-05-22T13:49:44.159224Z","shell.execute_reply":"2024-05-22T13:51:14.592515Z"},"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":"2024-05-22T13:51:14.595475Z","iopub.execute_input":"2024-05-22T13:51:14.596278Z","iopub.status.idle":"2024-05-22T13:51:23.321862Z","shell.execute_reply.started":"2024-05-22T13:51:14.596239Z","shell.execute_reply":"2024-05-22T13:51:23.320836Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import os\n# sample_dir = \"working\"\n# # Delete all the files in the directory\n# for file_name in os.listdir(sample_dir):\n#     file_path = os.path.join(sample_dir, file_name)\n#     if os.path.isfile(file_path):\n#         os.remove(file_path)\n# os.remove(\"/kaggle/working/images.zip\")\n# # Delete the directory\n# if os.path.isdir(sample_dir):\n#     os.rmdir(sample_dir)","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:51:23.323065Z","iopub.execute_input":"2024-05-22T13:51:23.323434Z","iopub.status.idle":"2024-05-22T13:51:23.328051Z","shell.execute_reply.started":"2024-05-22T13:51:23.323397Z","shell.execute_reply":"2024-05-22T13:51:23.327022Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Results after Training Model","metadata":{}},{"cell_type":"code","source":"# for images, labels in photo_dl:\n#     show_images(images.cpu(),nmax=4)\n#     to_monet = monet_generator(images)\n#     show_images(to_monet.cpu(),nmax = 4)\n#     break","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:51:23.329348Z","iopub.execute_input":"2024-05-22T13:51:23.330006Z","iopub.status.idle":"2024-05-22T13:51:23.399331Z","shell.execute_reply.started":"2024-05-22T13:51:23.329972Z","shell.execute_reply":"2024-05-22T13:51:23.398262Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Save the model checkpoints \n# torch.save(monet_generator.state_dict(), 'M_G.pth')\n# torch.save(photo_generator.state_dict(), 'P_G.pth')\n# torch.save(monet_discriminator.state_dict(), 'M_D.pth')\n# torch.save(photo_discriminator.state_dict(), 'P_D.pth')","metadata":{"execution":{"iopub.status.busy":"2024-05-22T13:51:23.400946Z","iopub.execute_input":"2024-05-22T13:51:23.401309Z","iopub.status.idle":"2024-05-22T13:51:23.410674Z","shell.execute_reply.started":"2024-05-22T13:51:23.401282Z","shell.execute_reply":"2024-05-22T13:51:23.409779Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## References\n\nKaggle Notebook: [Monet CycleGAN Tutorial](https://www.kaggle.com/code/amyjang/monet-cyclegan-tutorial)\n\nJovian notebook: [Training GAN in pytorch](https://jovian.com/aakashns/06b-anime-dcgan)\n\nGithub Repo: [AquibPy/Cycle-GAN](https://github.com/AquibPy/Cycle-GAN)","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}