{"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":3004,"databundleVersionId":861823,"sourceType":"competition"}],"dockerImageVersionId":30673,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport os\n\nimport matplotlib.pyplot as plt","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-03-26T05:06:25.892591Z","iopub.execute_input":"2024-03-26T05:06:25.893194Z","iopub.status.idle":"2024-03-26T05:06:26.884936Z","shell.execute_reply.started":"2024-03-26T05:06:25.893168Z","shell.execute_reply":"2024-03-26T05:06:26.884064Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df = pd.read_csv(\"/kaggle/input/digit-recognizer/train.csv\")\ntrain_df.shape","metadata":{"execution":{"iopub.status.busy":"2024-03-26T05:06:26.886597Z","iopub.execute_input":"2024-03-26T05:06:26.886993Z","iopub.status.idle":"2024-03-26T05:06:30.130758Z","shell.execute_reply.started":"2024-03-26T05:06:26.886969Z","shell.execute_reply":"2024-03-26T05:06:30.129908Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels = train_df['label'].values\nfeats = train_df.drop(columns=['label']).values.reshape(-1,1,28,28)\nfeats = feats / 255.0 # normalize this bitch","metadata":{"execution":{"iopub.status.busy":"2024-03-26T05:06:30.131964Z","iopub.execute_input":"2024-03-26T05:06:30.132266Z","iopub.status.idle":"2024-03-26T05:06:30.318757Z","shell.execute_reply.started":"2024-03-26T05:06:30.132238Z","shell.execute_reply":"2024-03-26T05:06:30.317709Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.imshow(feats[1].squeeze())\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-03-26T05:06:30.321354Z","iopub.execute_input":"2024-03-26T05:06:30.322122Z","iopub.status.idle":"2024-03-26T05:06:30.574947Z","shell.execute_reply.started":"2024-03-26T05:06:30.322087Z","shell.execute_reply":"2024-03-26T05:06:30.574079Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(feats) / 60","metadata":{"execution":{"iopub.status.busy":"2024-03-26T05:06:30.576113Z","iopub.execute_input":"2024-03-26T05:06:30.576447Z","iopub.status.idle":"2024-03-26T05:06:30.582639Z","shell.execute_reply.started":"2024-03-26T05:06:30.576414Z","shell.execute_reply":"2024-03-26T05:06:30.581818Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Dataset\n\nWe'll load the data into a pytorch dataset for easier data loading and batching for training","metadata":{}},{"cell_type":"code","source":"from torch.utils.data import Dataset, DataLoader","metadata":{"execution":{"iopub.status.busy":"2024-03-26T05:06:30.583751Z","iopub.execute_input":"2024-03-26T05:06:30.584009Z","iopub.status.idle":"2024-03-26T05:06:34.614813Z","shell.execute_reply.started":"2024-03-26T05:06:30.583987Z","shell.execute_reply":"2024-03-26T05:06:34.614019Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class MNISTDataset(Dataset):\n    def __init__(self, feats):\n        self.feats = feats\n    \n    def __len__(self):\n        return len(self.feats)\n    \n    def __getitem__(self, idx):\n        return torch.from_numpy(self.feats[idx]).float()","metadata":{"execution":{"iopub.status.busy":"2024-03-26T05:06:34.615990Z","iopub.execute_input":"2024-03-26T05:06:34.616574Z","iopub.status.idle":"2024-03-26T05:06:34.622271Z","shell.execute_reply.started":"2024-03-26T05:06:34.616525Z","shell.execute_reply":"2024-03-26T05:06:34.621442Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BATCH_SIZE = 60","metadata":{"execution":{"iopub.status.busy":"2024-03-26T05:06:34.623312Z","iopub.execute_input":"2024-03-26T05:06:34.623589Z","iopub.status.idle":"2024-03-26T05:06:34.631461Z","shell.execute_reply.started":"2024-03-26T05:06:34.623561Z","shell.execute_reply":"2024-03-26T05:06:34.630748Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"mnist_dataset = MNISTDataset(feats)\nmnist_dataloader = DataLoader(mnist_dataset, shuffle=True, batch_size=BATCH_SIZE)","metadata":{"execution":{"iopub.status.busy":"2024-03-26T05:06:34.632714Z","iopub.execute_input":"2024-03-26T05:06:34.633462Z","iopub.status.idle":"2024-03-26T05:06:34.641699Z","shell.execute_reply.started":"2024-03-26T05:06:34.633437Z","shell.execute_reply":"2024-03-26T05:06:34.640873Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# len(mnist_dataloader.)\nmnist_dataloader.batch_size","metadata":{"execution":{"iopub.status.busy":"2024-03-26T05:06:34.643966Z","iopub.execute_input":"2024-03-26T05:06:34.644219Z","iopub.status.idle":"2024-03-26T05:06:34.652238Z","shell.execute_reply.started":"2024-03-26T05:06:34.644197Z","shell.execute_reply":"2024-03-26T05:06:34.651448Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## GAN\n\nWe have a ranom latent vector which we want to use to generate new images of the MNIST dataset.. How tf do we do it? \n\nBased on the GAN theory, there's two networks Generator and Discriminator..\n\nGenerator tries to fool the discriminator by generating images and discriminator looks at the image and gives out a probablity of an image being fake or real..\n\n\nThus lets start with the networks itself first.. ","metadata":{}},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.optim as optim","metadata":{"execution":{"iopub.status.busy":"2024-03-26T05:06:34.653240Z","iopub.execute_input":"2024-03-26T05:06:34.653589Z","iopub.status.idle":"2024-03-26T05:06:34.659509Z","shell.execute_reply.started":"2024-03-26T05:06:34.653559Z","shell.execute_reply":"2024-03-26T05:06:34.658663Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Generator\n\n\nThe generator will take in a latent vector of size K and generate an output of shape 784 since we are dealing with 28x28 size images. Since we are normalizing the image all of our pixel values will be between 0 and 1 thus we can use a tanh or sigmoid activation function for the last layer..\n\n\n\n**Confusion 1**\n\nWhat should our input shape be, In a dcgan paper they start with a 100x1x1 latent vector and generates a 3*64*64 size image.. However we are dealing with a single channel image and we want to produce a 1x64x64 image.. so lets try 100 random numbers from a uniform distribution and that we expant to 784..","metadata":{}},{"cell_type":"code","source":"IN_FEATS_G = 100\nIN_FEATS_D = 784","metadata":{"execution":{"iopub.status.busy":"2024-03-25T19:05:07.166377Z","iopub.execute_input":"2024-03-25T19:05:07.166772Z","iopub.status.idle":"2024-03-25T19:05:07.173538Z","shell.execute_reply.started":"2024-03-25T19:05:07.166743Z","shell.execute_reply":"2024-03-25T19:05:07.172031Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Generator(nn.Module):\n    def __init__(self, in_feats):\n        super(Generator, self).__init__()\n        self.main = nn.Sequential(\n            \n            nn.Flatten(),\n            \n            nn.Linear(in_feats, 256),\n            nn.ReLU(True),\n            \n            nn.Linear(256, 512),\n            nn.ReLU(True),\n            \n            nn.Linear(512, 784),\n            nn.Sigmoid()\n        )\n        \n    def forward(self, x):\n        return self.main(x)","metadata":{"execution":{"iopub.status.busy":"2024-03-25T19:06:07.714458Z","iopub.execute_input":"2024-03-25T19:06:07.714843Z","iopub.status.idle":"2024-03-25T19:06:07.722594Z","shell.execute_reply.started":"2024-03-25T19:06:07.714814Z","shell.execute_reply":"2024-03-25T19:06:07.721631Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"gen = Generator(in_feats = IN_FEATS_G)\nprint(gen)","metadata":{"execution":{"iopub.status.busy":"2024-03-25T19:06:07.912967Z","iopub.execute_input":"2024-03-25T19:06:07.913371Z","iopub.status.idle":"2024-03-25T19:06:07.925458Z","shell.execute_reply.started":"2024-03-25T19:06:07.913341Z","shell.execute_reply":"2024-03-25T19:06:07.924430Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with torch.no_grad():\n    t = torch.randn((BATCH_SIZE,IN_FEATS_G, 1, 1))\n    o = gen(t)\n    o = o.reshape(-1,1,28,28)\n    print(o.shape)\n    \n    # plot image\n    \n    o1 = o[0].squeeze().detach().numpy()\n    plt.imshow(o1)\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2024-03-25T19:06:08.115729Z","iopub.execute_input":"2024-03-25T19:06:08.116171Z","iopub.status.idle":"2024-03-25T19:06:08.382722Z","shell.execute_reply.started":"2024-03-25T19:06:08.116136Z","shell.execute_reply":"2024-03-25T19:06:08.381457Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Cool, so our generator code is generating 784 values now!","metadata":{}},{"cell_type":"markdown","source":"## Discriminator\n\n\nThe job of the discriminator is to maximize the likelihood of classifying fake images as fake. Given it an image it should do a binary classification of image being real of fake, preety simple! \n\nThe discriminator will take an input of shape 784 and give us 1 output probablity ","metadata":{}},{"cell_type":"code","source":"class Discriminator(nn.Module):\n    def __init__(self, in_feats):\n        super(Discriminator, self).__init__()\n        self.main = nn.Sequential(\n            nn.Flatten(),\n            \n            nn.Linear(in_feats, 512),\n            nn.ReLU(True),\n            \n            nn.Linear(512, 256),\n            nn.ReLU(True),\n            \n            nn.Linear(256, 128),\n            nn.ReLU(True),\n            \n            nn.Linear(128, 1),\n            nn.Sigmoid(),\n        )\n        \n        \n    def forward(self, x):\n        return self.main(x)","metadata":{"execution":{"iopub.status.busy":"2024-03-25T19:06:16.532538Z","iopub.execute_input":"2024-03-25T19:06:16.533266Z","iopub.status.idle":"2024-03-25T19:06:16.541924Z","shell.execute_reply.started":"2024-03-25T19:06:16.533227Z","shell.execute_reply":"2024-03-25T19:06:16.540465Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"disc = Discriminator(in_feats = IN_FEATS_D)\nprint(disc)","metadata":{"execution":{"iopub.status.busy":"2024-03-25T19:06:17.160297Z","iopub.execute_input":"2024-03-25T19:06:17.161503Z","iopub.status.idle":"2024-03-25T19:06:17.176100Z","shell.execute_reply.started":"2024-03-25T19:06:17.161464Z","shell.execute_reply":"2024-03-25T19:06:17.174564Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Training\n\n\nSo how do we train this network.. Lets break it down into smaller steps..\n\n\n```\nfor epoch in epochs\n    for sample in feature_samples:\n        \n        For discriminator\n        \n        1. do classification on real images\n        2. calculate discriminator loss and backpropagate\n        \n        For Generator\n        \n        4. sample a random normal distribution \n        5. generate a sample\n        6. Make the discriminator learn that these images are fucking fake ass and backpropagate\n      \n        # Generator\n        \n        7. Now that the discriminator didnt get fool\n        8. We compute the loss over fake images as being real for the generator\n        9. backward pass for the generator\n        \n```\n","metadata":{}},{"cell_type":"code","source":"criterion = nn.BCELoss()\noptimizerD = optim.Adam(disc.parameters(), lr=0.0002)\noptimizerG = optim.Adam(gen.parameters(),  lr=0.0002)","metadata":{"execution":{"iopub.status.busy":"2024-03-25T19:06:31.705480Z","iopub.execute_input":"2024-03-25T19:06:31.705964Z","iopub.status.idle":"2024-03-25T19:06:31.714397Z","shell.execute_reply.started":"2024-03-25T19:06:31.705919Z","shell.execute_reply":"2024-03-25T19:06:31.712971Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"num_epochs = 100\n\nloss_g = []\nloss_d = []\n\nbreak_out = False\nfixed_vec = torch.randn((1,100,1,1))","metadata":{"execution":{"iopub.status.busy":"2024-03-25T19:06:34.835401Z","iopub.execute_input":"2024-03-25T19:06:34.835811Z","iopub.status.idle":"2024-03-25T19:06:34.842835Z","shell.execute_reply.started":"2024-03-25T19:06:34.835774Z","shell.execute_reply":"2024-03-25T19:06:34.841454Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for epoch in range(num_epochs):\n    print(f'Training Epoch: {epoch}')\n    for idx, data in enumerate(mnist_dataloader):\n        try:\n            # clear discriminator gradients\n            optimizerD.zero_grad()\n\n\n            feats = data\n            disc_labels = torch.ones((BATCH_SIZE,1 )).float() # generate real labels\n\n            # Part - 1. Train discriminator to classifiy fake vs real image\n\n            output = disc(feats)\n\n            error_d = criterion(output, disc_labels)\n\n            error_d.backward()        \n\n            # Part - 1.1 - Make the discriminator learn about fake images\n\n            fake_batch = torch.randn((BATCH_SIZE, IN_FEATS_G,1, 1)).float()\n            fake_labels = torch.zeros((BATCH_SIZE, )).float()\n\n            fake = gen(fake_batch)\n            output = disc(fake.detach()).view(-1)\n\n            loss_d_f = criterion(output, fake_labels)\n            loss_d_f.backward()\n\n            optimizerD.step()\n\n\n            # part 2 - generator step\n\n            optimizerG.zero_grad()\n\n            # part 2.1 for the generator we want it to penalize for generating bad images\n\n            generator_label =  torch.ones((BATCH_SIZE, 1)).float() # generate real labels\n\n\n            output = disc(fake)\n\n            error_g = criterion(output, generator_label)\n            error_g.backward()\n            optimizerG.step()\n\n\n            if idx%50 == 0:\n                print(f\"[{epoch+1}/{num_epochs}][{idx+1}/{len(mnist_dataloader)}] Loss_D_Real: {error_d.item()} Loss_D_Fake: {loss_d_f.item()} Loss_G: {error_g.item()}\")\n\n            if (idx % 500 == 0):\n                with torch.no_grad():\n                    fake = gen(fixed_vec).detach().cpu()\n                    fake = fake.reshape(-1,1,28,28)\n                    print(o.shape)\n\n                    # plot image\n\n                    fake1 = fake[0].squeeze().detach().numpy()\n                    plt.imshow(fake1)\n                    plt.show()\n        except:\n            print(\"EXCEPTION: \",output.shape, disc_labels.shape, feats.shape)\n            break_out = True\n            break\n    \n    if break_out:\n        break","metadata":{"execution":{"iopub.status.busy":"2024-03-25T19:06:38.627885Z","iopub.execute_input":"2024-03-25T19:06:38.628267Z","iopub.status.idle":"2024-03-25T19:16:30.976783Z","shell.execute_reply.started":"2024-03-25T19:06:38.628238Z","shell.execute_reply":"2024-03-25T19:16:30.975588Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with torch.no_grad():\n    rs = torch.randn((64,100,1,1))\n    rg = gen(rs).detach().numpy()\n    \n    fig = plt.figure(figsize=(15,15))\n    \n    for i in range(1len(rs)):\n        d = rg[i].reshape(28,28)\n        plt.subplot(4,8,i+1)\n        plt.imshow(d)\n    print(rg.shape)\n    ","metadata":{"execution":{"iopub.status.busy":"2024-03-25T19:21:10.051872Z","iopub.execute_input":"2024-03-25T19:21:10.052292Z","iopub.status.idle":"2024-03-25T19:21:14.673040Z","shell.execute_reply.started":"2024-03-25T19:21:10.052261Z","shell.execute_reply":"2024-03-25T19:21:14.670706Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## DCGAN - Deep Convolution GAN\n\n\nDCGAN's are GANS's with Deep Convolution Layers.. ","metadata":{}},{"cell_type":"code","source":"device = \"cuda\" if torch.cuda.is_available() else \"cpu\"","metadata":{"execution":{"iopub.status.busy":"2024-03-26T05:36:22.157337Z","iopub.execute_input":"2024-03-26T05:36:22.158091Z","iopub.status.idle":"2024-03-26T05:36:22.162687Z","shell.execute_reply.started":"2024-03-26T05:36:22.158054Z","shell.execute_reply":"2024-03-26T05:36:22.161598Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"random_z = torch.randn((1,100,2,2))\nuc = nn.ConvTranspose2d(100,1024,4,2,1,bias=False)\nuc(random_z).detach().shape\n\n# 1x1 -> \n# 2x2 -> 5,2,0\n# 7x7x1 -> 4,2,1\n# 14x14x1 -> 4,2,1","metadata":{"execution":{"iopub.status.busy":"2024-03-26T05:36:22.323003Z","iopub.execute_input":"2024-03-26T05:36:22.323366Z","iopub.status.idle":"2024-03-26T05:36:22.346533Z","shell.execute_reply.started":"2024-03-26T05:36:22.323337Z","shell.execute_reply":"2024-03-26T05:36:22.345617Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# custom weights initialization called on ``netG`` and ``netD``\ndef weights_init(m):\n    classname = m.__class__.__name__\n    if isinstance(m, nn.Conv2d):\n        nn.init.normal_(m.weight.data, 0.0, 0.02)\n    elif isinstance(m, nn.BatchNorm2d):\n        nn.init.normal_(m.weight.data, 1.0, 0.02)\n        nn.init.constant_(m.bias.data, 0)","metadata":{"execution":{"iopub.status.busy":"2024-03-26T05:36:22.435061Z","iopub.execute_input":"2024-03-26T05:36:22.435773Z","iopub.status.idle":"2024-03-26T05:36:22.441428Z","shell.execute_reply.started":"2024-03-26T05:36:22.435743Z","shell.execute_reply":"2024-03-26T05:36:22.440423Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class ConvGenerator(nn.Module):\n    def __init__(self, in_channels):\n        super(ConvGenerator, self).__init__()\n        self.main = nn.Sequential(\n            nn.ConvTranspose2d(in_channels, 1024, 2, 2,0, bias=False),\n            nn.BatchNorm2d(1024),\n            nn.ReLU(True), # [batch_size, 1024, 2, 2]\n\n            nn.ConvTranspose2d(1024, 512, 5, 2,0, bias=False),\n            nn.BatchNorm2d(512),\n            nn.ReLU(True), # [batch_size, 512, 7, 7]\n\n            nn.ConvTranspose2d(512, 256, 4, 2,1, bias=False),\n            nn.BatchNorm2d(256),\n            nn.ReLU(True), # [batch_size, 256, 14, 14]\n\n            nn.ConvTranspose2d(256,1, 4, 2,1, bias=False),\n            nn.Sigmoid(), # [batch_size, 1, 28, 28, 32]\n        )\n\n    def forward(self, x):\n        return self.main(x)","metadata":{"execution":{"iopub.status.busy":"2024-03-26T05:47:36.413322Z","iopub.execute_input":"2024-03-26T05:47:36.413792Z","iopub.status.idle":"2024-03-26T05:47:36.421605Z","shell.execute_reply.started":"2024-03-26T05:47:36.413749Z","shell.execute_reply":"2024-03-26T05:47:36.420614Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dcgen = ConvGenerator(in_channels=100).to(device)\ndcgen.apply(weights_init)\n\n\nwith torch.no_grad():\n    random_z = torch.randn((1,100,1,1)).to(device)\n    g = dcgen(random_z).detach().cpu().squeeze().numpy()\n    plt.imshow(g)","metadata":{"execution":{"iopub.status.busy":"2024-03-26T05:47:36.571349Z","iopub.execute_input":"2024-03-26T05:47:36.571658Z","iopub.status.idle":"2024-03-26T05:47:36.966209Z","shell.execute_reply.started":"2024-03-26T05:47:36.571634Z","shell.execute_reply":"2024-03-26T05:47:36.965230Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Discriminator**","metadata":{}},{"cell_type":"code","source":"random_z = torch.randn((1,1,3,3))\nc = nn.Conv2d(1,126, 4, 2, 1)\nc(random_z).shape","metadata":{"execution":{"iopub.status.busy":"2024-03-26T05:47:36.967676Z","iopub.execute_input":"2024-03-26T05:47:36.967957Z","iopub.status.idle":"2024-03-26T05:47:36.975795Z","shell.execute_reply.started":"2024-03-26T05:47:36.967932Z","shell.execute_reply":"2024-03-26T05:47:36.974763Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class ConvDiscriminator(nn.Module):\n    def __init__(self, in_channel=1):\n        super(ConvDiscriminator, self).__init__()\n        self.main = nn.Sequential(\n            nn.Conv2d(in_channel, 64, 4, 2, 1, bias=False),\n            nn.BatchNorm2d(64),\n            nn.LeakyReLU(0.2, inplace=True), # [batch_size, 64, 14, 14]\n            \n            nn.Conv2d(64, 128, 4, 2, 1, bias=False),\n            nn.BatchNorm2d(128),\n            nn.LeakyReLU(0.2, inplace=True), # [batch_size, 128, 7, 7]\n            \n            nn.Conv2d(128, 256, 4, 2, 1, bias=False),\n            nn.BatchNorm2d(256),\n            nn.LeakyReLU(0.2, inplace=True), # [batch_size, 128, 3, 3]\n            \n            nn.Conv2d(256, 1, 4, 2, 1, bias=False),   \n            nn.Flatten(),\n            nn.Sigmoid() # [batch_size, 1, 1, 1]\n        )\n    \n    def forward(self, x):\n        return self.main(x)","metadata":{"execution":{"iopub.status.busy":"2024-03-26T05:47:37.042962Z","iopub.execute_input":"2024-03-26T05:47:37.043212Z","iopub.status.idle":"2024-03-26T05:47:37.050945Z","shell.execute_reply.started":"2024-03-26T05:47:37.043191Z","shell.execute_reply":"2024-03-26T05:47:37.050001Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dcdisc = ConvDiscriminator(in_channel=1).to(device)\ndcdisc.apply(weights_init)\n\nwith torch.no_grad():\n    random_z = torch.randn((2,1,28,28)).to(device)\n    d = dcdisc(random_z).detach().cpu().numpy()\n    print(d.shape)","metadata":{"execution":{"iopub.status.busy":"2024-03-26T05:47:37.181501Z","iopub.execute_input":"2024-03-26T05:47:37.182199Z","iopub.status.idle":"2024-03-26T05:47:37.198901Z","shell.execute_reply.started":"2024-03-26T05:47:37.182174Z","shell.execute_reply":"2024-03-26T05:47:37.197934Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Training**","metadata":{}},{"cell_type":"code","source":"criterion = nn.BCELoss()\n\noptimizerG = optim.Adam(dcgen.parameters(), lr=0.0002)\noptimizerD = optim.Adam(dcdisc.parameters(), lr=0.0002)\n\nfixed_latent = torch.randn((16, 100,1,1)).to(device)\nnum_epochs = 100\n\n\nloss_g_history = []\nloss_d_history = []","metadata":{"execution":{"iopub.status.busy":"2024-03-26T05:47:37.632343Z","iopub.execute_input":"2024-03-26T05:47:37.632961Z","iopub.status.idle":"2024-03-26T05:47:37.640361Z","shell.execute_reply.started":"2024-03-26T05:47:37.632916Z","shell.execute_reply":"2024-03-26T05:47:37.639558Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BATCH_SIZE","metadata":{"execution":{"iopub.status.busy":"2024-03-26T05:47:37.861069Z","iopub.execute_input":"2024-03-26T05:47:37.861350Z","iopub.status.idle":"2024-03-26T05:47:37.866890Z","shell.execute_reply.started":"2024-03-26T05:47:37.861326Z","shell.execute_reply":"2024-03-26T05:47:37.865926Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(f\"Starting Training...\")\n\nfor epoch in range(num_epochs):\n\n    running_loss_g = 0\n    running_loss_d = 0\n    \n    for idx, data in enumerate(mnist_dataloader):\n        \n        optimizerD.zero_grad()\n        feat = data.to(device)\n        label = torch.ones((BATCH_SIZE,1)).float().to(device)\n        \n        # discriminator - real\n        \n        output = dcdisc(feat)\n        loss_d = criterion(output, label)\n        \n        loss_d.backward()\n        \n        \n        # discriminator - fake\n        \n        fake_feats = torch.randn((BATCH_SIZE, 100, 1, 1)).to(device)\n        fake_labels = torch.zeros((BATCH_SIZE, 1)).float().to(device)\n        \n        gen_op = dcgen(fake_feats)\n        disc_gen_op = dcdisc(gen_op.detach())\n        loss_dgen = criterion(disc_gen_op, fake_labels)\n        \n        # train\n        loss_dgen.backward()\n        \n        optimizerD.step()\n        \n        # combined_loss = \n        \n        combined_loss = loss_dgen + loss_d\n        \n        # generator\n        \n        optimizerG.zero_grad()\n        \n        gen_real_labels = torch.ones((BATCH_SIZE, 1)).to(device)\n        gen_disc_op = dcdisc(gen_op)\n        gen_loss = criterion(gen_disc_op, gen_real_labels)\n        \n        gen_loss.backward()\n        optimizerG.step()\n        \n        # logging\n        \n        running_loss_g += gen_loss.item()\n        running_loss_d += combined_loss.item()\n        \n        \n        if idx%100 == 0:\n            # log         \n            print(f\"[{epoch}/{num_epochs}] [{idx}/{len(mnist_dataloader)}] Loss_G = {gen_loss.item()}, Loss_D_Real = {loss_d.item()}, Loss_D_Fake = {loss_dgen.item()}\")\n        \n      \n    running_loss_g /= len(mnist_dataloader)\n    running_loss_d /= len(mnist_dataloader)\n    \n    loss_g_history.append(running_loss_g)\n    loss_d_history.append(running_loss_d)\n    \n    with torch.no_grad():\n        gen_p = dcgen(fixed_latent).detach().cpu().numpy()\n        fig = plt.figure(figsize=(20, 4))\n        for i in range(0,len(gen_p)):\n            plt.subplot(2, 8, i+1)\n            plt.imshow(gen_p[i].squeeze())\n        plt.show()\n","metadata":{"execution":{"iopub.status.busy":"2024-03-26T05:47:38.397495Z","iopub.execute_input":"2024-03-26T05:47:38.397879Z","iopub.status.idle":"2024-03-26T06:09:07.433984Z","shell.execute_reply.started":"2024-03-26T05:47:38.397850Z","shell.execute_reply":"2024-03-26T06:09:07.432749Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}