{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Import libraries","metadata":{"id":"3OHqrodZQROP"}},{"cell_type":"code","source":"import time\n\nimport pandas as pd\nimport platform\nimport io\n\nimport matplotlib.pyplot as plt\nfrom matplotlib.pyplot import cm \n\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\n\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nfrom torchvision.datasets import CIFAR10\nimport torchvision.transforms as transforms\nimport torchvision\n\nimport matplotlib.pyplot as plt\nimport numpy as np","metadata":{"id":"MyL9SFPWI9gm","execution":{"iopub.status.busy":"2022-05-25T15:40:56.347078Z","iopub.execute_input":"2022-05-25T15:40:56.347487Z","iopub.status.idle":"2022-05-25T15:40:58.556289Z","shell.execute_reply.started":"2022-05-25T15:40:56.347376Z","shell.execute_reply":"2022-05-25T15:40:58.555472Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Constants\nIMAGE_WIDTH = 32\nIMAGE_HEIGHT = 32\nCOLOR_CHANNELS = 3\nN_CLASSES = 10","metadata":{"id":"033jm0hmXEdU","execution":{"iopub.status.busy":"2022-05-25T15:40:58.558180Z","iopub.execute_input":"2022-05-25T15:40:58.558684Z","iopub.status.idle":"2022-05-25T15:40:58.562715Z","shell.execute_reply.started":"2022-05-25T15:40:58.558646Z","shell.execute_reply":"2022-05-25T15:40:58.562091Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device(\"cuda:0\" if (torch.cuda.is_available()) else \"cpu\")","metadata":{"id":"z8yWxOLEw3PE","outputId":"251b8fa7-f09f-4f35-eb83-270ea5699bd6","execution":{"iopub.status.busy":"2022-05-25T15:40:58.565428Z","iopub.execute_input":"2022-05-25T15:40:58.567040Z","iopub.status.idle":"2022-05-25T15:40:58.635089Z","shell.execute_reply.started":"2022-05-25T15:40:58.566976Z","shell.execute_reply":"2022-05-25T15:40:58.634287Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Root directory for dataset\ndataroot = '/content'\n\n# Number of workers for dataloader\nworkers = 2\n\n# Batch size during training\nbatch_size = 25\n\n# Spatial size of training images. All images will be resized to this\n#   size using a transformer.\nimage_size = 28\n\n# Number of channels in the training images. For color images this is 3\nnc = 3\n\n# Size of z latent vector (i.e. size of generator input)\nnz = 100\n\n# Size of feature maps in generator\nngf = 64\n\n# Size of feature maps in discriminator\nndf = 64\n\n# Number of training epochs\nnum_epochs = 5\n\n# Learning rate for optimizers\nlr = 0.002\n\n# Beta1 hyperparam for Adam optimizers\nbeta1 = 0.5\n\n# Decide which device we want to run on\ndevice = torch.device(\"cuda:0\" if (torch.cuda.is_available()) else \"cpu\")\n\n# Number of channels in the training images. For color images this is 3\nnc = 3\n\nnum_classes = 10","metadata":{"execution":{"iopub.status.busy":"2022-05-25T15:40:58.638562Z","iopub.execute_input":"2022-05-25T15:40:58.638842Z","iopub.status.idle":"2022-05-25T15:40:58.647523Z","shell.execute_reply.started":"2022-05-25T15:40:58.638801Z","shell.execute_reply":"2022-05-25T15:40:58.646847Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Load raw CIFAR-10 Dataset and Labels","metadata":{"id":"emPfVTRtQLR1"}},{"cell_type":"code","source":"SIZE_H = SIZE_W = 28\n\ntransform = transforms.Compose([\n    transforms.Resize((SIZE_H, SIZE_W)),\n    transforms.ToTensor(),\n    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))\n])\n\n\n# image_mean = [0.485, 0.456, 0.406]\n# image_std  = [0.229, 0.224, 0.225]\n\n# transformer = transforms.Compose([\n#     transforms.Resize((SIZE_H, SIZE_W)),        # scaling images to fixed size\n#     transforms.ToTensor(),                      # converting to tensors\n#     transforms.Normalize(image_mean, image_std) # normalize image data per-channel\n# ])","metadata":{"id":"tGO_AC1ZBFa5","execution":{"iopub.status.busy":"2022-05-25T15:40:58.648939Z","iopub.execute_input":"2022-05-25T15:40:58.649228Z","iopub.status.idle":"2022-05-25T15:40:58.657956Z","shell.execute_reply.started":"2022-05-25T15:40:58.649172Z","shell.execute_reply":"2022-05-25T15:40:58.657218Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset = CIFAR10(root='.',\n                        train=True,\n                        transform=transform,\n                        download=True)\n\ntest_dataset  = CIFAR10(root='.',\n                        train=False,\n                        transform=transform,)\n\nlen(train_dataset), len(test_dataset)","metadata":{"id":"DVMG2SCcJIfd","outputId":"69f32745-55ed-42f1-bc79-613569ed333b","execution":{"iopub.status.busy":"2022-05-25T15:40:58.659212Z","iopub.execute_input":"2022-05-25T15:40:58.659551Z","iopub.status.idle":"2022-05-25T15:41:06.277776Z","shell.execute_reply.started":"2022-05-25T15:40:58.659504Z","shell.execute_reply":"2022-05-25T15:41:06.276994Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import torchvision.transforms as T\n\n# # noise = torch.randn(batch_size, nz, 1, 1, device=device)\n# # fake = netG(noise)\n# # print (fake.shape)\n\n# fig, axs = plt.subplots(2, 3, figsize=(20,12))\n\n# for k in range(10):\n#     tensor_img = train_dataset[k][0]\n#     tensor_img = tensor_img/2 + 0.5 # unnormalize\n#     img = T.ToPILImage()(tensor_img)\n# #     img = img / 2. + 0.5 \n#     axs[1, k%3].imshow(img)\n\n# plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-05-25T15:41:06.279148Z","iopub.execute_input":"2022-05-25T15:41:06.279554Z","iopub.status.idle":"2022-05-25T15:41:06.284175Z","shell.execute_reply.started":"2022-05-25T15:41:06.279516Z","shell.execute_reply":"2022-05-25T15:41:06.283211Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Create DataLoader","metadata":{"id":"-4gkeIyrTQI-"}},{"cell_type":"code","source":"batch_size = 25         # hyper-parameter \ntrain_loader = torch.utils.data.DataLoader(\n                            dataset = train_dataset, \n                            batch_size = batch_size, \n                            shuffle = True)\n\ntest_loader = torch.utils.data.DataLoader(\n                            dataset = test_dataset, \n                            batch_size = batch_size, \n                            shuffle = True)","metadata":{"id":"4AHWYrRdSDqL","execution":{"iopub.status.busy":"2022-05-25T15:41:06.285658Z","iopub.execute_input":"2022-05-25T15:41:06.285953Z","iopub.status.idle":"2022-05-25T15:41:06.329585Z","shell.execute_reply.started":"2022-05-25T15:41:06.285897Z","shell.execute_reply":"2022-05-25T15:41:06.328961Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## weights initialization","metadata":{}},{"cell_type":"code","source":"def weights_init(m):\n    classname = m.__class__.__name__\n    if classname.find('Conv') != -1:\n        nn.init.normal_(m.weight.data, 0.0, 0.02)\n    elif classname.find('BatchNorm') != -1:\n        nn.init.normal_(m.weight.data, 1.0, 0.02)\n        nn.init.constant_(m.bias.data, 0)","metadata":{"execution":{"iopub.status.busy":"2022-05-25T15:41:06.330964Z","iopub.execute_input":"2022-05-25T15:41:06.331280Z","iopub.status.idle":"2022-05-25T15:41:06.339983Z","shell.execute_reply.started":"2022-05-25T15:41:06.331193Z","shell.execute_reply":"2022-05-25T15:41:06.339303Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Generator","metadata":{}},{"cell_type":"code","source":"class Generator(nn.Module):\n    def __init__(self):\n        super().__init__()\n        self.Linear1 = nn.Linear(nz, 128 * 7 * 7)\n        self.leaky_relu = nn.LeakyReLU(0.2)\n\n        self.convT1 = nn.ConvTranspose2d(in_channels=128, out_channels=128, kernel_size=4,\n                                     stride=2, padding=1, bias=False)\n        self.batchnorm1 = nn.BatchNorm2d(128)\n        self.leaky_relu1 = nn.LeakyReLU(0.2)\n###########################################\n        self.convT2 = nn.ConvTranspose2d(in_channels=128, out_channels=128, kernel_size=4,\n                                     stride=2, padding=1, bias=False)\n        self.batchnorm2 = nn.BatchNorm2d(128)\n        self.leaky_relu2 = nn.LeakyReLU(0.2)\n###########################################\n        self.convT3 = nn.ConvTranspose2d(in_channels=128, out_channels=nc, kernel_size=1,\n                                     stride=1, padding=0, bias=False)\n\n    def forward(self, input):\n        out = self.Linear1(input.squeeze())\n        out = self.leaky_relu(out)\n        out = out.reshape(-1,128,7,7)\n\n        out = self.convT1(out)\n        out = self.batchnorm1(out)\n        out = self.leaky_relu1(out)\n\n        out = self.convT2(out)\n        out = self.batchnorm2(out)\n        out = self.leaky_relu2(out)\n\n        out = self.convT3(out)\n\n        return torch.tanh(out)\n\n# Create the generator\nnetG = Generator().to(device)\n\n# Apply the weights_init function to randomly initialize all weights\n#  to mean=0, stdev=0.2.\nnetG.apply(weights_init)\n\nnoise = torch.randn(batch_size, nz, 1, 1, device=device)\nfake = netG(noise)\nprint(fake.shape)","metadata":{"execution":{"iopub.status.busy":"2022-05-25T15:41:06.343583Z","iopub.execute_input":"2022-05-25T15:41:06.343765Z","iopub.status.idle":"2022-05-25T15:41:15.744681Z","shell.execute_reply.started":"2022-05-25T15:41:06.343743Z","shell.execute_reply":"2022-05-25T15:41:15.743940Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Discriminator","metadata":{}},{"cell_type":"code","source":"class Discriminator(nn.Module):\n    def __init__(self, num_classes):\n        super().__init__()\n        self.num_classes = num_classes\n\n        self.conv1 = nn.Conv2d(in_channels=nc, out_channels=128,\n                           kernel_size=3, stride=2,\n                           padding=1, bias=False)\n        self.batchnorm1 = nn.BatchNorm2d(128)\n        self.leaky_relu1 = nn.LeakyReLU(0.2)\n##########################################\n        self.conv2 = nn.Conv2d(in_channels=128, out_channels=128,\n                           kernel_size=3, stride=2,\n                           padding=1, bias=False)\n        self.batchnorm2 = nn.BatchNorm2d(128)\n        self.leaky_relu2 = nn.LeakyReLU(0.2)\n#########################################\n        self.conv3 = nn.Conv2d(in_channels=128, out_channels=128,\n                           kernel_size=3, stride=2,\n                           padding=1, bias=False)\n        self.batchnorm3 = nn.BatchNorm2d(128)\n        self.leaky_relu3 = nn.LeakyReLU(0.2)\n#########################################\n        self.Linear = nn.Linear(128*4*4, self.num_classes)\n\n\n    def forward(self, input):\n\n        out = self.conv1(input)\n        out = self.batchnorm1(out)\n        out = self.leaky_relu1(out)\n        #############################\n        out = self.conv2(out)\n        out = self.batchnorm2(out)\n        out = self.leaky_relu2(out)\n        #############################\n        out = self.conv3(out)\n        out = self.batchnorm3(out)\n        out = self.leaky_relu3(out)\n        #############################\n        out = out.view(-1,128*4*4)\n        out = self.Linear(out)\n        xe = torch.exp(out)\n        logexpsum = xe.sum(dim = -1)\n        adv = logexpsum / (logexpsum + 1) # real_fake\n        aux = F.softmax(out.squeeze(), dim = 1) # classification\n\n        return adv, aux\n\n# Create the Discriminator\nnum_classes = 10\nnetD = Discriminator(num_classes).to(device)\n    \n# Apply the weights_init function to randomly initialize all weights\n#  to mean=0, stdev=0.2.\nnetD.apply(weights_init)\n\nnoise = torch.randn(batch_size, 3, 28, 28, device=device)\nadv, aux = netD(noise)\nprint(aux.shape)","metadata":{"execution":{"iopub.status.busy":"2022-05-25T15:41:15.746112Z","iopub.execute_input":"2022-05-25T15:41:15.746596Z","iopub.status.idle":"2022-05-25T15:41:15.798654Z","shell.execute_reply.started":"2022-05-25T15:41:15.746558Z","shell.execute_reply":"2022-05-25T15:41:15.797792Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create batch of latent vectors that we will use to visualize\n#  the progression of the generator\nfixed_noise = torch.randn(batch_size, nz, 1, 1, device=device)\n\n# Setup Adam optimizers for both G and D\noptimizerD = optim.Adam(netD.parameters(), lr=lr, betas=(beta1, 0.999))\noptimizerG = optim.Adam(netG.parameters(), lr=lr, betas=(beta1, 0.999))","metadata":{"execution":{"iopub.status.busy":"2022-05-25T15:41:15.800431Z","iopub.execute_input":"2022-05-25T15:41:15.800778Z","iopub.status.idle":"2022-05-25T15:41:15.806320Z","shell.execute_reply.started":"2022-05-25T15:41:15.800743Z","shell.execute_reply":"2022-05-25T15:41:15.805431Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tqdm import tqdm\nfrom numpy.random import randint\n\ndef get_supervised_samples(n_samples=100):\n    n_samples=n_samples\n    n_classes=10\n    n_per_class = int(n_samples / n_classes)\n    d = dict()\n    for i in range(n_classes):\n        d[i] = n_per_class\n\n    for idx, (X, y) in tqdm(enumerate(train_dataset)):\n        if idx == 0:\n            d[y] = d[y] - 1\n            final = X[None, :]\n            final_labels = torch.tensor(y)\n        else:\n            if d[y] > 0:\n                d[y] = d[y] - 1\n                final = torch.cat((final, X[None, :]), axis=0)\n                final_labels = torch.hstack((final_labels, torch.tensor(y)))\n\n    return final, final_labels","metadata":{"execution":{"iopub.status.busy":"2022-05-25T15:41:15.807945Z","iopub.execute_input":"2022-05-25T15:41:15.808233Z","iopub.status.idle":"2022-05-25T15:41:15.819124Z","shell.execute_reply.started":"2022-05-25T15:41:15.808195Z","shell.execute_reply":"2022-05-25T15:41:15.818430Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"final, final_labels = get_supervised_samples(100)","metadata":{"execution":{"iopub.status.busy":"2022-05-25T15:41:15.820445Z","iopub.execute_input":"2022-05-25T15:41:15.820754Z","iopub.status.idle":"2022-05-25T15:41:29.860221Z","shell.execute_reply.started":"2022-05-25T15:41:15.820721Z","shell.execute_reply":"2022-05-25T15:41:29.859453Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_netD(real_data, labels, optimizerD):\n    optimizerD.zero_grad()\n    \n    supervised_batch = batch_size // 2\n    bce_loss = nn.BCELoss()\n    ce_loss = nn.CrossEntropyLoss()\n\n    # update supervised discriminator\n    # idxs = np.random.randint(0, real_data.shape[0], supervised_batch)\n    # supervised_real, supervised_targets = real_data[idxs], labels[idxs]\n    supervised_real, supervised_targets = final.to(device), final_labels.to(device) #get_supervised_samples()\n\n\n    # print(supervised_real.shape, supervised_targets.shape) # torch.Size([12, 1, 28, 28]) torch.Size([12])\n    _, classific_label = netD(supervised_real)\n    classific_real_loss = ce_loss(classific_label, supervised_targets.to(device))\n\n    # update unsupervised discriminator (adv)\n    real_fake, _ = netD(real_data)\n    real_targets = torch.ones(real_data.shape[0], dtype=torch.float32).to(device)\n    real_fake_loss = bce_loss(real_fake, real_targets)\n\n    noise = torch.randn(real_data.shape[0], nz, 1, 1, device=device)\n    fake = netG(noise)\n    fake_real, _ = netD(fake.detach())\n    fake_real_loss = bce_loss(fake_real.view(-1), fake_targets)\n\n    # loss\n    lossD = 0.5 * (real_fake_loss + fake_real_loss) + classific_real_loss\n    lossD.backward()\n    # Update D\n    optimizerD.step()\n\n    # Calculate discriminator accuracy\n\n    pred = np.concatenate([classific_label.data.cpu().numpy(),\n                              ], axis=0)\n    gt = np.concatenate([supervised_targets.data.cpu().numpy(),\n                            ], axis=0)\n    d_acc = np.mean(np.argmax(pred, axis=1) == gt)\n\n#     netD.train(False)\n    with torch.no_grad():\n        idxs = np.random.randint(0, real_data.shape[0], supervised_batch)\n        supervised_real, supervised_targets = real_data[idxs], labels[idxs]\n        _, classific_label = netD(supervised_real)\n\n        pred = np.concatenate([classific_label.data.cpu().numpy(),\n                                ], axis=0)\n        gt = np.concatenate([supervised_targets.data.cpu().numpy(),\n                                ], axis=0)\n        d_acc_test = np.mean(np.argmax(pred, axis=1) == gt)\n#     netD.train(True)\n\n    return lossD.item(), d_acc, d_acc_test","metadata":{"execution":{"iopub.status.busy":"2022-05-25T15:41:29.862902Z","iopub.execute_input":"2022-05-25T15:41:29.863195Z","iopub.status.idle":"2022-05-25T15:41:29.876933Z","shell.execute_reply.started":"2022-05-25T15:41:29.863153Z","shell.execute_reply":"2022-05-25T15:41:29.876108Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_netG(real_targets, optimizerG):\n    optimizerG.zero_grad()\n\n    bce_loss = nn.BCELoss()\n\n    # update generator (g)\n    noise = torch.randn(real_data.shape[0], nz, 1, 1, device=device)\n    fake = netG(noise)\n    adv_g, _ = netD(fake)\n    lossG = bce_loss(adv_g.view(-1), real_targets)\n    lossG.backward()\n\n    # Update G\n    optimizerG.step()\n\n    return lossG.item()","metadata":{"execution":{"iopub.status.busy":"2022-05-25T15:41:29.878232Z","iopub.execute_input":"2022-05-25T15:41:29.878709Z","iopub.status.idle":"2022-05-25T15:41:29.890785Z","shell.execute_reply.started":"2022-05-25T15:41:29.878670Z","shell.execute_reply":"2022-05-25T15:41:29.890052Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from IPython.display import clear_output\nimport torchvision.transforms as T\n# Lists to keep track of progress\nimg_list = []\nimg_list_fixedN = []\nG_losses = []\nD_losses = []\niters = 0\n\ntrain_accuracy = []\ntest_accuracy = []\n\nsample_interval = 100\nnum_epochs = 10\nlen_train_loader = len(train_loader)\n\nsupervised_batch = batch_size // 2\n\nnetD.train(True)\nnetG.train(True)\nt0 = time.time()\nprint(\"Starting Training Loop...\")\nfor epoch in range(num_epochs):\n    ep_train_accuracy = []\n    ep_test_accuracy = []\n    for i, (imgs, labels) in enumerate(train_loader):\n#         clear_output(True)\n        real_data = imgs.to(device)\n\n        real_targets = torch.ones(real_data.shape[0], dtype=torch.float32).to(device)\n        fake_targets = torch.zeros(real_data.shape[0], dtype=torch.float32).to(device)\n        \n        # update discriminator\n        lossD, d_acc, d_acc_test = train_netD(real_data, labels, optimizerD)\n\n        lossG = train_netG(real_targets, optimizerG)\n        \n        # Save Losses for plotting later\n        G_losses.append(lossG)\n        D_losses.append(lossD)\n        train_accuracy.append(d_acc)\n        test_accuracy.append(d_acc_test)\n        \n        ep_train_accuracy.append(d_acc)\n        ep_test_accuracy.append(d_acc_test)\n        \n#         if iters % 1000 < 10:\n#             fig, axs = plt.subplots(2, 3, figsize=(20,12))\n\n#             axs[0, 0].plot(G_losses[:], label=f'ep_gen={epoch}', color='green')\n#             axs[0, 0].plot(D_losses[:], label=f'ep_discr={epoch}', color='blue')\n#             axs[0, 0].legend()\n#             axs[0, 0].grid()\n\n#             axs[0, 1].plot(train_accuracy[:], label=f'ep_acc={epoch}', color='black')\n#             axs[0, 1].legend()\n#             axs[0, 1].grid()\n\n#             axs[0, 2].plot(test_accuracy[:], label=f'ep_acc={epoch}', color='black')\n#             axs[0, 2].legend()\n#             axs[0, 2].grid()\n\n#             noise = torch.randn(real_data.shape[0], nz, 1, 1, device=device)\n#             fake_img = netG(noise)\n\n#             for k in range(10):\n#                 tensor_img = fake_img[k]/2 + 0.5 \n#                 img = T.ToPILImage()(tensor_img)\n#                 axs[1, k%3].imshow(img)\n#             plt.show()\n\n        iters += 1\n    print(f'epoch ={epoch}/{num_epochs}')\n    time.time() - t0\n    print(f'spent_time ={time.time() - t0}')\n    print('ep_train_accuracy', np.mean(ep_train_accuracy))\n    print('ep_test_accuracy', np.mean(ep_test_accuracy))\n    print('----------------------')","metadata":{"execution":{"iopub.status.busy":"2022-05-25T15:41:29.892120Z","iopub.execute_input":"2022-05-25T15:41:29.892573Z","iopub.status.idle":"2022-05-25T15:49:47.435421Z","shell.execute_reply.started":"2022-05-25T15:41:29.892537Z","shell.execute_reply":"2022-05-25T15:49:47.434587Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Losses, metrics and generated examples","metadata":{}},{"cell_type":"code","source":"fig, axs = plt.subplots(2, 3, figsize=(20,12))\n\naxs[0, 0].plot(G_losses[:], label=f'ep_gen={epoch}', color='green')\naxs[0, 0].plot(D_losses[:], label=f'ep_discr={epoch}', color='blue')\naxs[0, 0].legend()\naxs[0, 0].grid()\n\naxs[0, 1].plot(train_accuracy[:], label=f'ep_acc={epoch}', color='black')\naxs[0, 1].legend()\naxs[0, 1].grid()\n\naxs[0, 2].plot(test_accuracy[:], label=f'ep_acc={epoch}', color='black')\naxs[0, 2].legend()\naxs[0, 2].grid()\n\nnoise = torch.randn(real_data.shape[0], nz, 1, 1, device=device)\nfake_img = netG(noise)\n\nfor k in range(10):\n    tensor_img = fake_img[k]/2 + 0.5 \n    img = T.ToPILImage()(tensor_img)\n    axs[1, k%3].imshow(img)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-05-25T15:49:47.436821Z","iopub.execute_input":"2022-05-25T15:49:47.437235Z","iopub.status.idle":"2022-05-25T15:49:48.417747Z","shell.execute_reply.started":"2022-05-25T15:49:47.437195Z","shell.execute_reply":"2022-05-25T15:49:48.417065Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"netD.train()\ntest_loss = 0\ncorrect = 0\n\nwith torch.no_grad():\n    for imgs, labels in test_loader:\n        adv, aux = netD(imgs.to(device))\n        test_loss += F.nll_loss(aux, labels.to(device), size_average=False).item()\n        pred = aux.data.max(1, keepdim=True)[1]\n        correct += pred.eq(labels.to(device).data.view_as(pred)).sum()\n\ntest_loss /= len(test_loader.dataset)\n# test_loss.append(test_loss)\n  \nprint(f'Avg. loss: {test_loss}, Accuracy: {correct}/{len(test_loader.dataset)} {100. * correct / len(test_loader.dataset)}')","metadata":{"execution":{"iopub.status.busy":"2022-05-25T15:49:48.418820Z","iopub.execute_input":"2022-05-25T15:49:48.419055Z","iopub.status.idle":"2022-05-25T15:49:51.790451Z","shell.execute_reply.started":"2022-05-25T15:49:48.419025Z","shell.execute_reply":"2022-05-25T15:49:51.789715Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, axs = plt.subplots(2, 3, figsize=(20,12))\n\n\nnoise = torch.randn(real_data.shape[0], nz, 1, 1, device=device)\nfake_img = netG(noise)\n\nfor k in range(10):\n    tensor_img = fake_img[k]/2 + 0.5 \n    img = T.ToPILImage()(tensor_img)\n    axs[1, k%3].imshow(img)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-05-25T16:28:15.792616Z","iopub.execute_input":"2022-05-25T16:28:15.793075Z","iopub.status.idle":"2022-05-25T16:28:16.399159Z","shell.execute_reply.started":"2022-05-25T16:28:15.793034Z","shell.execute_reply":"2022-05-25T16:28:16.398520Z"},"trusted":true},"execution_count":null,"outputs":[]}]}