{"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":"nvidiaTeslaT4","dataSources":[{"sourceId":10091691,"sourceType":"datasetVersion","datasetId":6222942}],"dockerImageVersionId":31090,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport os\nfrom tqdm import tqdm\n\nfrom PIL import Image\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torchvision\nimport torchvision.transforms as T\nfrom torch.utils.data import Dataset, DataLoader, random_split\nfrom torch.utils.data import RandomSampler","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-07-19T22:00:04.547198Z","iopub.execute_input":"2025-07-19T22:00:04.547821Z","iopub.status.idle":"2025-07-19T22:00:10.582995Z","shell.execute_reply.started":"2025-07-19T22:00:04.547787Z","shell.execute_reply":"2025-07-19T22:00:10.582371Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\ndevice","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-19T22:00:10.584114Z","iopub.execute_input":"2025-07-19T22:00:10.584434Z","iopub.status.idle":"2025-07-19T22:00:10.677202Z","shell.execute_reply.started":"2025-07-19T22:00:10.584405Z","shell.execute_reply":"2025-07-19T22:00:10.676437Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"dir = '/kaggle/input/random-human-face-dataset/human_face_cropped/train/'\nfaces = os.listdir(dir)\npath = dir+faces[0]\n# img = Image.open(path)\nimg = Image.open(path).convert(\"RGB\")\nprint(img.size)\nimg","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-19T22:00:10.677872Z","iopub.execute_input":"2025-07-19T22:00:10.678122Z","iopub.status.idle":"2025-07-19T22:00:10.850763Z","shell.execute_reply.started":"2025-07-19T22:00:10.678105Z","shell.execute_reply":"2025-07-19T22:00:10.850066Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class photo_dataset(Dataset):\n    def __init__(self, photo_dir, transform, max_images=1000):\n        super().__init__()\n        self.dir = photo_dir\n        self.images = os.listdir(photo_dir)\n\n        # Limit to max_images if more exist\n        if len(self.images) > max_images:\n            self.images = self.images[:max_images]\n\n        self.transform = transform\n\n    def __len__(self):\n        \n        return len(self.images)\n\n    def __getitem__(self, idx):\n        image = Image.open(os.path.join(self.dir, self.images[idx]))\n        image = self.transform(image)\n        \n        return image\n        ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-19T22:00:12.325671Z","iopub.execute_input":"2025-07-19T22:00:12.326227Z","iopub.status.idle":"2025-07-19T22:00:12.331449Z","shell.execute_reply.started":"2025-07-19T22:00:12.326198Z","shell.execute_reply":"2025-07-19T22:00:12.330659Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"transform = T.Compose([\n    T.Resize((256,256)),\n    T.ToTensor(),\n    T.Normalize(0.5, 0.5)\n])\n\ndataset = photo_dataset(dir, transform)\na = dataset.__getitem__(1)\nprint(len(dataset))\nprint(a.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-19T22:00:14.216708Z","iopub.execute_input":"2025-07-19T22:00:14.217089Z","iopub.status.idle":"2025-07-19T22:00:14.246562Z","shell.execute_reply.started":"2025-07-19T22:00:14.217063Z","shell.execute_reply":"2025-07-19T22:00:14.245748Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_size, test_size = int(len(dataset) * 0.9), len(dataset) - int(len(dataset) * 0.9)\nprint(train_size, test_size)\n\ntraining_data, testing_data = random_split(dataset, [train_size, test_size], torch.manual_seed(32))\n\ntrain_dataloader = DataLoader(training_data.dataset, batch_size=16, shuffle=True, drop_last=True)\ntest_dataloader = DataLoader(testing_data.dataset, batch_size=1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-19T22:00:14.554515Z","iopub.execute_input":"2025-07-19T22:00:14.555054Z","iopub.status.idle":"2025-07-19T22:00:14.572808Z","shell.execute_reply.started":"2025-07-19T22:00:14.555032Z","shell.execute_reply":"2025-07-19T22:00:14.572135Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class Discriminator(nn.Module):\n    def __init__(self):\n        super().__init__()\n\n        # # initial size (batch_size, channel, height, width) = (b, 3, 256, 256)\n        # output = (Input+2XPadding−Kernel)/stride + 1\n        self.conv1 = nn.Conv2d(in_channels=3, out_channels=64, kernel_size=4, \n                               stride=2, padding=1, bias=False) # (b, 64, 128, 128)\n        self.conv2 = nn.Conv2d(in_channels=64, out_channels=128, kernel_size=4, \n                               stride=2, padding=1, bias=False) # (b, 128, 64, 64)\n        self.conv3 = nn.Conv2d(in_channels=128, out_channels=256, kernel_size=4, \n                               stride=2, padding=1, bias=False) # (b, 256, 32, 32)\n        self.conv4 = nn.Conv2d(in_channels=256, out_channels=512, kernel_size=4, \n                               stride=2, padding=1, bias=False) # (b, 512, 16, 16)\n        self.conv5 = nn.Conv2d(in_channels=512, out_channels=512, kernel_size=4, \n                               stride=2, padding=1, bias=False) # (b, 512, 8, 8)\n        self.conv6 = nn.Conv2d(in_channels=512, out_channels=1024, kernel_size=4, \n                               stride=2, padding=1, bias=False) # (b, 1024, 4, 4)\n        self.conv7 = nn.Conv2d(in_channels=1024, out_channels=1, kernel_size=4, \n                               stride=1, padding=0, bias=False) # (b, 1, 1, 1)\n\n        self.bn2 = nn.BatchNorm2d(128)\n        self.bn3 = nn.BatchNorm2d(256)\n        self.bn4 = nn.BatchNorm2d(512)\n        self.bn5 = nn.BatchNorm2d(512)\n        self.bn6 = nn.BatchNorm2d(1024)\n\n    \n    def forward(self, x):\n\n        # print('0 : ', x.shape)\n        x = F.leaky_relu(self.conv1(x), 0.2)\n        # print('1 : ', x.shape)\n        x = F.leaky_relu(self.conv2(x), 0.2)\n        x = self.bn2(x)\n        # print('2 : ', x.shape)\n        x = F.leaky_relu(self.conv3(x), 0.2)\n        x = self.bn3(x)\n        # print('3 : ', x.shape)\n        x = F.leaky_relu(self.conv4(x), 0.2)\n        x = self.bn4(x)\n        # print('4 : ', x.shape)\n        x = F.leaky_relu(self.conv5(x), 0.2)\n        x = self.bn5(x)\n        # print('5 : ', x.shape)\n        x = F.leaky_relu(self.conv6(x), 0.2)\n        x = self.bn6(x)\n        # print('6 : ', x.shape)\n        x = self.conv7(x)\n        # print('7 : ', x.shape)\n\n        return torch.sigmoid(x).view(-1,1)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-19T22:00:16.744761Z","iopub.execute_input":"2025-07-19T22:00:16.745056Z","iopub.status.idle":"2025-07-19T22:00:16.753981Z","shell.execute_reply.started":"2025-07-19T22:00:16.745032Z","shell.execute_reply":"2025-07-19T22:00:16.753292Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"dnet = Discriminator()\ny = dnet(torch.randn(10,3,256,256))\n# print(y)\nprint(y.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-19T22:00:18.360674Z","iopub.execute_input":"2025-07-19T22:00:18.361045Z","iopub.status.idle":"2025-07-19T22:00:19.068086Z","shell.execute_reply.started":"2025-07-19T22:00:18.361009Z","shell.execute_reply":"2025-07-19T22:00:19.067223Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class Generator(nn.Module):\n    def __init__(self):\n        super().__init__()\n\n        # # initial size (batch_size, channel, height, width) = (b, 100, 1, 1)\n        # output = (Input−1)×Stride−2Padding+Kernet+output_padding\n        self.conv1 = nn.ConvTranspose2d(in_channels=100, out_channels=1024, kernel_size=4, \n                               stride=1, padding=0, bias=False) # (b, 1024, 4, 4)\n        self.conv2 = nn.ConvTranspose2d(in_channels=1024, out_channels=512, kernel_size=4, \n                               stride=2, padding=1, bias=False) # (b, 512, 8, 8)\n        self.conv3 = nn.ConvTranspose2d(in_channels=512, out_channels=512, kernel_size=4, \n                               stride=2, padding=1, bias=False) # (b, 512, 16, 16)\n        self.conv4 = nn.ConvTranspose2d(in_channels=512, out_channels=256, kernel_size=4, \n                               stride=2, padding=1, bias=False) # (b, 256, 32, 32)\n        self.conv5 = nn.ConvTranspose2d(in_channels=256, out_channels=128, kernel_size=4, \n                               stride=2, padding=1, bias=False) # (b, 128, 64, 64)\n        self.conv6 = nn.ConvTranspose2d(in_channels=128, out_channels=64, kernel_size=4, \n                               stride=2, padding=1, bias=False) # (b, 64, 128, 128)\n        self.conv7 = nn.ConvTranspose2d(in_channels=64, out_channels=3, kernel_size=4, \n                               stride=2, padding=1, bias=False) # (b, 3, 256, 256)\n\n        self.bn1 = nn.BatchNorm2d(1024)\n        self.bn2 = nn.BatchNorm2d(512)\n        self.bn3 = nn.BatchNorm2d(512)\n        self.bn4 = nn.BatchNorm2d(256)\n        self.bn5 = nn.BatchNorm2d(128)\n        self.bn6 = nn.BatchNorm2d(64)\n\n    \n    def forward(self, x):\n\n        # print('0 : ', x.shape)\n        x = F.relu(self.bn1(self.conv1(x)) )\n        # print('1 : ', x.shape)\n        x = F.relu(self.bn2(self.conv2(x)) )\n        # print('2 : ', x.shape)\n        x = F.relu(self.bn3(self.conv3(x)) )\n        # print('3 : ', x.shape)\n        x = F.relu(self.bn4(self.conv4(x)) )\n        # print('4 : ', x.shape)\n        x = F.relu(self.bn5(self.conv5(x)) )\n        # print('5 : ', x.shape)\n        x = F.relu(self.bn6(self.conv6(x)) )\n        # print('6 : ', x.shape)\n        x = torch.tanh(self.conv7(x))\n        # print('7 : ', x.shape)\n\n        return x","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-19T22:00:19.069290Z","iopub.execute_input":"2025-07-19T22:00:19.069582Z","iopub.status.idle":"2025-07-19T22:00:19.078184Z","shell.execute_reply.started":"2025-07-19T22:00:19.069556Z","shell.execute_reply":"2025-07-19T22:00:19.077554Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"gnet = Generator()\ny = gnet(torch.randn(16,100,1,1))\nprint(y.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-19T22:00:21.514752Z","iopub.execute_input":"2025-07-19T22:00:21.515051Z","iopub.status.idle":"2025-07-19T22:00:22.635080Z","shell.execute_reply.started":"2025-07-19T22:00:21.515027Z","shell.execute_reply":"2025-07-19T22:00:22.634319Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"img = y[0].detach().cpu()  # [3, 256, 256]\n\n# Convert from [-1, 1] to [0, 1] range (tanh output fix)\nimg = (img + 1) / 2.0\n\n# Convert to [H, W, C] for matplotlib\nimg = T.ToPILImage()(img)\nplt.imshow(img)\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-19T22:00:23.213954Z","iopub.execute_input":"2025-07-19T22:00:23.214213Z","iopub.status.idle":"2025-07-19T22:00:23.477608Z","shell.execute_reply.started":"2025-07-19T22:00:23.214193Z","shell.execute_reply":"2025-07-19T22:00:23.476846Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def weights_init(m):\n    if isinstance(m, (nn.Conv2d, nn.ConvTranspose2d, nn.BatchNorm2d)):\n        nn.init.normal_(m.weight.data, 0.0, 0.02)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-19T22:00:26.052130Z","iopub.execute_input":"2025-07-19T22:00:26.052362Z","iopub.status.idle":"2025-07-19T22:00:26.056669Z","shell.execute_reply.started":"2025-07-19T22:00:26.052345Z","shell.execute_reply":"2025-07-19T22:00:26.055939Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"loss_func = nn.BCELoss()\n\ngnet = Generator()\ndnet = Discriminator()\n\ngnet.apply(weights_init)\ndnet.apply(weights_init)\n\ngnet = gnet.to(device)\ndnet = dnet.to(device)\n\ng_optimizer = torch.optim.Adam(gnet.parameters(), lr=0.0002, betas=(0.5, 0.999))\nd_optimizer = torch.optim.Adam(dnet.parameters(), lr=0.0002, betas=(0.5, 0.999))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-19T22:02:21.845355Z","iopub.execute_input":"2025-07-19T22:02:21.845609Z","iopub.status.idle":"2025-07-19T22:02:22.357214Z","shell.execute_reply.started":"2025-07-19T22:02:21.845588Z","shell.execute_reply":"2025-07-19T22:02:22.356371Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"num_epochs = 20\ndis_loss = []\ngen_loss = []\n\nfor epoch in tqdm(range(num_epochs)):\n\n    dnet.train()\n    gnet.train()\n\n    sampler = RandomSampler(train_dataloader.dataset, replacement=False)\n    shuffled_loader = iter(DataLoader(train_dataloader.dataset, batch_size=16, \n                                      sampler=sampler, drop_last=True))\n\n    for i, data in enumerate(shuffled_loader):\n\n        # one_labels = torch.ones(16,1).to(device)\n        # zero_labels = torch.zeros(16,1).to(device)\n        one_labels = torch.FloatTensor(16, 1).uniform_(0.95, 1.0).to(device)\n        zero_labels = torch.FloatTensor(16, 1).uniform_(0.0, 0.05).to(device) \n        \n        # Train Discriminator\n        d_real_pred = dnet(data.to(device))\n        output = d_real_pred.view(-1)\n        D_x = output.mean().item()\n        \n        d_noise_pred = dnet(gnet(torch.randn(16,100,1,1).to(device)) )\n        output = d_noise_pred.view(-1)\n        D_G_z1 = output.mean().item()\n\n        d_real_loss = loss_func(d_real_pred, one_labels)\n        d_noise_loss = loss_func(d_noise_pred, zero_labels)\n        d_loss = d_real_loss + d_noise_loss\n\n        d_optimizer.zero_grad()\n        d_loss.backward()\n        d_optimizer.step()\n\n        # Train generator\n        g_pred_image = gnet(torch.randn(16,100,1,1).to(device))\n        g_label = dnet(g_pred_image)\n        output = g_label.view(-1)\n        D_G_z2 = output.mean().item()\n\n        g_loss = loss_func(g_label, one_labels)\n\n        g_optimizer.zero_grad()\n        g_loss.backward()\n        g_optimizer.step()\n\n        dis_loss.append(d_loss.item())\n        gen_loss.append(g_loss.item())\n\n\n        # Output training stats\n        if i % 30 == 0:\n            print('[%d/%d][%d/%d]\\tLoss_D: %.4f\\tLoss_G: %.4f\\tD(x): %.4f\\tD(G(z)): %.4f / %.4f'\n                  % (epoch, num_epochs, i, len(train_dataloader),\n                     d_loss.item(), g_loss.item(), D_x, D_G_z1, D_G_z2))\n\n# overfitting - same data fed in each epoch, fix it","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-19T22:02:22.358342Z","iopub.execute_input":"2025-07-19T22:02:22.358648Z","iopub.status.idle":"2025-07-19T22:11:40.320777Z","shell.execute_reply.started":"2025-07-19T22:02:22.358631Z","shell.execute_reply":"2025-07-19T22:11:40.320229Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.plot(dis_loss, label = \"Discriminator loss\")\nplt.plot(gen_loss, label = \"Generator loss\")\nplt.legend()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-19T22:11:44.411713Z","iopub.execute_input":"2025-07-19T22:11:44.412435Z","iopub.status.idle":"2025-07-19T22:11:44.583711Z","shell.execute_reply.started":"2025-07-19T22:11:44.412408Z","shell.execute_reply":"2025-07-19T22:11:44.583059Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"dnet.eval()\ngnet.eval()\n\ng_img = gnet(torch.randn(16,100,1,1).to(device)).cpu()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-19T22:11:47.754742Z","iopub.execute_input":"2025-07-19T22:11:47.755499Z","iopub.status.idle":"2025-07-19T22:11:47.812392Z","shell.execute_reply.started":"2025-07-19T22:11:47.755465Z","shell.execute_reply":"2025-07-19T22:11:47.811680Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"g_image = g_img[0].detach().cpu()  # [3, 256, 256]\n\n# Convert from [-1, 1] to [0, 1] range (tanh output fix)\ng_image = (g_image + 1) / 2.0\n\n# Convert to [H, W, C] for matplotlib\ng_image = T.ToPILImage()(g_image)\nplt.imshow(g_image)\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-19T22:11:48.503783Z","iopub.execute_input":"2025-07-19T22:11:48.504616Z","iopub.status.idle":"2025-07-19T22:11:48.745893Z","shell.execute_reply.started":"2025-07-19T22:11:48.504588Z","shell.execute_reply":"2025-07-19T22:11:48.744978Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}