{"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":"code","source":"import os\nimport pandas as pd\nimport numpy as np\nimport random\nimport gc\nimport time\nimport matplotlib.animation as animation\nimport matplotlib.pyplot as plt\nfrom IPython.display import HTML\nimport cv2\nimport torch\nimport torch.nn as nn\nfrom torch.utils.data import Dataset,DataLoader\nimport torchvision.transforms as T\nimport albumentations.augmentations.transforms as AT\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2\nfrom albumentations.core.transforms_interface import ImageOnlyTransform\n\nfrom skimage.util import random_noise\n\nimport torchvision\nimport uuid\nfrom PIL import Image\n\n","metadata":{"execution":{"iopub.status.busy":"2021-12-26T21:27:54.836898Z","iopub.execute_input":"2021-12-26T21:27:54.837252Z","iopub.status.idle":"2021-12-26T21:27:54.845187Z","shell.execute_reply.started":"2021-12-26T21:27:54.837218Z","shell.execute_reply":"2021-12-26T21:27:54.844268Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# ENV CONFIG","metadata":{}},{"cell_type":"code","source":"class config():\n    \n    RUN_PATH=\"\"\n    \n    #SEEDING\n    manualSeed = 264\n    print(\"Random Seed: \", manualSeed)\n    random.seed(manualSeed)\n    torch.manual_seed(manualSeed)\n    \n    #ENV\n    DS_DIR = \"../input/sloppjockey-art-dataset/\"\n    \n    N_GPU = 0\n    DEVICE = torch.device(\"cuda:0\" if (torch.cuda.is_available() and N_GPU > 0) else \"cpu\")\n    print(\"Using :\",DEVICE.type)\n    N_WORKERS = 2 if N_GPU == 0 else 4 * N_GPU\n    PIN_MEMORY=False\n    NORM_MEAN=(0.5, 0.5, 0.5)\n    NORM_STD=(0.5, 0.5, 0.5)\n    \n    #MODEL\n    Z_LEN=1024\n    NGF=128\n    NDF=128\n    \n    WEIGHTS_MEAN=0\n    WEIGHTS_STD=0.02\n    \n    #TRAINING\n    IMG_SIZE=(64,64)\n    N_CHANNELS=3\n    \n    EPOCHS=4000\n    BATCH_SIZE=128\n    \n    REAL_SMOOTHING=[0.7, 1.2]\n    FAKE_SMOOTHING=[0.0, 0.3]\n    #HYPERPARAMETERS\n    LR=0.0002\n    OPT_BETAS=(0.5,0.999)\n    \n    # Speed ups\n    torch.autograd.set_detect_anomaly(False)\n    torch.autograd.profiler.profile(False)\n    torch.autograd.profiler.emit_nvtx(False)\n    torch.backends.cudnn.benchmark = True\nconfig()","metadata":{"execution":{"iopub.status.busy":"2021-12-26T21:31:13.11713Z","iopub.execute_input":"2021-12-26T21:31:13.117481Z","iopub.status.idle":"2021-12-26T21:31:13.134162Z","shell.execute_reply.started":"2021-12-26T21:31:13.11745Z","shell.execute_reply":"2021-12-26T21:31:13.133119Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# DATA","metadata":{}},{"cell_type":"code","source":"class ImagesDataset(Dataset):\n    def __init__(self,img_folder,transforms=None):\n        self.img_folder=img_folder\n        self.images_paths=[img_folder+img_filename for img_filename in os.listdir(img_folder)]\n        self.transforms=transforms\n    def __len__(self):\n        return len(self.images_paths)\n    def __getitem__(self,idx):\n        \n        image = cv2.cvtColor(cv2.imread( self.images_paths[idx]),cv2.COLOR_BGR2RGB)\n\n        if self.transforms:\n            aug=self.transforms(image=image)\n            image=aug['image']\n            \n        return image","metadata":{"execution":{"iopub.status.busy":"2021-12-26T21:31:16.01333Z","iopub.execute_input":"2021-12-26T21:31:16.01367Z","iopub.status.idle":"2021-12-26T21:31:16.021915Z","shell.execute_reply.started":"2021-12-26T21:31:16.013639Z","shell.execute_reply":"2021-12-26T21:31:16.020936Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class GaussianNoise(ImageOnlyTransform):\n    def __init__(self,scale,mean=0,std=0.2):\n        super().__init__()\n        self.mean=mean\n        self.std=std\n        self.scale=scale\n    def apply(self, x,**params):\n        noise_tensor = torch.normal(self.mean, self.std, size=x.size()).to(config.DEVICE)\n        return x + (noise_tensor * self.scale)","metadata":{"execution":{"iopub.status.busy":"2021-12-26T21:31:17.684845Z","iopub.execute_input":"2021-12-26T21:31:17.685367Z","iopub.status.idle":"2021-12-26T21:31:17.691844Z","shell.execute_reply.started":"2021-12-26T21:31:17.685331Z","shell.execute_reply":"2021-12-26T21:31:17.690878Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n        \nimgs_transforms = A.Compose([A.Resize(config.IMG_SIZE[0],config.IMG_SIZE[1]),\n                             A.CenterCrop(config.IMG_SIZE[0],config.IMG_SIZE[1]),\n                             A.Normalize(mean=config.NORM_MEAN, std=config.NORM_STD),\n                             ToTensorV2(),\n                             #GaussianNoise(scale=0.2)\n                            ])\n\nimgs_loader = DataLoader(ImagesDataset(config.DS_DIR,transforms=imgs_transforms),\n                        batch_size=config.BATCH_SIZE,\n                        shuffle=False)","metadata":{"execution":{"iopub.status.busy":"2021-12-26T21:31:19.651961Z","iopub.execute_input":"2021-12-26T21:31:19.652326Z","iopub.status.idle":"2021-12-26T21:31:19.692829Z","shell.execute_reply.started":"2021-12-26T21:31:19.652296Z","shell.execute_reply":"2021-12-26T21:31:19.69202Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_batch=next(iter(imgs_loader))\nprint(sample_batch[0][0].dtype)\nplt.imshow(sample_batch[78][0])#.reshape(64,64,3)","metadata":{"execution":{"iopub.status.busy":"2021-12-26T21:31:21.641827Z","iopub.execute_input":"2021-12-26T21:31:21.642172Z","iopub.status.idle":"2021-12-26T21:31:26.239703Z","shell.execute_reply.started":"2021-12-26T21:31:21.642139Z","shell.execute_reply":"2021-12-26T21:31:26.23877Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# DCGAN IMPLEMENTATION","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, config.WEIGHTS_MEAN, config.WEIGHTS_STD)\n    elif classname.find('BatchNorm') != -1:\n        nn.init.normal_(m.weight.data, 1.0, config.WEIGHTS_STD)\n        nn.init.constant_(m.bias.data, 0)","metadata":{"execution":{"iopub.status.busy":"2021-12-26T21:31:29.169769Z","iopub.execute_input":"2021-12-26T21:31:29.170345Z","iopub.status.idle":"2021-12-26T21:31:29.177323Z","shell.execute_reply.started":"2021-12-26T21:31:29.170301Z","shell.execute_reply":"2021-12-26T21:31:29.175956Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## GENERATOR","metadata":{}},{"cell_type":"code","source":"class GaussianNoiseLayer(nn.Module):\n    def __init__(self, scale,mean=0, std=0.2):\n        super(GaussianNoiseLayer, self).__init__()\n        self.mean = mean\n        self.std = std\n        self.scale = scale\n    def forward(self, x):\n        noise_tensor = torch.normal(self.mean, self.std, size=x.size()).to(config.DEVICE)\n        x = x + (noise_tensor * self.scale)\n        return x","metadata":{"execution":{"iopub.status.busy":"2021-12-26T21:31:32.082824Z","iopub.execute_input":"2021-12-26T21:31:32.083347Z","iopub.status.idle":"2021-12-26T21:31:32.089923Z","shell.execute_reply.started":"2021-12-26T21:31:32.083309Z","shell.execute_reply":"2021-12-26T21:31:32.089072Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Generator(nn.Module):\n    def __init__(self):\n        super(Generator,self).__init__()\n        self.model= nn.Sequential(\n            #INPUT -> Z_LEN , 1 , 1 -> 1024, 1, 1\n            nn.ConvTranspose2d(config.Z_LEN, config.NGF * 8, kernel_size = 4, stride = 1, padding = 0, bias=False),\n            nn.BatchNorm2d(config.NGF * 8),\n            nn.LeakyReLU(0.2, inplace = True),\n            nn.Dropout(p=0.5),\n            # 1024 X 4 X 4\n            nn.ConvTranspose2d(config.NGF * 8, config.NGF * 4, kernel_size = 4, stride = 2, padding = 1, bias=False),\n            nn.BatchNorm2d(config.NGF * 4),\n            nn.LeakyReLU(0.2, inplace = True),\n            nn.Dropout(p=0.5),\n            # 512 X 8 X 8\n            nn.ConvTranspose2d(config.NGF * 4, config.NGF * 2, kernel_size = 4, stride = 2, padding = 1, bias=False),\n            nn.BatchNorm2d(config.NGF * 2),\n            nn.LeakyReLU(0.2, inplace = True),\n            nn.Dropout(p=0.5),\n            # 256 X 16 x 16\n            nn.ConvTranspose2d(config.NGF * 2, config.NGF, kernel_size = 4, stride = 2, padding = 1, bias=False),\n            nn.BatchNorm2d(config.NGF ),\n            nn.LeakyReLU(0.2, inplace = True),\n            nn.Dropout(p=0.5),\n            # 128 X 32 X 32\n            nn.ConvTranspose2d(config.NGF, config.N_CHANNELS, kernel_size = 4, stride = 2, padding = 1, bias=False),\n            # 3 x 64 x 64\n            nn.Tanh()\n        )\n        \n    def forward(self,x):\n        return self.model(x)\n        ","metadata":{"execution":{"iopub.status.busy":"2021-12-26T21:31:33.524336Z","iopub.execute_input":"2021-12-26T21:31:33.524673Z","iopub.status.idle":"2021-12-26T21:31:33.538371Z","shell.execute_reply.started":"2021-12-26T21:31:33.524642Z","shell.execute_reply":"2021-12-26T21:31:33.537452Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"Gen = Generator().to(config.DEVICE)\n\nif (config.DEVICE.type == 'cuda') and (config.N_GPU > 1):\n    Gen = nn.DataParallel(Gen, list(range(config.N_GPU)))\n    \nGen.apply(weights_init)\n\nprint(Gen)","metadata":{"execution":{"iopub.status.busy":"2021-12-26T21:31:35.164513Z","iopub.execute_input":"2021-12-26T21:31:35.16492Z","iopub.status.idle":"2021-12-26T21:31:35.667452Z","shell.execute_reply.started":"2021-12-26T21:31:35.164882Z","shell.execute_reply":"2021-12-26T21:31:35.666708Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## DISCRIMINATOR","metadata":{}},{"cell_type":"code","source":"class Discriminator(nn.Module):\n    def __init__(self):\n        super(Discriminator,self).__init__()\n        self.model = nn.Sequential(\n            #Input -> (N_CHANNELS, IMG_SIZE[0],IMG_SIZE[1]) -> 3 X 64 X 64 \n            nn.Conv2d(config.N_CHANNELS, config.NDF, kernel_size = 4, stride = 2, padding = 1, bias=False),\n            nn.BatchNorm2d(config.NDF),\n            nn.LeakyReLU(0.2, inplace=True),\n            # 128 X 64 x 64\n            nn.Conv2d(config.NDF, config.NDF * 2, kernel_size = 4, stride = 2, padding = 1, bias=False),\n            nn.BatchNorm2d(config.NDF * 2),\n            nn.LeakyReLU(0.2, inplace=True),\n            # 256 X 32 x 32\n            nn.Conv2d(config.NDF * 2, config.NDF * 4, kernel_size = 4, stride = 2, padding = 1, bias=False),\n            nn.BatchNorm2d(config.NDF * 4),\n            nn.LeakyReLU(0.2, inplace=True),\n            # 512 X 16 X 16\n            nn.Conv2d(config.NDF * 4, config.NDF * 8, kernel_size = 4, stride = 2, padding = 1, bias=False),\n            nn.BatchNorm2d(config.NDF * 8),\n            nn.LeakyReLU(0.2, inplace=True),\n            # 1024 X 8 X 8\n            nn.Conv2d(config.NDF * 8, 1, kernel_size = 4, stride = 1, padding = 0, bias=False),\n            # 2048 X 1 X 1\n            nn.Sigmoid()\n        )\n    def forward(self,x):\n        return self.model(x)\n        ","metadata":{"execution":{"iopub.status.busy":"2021-12-26T21:31:37.547051Z","iopub.execute_input":"2021-12-26T21:31:37.547394Z","iopub.status.idle":"2021-12-26T21:31:37.561883Z","shell.execute_reply.started":"2021-12-26T21:31:37.547363Z","shell.execute_reply":"2021-12-26T21:31:37.560568Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"Dis = Discriminator().to(config.DEVICE)\n\nif (config.DEVICE.type == 'cuda') and (config.N_GPU > 1):\n    Dis = nn.DataParallel(Dis, list(range(config.N_GPU)))\n    \nDis.apply(weights_init)\n\nprint(Dis)","metadata":{"execution":{"iopub.status.busy":"2021-12-26T21:31:42.15632Z","iopub.execute_input":"2021-12-26T21:31:42.156664Z","iopub.status.idle":"2021-12-26T21:31:42.380762Z","shell.execute_reply.started":"2021-12-26T21:31:42.156631Z","shell.execute_reply":"2021-12-26T21:31:42.379751Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Loss and Optimizers","metadata":{}},{"cell_type":"markdown","source":"## $min_{G}max_{D}V(D,G)=E_{x\\sim p_{data}}[logD(x)]+E_{z\\sim p_{z}}[log(1-D(G(z)))]$","metadata":{}},{"cell_type":"code","source":"loss_fn=nn.BCELoss()\n\noptimizerD = torch.optim.Adam(Dis.parameters(), lr=config.LR, betas=config.OPT_BETAS)\noptimizerG = torch.optim.Adam(Gen.parameters(), lr=config.LR, betas=config.OPT_BETAS)","metadata":{"execution":{"iopub.status.busy":"2021-12-26T21:31:46.023232Z","iopub.execute_input":"2021-12-26T21:31:46.023611Z","iopub.status.idle":"2021-12-26T21:31:46.030765Z","shell.execute_reply.started":"2021-12-26T21:31:46.023577Z","shell.execute_reply":"2021-12-26T21:31:46.029467Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Training","metadata":{}},{"cell_type":"code","source":"def get_run_id():\n    filelist = os.listdir(\"./runs/\")\n    if filelist == []:\n        return 1\n    filelist = sorted(filelist,key=lambda x: int(os.path.splitext(x)[0].split(\"-\")[1]))\n\n    return int(filelist[-1].split(\"-\")[1]) + 1","metadata":{"execution":{"iopub.status.busy":"2021-12-26T21:31:47.998557Z","iopub.execute_input":"2021-12-26T21:31:47.99889Z","iopub.status.idle":"2021-12-26T21:31:48.005187Z","shell.execute_reply.started":"2021-12-26T21:31:47.998858Z","shell.execute_reply":"2021-12-26T21:31:48.004075Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def make_directory_for_run(run_id):\n    print(f'Running run-{str(run_id)}')\n    if not os.path.exists('./runs'):\n        os.mkdir('./runs')\n    os.mkdir(f'./runs/run-{str(run_id)}')\n    return f'./runs/run-{str(run_id)}/'","metadata":{"execution":{"iopub.status.busy":"2021-12-26T21:31:49.743158Z","iopub.execute_input":"2021-12-26T21:31:49.743485Z","iopub.status.idle":"2021-12-26T21:31:49.749208Z","shell.execute_reply.started":"2021-12-26T21:31:49.743455Z","shell.execute_reply":"2021-12-26T21:31:49.747969Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def generate_images(gen,noise,run_id,n_epoch,save=True):\n    \n    with torch.no_grad():\n        fakes = gen(noise).detach().cpu()\n    \n    if save:\n        \n        \n        run_epoch_path=config.RUN_PATH + f'epoch-{str(n_epoch)}/'\n        epoch_imgs_path=run_epoch_path+\"images/\"\n        \n        if not os.path.exists(run_epoch_path):\n            os.mkdir(run_epoch_path)\n            \n        if not os.path.exists(epoch_imgs_path):\n            os.mkdir(epoch_imgs_path)\n        \n        torchvision.utils.save_image(fakes,config.RUN_PATH+f\"DCGAN-Generator-epoch-{n_epoch}-imgs_grid.jpeg\", normalize=True)\n        \n        for i,img in enumerate(fakes):\n            torchvision.utils.save_image(img,epoch_imgs_path+f\"img-{i}.jpeg\", normalize=True)\n            \n    return torchvision.utils.make_grid(fakes, padding=2, normalize=True)","metadata":{"execution":{"iopub.status.busy":"2021-12-26T21:31:51.731417Z","iopub.execute_input":"2021-12-26T21:31:51.731746Z","iopub.status.idle":"2021-12-26T21:31:51.741641Z","shell.execute_reply.started":"2021-12-26T21:31:51.731714Z","shell.execute_reply":"2021-12-26T21:31:51.740423Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def clean():\n    gc.collect()\n    if config.DEVICE.type == 'cuda':\n        with pytorch.no_grad():\n            torch.cuda.empty_cache()","metadata":{"execution":{"iopub.status.busy":"2021-12-26T21:31:53.954714Z","iopub.execute_input":"2021-12-26T21:31:53.955072Z","iopub.status.idle":"2021-12-26T21:31:53.962156Z","shell.execute_reply.started":"2021-12-26T21:31:53.955038Z","shell.execute_reply":"2021-12-26T21:31:53.961133Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def save_model(model,model_name, run_id,n_epoch):\n    \n    run_epoch_path=config.RUN_PATH + f'epoch-{str(n_epoch)}/'\n    \n    if not os.path.exists(run_epoch_path):\n        os.mkdir(run_epoch_path)\n        \n    torch.save(model.state_dict(), f'{run_epoch_path}{model_name}-epoch-{n_epoch}.pth')\n    print(f\"\\nModel - {model_name} - Saved.\")","metadata":{"execution":{"iopub.status.busy":"2021-12-26T21:31:55.245033Z","iopub.execute_input":"2021-12-26T21:31:55.245372Z","iopub.status.idle":"2021-12-26T21:31:55.254051Z","shell.execute_reply.started":"2021-12-26T21:31:55.245333Z","shell.execute_reply":"2021-12-26T21:31:55.253226Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_labels(class_name,batch_size,smoothing=True,smoothing_round=2):\n    labels = {\n        \"real\": 1.0,\n        \"fake\": 0.0\n    }\n    if smoothing:\n        if class_name == \"real\":\n            return torch.Tensor([round(random.uniform(*config.REAL_SMOOTHING), smoothing_round) for i in range(batch_size)])\n        elif class_name == \"fake\":\n            return torch.Tensor([round(random.uniform(*config.FAKE_SMOOTHING), smoothing_round) for i in range(batch_size)])\n        \n    return torch.full((batch_size,), labels[classname], dtype=torch.float, device=config.DEVICE)","metadata":{"execution":{"iopub.status.busy":"2021-12-26T21:31:56.752587Z","iopub.execute_input":"2021-12-26T21:31:56.752911Z","iopub.status.idle":"2021-12-26T21:31:56.760503Z","shell.execute_reply.started":"2021-12-26T21:31:56.75288Z","shell.execute_reply":"2021-12-26T21:31:56.759485Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Trained (On Local)","metadata":{}},{"cell_type":"code","source":"\nrun_id=get_run_id()\n\nconfig.RUN_PATH=make_directory_for_run(run_id)\n\ngen_imgs_list=[]\ng_losses = []\nd_losses=[]\n\n\nfixed_noise = torch.randn(64, config.Z_LEN, 1, 1, device=config.DEVICE)\n\nstart_time= time.time()\n\nfor n_epoch in range(1,config.EPOCHS+1):\n    \n    print(f\"\\nEPOCH : {n_epoch}/{config.EPOCHS} :\\n\")\n    \n    Gen.train()\n    Dis.train()\n    \n    n_imgs=0\n    \n    for batch_idx,batch in enumerate(imgs_loader):\n        \n        n_imgs+=len(batch)\n        \n        print(f\"Batch #{batch_idx+1} -> {n_imgs}/{len(imgs_loader.dataset)}\")\n        \n        # Optimize Discriminator : maximize log(D(x)) + log(1 - D(G(z)))\n        # # # # REAL BATCH\n        Dis.zero_grad()\n        images = batch.to(config.DEVICE)\n        batch_size = images.size(0)\n        labels = get_labels(\"real\",batch_size)\n        output=Dis(images).view(-1)\n        D_real_loss = loss_fn(output, labels)\n        #Accumulating gradients for D(x) error\n        D_real_loss.backward()\n        D_x = output.mean().item()\n        \n        \n        del batch,images\n        \n        # # # # FAKE BATCH\n        noise = torch.randn(batch_size,config.Z_LEN,1,1,device=config.DEVICE)\n        #Generating fake images for D\n        fake = Gen(noise)\n        labels=get_labels(\"fake\",batch_size)\n        # Predicting fake labels \n        # detach() is called to not interfere with the backend Generator's backpropagation graph\n        output = Dis(fake.detach()).view(-1)\n        D_fake_loss = loss_fn(output,labels)\n        #Accumulating gradients for D(G(z)) error\n        D_fake_loss.backward()\n        \n        D_loss = D_real_loss + D_fake_loss\n        \n        D_G_z1 = output.mean().item()\n        \n        #Updating Discriminator's weights\n        optimizerD.step()\n        \n        # Optimizing Generator: maximize log(D(G(z)))\n        # # # # Generating image and discriminating it\n        Gen.zero_grad()\n        labels=get_labels(\"real\",batch_size)\n        output = Dis(fake).view(-1)\n        G_loss = loss_fn(output,labels)\n        #Accumualting gradients for the Generator\n        G_loss.backward()\n        #Updating Generator's weights\n        optimizerG.step()\n        \n        D_G_z2 = output.mean().item()\n        \n        \n        \n        D_G_z = (D_G_z1 + D_G_z2)/2\n        \n        \n        \n        print(f\"D_Loss: {D_loss.item():.4f} G_Loss: {G_loss.item():.4f} D(x): {D_x:.4f} D(G(z)): {D_G_z:.4f}\")\n        \n        d_losses.append(D_loss.item())\n        g_losses.append(G_loss.item())\n        \n   \n    # Generating Grid Images\n    Gen.eval()\n    gen_imgs_list.append(generate_images(Gen,fixed_noise,run_id,n_epoch,save=True))\n    \n    #Clean Memory\n    clean()\n    \n    #Saving Models\n    #save_model(Gen,\"DCGAN-Generator\", run_id ,n_epoch)\n    #save_model(Dis,\"DCGAN-Discriminator\", run_id ,n_epoch)\n    \nsave_model(Gen,\"DCGAN-Generator\", run_id ,n_epoch)\nsave_model(Dis,\"DCGAN-Discriminator\", run_id ,n_epoch)\nend_time=time.time()\ntime_passed = start_time - end_time\n\nprint(f\"DCGAN Training completed {config.EPOCHS}/{config.EPOCHS} Epochs in {time_passed:.4f} seconds.\")","metadata":{"_kg_hide-output":true,"execution":{"iopub.execute_input":"2021-12-24T00:13:08.854842Z","iopub.status.busy":"2021-12-24T00:13:08.854123Z","iopub.status.idle":"2021-12-24T09:04:41.981846Z","shell.execute_reply":"2021-12-24T09:04:41.979476Z","shell.execute_reply.started":"2021-12-24T00:13:08.854802Z"}},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#logging run output\n#with open(config.RUN_PATH+f\"run-{run_id}.txt\", 'w') as f:\n#    f.write(cap.stdout)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"save_model(Gen,\"DCGAN-Generator\", run_id ,n_epoch)\nsave_model(Dis,\"DCGAN-Discriminator\", run_id ,n_epoch)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.plot(g_losses)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.plot(d_losses)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = plt.figure(figsize=(8,8))\nplt.axis(\"off\")\nims = [[plt.imshow(np.transpose(i,(1,2,0)), animated=True)] for i in gen_imgs_list]\nani = animation.ArtistAnimation(fig, ims, interval=1000, repeat_delay=1000, blit=True)\n\nHTML(ani.to_jshtml())","metadata":{},"execution_count":null,"outputs":[]}]}