{ "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.6.1\n", "\n", "torch 1.2.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": [ "# Deep Convolutional Wasserstein GAN" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Implementation of a deep convolutional Wasserstein GAN 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 conventional deep convolutional 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" ] }, { "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.00005\n", "discriminator_learning_rate = 0.00005\n", "NUM_EPOCHS = 100\n", "BATCH_SIZE = 128\n", "LATENT_DIM = 100\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", "### 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", " num_workers=4,\n", " shuffle=True)\n", "\n", "test_loader = DataLoader(dataset=test_dataset, \n", " batch_size=BATCH_SIZE,\n", " num_workers=4,\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", "class Flatten(nn.Module):\n", " def forward(self, input):\n", " return input.view(input.size(0), -1)\n", " \n", "class Reshape1(nn.Module):\n", " def forward(self, input):\n", " return input.view(input.size(0), 64, 7, 7)\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", " \n", " nn.Linear(LATENT_DIM, 3136, bias=False),\n", " nn.BatchNorm1d(num_features=3136),\n", " nn.LeakyReLU(inplace=True, negative_slope=0.0001),\n", " Reshape1(),\n", " \n", " nn.ConvTranspose2d(in_channels=64, out_channels=32, kernel_size=(3, 3), stride=(2, 2), padding=1, bias=False),\n", " nn.BatchNorm2d(num_features=32),\n", " nn.LeakyReLU(inplace=True, negative_slope=0.0001),\n", " #nn.Dropout2d(p=0.2),\n", " \n", " nn.ConvTranspose2d(in_channels=32, out_channels=16, kernel_size=(3, 3), stride=(2, 2), padding=1, bias=False),\n", " nn.BatchNorm2d(num_features=16),\n", " nn.LeakyReLU(inplace=True, negative_slope=0.0001),\n", " #nn.Dropout2d(p=0.2),\n", " \n", " nn.ConvTranspose2d(in_channels=16, out_channels=8, kernel_size=(3, 3), stride=(1, 1), padding=0, bias=False),\n", " nn.BatchNorm2d(num_features=8),\n", " nn.LeakyReLU(inplace=True, negative_slope=0.0001),\n", " #nn.Dropout2d(p=0.2),\n", " \n", " nn.ConvTranspose2d(in_channels=8, out_channels=1, kernel_size=(2, 2), stride=(1, 1), padding=0, bias=False),\n", " nn.Tanh()\n", " )\n", " \n", " self.discriminator = nn.Sequential(\n", " nn.Conv2d(in_channels=1, out_channels=8, padding=1, kernel_size=(3, 3), stride=(2, 2), bias=False),\n", " nn.BatchNorm2d(num_features=8),\n", " nn.LeakyReLU(inplace=True, negative_slope=0.0001), \n", " #nn.Dropout2d(p=0.2),\n", " \n", " nn.Conv2d(in_channels=8, out_channels=16, padding=1, kernel_size=(3, 3), stride=(2, 2), bias=False),\n", " nn.BatchNorm2d(num_features=16),\n", " nn.LeakyReLU(inplace=True, negative_slope=0.0001), \n", " #nn.Dropout2d(p=0.2),\n", " \n", " nn.Conv2d(in_channels=16, out_channels=32, padding=1, kernel_size=(3, 3), stride=(2, 2), bias=False),\n", " nn.BatchNorm2d(num_features=32),\n", " nn.LeakyReLU(inplace=True, negative_slope=0.0001), \n", " #nn.Dropout2d(p=0.2),\n", " \n", " Flatten(),\n", "\n", " nn.Linear(512, 1),\n", " #nn.Sigmoid()\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)\n", "\n", "\n" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "GAN(\n", " (generator): Sequential(\n", " (0): Linear(in_features=100, out_features=3136, bias=False)\n", " (1): BatchNorm1d(3136, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", " (2): LeakyReLU(negative_slope=0.0001, inplace=True)\n", " (3): Reshape1()\n", " (4): ConvTranspose2d(64, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\n", " (5): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", " (6): LeakyReLU(negative_slope=0.0001, inplace=True)\n", " (7): ConvTranspose2d(32, 16, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\n", " (8): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", " (9): LeakyReLU(negative_slope=0.0001, inplace=True)\n", " (10): ConvTranspose2d(16, 8, kernel_size=(3, 3), stride=(1, 1), bias=False)\n", " (11): BatchNorm2d(8, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", " (12): LeakyReLU(negative_slope=0.0001, inplace=True)\n", " (13): ConvTranspose2d(8, 1, kernel_size=(2, 2), stride=(1, 1), bias=False)\n", " (14): Tanh()\n", " )\n", " (discriminator): Sequential(\n", " (0): Conv2d(1, 8, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\n", " (1): BatchNorm2d(8, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", " (2): LeakyReLU(negative_slope=0.0001, inplace=True)\n", " (3): Conv2d(8, 16, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\n", " (4): BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", " (5): LeakyReLU(negative_slope=0.0001, inplace=True)\n", " (6): Conv2d(16, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\n", " (7): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n", " (8): LeakyReLU(negative_slope=0.0001, inplace=True)\n", " (9): Flatten()\n", " (10): Linear(in_features=512, out_features=1, bias=True)\n", " )\n", ")\n" ] } ], "source": [ "torch.manual_seed(random_seed)\n", "\n", "#del model\n", "model = GAN()\n", "model = model.to(device)\n", "\n", "print(model)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'\\noutputs = []\\ndef hook(module, input, output):\\n outputs.append(output)\\n\\nfor i, layer in enumerate(model.discriminator):\\n if isinstance(layer, torch.nn.modules.conv.Conv2d):\\n model.discriminator[i].register_forward_hook(hook)\\n\\n#for i, layer in enumerate(model.generator):\\n# if isinstance(layer, torch.nn.modules.ConvTranspose2d):\\n# model.generator[i].register_forward_hook(hook)\\n'" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "### ## FOR DEBUGGING\n", "\n", "\"\"\"\n", "outputs = []\n", "def hook(module, input, output):\n", " outputs.append(output)\n", "\n", "for i, layer in enumerate(model.discriminator):\n", " if isinstance(layer, torch.nn.modules.conv.Conv2d):\n", " model.discriminator[i].register_forward_hook(hook)\n", "\n", "#for i, layer in enumerate(model.generator):\n", "# if isinstance(layer, torch.nn.modules.ConvTranspose2d):\n", "# model.generator[i].register_forward_hook(hook)\n", "\"\"\"" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "optim_gener = torch.optim.RMSprop(model.generator.parameters(), lr=generator_learning_rate)\n", "optim_discr = torch.optim.RMSprop(model.discriminator.parameters(), lr=discriminator_learning_rate)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Training" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Epoch: 001/100 | Batch 000/469 | Gen/Dis Loss: 0.3318/-0.0001\n", "Epoch: 001/100 | Batch 100/469 | Gen/Dis Loss: 0.0037/-0.0026\n", "Epoch: 001/100 | Batch 200/469 | Gen/Dis Loss: 0.0121/-0.0126\n", "Epoch: 001/100 | Batch 300/469 | Gen/Dis Loss: 0.0117/-0.0123\n", "Epoch: 001/100 | Batch 400/469 | Gen/Dis Loss: 0.0110/-0.0124\n", "Time elapsed: 0.31 min\n", "Epoch: 002/100 | Batch 000/469 | Gen/Dis Loss: 0.0123/-0.0140\n", "Epoch: 002/100 | Batch 100/469 | Gen/Dis Loss: 0.0124/-0.0136\n", "Epoch: 002/100 | Batch 200/469 | Gen/Dis Loss: 0.0108/-0.0126\n", "Epoch: 002/100 | Batch 300/469 | Gen/Dis Loss: 0.0089/-0.0104\n", "Epoch: 002/100 | Batch 400/469 | Gen/Dis Loss: 0.0093/-0.0108\n", "Time elapsed: 0.64 min\n", "Epoch: 003/100 | Batch 000/469 | Gen/Dis Loss: 0.0095/-0.0107\n", "Epoch: 003/100 | Batch 100/469 | Gen/Dis Loss: 0.0094/-0.0097\n", "Epoch: 003/100 | Batch 200/469 | Gen/Dis Loss: 0.0089/-0.0099\n", "Epoch: 003/100 | Batch 300/469 | Gen/Dis Loss: 0.0084/-0.0087\n", "Epoch: 003/100 | Batch 400/469 | Gen/Dis Loss: 0.0083/-0.0081\n", "Time elapsed: 1.12 min\n", "Epoch: 004/100 | Batch 000/469 | Gen/Dis Loss: 0.0071/-0.0080\n", "Epoch: 004/100 | Batch 100/469 | Gen/Dis Loss: 0.0077/-0.0076\n", "Epoch: 004/100 | Batch 200/469 | Gen/Dis Loss: 0.0090/-0.0070\n", "Epoch: 004/100 | Batch 300/469 | Gen/Dis Loss: 0.0079/-0.0082\n", "Epoch: 004/100 | Batch 400/469 | Gen/Dis Loss: 0.0101/-0.0072\n", "Time elapsed: 1.65 min\n", "Epoch: 005/100 | Batch 000/469 | Gen/Dis Loss: 0.0098/-0.0080\n", "Epoch: 005/100 | Batch 100/469 | Gen/Dis Loss: 0.0089/-0.0078\n", "Epoch: 005/100 | Batch 200/469 | Gen/Dis Loss: 0.0087/-0.0075\n", "Epoch: 005/100 | Batch 300/469 | Gen/Dis Loss: 0.0079/-0.0073\n", "Epoch: 005/100 | Batch 400/469 | Gen/Dis Loss: 0.0058/-0.0078\n", "Time elapsed: 2.15 min\n", "Epoch: 006/100 | Batch 000/469 | Gen/Dis Loss: 0.0048/-0.0071\n", "Epoch: 006/100 | Batch 100/469 | Gen/Dis Loss: 0.0050/-0.0070\n", "Epoch: 006/100 | Batch 200/469 | Gen/Dis Loss: 0.0046/-0.0069\n", "Epoch: 006/100 | Batch 300/469 | Gen/Dis Loss: 0.0060/-0.0069\n", "Epoch: 006/100 | Batch 400/469 | Gen/Dis Loss: 0.0067/-0.0067\n", "Time elapsed: 2.67 min\n", "Epoch: 007/100 | Batch 000/469 | Gen/Dis Loss: 0.0066/-0.0075\n", "Epoch: 007/100 | Batch 100/469 | Gen/Dis Loss: 0.0074/-0.0067\n", "Epoch: 007/100 | Batch 200/469 | Gen/Dis Loss: 0.0053/-0.0028\n", "Epoch: 007/100 | Batch 300/469 | Gen/Dis Loss: 0.0029/-0.0043\n", "Epoch: 007/100 | Batch 400/469 | Gen/Dis Loss: 0.0018/-0.0043\n", "Time elapsed: 3.20 min\n", "Epoch: 008/100 | Batch 000/469 | Gen/Dis Loss: 0.0025/-0.0040\n", "Epoch: 008/100 | Batch 100/469 | Gen/Dis Loss: 0.0015/-0.0034\n", "Epoch: 008/100 | Batch 200/469 | Gen/Dis Loss: -0.0001/-0.0023\n", "Epoch: 008/100 | Batch 300/469 | Gen/Dis Loss: 0.0014/-0.0017\n", "Epoch: 008/100 | Batch 400/469 | Gen/Dis Loss: -0.0003/-0.0022\n", "Time elapsed: 3.74 min\n", "Epoch: 009/100 | Batch 000/469 | Gen/Dis Loss: 0.0006/-0.0021\n", "Epoch: 009/100 | Batch 100/469 | Gen/Dis Loss: 0.0017/-0.0022\n", "Epoch: 009/100 | Batch 200/469 | Gen/Dis Loss: 0.0014/-0.0016\n", "Epoch: 009/100 | Batch 300/469 | Gen/Dis Loss: -0.0005/-0.0015\n", "Epoch: 009/100 | Batch 400/469 | Gen/Dis Loss: -0.0032/-0.0012\n", "Time elapsed: 4.25 min\n", "Epoch: 010/100 | Batch 000/469 | Gen/Dis Loss: -0.0036/-0.0015\n", "Epoch: 010/100 | Batch 100/469 | Gen/Dis Loss: -0.0000/-0.0015\n", "Epoch: 010/100 | Batch 200/469 | Gen/Dis Loss: -0.0024/-0.0009\n", "Epoch: 010/100 | Batch 300/469 | Gen/Dis Loss: -0.0010/-0.0012\n", "Epoch: 010/100 | Batch 400/469 | Gen/Dis Loss: 0.0012/-0.0015\n", "Time elapsed: 4.76 min\n", "Epoch: 011/100 | Batch 000/469 | Gen/Dis Loss: 0.0013/-0.0010\n", "Epoch: 011/100 | Batch 100/469 | Gen/Dis Loss: 0.0003/-0.0011\n", "Epoch: 011/100 | Batch 200/469 | Gen/Dis Loss: -0.0005/-0.0013\n", "Epoch: 011/100 | Batch 300/469 | Gen/Dis Loss: 0.0000/-0.0014\n", "Epoch: 011/100 | Batch 400/469 | Gen/Dis Loss: -0.0002/-0.0014\n", "Time elapsed: 5.26 min\n", "Epoch: 012/100 | Batch 000/469 | Gen/Dis Loss: -0.0000/-0.0012\n", "Epoch: 012/100 | Batch 100/469 | Gen/Dis Loss: 0.0009/-0.0010\n", "Epoch: 012/100 | Batch 200/469 | Gen/Dis Loss: -0.0001/-0.0011\n", "Epoch: 012/100 | Batch 300/469 | Gen/Dis Loss: -0.0016/-0.0010\n", "Epoch: 012/100 | Batch 400/469 | Gen/Dis Loss: -0.0021/-0.0010\n", "Time elapsed: 5.79 min\n", "Epoch: 013/100 | Batch 000/469 | Gen/Dis Loss: -0.0032/-0.0009\n", "Epoch: 013/100 | Batch 100/469 | Gen/Dis Loss: -0.0023/-0.0009\n", "Epoch: 013/100 | Batch 200/469 | Gen/Dis Loss: -0.0038/-0.0013\n", "Epoch: 013/100 | Batch 300/469 | Gen/Dis Loss: 0.0004/-0.0014\n", "Epoch: 013/100 | Batch 400/469 | Gen/Dis Loss: -0.0002/-0.0012\n", "Time elapsed: 6.30 min\n", "Epoch: 014/100 | Batch 000/469 | Gen/Dis Loss: -0.0007/-0.0011\n", "Epoch: 014/100 | Batch 100/469 | Gen/Dis Loss: -0.0009/-0.0012\n", "Epoch: 014/100 | Batch 200/469 | Gen/Dis Loss: -0.0007/-0.0010\n", "Epoch: 014/100 | Batch 300/469 | Gen/Dis Loss: -0.0002/-0.0009\n", "Epoch: 014/100 | Batch 400/469 | Gen/Dis Loss: -0.0009/-0.0008\n", "Time elapsed: 6.82 min\n", "Epoch: 015/100 | Batch 000/469 | Gen/Dis Loss: -0.0006/-0.0008\n", "Epoch: 015/100 | Batch 100/469 | Gen/Dis Loss: -0.0014/-0.0009\n", "Epoch: 015/100 | Batch 200/469 | Gen/Dis Loss: -0.0029/-0.0008\n", "Epoch: 015/100 | Batch 300/469 | Gen/Dis Loss: -0.0030/-0.0008\n", "Epoch: 015/100 | Batch 400/469 | Gen/Dis Loss: -0.0022/-0.0009\n", "Time elapsed: 7.32 min\n", "Epoch: 016/100 | Batch 000/469 | Gen/Dis Loss: -0.0015/-0.0010\n", "Epoch: 016/100 | Batch 100/469 | Gen/Dis Loss: -0.0013/-0.0008\n", "Epoch: 016/100 | Batch 200/469 | Gen/Dis Loss: -0.0011/-0.0008\n", "Epoch: 016/100 | Batch 300/469 | Gen/Dis Loss: -0.0008/-0.0007\n", "Epoch: 016/100 | Batch 400/469 | Gen/Dis Loss: -0.0023/-0.0008\n", "Time elapsed: 7.84 min\n", "Epoch: 017/100 | Batch 000/469 | Gen/Dis Loss: -0.0017/-0.0009\n", "Epoch: 017/100 | Batch 100/469 | Gen/Dis Loss: -0.0017/-0.0008\n", "Epoch: 017/100 | Batch 200/469 | Gen/Dis Loss: -0.0038/-0.0009\n", "Epoch: 017/100 | Batch 300/469 | Gen/Dis Loss: -0.0036/-0.0009\n", "Epoch: 017/100 | Batch 400/469 | Gen/Dis Loss: -0.0029/-0.0007\n", "Time elapsed: 8.39 min\n", "Epoch: 018/100 | Batch 000/469 | Gen/Dis Loss: -0.0024/-0.0009\n", "Epoch: 018/100 | Batch 100/469 | Gen/Dis Loss: -0.0029/-0.0008\n", "Epoch: 018/100 | Batch 200/469 | Gen/Dis Loss: -0.0029/-0.0007\n", "Epoch: 018/100 | Batch 300/469 | Gen/Dis Loss: -0.0014/-0.0007\n", "Epoch: 018/100 | Batch 400/469 | Gen/Dis Loss: -0.0017/-0.0008\n", "Time elapsed: 8.91 min\n", "Epoch: 019/100 | Batch 000/469 | Gen/Dis Loss: -0.0038/-0.0009\n", "Epoch: 019/100 | Batch 100/469 | Gen/Dis Loss: -0.0054/-0.0009\n", "Epoch: 019/100 | Batch 200/469 | Gen/Dis Loss: -0.0035/-0.0010\n", "Epoch: 019/100 | Batch 300/469 | Gen/Dis Loss: -0.0027/-0.0008\n", "Epoch: 019/100 | Batch 400/469 | Gen/Dis Loss: -0.0005/-0.0008\n", "Time elapsed: 9.44 min\n", "Epoch: 020/100 | Batch 000/469 | Gen/Dis Loss: -0.0005/-0.0006\n", "Epoch: 020/100 | Batch 100/469 | Gen/Dis Loss: -0.0010/-0.0005\n", "Epoch: 020/100 | Batch 200/469 | Gen/Dis Loss: -0.0012/-0.0006\n", "Epoch: 020/100 | Batch 300/469 | Gen/Dis Loss: -0.0038/-0.0007\n", "Epoch: 020/100 | Batch 400/469 | Gen/Dis Loss: -0.0041/-0.0008\n", "Time elapsed: 9.97 min\n", "Epoch: 021/100 | Batch 000/469 | Gen/Dis Loss: -0.0043/-0.0008\n", "Epoch: 021/100 | Batch 100/469 | Gen/Dis Loss: -0.0029/-0.0008\n", "Epoch: 021/100 | Batch 200/469 | Gen/Dis Loss: -0.0021/-0.0007\n", "Epoch: 021/100 | Batch 300/469 | Gen/Dis Loss: -0.0023/-0.0007\n", "Epoch: 021/100 | Batch 400/469 | Gen/Dis Loss: -0.0018/-0.0006\n", "Time elapsed: 10.47 min\n", "Epoch: 022/100 | Batch 000/469 | Gen/Dis Loss: -0.0014/-0.0006\n", "Epoch: 022/100 | Batch 100/469 | Gen/Dis Loss: -0.0033/-0.0007\n", "Epoch: 022/100 | Batch 200/469 | Gen/Dis Loss: -0.0007/-0.0005\n", "Epoch: 022/100 | Batch 300/469 | Gen/Dis Loss: 0.0003/-0.0007\n", "Epoch: 022/100 | Batch 400/469 | Gen/Dis Loss: -0.0019/-0.0006\n", "Time elapsed: 10.99 min\n", "Epoch: 023/100 | Batch 000/469 | Gen/Dis Loss: -0.0046/-0.0006\n", "Epoch: 023/100 | Batch 100/469 | Gen/Dis Loss: -0.0029/-0.0006\n", "Epoch: 023/100 | Batch 200/469 | Gen/Dis Loss: -0.0027/-0.0005\n", "Epoch: 023/100 | Batch 300/469 | Gen/Dis Loss: -0.0024/-0.0004\n", "Epoch: 023/100 | Batch 400/469 | Gen/Dis Loss: -0.0037/-0.0005\n", "Time elapsed: 11.48 min\n", "Epoch: 024/100 | Batch 000/469 | Gen/Dis Loss: -0.0032/-0.0005\n", "Epoch: 024/100 | Batch 100/469 | Gen/Dis Loss: -0.0027/-0.0006\n", "Epoch: 024/100 | Batch 200/469 | Gen/Dis Loss: -0.0013/-0.0006\n", "Epoch: 024/100 | Batch 300/469 | Gen/Dis Loss: -0.0010/-0.0006\n", "Epoch: 024/100 | Batch 400/469 | Gen/Dis Loss: -0.0025/-0.0007\n", "Time elapsed: 11.83 min\n", "Epoch: 025/100 | Batch 000/469 | Gen/Dis Loss: -0.0036/-0.0006\n", "Epoch: 025/100 | Batch 100/469 | Gen/Dis Loss: -0.0038/-0.0005\n", "Epoch: 025/100 | Batch 200/469 | Gen/Dis Loss: -0.0030/-0.0006\n", "Epoch: 025/100 | Batch 300/469 | Gen/Dis Loss: -0.0029/-0.0008\n", "Epoch: 025/100 | Batch 400/469 | Gen/Dis Loss: -0.0022/-0.0005\n", "Time elapsed: 12.14 min\n", "Epoch: 026/100 | Batch 000/469 | Gen/Dis Loss: -0.0010/-0.0005\n", "Epoch: 026/100 | Batch 100/469 | Gen/Dis Loss: -0.0030/-0.0005\n", "Epoch: 026/100 | Batch 200/469 | Gen/Dis Loss: -0.0002/-0.0005\n", "Epoch: 026/100 | Batch 300/469 | Gen/Dis Loss: -0.0004/-0.0004\n", "Epoch: 026/100 | Batch 400/469 | Gen/Dis Loss: 0.0006/-0.0005\n", "Time elapsed: 12.45 min\n", "Epoch: 027/100 | Batch 000/469 | Gen/Dis Loss: -0.0004/-0.0004\n", "Epoch: 027/100 | Batch 100/469 | Gen/Dis Loss: -0.0005/-0.0005\n", "Epoch: 027/100 | Batch 200/469 | Gen/Dis Loss: -0.0029/-0.0006\n", "Epoch: 027/100 | Batch 300/469 | Gen/Dis Loss: -0.0031/-0.0005\n", "Epoch: 027/100 | Batch 400/469 | Gen/Dis Loss: -0.0033/-0.0006\n", "Time elapsed: 12.76 min\n", "Epoch: 028/100 | Batch 000/469 | Gen/Dis Loss: 0.0026/-0.0005\n", "Epoch: 028/100 | Batch 100/469 | Gen/Dis Loss: 0.0000/-0.0006\n", "Epoch: 028/100 | Batch 200/469 | Gen/Dis Loss: 0.0007/-0.0002\n", "Epoch: 028/100 | Batch 300/469 | Gen/Dis Loss: -0.0001/-0.0004\n", "Epoch: 028/100 | Batch 400/469 | Gen/Dis Loss: 0.0024/-0.0005\n", "Time elapsed: 13.06 min\n", "Epoch: 029/100 | Batch 000/469 | Gen/Dis Loss: 0.0015/-0.0005\n", "Epoch: 029/100 | Batch 100/469 | Gen/Dis Loss: 0.0006/-0.0004\n", "Epoch: 029/100 | Batch 200/469 | Gen/Dis Loss: 0.0006/-0.0003\n", "Epoch: 029/100 | Batch 300/469 | Gen/Dis Loss: -0.0056/-0.0002\n", "Epoch: 029/100 | Batch 400/469 | Gen/Dis Loss: 0.0086/-0.0007\n", "Time elapsed: 13.36 min\n", "Epoch: 030/100 | Batch 000/469 | Gen/Dis Loss: 0.0015/-0.0006\n", "Epoch: 030/100 | Batch 100/469 | Gen/Dis Loss: -0.0056/-0.0008\n", "Epoch: 030/100 | Batch 200/469 | Gen/Dis Loss: 0.0057/-0.0007\n", "Epoch: 030/100 | Batch 300/469 | Gen/Dis Loss: -0.0112/-0.0001\n", "Epoch: 030/100 | Batch 400/469 | Gen/Dis Loss: 0.0086/-0.0005\n", "Time elapsed: 13.67 min\n", "Epoch: 031/100 | Batch 000/469 | Gen/Dis Loss: 0.0026/-0.0005\n", "Epoch: 031/100 | Batch 100/469 | Gen/Dis Loss: 0.0044/-0.0002\n", "Epoch: 031/100 | Batch 200/469 | Gen/Dis Loss: 0.0021/-0.0003\n", "Epoch: 031/100 | Batch 300/469 | Gen/Dis Loss: 0.0005/-0.0004\n", "Epoch: 031/100 | Batch 400/469 | Gen/Dis Loss: 0.0001/-0.0005\n", "Time elapsed: 13.98 min\n", "Epoch: 032/100 | Batch 000/469 | Gen/Dis Loss: 0.0011/-0.0005\n", "Epoch: 032/100 | Batch 100/469 | Gen/Dis Loss: 0.0046/-0.0008\n", "Epoch: 032/100 | Batch 200/469 | Gen/Dis Loss: 0.0025/-0.0007\n", "Epoch: 032/100 | Batch 300/469 | Gen/Dis Loss: 0.0029/-0.0005\n", "Epoch: 032/100 | Batch 400/469 | Gen/Dis Loss: 0.0069/-0.0007\n", "Time elapsed: 14.29 min\n", "Epoch: 033/100 | Batch 000/469 | Gen/Dis Loss: 0.0048/-0.0006\n", "Epoch: 033/100 | Batch 100/469 | Gen/Dis Loss: 0.0011/-0.0005\n", "Epoch: 033/100 | Batch 200/469 | Gen/Dis Loss: 0.0008/-0.0003\n", "Epoch: 033/100 | Batch 300/469 | Gen/Dis Loss: 0.0039/-0.0006\n", "Epoch: 033/100 | Batch 400/469 | Gen/Dis Loss: 0.0039/-0.0004\n", "Time elapsed: 14.60 min\n", "Epoch: 034/100 | Batch 000/469 | Gen/Dis Loss: 0.0010/-0.0005\n", "Epoch: 034/100 | Batch 100/469 | Gen/Dis Loss: 0.0001/-0.0004\n", "Epoch: 034/100 | Batch 200/469 | Gen/Dis Loss: 0.0026/-0.0004\n", "Epoch: 034/100 | Batch 300/469 | Gen/Dis Loss: 0.0008/-0.0003\n", "Epoch: 034/100 | Batch 400/469 | Gen/Dis Loss: 0.0043/-0.0005\n", "Time elapsed: 14.90 min\n", "Epoch: 035/100 | Batch 000/469 | Gen/Dis Loss: 0.0033/-0.0004\n", "Epoch: 035/100 | Batch 100/469 | Gen/Dis Loss: 0.0017/-0.0002\n", "Epoch: 035/100 | Batch 200/469 | Gen/Dis Loss: 0.0012/-0.0004\n", "Epoch: 035/100 | Batch 300/469 | Gen/Dis Loss: 0.0013/-0.0004\n", "Epoch: 035/100 | Batch 400/469 | Gen/Dis Loss: 0.0018/-0.0003\n", "Time elapsed: 15.20 min\n", "Epoch: 036/100 | Batch 000/469 | Gen/Dis Loss: 0.0046/-0.0004\n", "Epoch: 036/100 | Batch 100/469 | Gen/Dis Loss: 0.0046/-0.0004\n", "Epoch: 036/100 | Batch 200/469 | Gen/Dis Loss: 0.0022/-0.0004\n", "Epoch: 036/100 | Batch 300/469 | Gen/Dis Loss: 0.0007/-0.0002\n", "Epoch: 036/100 | Batch 400/469 | Gen/Dis Loss: 0.0027/-0.0003\n", "Time elapsed: 15.51 min\n", "Epoch: 037/100 | Batch 000/469 | Gen/Dis Loss: 0.0006/-0.0004\n", "Epoch: 037/100 | Batch 100/469 | Gen/Dis Loss: 0.0016/-0.0004\n", "Epoch: 037/100 | Batch 200/469 | Gen/Dis Loss: -0.0014/-0.0003\n", "Epoch: 037/100 | Batch 300/469 | Gen/Dis Loss: 0.0015/-0.0004\n", "Epoch: 037/100 | Batch 400/469 | Gen/Dis Loss: 0.0015/-0.0002\n", "Time elapsed: 15.82 min\n", "Epoch: 038/100 | Batch 000/469 | Gen/Dis Loss: 0.0013/-0.0003\n", "Epoch: 038/100 | Batch 100/469 | Gen/Dis Loss: 0.0011/-0.0002\n", "Epoch: 038/100 | Batch 200/469 | Gen/Dis Loss: 0.0023/-0.0003\n", "Epoch: 038/100 | Batch 300/469 | Gen/Dis Loss: 0.0008/-0.0003\n", "Epoch: 038/100 | Batch 400/469 | Gen/Dis Loss: 0.0031/-0.0003\n", "Time elapsed: 16.28 min\n", "Epoch: 039/100 | Batch 000/469 | Gen/Dis Loss: 0.0041/-0.0002\n", "Epoch: 039/100 | Batch 100/469 | Gen/Dis Loss: 0.0047/-0.0002\n", "Epoch: 039/100 | Batch 200/469 | Gen/Dis Loss: 0.0040/-0.0002\n", "Epoch: 039/100 | Batch 300/469 | Gen/Dis Loss: 0.0051/-0.0003\n", "Epoch: 039/100 | Batch 400/469 | Gen/Dis Loss: 0.0094/-0.0003\n", "Time elapsed: 16.76 min\n", "Epoch: 040/100 | Batch 000/469 | Gen/Dis Loss: 0.0061/-0.0002\n", "Epoch: 040/100 | Batch 100/469 | Gen/Dis Loss: 0.0054/-0.0003\n", "Epoch: 040/100 | Batch 200/469 | Gen/Dis Loss: 0.0064/-0.0002\n", "Epoch: 040/100 | Batch 300/469 | Gen/Dis Loss: 0.0075/-0.0001\n", "Epoch: 040/100 | Batch 400/469 | Gen/Dis Loss: 0.0066/-0.0002\n", "Time elapsed: 17.29 min\n", "Epoch: 041/100 | Batch 000/469 | Gen/Dis Loss: 0.0054/-0.0002\n", "Epoch: 041/100 | Batch 100/469 | Gen/Dis Loss: 0.0021/-0.0002\n", "Epoch: 041/100 | Batch 200/469 | Gen/Dis Loss: 0.0018/-0.0002\n", "Epoch: 041/100 | Batch 300/469 | Gen/Dis Loss: -0.0017/-0.0001\n", "Epoch: 041/100 | Batch 400/469 | Gen/Dis Loss: 0.0028/-0.0002\n", "Time elapsed: 17.79 min\n", "Epoch: 042/100 | Batch 000/469 | Gen/Dis Loss: 0.0041/-0.0002\n", "Epoch: 042/100 | Batch 100/469 | Gen/Dis Loss: 0.0044/-0.0003\n", "Epoch: 042/100 | Batch 200/469 | Gen/Dis Loss: -0.0007/-0.0002\n", "Epoch: 042/100 | Batch 300/469 | Gen/Dis Loss: -0.0091/0.0000\n", "Epoch: 042/100 | Batch 400/469 | Gen/Dis Loss: -0.0043/0.0001\n", "Time elapsed: 18.34 min\n", "Epoch: 043/100 | Batch 000/469 | Gen/Dis Loss: 0.0023/-0.0008\n", "Epoch: 043/100 | Batch 100/469 | Gen/Dis Loss: -0.0025/-0.0006\n", "Epoch: 043/100 | Batch 200/469 | Gen/Dis Loss: -0.0066/-0.0006\n", "Epoch: 043/100 | Batch 300/469 | Gen/Dis Loss: -0.0074/0.0004\n", "Epoch: 043/100 | Batch 400/469 | Gen/Dis Loss: -0.0021/-0.0018\n", "Time elapsed: 18.86 min\n", "Epoch: 044/100 | Batch 000/469 | Gen/Dis Loss: -0.0033/0.0001\n", "Epoch: 044/100 | Batch 100/469 | Gen/Dis Loss: 0.0019/0.0003\n", "Epoch: 044/100 | Batch 200/469 | Gen/Dis Loss: 0.0014/-0.0021\n", "Epoch: 044/100 | Batch 300/469 | Gen/Dis Loss: -0.0003/-0.0016\n", "Epoch: 044/100 | Batch 400/469 | Gen/Dis Loss: -0.0072/-0.0009\n", "Time elapsed: 19.35 min\n", "Epoch: 045/100 | Batch 000/469 | Gen/Dis Loss: -0.0013/-0.0012\n", "Epoch: 045/100 | Batch 100/469 | Gen/Dis Loss: -0.0002/-0.0002\n", "Epoch: 045/100 | Batch 200/469 | Gen/Dis Loss: 0.0008/0.0005\n", "Epoch: 045/100 | Batch 300/469 | Gen/Dis Loss: 0.0056/-0.0006\n", "Epoch: 045/100 | Batch 400/469 | Gen/Dis Loss: -0.0134/0.0001\n", "Time elapsed: 19.88 min\n", "Epoch: 046/100 | Batch 000/469 | Gen/Dis Loss: -0.0147/0.0003\n", "Epoch: 046/100 | Batch 100/469 | Gen/Dis Loss: 0.0120/0.0002\n", "Epoch: 046/100 | Batch 200/469 | Gen/Dis Loss: -0.0061/-0.0006\n", "Epoch: 046/100 | Batch 300/469 | Gen/Dis Loss: 0.0007/-0.0012\n", "Epoch: 046/100 | Batch 400/469 | Gen/Dis Loss: -0.0118/0.0007\n", "Time elapsed: 20.40 min\n", "Epoch: 047/100 | Batch 000/469 | Gen/Dis Loss: 0.0015/-0.0018\n", "Epoch: 047/100 | Batch 100/469 | Gen/Dis Loss: -0.0118/-0.0000\n", "Epoch: 047/100 | Batch 200/469 | Gen/Dis Loss: 0.0048/0.0009\n", "Epoch: 047/100 | Batch 300/469 | Gen/Dis Loss: -0.0124/-0.0005\n", "Epoch: 047/100 | Batch 400/469 | Gen/Dis Loss: -0.0039/0.0002\n", "Time elapsed: 20.91 min\n", "Epoch: 048/100 | Batch 000/469 | Gen/Dis Loss: 0.0008/-0.0021\n", "Epoch: 048/100 | Batch 100/469 | Gen/Dis Loss: -0.0005/-0.0018\n", "Epoch: 048/100 | Batch 200/469 | Gen/Dis Loss: 0.0010/-0.0005\n", "Epoch: 048/100 | Batch 300/469 | Gen/Dis Loss: 0.0115/0.0001\n", "Epoch: 048/100 | Batch 400/469 | Gen/Dis Loss: 0.0111/-0.0002\n", "Time elapsed: 21.40 min\n", "Epoch: 049/100 | Batch 000/469 | Gen/Dis Loss: -0.0005/-0.0015\n", "Epoch: 049/100 | Batch 100/469 | Gen/Dis Loss: 0.0011/0.0006\n", "Epoch: 049/100 | Batch 200/469 | Gen/Dis Loss: -0.0071/-0.0001\n", "Epoch: 049/100 | Batch 300/469 | Gen/Dis Loss: -0.0178/0.0002\n", "Epoch: 049/100 | Batch 400/469 | Gen/Dis Loss: 0.0072/-0.0016\n", "Time elapsed: 21.93 min\n", "Epoch: 050/100 | Batch 000/469 | Gen/Dis Loss: -0.0129/0.0002\n", "Epoch: 050/100 | Batch 100/469 | Gen/Dis Loss: 0.0003/-0.0013\n", "Epoch: 050/100 | Batch 200/469 | Gen/Dis Loss: -0.0002/-0.0005\n", "Epoch: 050/100 | Batch 300/469 | Gen/Dis Loss: -0.0052/-0.0002\n", "Epoch: 050/100 | Batch 400/469 | Gen/Dis Loss: -0.0026/0.0008\n", "Time elapsed: 22.46 min\n", "Epoch: 051/100 | Batch 000/469 | Gen/Dis Loss: -0.0113/0.0000\n", "Epoch: 051/100 | Batch 100/469 | Gen/Dis Loss: -0.0013/-0.0012\n", "Epoch: 051/100 | Batch 200/469 | Gen/Dis Loss: 0.0119/0.0004\n", "Epoch: 051/100 | Batch 300/469 | Gen/Dis Loss: -0.0066/0.0003\n", "Epoch: 051/100 | Batch 400/469 | Gen/Dis Loss: -0.0078/-0.0013\n", "Time elapsed: 22.98 min\n", "Epoch: 052/100 | Batch 000/469 | Gen/Dis Loss: 0.0033/-0.0019\n", "Epoch: 052/100 | Batch 100/469 | Gen/Dis Loss: -0.0053/-0.0001\n", "Epoch: 052/100 | Batch 200/469 | Gen/Dis Loss: 0.0040/0.0007\n", "Epoch: 052/100 | Batch 300/469 | Gen/Dis Loss: 0.0033/-0.0021\n", "Time elapsed: 23.50 min\n", "Epoch: 053/100 | Batch 000/469 | Gen/Dis Loss: -0.0034/-0.0008\n", "Epoch: 053/100 | Batch 100/469 | Gen/Dis Loss: 0.0042/-0.0001\n", "Epoch: 053/100 | Batch 200/469 | Gen/Dis Loss: 0.0124/-0.0001\n", "Epoch: 053/100 | Batch 300/469 | Gen/Dis Loss: -0.0017/0.0004\n", "Epoch: 053/100 | Batch 400/469 | Gen/Dis Loss: -0.0066/0.0002\n", "Time elapsed: 24.02 min\n", "Epoch: 054/100 | Batch 000/469 | Gen/Dis Loss: 0.0108/-0.0000\n", "Epoch: 054/100 | Batch 100/469 | Gen/Dis Loss: -0.0019/-0.0019\n", "Epoch: 054/100 | Batch 200/469 | Gen/Dis Loss: 0.0058/-0.0010\n", "Epoch: 054/100 | Batch 300/469 | Gen/Dis Loss: 0.0080/-0.0002\n", "Epoch: 054/100 | Batch 400/469 | Gen/Dis Loss: -0.0115/-0.0003\n", "Time elapsed: 24.55 min\n", "Epoch: 055/100 | Batch 000/469 | Gen/Dis Loss: 0.0126/-0.0001\n", "Epoch: 055/100 | Batch 100/469 | Gen/Dis Loss: 0.0151/-0.0007\n", "Epoch: 055/100 | Batch 200/469 | Gen/Dis Loss: -0.0005/0.0007\n", "Epoch: 055/100 | Batch 300/469 | Gen/Dis Loss: 0.0079/-0.0014\n", "Epoch: 055/100 | Batch 400/469 | Gen/Dis Loss: -0.0089/-0.0005\n", "Time elapsed: 25.07 min\n", "Epoch: 056/100 | Batch 000/469 | Gen/Dis Loss: -0.0097/0.0002\n", "Epoch: 056/100 | Batch 100/469 | Gen/Dis Loss: -0.0038/0.0010\n", "Epoch: 056/100 | Batch 200/469 | Gen/Dis Loss: -0.0095/0.0006\n", "Epoch: 056/100 | Batch 300/469 | Gen/Dis Loss: -0.0044/-0.0008\n", "Epoch: 056/100 | Batch 400/469 | Gen/Dis Loss: -0.0044/-0.0016\n", "Time elapsed: 25.58 min\n", "Epoch: 057/100 | Batch 000/469 | Gen/Dis Loss: -0.0152/-0.0004\n", "Epoch: 057/100 | Batch 100/469 | Gen/Dis Loss: 0.0012/-0.0002\n", "Epoch: 057/100 | Batch 200/469 | Gen/Dis Loss: -0.0033/-0.0004\n", "Epoch: 057/100 | Batch 300/469 | Gen/Dis Loss: 0.0100/-0.0000\n", "Epoch: 057/100 | Batch 400/469 | Gen/Dis Loss: -0.0003/-0.0003\n", "Time elapsed: 26.10 min\n", "Epoch: 058/100 | Batch 000/469 | Gen/Dis Loss: -0.0068/-0.0003\n", "Epoch: 058/100 | Batch 100/469 | Gen/Dis Loss: -0.0049/0.0001\n", "Epoch: 058/100 | Batch 200/469 | Gen/Dis Loss: 0.0008/0.0003\n", "Epoch: 058/100 | Batch 300/469 | Gen/Dis Loss: -0.0002/-0.0016\n", "Epoch: 058/100 | Batch 400/469 | Gen/Dis Loss: -0.0016/-0.0004\n", "Time elapsed: 26.57 min\n", "Epoch: 059/100 | Batch 000/469 | Gen/Dis Loss: -0.0093/-0.0001\n", "Epoch: 059/100 | Batch 100/469 | Gen/Dis Loss: 0.0033/-0.0002\n", "Epoch: 059/100 | Batch 200/469 | Gen/Dis Loss: 0.0009/-0.0004\n", "Epoch: 059/100 | Batch 300/469 | Gen/Dis Loss: -0.0142/-0.0001\n", "Epoch: 059/100 | Batch 400/469 | Gen/Dis Loss: -0.0129/0.0001\n", "Time elapsed: 26.97 min\n", "Epoch: 060/100 | Batch 000/469 | Gen/Dis Loss: -0.0021/-0.0009\n", "Epoch: 060/100 | Batch 100/469 | Gen/Dis Loss: 0.0020/-0.0002\n", "Epoch: 060/100 | Batch 200/469 | Gen/Dis Loss: -0.0099/-0.0010\n", "Epoch: 060/100 | Batch 300/469 | Gen/Dis Loss: -0.0112/0.0001\n", "Epoch: 060/100 | Batch 400/469 | Gen/Dis Loss: -0.0024/-0.0004\n", "Time elapsed: 27.28 min\n", "Epoch: 061/100 | Batch 000/469 | Gen/Dis Loss: -0.0044/-0.0012\n", "Epoch: 061/100 | Batch 100/469 | Gen/Dis Loss: -0.0034/-0.0005\n", "Epoch: 061/100 | Batch 200/469 | Gen/Dis Loss: -0.0031/-0.0009\n", "Epoch: 061/100 | Batch 300/469 | Gen/Dis Loss: -0.0058/-0.0000\n", "Epoch: 061/100 | Batch 400/469 | Gen/Dis Loss: -0.0034/0.0003\n", "Time elapsed: 27.59 min\n", "Epoch: 062/100 | Batch 000/469 | Gen/Dis Loss: -0.0017/-0.0014\n", "Epoch: 062/100 | Batch 100/469 | Gen/Dis Loss: -0.0043/0.0000\n", "Epoch: 062/100 | Batch 200/469 | Gen/Dis Loss: -0.0055/0.0001\n", "Epoch: 062/100 | Batch 300/469 | Gen/Dis Loss: 0.0066/-0.0009\n", "Epoch: 062/100 | Batch 400/469 | Gen/Dis Loss: -0.0013/0.0007\n", "Time elapsed: 27.89 min\n", "Epoch: 063/100 | Batch 000/469 | Gen/Dis Loss: 0.0031/-0.0013\n", "Epoch: 063/100 | Batch 100/469 | Gen/Dis Loss: -0.0093/0.0000\n", "Epoch: 063/100 | Batch 200/469 | Gen/Dis Loss: -0.0041/-0.0003\n", "Epoch: 063/100 | Batch 300/469 | Gen/Dis Loss: 0.0093/-0.0003\n", "Epoch: 063/100 | Batch 400/469 | Gen/Dis Loss: 0.0140/0.0003\n", "Time elapsed: 28.20 min\n", "Epoch: 064/100 | Batch 000/469 | Gen/Dis Loss: 0.0119/0.0003\n", "Epoch: 064/100 | Batch 100/469 | Gen/Dis Loss: 0.0124/-0.0009\n", "Epoch: 064/100 | Batch 200/469 | Gen/Dis Loss: -0.0076/0.0001\n", "Epoch: 064/100 | Batch 300/469 | Gen/Dis Loss: -0.0027/-0.0002\n", "Epoch: 064/100 | Batch 400/469 | Gen/Dis Loss: 0.0005/0.0002\n", "Time elapsed: 28.51 min\n", "Epoch: 065/100 | Batch 000/469 | Gen/Dis Loss: -0.0002/0.0005\n", "Epoch: 065/100 | Batch 100/469 | Gen/Dis Loss: 0.0005/-0.0006\n", "Epoch: 065/100 | Batch 200/469 | Gen/Dis Loss: 0.0089/0.0001\n", "Epoch: 065/100 | Batch 300/469 | Gen/Dis Loss: -0.0060/-0.0007\n", "Epoch: 065/100 | Batch 400/469 | Gen/Dis Loss: 0.0010/-0.0006\n", "Time elapsed: 28.82 min\n", "Epoch: 066/100 | Batch 000/469 | Gen/Dis Loss: 0.0078/0.0003\n", "Epoch: 066/100 | Batch 100/469 | Gen/Dis Loss: 0.0001/0.0003\n", "Epoch: 066/100 | Batch 200/469 | Gen/Dis Loss: -0.0047/-0.0001\n", "Epoch: 066/100 | Batch 300/469 | Gen/Dis Loss: 0.0067/-0.0005\n", "Epoch: 066/100 | Batch 400/469 | Gen/Dis Loss: 0.0030/-0.0004\n", "Time elapsed: 29.13 min\n", "Epoch: 067/100 | Batch 000/469 | Gen/Dis Loss: 0.0048/-0.0002\n", "Epoch: 067/100 | Batch 100/469 | Gen/Dis Loss: 0.0046/-0.0004\n", "Epoch: 067/100 | Batch 200/469 | Gen/Dis Loss: -0.0027/-0.0002\n", "Epoch: 067/100 | Batch 300/469 | Gen/Dis Loss: 0.0040/-0.0005\n", "Epoch: 067/100 | Batch 400/469 | Gen/Dis Loss: 0.0062/-0.0004\n", "Time elapsed: 29.44 min\n", "Epoch: 068/100 | Batch 000/469 | Gen/Dis Loss: 0.0033/0.0000\n", "Epoch: 068/100 | Batch 100/469 | Gen/Dis Loss: 0.0000/-0.0007\n", "Epoch: 068/100 | Batch 200/469 | Gen/Dis Loss: -0.0038/0.0001\n", "Epoch: 068/100 | Batch 300/469 | Gen/Dis Loss: -0.0047/-0.0000\n", "Epoch: 068/100 | Batch 400/469 | Gen/Dis Loss: 0.0131/-0.0001\n", "Time elapsed: 29.74 min\n", "Epoch: 069/100 | Batch 000/469 | Gen/Dis Loss: 0.0051/-0.0004\n", "Epoch: 069/100 | Batch 100/469 | Gen/Dis Loss: 0.0027/-0.0002\n", "Epoch: 069/100 | Batch 200/469 | Gen/Dis Loss: -0.0019/-0.0005\n", "Epoch: 069/100 | Batch 300/469 | Gen/Dis Loss: 0.0072/-0.0000\n", "Epoch: 069/100 | Batch 400/469 | Gen/Dis Loss: -0.0068/0.0002\n", "Time elapsed: 30.05 min\n", "Epoch: 070/100 | Batch 000/469 | Gen/Dis Loss: 0.0098/-0.0007\n", "Epoch: 070/100 | Batch 100/469 | Gen/Dis Loss: -0.0070/-0.0001\n", "Epoch: 070/100 | Batch 200/469 | Gen/Dis Loss: 0.0102/-0.0005\n", "Epoch: 070/100 | Batch 300/469 | Gen/Dis Loss: -0.0098/0.0000\n", "Epoch: 070/100 | Batch 400/469 | Gen/Dis Loss: -0.0121/-0.0001\n", "Time elapsed: 30.37 min\n", "Epoch: 071/100 | Batch 000/469 | Gen/Dis Loss: 0.0081/0.0000\n", "Epoch: 071/100 | Batch 100/469 | Gen/Dis Loss: 0.0028/-0.0002\n", "Epoch: 071/100 | Batch 200/469 | Gen/Dis Loss: -0.0082/-0.0002\n", "Epoch: 071/100 | Batch 300/469 | Gen/Dis Loss: 0.0113/-0.0003\n", "Epoch: 071/100 | Batch 400/469 | Gen/Dis Loss: 0.0028/-0.0009\n", "Time elapsed: 30.68 min\n", "Epoch: 072/100 | Batch 000/469 | Gen/Dis Loss: 0.0087/-0.0003\n", "Epoch: 072/100 | Batch 100/469 | Gen/Dis Loss: -0.0092/0.0004\n", "Epoch: 072/100 | Batch 200/469 | Gen/Dis Loss: 0.0016/-0.0002\n", "Epoch: 072/100 | Batch 300/469 | Gen/Dis Loss: 0.0059/-0.0011\n", "Epoch: 072/100 | Batch 400/469 | Gen/Dis Loss: -0.0058/-0.0004\n", "Time elapsed: 30.99 min\n", "Epoch: 073/100 | Batch 000/469 | Gen/Dis Loss: -0.0079/-0.0006\n", "Epoch: 073/100 | Batch 100/469 | Gen/Dis Loss: 0.0076/-0.0001\n", "Epoch: 073/100 | Batch 200/469 | Gen/Dis Loss: -0.0003/-0.0004\n", "Epoch: 073/100 | Batch 300/469 | Gen/Dis Loss: 0.0090/-0.0000\n", "Epoch: 073/100 | Batch 400/469 | Gen/Dis Loss: 0.0064/-0.0003\n", "Time elapsed: 31.29 min\n", "Epoch: 074/100 | Batch 000/469 | Gen/Dis Loss: -0.0062/0.0002\n", "Epoch: 074/100 | Batch 100/469 | Gen/Dis Loss: 0.0074/0.0004\n", "Epoch: 074/100 | Batch 200/469 | Gen/Dis Loss: 0.0034/-0.0004\n", "Epoch: 074/100 | Batch 300/469 | Gen/Dis Loss: -0.0032/0.0000\n", "Epoch: 074/100 | Batch 400/469 | Gen/Dis Loss: 0.0045/-0.0016\n", "Time elapsed: 31.61 min\n", "Epoch: 075/100 | Batch 000/469 | Gen/Dis Loss: 0.0067/-0.0018\n", "Epoch: 075/100 | Batch 100/469 | Gen/Dis Loss: -0.0029/-0.0007\n", "Epoch: 075/100 | Batch 200/469 | Gen/Dis Loss: -0.0014/-0.0001\n", "Epoch: 075/100 | Batch 300/469 | Gen/Dis Loss: -0.0001/-0.0013\n", "Epoch: 075/100 | Batch 400/469 | Gen/Dis Loss: -0.0023/-0.0006\n", "Time elapsed: 31.91 min\n", "Epoch: 076/100 | Batch 000/469 | Gen/Dis Loss: 0.0036/-0.0008\n", "Epoch: 076/100 | Batch 100/469 | Gen/Dis Loss: -0.0003/-0.0001\n", "Epoch: 076/100 | Batch 200/469 | Gen/Dis Loss: 0.0024/-0.0001\n", "Epoch: 076/100 | Batch 300/469 | Gen/Dis Loss: 0.0006/-0.0003\n", "Epoch: 076/100 | Batch 400/469 | Gen/Dis Loss: -0.0000/0.0000\n", "Time elapsed: 32.23 min\n", "Epoch: 077/100 | Batch 000/469 | Gen/Dis Loss: -0.0022/0.0005\n", "Epoch: 077/100 | Batch 100/469 | Gen/Dis Loss: 0.0091/-0.0000\n", "Epoch: 077/100 | Batch 200/469 | Gen/Dis Loss: 0.0090/-0.0004\n", "Epoch: 077/100 | Batch 300/469 | Gen/Dis Loss: -0.0045/-0.0001\n", "Epoch: 077/100 | Batch 400/469 | Gen/Dis Loss: 0.0035/0.0006\n", "Time elapsed: 32.53 min\n", "Epoch: 078/100 | Batch 000/469 | Gen/Dis Loss: 0.0089/0.0001\n", "Epoch: 078/100 | Batch 100/469 | Gen/Dis Loss: 0.0075/-0.0003\n", "Epoch: 078/100 | Batch 200/469 | Gen/Dis Loss: -0.0023/-0.0014\n", "Epoch: 078/100 | Batch 300/469 | Gen/Dis Loss: 0.0030/-0.0012\n", "Epoch: 078/100 | Batch 400/469 | Gen/Dis Loss: -0.0115/0.0000\n", "Time elapsed: 32.84 min\n", "Epoch: 079/100 | Batch 000/469 | Gen/Dis Loss: -0.0055/0.0006\n", "Epoch: 079/100 | Batch 100/469 | Gen/Dis Loss: -0.0082/-0.0001\n", "Epoch: 079/100 | Batch 200/469 | Gen/Dis Loss: -0.0013/-0.0006\n", "Epoch: 079/100 | Batch 300/469 | Gen/Dis Loss: -0.0147/0.0006\n", "Epoch: 079/100 | Batch 400/469 | Gen/Dis Loss: 0.0019/-0.0005\n", "Time elapsed: 33.15 min\n", "Epoch: 080/100 | Batch 000/469 | Gen/Dis Loss: -0.0017/-0.0001\n", "Epoch: 080/100 | Batch 100/469 | Gen/Dis Loss: -0.0035/-0.0014\n", "Epoch: 080/100 | Batch 200/469 | Gen/Dis Loss: -0.0055/0.0005\n", "Epoch: 080/100 | Batch 300/469 | Gen/Dis Loss: 0.0093/0.0001\n", "Epoch: 080/100 | Batch 400/469 | Gen/Dis Loss: 0.0036/-0.0003\n", "Time elapsed: 33.45 min\n", "Epoch: 081/100 | Batch 000/469 | Gen/Dis Loss: -0.0003/-0.0008\n", "Epoch: 081/100 | Batch 100/469 | Gen/Dis Loss: -0.0013/-0.0002\n", "Epoch: 081/100 | Batch 200/469 | Gen/Dis Loss: -0.0011/0.0001\n", "Epoch: 081/100 | Batch 300/469 | Gen/Dis Loss: 0.0014/-0.0009\n", "Epoch: 081/100 | Batch 400/469 | Gen/Dis Loss: -0.0065/0.0005\n", "Time elapsed: 33.76 min\n", "Epoch: 082/100 | Batch 000/469 | Gen/Dis Loss: 0.0072/-0.0007\n", "Epoch: 082/100 | Batch 100/469 | Gen/Dis Loss: 0.0079/-0.0005\n", "Epoch: 082/100 | Batch 200/469 | Gen/Dis Loss: -0.0043/-0.0005\n", "Epoch: 082/100 | Batch 300/469 | Gen/Dis Loss: -0.0119/0.0002\n", "Epoch: 082/100 | Batch 400/469 | Gen/Dis Loss: -0.0008/-0.0007\n", "Time elapsed: 34.06 min\n", "Epoch: 083/100 | Batch 000/469 | Gen/Dis Loss: -0.0010/-0.0015\n", "Epoch: 083/100 | Batch 100/469 | Gen/Dis Loss: 0.0126/-0.0000\n", "Epoch: 083/100 | Batch 200/469 | Gen/Dis Loss: -0.0006/-0.0008\n", "Epoch: 083/100 | Batch 300/469 | Gen/Dis Loss: 0.0055/-0.0005\n", "Epoch: 083/100 | Batch 400/469 | Gen/Dis Loss: 0.0085/-0.0000\n", "Time elapsed: 34.37 min\n", "Epoch: 084/100 | Batch 000/469 | Gen/Dis Loss: -0.0085/-0.0003\n", "Epoch: 084/100 | Batch 100/469 | Gen/Dis Loss: -0.0008/-0.0001\n", "Epoch: 084/100 | Batch 200/469 | Gen/Dis Loss: 0.0046/-0.0001\n", "Epoch: 084/100 | Batch 300/469 | Gen/Dis Loss: -0.0052/-0.0002\n", "Epoch: 084/100 | Batch 400/469 | Gen/Dis Loss: -0.0037/-0.0002\n", "Time elapsed: 34.67 min\n", "Epoch: 085/100 | Batch 000/469 | Gen/Dis Loss: -0.0008/-0.0006\n", "Epoch: 085/100 | Batch 100/469 | Gen/Dis Loss: -0.0061/-0.0001\n", "Epoch: 085/100 | Batch 200/469 | Gen/Dis Loss: -0.0102/0.0001\n", "Epoch: 085/100 | Batch 300/469 | Gen/Dis Loss: 0.0008/-0.0008\n", "Epoch: 085/100 | Batch 400/469 | Gen/Dis Loss: -0.0019/-0.0004\n", "Time elapsed: 34.99 min\n", "Epoch: 086/100 | Batch 000/469 | Gen/Dis Loss: -0.0029/0.0001\n", "Epoch: 086/100 | Batch 100/469 | Gen/Dis Loss: 0.0046/-0.0001\n", "Epoch: 086/100 | Batch 200/469 | Gen/Dis Loss: -0.0042/-0.0005\n", "Epoch: 086/100 | Batch 300/469 | Gen/Dis Loss: -0.0082/-0.0002\n", "Epoch: 086/100 | Batch 400/469 | Gen/Dis Loss: -0.0093/-0.0004\n", "Time elapsed: 35.29 min\n", "Epoch: 087/100 | Batch 000/469 | Gen/Dis Loss: -0.0035/0.0002\n", "Epoch: 087/100 | Batch 100/469 | Gen/Dis Loss: -0.0071/0.0000\n", "Epoch: 087/100 | Batch 200/469 | Gen/Dis Loss: 0.0018/0.0002\n", "Epoch: 087/100 | Batch 300/469 | Gen/Dis Loss: -0.0019/-0.0004\n", "Epoch: 087/100 | Batch 400/469 | Gen/Dis Loss: 0.0075/-0.0002\n", "Time elapsed: 35.60 min\n", "Epoch: 088/100 | Batch 000/469 | Gen/Dis Loss: 0.0017/-0.0003\n", "Epoch: 088/100 | Batch 100/469 | Gen/Dis Loss: 0.0024/-0.0005\n", "Epoch: 088/100 | Batch 200/469 | Gen/Dis Loss: -0.0023/-0.0003\n", "Epoch: 088/100 | Batch 300/469 | Gen/Dis Loss: 0.0001/-0.0005\n", "Epoch: 088/100 | Batch 400/469 | Gen/Dis Loss: -0.0027/-0.0003\n", "Time elapsed: 35.91 min\n", "Epoch: 089/100 | Batch 000/469 | Gen/Dis Loss: -0.0039/-0.0007\n", "Epoch: 089/100 | Batch 100/469 | Gen/Dis Loss: -0.0031/-0.0003\n", "Epoch: 089/100 | Batch 200/469 | Gen/Dis Loss: 0.0024/-0.0003\n", "Epoch: 089/100 | Batch 300/469 | Gen/Dis Loss: -0.0041/-0.0001\n", "Epoch: 089/100 | Batch 400/469 | Gen/Dis Loss: 0.0014/-0.0005\n", "Time elapsed: 36.22 min\n", "Epoch: 090/100 | Batch 000/469 | Gen/Dis Loss: -0.0012/-0.0004\n", "Epoch: 090/100 | Batch 100/469 | Gen/Dis Loss: -0.0022/-0.0004\n", "Epoch: 090/100 | Batch 200/469 | Gen/Dis Loss: -0.0083/-0.0005\n", "Epoch: 090/100 | Batch 300/469 | Gen/Dis Loss: -0.0047/-0.0004\n", "Epoch: 090/100 | Batch 400/469 | Gen/Dis Loss: 0.0001/-0.0003\n", "Time elapsed: 36.52 min\n", "Epoch: 091/100 | Batch 000/469 | Gen/Dis Loss: -0.0013/-0.0003\n", "Epoch: 091/100 | Batch 100/469 | Gen/Dis Loss: -0.0040/-0.0005\n", "Epoch: 091/100 | Batch 200/469 | Gen/Dis Loss: -0.0029/-0.0003\n", "Epoch: 091/100 | Batch 300/469 | Gen/Dis Loss: -0.0026/-0.0003\n", "Epoch: 091/100 | Batch 400/469 | Gen/Dis Loss: -0.0001/-0.0002\n", "Time elapsed: 36.84 min\n", "Epoch: 092/100 | Batch 000/469 | Gen/Dis Loss: 0.0051/-0.0004\n", "Epoch: 092/100 | Batch 100/469 | Gen/Dis Loss: -0.0005/-0.0003\n", "Epoch: 092/100 | Batch 200/469 | Gen/Dis Loss: 0.0041/-0.0004\n", "Epoch: 092/100 | Batch 300/469 | Gen/Dis Loss: 0.0020/-0.0004\n", "Epoch: 092/100 | Batch 400/469 | Gen/Dis Loss: 0.0004/-0.0003\n", "Time elapsed: 37.15 min\n", "Epoch: 093/100 | Batch 000/469 | Gen/Dis Loss: -0.0005/-0.0003\n", "Epoch: 093/100 | Batch 100/469 | Gen/Dis Loss: 0.0008/-0.0004\n", "Epoch: 093/100 | Batch 200/469 | Gen/Dis Loss: -0.0013/-0.0004\n", "Epoch: 093/100 | Batch 300/469 | Gen/Dis Loss: -0.0007/-0.0004\n", "Epoch: 093/100 | Batch 400/469 | Gen/Dis Loss: -0.0013/-0.0002\n", "Time elapsed: 37.45 min\n", "Epoch: 094/100 | Batch 000/469 | Gen/Dis Loss: -0.0017/-0.0003\n", "Epoch: 094/100 | Batch 100/469 | Gen/Dis Loss: -0.0018/-0.0003\n", "Epoch: 094/100 | Batch 200/469 | Gen/Dis Loss: -0.0018/-0.0003\n", "Epoch: 094/100 | Batch 300/469 | Gen/Dis Loss: -0.0017/-0.0003\n", "Epoch: 094/100 | Batch 400/469 | Gen/Dis Loss: -0.0019/-0.0003\n", "Time elapsed: 37.75 min\n", "Epoch: 095/100 | Batch 000/469 | Gen/Dis Loss: -0.0026/-0.0003\n", "Epoch: 095/100 | Batch 100/469 | Gen/Dis Loss: -0.0022/-0.0003\n", "Epoch: 095/100 | Batch 200/469 | Gen/Dis Loss: -0.0014/-0.0003\n", "Epoch: 095/100 | Batch 300/469 | Gen/Dis Loss: -0.0005/-0.0002\n", "Epoch: 095/100 | Batch 400/469 | Gen/Dis Loss: -0.0008/-0.0002\n", "Time elapsed: 38.06 min\n", "Epoch: 096/100 | Batch 000/469 | Gen/Dis Loss: -0.0002/-0.0003\n", "Epoch: 096/100 | Batch 100/469 | Gen/Dis Loss: 0.0011/-0.0003\n", "Epoch: 096/100 | Batch 200/469 | Gen/Dis Loss: 0.0006/-0.0003\n", "Epoch: 096/100 | Batch 300/469 | Gen/Dis Loss: 0.0019/-0.0004\n", "Epoch: 096/100 | Batch 400/469 | Gen/Dis Loss: 0.0012/-0.0003\n", "Time elapsed: 38.37 min\n", "Epoch: 097/100 | Batch 000/469 | Gen/Dis Loss: -0.0001/-0.0003\n", "Epoch: 097/100 | Batch 100/469 | Gen/Dis Loss: -0.0007/-0.0004\n", "Epoch: 097/100 | Batch 200/469 | Gen/Dis Loss: -0.0015/-0.0003\n", "Epoch: 097/100 | Batch 300/469 | Gen/Dis Loss: -0.0034/-0.0003\n", "Epoch: 097/100 | Batch 400/469 | Gen/Dis Loss: -0.0007/-0.0004\n", "Time elapsed: 38.67 min\n", "Epoch: 098/100 | Batch 000/469 | Gen/Dis Loss: -0.0004/-0.0003\n", "Epoch: 098/100 | Batch 100/469 | Gen/Dis Loss: -0.0015/-0.0004\n", "Epoch: 098/100 | Batch 200/469 | Gen/Dis Loss: -0.0017/-0.0002\n", "Epoch: 098/100 | Batch 300/469 | Gen/Dis Loss: -0.0014/-0.0004\n", "Epoch: 098/100 | Batch 400/469 | Gen/Dis Loss: -0.0037/-0.0004\n", "Time elapsed: 38.97 min\n", "Epoch: 099/100 | Batch 000/469 | Gen/Dis Loss: -0.0055/-0.0003\n", "Epoch: 099/100 | Batch 100/469 | Gen/Dis Loss: -0.0039/-0.0003\n", "Epoch: 099/100 | Batch 200/469 | Gen/Dis Loss: -0.0037/-0.0003\n", "Epoch: 099/100 | Batch 300/469 | Gen/Dis Loss: -0.0041/-0.0003\n", "Epoch: 099/100 | Batch 400/469 | Gen/Dis Loss: -0.0044/-0.0003\n", "Time elapsed: 39.27 min\n", "Epoch: 100/100 | Batch 000/469 | Gen/Dis Loss: -0.0041/-0.0002\n", "Epoch: 100/100 | Batch 100/469 | Gen/Dis Loss: -0.0024/-0.0003\n", "Epoch: 100/100 | Batch 200/469 | Gen/Dis Loss: -0.0021/-0.0002\n", "Epoch: 100/100 | Batch 300/469 | Gen/Dis Loss: -0.0033/-0.0002\n", "Epoch: 100/100 | Batch 400/469 | Gen/Dis Loss: -0.0035/-0.0002\n", "Time elapsed: 39.57 min\n", "Total Training Time: 39.57 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", " # Normalize images to [-1, 1] range\n", " features = (features - 0.5)*2.\n", " features = features.view(-1, IMG_SIZE).to(device) \n", "\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_(0.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.view(targets.size(0), 1, 28, 28))\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", " # --------------------------\n", " # Train Discriminator\n", " # -------------------------- \n", "\n", " # WGAN: Multiple loops for the discriminator\n", " for _ in range(num_iter_critic):\n", " \n", " discr_pred_real = model.discriminator_forward(features.view(targets.size(0), 1, 28, 28))\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.view(targets.size(0), 1, 28, 28).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", " discr_loss = 0.5*(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", " ### 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": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'\\nfor i in outputs:\\n print(i.size())\\n'" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "### For Debugging\n", "\n", "\"\"\"\n", "for i in outputs:\n", " print(i.size())\n", "\"\"\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Evaluation" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "%matplotlib inline\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYgAAAEzCAYAAAArTpSQAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjAsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+17YcXAAAgAElEQVR4nO3deXwV1d3H8c8vCUnYdxQJyiKIbAYNiGIBQRZFkbZaccXlqaVuVdpaLBURu1D1sa5VeRSX1op1R8UVVxSVfRdZ1QgCsiMk5Ca/5487CTfJJCSQmyD5vl+v+7ozZ87MOTP33vndOTNzxtwdERGRohKqugIiInJwUoAQEZFQChAiIhJKAUJEREIpQIiISKikqq5ARUlISPCaNWtWdTVERH5Udu3a5e4eerBwyASImjVr8sMPP1R1NUREflTMbHdJ09TEJCIioRQgREQklAKEiIiEOmTOQYhI2eXk5JCZmUlWVlZVV0UqSWpqKmlpadSoUaPM8yhAiFRDmZmZ1K1bl1atWmFmVV0diTN3Z9OmTWRmZtK6desyz6cmJpFqKCsri8aNGys4VBNmRuPGjct9xKgAIVJNKThUL/vzeVf7ALFrT4S73lrG3K+3VHVVREQOKtU+QOzek8u9765g4bfbqroqItXK+vXrueCCC2jTpg0nnHACJ510Ei+++GKV1ef999/nk08+OeBlnHnmmRVUo6pX7QOEiFQ+d2fYsGH07t2bVatWMXv2bCZPnkxmZmZcy41EIiVO258AUdryDgUKECJS6d59912Sk5MZOXJkQdpRRx3FtddeC0Bubi6///3v6d69O127duXhhx8Gojvxvn37cs4559ChQwcuvPBC8p+KOXv2bPr06cMJJ5zAoEGDWLduHQB9+/blj3/8I3369OGee+7hlVde4cQTT6Rbt26cdtpprF+/njVr1vDQQw/xj3/8g/T0dD766CO++uor+vfvT9euXenfvz9ff/01AJdeeimjRo3i1FNP5Q9/+EOJ67h582aGDRtG165d6dmzJwsWLADggw8+ID09nfT0dLp168aOHTtYt24dvXv3Jj09nc6dO/PRRx9V/EbfD7rMVaSau/WVxSxZu71Cl9nxiHrcclanEqcvXryY448/vsTpjz76KPXr12fmzJlkZ2fTq1cvBg4cCMDcuXNZvHgxRxxxBL169eLjjz/mxBNP5Nprr+Xll1+madOmPPPMM4wZM4ZJkyYBsHXrVj744AMAtmzZwqeffoqZ8cgjj3D77bfzv//7v4wcOZI6derwu9/9DoCzzjqLSy65hBEjRjBp0iSuu+46XnrpJQC+/PJL3nnnHRITE0tch1tuuYVu3brx0ksv8e6773LJJZcwb9487rzzTh544AF69erFzp07SU1NZeLEiQwaNIgxY8aQm5vLrl27yrfB40QBQkSq3NVXX8306dNJTk5m5syZvPXWWyxYsIDnnnsOgG3btrF8+XKSk5Pp0aMHaWlpAKSnp7NmzRoaNGjAokWLGDBgABA9AmnevHnB8s8777yC4czMTM477zzWrVvHnj17SrwvYMaMGbzwwgsAXHzxxdx4440F084999xSgwPA9OnTef755wHo168fmzZtYtu2bfTq1YtRo0Zx4YUX8rOf/Yy0tDS6d+/O5ZdfTk5ODsOGDSM9Pb28mzAuFCBEqrnS/unHS6dOnQp2ngAPPPAA33//PRkZGUD0HMV9993HoEGDCs33/vvvk5KSUjCemJhIJBLB3enUqRMzZswILa927doFw9deey2jRo1i6NChvP/++4wbN65MdY69TDR2eSXJb/oquozRo0czZMgQpk6dSs+ePXnnnXfo3bs3H374Ia+99hoXX3wxv//977nkkkvKVK940jkIEal0/fr1IysriwcffLAgLbZZZdCgQTz44IPk5OQA0Sad0rrzP+aYY9i4cWNBgMjJyWHx4sWhebdt20aLFi0AeOKJJwrS69aty44dOwrGTz75ZCZPngzAU089xSmnnFKudezduzdPPfUUEA1sTZo0oV69eqxcuZIuXbrwhz/8gYyMDL744gu++uormjVrxi9/+UuuuOIK5syZU66y4kVHECJS6cyMl156iRtuuIHbb7+dpk2bUrt2bf7+978D8D//8z+sWbOG448/HnenadOmBe3/YZKTk3nuuee47rrr2LZtG5FIhOuvv55OnYofHY0bN45zzz2XFi1a0LNnT1avXg1Ezzmcc845vPzyy9x3333ce++9XH755dxxxx00bdqUxx57rFzrOG7cOC677DK6du1KrVq1CoLR3XffzXvvvUdiYiIdO3bk9NNPZ/Lkydxxxx3UqFGDOnXq8OSTT5arrHixsMOgH6PatWv7/jwwaNPObE748zuM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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": 15, "metadata": {}, "outputs": [ { "data": { "image/png": "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0ThIslSmnx7jZujQoc7nm266ycpoV2HHodcKzCcxaNAgp+0rX/mKlTGHiZ4zQWCMMebvGj16tNMPY4r1tSSlx9JxdZ4OLPmL+apE3LLzGLOO+SI0OncPxkVjGU1dmhvz82BZZ70uhtU92jaWBxdx4791LDhpHJzn7dq1c9rOP//8UMfA/DMTJkxw2jCvD86LIJo2bep8fu6556wcNadaNcsPazvFXEq33367lZ999lnffvo5g3nM8No6dOjg9MO8FbvvvrvvGLt162blM88802lDO8U8XaNGjXL6oa6nTJnitL399ttWvu+++6yMa2tjZLmENI4Nc+mIiEycONHKv/nNb5w2nBt4DH3/brzxRivj+o153URETj/9dCsPGzbMaUNbP+OMM6x8xx13OP0w11Tv3r19j0GS4b///a9vm85nWETS+k2hz4N7IbQrzPcj4q8fvUbj74SlS5c6bbi3atGihZV1LqCkfyMnvUcNygkbVs/6md+lSxcrYw5JEXcvimuVzs+D6/Ahhxxi5X79+jn9xo8fb2W9FmLuwTzAlZsQQgghhBBCCCGkoPDFDyGEEEIIIYQQQkhBST3Uq+RypUMtqlnGzo/LL7/cygsWLPDtd8oppzifsbxqVq4lTrJ+TegyPn/+fCs///zzTr8gN1oEXdN1CEnSLudJ3uu09KjDepYvX27lBx980MojRoxw+kUJnZs8ebLzedOmTVZ+7733rBxHKei2bds6behaumXLFqetVAo3zvnieZ6dw/q4GDaAJbZFRO68804rY1n2AQMGOP2wRLMO4Xr11VetjG6uGEYm4obq4DyIOvcwTFCHzRx66KFWTsItOg17yXv4xKpVq6z80ksvOW3aJvzA+frXv/7VadNld6OQlB7DHFfrt66uzsoYuhF0rzAcQMS1MZR1KKQO1yyhw+7Wrl1rZV0G/N5777Xy1KlTrRwUJqqfs7NmzbIy7qu+/OUv+x5Dk5fnol6HUP9BaxSu561atXLaMIwOdapt46GHHrKy1s9+++1nZQwlw9AuEfdeYFieiBtyVk7otN/x4yStMPa40c/xcePGWblr165OW7VKuOsxppGOIG06depkZQyV1/tLv98Q+u+4f7ruuuucNvxNgTo97rjjwg84wyRpi7jmYRi4iGs769atszKmhhDZfs9a4p577nE+/+1vf7PyypUrnbZp06ZZ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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((10, LATENT_DIM)).uniform_(0.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=10, 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')" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "----------------------------------------------------------------\n", " Layer (type) Output Shape Param #\n", "================================================================\n", " Linear-1 [-1, 3136] 313,600\n", " BatchNorm1d-2 [-1, 3136] 6,272\n", " LeakyReLU-3 [-1, 3136] 0\n", " Reshape1-4 [-1, 64, 7, 7] 0\n", " ConvTranspose2d-5 [-1, 32, 13, 13] 18,432\n", " BatchNorm2d-6 [-1, 32, 13, 13] 64\n", " LeakyReLU-7 [-1, 32, 13, 13] 0\n", " ConvTranspose2d-8 [-1, 16, 25, 25] 4,608\n", " BatchNorm2d-9 [-1, 16, 25, 25] 32\n", " LeakyReLU-10 [-1, 16, 25, 25] 0\n", " ConvTranspose2d-11 [-1, 8, 27, 27] 1,152\n", " BatchNorm2d-12 [-1, 8, 27, 27] 16\n", " LeakyReLU-13 [-1, 8, 27, 27] 0\n", " ConvTranspose2d-14 [-1, 1, 28, 28] 32\n", " Tanh-15 [-1, 1, 28, 28] 0\n", "================================================================\n", "Total params: 344,208\n", "Trainable params: 344,208\n", "Non-trainable params: 0\n", "----------------------------------------------------------------\n", "Input size (MB): 0.00\n", "Forward/backward pass size (MB): 0.59\n", "Params size (MB): 1.31\n", "Estimated Total Size (MB): 1.91\n", "----------------------------------------------------------------\n", "----------------------------------------------------------------\n", " Layer (type) Output Shape Param #\n", "================================================================\n", " Conv2d-1 [-1, 8, 14, 14] 72\n", " BatchNorm2d-2 [-1, 8, 14, 14] 16\n", " LeakyReLU-3 [-1, 8, 14, 14] 0\n", " Conv2d-4 [-1, 16, 7, 7] 1,152\n", " BatchNorm2d-5 [-1, 16, 7, 7] 32\n", " LeakyReLU-6 [-1, 16, 7, 7] 0\n", " Conv2d-7 [-1, 32, 4, 4] 4,608\n", " BatchNorm2d-8 [-1, 32, 4, 4] 64\n", " LeakyReLU-9 [-1, 32, 4, 4] 0\n", " Flatten-10 [-1, 512] 0\n", " Linear-11 [-1, 1] 513\n", "================================================================\n", "Total params: 6,457\n", "Trainable params: 6,457\n", "Non-trainable params: 0\n", "----------------------------------------------------------------\n", "Input size (MB): 0.00\n", "Forward/backward pass size (MB): 0.07\n", "Params size (MB): 0.02\n", "Estimated Total Size (MB): 0.10\n", "----------------------------------------------------------------\n" ] } ], "source": [ "from torchsummary import summary\n", "model = model.to('cuda:0')\n", "summary(model.generator, input_size=(100,))\n", "summary(model.discriminator, input_size=(1, 28, 28))" ] } ], "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 }