{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":21755,"databundleVersionId":1475600,"sourceType":"competition"},{"sourceId":261497222,"sourceType":"kernelVersion"},{"sourceId":471612,"sourceType":"modelInstanceVersion","modelInstanceId":380242,"modelId":399998},{"sourceId":471979,"sourceType":"modelInstanceVersion","modelInstanceId":380488,"modelId":400203},{"sourceId":578433,"sourceType":"modelInstanceVersion","isSourceIdPinned":true,"modelInstanceId":431906,"modelId":448822},{"sourceId":578456,"sourceType":"modelInstanceVersion","isSourceIdPinned":true,"modelInstanceId":431913,"modelId":448829}],"dockerImageVersionId":31089,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"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    print(dirname)\n    for filename in filenames:\n        continue\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","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-09-12T20:47:40.956049Z","iopub.execute_input":"2025-09-12T20:47:40.956472Z","iopub.status.idle":"2025-09-12T20:47:50.668564Z","shell.execute_reply.started":"2025-09-12T20:47:40.956447Z","shell.execute_reply":"2025-09-12T20:47:50.667521Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ls /kaggle/input/","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-12T20:47:50.670312Z","iopub.execute_input":"2025-09-12T20:47:50.670675Z","iopub.status.idle":"2025-09-12T20:47:50.82545Z","shell.execute_reply.started":"2025-09-12T20:47:50.670644Z","shell.execute_reply":"2025-09-12T20:47:50.823843Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"\nThe self.net = nn.Sequential(...) Block\nThe network is built using nn.Sequential, which creates a container where modules are executed in the order they are passed.\n\nInput: A random noise tensor of shape (N, noise_dim, 1, 1), where N is the batch size. For example: (64, 100, 1, 1).\n\nBlock 1: Initial Projection\n\nnn.ConvTranspose2d(noise_dim, feature_maps*8, kernel_size=4, stride=1, padding=0)\n\nPurpose: This layer takes the 1x1 noise vector and projects it into a small spatial volume. It's the starting point of the image generation process.\n\nInput Shape: (N, 100, 1, 1)\n\nCalculation: H_out=(1−1)×1−2×0+4=4\n\nOutput Shape: (N, 512, 4, 4) (since feature_maps*8 = 64*8 = 512)\n\nBlock 2: Upsample to 8x8\n\nnn.ConvTranspose2d(feature_maps*8, feature_maps*4, kernel_size=4, stride=2, padding=1)\n\nPurpose: To double the spatial dimensions while halving the number of feature maps. This combination of kernel_size=4, stride=2, padding=1 is a standard DCGAN practice for cleanly doubling the height and width.\n\nInput Shape: (N, 512, 4, 4)\n\nCalculation: H_out=(4−1)×2−2×1+4=3×2−2+4=8\n\nOutput Shape: (N, 256, 8, 8)\n\nBlock 3: Upsample to 16x16\n\nnn.ConvTranspose2d(feature_maps*4, feature_maps*2, kernel_size=4, stride=2, padding=1)\n\nInput Shape: (N, 256, 8, 8)\n\nCalculation: H_out=(8−1)×2−2×1+4=14−2+4=16\n\nOutput Shape: (N, 128, 16, 16)\n\nBlock 4: Upsample to 32x32\n\nnn.ConvTranspose2d(feature_maps * 2, feature_maps, kernel_size=4, stride=2, padding=1)\n\nInput Shape: (N, 128, 16, 16)\n\nOutput Shape: (N, 64, 32, 32)\n\nBlock 5: Upsample to 64x64\n\nnn.ConvTranspose2d(feature_maps, feature_maps // 2, kernel_size=4, stride=2, padding=1)\n\nInput Shape: (N, 64, 32, 32)\n\nOutput Shape: (N, 32, 64, 64)\n\nBlock 6: Upsample to 128x128\n\nnn.ConvTranspose2d(feature_maps//2, feature_maps // 4, kernel_size=4, stride=2, padding=1)\n\nInput Shape: (N, 32, 64, 64)\n\nOutput Shape: (N, 16, 128, 128)\n\nBlock 7: Final Output Layer\n\nnn.ConvTranspose2d(feature_maps // 4, image_channels, kernel_size=4, stride=2, padding=1)\n\nPurpose: This is the final upsampling layer that produces the image. The output channels are set to image_channels (e.g., 3 for RGB).\n\nInput Shape: (N, 16, 128, 128)\n\nOutput Shape: (N, 3, 256, 256)\n\nActivation Function: nn.Tanh()\n\nPurpose: The Tanh activation function squashes the output values of the final layer to be in the range [-1, 1]. This is a crucial step. When you train a GAN, you typically normalize your real training images to this same range. Using Tanh ensures that the generated images have the same scale and distribution as the real images, making the Discriminator's job more consistent.\n\n","metadata":{}},{"cell_type":"code","source":"loimport torch \nimport torch.nn as nn\n\n'''\nClass for Generator component for DCGAN (Deep Convolutional Adverserial Network)\nto generate 256x256 images.\n'''\nclass Generator(nn.Module):\n    def __init__(self, noise_dim=100, image_channels=3, feature_maps=64):\n        super(Generator, self).__init__()\n\n        '''\n        Generator generates image from noise. That is why we use ConvTranspose2D\n        as its internal layers, to upsample the noise into an image.\n        '''\n        self.net = nn.Sequential(\n            # Input: (N, noise_dim, 1, 1)\n            self._make_block(noise_dim, feature_maps * 8, kernel_size=4, stride=1, padding=0),\n            # Shape: (N, feature_maps*8, 4, 4)\n\n            self._make_block(feature_maps * 8, feature_maps * 4, kernel_size=4, stride=2, padding=1),\n            # Shape: (N, feature_maps*4, 8, 8)\n\n            self._make_block(feature_maps * 4, feature_maps * 2, kernel_size=4, stride=2, padding=1),\n            # Shape: (N, feature_maps*2, 16, 16)\n\n            self._make_block(feature_maps * 2, feature_maps, kernel_size=4, stride=2, padding=1),\n            # Shape: (N, feature_maps, 32, 32)\n\n            # self._make_block(feature_maps, feature_maps // 2, kernel_size=4, stride=2, padding=1),\n            # # Shape: (N, feature_maps/2, 64, 64)\n\n            # self._make_block(feature_maps // 2, feature_maps // 4, kernel_size=4, stride=2, padding=1),\n            # # Shape: (N, feature_maps/4, 128, 128)\n\n            # Final Output Layer\n            nn.ConvTranspose2d(\n                feature_maps, image_channels, kernel_size=4, stride=2, padding=1\n            ),\n            # Output Shape: (N, image_channels, 256, 256)\n            nn.Tanh() # Normalize output to [-1, 1]\n        )\n\n    def _make_block(self, in_channels, out_channels, kernel_size, stride, padding):\n        \"\"\"Helper function to create a standard DCGAN generator block.\"\"\"\n        return nn.Sequential(\n            nn.ConvTranspose2d(\n                in_channels,\n                out_channels,\n                kernel_size=kernel_size,\n                stride=stride,\n                padding=padding,\n                bias=False # Set bias to False as BatchNorm2d has its own bias (beta)\n            ),\n            nn.BatchNorm2d(out_channels),\n            nn.LeakyReLU(0.2, inplace=True),\n        )\n\n    def forward(self, x):\n        \"\"\"Produce output from the network.\"\"\"\n        return self.net(x)\n\n# Example of how to use it\nif __name__ == '__main__':\n    noise_dimension = 100\n    batch_size = 16\n    gen = Generator(noise_dim=noise_dimension)\n    print(gen)\n\n    # Create a random noise vector\n    noise = torch.randn(batch_size, noise_dimension, 1, 1)\n    print(noise.shape)\n\n    # Generate an image\n    fake_image = gen(noise)\n\n    print(\"Generator output shape:\", fake_image.shape) # Expected: torch.Size([1, 3, 256, 256])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-12T20:47:56.645892Z","iopub.execute_input":"2025-09-12T20:47:56.646735Z","iopub.status.idle":"2025-09-12T20:47:56.776771Z","shell.execute_reply.started":"2025-09-12T20:47:56.646695Z","shell.execute_reply":"2025-09-12T20:47:56.775663Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from torchvision.utils import save_image, make_grid\nimport matplotlib.pyplot as plt\n# Convert range from [-1, 1] to [0, 1]\nprint(\"Making a grid\")\ngrid = make_grid(fake_image, nrow=4, normalize=True)\n\nprint(\"Images\")\n# Plot\nplt.figure(figsize=(8, 8))\nplt.imshow(grid.permute(1, 2, 0).cpu().numpy())\nplt.axis(\"off\")\nplt.title(\"Generated Images\")\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-12T20:48:00.539844Z","iopub.execute_input":"2025-09-12T20:48:00.540242Z","iopub.status.idle":"2025-09-12T20:48:00.900864Z","shell.execute_reply.started":"2025-09-12T20:48:00.540213Z","shell.execute_reply":"2025-09-12T20:48:00.897603Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# from PIL import Image\n\n# img_pil = Image.fromarray(fake_image[0].permute(1, 2, 0).numpy())  # CHW → HWC\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-12T20:48:05.506871Z","iopub.execute_input":"2025-09-12T20:48:05.507248Z","iopub.status.idle":"2025-09-12T20:48:05.511923Z","shell.execute_reply.started":"2025-09-12T20:48:05.507223Z","shell.execute_reply":"2025-09-12T20:48:05.510918Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\n\n# Initialize model\ngen = Generator()\n\nmodel_path = \"/kaggle/input/generator_v0/pytorch/default/1/generator.pth\"\ngen.load_state_dict(torch.load(model_path, map_location='cpu'))\n\n\nprint(gen.eval())\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-12T20:48:09.117963Z","iopub.execute_input":"2025-09-12T20:48:09.118453Z","iopub.status.idle":"2025-09-12T20:48:09.182938Z","shell.execute_reply.started":"2025-09-12T20:48:09.118425Z","shell.execute_reply":"2025-09-12T20:48:09.181963Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"device = \"cuda\" if torch.cuda.is_available() else \"cpu\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-12T20:48:11.17061Z","iopub.execute_input":"2025-09-12T20:48:11.171001Z","iopub.status.idle":"2025-09-12T20:48:11.176032Z","shell.execute_reply.started":"2025-09-12T20:48:11.170973Z","shell.execute_reply":"2025-09-12T20:48:11.174906Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"device","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-12T20:48:12.221507Z","iopub.execute_input":"2025-09-12T20:48:12.222365Z","iopub.status.idle":"2025-09-12T20:48:12.227827Z","shell.execute_reply.started":"2025-09-12T20:48:12.222338Z","shell.execute_reply":"2025-09-12T20:48:12.226962Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tqdm import tqdm\nimport os\nfrom PIL import Image\nimport zipfile\nimport io\n\nbatch_size = 100\nz_dim = 100  # latent dim\nnum_images = 10000\n\nzip_path = \"images.zip\"\nzipf = zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED)\n\nidx = 0\nwith torch.no_grad():\n    for i in tqdm(range(0, num_images, batch_size)):\n        print(i)\n        z = torch.randn(batch_size, z_dim, 1, 1).to(device)\n        print(z.shape)\n        fake_imgs = gen(z)\n        fake_imgs = (fake_imgs + 1) / 2  # scale from [-1, 1] to [0, 1]\n\n        fake_imgs = (fake_imgs * 255).clamp(0, 255).byte().cpu()  # shape: [B, 3, H, W]\n        print(fake_imgs.shape)\n        for img_tensor in fake_imgs:\n            idx += 1\n            print(idx)\n            img_pil = Image.fromarray(img_tensor.permute(1, 2, 0).numpy())  # CHW → HWC\n            img_bytes = io.BytesIO()\n            img_pil.save(img_bytes, format='PNG')\n            zipf.writestr(f'image_{idx:05d}.png', img_bytes.getvalue())\n\nzipf.close()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-12T20:49:31.820576Z","iopub.execute_input":"2025-09-12T20:49:31.820948Z","iopub.status.idle":"2025-09-12T20:49:31.898602Z","shell.execute_reply.started":"2025-09-12T20:49:31.820917Z","shell.execute_reply":"2025-09-12T20:49:31.897524Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!zip -rq /kaggle/working/images.zip /kaggle/working/images\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-09-12T20:48:39.303188Z","iopub.execute_input":"2025-09-12T20:48:39.303651Z","iopub.status.idle":"2025-09-12T20:48:39.466313Z","shell.execute_reply.started":"2025-09-12T20:48:39.30362Z","shell.execute_reply":"2025-09-12T20:48:39.46468Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}