{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "Deep Learning Models -- A collection of various deep learning architectures, models, and tips for TensorFlow and PyTorch in Jupyter Notebooks.\n", "- Author: Sebastian Raschka\n", "- GitHub Repository: https://github.com/rasbt/deeplearning-models" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Sebastian Raschka \n", "\n", "CPython 3.7.3\n", "IPython 7.9.0\n", "\n", "torch 1.7.0\n" ] } ], "source": [ "%load_ext watermark\n", "%watermark -a 'Sebastian Raschka' -v -p torch" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Runs on CPU or GPU (if available)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Model Zoo -- Wasserstein Generative Adversarial Networks (GAN)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Implementation of a very simple/rudimentary Wasserstein GAN using just fully connected layers.\n", "\n", "The Wasserstein GAN is based on the paper\n", "\n", "- Arjovsky, M., Chintala, S., & Bottou, L. (2017). Wasserstein GAN. arXiv preprint arXiv:1701.07875. (https://arxiv.org/abs/1701.07875)\n", "\n", "The main differences to a regular GAN are annotated in the code. In short, the main differences are \n", "\n", "1. Not using a sigmoid activation function and just using a linear output layer for the critic (i.e., discriminator).\n", "2. Using label -1 instead of 1 for the real images; using label 1 instead of 0 for fake images.\n", "3. Using Wasserstein distance (loss) for training both the critic and the generator.\n", "4. After each weight update, clip the weights to be in range [-0.1, 0.1].\n", "5. Train the critic 5 times for each generator training update.\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Imports" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import time\n", "import numpy as np\n", "import torch\n", "import torch.nn.functional as F\n", "from torchvision import datasets\n", "from torchvision import transforms\n", "import torch.nn as nn\n", "from torch.utils.data import DataLoader\n", "\n", "\n", "if torch.cuda.is_available():\n", " torch.backends.cudnn.deterministic = True" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Settings and Dataset" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Image batch dimensions: torch.Size([128, 1, 28, 28])\n", "Image label dimensions: torch.Size([128])\n" ] } ], "source": [ "##########################\n", "### SETTINGS\n", "##########################\n", "\n", "# Device\n", "device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n", "\n", "# Hyperparameters\n", "random_seed = 0\n", "generator_learning_rate = 0.0005\n", "discriminator_learning_rate = 0.0005\n", "NUM_EPOCHS = 100\n", "BATCH_SIZE = 128\n", "LATENT_DIM = 50\n", "IMG_SHAPE = (1, 28, 28)\n", "IMG_SIZE = 1\n", "for x in IMG_SHAPE:\n", " IMG_SIZE *= x\n", "\n", "## WGAN-specific settings\n", "num_iter_critic = 5\n", "weight_clip_value = 0.01\n", "\n", "\n", "\n", "##########################\n", "### MNIST DATASET\n", "##########################\n", "\n", "# Note transforms.ToTensor() scales input images\n", "# to 0-1 range\n", "train_dataset = datasets.MNIST(root='data', \n", " train=True, \n", " transform=transforms.ToTensor(),\n", " download=True)\n", "\n", "test_dataset = datasets.MNIST(root='data', \n", " train=False, \n", " transform=transforms.ToTensor())\n", "\n", "\n", "train_loader = DataLoader(dataset=train_dataset, \n", " batch_size=BATCH_SIZE, \n", " shuffle=True)\n", "\n", "test_loader = DataLoader(dataset=test_dataset, \n", " batch_size=BATCH_SIZE, \n", " shuffle=False)\n", "\n", "# Checking the dataset\n", "for images, labels in train_loader: \n", " print('Image batch dimensions:', images.shape)\n", " print('Image label dimensions:', labels.shape)\n", " break" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Model" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "##########################\n", "### MODEL\n", "##########################\n", "\n", "\n", "def wasserstein_loss(y_true, y_pred):\n", " return torch.mean(y_true * y_pred)\n", "\n", "\n", "class GAN(torch.nn.Module):\n", "\n", " def __init__(self):\n", " super(GAN, self).__init__()\n", " \n", " \n", " self.generator = nn.Sequential(\n", " nn.Linear(LATENT_DIM, 128),\n", " nn.LeakyReLU(inplace=True),\n", " #nn.Dropout(p=0.5),\n", " nn.Linear(128, IMG_SIZE),\n", " nn.Tanh()\n", " )\n", " \n", " self.discriminator = nn.Sequential(\n", " nn.Linear(IMG_SIZE, 128),\n", " nn.LeakyReLU(inplace=True),\n", " #nn.Dropout(p=0.5),\n", " nn.Linear(128, 1),\n", " #nn.Sigmoid() # WGAN should have linear activation\n", " )\n", "\n", " \n", " def generator_forward(self, z):\n", " img = self.generator(z)\n", " return img\n", " \n", " def discriminator_forward(self, img):\n", " pred = model.discriminator(img)\n", " return pred.view(-1)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "torch.manual_seed(random_seed)\n", "\n", "model = GAN()\n", "model = model.to(device)\n", "\n", "optim_gener = torch.optim.Adam(model.generator.parameters(), lr=generator_learning_rate)\n", "optim_discr = torch.optim.Adam(model.discriminator.parameters(), lr=discriminator_learning_rate)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Training" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Epoch: 001/100 | Batch 000/469 | Gen/Dis Loss: -0.0519/-0.2590\n", "Epoch: 001/100 | Batch 100/469 | Gen/Dis Loss: -2.3542/-0.7692\n", "Epoch: 001/100 | Batch 200/469 | Gen/Dis Loss: -2.0051/-0.4396\n", "Epoch: 001/100 | Batch 300/469 | Gen/Dis Loss: -2.0768/-0.3943\n", "Epoch: 001/100 | Batch 400/469 | Gen/Dis Loss: -2.1300/-0.2482\n", "Time elapsed: 0.23 min\n", "Epoch: 002/100 | Batch 000/469 | Gen/Dis Loss: -1.9071/-0.3102\n", "Epoch: 002/100 | Batch 100/469 | Gen/Dis Loss: -1.7146/-0.3059\n", "Epoch: 002/100 | Batch 200/469 | Gen/Dis Loss: -1.1119/-0.2778\n", "Epoch: 002/100 | Batch 300/469 | Gen/Dis Loss: -1.7026/-0.2407\n", "Epoch: 002/100 | Batch 400/469 | Gen/Dis Loss: -2.5018/-0.3091\n", "Time elapsed: 0.43 min\n", "Epoch: 003/100 | Batch 000/469 | Gen/Dis Loss: -2.3521/-0.3923\n", "Epoch: 003/100 | Batch 100/469 | Gen/Dis Loss: -2.4121/-0.0815\n", "Epoch: 003/100 | Batch 200/469 | Gen/Dis Loss: 0.7962/-0.4601\n", "Epoch: 003/100 | Batch 300/469 | Gen/Dis Loss: 0.4143/-0.2456\n", "Epoch: 003/100 | Batch 400/469 | Gen/Dis Loss: 0.5025/-0.1760\n", "Time elapsed: 0.63 min\n", "Epoch: 004/100 | Batch 000/469 | Gen/Dis Loss: 0.2936/-0.2024\n", "Epoch: 004/100 | Batch 100/469 | Gen/Dis Loss: 0.2512/-0.1884\n", "Epoch: 004/100 | Batch 200/469 | Gen/Dis Loss: 0.2651/-0.1717\n", "Epoch: 004/100 | Batch 300/469 | Gen/Dis Loss: 0.0757/-0.2229\n", "Epoch: 004/100 | Batch 400/469 | Gen/Dis Loss: 0.0861/-0.2141\n", "Time elapsed: 0.84 min\n", "Epoch: 005/100 | Batch 000/469 | Gen/Dis Loss: 0.0504/-0.2027\n", "Epoch: 005/100 | Batch 100/469 | Gen/Dis Loss: 0.1028/-0.1916\n", "Epoch: 005/100 | Batch 200/469 | Gen/Dis Loss: 0.0453/-0.2073\n", "Epoch: 005/100 | Batch 300/469 | Gen/Dis Loss: 0.1046/-0.2076\n", "Epoch: 005/100 | Batch 400/469 | Gen/Dis Loss: 0.0345/-0.2062\n", "Time elapsed: 1.05 min\n", "Epoch: 006/100 | Batch 000/469 | Gen/Dis Loss: 0.1727/-0.1755\n", "Epoch: 006/100 | Batch 100/469 | Gen/Dis Loss: 0.0390/-0.1798\n", "Epoch: 006/100 | Batch 200/469 | Gen/Dis Loss: 0.0152/-0.1769\n", "Epoch: 006/100 | Batch 300/469 | Gen/Dis Loss: 0.0941/-0.1842\n", "Epoch: 006/100 | Batch 400/469 | Gen/Dis Loss: 0.0499/-0.1918\n", "Time elapsed: 1.27 min\n", "Epoch: 007/100 | Batch 000/469 | Gen/Dis Loss: 0.0534/-0.1916\n", "Epoch: 007/100 | Batch 100/469 | Gen/Dis Loss: 0.0582/-0.1720\n", "Epoch: 007/100 | Batch 200/469 | Gen/Dis Loss: 0.0579/-0.1695\n", "Epoch: 007/100 | Batch 300/469 | Gen/Dis Loss: 0.0301/-0.1762\n", "Epoch: 007/100 | Batch 400/469 | Gen/Dis Loss: 0.0527/-0.1875\n", "Time elapsed: 1.49 min\n", "Epoch: 008/100 | Batch 000/469 | Gen/Dis Loss: 0.0047/-0.1685\n", "Epoch: 008/100 | Batch 100/469 | Gen/Dis Loss: 0.0790/-0.1731\n", "Epoch: 008/100 | Batch 200/469 | Gen/Dis Loss: 0.0452/-0.1532\n", "Epoch: 008/100 | Batch 300/469 | Gen/Dis Loss: 0.0667/-0.1664\n", "Epoch: 008/100 | Batch 400/469 | Gen/Dis Loss: 0.0671/-0.1472\n", "Time elapsed: 1.70 min\n", "Epoch: 009/100 | Batch 000/469 | Gen/Dis Loss: -0.1168/-0.1543\n", "Epoch: 009/100 | Batch 100/469 | Gen/Dis Loss: -0.0275/-0.1722\n", "Epoch: 009/100 | Batch 200/469 | Gen/Dis Loss: -0.0670/-0.1380\n", "Epoch: 009/100 | Batch 300/469 | Gen/Dis Loss: 0.0860/-0.1640\n", "Epoch: 009/100 | Batch 400/469 | Gen/Dis Loss: -0.0830/-0.1598\n", "Time elapsed: 1.92 min\n", "Epoch: 010/100 | Batch 000/469 | Gen/Dis Loss: -0.0486/-0.1543\n", "Epoch: 010/100 | Batch 100/469 | Gen/Dis Loss: -0.0919/-0.1593\n", "Epoch: 010/100 | Batch 200/469 | Gen/Dis Loss: -0.1185/-0.1507\n", "Epoch: 010/100 | Batch 300/469 | Gen/Dis Loss: 0.2264/-0.1845\n", "Epoch: 010/100 | Batch 400/469 | Gen/Dis Loss: -0.0288/-0.1592\n", "Time elapsed: 2.15 min\n", "Epoch: 011/100 | Batch 000/469 | Gen/Dis Loss: 0.0199/-0.1172\n", "Epoch: 011/100 | Batch 100/469 | Gen/Dis Loss: -0.0620/-0.1829\n", "Epoch: 011/100 | Batch 200/469 | Gen/Dis Loss: -0.2088/-0.1470\n", "Epoch: 011/100 | Batch 300/469 | Gen/Dis Loss: -0.2648/-0.1350\n", "Epoch: 011/100 | Batch 400/469 | Gen/Dis Loss: -0.3467/-0.1724\n", "Time elapsed: 2.37 min\n", "Epoch: 012/100 | Batch 000/469 | Gen/Dis Loss: -0.4080/-0.1568\n", "Epoch: 012/100 | Batch 100/469 | Gen/Dis Loss: -0.7657/-0.0293\n", "Epoch: 012/100 | Batch 200/469 | Gen/Dis Loss: -0.5468/-0.2377\n", "Epoch: 012/100 | Batch 300/469 | Gen/Dis Loss: -1.2844/-0.3580\n", "Epoch: 012/100 | Batch 400/469 | Gen/Dis Loss: -2.7551/-0.2147\n", "Time elapsed: 2.60 min\n", "Epoch: 013/100 | Batch 000/469 | Gen/Dis Loss: -1.7467/-0.0907\n", "Epoch: 013/100 | Batch 100/469 | Gen/Dis Loss: -2.7303/-0.0891\n", "Epoch: 013/100 | Batch 200/469 | Gen/Dis Loss: -2.6419/0.0203\n", "Epoch: 013/100 | Batch 300/469 | Gen/Dis Loss: -0.8218/-0.1482\n", "Epoch: 013/100 | Batch 400/469 | Gen/Dis Loss: -0.5836/-0.0678\n", "Time elapsed: 2.82 min\n", "Epoch: 014/100 | Batch 000/469 | Gen/Dis Loss: -0.3991/-0.0687\n", "Epoch: 014/100 | Batch 100/469 | Gen/Dis Loss: -0.5065/-0.0607\n", "Epoch: 014/100 | Batch 200/469 | Gen/Dis Loss: -0.5567/-0.0668\n", "Epoch: 014/100 | Batch 300/469 | Gen/Dis Loss: -0.6253/-0.0645\n", "Epoch: 014/100 | Batch 400/469 | Gen/Dis Loss: -0.3879/-0.0675\n", "Time elapsed: 3.04 min\n", "Epoch: 015/100 | Batch 000/469 | Gen/Dis Loss: -0.4144/-0.0552\n", "Epoch: 015/100 | Batch 100/469 | Gen/Dis Loss: -0.5014/-0.0597\n", "Epoch: 015/100 | Batch 200/469 | Gen/Dis Loss: -0.3966/-0.0677\n", "Epoch: 015/100 | Batch 300/469 | Gen/Dis Loss: -0.6472/-0.0579\n", "Epoch: 015/100 | Batch 400/469 | Gen/Dis Loss: -0.4149/-0.0627\n", "Time elapsed: 3.27 min\n", "Epoch: 016/100 | Batch 000/469 | Gen/Dis Loss: -0.2195/-0.0803\n", "Epoch: 016/100 | Batch 100/469 | Gen/Dis Loss: -0.3068/-0.0720\n", "Epoch: 016/100 | Batch 200/469 | Gen/Dis Loss: -0.2980/-0.0629\n", "Epoch: 016/100 | Batch 300/469 | Gen/Dis Loss: -0.3517/-0.0619\n", "Epoch: 016/100 | Batch 400/469 | Gen/Dis Loss: -0.2649/-0.0652\n", "Time elapsed: 3.49 min\n", "Epoch: 017/100 | Batch 000/469 | Gen/Dis Loss: -0.2006/-0.0646\n", "Epoch: 017/100 | Batch 100/469 | Gen/Dis Loss: -0.2398/-0.0810\n", "Epoch: 017/100 | Batch 200/469 | Gen/Dis Loss: -0.3902/-0.0692\n", "Epoch: 017/100 | Batch 300/469 | Gen/Dis Loss: -0.2892/-0.0965\n", "Epoch: 017/100 | Batch 400/469 | Gen/Dis Loss: -0.1373/-0.0793\n", "Time elapsed: 3.71 min\n", "Epoch: 018/100 | Batch 000/469 | Gen/Dis Loss: -0.6073/-0.0757\n", "Epoch: 018/100 | Batch 100/469 | Gen/Dis Loss: -1.0577/-0.1260\n", "Epoch: 018/100 | Batch 200/469 | Gen/Dis Loss: -1.6690/-0.2670\n", "Epoch: 018/100 | Batch 300/469 | Gen/Dis Loss: -0.1478/-0.3556\n", "Epoch: 018/100 | Batch 400/469 | Gen/Dis Loss: -0.9182/-0.1792\n", "Time elapsed: 3.94 min\n", "Epoch: 019/100 | Batch 000/469 | Gen/Dis Loss: 0.1504/-0.0533\n", "Epoch: 019/100 | Batch 100/469 | Gen/Dis Loss: -0.9131/-0.1791\n", "Epoch: 019/100 | Batch 200/469 | Gen/Dis Loss: -1.7046/-0.0276\n", "Epoch: 019/100 | Batch 300/469 | Gen/Dis Loss: -0.0904/-0.2029\n", "Epoch: 019/100 | Batch 400/469 | Gen/Dis Loss: -0.9669/-0.1121\n", "Time elapsed: 4.16 min\n", "Epoch: 020/100 | Batch 000/469 | Gen/Dis Loss: -2.1731/-0.0876\n", "Epoch: 020/100 | Batch 100/469 | Gen/Dis Loss: -0.1601/-0.0603\n", "Epoch: 020/100 | Batch 200/469 | Gen/Dis Loss: -0.5421/-0.1073\n", "Epoch: 020/100 | Batch 300/469 | Gen/Dis Loss: -0.2042/-0.0753\n", "Epoch: 020/100 | Batch 400/469 | Gen/Dis Loss: -0.3516/-0.0610\n", "Time elapsed: 4.38 min\n", "Epoch: 021/100 | Batch 000/469 | Gen/Dis Loss: -0.3735/-0.0515\n", "Epoch: 021/100 | Batch 100/469 | Gen/Dis Loss: -0.3435/-0.0578\n", "Epoch: 021/100 | Batch 200/469 | Gen/Dis Loss: -0.3828/-0.0577\n", "Epoch: 021/100 | Batch 300/469 | Gen/Dis Loss: -0.2621/-0.0567\n", "Epoch: 021/100 | Batch 400/469 | Gen/Dis Loss: -0.2977/-0.0625\n", "Time elapsed: 4.59 min\n", "Epoch: 022/100 | Batch 000/469 | Gen/Dis Loss: -0.3331/-0.0763\n", "Epoch: 022/100 | Batch 100/469 | Gen/Dis Loss: -0.1885/-0.0613\n", "Epoch: 022/100 | Batch 200/469 | Gen/Dis Loss: -0.2759/-0.0524\n", "Epoch: 022/100 | Batch 300/469 | Gen/Dis Loss: -0.5057/-0.0597\n", "Epoch: 022/100 | Batch 400/469 | Gen/Dis Loss: -0.2072/-0.0557\n", "Time elapsed: 4.82 min\n", "Epoch: 023/100 | Batch 000/469 | Gen/Dis Loss: -0.1932/-0.0640\n", "Epoch: 023/100 | Batch 100/469 | Gen/Dis Loss: -0.1665/-0.0632\n", "Epoch: 023/100 | Batch 200/469 | Gen/Dis Loss: -0.2458/-0.0522\n", "Epoch: 023/100 | Batch 300/469 | Gen/Dis Loss: -0.1301/-0.0617\n", "Epoch: 023/100 | Batch 400/469 | Gen/Dis Loss: -0.1029/-0.0619\n", "Time elapsed: 5.04 min\n", "Epoch: 024/100 | Batch 000/469 | Gen/Dis Loss: -0.1794/-0.0556\n", "Epoch: 024/100 | Batch 100/469 | Gen/Dis Loss: -0.1865/-0.0649\n", "Epoch: 024/100 | Batch 200/469 | Gen/Dis Loss: 0.9111/-0.0913\n", "Epoch: 024/100 | Batch 300/469 | Gen/Dis Loss: 0.7172/-0.1890\n", "Epoch: 024/100 | Batch 400/469 | Gen/Dis Loss: -1.7994/-0.2592\n", "Time elapsed: 5.26 min\n", "Epoch: 025/100 | Batch 000/469 | Gen/Dis Loss: -1.0366/-0.2872\n", "Epoch: 025/100 | Batch 100/469 | Gen/Dis Loss: -2.4762/-0.3209\n", "Epoch: 025/100 | Batch 200/469 | Gen/Dis Loss: -0.8765/-0.0749\n", "Epoch: 025/100 | Batch 300/469 | Gen/Dis Loss: -1.9202/-0.1480\n", "Epoch: 025/100 | Batch 400/469 | Gen/Dis Loss: -1.4956/-0.0559\n", "Time elapsed: 5.48 min\n", "Epoch: 026/100 | Batch 000/469 | Gen/Dis Loss: -0.8660/-0.0154\n", "Epoch: 026/100 | Batch 100/469 | Gen/Dis Loss: -0.5595/-0.0530\n", "Epoch: 026/100 | Batch 200/469 | Gen/Dis Loss: -0.4411/-0.0221\n", "Epoch: 026/100 | Batch 300/469 | Gen/Dis Loss: -0.9117/-0.0478\n", "Epoch: 026/100 | Batch 400/469 | Gen/Dis Loss: -0.7948/-0.0565\n", "Time elapsed: 5.70 min\n", "Epoch: 027/100 | Batch 000/469 | Gen/Dis Loss: -0.3556/-0.0010\n", "Epoch: 027/100 | Batch 100/469 | Gen/Dis Loss: -0.6643/-0.0375\n", "Epoch: 027/100 | Batch 200/469 | Gen/Dis Loss: -0.8789/-0.0222\n", "Epoch: 027/100 | Batch 300/469 | Gen/Dis Loss: -0.6258/-0.0236\n", "Epoch: 027/100 | Batch 400/469 | Gen/Dis Loss: -0.6097/-0.0116\n", "Time elapsed: 5.93 min\n", "Epoch: 028/100 | Batch 000/469 | Gen/Dis Loss: -0.5124/-0.0151\n", "Epoch: 028/100 | Batch 100/469 | Gen/Dis Loss: -0.3840/-0.0237\n", "Epoch: 028/100 | Batch 200/469 | Gen/Dis Loss: -0.1995/-0.0381\n", "Epoch: 028/100 | Batch 300/469 | Gen/Dis Loss: -0.1822/-0.0293\n", "Epoch: 028/100 | Batch 400/469 | Gen/Dis Loss: -0.1177/-0.0334\n", "Time elapsed: 6.15 min\n", "Epoch: 029/100 | Batch 000/469 | Gen/Dis Loss: -0.1504/-0.0339\n", "Epoch: 029/100 | Batch 100/469 | Gen/Dis Loss: -0.0851/-0.0310\n", "Epoch: 029/100 | Batch 200/469 | Gen/Dis Loss: -0.0847/-0.0295\n", "Epoch: 029/100 | Batch 300/469 | Gen/Dis Loss: -0.8884/-0.0660\n", "Epoch: 029/100 | Batch 400/469 | Gen/Dis Loss: -1.3062/-0.0932\n", "Time elapsed: 6.37 min\n", "Epoch: 030/100 | Batch 000/469 | Gen/Dis Loss: -1.6727/-0.0356\n", "Epoch: 030/100 | Batch 100/469 | Gen/Dis Loss: -0.9586/-0.1639\n", "Epoch: 030/100 | Batch 200/469 | Gen/Dis Loss: -1.1727/-0.1016\n", "Epoch: 030/100 | Batch 300/469 | Gen/Dis Loss: -1.7424/-0.1240\n", "Epoch: 030/100 | Batch 400/469 | Gen/Dis Loss: -1.9941/-0.1225\n", "Time elapsed: 6.60 min\n", "Epoch: 031/100 | Batch 000/469 | Gen/Dis Loss: -2.3835/-0.0252\n", "Epoch: 031/100 | Batch 100/469 | Gen/Dis Loss: -1.2459/-0.0767\n", "Epoch: 031/100 | Batch 200/469 | Gen/Dis Loss: -0.9153/-0.1023\n", "Epoch: 031/100 | Batch 300/469 | Gen/Dis Loss: -0.5369/-0.0466\n", "Epoch: 031/100 | Batch 400/469 | Gen/Dis Loss: -0.8644/-0.0314\n", "Time elapsed: 6.82 min\n", "Epoch: 032/100 | Batch 000/469 | Gen/Dis Loss: -0.1392/-0.0423\n", "Epoch: 032/100 | Batch 100/469 | Gen/Dis Loss: -0.2171/-0.0870\n", "Epoch: 032/100 | Batch 200/469 | Gen/Dis Loss: -0.1663/-0.0909\n", "Epoch: 032/100 | Batch 300/469 | Gen/Dis Loss: -0.1990/-0.0905\n", "Epoch: 032/100 | Batch 400/469 | Gen/Dis Loss: -0.1221/-0.0977\n", "Time elapsed: 7.02 min\n", "Epoch: 033/100 | Batch 000/469 | Gen/Dis Loss: -0.2224/-0.1383\n", "Epoch: 033/100 | Batch 100/469 | Gen/Dis Loss: -1.0020/-0.1380\n", "Epoch: 033/100 | Batch 200/469 | Gen/Dis Loss: -0.4386/-0.0438\n", "Epoch: 033/100 | Batch 300/469 | Gen/Dis Loss: -1.2815/-0.0513\n", "Epoch: 033/100 | Batch 400/469 | Gen/Dis Loss: -2.0354/0.0270\n", "Time elapsed: 7.23 min\n", "Epoch: 034/100 | Batch 000/469 | Gen/Dis Loss: -2.7790/-0.1876\n", "Epoch: 034/100 | Batch 100/469 | Gen/Dis Loss: -3.9126/-0.0100\n", "Epoch: 034/100 | Batch 200/469 | Gen/Dis Loss: -3.3824/-0.0662\n", "Epoch: 034/100 | Batch 300/469 | Gen/Dis Loss: -3.0964/-0.0396\n", "Epoch: 034/100 | Batch 400/469 | Gen/Dis Loss: -1.0305/-0.1450\n", "Time elapsed: 7.44 min\n", "Epoch: 035/100 | Batch 000/469 | Gen/Dis Loss: -1.6022/-0.1637\n", "Epoch: 035/100 | Batch 100/469 | Gen/Dis Loss: -1.5141/-0.0263\n", "Epoch: 035/100 | Batch 200/469 | Gen/Dis Loss: -0.4072/-0.0307\n", "Epoch: 035/100 | Batch 300/469 | Gen/Dis Loss: -0.2337/0.0006\n", "Epoch: 035/100 | Batch 400/469 | Gen/Dis Loss: -0.3348/-0.0346\n", "Time elapsed: 7.64 min\n", "Epoch: 036/100 | Batch 000/469 | Gen/Dis Loss: -0.7794/-0.0191\n", "Epoch: 036/100 | Batch 100/469 | Gen/Dis Loss: -0.4455/-0.0138\n", "Epoch: 036/100 | Batch 200/469 | Gen/Dis Loss: -0.0616/-0.0118\n", "Epoch: 036/100 | Batch 300/469 | Gen/Dis Loss: 0.0603/-0.0156\n", "Epoch: 036/100 | Batch 400/469 | Gen/Dis Loss: 0.1056/-0.0125\n", "Time elapsed: 7.86 min\n", "Epoch: 037/100 | Batch 000/469 | Gen/Dis Loss: 0.0759/-0.0142\n", "Epoch: 037/100 | Batch 100/469 | Gen/Dis Loss: 0.1198/-0.0079\n", "Epoch: 037/100 | Batch 200/469 | Gen/Dis Loss: 0.0732/-0.0058\n", "Epoch: 037/100 | Batch 300/469 | Gen/Dis Loss: 0.0837/-0.0093\n", "Epoch: 037/100 | Batch 400/469 | Gen/Dis Loss: 0.1131/-0.0061\n", "Time elapsed: 8.08 min\n", "Epoch: 038/100 | Batch 000/469 | Gen/Dis Loss: 0.0629/-0.0076\n", "Epoch: 038/100 | Batch 100/469 | Gen/Dis Loss: 0.0766/-0.0072\n", "Epoch: 038/100 | Batch 200/469 | Gen/Dis Loss: 0.0196/-0.0092\n", "Epoch: 038/100 | Batch 300/469 | Gen/Dis Loss: 0.1233/-0.0053\n", "Epoch: 038/100 | Batch 400/469 | Gen/Dis Loss: 0.0524/-0.0143\n", "Time elapsed: 8.30 min\n", "Epoch: 039/100 | Batch 000/469 | Gen/Dis Loss: 0.0693/-0.0063\n", "Epoch: 039/100 | Batch 100/469 | Gen/Dis Loss: -1.8572/-0.1096\n", "Epoch: 039/100 | Batch 200/469 | Gen/Dis Loss: -0.9776/-0.0526\n", "Epoch: 039/100 | Batch 300/469 | Gen/Dis Loss: -1.2697/-0.1387\n", "Epoch: 039/100 | Batch 400/469 | Gen/Dis Loss: -1.3924/-0.1120\n", "Time elapsed: 8.52 min\n", "Epoch: 040/100 | Batch 000/469 | Gen/Dis Loss: -1.8005/-0.0139\n", "Epoch: 040/100 | Batch 100/469 | Gen/Dis Loss: -1.1539/-0.1221\n", "Epoch: 040/100 | Batch 200/469 | Gen/Dis Loss: -0.1513/-0.0415\n", "Epoch: 040/100 | Batch 300/469 | Gen/Dis Loss: -2.2896/-0.0223\n", "Epoch: 040/100 | Batch 400/469 | Gen/Dis Loss: -2.7501/-0.0865\n", "Time elapsed: 8.74 min\n", "Epoch: 041/100 | Batch 000/469 | Gen/Dis Loss: -0.8860/-0.0310\n", "Epoch: 041/100 | Batch 100/469 | Gen/Dis Loss: -1.0508/-0.0627\n", "Epoch: 041/100 | Batch 200/469 | Gen/Dis Loss: -1.2014/-0.2148\n", "Epoch: 041/100 | Batch 300/469 | Gen/Dis Loss: -0.8424/-0.1071\n", "Epoch: 041/100 | Batch 400/469 | Gen/Dis Loss: -0.9346/-0.0857\n", "Time elapsed: 8.97 min\n", "Epoch: 042/100 | Batch 000/469 | Gen/Dis Loss: -0.1562/-0.0464\n", "Epoch: 042/100 | Batch 100/469 | Gen/Dis Loss: -0.2710/-0.1163\n", "Epoch: 042/100 | Batch 200/469 | Gen/Dis Loss: -1.1959/0.0357\n", "Epoch: 042/100 | Batch 300/469 | Gen/Dis Loss: -0.3887/-0.0603\n", "Epoch: 042/100 | Batch 400/469 | Gen/Dis Loss: -0.1826/-0.2110\n", "Time elapsed: 9.19 min\n", "Epoch: 043/100 | Batch 000/469 | Gen/Dis Loss: -2.1735/0.0343\n", "Epoch: 043/100 | Batch 100/469 | Gen/Dis Loss: -0.3043/-0.1190\n", "Epoch: 043/100 | Batch 200/469 | Gen/Dis Loss: -0.6211/-0.0375\n", "Epoch: 043/100 | Batch 300/469 | Gen/Dis Loss: -0.1019/-0.0665\n", "Epoch: 043/100 | Batch 400/469 | Gen/Dis Loss: 0.0640/-0.0602\n", "Time elapsed: 9.41 min\n", "Epoch: 044/100 | Batch 000/469 | Gen/Dis Loss: 0.1020/-0.0610\n", "Epoch: 044/100 | Batch 100/469 | Gen/Dis Loss: 0.0250/-0.0760\n", "Epoch: 044/100 | Batch 200/469 | Gen/Dis Loss: 0.1465/-0.0735\n", "Epoch: 044/100 | Batch 300/469 | Gen/Dis Loss: -0.1694/-0.0410\n", "Epoch: 044/100 | Batch 400/469 | Gen/Dis Loss: 0.1538/-0.0760\n", "Time elapsed: 9.63 min\n", "Epoch: 045/100 | Batch 000/469 | Gen/Dis Loss: 0.1115/-0.0883\n", "Epoch: 045/100 | Batch 100/469 | Gen/Dis Loss: 0.3155/-0.0957\n", "Epoch: 045/100 | Batch 200/469 | Gen/Dis Loss: -0.0393/-0.0787\n", "Epoch: 045/100 | Batch 300/469 | Gen/Dis Loss: 0.1622/-0.0675\n", "Epoch: 045/100 | Batch 400/469 | Gen/Dis Loss: -0.1042/-0.0991\n", "Time elapsed: 9.86 min\n", "Epoch: 046/100 | Batch 000/469 | Gen/Dis Loss: 0.4376/-0.0861\n", "Epoch: 046/100 | Batch 100/469 | Gen/Dis Loss: 0.6087/-0.0942\n", "Epoch: 046/100 | Batch 200/469 | Gen/Dis Loss: 0.7479/-0.0922\n", "Epoch: 046/100 | Batch 300/469 | Gen/Dis Loss: 0.8891/-0.1128\n", "Epoch: 046/100 | Batch 400/469 | Gen/Dis Loss: 0.1424/-0.1214\n", "Time elapsed: 10.08 min\n", "Epoch: 047/100 | Batch 000/469 | Gen/Dis Loss: -0.0025/-0.0809\n", "Epoch: 047/100 | Batch 100/469 | Gen/Dis Loss: 0.2443/-0.0811\n", "Epoch: 047/100 | Batch 200/469 | Gen/Dis Loss: 0.5209/-0.1100\n", "Epoch: 047/100 | Batch 300/469 | Gen/Dis Loss: 0.7354/-0.0890\n", "Epoch: 047/100 | Batch 400/469 | Gen/Dis Loss: -0.1064/-0.0592\n", "Time elapsed: 10.30 min\n", "Epoch: 048/100 | Batch 000/469 | Gen/Dis Loss: -0.3177/-0.0673\n", "Epoch: 048/100 | Batch 100/469 | Gen/Dis Loss: -0.0627/-0.0461\n", "Epoch: 048/100 | Batch 200/469 | Gen/Dis Loss: -0.2542/-0.0726\n", "Epoch: 048/100 | Batch 300/469 | Gen/Dis Loss: -0.2590/-0.0624\n", "Epoch: 048/100 | Batch 400/469 | Gen/Dis Loss: -0.2193/-0.0638\n", "Time elapsed: 10.52 min\n", "Epoch: 049/100 | Batch 000/469 | Gen/Dis Loss: -0.1196/-0.0703\n", "Epoch: 049/100 | Batch 100/469 | Gen/Dis Loss: -0.2319/-0.0537\n", "Epoch: 049/100 | Batch 200/469 | Gen/Dis Loss: -0.0904/-0.0592\n", "Epoch: 049/100 | Batch 300/469 | Gen/Dis Loss: -0.0149/-0.0473\n", "Epoch: 049/100 | Batch 400/469 | Gen/Dis Loss: -0.1192/-0.1009\n", "Time elapsed: 10.75 min\n", "Epoch: 050/100 | Batch 000/469 | Gen/Dis Loss: -0.0885/-0.0917\n", "Epoch: 050/100 | Batch 100/469 | Gen/Dis Loss: -0.0275/-0.0468\n", "Epoch: 050/100 | Batch 200/469 | Gen/Dis Loss: -0.2900/-0.0846\n", "Epoch: 050/100 | Batch 300/469 | Gen/Dis Loss: -0.4733/-0.0905\n", "Epoch: 050/100 | Batch 400/469 | Gen/Dis Loss: -0.6236/-0.0697\n", "Time elapsed: 10.97 min\n", "Epoch: 051/100 | Batch 000/469 | Gen/Dis Loss: -0.3837/-0.2036\n", "Epoch: 051/100 | Batch 100/469 | Gen/Dis Loss: -0.9772/-0.1589\n", "Epoch: 051/100 | Batch 200/469 | Gen/Dis Loss: -0.8187/-0.1831\n", "Epoch: 051/100 | Batch 300/469 | Gen/Dis Loss: -0.9445/-0.0874\n", "Epoch: 051/100 | Batch 400/469 | Gen/Dis Loss: -1.4658/-0.0436\n", "Time elapsed: 11.19 min\n", "Epoch: 052/100 | Batch 000/469 | Gen/Dis Loss: -1.3324/-0.0003\n", "Epoch: 052/100 | Batch 100/469 | Gen/Dis Loss: -1.0217/-0.0906\n", "Epoch: 052/100 | Batch 200/469 | Gen/Dis Loss: -0.8700/-0.0581\n", "Epoch: 052/100 | Batch 300/469 | Gen/Dis Loss: -0.5518/-0.0399\n", "Epoch: 052/100 | Batch 400/469 | Gen/Dis Loss: -0.8691/-0.0255\n", "Time elapsed: 11.41 min\n", "Epoch: 053/100 | Batch 000/469 | Gen/Dis Loss: -0.5911/-0.0867\n", "Epoch: 053/100 | Batch 100/469 | Gen/Dis Loss: -0.9219/-0.0518\n", "Epoch: 053/100 | Batch 200/469 | Gen/Dis Loss: -0.8089/-0.0686\n", "Epoch: 053/100 | Batch 300/469 | Gen/Dis Loss: -0.9910/0.0054\n", "Epoch: 053/100 | Batch 400/469 | Gen/Dis Loss: -1.1288/-0.0324\n", "Time elapsed: 11.64 min\n", "Epoch: 054/100 | Batch 000/469 | Gen/Dis Loss: -1.4742/-0.0809\n", "Epoch: 054/100 | Batch 100/469 | Gen/Dis Loss: -1.5307/-0.0613\n", "Epoch: 054/100 | Batch 200/469 | Gen/Dis Loss: -2.2387/0.0006\n", "Epoch: 054/100 | Batch 300/469 | Gen/Dis Loss: -0.7110/-0.0670\n", "Epoch: 054/100 | Batch 400/469 | Gen/Dis Loss: -0.8786/-0.0557\n", "Time elapsed: 11.86 min\n", "Epoch: 055/100 | Batch 000/469 | Gen/Dis Loss: -0.6164/-0.0741\n", "Epoch: 055/100 | Batch 100/469 | Gen/Dis Loss: -0.2841/-0.0537\n", "Epoch: 055/100 | Batch 200/469 | Gen/Dis Loss: -1.0291/-0.0281\n", "Epoch: 055/100 | Batch 300/469 | Gen/Dis Loss: -1.4945/-0.0017\n", "Epoch: 055/100 | Batch 400/469 | Gen/Dis Loss: -1.1892/-0.0073\n", "Time elapsed: 12.08 min\n", "Epoch: 056/100 | Batch 000/469 | Gen/Dis Loss: -1.0694/-0.0216\n", "Epoch: 056/100 | Batch 100/469 | Gen/Dis Loss: -1.1426/-0.0204\n", "Epoch: 056/100 | Batch 200/469 | Gen/Dis Loss: -2.2945/-0.0640\n", "Epoch: 056/100 | Batch 300/469 | Gen/Dis Loss: -1.1074/-0.0463\n", "Epoch: 056/100 | Batch 400/469 | Gen/Dis Loss: -0.7330/-0.0245\n", "Time elapsed: 12.30 min\n", "Epoch: 057/100 | Batch 000/469 | Gen/Dis Loss: -0.5903/-0.0049\n", "Epoch: 057/100 | Batch 100/469 | Gen/Dis Loss: -0.8674/-0.0973\n", "Epoch: 057/100 | Batch 200/469 | Gen/Dis Loss: -0.5229/0.0020\n", "Epoch: 057/100 | Batch 300/469 | Gen/Dis Loss: -0.2379/0.0131\n", "Epoch: 057/100 | Batch 400/469 | Gen/Dis Loss: -0.4983/-0.0531\n", "Time elapsed: 12.52 min\n", "Epoch: 058/100 | Batch 000/469 | Gen/Dis Loss: -0.5298/-0.0460\n", "Epoch: 058/100 | Batch 100/469 | Gen/Dis Loss: -1.3276/-0.0886\n", "Epoch: 058/100 | Batch 200/469 | Gen/Dis Loss: -2.1372/-0.0680\n", "Epoch: 058/100 | Batch 300/469 | Gen/Dis Loss: -1.3350/-0.0856\n", "Epoch: 058/100 | Batch 400/469 | Gen/Dis Loss: -0.5794/-0.0047\n", "Time elapsed: 12.75 min\n", "Epoch: 059/100 | Batch 000/469 | Gen/Dis Loss: -1.5859/-0.0384\n", "Epoch: 059/100 | Batch 100/469 | Gen/Dis Loss: -0.6838/-0.0324\n", "Epoch: 059/100 | Batch 200/469 | Gen/Dis Loss: 0.1981/-0.0412\n", "Epoch: 059/100 | Batch 300/469 | Gen/Dis Loss: 0.0314/-0.0073\n", "Epoch: 059/100 | Batch 400/469 | Gen/Dis Loss: 0.2410/-0.0020\n", "Time elapsed: 12.97 min\n", "Epoch: 060/100 | Batch 000/469 | Gen/Dis Loss: -0.1257/0.0094\n", "Epoch: 060/100 | Batch 100/469 | Gen/Dis Loss: -0.2361/-0.0420\n", "Epoch: 060/100 | Batch 200/469 | Gen/Dis Loss: -0.0831/-0.0100\n", "Epoch: 060/100 | Batch 300/469 | Gen/Dis Loss: 0.7063/-0.0007\n", "Epoch: 060/100 | Batch 400/469 | Gen/Dis Loss: 0.6816/0.0040\n", "Time elapsed: 13.19 min\n", "Epoch: 061/100 | Batch 000/469 | Gen/Dis Loss: 0.3744/-0.0265\n", "Epoch: 061/100 | Batch 100/469 | Gen/Dis Loss: 0.8184/-0.0424\n", "Epoch: 061/100 | Batch 200/469 | Gen/Dis Loss: 0.2331/-0.0215\n", "Epoch: 061/100 | Batch 300/469 | Gen/Dis Loss: 0.3921/-0.0157\n", "Epoch: 061/100 | Batch 400/469 | Gen/Dis Loss: 0.2618/-0.0102\n", "Time elapsed: 13.41 min\n", "Epoch: 062/100 | Batch 000/469 | Gen/Dis Loss: 0.0962/-0.0024\n", "Epoch: 062/100 | Batch 100/469 | Gen/Dis Loss: 0.1103/-0.0164\n", "Epoch: 062/100 | Batch 200/469 | Gen/Dis Loss: 0.1266/-0.0099\n", "Epoch: 062/100 | Batch 300/469 | Gen/Dis Loss: 0.3365/-0.0050\n", "Epoch: 062/100 | Batch 400/469 | Gen/Dis Loss: 0.4718/-0.0315\n", "Time elapsed: 13.63 min\n", "Epoch: 063/100 | Batch 000/469 | Gen/Dis Loss: 0.6478/-0.0329\n", "Epoch: 063/100 | Batch 100/469 | Gen/Dis Loss: 0.1355/-0.0061\n", "Epoch: 063/100 | Batch 200/469 | Gen/Dis Loss: 0.0004/-0.0016\n", "Epoch: 063/100 | Batch 300/469 | Gen/Dis Loss: -0.0462/-0.0090\n", "Epoch: 063/100 | Batch 400/469 | Gen/Dis Loss: 0.1347/-0.0029\n", "Time elapsed: 13.85 min\n", "Epoch: 064/100 | Batch 000/469 | Gen/Dis Loss: 0.1120/-0.0024\n", "Epoch: 064/100 | Batch 100/469 | Gen/Dis Loss: 0.1123/-0.0097\n", "Epoch: 064/100 | Batch 200/469 | Gen/Dis Loss: -0.0541/0.0003\n", "Epoch: 064/100 | Batch 300/469 | Gen/Dis Loss: -0.0160/-0.0031\n", "Epoch: 064/100 | Batch 400/469 | Gen/Dis Loss: 0.0686/-0.0012\n", "Time elapsed: 14.08 min\n", "Epoch: 065/100 | Batch 000/469 | Gen/Dis Loss: 0.0104/-0.0068\n", "Epoch: 065/100 | Batch 100/469 | Gen/Dis Loss: 0.0641/-0.0050\n", "Epoch: 065/100 | Batch 200/469 | Gen/Dis Loss: 0.4558/-0.0234\n", "Epoch: 065/100 | Batch 300/469 | Gen/Dis Loss: 0.7145/-0.1104\n", "Epoch: 065/100 | Batch 400/469 | Gen/Dis Loss: 1.1978/-0.1029\n", "Time elapsed: 14.30 min\n", "Epoch: 066/100 | Batch 000/469 | Gen/Dis Loss: 0.1297/-0.0332\n", "Epoch: 066/100 | Batch 100/469 | Gen/Dis Loss: 0.7369/-0.0627\n", "Epoch: 066/100 | Batch 200/469 | Gen/Dis Loss: 0.9838/-0.0302\n", "Epoch: 066/100 | Batch 300/469 | Gen/Dis Loss: 2.6508/-0.1789\n", "Epoch: 066/100 | Batch 400/469 | Gen/Dis Loss: 0.7896/-0.1680\n", "Time elapsed: 14.53 min\n", "Epoch: 067/100 | Batch 000/469 | Gen/Dis Loss: 1.9006/0.0303\n", "Epoch: 067/100 | Batch 100/469 | Gen/Dis Loss: 1.6707/-0.0282\n", "Epoch: 067/100 | Batch 200/469 | Gen/Dis Loss: -0.1290/-0.0148\n", "Epoch: 067/100 | Batch 300/469 | Gen/Dis Loss: -0.7942/-0.0258\n", "Epoch: 067/100 | Batch 400/469 | Gen/Dis Loss: -0.4003/-0.0190\n", "Time elapsed: 14.73 min\n", "Epoch: 068/100 | Batch 000/469 | Gen/Dis Loss: -0.6044/-0.0053\n", "Epoch: 068/100 | Batch 100/469 | Gen/Dis Loss: -0.6929/-0.0031\n", "Epoch: 068/100 | Batch 200/469 | Gen/Dis Loss: -0.4085/0.0064\n", "Epoch: 068/100 | Batch 300/469 | Gen/Dis Loss: -0.5156/-0.0066\n", "Epoch: 068/100 | Batch 400/469 | Gen/Dis Loss: 0.1810/0.0041\n", "Time elapsed: 14.93 min\n", "Epoch: 069/100 | Batch 000/469 | Gen/Dis Loss: -0.2750/-0.0059\n", "Epoch: 069/100 | Batch 100/469 | Gen/Dis Loss: -0.0665/-0.0011\n", "Epoch: 069/100 | Batch 200/469 | Gen/Dis Loss: -0.0914/-0.0007\n", "Epoch: 069/100 | Batch 300/469 | Gen/Dis Loss: -0.0312/-0.0001\n", "Epoch: 069/100 | Batch 400/469 | Gen/Dis Loss: -0.0557/-0.0002\n", "Time elapsed: 15.13 min\n", "Epoch: 070/100 | Batch 000/469 | Gen/Dis Loss: -0.0603/0.0003\n", "Epoch: 070/100 | Batch 100/469 | Gen/Dis Loss: 0.0181/0.0018\n", "Epoch: 070/100 | Batch 200/469 | Gen/Dis Loss: -0.0190/0.0002\n", "Epoch: 070/100 | Batch 300/469 | Gen/Dis Loss: -0.0765/0.0006\n", "Epoch: 070/100 | Batch 400/469 | Gen/Dis Loss: -0.2264/-0.0128\n", "Time elapsed: 15.33 min\n", "Epoch: 071/100 | Batch 000/469 | Gen/Dis Loss: -0.0976/-0.0021\n", "Epoch: 071/100 | Batch 100/469 | Gen/Dis Loss: -0.2573/0.0020\n", "Epoch: 071/100 | Batch 200/469 | Gen/Dis Loss: 0.0093/-0.0019\n", "Epoch: 071/100 | Batch 300/469 | Gen/Dis Loss: 0.0989/-0.0047\n", "Epoch: 071/100 | Batch 400/469 | Gen/Dis Loss: -0.1550/-0.0051\n", "Time elapsed: 15.54 min\n", "Epoch: 072/100 | Batch 000/469 | Gen/Dis Loss: -0.0617/-0.0015\n", "Epoch: 072/100 | Batch 100/469 | Gen/Dis Loss: -0.0673/-0.0039\n", "Epoch: 072/100 | Batch 200/469 | Gen/Dis Loss: -0.1668/-0.0009\n", "Epoch: 072/100 | Batch 300/469 | Gen/Dis Loss: -0.1308/-0.0009\n", "Epoch: 072/100 | Batch 400/469 | Gen/Dis Loss: 0.5936/-0.0459\n", "Time elapsed: 15.76 min\n", "Epoch: 073/100 | Batch 000/469 | Gen/Dis Loss: 0.4555/-0.0955\n", "Epoch: 073/100 | Batch 100/469 | Gen/Dis Loss: -0.5352/-0.0407\n", "Epoch: 073/100 | Batch 200/469 | Gen/Dis Loss: -1.0010/-0.0430\n", "Epoch: 073/100 | Batch 300/469 | Gen/Dis Loss: -0.3312/-0.0211\n", "Epoch: 073/100 | Batch 400/469 | Gen/Dis Loss: -0.6744/-0.0705\n", "Time elapsed: 15.98 min\n", "Epoch: 074/100 | Batch 000/469 | Gen/Dis Loss: -0.2362/-0.0283\n", "Epoch: 074/100 | Batch 100/469 | Gen/Dis Loss: -0.5404/0.0122\n", "Epoch: 074/100 | Batch 200/469 | Gen/Dis Loss: -0.0699/0.0050\n", "Epoch: 074/100 | Batch 300/469 | Gen/Dis Loss: -0.3420/-0.0109\n", "Epoch: 074/100 | Batch 400/469 | Gen/Dis Loss: -0.2500/-0.0434\n", "Time elapsed: 16.20 min\n", "Epoch: 075/100 | Batch 000/469 | Gen/Dis Loss: 0.2550/-0.0134\n", "Epoch: 075/100 | Batch 100/469 | Gen/Dis Loss: -0.0334/-0.0154\n", "Epoch: 075/100 | Batch 200/469 | Gen/Dis Loss: -0.1309/-0.0169\n", "Epoch: 075/100 | Batch 300/469 | Gen/Dis Loss: -0.1829/-0.0050\n", "Epoch: 075/100 | Batch 400/469 | Gen/Dis Loss: 0.0190/-0.0159\n", "Time elapsed: 16.42 min\n", "Epoch: 076/100 | Batch 000/469 | Gen/Dis Loss: -0.0615/-0.0070\n", "Epoch: 076/100 | Batch 100/469 | Gen/Dis Loss: -0.0425/-0.0027\n", "Epoch: 076/100 | Batch 200/469 | Gen/Dis Loss: -0.2873/-0.0004\n", "Epoch: 076/100 | Batch 300/469 | Gen/Dis Loss: -0.2644/-0.0015\n", "Epoch: 076/100 | Batch 400/469 | Gen/Dis Loss: 0.0010/-0.0117\n", "Time elapsed: 16.64 min\n", "Epoch: 077/100 | Batch 000/469 | Gen/Dis Loss: -0.4785/-0.0143\n", "Epoch: 077/100 | Batch 100/469 | Gen/Dis Loss: 0.2545/-0.0538\n", "Epoch: 077/100 | Batch 200/469 | Gen/Dis Loss: 1.1126/-0.0420\n", "Epoch: 077/100 | Batch 300/469 | Gen/Dis Loss: -0.0171/-0.0281\n", "Epoch: 077/100 | Batch 400/469 | Gen/Dis Loss: -0.2377/-0.0282\n", "Time elapsed: 16.86 min\n", "Epoch: 078/100 | Batch 000/469 | Gen/Dis Loss: -1.0293/-0.0400\n", "Epoch: 078/100 | Batch 100/469 | Gen/Dis Loss: -0.6561/-0.0403\n", "Epoch: 078/100 | Batch 200/469 | Gen/Dis Loss: -0.3585/0.0199\n", "Epoch: 078/100 | Batch 300/469 | Gen/Dis Loss: -0.2837/0.0207\n", "Epoch: 078/100 | Batch 400/469 | Gen/Dis Loss: -0.5526/-0.0081\n", "Time elapsed: 17.08 min\n", "Epoch: 079/100 | Batch 000/469 | Gen/Dis Loss: -0.2561/-0.0348\n", "Epoch: 079/100 | Batch 100/469 | Gen/Dis Loss: -0.5544/0.0026\n", "Epoch: 079/100 | Batch 200/469 | Gen/Dis Loss: -0.6737/-0.0098\n", "Epoch: 079/100 | Batch 300/469 | Gen/Dis Loss: -0.1180/-0.0130\n", "Epoch: 079/100 | Batch 400/469 | Gen/Dis Loss: -0.1299/0.0001\n", "Time elapsed: 17.30 min\n", "Epoch: 080/100 | Batch 000/469 | Gen/Dis Loss: -0.4765/-0.0191\n", "Epoch: 080/100 | Batch 100/469 | Gen/Dis Loss: -0.1213/-0.0290\n", "Epoch: 080/100 | Batch 200/469 | Gen/Dis Loss: -0.1815/0.0004\n", "Epoch: 080/100 | Batch 300/469 | Gen/Dis Loss: 0.0792/-0.0099\n", "Epoch: 080/100 | Batch 400/469 | Gen/Dis Loss: 0.0294/0.0005\n", "Time elapsed: 17.52 min\n", "Epoch: 081/100 | Batch 000/469 | Gen/Dis Loss: -0.0135/-0.0124\n", "Epoch: 081/100 | Batch 100/469 | Gen/Dis Loss: -0.1607/-0.0117\n", "Epoch: 081/100 | Batch 200/469 | Gen/Dis Loss: -0.0133/-0.0067\n", "Epoch: 081/100 | Batch 300/469 | Gen/Dis Loss: -0.1880/-0.0087\n", "Epoch: 081/100 | Batch 400/469 | Gen/Dis Loss: 0.0065/-0.0080\n", "Time elapsed: 17.75 min\n", "Epoch: 082/100 | Batch 000/469 | Gen/Dis Loss: 0.1546/-0.0072\n", "Epoch: 082/100 | Batch 100/469 | Gen/Dis Loss: -0.0983/-0.0176\n", "Epoch: 082/100 | Batch 200/469 | Gen/Dis Loss: -0.0293/-0.0161\n", "Epoch: 082/100 | Batch 300/469 | Gen/Dis Loss: -0.0014/-0.0127\n", "Epoch: 082/100 | Batch 400/469 | Gen/Dis Loss: 0.6860/-0.0461\n", "Time elapsed: 17.97 min\n", "Epoch: 083/100 | Batch 000/469 | Gen/Dis Loss: 0.1244/-0.0502\n", "Epoch: 083/100 | Batch 100/469 | Gen/Dis Loss: 0.2871/-0.0777\n", "Epoch: 083/100 | Batch 200/469 | Gen/Dis Loss: 0.2586/-0.0511\n", "Epoch: 083/100 | Batch 300/469 | Gen/Dis Loss: 0.7882/-0.0167\n", "Epoch: 083/100 | Batch 400/469 | Gen/Dis Loss: -0.6637/0.0116\n", "Time elapsed: 18.19 min\n", "Epoch: 084/100 | Batch 000/469 | Gen/Dis Loss: -0.3545/-0.0194\n", "Epoch: 084/100 | Batch 100/469 | Gen/Dis Loss: -0.5852/-0.0206\n", "Epoch: 084/100 | Batch 200/469 | Gen/Dis Loss: -0.7705/0.0064\n", "Epoch: 084/100 | Batch 300/469 | Gen/Dis Loss: -0.5049/-0.0083\n", "Epoch: 084/100 | Batch 400/469 | Gen/Dis Loss: 0.2705/0.0011\n", "Time elapsed: 18.40 min\n", "Epoch: 085/100 | Batch 000/469 | Gen/Dis Loss: 0.2000/-0.0048\n", "Epoch: 085/100 | Batch 100/469 | Gen/Dis Loss: 0.0808/-0.0103\n", "Epoch: 085/100 | Batch 200/469 | Gen/Dis Loss: 0.2059/-0.0094\n", "Epoch: 085/100 | Batch 300/469 | Gen/Dis Loss: -0.0031/-0.0018\n", "Epoch: 085/100 | Batch 400/469 | Gen/Dis Loss: -0.0381/-0.0005\n", "Time elapsed: 18.60 min\n", "Epoch: 086/100 | Batch 000/469 | Gen/Dis Loss: 0.1286/-0.0044\n", "Epoch: 086/100 | Batch 100/469 | Gen/Dis Loss: 0.0331/-0.0044\n", "Epoch: 086/100 | Batch 200/469 | Gen/Dis Loss: 0.1965/-0.0048\n", "Epoch: 086/100 | Batch 300/469 | Gen/Dis Loss: -0.0337/-0.0016\n", "Epoch: 086/100 | Batch 400/469 | Gen/Dis Loss: -0.0184/-0.0004\n", "Time elapsed: 18.80 min\n", "Epoch: 087/100 | Batch 000/469 | Gen/Dis Loss: -0.0462/-0.0016\n", "Epoch: 087/100 | Batch 100/469 | Gen/Dis Loss: -0.0760/-0.0037\n", "Epoch: 087/100 | Batch 200/469 | Gen/Dis Loss: 0.0399/-0.0049\n", "Epoch: 087/100 | Batch 300/469 | Gen/Dis Loss: 0.0365/0.0037\n", "Epoch: 087/100 | Batch 400/469 | Gen/Dis Loss: -0.1306/-0.0062\n", "Time elapsed: 19.00 min\n", "Epoch: 088/100 | Batch 000/469 | Gen/Dis Loss: -0.0738/-0.0088\n", "Epoch: 088/100 | Batch 100/469 | Gen/Dis Loss: -0.0802/-0.0042\n", "Epoch: 088/100 | Batch 200/469 | Gen/Dis Loss: -0.0822/-0.0090\n", "Epoch: 088/100 | Batch 300/469 | Gen/Dis Loss: -0.1203/-0.0012\n", "Epoch: 088/100 | Batch 400/469 | Gen/Dis Loss: -0.1172/-0.0026\n", "Time elapsed: 19.20 min\n", "Epoch: 089/100 | Batch 000/469 | Gen/Dis Loss: -0.0263/-0.0020\n", "Epoch: 089/100 | Batch 100/469 | Gen/Dis Loss: -0.0841/-0.0101\n", "Epoch: 089/100 | Batch 200/469 | Gen/Dis Loss: -0.1369/-0.0121\n", "Epoch: 089/100 | Batch 300/469 | Gen/Dis Loss: 0.1396/-0.0129\n", "Epoch: 089/100 | Batch 400/469 | Gen/Dis Loss: 1.0665/-0.0987\n", "Time elapsed: 19.40 min\n", "Epoch: 090/100 | Batch 000/469 | Gen/Dis Loss: 1.4815/-0.0318\n", "Epoch: 090/100 | Batch 100/469 | Gen/Dis Loss: 0.0725/-0.1139\n", "Epoch: 090/100 | Batch 200/469 | Gen/Dis Loss: 2.0467/-0.1155\n", "Epoch: 090/100 | Batch 300/469 | Gen/Dis Loss: 2.3618/-0.0439\n", "Epoch: 090/100 | Batch 400/469 | Gen/Dis Loss: 0.2455/-0.0782\n", "Time elapsed: 19.60 min\n", "Epoch: 091/100 | Batch 000/469 | Gen/Dis Loss: -0.3347/0.0024\n", "Epoch: 091/100 | Batch 100/469 | Gen/Dis Loss: -0.3745/-0.0038\n", "Epoch: 091/100 | Batch 200/469 | Gen/Dis Loss: -0.0828/-0.0351\n", "Epoch: 091/100 | Batch 300/469 | Gen/Dis Loss: -0.6020/-0.0001\n", "Epoch: 091/100 | Batch 400/469 | Gen/Dis Loss: -0.1889/-0.0489\n", "Time elapsed: 19.80 min\n", "Epoch: 092/100 | Batch 000/469 | Gen/Dis Loss: -0.3254/-0.0110\n", "Epoch: 092/100 | Batch 100/469 | Gen/Dis Loss: 0.0726/-0.0020\n", "Epoch: 092/100 | Batch 200/469 | Gen/Dis Loss: 0.0384/0.0016\n", "Epoch: 092/100 | Batch 300/469 | Gen/Dis Loss: -0.0508/-0.0077\n", "Epoch: 092/100 | Batch 400/469 | Gen/Dis Loss: 0.1877/-0.0063\n", "Time elapsed: 19.99 min\n", "Epoch: 093/100 | Batch 000/469 | Gen/Dis Loss: 0.0010/0.0017\n", "Epoch: 093/100 | Batch 100/469 | Gen/Dis Loss: 0.0229/-0.0026\n", "Epoch: 093/100 | Batch 200/469 | Gen/Dis Loss: -0.1199/-0.0056\n", "Epoch: 093/100 | Batch 300/469 | Gen/Dis Loss: -0.1033/-0.0058\n", "Epoch: 093/100 | Batch 400/469 | Gen/Dis Loss: -0.0920/-0.0029\n", "Time elapsed: 20.19 min\n", "Epoch: 094/100 | Batch 000/469 | Gen/Dis Loss: -0.1888/-0.0027\n", "Epoch: 094/100 | Batch 100/469 | Gen/Dis Loss: -0.0180/-0.0011\n", "Epoch: 094/100 | Batch 200/469 | Gen/Dis Loss: -0.1378/0.0004\n", "Epoch: 094/100 | Batch 300/469 | Gen/Dis Loss: -0.1408/-0.0006\n", "Epoch: 094/100 | Batch 400/469 | Gen/Dis Loss: -0.1772/-0.0040\n", "Time elapsed: 20.39 min\n", "Epoch: 095/100 | Batch 000/469 | Gen/Dis Loss: -0.3192/-0.0059\n", "Epoch: 095/100 | Batch 100/469 | Gen/Dis Loss: 0.1092/-0.0199\n", "Epoch: 095/100 | Batch 200/469 | Gen/Dis Loss: -0.8190/-0.0505\n", "Epoch: 095/100 | Batch 300/469 | Gen/Dis Loss: -1.4537/-0.1348\n", "Epoch: 095/100 | Batch 400/469 | Gen/Dis Loss: -1.2839/-0.0552\n", "Time elapsed: 20.59 min\n", "Epoch: 096/100 | Batch 000/469 | Gen/Dis Loss: -2.2877/-0.0374\n", "Epoch: 096/100 | Batch 100/469 | Gen/Dis Loss: -1.9977/-0.0345\n", "Epoch: 096/100 | Batch 200/469 | Gen/Dis Loss: -1.2651/-0.0732\n", "Epoch: 096/100 | Batch 300/469 | Gen/Dis Loss: -0.2708/-0.0259\n", "Epoch: 096/100 | Batch 400/469 | Gen/Dis Loss: 0.0806/-0.0034\n", "Time elapsed: 20.79 min\n", "Epoch: 097/100 | Batch 000/469 | Gen/Dis Loss: 0.0644/-0.0152\n", "Epoch: 097/100 | Batch 100/469 | Gen/Dis Loss: 0.2800/-0.0039\n", "Epoch: 097/100 | Batch 200/469 | Gen/Dis Loss: -0.1104/-0.0107\n", "Epoch: 097/100 | Batch 300/469 | Gen/Dis Loss: 0.0570/-0.0085\n", "Epoch: 097/100 | Batch 400/469 | Gen/Dis Loss: -0.1557/-0.0142\n", "Time elapsed: 20.99 min\n", "Epoch: 098/100 | Batch 000/469 | Gen/Dis Loss: -0.1008/-0.0084\n", "Epoch: 098/100 | Batch 100/469 | Gen/Dis Loss: -0.0895/-0.0114\n", "Epoch: 098/100 | Batch 200/469 | Gen/Dis Loss: -0.0015/-0.0081\n", "Epoch: 098/100 | Batch 300/469 | Gen/Dis Loss: -0.2192/-0.0051\n", "Epoch: 098/100 | Batch 400/469 | Gen/Dis Loss: -0.0046/-0.0065\n", "Time elapsed: 21.20 min\n", "Epoch: 099/100 | Batch 000/469 | Gen/Dis Loss: -0.0141/-0.0044\n", "Epoch: 099/100 | Batch 100/469 | Gen/Dis Loss: -0.0081/-0.0092\n", "Epoch: 099/100 | Batch 200/469 | Gen/Dis Loss: -0.1231/-0.0125\n", "Epoch: 099/100 | Batch 300/469 | Gen/Dis Loss: -0.1279/-0.0022\n", "Epoch: 099/100 | Batch 400/469 | Gen/Dis Loss: -0.1377/-0.0124\n", "Time elapsed: 21.42 min\n", "Epoch: 100/100 | Batch 000/469 | Gen/Dis Loss: -0.1776/-0.0067\n", "Epoch: 100/100 | Batch 100/469 | Gen/Dis Loss: -0.0924/-0.0051\n", "Epoch: 100/100 | Batch 200/469 | Gen/Dis Loss: 0.5641/-0.0004\n", "Epoch: 100/100 | Batch 300/469 | Gen/Dis Loss: 0.5127/-0.0377\n", "Epoch: 100/100 | Batch 400/469 | Gen/Dis Loss: 0.5550/-0.0404\n", "Time elapsed: 21.64 min\n", "Total Training Time: 21.64 min\n" ] } ], "source": [ "start_time = time.time() \n", "\n", "discr_costs = []\n", "gener_costs = []\n", "for epoch in range(NUM_EPOCHS):\n", " model = model.train()\n", " for batch_idx, (features, targets) in enumerate(train_loader):\n", "\n", " \n", " \n", " features = (features - 0.5)*2.\n", " features = features.view(-1, IMG_SIZE).to(device) \n", " targets = targets.to(device)\n", "\n", " # Regular GAN:\n", " # valid = torch.ones(targets.size(0)).float().to(device)\n", " # fake = torch.zeros(targets.size(0)).float().to(device)\n", " \n", " # WGAN:\n", " valid = -(torch.ones(targets.size(0)).float()).to(device)\n", " fake = torch.ones(targets.size(0)).float().to(device)\n", " \n", "\n", " ### FORWARD AND BACK PROP\n", " \n", " \n", " # --------------------------\n", " # Train Generator\n", " # --------------------------\n", " \n", " # Make new images\n", " z = torch.zeros((targets.size(0), LATENT_DIM)).uniform_(-1.0, 1.0).to(device)\n", " generated_features = model.generator_forward(z)\n", " \n", " # Loss for fooling the discriminator\n", " discr_pred = model.discriminator_forward(generated_features)\n", " \n", " \n", " # Regular GAN:\n", " # gener_loss = F.binary_cross_entropy_with_logits(discr_pred, valid)\n", " \n", " # WGAN:\n", " gener_loss = wasserstein_loss(valid, discr_pred)\n", " \n", " optim_gener.zero_grad()\n", " gener_loss.backward()\n", " optim_gener.step()\n", " \n", " # --------------------------\n", " # Train Discriminator\n", " # -------------------------- \n", "\n", " \n", " # WGAN: 5 loops for discriminator\n", " for _ in range(num_iter_critic):\n", " \n", " discr_pred_real = model.discriminator_forward(features.view(-1, IMG_SIZE))\n", " # Regular GAN:\n", " # real_loss = F.binary_cross_entropy_with_logits(discr_pred_real, valid)\n", " # WGAN:\n", " real_loss = wasserstein_loss(valid, discr_pred_real)\n", "\n", " discr_pred_fake = model.discriminator_forward(generated_features.detach())\n", "\n", " # Regular GAN:\n", " # fake_loss = F.binary_cross_entropy_with_logits(discr_pred_fake, fake)\n", " # WGAN:\n", " fake_loss = wasserstein_loss(fake, discr_pred_fake)\n", "\n", " # Regular GAN:\n", " discr_loss = (real_loss + fake_loss)\n", " # WGAN:\n", " #discr_loss = -(real_loss - fake_loss)\n", "\n", " optim_discr.zero_grad()\n", " discr_loss.backward()\n", " optim_discr.step() \n", "\n", " # WGAN:\n", " for p in model.discriminator.parameters():\n", " p.data.clamp_(-weight_clip_value, weight_clip_value)\n", "\n", " \n", " discr_costs.append(discr_loss.item())\n", " gener_costs.append(gener_loss.item())\n", " \n", " \n", " \n", " \n", " ### LOGGING\n", " if not batch_idx % 100:\n", " print ('Epoch: %03d/%03d | Batch %03d/%03d | Gen/Dis Loss: %.4f/%.4f' \n", " %(epoch+1, NUM_EPOCHS, batch_idx, \n", " len(train_loader), gener_loss, discr_loss))\n", "\n", " print('Time elapsed: %.2f min' % ((time.time() - start_time)/60))\n", " \n", "print('Total Training Time: %.2f min' % ((time.time() - start_time)/60))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Evaluation" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "%matplotlib inline\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "ax1 = plt.subplot(1, 1, 1)\n", "ax1.plot(range(len(gener_costs)), gener_costs, label='Generator loss')\n", "ax1.plot(range(len(discr_costs)), discr_costs, label='Discriminator loss')\n", "ax1.set_xlabel('Iterations')\n", "ax1.set_ylabel('Loss')\n", "ax1.legend()\n", "\n", "###################\n", "# Set scond x-axis\n", "ax2 = ax1.twiny()\n", "newlabel = list(range(NUM_EPOCHS+1))\n", "iter_per_epoch = len(train_loader)\n", "newpos = [e*iter_per_epoch for e in newlabel]\n", "\n", "ax2.set_xticklabels(newlabel[::10])\n", "ax2.set_xticks(newpos[::10])\n", "\n", "ax2.xaxis.set_ticks_position('bottom')\n", "ax2.xaxis.set_label_position('bottom')\n", "ax2.spines['bottom'].set_position(('outward', 45))\n", "ax2.set_xlabel('Epochs')\n", "ax2.set_xlim(ax1.get_xlim())\n", "###################\n", "\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "##########################\n", "### VISUALIZATION\n", "##########################\n", "\n", "\n", "model.eval()\n", "# Make new images\n", "z = torch.zeros((5, LATENT_DIM)).uniform_(-1.0, 1.0).to(device)\n", "generated_features = model.generator_forward(z)\n", "imgs = generated_features.view(-1, 28, 28)\n", "\n", "fig, axes = plt.subplots(nrows=1, ncols=5, figsize=(20, 2.5))\n", "\n", "\n", "for i, ax in enumerate(axes):\n", " axes[i].imshow(imgs[i].to(torch.device('cpu')).detach(), cmap='binary')" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.3" }, "toc": { "nav_menu": {}, "number_sections": true, "sideBar": true, "skip_h1_title": false, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": false, "toc_position": {}, "toc_section_display": true, "toc_window_display": false } }, "nbformat": 4, "nbformat_minor": 4 }