{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\nimport os\nprint(os.listdir(\"../input\"))","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\nfrom torch.autograd import Variable\nimport os\nfrom tqdm import tqdm","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"device = torch.device(\"cuda\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"## Hyper paramatric\nlatent_dim = 100\nlr = 0.002\nimg_size = 64\nbatch_size = 32\nchannels = 3\nepochs = 220\n\n#Crop 64x64 image\ntransform = transforms.Compose([transforms.Resize(img_size),\n                                transforms.CenterCrop(img_size),\n                                transforms.ToTensor(),\n                                transforms.Normalize([0.5]*3,[0.5]*3)])\n# Dataloader\ntrain_data = datasets.ImageFolder('../input/all-dogs/', transform=transform)\ntrain_loader = torch.utils.data.DataLoader(train_data, shuffle=True,\n                                           batch_size=batch_size)\n\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Generator"},{"metadata":{"trusted":true},"cell_type":"code","source":"128 * img_size ** 2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"## Generator\nclass Generator(nn.Module):\n    def __init__(self):\n        super(Generator, self).__init__()\n\n        self.init_size = img_size // 4\n        self.l1 = nn.Sequential(nn.Linear(latent_dim, 128 * self.init_size ** 2))\n\n        self.conv_blocks = nn.Sequential(\n            nn.BatchNorm2d(128),\n            nn.Upsample(scale_factor=2),\n            nn.Conv2d(128, 128, 3, stride=1, padding=1),\n            nn.BatchNorm2d(128, 0.8),\n            nn.LeakyReLU(0.2, inplace=True),\n            nn.Upsample(scale_factor=2),\n            nn.Conv2d(128, 64, 3, stride=1, padding=1),\n            nn.BatchNorm2d(64, 0.8),\n            nn.LeakyReLU(0.2, inplace=True),\n            nn.Conv2d(64, channels, 3, stride=1, padding=1),\n            nn.Tanh(),\n        )\n\n    def forward(self, z):\n        out = self.l1(z)\n        out = out.view(out.shape[0], 128, self.init_size, self.init_size)\n        img = self.conv_blocks(out)\n        return img","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        def discriminator_block(in_filters, out_filters, bn=True):\n            block = [nn.Conv2d(in_filters, out_filters, 3, 2, 1), nn.LeakyReLU(0.2, inplace=True), nn.Dropout2d(0.25)]\n            if bn:\n                block.append(nn.BatchNorm2d(out_filters, 0.8))\n            return block\n\n        self.model = nn.Sequential(\n            *discriminator_block(channels, 16, bn=False),\n            *discriminator_block(16, 32),\n            *discriminator_block(32, 64),\n            *discriminator_block(64, 128),\n        )\n\n        # The height and width of downsampled image\n        ds_size = img_size // 2 ** 4\n        self.adv_layer = nn.Sequential(nn.Linear(128 * ds_size ** 2 , 1), nn.Sigmoid())\n\n    def forward(self, img):\n        #print (img.shape)\n        out = self.model(img)\n        out = out.view(out.shape[0], -1)\n        #out = nn.Sigmoid()(out)\n        #print (out.shape)\n        validity = self.adv_layer(out)\n\n        return validity","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def weights_init(m):\n    classname = m.__class__.__name__\n    if classname.find(\"Conv\") != -1:\n        torch.nn.init.normal_(m.weight.data, 0.0, 0.02)\n    elif classname.find(\"BatchNorm2d\") != -1:\n        torch.nn.init.normal_(m.weight.data, 1.0, 0.02)\n        torch.nn.init.constant_(m.bias.data, 0.0)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Initial G & D , Loss function, Optimizers"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Initialize generator and discriminator\ngenerator = Generator().cuda()\ndiscriminator = Discriminator().cuda()\n\n# weight initial\ngenerator.apply(weights_init)\ndiscriminator.apply(weights_init)\n\n# Loss function\nadversarial_loss = nn.BCELoss()\n\n# Optimizers\noptimizer_G = torch.optim.Adam(generator.parameters(), lr=lr, betas=(0.5, 0.999))\noptimizer_D = torch.optim.Adam(discriminator.parameters(), lr=lr, betas=(0.5, 0.999))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def generate_image(z):\n    #z = Variable(torch.cuda.FloatTensor((np.random.normal(0, 1, (1, latent_dim)))))\n    #z = torch.randn(im_batch_size, latent_dim, device=device)\n    gen_images = generator(z)\n    images = gen_images.to(\"cpu\").clone().detach()\n    images = images.numpy().transpose(0, 2, 3, 1)\n    return images","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Start Training"},{"metadata":{"trusted":true},"cell_type":"code","source":"ims_animation = []\nsample_interval_check = 300\nvalid_z = Variable(torch.cuda.FloatTensor((np.random.normal(0, 1, (1, latent_dim)))))\n\nfor epoch in range(epochs):\n    d_loss_avg = 0.\n    g_loss_avg = 0.\n    for i, (imgs, _) in enumerate(train_loader):\n        \n        # Adversarial ground truths\n        valid = Variable(torch.cuda.FloatTensor(imgs.shape[0], 1).fill_(1.0), requires_grad=False).cuda()\n        fake = Variable(torch.cuda.FloatTensor(imgs.shape[0], 1).fill_(0.0), requires_grad=False).cuda()\n        \n        real_imgs = Variable(imgs.type(torch.cuda.FloatTensor))\n\n        #  Train Generator\n        optimizer_G.zero_grad()\n        \n        # Sample noise as generator input\n        z = Variable(torch.cuda.FloatTensor((np.random.normal(0, 1, (imgs.shape[0], latent_dim)))))\n\n        # Generate a batch of images\n        gen_imgs = generator(z)\n\n        # Loss measures generator's ability to fool the discriminator\n        g_loss = adversarial_loss(discriminator(gen_imgs), valid)\n        g_loss.backward()\n        optimizer_G.step()\n        \n        #-------------------------------------------------------------\n        #  Train Discriminator\n        optimizer_D.zero_grad()\n\n        # Measure discriminator's ability to classify real from generated samples\n        real_loss = adversarial_loss(discriminator(real_imgs), valid)\n        fake_loss = adversarial_loss(discriminator(gen_imgs.detach()), fake)\n        d_loss = (real_loss + fake_loss) \n\n        d_loss.backward()\n        optimizer_D.step()\n        #---------------------------------------------------------------\n        #  Save loss\n        d_loss_avg += d_loss/len(train_loader)\n        g_loss_avg += g_loss/len(train_loader)\n\n        batches_done = epoch * len(train_loader) + i\n        if i % sample_interval_check == 0:  \n            ims_animation.append(generate_image(valid_z))\n            \n    print(\n        \"Epoch %d/%d [D loss: %f] [G loss: %f]\"\n        % (epoch, epochs, d_loss_avg.item(), g_loss_avg.item())\n        )","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Let's see the computer generation!(Animation!!!)"},{"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=50, blit=True, repeat_delay=1000,repeat = True)\n\nanim.save('generate_dog.gif',writer='ffmpeg')\n#print ('[[file:/aaa.gif]]')\n#plt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Submit file"},{"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    z = Variable(torch.cuda.FloatTensor((np.random.normal(0, 1, (im_batch_size, latent_dim)))))\n    #z = torch.randn(im_batch_size, latent_dim, device=device)\n    gen_images = generator(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":{"trusted":true},"cell_type":"code","source":"for i in range(10):\n    plt.imshow(images[i])\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","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}