{"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":"from __future__ import print_function\nimport torch.nn as nn\nimport torch\nimport numpy as np\nimport torchvision\nimport matplotlib.pyplot as plt\nimport torchvision.utils as vutils\nimport torch.nn.functional as F\n\ntorch.manual_seed(1992)","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","jupyter":{"source_hidden":true},"execution":{"iopub.status.busy":"2022-01-30T13:15:38.321994Z","iopub.execute_input":"2022-01-30T13:15:38.322471Z","iopub.status.idle":"2022-01-30T13:15:39.970392Z","shell.execute_reply.started":"2022-01-30T13:15:38.322390Z","shell.execute_reply":"2022-01-30T13:15:39.969438Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h1 style=\"background-color:#A50034; font-family:segoeui; font-size:200%; text-align:center; border-radius: 15px 50px;\"> 1. GAN Introduction </h1>\n\n![gan](https://learn-neural-networks.com/wp-content/uploads/2020/04/gan.jpg)\n\nThe core idea of a GAN is based on the \"indirect\" training through the discriminator, another neural network that is able to tell how much an input is \"realistic\", which itself is also being updated dynamically This basically means that the generator is not trained to minimize the distance to a specific image, but rather to fool the discriminator. This enables the model to learn in an unsupervised manner.(Wiki)<br>\n<br>\nIn this notebook I will share ready to use GAN Generator\n1. Intialize Generator instance\n2. Create the random noise\n3. Input random noise to generator\n4. Yield the generated images\n5. Create unlimited COTS\n\n**When you will be interested in the training routine I will consider to create another notebook where whole training process will be explained**<br>\nGan is the interesting approach in data augumentation field.<br>\nI have also presented the Neural Style Transfer [Notebook Here](https://www.kaggle.com/marcinstasko/cots-neuralstyle-transfer-pytorch-augumentation)\n","metadata":{}},{"cell_type":"markdown","source":"<h1 style=\"background-color:#A50034; font-family:segoeui; font-size:200%; text-align:center; border-radius: 15px 50px;\"> 2. Create Generator Instance </h1>\n","metadata":{}},{"cell_type":"code","source":"# Define the Generator Network\nclass Generator(nn.Module):\n    def __init__(self, params):\n        super().__init__()\n\n        # Input is the latent vector Z.\n        self.tconv1 = nn.ConvTranspose2d(params['nz'], params['ngf']*8,\n            kernel_size=4, stride=1, padding=0, bias=False)\n        self.bn1 = nn.BatchNorm2d(params['ngf']*8)\n\n        # Input Dimension: (ngf*8) x 4 x 4\n        self.tconv2 = nn.ConvTranspose2d(params['ngf']*8, params['ngf']*4,\n            4, 2, 1, bias=False)\n        self.bn2 = nn.BatchNorm2d(params['ngf']*4)\n\n        # Input Dimension: (ngf*4) x 8 x 8\n        self.tconv3 = nn.ConvTranspose2d(params['ngf']*4, params['ngf']*2,\n            4, 2, 1, bias=False)\n        self.bn3 = nn.BatchNorm2d(params['ngf']*2)\n\n        # Input Dimension: (ngf*2) x 16 x 16\n        self.tconv4 = nn.ConvTranspose2d(params['ngf']*2, params['ngf'],\n            4, 2, 1, bias=False)\n        self.bn4 = nn.BatchNorm2d(params['ngf'])\n\n        # Input Dimension: (ngf) * 32 * 32\n        self.tconv5 = nn.ConvTranspose2d(params['ngf'], params['nc'],\n            4, 2, 1, bias=False)\n        #Output Dimension: (nc) x 64 x 64\n\n    def forward(self, x):\n        x = F.relu(self.bn1(self.tconv1(x)))\n        x = F.relu(self.bn2(self.tconv2(x)))\n        x = F.relu(self.bn3(self.tconv3(x)))\n        x = F.relu(self.bn4(self.tconv4(x)))\n\n        x = F.tanh(self.tconv5(x))\n\n        return x","metadata":{"execution":{"iopub.status.busy":"2022-01-30T13:15:39.972114Z","iopub.execute_input":"2022-01-30T13:15:39.972434Z","iopub.status.idle":"2022-01-30T13:15:39.983746Z","shell.execute_reply.started":"2022-01-30T13:15:39.972395Z","shell.execute_reply":"2022-01-30T13:15:39.982770Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Input necessary parameters (established during training)\nparams = {\n    'nc' : 3,    # Number of channles (3-colour)\n    'nz' : 100,  # The input size to the generator (latent vector).\n    'ngf' : 64,  # Feature maps (For training)\n}\n","metadata":{"execution":{"iopub.status.busy":"2022-01-30T13:15:39.985205Z","iopub.execute_input":"2022-01-30T13:15:39.985745Z","iopub.status.idle":"2022-01-30T13:15:39.993586Z","shell.execute_reply.started":"2022-01-30T13:15:39.985707Z","shell.execute_reply":"2022-01-30T13:15:39.992805Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"MODEL_PATH = '../input/cots-ganv1/COTS_GAN_v1.pth'\nnetG = Generator(params).cuda()\nmodel = torch.load(MODEL_PATH)\nnetG.load_state_dict(model['generator'])\nnetG.eval()","metadata":{"execution":{"iopub.status.busy":"2022-01-30T13:15:39.995741Z","iopub.execute_input":"2022-01-30T13:15:39.996090Z","iopub.status.idle":"2022-01-30T13:15:45.175198Z","shell.execute_reply.started":"2022-01-30T13:15:39.995964Z","shell.execute_reply":"2022-01-30T13:15:45.174447Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<h1 style=\"background-color:#A50034; font-family:segoeui; font-size:200%; text-align:center; border-radius: 15px 50px;\"> 3. Generate Images </h1>\n","metadata":{}},{"cell_type":"code","source":"from tqdm import tqdm_notebook as tqdm\n# How many images in batch\nim_batch_size = 40\n\n# How many images in total\nn_images=40\n\nplt.rcParams['figure.figsize'] = (4*n_images, n_images)\n\ndevice = torch.device('cuda')\nplt.ion() # plt interactive mode \n\nfor i_batch in tqdm(range(0, n_images, im_batch_size)):\n    # Generate Random Noise for generator\n    gen_z = torch.randn(im_batch_size, params['nz'], 1, 1, device=device)\n    \n    # Input noise to the generator instance\n    gen_images = netG(gen_z)\n    \n    # Create grind and plot the results\n    grid = vutils.make_grid(gen_images, nrow=4, padding=10,normalize=True)\n    cpu_grid = grid.to(\"cpu\")#.clone().detach()\n    cpu_permuted = np.transpose(cpu_grid,(1,2,0))\n    plt.imshow(cpu_permuted)\n    \n    # If you want to save the image, \n    # Change \"./\" to your location if other than working directory\n    \n    vutils.save_image(gen_images.data, '{}/COTS_GAN1{}.jpg'.format(\"./\", i_batch), normalize=True)","metadata":{"execution":{"iopub.status.busy":"2022-01-30T13:17:55.968594Z","iopub.execute_input":"2022-01-30T13:17:55.969176Z","iopub.status.idle":"2022-01-30T13:17:58.310514Z","shell.execute_reply.started":"2022-01-30T13:17:55.969131Z","shell.execute_reply":"2022-01-30T13:17:58.309869Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls ./","metadata":{"execution":{"iopub.status.busy":"2022-01-30T13:17:03.064092Z","iopub.execute_input":"2022-01-30T13:17:03.064792Z","iopub.status.idle":"2022-01-30T13:17:03.752261Z","shell.execute_reply.started":"2022-01-30T13:17:03.064749Z","shell.execute_reply":"2022-01-30T13:17:03.751443Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**If you like the code please upvote and comment :)**","metadata":{}}]}