{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load in \n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory\n\nimport os\nprint(os.listdir(\"../input\"))\n\n# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport numpy as np\nimport torch\nfrom torch import nn, optim\nimport torch.nn.functional as F\nfrom torchvision import datasets, transforms\nfrom torchvision.utils import save_image\nimport os\nfrom tqdm import tqdm_notebook as tqdm\n\nbatch_size = 32\n\n# 64x64 images!\nrandom_transforms = [transforms.ColorJitter(), transforms.RandomRotation(degrees=20)]\ntransform = transforms.Compose([transforms.Resize(64),\n                                transforms.CenterCrop(64),\n                                transforms.RandomHorizontalFlip(p=0.5),\n                                transforms.RandomApply(random_transforms, p=0.2),\n                                transforms.ToTensor(),\n                                transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])\n\ntrain_data = datasets.ImageFolder('../input/all-dogs/', transform=transform)\ntrain_loader = torch.utils.data.DataLoader(train_data, shuffle=True,\n                                           batch_size=batch_size, num_workers=4)\n                                           \nimgs, label = next(iter(train_loader))\nimgs = imgs.numpy().transpose(0, 2, 3, 1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class Generator(nn.Module):\n    def __init__(self, nz=128, channels=3):\n        super(Generator, self).__init__()\n        \n        self.nz = nz\n        self.channels = channels\n        \n        def convlayer(n_input, n_output, k_size=4, stride=2, padding=0):\n            block = [\n                nn.ConvTranspose2d(n_input, n_output, kernel_size=k_size, stride=stride, padding=padding, bias=False),\n                nn.BatchNorm2d(n_output),\n                nn.ReLU(inplace=True),\n            ]\n            return block\n\n        self.model = nn.Sequential(\n            *convlayer(self.nz, 1024, 4, 1, 0), # Fully connected layer via convolution.\n            *convlayer(1024, 512, 4, 2, 1),\n            *convlayer(512, 256, 4, 2, 1),\n            *convlayer(256, 128, 4, 2, 1),\n            *convlayer(128, 64, 4, 2, 1),\n            nn.ConvTranspose2d(64, self.channels, 3, 1, 1),\n            nn.Tanh()\n        )\n\n\n    def forward(self, z):\n        z = z.view(-1, self.nz, 1, 1)\n        img = self.model(z)\n        return img\n\nclass Discriminator(nn.Module):\n    def __init__(self, channels=3):\n        super(Discriminator, self).__init__()\n        \n        self.channels = channels\n\n        def convlayer(n_input, n_output, k_size=4, stride=2, padding=0, bn=False):\n            block = [nn.Conv2d(n_input, n_output, kernel_size=k_size, stride=stride, padding=padding, bias=False)]\n            if bn:\n                block.append(nn.BatchNorm2d(n_output))\n            block.append(nn.LeakyReLU(0.2, inplace=True))\n            return block\n\n        self.model = nn.Sequential(\n            *convlayer(self.channels, 32, 4, 2, 1),\n            *convlayer(32, 64, 4, 2, 1),\n            *convlayer(64, 128, 4, 2, 1, bn=True),\n            *convlayer(128, 256, 4, 2, 1, bn=True),\n            nn.Conv2d(256, 1, 4, 1, 0, bias=False),  # FC with Conv.\n        )\n\n    def forward(self, imgs):\n        out = self.model(imgs)\n        return out.view(-1, 1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n\nepochs = 200\nnz = 128\nlr_D = 0.001\nlr_G = 0.0007\nbeta1 = 0.5\n\nnetG = Generator(nz).to(device)\nnetD = Discriminator().to(device)\ny1 = 0.95\ny2 = 0.03\nbatch_size = train_loader.batch_size\n\nfixed_noise = torch.randn(25, nz, 1, 1, device=device)\n\n\n### training here\n\n\n\ncriterion = nn.BCEWithLogitsLoss()\n\noptimizerD = optim.Adam(netD.parameters(), lr=lr_D, betas=(beta1, 0.999))\noptimizerG = optim.Adam(netG.parameters(), lr=lr_G, betas=(beta1, 0.999))\n\nlr_schedulerG = torch.optim.lr_scheduler.CosineAnnealingWarmRestarts(optimizerG, T_0=epochs//20, eta_min=0.00001)\nlr_schedulerD = torch.optim.lr_scheduler.CosineAnnealingWarmRestarts(optimizerD, T_0=epochs//20, eta_min=0.00004)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def show_generated_img():\n    noise = torch.randn(1, nz, 1, 1, device=device)\n    gen_image = netG(noise).to(\"cpu\").clone().detach().squeeze(0)\n    gen_image = gen_image.numpy().transpose(1, 2, 0)\n    plt.imshow((gen_image+1)/2)\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"step = 0\nfor epoch in range(epochs):\n    for ii, (real_images, train_labels) in tqdm(enumerate(train_loader), total=len(train_loader)):\n        ############################\n        # (1) Update D network\n        ###########################\n        if ii & 1 == 1: \n            netD.zero_grad()\n            real_images = real_images.to(device)\n            batch_size = real_images.size(0)\n            real_label = torch.full((batch_size, 1), y1, device=device)\n            fake_label = torch.full((batch_size, 1), y2, device=device)\n        \n            y_pred = netD(real_images)\n         \n            noise = torch.randn(batch_size, nz, 1, 1, device=device)\n            fake_images = netG(noise)\n        \n            y_pred_fake = netD(fake_images.detach())\n        \n            errD = (torch.mean((y_pred - torch.mean(y_pred_fake) - real_label) ** 2) + \n                    torch.mean((y_pred_fake - torch.mean(y_pred) + real_label) ** 2))/2\n            errD.backward(retain_graph=True)\n            optimizerD.step()\n            lr_schedulerD.step(epoch)\n\n        \n        ############################\n        # (2) Update G network\n        ###########################\n        else:\n            netG.zero_grad()\n            real_images = real_images.to(device)\n            batch_size = real_images.size(0)\n            real_label = torch.full((batch_size, 1), y1, device=device)\n            fake_label = torch.full((batch_size, 1), y2, device=device)\n        \n            y_pred = netD(real_images)\n         \n            noise = torch.randn(batch_size, nz, 1, 1, device=device)\n            fake_images = netG(noise)\n            y_pred_fake = netD(fake_images)\n        \n            errG = (torch.mean((y_pred - torch.mean(y_pred_fake) + real_label) ** 2) + \n                    torch.mean((y_pred_fake - torch.mean(y_pred) - real_label) ** 2))/2\n            errG.backward()\n            optimizerG.step() \n            lr_schedulerG.step(epoch)\n        \n         \n        \n        \n        if (step+1) % 500 == 0:\n            print('[%d/%d][%d/%d] Loss_D: %.4f Loss_G: %.4f'\n                  % (epoch + 1, epochs, ii, len(train_loader),\n                     errD.item(), errG.item()))\n            \n        step += 1\n    show_generated_img()\n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"if not os.path.exists('../output_images'):\n    os.mkdir('../output_images')\nim_batch_size = 50\nn_images=10000\nfor i_batch in range(0, n_images, im_batch_size):\n    gen_z = torch.randn(im_batch_size, nz, 1, 1, device=device)\n    gen_images = netG(gen_z)\n    images = gen_images.to(\"cpu\").clone().detach()\n    images = images.numpy().transpose(0, 2, 3, 1)\n    for i_image in range(gen_images.size(0)):\n        save_image(gen_images[i_image, :, :, :], os.path.join('../output_images', f'image_{i_batch+i_image:05d}.png'))\n\n\nimport shutil\nshutil.make_archive('images', 'zip', '../output_images')","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}