{"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":"gpu","dataSources":[{"sourceId":21755,"databundleVersionId":1475600,"sourceType":"competition"},{"sourceId":68574,"sourceType":"modelInstanceVersion","modelInstanceId":57177}],"dockerImageVersionId":30733,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"Now that your CycleGAN model has been trained, you can use it to generate Monet-style images from photos in the specified directory. The process involves the following steps:\n\n1. **Load the Trained Generator Model**: Load the trained model that translates photos to Monet-style paintings.\n2. **Process the Photos**: Load and preprocess the photos from the given path.\n3. **Generate Monet-Style Images**: Use the generator to convert the photos.\n4. **Save the Outputs**: Save the generated images to a specified directory.\n5. **Create a .zip File**: Compress the directory into a .zip file for easy download.","metadata":{}},{"cell_type":"markdown","source":"Let's walk through these steps with detailed explanations and code.\n\n### Step 1: Load the Trained Generator Model\n\nAssume that you have trained and saved your generator model. Here’s how you can load it:","metadata":{}},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torchvision import transforms\nfrom PIL import Image\nimport os\nimport shutil\n\n# Define the Generator model class\nclass Generator(nn.Module):\n    def __init__(self, in_channels, out_channels):\n        super(Generator, self).__init__()\n        self.encoder = nn.Sequential(\n            nn.Conv2d(in_channels, 64, kernel_size=7, stride=1, padding=3),\n            nn.BatchNorm2d(64),\n            nn.ReLU(inplace=True),\n            nn.Conv2d(64, 128, kernel_size=3, stride=2, padding=1),\n            nn.BatchNorm2d(128),\n            nn.ReLU(inplace=True),\n            nn.Conv2d(128, 256, kernel_size=3, stride=2, padding=1),\n            nn.BatchNorm2d(256),\n            nn.ReLU(inplace=True)\n        )\n        self.res_blocks = nn.Sequential(\n            *[ResidualBlock(256) for _ in range(6)]\n        )\n        self.decoder = nn.Sequential(\n            nn.ConvTranspose2d(256, 128, kernel_size=3, stride=2, padding=1, output_padding=1),\n            nn.BatchNorm2d(128),\n            nn.ReLU(inplace=True),\n            nn.ConvTranspose2d(128, 64, kernel_size=3, stride=2, padding=1, output_padding=1),\n            nn.BatchNorm2d(64),\n            nn.ReLU(inplace=True),\n            nn.Conv2d(64, out_channels, kernel_size=7, stride=1, padding=3),\n            nn.Tanh()\n        )\n    def forward(self, x):\n        x = self.encoder(x)\n        x = self.res_blocks(x)\n        x = self.decoder(x)\n        return x\n\n# Residual Block class\nclass ResidualBlock(nn.Module):\n    def __init__(self, in_channels):\n        super(ResidualBlock, self).__init__()\n        self.conv1 = nn.Conv2d(in_channels, in_channels, kernel_size=3, padding=1)\n        self.bn1 = nn.BatchNorm2d(in_channels)\n        self.conv2 = nn.Conv2d(in_channels, in_channels, kernel_size=3, padding=1)\n        self.bn2 = nn.BatchNorm2d(in_channels)\n\n    def forward(self, x):\n        residual = x\n        out = F.relu(self.bn1(self.conv1(x)))\n        out = self.bn2(self.conv2(out))\n        out += residual\n        return out","metadata":{"execution":{"iopub.status.busy":"2024-06-24T02:53:47.393990Z","iopub.execute_input":"2024-06-24T02:53:47.394646Z","iopub.status.idle":"2024-06-24T02:53:51.904755Z","shell.execute_reply.started":"2024-06-24T02:53:47.394597Z","shell.execute_reply":"2024-06-24T02:53:51.903917Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load the trained model\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\nG_XtoY = Generator(in_channels=3, out_channels=3).to(device)\nG_XtoY.load_state_dict(torch.load('/kaggle/input/monetgen/pytorch/monetgen_v2/1/G_XtoY.pth'))\nG_XtoY.eval()","metadata":{"execution":{"iopub.status.busy":"2024-06-24T02:53:51.906169Z","iopub.execute_input":"2024-06-24T02:53:51.906584Z","iopub.status.idle":"2024-06-24T02:53:52.673807Z","shell.execute_reply.started":"2024-06-24T02:53:51.906557Z","shell.execute_reply":"2024-06-24T02:53:52.672919Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Step 2: Process the Photos\n\nLoad and preprocess the photos to match the input format expected by the generator.","metadata":{}},{"cell_type":"code","source":"import os\nfrom torchvision import transforms\nfrom PIL import Image\nimport numpy as np\n\n# Path to the directory containing photos\nphotos_path = \"/kaggle/input/gan-getting-started/photo_jpg\"\n\n# Define the image transformation\ntransform = transforms.Compose([\n    transforms.Resize((256, 256)),\n    transforms.ToTensor(),\n    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))\n])\n\n# Load and preprocess photos\nphoto_filenames = [f for f in os.listdir(photos_path) if f.endswith('.jpg')]\nphotos = []\nfor filename in photo_filenames:\n    image = Image.open(os.path.join(photos_path, filename)).convert('RGB')\n    image = transform(image)\n    photos.append(image)\n\nphotos = torch.stack(photos)\n","metadata":{"execution":{"iopub.status.busy":"2024-06-24T02:53:55.270193Z","iopub.execute_input":"2024-06-24T02:53:55.270548Z","iopub.status.idle":"2024-06-24T02:54:55.337407Z","shell.execute_reply.started":"2024-06-24T02:53:55.270520Z","shell.execute_reply":"2024-06-24T02:54:55.336561Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"photos[:5].shape","metadata":{"execution":{"iopub.status.busy":"2024-06-24T02:54:55.339252Z","iopub.execute_input":"2024-06-24T02:54:55.339605Z","iopub.status.idle":"2024-06-24T02:54:55.347442Z","shell.execute_reply.started":"2024-06-24T02:54:55.339575Z","shell.execute_reply":"2024-06-24T02:54:55.346641Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Step 3: Generate Monet-Style Images\n\nUse the loaded generator model to convert the photos to Monet-style paintings.\n\n\n#### Requirements from the competetion:\n\n**Submission File** \n    You are going to generate 7,000-10,000 Monet-style images that are in jpg format. Their sizes should be 256x256x3 (RGB). Then you need to zip those images and your output from your Kernel should only have ONE output file named images.zip.","metadata":{}},{"cell_type":"code","source":"%%time\n# Directory to save the output images\noutput_dir = '/images'\nos.makedirs(output_dir, exist_ok=True)\n\n# Generate Monet-style images\nwith torch.no_grad():\n    for i, photo in enumerate(photos):\n        photo = photo.unsqueeze(0).to(device)  # Add batch dimension\n        monet_style_image = G_XtoY(photo)\n        monet_style_image = monet_style_image.squeeze(0).cpu()  # Remove batch dimension\n\n        # Convert tensor to PIL Image and denormalize\n        monet_style_image = transforms.ToPILImage()(monet_style_image * 0.5 + 0.5)\n        monet_style_image.save(os.path.join(output_dir, f'monet_style_{i+1}.jpg'))\n","metadata":{"execution":{"iopub.status.busy":"2024-06-24T02:54:55.348757Z","iopub.execute_input":"2024-06-24T02:54:55.349044Z","iopub.status.idle":"2024-06-24T02:56:21.150100Z","shell.execute_reply.started":"2024-06-24T02:54:55.349021Z","shell.execute_reply":"2024-06-24T02:56:21.149190Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Step 4: Create a .zip File\n\nZip the output directory containing the Monet-style images.","metadata":{}},{"cell_type":"code","source":"import shutil","metadata":{"execution":{"iopub.status.busy":"2024-06-24T02:56:21.151956Z","iopub.execute_input":"2024-06-24T02:56:21.152231Z","iopub.status.idle":"2024-06-24T02:56:21.156156Z","shell.execute_reply.started":"2024-06-24T02:56:21.152207Z","shell.execute_reply":"2024-06-24T02:56:21.155299Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"output_dir","metadata":{"execution":{"iopub.status.busy":"2024-06-24T02:56:21.157298Z","iopub.execute_input":"2024-06-24T02:56:21.157639Z","iopub.status.idle":"2024-06-24T02:56:21.170416Z","shell.execute_reply.started":"2024-06-24T02:56:21.157586Z","shell.execute_reply":"2024-06-24T02:56:21.169531Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Make Zipfile\nshutil.make_archive(\"/kaggle/working/images\", 'zip', output_dir)","metadata":{"execution":{"iopub.status.busy":"2024-06-24T02:56:21.171506Z","iopub.execute_input":"2024-06-24T02:56:21.171762Z","iopub.status.idle":"2024-06-24T02:56:24.906915Z","shell.execute_reply.started":"2024-06-24T02:56:21.171741Z","shell.execute_reply":"2024-06-24T02:56:24.905868Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nprint(\"Generated Monet-style images and created a zip file successfully.\")","metadata":{"execution":{"iopub.status.busy":"2024-06-24T02:56:24.908023Z","iopub.execute_input":"2024-06-24T02:56:24.908368Z","iopub.status.idle":"2024-06-24T02:56:24.913475Z","shell.execute_reply.started":"2024-06-24T02:56:24.908333Z","shell.execute_reply":"2024-06-24T02:56:24.912491Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"raw","source":"import os\nimport random\nimport matplotlib.pyplot as plt\nfrom PIL import Image\n\n# Number of images to display\nnum_images = 10\n\n# Get list of image file names\nimage_files = [f for f in os.listdir(output_dir) if f.endswith('.jpg')]\n\n# Randomly select images to display\nsample_images = random.sample(image_files, num_images)\n\n# Set up Matplotlib figure\nfig, axs = plt.subplots(2, 5, figsize=(15, 6))\nfig.suptitle('Sample Generated Monet-Style Images', fontsize=16)\n\n# Plot images\nfor i, ax in enumerate(axs.flatten()):\n    img_path = os.path.join(output_dir, sample_images[i])\n    img = Image.open(img_path)\n    ax.imshow(img)\n    ax.axis('off')  # Turn off axis\n    ax.set_title(f\"Image {i+1}\")\n\n# Show the plot\nplt.tight_layout(rect=[0, 0, 1, 0.95])\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-06-24T03:08:12.780713Z","iopub.execute_input":"2024-06-24T03:08:12.781483Z","iopub.status.idle":"2024-06-24T03:08:14.021294Z","shell.execute_reply.started":"2024-06-24T03:08:12.781451Z","shell.execute_reply":"2024-06-24T03:08:14.020244Z"}}},{"cell_type":"code","source":"# Delete Origin file\n# shutil.rmtree(output_dir)","metadata":{"execution":{"iopub.status.busy":"2024-06-23T06:16:10.325220Z","iopub.execute_input":"2024-06-23T06:16:10.325604Z","iopub.status.idle":"2024-06-23T06:16:10.584068Z","shell.execute_reply.started":"2024-06-23T06:16:10.325564Z","shell.execute_reply":"2024-06-23T06:16:10.583241Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This code will process the photos, generate Monet-style images, save them in the specified directory, and create a .zip file of the output directory. You can now easily download the .zip file and share the results.","metadata":{}}]}