{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":21755,"databundleVersionId":1475600,"sourceType":"competition"}],"dockerImageVersionId":30787,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"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\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        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","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2024-11-03T16:03:28.324393Z","iopub.execute_input":"2024-11-03T16:03:28.324773Z","iopub.status.idle":"2024-11-03T16:03:31.051262Z","shell.execute_reply.started":"2024-11-03T16:03:28.324735Z","shell.execute_reply":"2024-11-03T16:03:31.050437Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nfrom torchvision import datasets, transforms\nfrom torch.utils.data import DataLoader, Dataset\nfrom PIL import Image\n\nclass SimpleDataset(Dataset):\n    def __init__(self, root_dir, transform=None):\n        self.root_dir = root_dir\n        self.transform = transform\n        self.image_paths = [os.path.join(root_dir, fname) for fname in os.listdir(root_dir)]\n    \n    def __len__(self):\n        return len(self.image_paths)\n    \n    def __getitem__(self, idx):\n        img_path = self.image_paths[idx]\n        image = Image.open(img_path).convert(\"RGB\")\n        if self.transform:\n            image = self.transform(image)\n        return image\n\ntransform = transforms.Compose([\n    transforms.Resize(256),\n    transforms.CenterCrop(256),\n    transforms.ToTensor(),\n    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))\n])\n\nmonet_data = SimpleDataset(root_dir='/kaggle/input/gan-getting-started/monet_jpg/', transform=transform)\nmonet_loader = DataLoader(monet_data, batch_size=4, shuffle=True)\n\nphoto_data = SimpleDataset(root_dir='/kaggle/input/gan-getting-started/photo_jpg/', transform=transform)\nphoto_loader = DataLoader(photo_data, batch_size=4, shuffle=True)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-03T16:03:31.053173Z","iopub.execute_input":"2024-11-03T16:03:31.053490Z","iopub.status.idle":"2024-11-03T16:03:31.080162Z","shell.execute_reply.started":"2024-11-03T16:03:31.053456Z","shell.execute_reply":"2024-11-03T16:03:31.079445Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import DataLoader\nfrom torchvision import datasets, transforms\nfrom torchvision.utils import save_image\n\nclass ResidualBlock(nn.Module):\n    def __init__(self, in_channels):\n        super(ResidualBlock, self).__init__()\n        self.conv_block = nn.Sequential(\n            nn.Conv2d(in_channels, in_channels, kernel_size=3, stride=1, padding=1),\n            nn.InstanceNorm2d(in_channels),\n            nn.ReLU(inplace=True),\n            nn.Conv2d(in_channels, in_channels, kernel_size=3, stride=1, padding=1),\n            nn.InstanceNorm2d(in_channels)\n        )\n\n    def forward(self, x):\n        return x + self.conv_block(x)\n\nclass Generator(nn.Module):\n    def __init__(self, input_channels, output_channels):\n        super(Generator, self).__init__()\n        self.model = nn.Sequential(\n            nn.Conv2d(input_channels, 64, kernel_size=7, stride=1, padding=3),\n            nn.InstanceNorm2d(64),\n            nn.ReLU(inplace=True),\n            self.downsample(64, 128),\n            self.downsample(128, 256),\n            *[ResidualBlock(256) for _ in range(6)],\n            self.upsample(256, 128),\n            self.upsample(128, 64),\n            nn.Conv2d(64, output_channels, kernel_size=7, stride=1, padding=3),\n            nn.Tanh()\n        )\n\n    def downsample(self, in_channels, out_channels):\n        return nn.Sequential(\n            nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=2, padding=1),\n            nn.InstanceNorm2d(out_channels),\n            nn.ReLU(inplace=True)\n        )\n\n    def upsample(self, in_channels, out_channels):\n        return nn.Sequential(\n            nn.ConvTranspose2d(in_channels, out_channels, kernel_size=3, stride=2, padding=1, output_padding=1),\n            nn.InstanceNorm2d(out_channels),\n            nn.ReLU(inplace=True)\n        )\n\n    def forward(self, x):\n        return self.model(x)\n\nclass Discriminator(nn.Module):\n    def __init__(self, input_channels):\n        super(Discriminator, self).__init__()\n        self.model = nn.Sequential(\n            self.discriminator_block(input_channels, 64, normalization=False),\n            self.discriminator_block(64, 128),\n            self.discriminator_block(128, 256),\n            self.discriminator_block(256, 512),\n            nn.Conv2d(512, 1, kernel_size=3, stride=1, padding=1)\n        )\n\n    def discriminator_block(self, in_channels, out_channels, normalization=True):\n        layers = [nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=2, padding=1)]\n        if normalization:\n            layers.append(nn.InstanceNorm2d(out_channels))\n        layers.append(nn.LeakyReLU(0.2, inplace=True))\n        return nn.Sequential(*layers)\n\n    def forward(self, x):\n        return self.model(x)\n\ndef weights_init_normal(m):\n    classname = m.__class__.__name__\n    if isinstance(m, (nn.Conv2d, nn.Linear)):\n        nn.init.normal_(m.weight.data, 0.0, 0.02)\n        if m.bias is not None:\n            nn.init.constant_(m.bias.data, 0.0)\n    elif isinstance(m, nn.InstanceNorm2d):\n        if m.weight is not None:  # Check if weight exists\n            nn.init.normal_(m.weight.data, 1.0, 0.02)\n        if m.bias is not None:  # Check if bias exists\n            nn.init.constant_(m.bias.data, 0.0)\n\n# Hyperparameters\ninput_channels = 3\noutput_channels = 3\nepochs = 100\nbatch_size = 1\nlr = 0.0002\nlambda_cycle = 10.0\nlambda_identity = 0.5 * lambda_cycle","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-03T16:03:31.081203Z","iopub.execute_input":"2024-11-03T16:03:31.081472Z","iopub.status.idle":"2024-11-03T16:03:31.103475Z","shell.execute_reply.started":"2024-11-03T16:03:31.081442Z","shell.execute_reply":"2024-11-03T16:03:31.102625Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"G_Monet = Generator(input_channels=3, output_channels=3)\nG_Photo = Generator(input_channels=3, output_channels=3)\nD_Monet = Discriminator(input_channels=3)\nD_Photo = Discriminator(input_channels=3)\n\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nG_Monet.to(device)\nG_Photo.to(device)\nD_Monet.to(device)\nD_Photo.to(device)\n\nG_Monet.apply(weights_init_normal)\nG_Photo.apply(weights_init_normal)\nD_Monet.apply(weights_init_normal)\nD_Photo.apply(weights_init_normal)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-03T16:03:31.105206Z","iopub.execute_input":"2024-11-03T16:03:31.105503Z","iopub.status.idle":"2024-11-03T16:03:31.443299Z","shell.execute_reply.started":"2024-11-03T16:03:31.105471Z","shell.execute_reply":"2024-11-03T16:03:31.442333Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Initialize optimizers\noptimizer_G = optim.Adam(list(G_Monet.parameters()) + list(G_Photo.parameters()), lr=lr, betas=(0.5, 0.999))\noptimizer_D_Monet = optim.Adam(D_Monet.parameters(), lr=lr, betas=(0.5, 0.999))\noptimizer_D_Photo = optim.Adam(D_Photo.parameters(), lr=lr, betas=(0.5, 0.999))\n\n# Loss functions\ncriterion_GAN = nn.MSELoss()\ncriterion_cycle = nn.L1Loss()\ncriterion_identity = nn.L1Loss()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-03T16:03:31.444673Z","iopub.execute_input":"2024-11-03T16:03:31.445479Z","iopub.status.idle":"2024-11-03T16:03:31.453304Z","shell.execute_reply.started":"2024-11-03T16:03:31.445430Z","shell.execute_reply":"2024-11-03T16:03:31.452466Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"epochs = 5\nfor epoch in range(epochs):\n    for i, (real_monet, real_photo) in enumerate(zip(monet_loader, photo_loader)):\n        real_monet = real_monet.to(device)\n        real_photo = real_photo.to(device)\n\n        # Train Generators\n        optimizer_G.zero_grad()\n\n        # Identity loss\n        identity_photo = G_Photo(real_photo)\n        loss_identity_photo = criterion_identity(identity_photo, real_photo) * lambda_identity\n\n        identity_monet = G_Monet(real_monet)\n        loss_identity_monet = criterion_identity(identity_monet, real_monet) * lambda_identity\n\n        # GAN loss\n        fake_monet = G_Monet(real_photo)\n        pred_fake = D_Monet(fake_monet)\n        loss_GAN_Monet = criterion_GAN(pred_fake, torch.ones_like(pred_fake))\n\n        fake_photo = G_Photo(real_monet)\n        pred_fake = D_Photo(fake_photo)\n        loss_GAN_Photo = criterion_GAN(pred_fake, torch.ones_like(pred_fake))\n\n        # Cycle loss\n        recovered_photo = G_Photo(fake_monet)\n        loss_cycle_photo = criterion_cycle(recovered_photo, real_photo) * lambda_cycle\n\n        recovered_monet = G_Monet(fake_photo)\n        loss_cycle_monet = criterion_cycle(recovered_monet, real_monet) * lambda_cycle\n\n        # Total loss\n        loss_G = loss_identity_photo + loss_identity_monet + loss_GAN_Monet + loss_GAN_Photo + loss_cycle_photo + loss_cycle_monet\n        loss_G.backward()\n        nn.utils.clip_grad_norm_(G_Monet.parameters(), max_norm=1.0)  # Gradient clipping\n        nn.utils.clip_grad_norm_(G_Photo.parameters(), max_norm=1.0)  # Gradient clipping\n        optimizer_G.step()\n\n        # Train Discriminator Monet\n        optimizer_D_Monet.zero_grad()\n\n        pred_real = D_Monet(real_monet)\n        loss_D_real = criterion_GAN(pred_real, torch.ones_like(pred_real))\n\n        fake_monet = fake_monet.detach()\n        pred_fake = D_Monet(fake_monet)\n        loss_D_fake = criterion_GAN(pred_fake, torch.zeros_like(pred_fake))\n\n        loss_D_Monet = (loss_D_real + loss_D_fake) * 0.5\n        loss_D_Monet.backward()\n        nn.utils.clip_grad_norm_(D_Monet.parameters(), max_norm=1.0)  # Gradient clipping\n        optimizer_D_Monet.step()\n\n        # Train Discriminator Photo\n        optimizer_D_Photo.zero_grad()\n\n        pred_real = D_Photo(real_photo)\n        loss_D_real = criterion_GAN(pred_real, torch.ones_like(pred_real))\n\n        fake_photo = fake_photo.detach()\n        pred_fake = D_Photo(fake_photo)\n        loss_D_fake = criterion_GAN(pred_fake, torch.zeros_like(pred_fake))\n\n        loss_D_Photo = (loss_D_real + loss_D_fake) * 0.5\n        loss_D_Photo.backward()\n        nn.utils.clip_grad_norm_(D_Photo.parameters(), max_norm=1.0)  # Gradient clipping\n        optimizer_D_Photo.step()\n\n        if i % 50 == 0:\n            print(f'Epoch [{epoch+1}/{epochs}], Batch [{i+1}], Loss G: {loss_G.item():.4f}, Loss D Monet: {loss_D_Monet.item():.4f}, Loss D Photo: {loss_D_Photo.item():.4f}')\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-03T16:08:56.675356Z","iopub.execute_input":"2024-11-03T16:08:56.675752Z","iopub.status.idle":"2024-11-03T16:14:08.589429Z","shell.execute_reply.started":"2024-11-03T16:08:56.675713Z","shell.execute_reply":"2024-11-03T16:14:08.588330Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from PIL import Image\nimport zipfile\n\n# Directory to save generated images\noutput_dir = 'images'\nos.makedirs(output_dir, exist_ok=True)\n\n# Set the model to evaluation mode\nG_Monet.eval()\n\n# Set the number of images to generate (between 7,000-10,000)\ntotal_images = 7000\nbatch_size = 4  # Your batch size\nimages_generated = 0\n\n# Iterate through the DataLoader\nwhile images_generated < total_images:\n    for i, data in enumerate(photo_loader):\n        real_photo = data.to(device)\n        with torch.no_grad():\n            fake_monet_batch = G_Monet(real_photo)\n  # Process each image in the batch\n        for j, fake_monet in enumerate(fake_monet_batch):\n            fake_monet = fake_monet.permute(1, 2, 0)  # Rearrange from CxHxW to HxWxC\n            fake_monet = fake_monet.cpu().numpy()\n            fake_monet = (fake_monet * 0.5 + 0.5) * 255  # Unnormalize\n            fake_monet = fake_monet.astype(np.uint8)  # Convert to uint8\n\n            img = Image.fromarray(fake_monet)\n            img_path = os.path.join(output_dir, f'image_{images_generated + 1}.png')\n            img.save(img_path)\n            images_generated += 1\n\n            # Break if we reach the total_images\n            if images_generated >= total_images:\n                break\n        if images_generated >= total_images:\n            break\n\nprint(f\"Generated {images_generated}/{total_images} images saved to {output_dir}\")\n\n# Zip all the images into a zip file\nzip_filename = \"images.zip\"\nwith zipfile.ZipFile(zip_filename, 'w', zipfile.ZIP_DEFLATED) as img_zip:\n    for filename in os.listdir(output_dir):\n        img_zip.write(os.path.join(output_dir, filename), arcname=filename)\n\nprint(f\"All images zipped into {zip_filename}\")        ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-03T16:14:08.591078Z","iopub.execute_input":"2024-11-03T16:14:08.591400Z","iopub.status.idle":"2024-11-03T16:18:26.487469Z","shell.execute_reply.started":"2024-11-03T16:14:08.591365Z","shell.execute_reply":"2024-11-03T16:18:26.486382Z"}},"outputs":[],"execution_count":null}]}