{"cells":[{"metadata":{},"cell_type":"markdown","source":"## Loading Libraries"},{"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\n# Any results you write to the current directory are saved as output.\nimport argparse\nimport math\nimport sys\nimport matplotlib.pyplot as plt\n\nimport torchvision.transforms as transforms\nfrom torchvision.utils import save_image\n\nfrom torch.utils.data import DataLoader\nfrom torchvision import datasets\nfrom torch.autograd import Variable\n\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.autograd as autograd\nimport torch\nimport 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\nfrom torch.utils.data import Dataset, DataLoader\nfrom tqdm import tqdm_notebook as tqdm\nfrom time import time\nfrom PIL import Image\nimport torch.nn.parallel\nimport torch.optim as optim\nimport torch.utils.data\nimport torchvision\nimport torchvision.datasets as dset\nimport torchvision.transforms as transforms\nimport torchvision.utils as vutils\nfrom torch.autograd import Variable\nfrom torch import nn, optim\nimport torch.nn.functional as F\nfrom torchvision import datasets, transforms\nfrom torchvision.utils import save_image\nimport matplotlib.image as mpimg\nimport torchvision\nimport torchvision.datasets as dset\nfrom torch.utils.data import Dataset, DataLoader\nimport torchvision.transforms as transforms\nimport torchvision.utils as vutils\nfrom torch.autograd import Variable\nimport xml.etree.ElementTree as ET\nimport random\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def seed_everything(seed=42):\n    random.seed(seed)\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.backends.cudnn.deterministic = True\nseed_everything()\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class opt:\n    n_epochs = 1000\n    batch_size = 64\n    lr = 0.0002\n    b1= 0.5\n    b2 = 0.999\n    latent_dim=100\n    img_size = 64\n    channels = 3\n    n_critic = 60\n    clip_value = 0.01\n    sample_interval = 50","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class DataGenerator(Dataset):\n    def __init__(self, directory, transform=None, n_samples=np.inf):\n        self.directory = directory\n        self.transform = transform\n        self.n_samples = n_samples\n\n        self.samples = self._load_subfolders_images(directory)\n        if len(self.samples) == 0:\n            raise RuntimeError(\"Found 0 files in subfolders of: {}\".format(directory))\n\n    def _load_subfolders_images(self, root):\n        IMG_EXTENSIONS = (\n        '.jpg', '.jpeg', '.png', '.ppm', '.bmp', '.pgm', '.tif', '.tiff', '.webp')\n\n        def is_valid_file(x):\n            return torchvision.datasets.folder.has_file_allowed_extension(x, IMG_EXTENSIONS)\n\n        required_transforms = torchvision.transforms.Compose([\n                torchvision.transforms.Resize(64),\n                torchvision.transforms.CenterCrop(64),\n        ])\n\n        imgs = []\n        paths = []\n        for root, _, fnames in sorted(os.walk(root)):\n            for fname in sorted(fnames)[:min(self.n_samples, 999999999999999)]:\n                path = os.path.join(root, fname)\n                paths.append(path)\n\n        for path in paths:\n            if is_valid_file(path):\n                # Load image\n                img = dset.folder.default_loader(path)\n\n                # Get bounding boxes\n                annotation_basename = os.path.splitext(os.path.basename(path))[0]\n                annotation_dirname = next(\n                        dirname for dirname in os.listdir('../input/annotation/Annotation/') if\n                        dirname.startswith(annotation_basename.split('_')[0]))\n                annotation_filename = os.path.join('../input/annotation/Annotation/',\n                                                   annotation_dirname, annotation_basename)\n                tree = ET.parse(annotation_filename)\n                root = tree.getroot()\n                objects = root.findall('object')\n                for o in objects:\n                    bndbox = o.find('bndbox')\n                    xmin = int(bndbox.find('xmin').text)\n                    ymin = int(bndbox.find('ymin').text)\n                    xmax = int(bndbox.find('xmax').text)\n                    ymax = int(bndbox.find('ymax').text)\n                    \n                    \n                    w = np.min((xmax - xmin, ymax - ymin))\n                    bbox = (xmin-5, ymin-5, xmin+w+10, ymin+w+10)\n                    object_img = required_transforms(img.crop(bbox))\n                    object_img = object_img.resize((64,64), Image.ANTIALIAS)\n                    imgs.append(object_img)\n        return imgs\n\n    def __getitem__(self, index):\n        sample = self.samples[index]\n        \n        if self.transform is not None:\n            sample = self.transform(sample)\n            \n        return np.asarray(sample)\n    \n    def __len__(self):\n        return len(self.samples)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"%%time\ndatabase = '../input/all-dogs/all-dogs/'\n\ntransform = transforms.Compose([transforms.RandomHorizontalFlip(p=0.1),\n                                transforms.ToTensor(),\n                                transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])\ntransform1 = transforms.Compose([transforms.RandomHorizontalFlip(p=0.9),\n                                transforms.ToTensor(),\n                                transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])\n\ntrain_data1 = DataGenerator(database, transform=transform,n_samples=20579)\n#train_data2 = DataGenerator(database, transform=transform,n_samples=20579)\n#train_data = train_data1+ train_data2\ndataloader = torch.utils.data.DataLoader(train_data1, shuffle=True,batch_size=opt.batch_size, num_workers = 4)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x = next(iter(dataloader))\n#imgs = imgs.numpy().transpose(0, 2, 3, 1)\n\n\nfig = plt.figure(figsize=(25, 16))\nfor ii, img in enumerate(x[:32]):\n    ax = fig.add_subplot(4, 8, ii + 1, xticks=[], yticks=[])\n    \n    img = img.numpy().transpose(1, 2, 0)\n    plt.imshow((img +1.0)/2.0)\n    \n\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Parameters for Parsing"},{"metadata":{},"cell_type":"markdown","source":"## Configure for this problem"},{"metadata":{"trusted":true},"cell_type":"code","source":"img_shape = (opt.channels, opt.img_size, opt.img_size)\n\ncuda = True if torch.cuda.is_available() else False","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## generator"},{"metadata":{"trusted":true},"cell_type":"code","source":"class Generator(nn.Module):\n    def __init__(self):\n        super(Generator, self).__init__()\n\n        def block(in_feat, out_feat, normalize=True):\n            layers = [nn.Linear(in_feat, out_feat)]\n            if normalize:\n                layers.append(nn.BatchNorm1d(out_feat, 0.8))\n            layers.append(nn.LeakyReLU(0.2, inplace=True))\n            return layers\n\n        self.model = nn.Sequential(\n            *block(opt.latent_dim, 128, normalize=False),\n            *block(128, 256),\n            *block(256, 512),\n            *block(512, 1024),\n            nn.Linear(1024, int(np.prod(img_shape))),\n            nn.Tanh()\n        )\n\n    def forward(self, z):\n        img = self.model(z)\n        img = img.view(img.shape[0], *img_shape)\n        return img\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Discriminator"},{"metadata":{"trusted":true},"cell_type":"code","source":"class Discriminator(nn.Module):\n    def __init__(self):\n        super(Discriminator, self).__init__()\n\n        self.model = nn.Sequential(\n            nn.Linear(int(np.prod(img_shape)), 512),\n            nn.LeakyReLU(0.2, inplace=True),\n            nn.Linear(512, 256),\n            nn.LeakyReLU(0.2, inplace=True),\n            nn.Linear(256, 1),\n        )\n\n    def forward(self, img):\n        img_flat = img.view(img.shape[0], -1)\n        validity = self.model(img_flat)\n        return validity","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Co-efficient and power of regularization"},{"metadata":{"trusted":true},"cell_type":"code","source":"k = 2\np = 6","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Initialize Generator and Discriminator"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Initialize generator and discriminator\ngenerator = Generator()\ndiscriminator = Discriminator()\n\nif cuda:\n    generator.cuda()\n    discriminator.cuda()\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Configure data loader"},{"metadata":{},"cell_type":"markdown","source":"## Optimizers"},{"metadata":{"trusted":true},"cell_type":"code","source":"## This is to show the losses of the different loss functions\ndef show_losses():\n    fig, ax = plt.subplots()\n    plt.plot(d_losses, label='Discriminator', alpha=0.5)\n    plt.plot(g_losses, label='Generator', alpha=0.5)\n    #plt.title(title)\n    plt.legend()\n    #plt.savefig(filename)\n    plt.show()\n    plt.close()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"optimizer_G = torch.optim.Adam(generator.parameters(), lr=opt.lr, betas=(opt.b1, opt.b2))\noptimizer_D = torch.optim.Adam(discriminator.parameters(), lr=opt.lr, betas=(opt.b1, opt.b2))\n\nTensor = torch.cuda.FloatTensor if cuda else torch.FloatTensor","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Training"},{"metadata":{"trusted":true},"cell_type":"code","source":"if not os.path.exists('../output_images'):\n    os.mkdir('../output_images')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"batches_done = 0\ng_losses = []\nd_losses =[]\nfor epoch in range(opt.n_epochs):\n    for i, imgs in tqdm(enumerate(dataloader), total=len(dataloader)):\n\n        # Configure input\n        real_imgs = Variable(imgs.type(Tensor), requires_grad=True)\n\n        # ---------------------\n        #  Train Discriminator\n        # ---------------------\n\n        optimizer_D.zero_grad()\n\n        # Sample noise as generator input\n        z = Variable(Tensor(np.random.normal(0, 1, (imgs.shape[0], opt.latent_dim))))\n\n        # Generate a batch of images\n        fake_imgs = generator(z)\n\n        # Real images\n        real_validity = discriminator(real_imgs)\n        # Fake images\n        fake_validity = discriminator(fake_imgs)\n\n        # Compute W-div gradient penalty\n        real_grad_out = Variable(Tensor(real_imgs.size(0), 1).fill_(1.0), requires_grad=False)\n        real_grad = autograd.grad(\n            real_validity, real_imgs, real_grad_out, create_graph=True, retain_graph=True, only_inputs=True\n        )[0]\n        real_grad_norm = real_grad.view(real_grad.size(0), -1).pow(2).sum(1) ** (p / 2)\n\n        fake_grad_out = Variable(Tensor(fake_imgs.size(0), 1).fill_(1.0), requires_grad=False)\n        fake_grad = autograd.grad(\n            fake_validity, fake_imgs, fake_grad_out, create_graph=True, retain_graph=True, only_inputs=True\n        )[0]\n        fake_grad_norm = fake_grad.view(fake_grad.size(0), -1).pow(2).sum(1) ** (p / 2)\n\n        div_gp = torch.mean(real_grad_norm + fake_grad_norm) * k / 2\n\n        # Adversarial loss\n        d_loss = -torch.mean(real_validity) + torch.mean(fake_validity) + div_gp\n        #d_losses.append(d_loss)\n\n        d_loss.backward()\n        optimizer_D.step()\n\n        optimizer_G.zero_grad()\n\n        # Train the generator every n_critic steps\n        if i % opt.n_critic == 0:\n\n            # -----------------\n            #  Train Generator\n            # -----------------\n\n            # Generate a batch of images\n            fake_imgs = generator(z)\n            # Loss measures generator's ability to fool the discriminator\n            # Train on fake images\n            fake_validity = discriminator(fake_imgs)\n            g_loss = -torch.mean(fake_validity)\n            #g_losses.append(g_loss)\n\n            g_loss.backward()\n            optimizer_G.step()\n            \n            print(\n                \"[Epoch %d/%d] [Batch %d/%d] [D loss: %f] [G loss: %f]\"\n                % (epoch, opt.n_epochs, i, len(dataloader), d_loss.item(), g_loss.item())\n            )\n\n            if batches_done % opt.sample_interval == 0:\n                g_losses.append(g_loss)\n                d_losses.append(d_loss)\n                save_image(fake_imgs.data[:25], \"../output_images/%d.png\" % batches_done, nrow=5, normalize=True)\n\n            batches_done += opt.n_critic","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Show the images generated ?"},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_fake_images(z):\n    #gen_z = torch.randn(32, opt.latent_dim, 1, 1)\n    gen_images = generator(z)\n    images = gen_images.to(\"cpu\").clone().detach()\n    images = images.numpy().transpose(0, 2, 3, 1)\n    images = (images +1.0)/2.0\n    fig = plt.figure(figsize=(25, 16))\n    for ii, img in enumerate(images[:32]):\n        ax = fig.add_subplot(4, 8, ii+1 , xticks=[], yticks=[])\n        plt.imshow(img)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"show_losses()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"ims_animation = []\nif not os.path.exists('../output_images'):\n    os.mkdir('../output_images')\nim_batch_size = 64\nn_images=200\nfor i_batch in range(0, n_images, im_batch_size):\n    z = Variable(torch.cuda.FloatTensor((np.random.normal(0, 1, (im_batch_size, opt.latent_dim)))))\n    #z = torch.randn(im_batch_size, latent_dim, device=device)\n    plot_fake_images(z)\n    gen_images = generator(z)\n    images = gen_images.to(\"cpu\").clone().detach()\n    images = images.numpy().transpose(0, 2, 3, 1)\n    ims_animation.append(images)\n    for i_image in range(gen_images.size(0)):\n        save_image((gen_images[i_image, :, :, :]+1.0)/2.0, os.path.join('../output_images', f'image_{i_batch+i_image:05d}.png'))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import matplotlib.animation as animation\n#from matplotlib.animation import FuncAnimation\n\nfig = plt.figure() \n\nims = []\n#fig, ax = plt.subplots()\n#xdata, ydata = [], []\n#ln, = plt.plot([], [], 'ro',animated=True)\nfor j in range(len(ims_animation)):\n    im = plt.imshow(ims_animation[j][0],animated=True)\n    ims.append([im])\n    \nanim  = animation.ArtistAnimation(fig, ims, interval=5, blit=True, repeat_delay=10,repeat = True)\n\nanim.save('generate_dog.gif',writer='ffmpeg')","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}