A-Simple-GAN

H
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# G.A.N\n",
    "> Generative Adversial Network:\n",
    "> -  The main focus for GAN is to generate data from scratch.\n",
    "> -  It brings us closer to understanding intelligence.\n",
    "- It trains two deep networks, called Generator and Discriminator, that compete and cooperate with each other. In the course of training, both networks eventually learn how to perform their tasks.\n",
    "> > - The generator never actually sees examples from the domain and is adapted based on how well the discriminator performs."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[Original Article: How to Develop a 1D GAN](https://machinelearningmastery.com/how-to-develop-a-generative-adversarial-network-for-a-1-dimensional-function-from-scratch-in-keras/)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "# The Import Statements:\n",
    "from matplotlib import pyplot\n",
    "import numpy as np\n",
    "from keras.models import Sequential\n",
    "from keras.layers import Dense\n",
    "from keras.utils.vis_utils import plot_model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Defining a 1 D function:\n",
    "> y=f(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def function_1D(x):\n",
    "    return x*x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "inputs=np.arange(-0.5,0.6,0.1)\n",
    "outputs=[function_1D(x) for x in inputs]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# plot the result\n",
    "pyplot.plot(inputs, outputs)\n",
    "pyplot.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Defining random values\n",
    "def generate_samples(n=100):\n",
    "    x1=np.random.rand(n)-0.5\n",
    "    x2=x1*x1\n",
    "    x1=x1.reshape(n,1)\n",
    "    x2=x2.reshape(n,1)\n",
    "    return np.hstack((x1,x2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# generate samples and plotting them\n",
    "data = generate_samples()\n",
    "\n",
    "pyplot.scatter(data[:, 0], data[:, 1])\n",
    "pyplot.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Note:\n",
    "> *a sample is comprised of a vector with two elements, one for the input and one for the output of our one-dimensional function.*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### The Discriminator\n",
    "- The difference from a typical CNN is the absence of max-pooling in between layers.\n",
    "- will have 1 hidden layer with 25 nodes.\n",
    "- will use the ReLU activation function\n",
    "- The output layer will have 1 node for the binary classification using the sigmoid activation function.\n",
    "- Loss Function: Binary Cross Entropy\n",
    "- Optimizer : Adam version of stochastic Gradient Descent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Code for the Discriminator Unit:\n",
    "def define_discriminator(n_inputs=2):\n",
    "\tmodel = Sequential()\n",
    "\tmodel.add(Dense(25, activation='relu', kernel_initializer='he_uniform', input_dim=n_inputs))\n",
    "\tmodel.add(Dense(1, activation='sigmoid'))\n",
    "\t# compile model\n",
    "\tmodel.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])\n",
    "\treturn model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential_1\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "dense_1 (Dense)              (None, 25)                75        \n",
      "_________________________________________________________________\n",
      "dense_2 (Dense)              (None, 1)                 26        \n",
      "=================================================================\n",
      "Total params: 101\n",
      "Trainable params: 101\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "# define the discriminator model\n",
    "model = define_discriminator()\n",
    "# summarize the model\n",
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "def generate_real_samples(n):\n",
    "    x1=np.random.rand(n)-0.5\n",
    "    x2=x1*x1\n",
    "    x1=x1.reshape(n,1)\n",
    "    x2=x2.reshape(n,1)\n",
    "    X= np.hstack((x1,x2))\n",
    "    y=np.ones((n,1))\n",
    "    return X,y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "def generate_fake_samples(n):\n",
    "\t# generate inputs in [-1, 1]\n",
    "\tX1 = -1 + np.random.rand(n) * 2\n",
    "\t# generate outputs in [-1, 1]\n",
    "\tX2 = -1 + np.random.rand(n) * 2\n",
    "\t# stack arrays\n",
    "\tX1 = X1.reshape(n, 1)\n",
    "\tX2 = X2.reshape(n, 1)\n",
    "\tX = np.hstack((X1, X2))\n",
    "\t# generate class labels\n",
    "\ty = np.zeros((n, 1))\n",
    "\treturn X, y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "#training the discriminator model\n",
    "def train_discriminator(model, n_epochs=1000, n_batch=128):\n",
    "\thalf_batch = int(n_batch / 2)\n",
    "\t# run epochs manually\n",
    "\tfor i in range(n_epochs):\n",
    "\t\t# generate real examples\n",
    "\t\tX_real, y_real = generate_real_samples(half_batch)\n",
    "\t\t# update model\n",
    "\t\tmodel.train_on_batch(X_real, y_real)\n",
    "\t\t# generate fake examples\n",
    "\t\tX_fake, y_fake = generate_fake_samples(half_batch)\n",
    "\t\t# update model\n",
    "\t\tmodel.train_on_batch(X_fake, y_fake)\n",
    "\t\t# evaluate the model\n",
    "\t\t_, acc_real = model.evaluate(X_real, y_real, verbose=0)\n",
    "\t\t_, acc_fake = model.evaluate(X_fake, y_fake, verbose=0)\n",
    "\t\tprint(i, acc_real, acc_fake)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 0.5 0.15625\n",
      "1 0.546875 0.25\n",
      "2 0.578125 0.21875\n",
      "3 0.5625 0.21875\n",
      "4 0.640625 0.234375\n",
      "5 0.515625 0.40625\n",
      "6 0.515625 0.46875\n",
      "7 0.59375 0.390625\n",
      "8 0.5625 0.46875\n",
      "9 0.53125 0.4375\n",
      "10 0.46875 0.484375\n",
      "11 0.421875 0.53125\n",
      "12 0.46875 0.484375\n",
      "13 0.515625 0.5625\n",
      "14 0.46875 0.6875\n",
      "15 0.5625 0.515625\n",
      "16 0.515625 0.53125\n",
      "17 0.53125 0.5\n",
      "18 0.484375 0.609375\n",
      "19 0.40625 0.5\n",
      "20 0.46875 0.671875\n",
      "21 0.484375 0.59375\n",
      "22 0.546875 0.609375\n",
      "23 0.375 0.53125\n",
      "24 0.421875 0.53125\n",
      "25 0.34375 0.65625\n",
      "26 0.421875 0.484375\n",
      "27 0.421875 0.578125\n",
      "28 0.328125 0.546875\n",
      "29 0.359375 0.640625\n",
      "30 0.4375 0.609375\n",
      "31 0.296875 0.484375\n",
      "32 0.296875 0.53125\n",
      "33 0.515625 0.625\n",
      "34 0.359375 0.59375\n",
      "35 0.40625 0.65625\n",
      "36 0.359375 0.6875\n",
      "37 0.28125 0.578125\n",
      "38 0.328125 0.578125\n",
      "39 0.328125 0.671875\n",
      "40 0.40625 0.671875\n",
      "41 0.296875 0.515625\n",
      "42 0.296875 0.578125\n",
      "43 0.296875 0.625\n",
      "44 0.34375 0.625\n",
      "45 0.390625 0.671875\n",
      "46 0.375 0.609375\n",
      "47 0.34375 0.59375\n",
      "48 0.359375 0.578125\n",
      "49 0.359375 0.6875\n",
      "50 0.34375 0.65625\n",
      "51 0.375 0.515625\n",
      "52 0.390625 0.609375\n",
      "53 0.234375 0.625\n",
      "54 0.359375 0.625\n",
      "55 0.234375 0.59375\n",
      "56 0.40625 0.6875\n",
      "57 0.34375 0.765625\n",
      "58 0.296875 0.609375\n",
      "59 0.265625 0.59375\n",
      "60 0.25 0.65625\n",
      "61 0.390625 0.65625\n",
      "62 0.265625 0.65625\n",
      "63 0.46875 0.703125\n",
      "64 0.40625 0.59375\n",
      "65 0.359375 0.625\n",
      "66 0.28125 0.625\n",
      "67 0.3125 0.625\n",
      "68 0.328125 0.640625\n",
      "69 0.390625 0.625\n",
      "70 0.28125 0.640625\n",
      "71 0.328125 0.609375\n",
      "72 0.296875 0.59375\n",
      "73 0.125 0.703125\n",
      "74 0.359375 0.765625\n",
      "75 0.359375 0.65625\n",
      "76 0.34375 0.5625\n",
      "77 0.234375 0.671875\n",
      "78 0.34375 0.6875\n",
      "79 0.21875 0.734375\n",
      "80 0.3125 0.78125\n",
      "81 0.28125 0.6875\n",
      "82 0.34375 0.640625\n",
      "83 0.375 0.765625\n",
      "84 0.34375 0.640625\n",
      "85 0.328125 0.703125\n",
      "86 0.21875 0.75\n",
      "87 0.25 0.65625\n",
      "88 0.28125 0.640625\n",
      "89 0.3125 0.78125\n",
      "90 0.234375 0.71875\n",
      "91 0.328125 0.71875\n",
      "92 0.25 0.671875\n",
      "93 0.25 0.703125\n",
      "94 0.265625 0.546875\n",
      "95 0.296875 0.546875\n",
      "96 0.328125 0.625\n",
      "97 0.265625 0.75\n",
      "98 0.296875 0.671875\n",
      "99 0.265625 0.703125\n",
      "100 0.15625 0.734375\n",
      "101 0.234375 0.796875\n",
      "102 0.25 0.71875\n",
      "103 0.21875 0.828125\n",
      "104 0.21875 0.828125\n",
      "105 0.328125 0.765625\n",
      "106 0.21875 0.671875\n",
      "107 0.28125 0.84375\n",
      "108 0.21875 0.796875\n",
      "109 0.21875 0.78125\n",
      "110 0.25 0.65625\n",
      "111 0.25 0.8125\n",
      "112 0.21875 0.859375\n",
      "113 0.28125 0.796875\n",
      "114 0.234375 0.625\n",
      "115 0.21875 0.671875\n",
      "116 0.234375 0.859375\n",
      "117 0.265625 0.71875\n",
      "118 0.21875 0.765625\n",
      "119 0.234375 0.765625\n",
      "120 0.234375 0.6875\n",
      "121 0.234375 0.8125\n",
      "122 0.296875 0.828125\n",
      "123 0.25 0.796875\n",
      "124 0.234375 0.890625\n",
      "125 0.359375 0.765625\n",
      "126 0.203125 0.75\n",
      "127 0.328125 0.703125\n",
      "128 0.203125 0.78125\n",
      "129 0.265625 0.796875\n",
      "130 0.3125 0.828125\n",
      "131 0.21875 0.828125\n",
      "132 0.25 0.828125\n",
      "133 0.296875 0.84375\n",
      "134 0.203125 0.875\n",
      "135 0.34375 0.734375\n",
      "136 0.421875 0.765625\n",
      "137 0.15625 0.796875\n",
      "138 0.359375 0.75\n",
      "139 0.234375 0.75\n",
      "140 0.421875 0.71875\n",
      "141 0.28125 0.703125\n",
      "142 0.1875 0.6875\n",
      "143 0.21875 0.828125\n",
      "144 0.25 0.890625\n",
      "145 0.265625 0.9375\n",
      "146 0.171875 0.8125\n",
      "147 0.265625 0.84375\n",
      "148 0.296875 0.90625\n",
      "149 0.171875 0.875\n",
      "150 0.21875 0.765625\n",
      "151 0.25 0.875\n",
      "152 0.25 0.90625\n",
      "153 0.25 0.90625\n",
      "154 0.328125 0.796875\n",
      "155 0.296875 0.921875\n",
      "156 0.234375 0.84375\n",
      "157 0.25 0.875\n",
      "158 0.1875 0.9375\n",
      "159 0.234375 0.859375\n",
      "160 0.234375 0.890625\n",
      "161 0.28125 0.984375\n",
      "162 0.21875 0.90625\n",
      "163 0.21875 0.90625\n",
      "164 0.265625 0.953125\n",
      "165 0.28125 0.953125\n",
      "166 0.328125 0.984375\n",
      "167 0.28125 0.96875\n",
      "168 0.25 0.953125\n",
      "169 0.359375 0.921875\n",
      "170 0.34375 1.0\n",
      "171 0.328125 0.953125\n",
      "172 0.296875 0.96875\n",
      "173 0.359375 0.921875\n",
      "174 0.28125 0.9375\n",
      "175 0.375 0.984375\n",
      "176 0.359375 0.96875\n",
      "177 0.265625 0.984375\n",
      "178 0.21875 0.96875\n",
      "179 0.28125 0.9375\n",
      "180 0.359375 1.0\n",
      "181 0.34375 0.984375\n",
      "182 0.40625 0.984375\n",
      "183 0.296875 0.953125\n",
      "184 0.34375 0.984375\n",
      "185 0.3125 0.984375\n",
      "186 0.359375 0.96875\n",
      "187 0.375 0.984375\n",
      "188 0.53125 0.953125\n",
      "189 0.40625 0.921875\n",
      "190 0.453125 0.953125\n",
      "191 0.375 0.96875\n",
      "192 0.609375 0.9375\n",
      "193 0.40625 0.96875\n",
      "194 0.4375 0.96875\n",
      "195 0.390625 0.96875\n",
      "196 0.40625 0.984375\n",
      "197 0.4375 1.0\n",
      "198 0.546875 0.953125\n",
      "199 0.328125 1.0\n",
      "200 0.328125 0.984375\n",
      "201 0.328125 0.984375\n",
      "202 0.453125 0.96875\n",
      "203 0.34375 0.96875\n",
      "204 0.34375 0.984375\n",
      "205 0.359375 0.96875\n",
      "206 0.359375 0.984375\n",
      "207 0.421875 0.96875\n",
      "208 0.5 0.984375\n",
      "209 0.40625 1.0\n",
      "210 0.390625 0.96875\n",
      "211 0.546875 0.96875\n",
      "212 0.390625 0.984375\n",
      "213 0.5 0.921875\n",
      "214 0.578125 0.96875\n",
      "215 0.671875 0.9375\n",
      "216 0.484375 0.984375\n",
      "217 0.4375 0.90625\n",
      "218 0.453125 0.96875\n",
      "219 0.421875 0.953125\n",
      "220 0.625 0.9375\n",
      "221 0.5 0.953125\n",
      "222 0.578125 0.984375\n",
      "223 0.53125 0.9375\n",
      "224 0.5625 0.984375\n",
      "225 0.546875 0.984375\n",
      "226 0.5625 0.96875\n",
      "227 0.578125 0.984375\n",
      "228 0.5625 0.953125\n",
      "229 0.546875 0.90625\n",
      "230 0.546875 0.921875\n",
      "231 0.75 1.0\n",
      "232 0.546875 1.0\n",
      "233 0.671875 1.0\n",
      "234 0.5625 0.96875\n",
      "235 0.640625 0.984375\n",
      "236 0.6875 0.921875\n",
      "237 0.59375 0.90625\n",
      "238 0.71875 0.921875\n",
      "239 0.609375 1.0\n",
      "240 0.59375 0.953125\n",
      "241 0.65625 0.953125\n",
      "242 0.640625 0.984375\n",
      "243 0.6875 0.984375\n",
      "244 0.546875 0.9375\n",
      "245 0.71875 1.0\n",
      "246 0.71875 0.953125\n",
      "247 0.609375 1.0\n",
      "248 0.671875 0.96875\n",
      "249 0.625 0.953125\n",
      "250 0.53125 0.921875\n",
      "251 0.6875 0.984375\n",
      "252 0.625 0.921875\n",
      "253 0.65625 0.984375\n",
      "254 0.625 0.9375\n",
      "255 0.75 0.96875\n",
      "256 0.609375 0.984375\n",
      "257 0.640625 0.921875\n",
      "258 0.6875 0.984375\n",
      "259 0.671875 1.0\n",
      "260 0.625 0.9375\n",
      "261 0.65625 0.984375\n",
      "262 0.703125 0.96875\n",
      "263 0.734375 1.0\n",
      "264 0.65625 0.984375\n",
      "265 0.578125 0.9375\n",
      "266 0.59375 0.96875\n",
      "267 0.703125 0.921875\n",
      "268 0.734375 1.0\n",
      "269 0.734375 1.0\n",
      "270 0.703125 0.984375\n",
      "271 0.734375 0.984375\n",
      "272 0.6875 0.953125\n",
      "273 0.703125 0.96875\n",
      "274 0.71875 1.0\n",
      "275 0.65625 0.953125\n",
      "276 0.75 0.921875\n",
      "277 0.609375 0.984375\n",
      "278 0.6875 1.0\n",
      "279 0.6875 0.953125\n",
      "280 0.765625 1.0\n",
      "281 0.796875 1.0\n",
      "282 0.734375 0.96875\n",
      "283 0.671875 0.984375\n",
      "284 0.578125 1.0\n",
      "285 0.671875 0.953125\n",
      "286 0.671875 0.984375\n",
      "287 0.75 0.9375\n",
      "288 0.734375 0.984375\n",
      "289 0.71875 0.96875\n",
      "290 0.75 0.96875\n",
      "291 0.6875 0.984375\n",
      "292 0.65625 0.9375\n",
      "293 0.734375 0.984375\n",
      "294 0.65625 0.953125\n",
      "295 0.703125 0.96875\n",
      "296 0.6875 0.984375\n",
      "297 0.71875 0.984375\n",
      "298 0.734375 0.953125\n",
      "299 0.71875 0.9375\n",
      "300 0.734375 0.984375\n",
      "301 0.78125 0.953125\n",
      "302 0.75 0.9375\n",
      "303 0.75 0.953125\n",
      "304 0.796875 0.96875\n",
      "305 0.734375 1.0\n",
      "306 0.71875 0.921875\n",
      "307 0.796875 0.953125\n",
      "308 0.84375 0.96875\n",
      "309 0.75 0.96875\n",
      "310 0.71875 1.0\n",
      "311 0.828125 0.96875\n",
      "312 0.8125 0.984375\n",
      "313 0.78125 0.9375\n",
      "314 0.84375 0.96875\n",
      "315 0.6875 0.984375\n",
      "316 0.84375 0.953125\n",
      "317 0.8125 0.984375\n",
      "318 0.765625 0.9375\n",
      "319 0.71875 0.9375\n",
      "320 0.703125 0.9375\n",
      "321 0.671875 0.96875\n",
      "322 0.703125 0.921875\n",
      "323 0.765625 0.96875\n",
      "324 0.703125 0.953125\n",
      "325 0.828125 0.96875\n",
      "326 0.828125 0.96875\n",
      "327 0.78125 0.984375\n",
      "328 0.8125 0.953125\n",
      "329 0.796875 0.984375\n",
      "330 0.765625 0.9375\n",
      "331 0.890625 0.90625\n",
      "332 0.8125 0.90625\n",
      "333 0.8125 1.0\n",
      "334 0.78125 0.96875\n",
      "335 0.875 0.96875\n",
      "336 0.84375 0.984375\n",
      "337 0.796875 1.0\n",
      "338 0.8125 0.984375\n",
      "339 0.78125 0.9375\n",
      "340 0.875 0.953125\n",
      "341 0.8125 0.921875\n",
      "342 0.796875 0.90625\n",
      "343 0.796875 0.953125\n",
      "344 0.8125 0.984375\n",
      "345 0.890625 0.9375\n",
      "346 0.828125 0.9375\n",
      "347 0.78125 0.96875\n",
      "348 0.90625 0.953125\n",
      "349 0.828125 0.96875\n",
      "350 0.796875 0.953125\n",
      "351 0.734375 0.921875\n",
      "352 0.796875 0.984375\n",
      "353 0.765625 0.921875\n",
      "354 0.8125 0.90625\n",
      "355 0.765625 0.96875\n",
      "356 0.84375 0.96875\n",
      "357 0.875 0.953125\n",
      "358 0.8125 0.90625\n",
      "359 0.828125 0.96875\n",
      "360 0.828125 0.953125\n",
      "361 0.84375 0.984375\n",
      "362 0.859375 0.9375\n",
      "363 0.859375 0.953125\n",
      "364 0.859375 0.9375\n",
      "365 0.875 0.96875\n",
      "366 0.875 0.953125\n",
      "367 0.8125 0.953125\n",
      "368 0.90625 0.9375\n",
      "369 0.875 0.984375\n",
      "370 0.9375 0.890625\n",
      "371 0.875 0.9375\n",
      "372 0.796875 0.921875\n",
      "373 0.828125 0.921875\n",
      "374 0.90625 0.921875\n",
      "375 0.8125 0.9375\n",
      "376 0.8125 0.90625\n",
      "377 0.90625 0.921875\n",
      "378 0.765625 1.0\n",
      "379 0.78125 0.953125\n",
      "380 0.78125 0.953125\n",
      "381 0.875 0.953125\n",
      "382 0.875 0.9375\n",
      "383 0.84375 0.890625\n",
      "384 0.796875 0.9375\n",
      "385 0.859375 0.96875\n",
      "386 0.8125 0.96875\n",
      "387 0.90625 0.953125\n",
      "388 0.921875 0.9375\n",
      "389 0.890625 0.953125\n",
      "390 0.96875 0.921875\n",
      "391 0.84375 0.875\n",
      "392 0.875 0.921875\n",
      "393 0.828125 0.9375\n",
      "394 0.921875 0.9375\n",
      "395 0.890625 0.9375\n",
      "396 0.921875 0.921875\n",
      "397 0.890625 1.0\n",
      "398 0.875 0.984375\n",
      "399 0.921875 0.9375\n",
      "400 0.828125 0.953125\n",
      "401 0.828125 0.90625\n",
      "402 0.9375 0.953125\n",
      "403 0.8125 0.890625\n",
      "404 0.953125 0.953125\n",
      "405 0.9375 0.890625\n",
      "406 0.90625 0.96875\n",
      "407 0.890625 0.984375\n",
      "408 0.875 0.9375\n",
      "409 0.921875 0.984375\n",
      "410 0.859375 0.96875\n",
      "411 0.890625 0.953125\n",
      "412 0.921875 0.96875\n",
      "413 0.921875 1.0\n",
      "414 0.921875 0.96875\n",
      "415 0.875 0.90625\n",
      "416 0.96875 0.96875\n",
      "417 0.890625 0.921875\n",
      "418 0.90625 0.953125\n",
      "419 0.875 0.9375\n",
      "420 0.875 0.921875\n",
      "421 0.96875 0.953125\n",
      "422 0.921875 0.96875\n",
      "423 0.890625 0.875\n",
      "424 0.84375 0.90625\n",
      "425 0.921875 0.984375\n",
      "426 0.953125 0.890625\n",
      "427 1.0 0.90625\n",
      "428 0.890625 0.9375\n",
      "429 0.921875 0.9375\n",
      "430 0.9375 0.953125\n",
      "431 0.96875 0.953125\n",
      "432 0.90625 0.9375\n",
      "433 0.953125 0.875\n",
      "434 0.953125 0.890625\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "435 0.96875 0.90625\n",
      "436 0.9375 0.953125\n",
      "437 0.96875 0.953125\n",
      "438 0.953125 0.890625\n",
      "439 0.921875 0.953125\n",
      "440 0.953125 0.90625\n",
      "441 0.90625 0.984375\n",
      "442 0.96875 0.96875\n",
      "443 0.984375 0.9375\n",
      "444 0.921875 0.9375\n",
      "445 0.96875 0.90625\n",
      "446 0.921875 0.96875\n",
      "447 0.890625 0.875\n",
      "448 0.953125 0.953125\n",
      "449 0.984375 0.953125\n",
      "450 0.921875 0.953125\n",
      "451 1.0 0.90625\n",
      "452 0.984375 0.96875\n",
      "453 1.0 0.90625\n",
      "454 0.953125 0.953125\n",
      "455 0.96875 0.9375\n",
      "456 0.953125 0.90625\n",
      "457 1.0 0.921875\n",
      "458 0.984375 0.96875\n",
      "459 0.984375 0.90625\n",
      "460 0.984375 0.984375\n",
      "461 1.0 0.921875\n",
      "462 0.984375 0.953125\n",
      "463 0.96875 0.921875\n",
      "464 1.0 0.921875\n",
      "465 0.984375 0.859375\n",
      "466 1.0 0.90625\n",
      "467 1.0 0.890625\n",
      "468 1.0 0.90625\n",
      "469 1.0 0.875\n",
      "470 1.0 0.84375\n",
      "471 1.0 0.875\n",
      "472 0.984375 0.859375\n",
      "473 1.0 0.859375\n",
      "474 1.0 0.921875\n",
      "475 0.984375 0.96875\n",
      "476 1.0 0.875\n",
      "477 1.0 0.890625\n",
      "478 1.0 0.921875\n",
      "479 1.0 0.890625\n",
      "480 1.0 0.953125\n",
      "481 1.0 0.90625\n",
      "482 1.0 0.890625\n",
      "483 1.0 0.90625\n",
      "484 1.0 0.90625\n",
      "485 1.0 0.890625\n",
      "486 1.0 0.921875\n",
      "487 1.0 0.96875\n",
      "488 1.0 0.9375\n",
      "489 1.0 0.921875\n",
      "490 1.0 0.890625\n",
      "491 1.0 0.890625\n",
      "492 1.0 0.9375\n",
      "493 1.0 0.90625\n",
      "494 0.984375 0.9375\n",
      "495 1.0 0.875\n",
      "496 1.0 0.890625\n",
      "497 1.0 0.9375\n",
      "498 1.0 0.921875\n",
      "499 0.984375 0.921875\n",
      "500 1.0 0.921875\n",
      "501 1.0 0.875\n",
      "502 1.0 0.90625\n",
      "503 1.0 0.953125\n",
      "504 1.0 0.921875\n",
      "505 1.0 0.96875\n",
      "506 1.0 0.953125\n",
      "507 1.0 0.921875\n",
      "508 1.0 0.921875\n",
      "509 1.0 0.890625\n",
      "510 1.0 0.96875\n",
      "511 1.0 0.921875\n",
      "512 1.0 0.921875\n",
      "513 1.0 0.859375\n",
      "514 1.0 0.875\n",
      "515 1.0 0.921875\n",
      "516 1.0 0.9375\n",
      "517 1.0 0.890625\n",
      "518 1.0 0.90625\n",
      "519 1.0 0.875\n",
      "520 1.0 0.90625\n",
      "521 1.0 0.9375\n",
      "522 1.0 0.921875\n",
      "523 1.0 0.875\n",
      "524 1.0 0.875\n",
      "525 1.0 0.921875\n",
      "526 1.0 0.953125\n",
      "527 1.0 0.90625\n",
      "528 1.0 0.90625\n",
      "529 1.0 0.90625\n",
      "530 1.0 0.890625\n",
      "531 1.0 0.90625\n",
      "532 1.0 0.921875\n",
      "533 1.0 0.921875\n",
      "534 1.0 0.953125\n",
      "535 1.0 0.875\n",
      "536 1.0 0.90625\n",
      "537 1.0 0.859375\n",
      "538 1.0 0.890625\n",
      "539 1.0 0.9375\n",
      "540 1.0 0.9375\n",
      "541 1.0 0.953125\n",
      "542 1.0 0.890625\n",
      "543 1.0 0.90625\n",
      "544 1.0 0.84375\n",
      "545 1.0 0.890625\n",
      "546 1.0 0.890625\n",
      "547 1.0 0.953125\n",
      "548 1.0 0.9375\n",
      "549 1.0 0.9375\n",
      "550 1.0 0.890625\n",
      "551 1.0 0.96875\n",
      "552 1.0 0.921875\n",
      "553 1.0 0.890625\n",
      "554 1.0 0.90625\n",
      "555 1.0 0.96875\n",
      "556 1.0 0.921875\n",
      "557 1.0 0.953125\n",
      "558 1.0 0.890625\n",
      "559 1.0 0.9375\n",
      "560 1.0 0.9375\n",
      "561 1.0 0.90625\n",
      "562 1.0 0.9375\n",
      "563 1.0 0.953125\n",
      "564 1.0 0.875\n",
      "565 1.0 0.90625\n",
      "566 1.0 0.859375\n",
      "567 1.0 0.875\n",
      "568 1.0 0.921875\n",
      "569 1.0 0.84375\n",
      "570 1.0 0.890625\n",
      "571 1.0 0.890625\n",
      "572 1.0 0.953125\n",
      "573 1.0 0.90625\n",
      "574 1.0 0.921875\n",
      "575 1.0 0.921875\n",
      "576 1.0 0.921875\n",
      "577 1.0 0.859375\n",
      "578 1.0 0.9375\n",
      "579 1.0 0.953125\n",
      "580 1.0 0.921875\n",
      "581 1.0 0.875\n",
      "582 1.0 0.875\n",
      "583 1.0 0.875\n",
      "584 1.0 0.921875\n",
      "585 1.0 0.890625\n",
      "586 1.0 0.890625\n",
      "587 1.0 0.890625\n",
      "588 1.0 0.90625\n",
      "589 1.0 0.875\n",
      "590 1.0 0.90625\n",
      "591 1.0 0.859375\n",
      "592 1.0 0.90625\n",
      "593 1.0 0.84375\n",
      "594 1.0 0.859375\n",
      "595 1.0 0.890625\n",
      "596 1.0 0.90625\n",
      "597 1.0 0.875\n",
      "598 1.0 0.953125\n",
      "599 1.0 0.875\n",
      "600 1.0 0.859375\n",
      "601 1.0 0.9375\n",
      "602 1.0 0.875\n",
      "603 1.0 0.859375\n",
      "604 1.0 0.90625\n",
      "605 1.0 0.90625\n",
      "606 1.0 0.78125\n",
      "607 1.0 0.828125\n",
      "608 1.0 0.9375\n",
      "609 1.0 0.921875\n",
      "610 1.0 0.90625\n",
      "611 1.0 0.953125\n",
      "612 1.0 0.890625\n",
      "613 1.0 0.9375\n",
      "614 1.0 0.921875\n",
      "615 1.0 0.796875\n",
      "616 1.0 0.890625\n",
      "617 1.0 0.921875\n",
      "618 1.0 0.90625\n",
      "619 1.0 0.890625\n",
      "620 1.0 0.859375\n",
      "621 1.0 0.921875\n",
      "622 1.0 0.828125\n",
      "623 1.0 0.875\n",
      "624 1.0 0.953125\n",
      "625 1.0 0.84375\n",
      "626 1.0 0.9375\n",
      "627 1.0 0.9375\n",
      "628 1.0 0.859375\n",
      "629 1.0 0.9375\n",
      "630 1.0 0.90625\n",
      "631 1.0 0.9375\n",
      "632 1.0 0.921875\n",
      "633 1.0 0.90625\n",
      "634 1.0 0.90625\n",
      "635 1.0 0.890625\n",
      "636 1.0 0.78125\n",
      "637 1.0 0.90625\n",
      "638 1.0 0.890625\n",
      "639 1.0 0.921875\n",
      "640 1.0 0.75\n",
      "641 1.0 0.875\n",
      "642 1.0 0.875\n",
      "643 1.0 0.90625\n",
      "644 1.0 0.953125\n",
      "645 1.0 0.921875\n",
      "646 1.0 0.890625\n",
      "647 1.0 0.859375\n",
      "648 1.0 0.84375\n",
      "649 1.0 0.90625\n",
      "650 1.0 0.84375\n",
      "651 1.0 0.84375\n",
      "652 1.0 0.921875\n",
      "653 1.0 0.90625\n",
      "654 1.0 0.921875\n",
      "655 1.0 0.921875\n",
      "656 1.0 0.921875\n",
      "657 1.0 0.84375\n",
      "658 1.0 0.84375\n",
      "659 1.0 0.90625\n",
      "660 1.0 0.953125\n",
      "661 1.0 0.890625\n",
      "662 1.0 0.875\n",
      "663 1.0 0.84375\n",
      "664 1.0 0.84375\n",
      "665 1.0 0.8125\n",
      "666 1.0 0.859375\n",
      "667 1.0 0.90625\n",
      "668 1.0 0.90625\n",
      "669 1.0 0.875\n",
      "670 1.0 0.921875\n",
      "671 1.0 0.84375\n",
      "672 1.0 0.953125\n",
      "673 1.0 0.84375\n",
      "674 1.0 0.8125\n",
      "675 1.0 0.84375\n",
      "676 1.0 0.921875\n",
      "677 1.0 0.953125\n",
      "678 1.0 0.84375\n",
      "679 1.0 0.859375\n",
      "680 1.0 0.859375\n",
      "681 1.0 0.90625\n",
      "682 1.0 0.90625\n",
      "683 1.0 0.90625\n",
      "684 1.0 0.828125\n",
      "685 1.0 0.875\n",
      "686 1.0 0.9375\n",
      "687 1.0 0.859375\n",
      "688 1.0 0.859375\n",
      "689 1.0 0.84375\n",
      "690 1.0 0.953125\n",
      "691 1.0 0.84375\n",
      "692 1.0 0.859375\n",
      "693 1.0 0.9375\n",
      "694 1.0 0.890625\n",
      "695 1.0 0.859375\n",
      "696 1.0 0.875\n",
      "697 1.0 0.875\n",
      "698 1.0 0.9375\n",
      "699 1.0 0.890625\n",
      "700 1.0 0.921875\n",
      "701 1.0 0.828125\n",
      "702 1.0 0.84375\n",
      "703 1.0 0.90625\n",
      "704 1.0 0.859375\n",
      "705 1.0 0.90625\n",
      "706 1.0 0.921875\n",
      "707 1.0 0.9375\n",
      "708 1.0 0.84375\n",
      "709 1.0 0.875\n",
      "710 1.0 0.90625\n",
      "711 1.0 0.90625\n",
      "712 1.0 0.890625\n",
      "713 1.0 0.921875\n",
      "714 1.0 0.90625\n",
      "715 1.0 0.890625\n",
      "716 1.0 0.8125\n",
      "717 1.0 0.875\n",
      "718 1.0 0.890625\n",
      "719 1.0 0.890625\n",
      "720 1.0 0.90625\n",
      "721 1.0 0.875\n",
      "722 1.0 0.84375\n",
      "723 1.0 0.9375\n",
      "724 1.0 0.90625\n",
      "725 1.0 0.84375\n",
      "726 1.0 0.9375\n",
      "727 1.0 0.875\n",
      "728 1.0 0.8125\n",
      "729 1.0 0.84375\n",
      "730 1.0 0.9375\n",
      "731 1.0 0.84375\n",
      "732 1.0 0.875\n",
      "733 1.0 0.921875\n",
      "734 1.0 0.78125\n",
      "735 1.0 0.78125\n",
      "736 1.0 0.859375\n",
      "737 1.0 0.84375\n",
      "738 1.0 0.90625\n",
      "739 1.0 0.859375\n",
      "740 1.0 0.875\n",
      "741 1.0 0.859375\n",
      "742 1.0 0.890625\n",
      "743 1.0 0.875\n",
      "744 1.0 0.890625\n",
      "745 1.0 0.859375\n",
      "746 1.0 0.8125\n",
      "747 1.0 0.859375\n",
      "748 1.0 0.953125\n",
      "749 1.0 0.84375\n",
      "750 1.0 0.890625\n",
      "751 1.0 0.796875\n",
      "752 1.0 0.890625\n",
      "753 1.0 0.796875\n",
      "754 1.0 0.84375\n",
      "755 1.0 0.890625\n",
      "756 1.0 0.875\n",
      "757 1.0 0.890625\n",
      "758 1.0 0.921875\n",
      "759 1.0 0.84375\n",
      "760 1.0 0.875\n",
      "761 1.0 0.859375\n",
      "762 1.0 0.953125\n",
      "763 1.0 0.890625\n",
      "764 1.0 0.859375\n",
      "765 1.0 0.84375\n",
      "766 1.0 0.828125\n",
      "767 1.0 0.8125\n",
      "768 1.0 0.84375\n",
      "769 1.0 0.859375\n",
      "770 1.0 0.875\n",
      "771 1.0 0.890625\n",
      "772 1.0 0.90625\n",
      "773 1.0 0.90625\n",
      "774 1.0 0.953125\n",
      "775 1.0 0.90625\n",
      "776 1.0 0.890625\n",
      "777 1.0 0.890625\n",
      "778 1.0 0.921875\n",
      "779 1.0 0.90625\n",
      "780 1.0 0.90625\n",
      "781 1.0 0.90625\n",
      "782 1.0 0.796875\n",
      "783 1.0 0.765625\n",
      "784 1.0 0.921875\n",
      "785 1.0 0.875\n",
      "786 1.0 0.890625\n",
      "787 1.0 0.90625\n",
      "788 1.0 0.90625\n",
      "789 1.0 0.890625\n",
      "790 1.0 0.859375\n",
      "791 1.0 0.890625\n",
      "792 1.0 0.875\n",
      "793 1.0 0.796875\n",
      "794 1.0 0.859375\n",
      "795 1.0 0.828125\n",
      "796 1.0 0.890625\n",
      "797 1.0 0.875\n",
      "798 1.0 0.890625\n",
      "799 1.0 0.8125\n",
      "800 1.0 0.875\n",
      "801 1.0 0.921875\n",
      "802 1.0 0.90625\n",
      "803 1.0 0.890625\n",
      "804 1.0 0.90625\n",
      "805 1.0 0.890625\n",
      "806 1.0 0.90625\n",
      "807 1.0 0.9375\n",
      "808 1.0 0.90625\n",
      "809 1.0 0.90625\n",
      "810 1.0 0.859375\n",
      "811 1.0 0.859375\n",
      "812 1.0 0.890625\n",
      "813 1.0 0.875\n",
      "814 1.0 0.8125\n",
      "815 1.0 0.875\n",
      "816 1.0 0.921875\n",
      "817 1.0 0.9375\n",
      "818 1.0 0.890625\n",
      "819 1.0 0.90625\n",
      "820 1.0 0.921875\n",
      "821 1.0 0.875\n",
      "822 1.0 0.9375\n",
      "823 1.0 0.90625\n",
      "824 1.0 0.875\n",
      "825 1.0 0.84375\n",
      "826 1.0 0.875\n",
      "827 1.0 0.8125\n",
      "828 1.0 0.8125\n",
      "829 1.0 0.890625\n",
      "830 1.0 0.78125\n",
      "831 1.0 0.890625\n",
      "832 1.0 0.890625\n",
      "833 1.0 0.84375\n",
      "834 1.0 0.859375\n",
      "835 1.0 0.875\n",
      "836 1.0 0.890625\n",
      "837 1.0 0.9375\n",
      "838 1.0 0.953125\n",
      "839 1.0 0.875\n",
      "840 1.0 0.890625\n",
      "841 1.0 0.78125\n",
      "842 1.0 0.921875\n",
      "843 1.0 0.875\n",
      "844 1.0 0.84375\n",
      "845 1.0 0.859375\n",
      "846 1.0 0.828125\n",
      "847 1.0 0.8125\n",
      "848 1.0 0.921875\n",
      "849 1.0 0.890625\n",
      "850 1.0 0.84375\n",
      "851 1.0 0.96875\n",
      "852 1.0 0.90625\n",
      "853 1.0 0.9375\n",
      "854 1.0 0.875\n",
      "855 1.0 0.890625\n",
      "856 1.0 0.859375\n",
      "857 1.0 0.890625\n",
      "858 1.0 0.8125\n",
      "859 1.0 0.875\n",
      "860 1.0 0.875\n",
      "861 1.0 0.875\n",
      "862 1.0 0.859375\n",
      "863 1.0 0.875\n",
      "864 1.0 0.9375\n",
      "865 1.0 0.796875\n",
      "866 1.0 0.84375\n",
      "867 1.0 0.90625\n",
      "868 1.0 0.875\n",
      "869 1.0 0.890625\n",
      "870 1.0 0.953125\n",
      "871 1.0 0.890625\n",
      "872 1.0 0.90625\n",
      "873 1.0 0.828125\n",
      "874 1.0 0.96875\n",
      "875 1.0 0.90625\n",
      "876 1.0 0.84375\n",
      "877 1.0 0.765625\n",
      "878 1.0 0.96875\n",
      "879 1.0 0.890625\n",
      "880 1.0 0.890625\n",
      "881 1.0 0.84375\n",
      "882 1.0 0.890625\n",
      "883 1.0 0.84375\n",
      "884 1.0 0.859375\n",
      "885 1.0 0.84375\n",
      "886 1.0 0.859375\n",
      "887 1.0 0.875\n",
      "888 1.0 0.921875\n",
      "889 1.0 0.90625\n",
      "890 1.0 0.90625\n",
      "891 1.0 0.859375\n",
      "892 1.0 0.859375\n",
      "893 1.0 0.9375\n",
      "894 1.0 0.84375\n",
      "895 1.0 0.859375\n",
      "896 1.0 0.90625\n",
      "897 1.0 0.9375\n",
      "898 1.0 0.84375\n",
      "899 1.0 0.890625\n",
      "900 1.0 0.828125\n",
      "901 1.0 0.90625\n",
      "902 1.0 0.90625\n",
      "903 1.0 0.859375\n",
      "904 1.0 0.875\n",
      "905 1.0 0.84375\n",
      "906 1.0 0.875\n",
      "907 1.0 0.875\n",
      "908 1.0 0.859375\n",
      "909 1.0 0.875\n",
      "910 1.0 0.9375\n",
      "911 1.0 0.796875\n",
      "912 1.0 0.90625\n",
      "913 1.0 0.859375\n",
      "914 1.0 0.9375\n",
      "915 1.0 0.875\n",
      "916 1.0 0.859375\n",
      "917 1.0 0.890625\n",
      "918 1.0 0.890625\n",
      "919 1.0 0.875\n",
      "920 1.0 0.953125\n",
      "921 1.0 0.921875\n",
      "922 1.0 0.921875\n",
      "923 1.0 0.890625\n",
      "924 1.0 0.9375\n",
      "925 1.0 0.859375\n",
      "926 1.0 0.90625\n",
      "927 1.0 0.921875\n",
      "928 1.0 0.859375\n",
      "929 1.0 0.859375\n",
      "930 1.0 0.875\n",
      "931 1.0 0.890625\n",
      "932 1.0 0.890625\n",
      "933 1.0 0.859375\n",
      "934 1.0 0.859375\n",
      "935 1.0 0.828125\n",
      "936 1.0 0.96875\n",
      "937 1.0 0.875\n",
      "938 1.0 0.75\n",
      "939 1.0 0.9375\n",
      "940 1.0 0.828125\n",
      "941 1.0 0.890625\n",
      "942 1.0 0.828125\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "943 1.0 0.859375\n",
      "944 1.0 0.875\n",
      "945 1.0 0.921875\n",
      "946 1.0 0.890625\n",
      "947 1.0 0.921875\n",
      "948 1.0 0.9375\n",
      "949 1.0 0.953125\n",
      "950 1.0 0.875\n",
      "951 1.0 0.859375\n",
      "952 1.0 0.890625\n",
      "953 1.0 0.84375\n",
      "954 1.0 0.875\n",
      "955 1.0 0.875\n",
      "956 1.0 0.90625\n",
      "957 1.0 0.84375\n",
      "958 1.0 0.828125\n",
      "959 1.0 0.75\n",
      "960 1.0 0.890625\n",
      "961 1.0 0.875\n",
      "962 1.0 0.921875\n",
      "963 1.0 0.796875\n",
      "964 1.0 0.875\n",
      "965 1.0 0.90625\n",
      "966 1.0 0.921875\n",
      "967 1.0 0.796875\n",
      "968 1.0 0.875\n",
      "969 1.0 0.921875\n",
      "970 1.0 0.828125\n",
      "971 1.0 0.9375\n",
      "972 1.0 0.890625\n",
      "973 1.0 0.921875\n",
      "974 1.0 0.875\n",
      "975 1.0 0.9375\n",
      "976 1.0 0.90625\n",
      "977 1.0 0.953125\n",
      "978 1.0 0.859375\n",
      "979 1.0 0.828125\n",
      "980 1.0 0.9375\n",
      "981 1.0 0.953125\n",
      "982 1.0 0.90625\n",
      "983 1.0 0.828125\n",
      "984 1.0 0.78125\n",
      "985 1.0 0.90625\n",
      "986 1.0 0.921875\n",
      "987 1.0 0.90625\n",
      "988 1.0 0.921875\n",
      "989 1.0 0.890625\n",
      "990 1.0 0.90625\n",
      "991 1.0 0.890625\n",
      "992 1.0 0.78125\n",
      "993 1.0 0.859375\n",
      "994 1.0 0.765625\n",
      "995 1.0 0.8125\n",
      "996 1.0 0.890625\n",
      "997 1.0 0.890625\n",
      "998 1.0 0.875\n",
      "999 1.0 0.84375\n"
     ]
    }
   ],
   "source": [
    "# define the discriminator model\n",
    "model = define_discriminator()\n",
    "# fit the model\n",
    "train_discriminator(model)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\"*The goal is to train a generator model, not a discriminator model, and that is where the complexity of GANs truly lies.*\" "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# The Generator Model\n",
    "*We will define a small latent space of five dimensions and use the standard approach in the GAN literature of using a Gaussian distribution for each variable in the latent space. We will generate new inputs by drawing random numbers from a standard Gaussian distribution, i.e. mean of zero and a standard deviation of one.*\n",
    "\n",
    "* Specs:\n",
    "> * Single Hidden Layer with 5 nodes\n",
    "> * ReLU activation Function\n",
    "> * He weight initialization\n",
    "> * Output layer will have 2 nodes+ will use linear activation function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "# define the generator model unit\n",
    "def define_generator(latent_dim, n_outputs=2):\n",
    "\tmodel = Sequential()\n",
    "\tmodel.add(Dense(15, activation='relu', kernel_initializer='he_uniform', input_dim=latent_dim))\n",
    "\tmodel.add(Dense(n_outputs, activation='linear'))\n",
    "\treturn model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential_3\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "dense_5 (Dense)              (None, 15)                90        \n",
      "_________________________________________________________________\n",
      "dense_6 (Dense)              (None, 2)                 32        \n",
      "=================================================================\n",
      "Total params: 122\n",
      "Trainable params: 122\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "# define the discriminator model\n",
    "model = define_generator(5)\n",
    "# summarize the model\n",
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "# generate points in latent space as input for the generator\n",
    "def generate_latent_points(latent_dim, n):\n",
    "\t# generate points in the latent space\n",
    "\tx_input = np.random.randn(latent_dim * n)\n",
    "\t# reshape into a batch of inputs for the network\n",
    "\tx_input = x_input.reshape(n, latent_dim)\n",
    "\treturn x_input"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "# use the generator to generate n fake examples and plot the results\n",
    "def generate_fake_samples(generator, latent_dim, n):\n",
    "\t# generate points in latent space\n",
    "\tx_input = generate_latent_points(latent_dim, n)\n",
    "\t# predict outputs\n",
    "\tX = generator.predict(x_input)\n",
    "    # create class labels\n",
    "\ty = np.zeros((n, 1))\n",
    "\treturn X, y"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*When the discriminator is good at detecting fake samples, the generator is updated more, and when the discriminator model is relatively poor or confused when detecting fake samples, the generator model is updated less.*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "# define the combined generator and discriminator model, for updating the generator\n",
    "def define_gan(generator, discriminator):\n",
    "\t# make weights in the discriminator not trainable\n",
    "\tdiscriminator.trainable = False\n",
    "\t# connect them\n",
    "\tmodel = Sequential()\n",
    "\t# add generator\n",
    "\tmodel.add(generator)\n",
    "\t# add the discriminator\n",
    "\tmodel.add(discriminator)\n",
    "\t# compile model\n",
    "\tmodel.compile(loss='binary_crossentropy', optimizer='adam')\n",
    "\treturn model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "# train the generator and discriminator\n",
    "def train(g_model, d_model, gan_model, latent_dim, n_epochs=10000, n_batch=128, n_eval=2000):\n",
    "\t# determine half the size of one batch, for updating the discriminator\n",
    "\thalf_batch = int(n_batch / 2)\n",
    "\t# manually enumerate epochs\n",
    "\tfor i in range(n_epochs):\n",
    "\t\t# prepare real samples\n",
    "\t\tx_real, y_real = generate_real_samples(half_batch)\n",
    "\t\t# prepare fake examples\n",
    "\t\tx_fake, y_fake = generate_fake_samples(g_model, latent_dim, half_batch)\n",
    "\t\t# update discriminator\n",
    "\t\td_model.train_on_batch(x_real, y_real)\n",
    "\t\td_model.train_on_batch(x_fake, y_fake)\n",
    "\t\t# prepare points in latent space as input for the generator\n",
    "\t\tx_gan = generate_latent_points(latent_dim, n_batch)\n",
    "\t\t# create inverted labels for the fake samples\n",
    "\t\ty_gan = np.ones((n_batch, 1))\n",
    "\t\t# update the generator via the discriminator's error\n",
    "\t\tgan_model.train_on_batch(x_gan, y_gan)\n",
    "\t\t# evaluate the model every n_eval epochs\n",
    "\t\tif (i+1) % n_eval == 0:\n",
    "\t\t\tsummarize_performance(i, g_model, d_model, latent_dim)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "# evaluate the discriminator and plot real and fake points\n",
    "def summarize_performance(epoch, generator, discriminator, latent_dim, n=100):\n",
    "\t# prepare real samples\n",
    "\tx_real, y_real = generate_real_samples(n)\n",
    "\t# evaluate discriminator on real examples\n",
    "\t_, acc_real = discriminator.evaluate(x_real, y_real, verbose=0)\n",
    "\t# prepare fake examples\n",
    "\tx_fake, y_fake = generate_fake_samples(generator, latent_dim, n)\n",
    "\t# evaluate discriminator on fake examples\n",
    "\t_, acc_fake = discriminator.evaluate(x_fake, y_fake, verbose=0)\n",
    "\t# summarize discriminator performance\n",
    "\tprint(epoch, acc_real, acc_fake)\n",
    "\t# scatter plot real and fake data points\n",
    "\tpyplot.scatter(x_real[:, 0], x_real[:, 1], color='red')\n",
    "\tpyplot.scatter(x_fake[:, 0], x_fake[:, 1], color='blue')\n",
    "\tpyplot.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1999 0.7400000095367432 0.4399999976158142\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXQAAAD4CAYAAAD8Zh1EAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAfi0lEQVR4nO3df4wcZ53n8fd3xp6Qdthd0rZYiDPdZpXVytye4JiLTsfp9kesJXBSggS7F6fNml8xOBvWEne6zWZO6JTT5A5WYjW6g4SB82IyjQOb0+p8t0YRcUBaWOAyuQuwAQVMPOMkyxHHYSHOkDie+d4fVT1T3V01XT3TXV1d/XlJremuqu56XO7+9NNPPc9T5u6IiMjwGxt0AUREpDcU6CIiBaFAFxEpCAW6iEhBKNBFRApi26B2vHPnTq9Wq4PavYjIUHrkkUeedfddcesGFujVapWFhYVB7V5EZCiZ2VLSOjW5iIgUhAJdRKQgFOgiIgWhQBcRKQgFuohIQSjQRUQKQoEuIlIQQxno9TpUqzA2Fvyt1wddIhGRwRvYwKLNqtfh0CFYXg4eLy0FjwFqtcGVS0Rk0Iauhj49vR7mDcvLwXIRkVE2dIF+9mx3y0VERsXQBfrkZHfLRURGRapAN7PrzexxMzttZrdvsN07zMzNbKp3RWw2MwOlUvOyUilYLiIyyjoGupmNA58A3grsBfab2d6Y7V4JHAG+1etCRtVqMDcHlQqYBX/n5nRCVEQkTQ39WuC0uz/h7heB+4AbY7b7j8BHgRd7WL5YtRosLsLqavBXYS4iki7QrwKejDx+Kly2xsz+CXC1u/91D8smIiJd2PJJUTMbAz4O/JsU2x4yswUzWzh37txWdy0iIhFpAv1p4OrI493hsoZXAv8I+KqZLQL/DDgRd2LU3efcfcrdp3btir2CkoiIbFKaQH8YuMbM9pjZBHATcKKx0t1/5u473b3q7lXgm8AN7q7ry4mIZKhjoLv7JeA24AHg+8AX3f0xM7vTzG7odwFFRCSdVHO5uPtJ4GTLso8kbPvbWy+WiIh0a+hGioqISDwFuohIQSjQRUQKQoEuIlIQCnQRkYJQoIuIFIQCXUSkIBToIiIFoUAXESkIBbqISEEo0EVECkKBLiJSEAp0EZGCUKCLiBSEAl1EpCAU6CIiBaFAFxEpCAW6iEhBKNBFRApCgS4iUhAjFej1OlSrMDYW/K3XB10iEZHe2TboAmSlXodDh2B5OXi8tBQ8BqjVBlcuEZFeGZka+vT0epg3LC8Hy0VEimBkAv3s2e6Wi4gMm5EJ9MnJ7paLiAybkQn0mRkolZqXlUrBchGRIhiZQK/VYG4OKhUwC/7OzemEqIgUx8j0coEgvBXgIlJUI1NDFxEpOgW6iEhBKNBFRApCgS4iUhAK9A40/4uIDIuR6uXSLc3/IiLDJFUN3cyuN7PHzey0md0es/6DZvZdM3vUzL5mZnt7X9Tsaf4XERkmHQPdzMaBTwBvBfYC+2MC+/Pu/pvu/gbgY8DHe17SAdD8LyIyTNLU0K8FTrv7E+5+EbgPuDG6gbv/PPJwB+C9K+LgaP4XERkmaQL9KuDJyOOnwmVNzOyPzOxHBDX0P457ITM7ZGYLZrZw7ty5zZQ3U5r/RUSGSc96ubj7J9z914A/Af59wjZz7j7l7lO7du3q1a77RvO/iMgwSdPL5Wng6sjj3eGyJPcBd2+lUHmi+V9EZFikqaE/DFxjZnvMbAK4CTgR3cDMrok8/FfAD3tXRBERSaNjDd3dL5nZbcADwDhw1N0fM7M7gQV3PwHcZmb7gJeBnwIH+1loERFpl2pgkbufBE62LPtI5P6RHpdLRES6pKH/PaIpAkRk0DT0vwc0RYCI5IFq6D2gKQJEJA8U6D2gKQJEJA8U6D2gKQJEJA8U6D2gKQJEJA8U6D1Qq8HBgzA+HjweHw8e64SoiGRJgd4D9TocOwYrK8HjlZXgsbouikiWFOg9oF4uIpIHCvQeUC8XEckDBXoPqJeLiOSBAr0H1MtFRDaS1dQgCvQe0IUwRCRJY2qQpSVwX58apB+hbu6Dufzn1NSULywsDGTfIiJZqVaDEG9VqcDiYvevZ2aPuPtU3DrV0EVEUtpM00mWnSYU6CIiKWy26STLThMKdBGRFDY73iTLThMKdBHpr4Jc/WWzTSdZdppQoA+hgnw+ZBRk2cWjz7bSdFKrBSdAV1eDv/3qAadAHzIF+nzIKCjQvBjDMN5EgT5kCvT5kFFQoHkxhmG8ia4pOmQK9PmQUTA5Gd8Je0jnxajV8hXgrVRDHyb1OpNjT8WuGtLPhxTdMLRTFIgCPWfqddi5M/hJZxbcr9fDFe95DzMr/44SLzQ9R58Pya1haKcoEDW55Ei9Du99L1y8uL7s/Hk4cAC+PvELPvnyy9Q4DsA0d3GWSSbHnmZm7mp9PiS/8t5OUSCayyVHkuZ8ADBWuZcDa4HeZED/hyKSPc3lMiQ2OrHpjDHNXdkVRmSzNFBiYBToOdLpxOZZYjYol/tTGJHN0ECJgVKg58jMDExMJK+f5Mn2hc89B7fe2r9CiXRDAyUGSoGeI7UaHD0KV1zRvq5UgpnDT7avdIe774Z9+7IppMhGNFBioBToOVOrwfPPw/z8ek+vchkuvxzedc+/oHrh76izv/2Jp07pZ60Mni6wO1AK9JxqTOZz773w858H3RfdYYkK7+FofKjrZ60MmgYSDZQCPeeOHIGXX25e9jKv4Aiz7RvrZ60MmgYSDVSqQDez683scTM7bWa3x6z/sJl9z8y+Y2anzKzS+6KOpvPnE5azs+lxnf1UbUk9xWTwsporVtp0DHQzGwc+AbwV2AvsN7O9LZv9X2DK3f8xcD/wsV4XVJLV2c8hPs3S6tXqKSYywtLU0K8FTrv7E+5+EbgPuDG6gbt/xd0bfZW+CezubTFHV1I387I9t3Z/mrtYZkfTevUUk0xoEFGupAn0q6CpA/RT4bIk7wO+FLfCzA6Z2YKZLZw7dy59KUfY7Gx73/SJCZj1P157HDvgCDWpS59pEFHu9PSkqJkdAKaAP4tb7+5z7j7l7lO7du3q5a4Lq9E3PXqO6ehRoFymyhnGWGGM1djnqqeY9JUGEeVOmkB/Grg68nh3uKyJme0DpoEb3P2l3hRPoP0cE8Ch5z/OElWcMVbYBjRP0FWyZfUUk/7SIKLcSRPoDwPXmNkeM5sAbgJORDcwszcCnyII82d6X0yJmp6G5YutMx8b41zCWKXCInN+izoXSH9pEFHudAx0d78E3AY8AHwf+KK7P2Zmd5rZDeFmfwZcAfylmT1qZicSXk56IKkCtMoYq4yzyB5qla9nWygZPRpElDupLnDh7ieBky3LPhK5r4lEMpR4mUbCpNeHSrLQ+Ak4PR3UMiYng/edfhoOjEaKDqHYipEtM8O0RuZJ/0W7Kk5PB29IDSLKBV2CbgjFV4xK1GrqLiZ91uiq2Ojd0uiqCArzHNAl6EQkvaTrJFYq612wpK90CToR6Q11Vcw1BbqIpKeuirmmQBeR9NRVMdcU6CKSnuY7zzX1chGR7tRqCvCcUg1dRKQgFOgjRFNXS9f0phkqanIZERoPIl2r1+G974WLF4PHS0vBY9CbJqc0sGhEVHdeYOn8FW3LNR5EEu3cGX9R23IZnn02+/IIoIFFUq9z9nwpdpXGg0iixCuUJyyXgVOgj4Lp6fWZGFuMjal5VGLceuugSyCboEAfBWfPMsMdlHihZYWzsqLLQUqLeh3uvjt5fdKVy2XgFOijYHKSGseZ4xYqLGKsMs4lwJo20+UgBYB3v3vj9bOzmRRDuqdAHwXhcO0ax1lkD6uMs5rwX6829RG3bx9cupS8vlxWD5ccU6CPgpjh2pPl5dhNNcfSiDt1auP1qp3nmgJ9VNRqQf/E8MoyM3/wKCVrDnXNsSQb2rFDtfOcU6CPonqd2rG3MOfvX2tTr9hZ5g5+TZ9XSfapTw26BNKBBhaNoqSrzmjAiOzbF9/ssncvPPZY9uWRNhpYJM2SznyeP69+iyNmbaoWc6rbnqJ+6tUwMdG80XXXKcyHhAJ9FG105lP9FkdGY36fpSVwjKWV3RxijvrFdwQnVObng0EKDz446KJKSgr0UdRy5rPOfqqcYYwVqktfVSV9RExPr0/W1rDMDqa5a21QgiZbHC4K9FFUq62N9quzn0N8miWqOGMsUdWI0RGReL1ngl9w9aU3r9fgNZp4KCjQR9XsLJRKTHMXy+xoWtU6YlS1tGKavPJC/PJw3p/p8Y+21+A1mjjXFOijKhxs1KiNtWrU3praWVVLK456nZmfHm6b36fEC8xwB5RKnF25KvapGk2cXwr0UVarMVmJfws0zpvGtrOqljb8jhyhtjrfNL9PhUXmuIVa5W9hbo7JisU+VaOJ80uBPuLCaV6alGyZmaUaVKucXYofp6Ba2pAL5zSPzu+zyB5qHA9GFNdq8e8NjSbONQX6iGua5gUPRoz6+6nxeVhaYtKejH2eamnFFzMFEHNzGv2fZxopKutiRpDW2c8h+wzLvl5VMwva0yuVoLamD/gQ0uXlhpZGiko6Me0oNY4z57dQqQSPG2EOOkE61GZn20eETkxoNsUhp0CXdQntKLXK11lcDGrkrT/olpfhyBF1axw6tRocPdrcnnL0aM9/bqnLa7ZSBbqZXW9mj5vZaTO7PWb9vzSz/2Nml8zsnb0vpmQi7iyYWVAVr1ZZSjhBev68ujUOpZYplfsR5urymq2OgW5m48AngLcCe4H9Zra3ZbOzwLuBz/e6gJKh6FkwaGtfGWcl1cuoW6OAurwOQpoa+rXAaXd/wt0vAvcBN0Y3cPdFd/8OsNqHMkqWGrW2mPaVlS5a6NStMUcG1O6ROLWA3ht9k+YTehUQ7bv2VLhMiizmU1ch/SdR3Rpzok/tHmm+I5LeA3pv9E+mJ0XN7JCZLZjZwrlz57LctXQr5lM3wx1s58VUT3/b23pdINmUPrR7pP2O0MCk7KUJ9KeBqyOPd4fLuubuc+4+5e5Tu3bt2sxLSFbiPo2AET8cvNVnPqOTXwNXr8dfmQq21O6R9jtCA5Oy13FgkZltA34AXEcQ5A8DN7t72yVMzOyzwP9y9/s77VgDi4ZAvR58SsNQqHKGJaqpn16pBM3xMgCNanRr8jZs4T9nbKy9+yoEob2qs2h9t6WBRe5+CbgNeAD4PvBFd3/MzO40sxvCHfxTM3sK+H3gU2am61UVQeMEqQW18qSZGZPo5NeA1Otw8GBymG+x3UNt4/mVqg3d3U+6+6+7+6+5+0y47CPufiK8/7C773b3He5edvfX97PQkrHwkzrZxUnRyNMkS42a+coGXUy32O6htvH80khR6Sz8BM9wR9v82Um2b9cHfCCmp6kv37h+SUHOcCv/Zf3x+JPU2VojttrG80uTc0k69TocOECd/RygDh1Ojs7P6wM+CHWrcYi5lqtQOdH/r1JJATzMNDmXbF2tBpUKNY5TIaHnBEHNfFTDPA/zlkyPf7TtkoKtX74arVlcCnRJb2YGzBKaXpwyz/IX7//ayIZ5FvOWdPrSSLpsXCudsC4mBbqkV6vBBz9Ize5ru3TZPDWeZRe1kweAfNRWs5TFvCVpvjSSLhvXSiesC8rdB3J705ve5DKk5ufdg0yJvc0f/hsvlZoXl0rB01pfplJxNwv+tq4fJmbxh8Osd/uoVOL3UamsbzM/723HvvUW93/RjSL9vw0jYMETclWBLpuTlC7gFc5sKni2GjSDlCZstyrxS4OVpmRtDdzDh3sXwEX7fxtGCnTpvQ2qgsZKYm21ETZJtcdeBmCWsgi6cjnhmHEms2TN4otLNrZRoKsNXTan0Rk5RtIApCuvXG8DTjKsJ+s20zc7zXmGxjZm8ZcA3c6LzHBH8CCD7iuaEjfnkpK+3zfV0Asipso2z34vcaGttppUwxzFml6aGn2a9vAyz7T/DNpkedI0y6iGPnioyUX6Zn4+tnF3nv1e4YwbK2sBkdQGPIptsWmCcaOmqab28y0mazfNRWpDHzwFuvTX4cMbps58+UNeKT+/cU2zPFqhkKZXTKcvwKb2c/B5bvZK+fmuT352W+tWL5fBUqBL/x0+nFhTb21+SRMeRQ+NNCHaqYmqxAWfZ/9amJe2vbipmnMWXS6ldxToko2YLixJXRg3Co9uf9b3Kvyz/BKZn3efmGj+N05MNO8zOdBXvcKZtTD38fHEX0BpWmDULj5cFOiSrUiVL6kLY1yTS0M3ARMX/o3ddxPK3bYjbzX45+fdt29v3t/27c2vtWG/85ZCbqWWrXbx4aJAl2xFEjltDT1aO+0mnDqdOEwbTGm/RHoVfls5KRptN2/seKu17KI3cRWJAl2yFUm9+Db0+Fp7I3y6CadUJw5jnpf2dVq/RJLKNj7eXRh23N/8vM+XP9Te/TPSbh58fNsOuWrZBadAl+xF2tObujByJjHQG4FWLre3L5sF511bpena1wj1jQI37ZdImi+QNEGauL/y802N563HrinMr7su9pCrll1sCnQZnJjkStMMMzaWLijTDL5pDeG0rxPdrtOUBd3+Kojd38TLPj/+rnQ7eO1re/QfJMNGgS6DEzMzY9qujGmDMhq2reGdVKPe6HVaa7hpvjTivkTSHJq1/ZWf93lu7vzC4+PxP1VkZCjQZbBiBh5FmxJgtWdB2RrKWwnchm5q5mlr6G3Hp1cnA6TwNgp0Tc4l/ffJTwbXpatU1hbVOM4ie1hlnDLPpn6pThdmqNVgcRFWV4O/kV129TpRG00mFqdU6uIC2bfeCnffHUR2z15URpUCXbLRSNqYhH2Jy1K9xMRE95k2MxNkYVS32Tg+nm6btLMsrtm3LwjzTsx0VWdJRYEu2YpJ2Au8MtVTO1Vi42xmWttWKyudt1ldXf9V0PG163W47DI4darzC2/fDvfeqzCXVMw38ynpgampKV9YWBjIvmXA6vVg3u6wLcNYpfXK9EkqlSA0s1Stdm52SV2u178evve9dDsul2F2VmEuTczsEXefilunGrpkr9H8Ui4DdNWGHg3WrC5EHdds0+rChRT77ybMDx+GZ59VmEtXFOgyOLOzMDHBLEfYzostK1cTnuRccUXQfPKudwUB7x78PXQoXah3+0VQq8HBg+tt6WNjQXt+1PnzG+y/XoedO9OH+RVXBCeSRbqV1P2l3zd1WxR3D/oZlstN3RjLPOPbuNizfuqtu+t2iHxcr8KkXoblcktf9sN/010n9saFV0USoH7oknuRAUhpJ/TaKA+ThsBv5mIOabqIJ91K9kLzcP2NbpddpjCXjjYKdJ0Ulfyo1+EP/5Cx1ZfZ7BCJchl+8YvgeskNpdJ6z5axsfjeMmZBL5VWaU6IdlJhkUX2bLzRddfBgw9ubUcyEnRSVIZDrQaf+xyT43+/qac3TlxGw7zxeHo6uJ80oChp+UZXs7e2jjnxlaOzdBjFdPiwwlx6QoEu+VKrMXNsd5dPcsC5/PLg5GScRjB3O9BooxGlH/wgVF7xE4xVKiwm9taZJOZboVwORs+66wSo9IwCXXKnVlvr0ZiSAcb582AJteRGMHc70Ghmpr1HCwRNN2/+wVEWX/xVVhlnkT3McoQSLzRtV+IFZrijeYfz8+qSKH2hQJdcmp3t3Pc7jmPhQKV1JV5gZunmIFCrVWrUm+Z7SczVffuoHTBeefFc26rVVZg+dV3TshrHmeMWKiyu1drnuIVa5W9Jt0ORrUkV6GZ2vZk9bmanzez2mPWXmdkXwvXfMrNqrwsqo6VRk+6uph5waA9Vjgcrl5bgwIEg3Bu3apX6rV+jevlPGLNVqrZI3W5eG5r/HPGFWGKSOvubyx2ZdGyRPcF+NamWZCWp+0vjBowDPwJeB0wA3wb2tmxzK3BPeP8m4AudXlfdFiWtaDfEVH3Ro9fcTHGLm589eqm3jbpRtl0SrvXWclUhka1ii9PnXgucdvcn3P0icB9wY8s2NwLHwvv3A9eZtfcBENmM6JS4SdPhNqy1WXdhmrtYZkfTsmV2MM1dAMxwR1vbeNx2TcbH1XtFMpcm0K8Cnow8fipcFruNu18Cfgbtv1PN7JCZLZjZwrlz7e2SIkkaw/WXltq7CzYeV8oXOGifY5q7GGOFKmfamkTiJHUrbCxvtI137JbYCHF3uHRJvVckc5meFHX3OXefcvepXbt2ZblrGWL1ejBPSmOAj3skxCvB7LLuMDN7Bce238ISVZwxlqhyiE/Hhnqd/VQ5wxgrjCXMGxPtbljjOBXiRxhNVsYU4pILaQL9aeDqyOPd4bLYbcxsG/DLQEKPYJHuTE+3DxZyX5+yttFpZHoali9ua9ourkmkzn4Ocmwt+FfYRmvt21hlicmmWn5c04suJCR5kibQHwauMbM9ZjZBcNLzRMs2J4CD4f13Ag+FjfciW5Y0WrN1eeJ2Vg2+AebnYccOPsA9rLC9ZSsjmOFxFWM1nHogrOWXPk993qn555mb37Gli2WI9FPHQA/bxG8DHgC+D3zR3R8zszvN7IZws/8GlM3sNPBhoK1ro8hmpRmuX68Hg3023K5WgwsXeIFfStjTGJXKWNs8MtGpA1qvWaowlzzZ1nkTcPeTwMmWZR+J3H8R+P3eFk0kMDMTtKG3TrjVaOpotLHHXSpu+/ZgOoBGm3unfu1pfw2I5JFGikrudRquH9fGDuszK164sL4saa6XxvbdTt4lkiepaugig1arJTdvJNWeGxduTusDH4A3v3njXwMieaYaugy9zdaeG5eUGx8PpiM/eTK4rN3llwdNMzrxKcNGgS5DL2lK3E7t5ZcuBU0yx47BN76xfn3S8+eDi2Tce69OfMpwUaDL0EtqY5+dTX5ONOzj2uCjPVtEhoXa0KUQktrYv/51uPvu5mUTE81hr54tUhSqoUuhffKTwXiiaO396NHm8FfPFikKBboUXqfBQN1elk4krxToMvK6vSydSF6pDV2Ejfu5iwwL1dBlpDTmVR8bC/7W64MukUjvqIYuI6Mx50uji+LSUvAYVDuXYlANXUaG+ptL0SnQZWSov7kUnQJdRob6m0vRKdBlZKi/uRSdAl1GhvqbS9Gpl4uMFPU3lyJTDV1EpCAU6CIiBaFAFxEpCAW6iEhBKNBFRApCgS4iUhAKdBGRgjB3H8yOzc4BSxnvdifwbMb73CqVOTvDWG6VORt5KnPF3XfFrRhYoA+CmS24+9Sgy9ENlTk7w1hulTkbw1JmNbmIiBSEAl1EpCBGLdDnBl2ATVCZszOM5VaZszEUZR6pNnQRkSIbtRq6iEhhKdBFRAqicIFuZlea2ZfN7Ifh31fFbPM7ZvZo5Paimb09XPdZMzsTWfeGPJQ53G4lUq4TkeV7zOxbZnbazL5gZhN5KLOZvcHMvmFmj5nZd8zsX0fWZXaczex6M3s8PD63x6y/LDxup8PjWI2s+9Nw+eNm9pZ+lXETZf6wmX0vPK6nzKwSWRf7PslJud9tZuci5Xt/ZN3B8P30QzM7mKMy/3mkvD8ws3+IrBvYsY7l7oW6AR8Dbg/v3w58tMP2VwLPAaXw8WeBd+axzMCFhOVfBG4K798DHM5DmYFfB64J778W+DHwK1keZ2Ac+BHwOmAC+Dawt2WbW4F7wvs3AV8I7+8Nt78M2BO+znhOyvw7kffs4UaZN3qf5KTc7wb+a8xzrwSeCP++Krz/qjyUuWX7DwFHB32sk26Fq6EDNwLHwvvHgLd32P6dwJfcfbmvpdpYt2VeY2YG/C5w/2aevwUdy+zuP3D3H4b3/x54Bogd4dZH1wKn3f0Jd78I3EdQ9qjov+V+4LrwuN4I3OfuL7n7GeB0+HoDL7O7fyXynv0msDuDcnWS5lgneQvwZXd/zt1/CnwZuL5P5Yzqtsz7geMZlGtTihjor3b3H4f3/x/w6g7b30T7f9BM+FP2z83ssp6XsF3aMr/CzBbM7JuNJiKgDPyDu18KHz8FXNXHsjZ0dZzN7FqCGtCPIouzOM5XAU9GHscdn7VtwuP4M4Ljmua5/dDtft8HfCnyOO59koW05X5H+P9+v5ld3eVzey31fsNmrT3AQ5HFgzrWsYbymqJm9iDwqzGrpqMP3N3NLLFfppm9BvhN4IHI4j8lCKgJgr6nfwLcmZMyV9z9aTN7HfCQmX2XIHz6osfH+V7goLuvhov7cpxHjZkdAKaA34osbnufuPuP4l8hc/8TOO7uL5nZBwh+Gf3ugMuU1k3A/e6+ElmWq2M9lIHu7vuS1pnZT8zsNe7+4zBIntngpf4A+Ct3fzny2o1a50tm9hfAv81Lmd396fDvE2b2VeCNwH8HfsXMtoW1y93A03kps5n9EvDXwLS7fzPy2n05zjGeBq6OPI47Po1tnjKzbcAvA+dTPrcfUu3XzPYRfLn+lru/1Fie8D7JImQ6ltvdz0cefobgXEzjub/d8tyv9ryE7br5P74J+KPoggEe61hFbHI5ATTOkB8E/scG27a1h4Xh1Gibfjvwd30oY6uOZTazVzWaJcxsJ/Bm4HsenJn5CsG5gMTn90GaMk8AfwV8zt3vb1mX1XF+GLjGgp5AEwQfytbeCNF/yzuBh8LjegK4KewFswe4BvjffSpnV2U2szcCnwJucPdnIstj3ycZlDltuV8TeXgD8P3w/gPA74XlfxXwezT/ch5YmQHM7DcITtZ+I7JskMc63qDPyvb6RtD2eQr4IfAgcGW4fAr4TGS7KsE38VjL8x8CvksQMPPAFXkoM/DPw3J9O/z7vsjzX0cQNKeBvwQuy0mZDwAvA49Gbm/I+jgDbwN+QFBzmg6X3UkQhgCvCI/b6fA4vi7y3OnweY8Db83wfdypzA8CP4kc1xOd3ic5Kfd/Ah4Ly/cV4Dciz31v+H9wGnhPXsocPv4PwH9ued5Aj3XcTUP/RUQKoohNLiIiI0mBLiJSEAp0EZGCUKCLiBSEAl1EpCAU6CIiBaFAFxEpiP8Ptu7cvVG/7NEAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# size of the latent space\n",
    "latent_dim = 5\n",
    "# create the discriminator\n",
    "discriminator = define_discriminator()\n",
    "# create the generator\n",
    "generator = define_generator(latent_dim)\n",
    "# create the gan\n",
    "gan_model = define_gan(generator, discriminator)\n",
    "# train model\n",
    "train(generator, discriminator, gan_model, latent_dim)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "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.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
About this Algorithm

G.A.N

Generative Adversial Network:

  • The main focus for GAN is to generate data from scratch.
  • It brings us closer to understanding intelligence.
  • It trains two deep networks, called Generator and Discriminator, that compete and cooperate with each other. In the course of training, both networks eventually learn how to perform their tasks.
    • The generator never actually sees examples from the domain and is adapted based on how well the discriminator performs.
# The Import Statements:
from matplotlib import pyplot
import numpy as np
from keras.models import Sequential
from keras.layers import Dense
from keras.utils.vis_utils import plot_model
Using TensorFlow backend.

Defining a 1 D function:

y=f(x)

def function_1D(x):
    return x*x
inputs=np.arange(-0.5,0.6,0.1)
outputs=[function_1D(x) for x in inputs]
# plot the result
pyplot.plot(inputs, outputs)
pyplot.show()
#Defining random values
def generate_samples(n=100):
    x1=np.random.rand(n)-0.5
    x2=x1*x1
    x1=x1.reshape(n,1)
    x2=x2.reshape(n,1)
    return np.hstack((x1,x2))
# generate samples and plotting them
data = generate_samples()

pyplot.scatter(data[:, 0], data[:, 1])
pyplot.show()

Note:

a sample is comprised of a vector with two elements, one for the input and one for the output of our one-dimensional function.

The Discriminator

  • The difference from a typical CNN is the absence of max-pooling in between layers.
  • will have 1 hidden layer with 25 nodes.
  • will use the ReLU activation function
  • The output layer will have 1 node for the binary classification using the sigmoid activation function.
  • Loss Function: Binary Cross Entropy
  • Optimizer : Adam version of stochastic Gradient Descent
#Code for the Discriminator Unit:
def define_discriminator(n_inputs=2):
	model = Sequential()
	model.add(Dense(25, activation='relu', kernel_initializer='he_uniform', input_dim=n_inputs))
	model.add(Dense(1, activation='sigmoid'))
	# compile model
	model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
	return model
# define the discriminator model
model = define_discriminator()
# summarize the model
model.summary()
Model: &quot;sequential_1&quot;
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_1 (Dense)              (None, 25)                75        
_________________________________________________________________
dense_2 (Dense)              (None, 1)                 26        
=================================================================
Total params: 101
Trainable params: 101
Non-trainable params: 0
_________________________________________________________________
def generate_real_samples(n):
    x1=np.random.rand(n)-0.5
    x2=x1*x1
    x1=x1.reshape(n,1)
    x2=x2.reshape(n,1)
    X= np.hstack((x1,x2))
    y=np.ones((n,1))
    return X,y
def generate_fake_samples(n):
	# generate inputs in [-1, 1]
	X1 = -1 + np.random.rand(n) * 2
	# generate outputs in [-1, 1]
	X2 = -1 + np.random.rand(n) * 2
	# stack arrays
	X1 = X1.reshape(n, 1)
	X2 = X2.reshape(n, 1)
	X = np.hstack((X1, X2))
	# generate class labels
	y = np.zeros((n, 1))
	return X, y
#training the discriminator model
def train_discriminator(model, n_epochs=1000, n_batch=128):
	half_batch = int(n_batch / 2)
	# run epochs manually
	for i in range(n_epochs):
		# generate real examples
		X_real, y_real = generate_real_samples(half_batch)
		# update model
		model.train_on_batch(X_real, y_real)
		# generate fake examples
		X_fake, y_fake = generate_fake_samples(half_batch)
		# update model
		model.train_on_batch(X_fake, y_fake)
		# evaluate the model
		_, acc_real = model.evaluate(X_real, y_real, verbose=0)
		_, acc_fake = model.evaluate(X_fake, y_fake, verbose=0)
		print(i, acc_real, acc_fake)
# define the discriminator model
model = define_discriminator()
# fit the model
train_discriminator(model)
0 0.5 0.15625
1 0.546875 0.25
2 0.578125 0.21875
3 0.5625 0.21875
4 0.640625 0.234375
5 0.515625 0.40625
6 0.515625 0.46875
7 0.59375 0.390625
8 0.5625 0.46875
9 0.53125 0.4375
10 0.46875 0.484375
11 0.421875 0.53125
12 0.46875 0.484375
13 0.515625 0.5625
14 0.46875 0.6875
15 0.5625 0.515625
16 0.515625 0.53125
17 0.53125 0.5
18 0.484375 0.609375
19 0.40625 0.5
20 0.46875 0.671875
21 0.484375 0.59375
22 0.546875 0.609375
23 0.375 0.53125
24 0.421875 0.53125
25 0.34375 0.65625
26 0.421875 0.484375
27 0.421875 0.578125
28 0.328125 0.546875
29 0.359375 0.640625
30 0.4375 0.609375
31 0.296875 0.484375
32 0.296875 0.53125
33 0.515625 0.625
34 0.359375 0.59375
35 0.40625 0.65625
36 0.359375 0.6875
37 0.28125 0.578125
38 0.328125 0.578125
39 0.328125 0.671875
40 0.40625 0.671875
41 0.296875 0.515625
42 0.296875 0.578125
43 0.296875 0.625
44 0.34375 0.625
45 0.390625 0.671875
46 0.375 0.609375
47 0.34375 0.59375
48 0.359375 0.578125
49 0.359375 0.6875
50 0.34375 0.65625
51 0.375 0.515625
52 0.390625 0.609375
53 0.234375 0.625
54 0.359375 0.625
55 0.234375 0.59375
56 0.40625 0.6875
57 0.34375 0.765625
58 0.296875 0.609375
59 0.265625 0.59375
60 0.25 0.65625
61 0.390625 0.65625
62 0.265625 0.65625
63 0.46875 0.703125
64 0.40625 0.59375
65 0.359375 0.625
66 0.28125 0.625
67 0.3125 0.625
68 0.328125 0.640625
69 0.390625 0.625
70 0.28125 0.640625
71 0.328125 0.609375
72 0.296875 0.59375
73 0.125 0.703125
74 0.359375 0.765625
75 0.359375 0.65625
76 0.34375 0.5625
77 0.234375 0.671875
78 0.34375 0.6875
79 0.21875 0.734375
80 0.3125 0.78125
81 0.28125 0.6875
82 0.34375 0.640625
83 0.375 0.765625
84 0.34375 0.640625
85 0.328125 0.703125
86 0.21875 0.75
87 0.25 0.65625
88 0.28125 0.640625
89 0.3125 0.78125
90 0.234375 0.71875
91 0.328125 0.71875
92 0.25 0.671875
93 0.25 0.703125
94 0.265625 0.546875
95 0.296875 0.546875
96 0.328125 0.625
97 0.265625 0.75
98 0.296875 0.671875
99 0.265625 0.703125
100 0.15625 0.734375
101 0.234375 0.796875
102 0.25 0.71875
103 0.21875 0.828125
104 0.21875 0.828125
105 0.328125 0.765625
106 0.21875 0.671875
107 0.28125 0.84375
108 0.21875 0.796875
109 0.21875 0.78125
110 0.25 0.65625
111 0.25 0.8125
112 0.21875 0.859375
113 0.28125 0.796875
114 0.234375 0.625
115 0.21875 0.671875
116 0.234375 0.859375
117 0.265625 0.71875
118 0.21875 0.765625
119 0.234375 0.765625
120 0.234375 0.6875
121 0.234375 0.8125
122 0.296875 0.828125
123 0.25 0.796875
124 0.234375 0.890625
125 0.359375 0.765625
126 0.203125 0.75
127 0.328125 0.703125
128 0.203125 0.78125
129 0.265625 0.796875
130 0.3125 0.828125
131 0.21875 0.828125
132 0.25 0.828125
133 0.296875 0.84375
134 0.203125 0.875
135 0.34375 0.734375
136 0.421875 0.765625
137 0.15625 0.796875
138 0.359375 0.75
139 0.234375 0.75
140 0.421875 0.71875
141 0.28125 0.703125
142 0.1875 0.6875
143 0.21875 0.828125
144 0.25 0.890625
145 0.265625 0.9375
146 0.171875 0.8125
147 0.265625 0.84375
148 0.296875 0.90625
149 0.171875 0.875
150 0.21875 0.765625
151 0.25 0.875
152 0.25 0.90625
153 0.25 0.90625
154 0.328125 0.796875
155 0.296875 0.921875
156 0.234375 0.84375
157 0.25 0.875
158 0.1875 0.9375
159 0.234375 0.859375
160 0.234375 0.890625
161 0.28125 0.984375
162 0.21875 0.90625
163 0.21875 0.90625
164 0.265625 0.953125
165 0.28125 0.953125
166 0.328125 0.984375
167 0.28125 0.96875
168 0.25 0.953125
169 0.359375 0.921875
170 0.34375 1.0
171 0.328125 0.953125
172 0.296875 0.96875
173 0.359375 0.921875
174 0.28125 0.9375
175 0.375 0.984375
176 0.359375 0.96875
177 0.265625 0.984375
178 0.21875 0.96875
179 0.28125 0.9375
180 0.359375 1.0
181 0.34375 0.984375
182 0.40625 0.984375
183 0.296875 0.953125
184 0.34375 0.984375
185 0.3125 0.984375
186 0.359375 0.96875
187 0.375 0.984375
188 0.53125 0.953125
189 0.40625 0.921875
190 0.453125 0.953125
191 0.375 0.96875
192 0.609375 0.9375
193 0.40625 0.96875
194 0.4375 0.96875
195 0.390625 0.96875
196 0.40625 0.984375
197 0.4375 1.0
198 0.546875 0.953125
199 0.328125 1.0
200 0.328125 0.984375
201 0.328125 0.984375
202 0.453125 0.96875
203 0.34375 0.96875
204 0.34375 0.984375
205 0.359375 0.96875
206 0.359375 0.984375
207 0.421875 0.96875
208 0.5 0.984375
209 0.40625 1.0
210 0.390625 0.96875
211 0.546875 0.96875
212 0.390625 0.984375
213 0.5 0.921875
214 0.578125 0.96875
215 0.671875 0.9375
216 0.484375 0.984375
217 0.4375 0.90625
218 0.453125 0.96875
219 0.421875 0.953125
220 0.625 0.9375
221 0.5 0.953125
222 0.578125 0.984375
223 0.53125 0.9375
224 0.5625 0.984375
225 0.546875 0.984375
226 0.5625 0.96875
227 0.578125 0.984375
228 0.5625 0.953125
229 0.546875 0.90625
230 0.546875 0.921875
231 0.75 1.0
232 0.546875 1.0
233 0.671875 1.0
234 0.5625 0.96875
235 0.640625 0.984375
236 0.6875 0.921875
237 0.59375 0.90625
238 0.71875 0.921875
239 0.609375 1.0
240 0.59375 0.953125
241 0.65625 0.953125
242 0.640625 0.984375
243 0.6875 0.984375
244 0.546875 0.9375
245 0.71875 1.0
246 0.71875 0.953125
247 0.609375 1.0
248 0.671875 0.96875
249 0.625 0.953125
250 0.53125 0.921875
251 0.6875 0.984375
252 0.625 0.921875
253 0.65625 0.984375
254 0.625 0.9375
255 0.75 0.96875
256 0.609375 0.984375
257 0.640625 0.921875
258 0.6875 0.984375
259 0.671875 1.0
260 0.625 0.9375
261 0.65625 0.984375
262 0.703125 0.96875
263 0.734375 1.0
264 0.65625 0.984375
265 0.578125 0.9375
266 0.59375 0.96875
267 0.703125 0.921875
268 0.734375 1.0
269 0.734375 1.0
270 0.703125 0.984375
271 0.734375 0.984375
272 0.6875 0.953125
273 0.703125 0.96875
274 0.71875 1.0
275 0.65625 0.953125
276 0.75 0.921875
277 0.609375 0.984375
278 0.6875 1.0
279 0.6875 0.953125
280 0.765625 1.0
281 0.796875 1.0
282 0.734375 0.96875
283 0.671875 0.984375
284 0.578125 1.0
285 0.671875 0.953125
286 0.671875 0.984375
287 0.75 0.9375
288 0.734375 0.984375
289 0.71875 0.96875
290 0.75 0.96875
291 0.6875 0.984375
292 0.65625 0.9375
293 0.734375 0.984375
294 0.65625 0.953125
295 0.703125 0.96875
296 0.6875 0.984375
297 0.71875 0.984375
298 0.734375 0.953125
299 0.71875 0.9375
300 0.734375 0.984375
301 0.78125 0.953125
302 0.75 0.9375
303 0.75 0.953125
304 0.796875 0.96875
305 0.734375 1.0
306 0.71875 0.921875
307 0.796875 0.953125
308 0.84375 0.96875
309 0.75 0.96875
310 0.71875 1.0
311 0.828125 0.96875
312 0.8125 0.984375
313 0.78125 0.9375
314 0.84375 0.96875
315 0.6875 0.984375
316 0.84375 0.953125
317 0.8125 0.984375
318 0.765625 0.9375
319 0.71875 0.9375
320 0.703125 0.9375
321 0.671875 0.96875
322 0.703125 0.921875
323 0.765625 0.96875
324 0.703125 0.953125
325 0.828125 0.96875
326 0.828125 0.96875
327 0.78125 0.984375
328 0.8125 0.953125
329 0.796875 0.984375
330 0.765625 0.9375
331 0.890625 0.90625
332 0.8125 0.90625
333 0.8125 1.0
334 0.78125 0.96875
335 0.875 0.96875
336 0.84375 0.984375
337 0.796875 1.0
338 0.8125 0.984375
339 0.78125 0.9375
340 0.875 0.953125
341 0.8125 0.921875
342 0.796875 0.90625
343 0.796875 0.953125
344 0.8125 0.984375
345 0.890625 0.9375
346 0.828125 0.9375
347 0.78125 0.96875
348 0.90625 0.953125
349 0.828125 0.96875
350 0.796875 0.953125
351 0.734375 0.921875
352 0.796875 0.984375
353 0.765625 0.921875
354 0.8125 0.90625
355 0.765625 0.96875
356 0.84375 0.96875
357 0.875 0.953125
358 0.8125 0.90625
359 0.828125 0.96875
360 0.828125 0.953125
361 0.84375 0.984375
362 0.859375 0.9375
363 0.859375 0.953125
364 0.859375 0.9375
365 0.875 0.96875
366 0.875 0.953125
367 0.8125 0.953125
368 0.90625 0.9375
369 0.875 0.984375
370 0.9375 0.890625
371 0.875 0.9375
372 0.796875 0.921875
373 0.828125 0.921875
374 0.90625 0.921875
375 0.8125 0.9375
376 0.8125 0.90625
377 0.90625 0.921875
378 0.765625 1.0
379 0.78125 0.953125
380 0.78125 0.953125
381 0.875 0.953125
382 0.875 0.9375
383 0.84375 0.890625
384 0.796875 0.9375
385 0.859375 0.96875
386 0.8125 0.96875
387 0.90625 0.953125
388 0.921875 0.9375
389 0.890625 0.953125
390 0.96875 0.921875
391 0.84375 0.875
392 0.875 0.921875
393 0.828125 0.9375
394 0.921875 0.9375
395 0.890625 0.9375
396 0.921875 0.921875
397 0.890625 1.0
398 0.875 0.984375
399 0.921875 0.9375
400 0.828125 0.953125
401 0.828125 0.90625
402 0.9375 0.953125
403 0.8125 0.890625
404 0.953125 0.953125
405 0.9375 0.890625
406 0.90625 0.96875
407 0.890625 0.984375
408 0.875 0.9375
409 0.921875 0.984375
410 0.859375 0.96875
411 0.890625 0.953125
412 0.921875 0.96875
413 0.921875 1.0
414 0.921875 0.96875
415 0.875 0.90625
416 0.96875 0.96875
417 0.890625 0.921875
418 0.90625 0.953125
419 0.875 0.9375
420 0.875 0.921875
421 0.96875 0.953125
422 0.921875 0.96875
423 0.890625 0.875
424 0.84375 0.90625
425 0.921875 0.984375
426 0.953125 0.890625
427 1.0 0.90625
428 0.890625 0.9375
429 0.921875 0.9375
430 0.9375 0.953125
431 0.96875 0.953125
432 0.90625 0.9375
433 0.953125 0.875
434 0.953125 0.890625
435 0.96875 0.90625
436 0.9375 0.953125
437 0.96875 0.953125
438 0.953125 0.890625
439 0.921875 0.953125
440 0.953125 0.90625
441 0.90625 0.984375
442 0.96875 0.96875
443 0.984375 0.9375
444 0.921875 0.9375
445 0.96875 0.90625
446 0.921875 0.96875
447 0.890625 0.875
448 0.953125 0.953125
449 0.984375 0.953125
450 0.921875 0.953125
451 1.0 0.90625
452 0.984375 0.96875
453 1.0 0.90625
454 0.953125 0.953125
455 0.96875 0.9375
456 0.953125 0.90625
457 1.0 0.921875
458 0.984375 0.96875
459 0.984375 0.90625
460 0.984375 0.984375
461 1.0 0.921875
462 0.984375 0.953125
463 0.96875 0.921875
464 1.0 0.921875
465 0.984375 0.859375
466 1.0 0.90625
467 1.0 0.890625
468 1.0 0.90625
469 1.0 0.875
470 1.0 0.84375
471 1.0 0.875
472 0.984375 0.859375
473 1.0 0.859375
474 1.0 0.921875
475 0.984375 0.96875
476 1.0 0.875
477 1.0 0.890625
478 1.0 0.921875
479 1.0 0.890625
480 1.0 0.953125
481 1.0 0.90625
482 1.0 0.890625
483 1.0 0.90625
484 1.0 0.90625
485 1.0 0.890625
486 1.0 0.921875
487 1.0 0.96875
488 1.0 0.9375
489 1.0 0.921875
490 1.0 0.890625
491 1.0 0.890625
492 1.0 0.9375
493 1.0 0.90625
494 0.984375 0.9375
495 1.0 0.875
496 1.0 0.890625
497 1.0 0.9375
498 1.0 0.921875
499 0.984375 0.921875
500 1.0 0.921875
501 1.0 0.875
502 1.0 0.90625
503 1.0 0.953125
504 1.0 0.921875
505 1.0 0.96875
506 1.0 0.953125
507 1.0 0.921875
508 1.0 0.921875
509 1.0 0.890625
510 1.0 0.96875
511 1.0 0.921875
512 1.0 0.921875
513 1.0 0.859375
514 1.0 0.875
515 1.0 0.921875
516 1.0 0.9375
517 1.0 0.890625
518 1.0 0.90625
519 1.0 0.875
520 1.0 0.90625
521 1.0 0.9375
522 1.0 0.921875
523 1.0 0.875
524 1.0 0.875
525 1.0 0.921875
526 1.0 0.953125
527 1.0 0.90625
528 1.0 0.90625
529 1.0 0.90625
530 1.0 0.890625
531 1.0 0.90625
532 1.0 0.921875
533 1.0 0.921875
534 1.0 0.953125
535 1.0 0.875
536 1.0 0.90625
537 1.0 0.859375
538 1.0 0.890625
539 1.0 0.9375
540 1.0 0.9375
541 1.0 0.953125
542 1.0 0.890625
543 1.0 0.90625
544 1.0 0.84375
545 1.0 0.890625
546 1.0 0.890625
547 1.0 0.953125
548 1.0 0.9375
549 1.0 0.9375
550 1.0 0.890625
551 1.0 0.96875
552 1.0 0.921875
553 1.0 0.890625
554 1.0 0.90625
555 1.0 0.96875
556 1.0 0.921875
557 1.0 0.953125
558 1.0 0.890625
559 1.0 0.9375
560 1.0 0.9375
561 1.0 0.90625
562 1.0 0.9375
563 1.0 0.953125
564 1.0 0.875
565 1.0 0.90625
566 1.0 0.859375
567 1.0 0.875
568 1.0 0.921875
569 1.0 0.84375
570 1.0 0.890625
571 1.0 0.890625
572 1.0 0.953125
573 1.0 0.90625
574 1.0 0.921875
575 1.0 0.921875
576 1.0 0.921875
577 1.0 0.859375
578 1.0 0.9375
579 1.0 0.953125
580 1.0 0.921875
581 1.0 0.875
582 1.0 0.875
583 1.0 0.875
584 1.0 0.921875
585 1.0 0.890625
586 1.0 0.890625
587 1.0 0.890625
588 1.0 0.90625
589 1.0 0.875
590 1.0 0.90625
591 1.0 0.859375
592 1.0 0.90625
593 1.0 0.84375
594 1.0 0.859375
595 1.0 0.890625
596 1.0 0.90625
597 1.0 0.875
598 1.0 0.953125
599 1.0 0.875
600 1.0 0.859375
601 1.0 0.9375
602 1.0 0.875
603 1.0 0.859375
604 1.0 0.90625
605 1.0 0.90625
606 1.0 0.78125
607 1.0 0.828125
608 1.0 0.9375
609 1.0 0.921875
610 1.0 0.90625
611 1.0 0.953125
612 1.0 0.890625
613 1.0 0.9375
614 1.0 0.921875
615 1.0 0.796875
616 1.0 0.890625
617 1.0 0.921875
618 1.0 0.90625
619 1.0 0.890625
620 1.0 0.859375
621 1.0 0.921875
622 1.0 0.828125
623 1.0 0.875
624 1.0 0.953125
625 1.0 0.84375
626 1.0 0.9375
627 1.0 0.9375
628 1.0 0.859375
629 1.0 0.9375
630 1.0 0.90625
631 1.0 0.9375
632 1.0 0.921875
633 1.0 0.90625
634 1.0 0.90625
635 1.0 0.890625
636 1.0 0.78125
637 1.0 0.90625
638 1.0 0.890625
639 1.0 0.921875
640 1.0 0.75
641 1.0 0.875
642 1.0 0.875
643 1.0 0.90625
644 1.0 0.953125
645 1.0 0.921875
646 1.0 0.890625
647 1.0 0.859375
648 1.0 0.84375
649 1.0 0.90625
650 1.0 0.84375
651 1.0 0.84375
652 1.0 0.921875
653 1.0 0.90625
654 1.0 0.921875
655 1.0 0.921875
656 1.0 0.921875
657 1.0 0.84375
658 1.0 0.84375
659 1.0 0.90625
660 1.0 0.953125
661 1.0 0.890625
662 1.0 0.875
663 1.0 0.84375
664 1.0 0.84375
665 1.0 0.8125
666 1.0 0.859375
667 1.0 0.90625
668 1.0 0.90625
669 1.0 0.875
670 1.0 0.921875
671 1.0 0.84375
672 1.0 0.953125
673 1.0 0.84375
674 1.0 0.8125
675 1.0 0.84375
676 1.0 0.921875
677 1.0 0.953125
678 1.0 0.84375
679 1.0 0.859375
680 1.0 0.859375
681 1.0 0.90625
682 1.0 0.90625
683 1.0 0.90625
684 1.0 0.828125
685 1.0 0.875
686 1.0 0.9375
687 1.0 0.859375
688 1.0 0.859375
689 1.0 0.84375
690 1.0 0.953125
691 1.0 0.84375
692 1.0 0.859375
693 1.0 0.9375
694 1.0 0.890625
695 1.0 0.859375
696 1.0 0.875
697 1.0 0.875
698 1.0 0.9375
699 1.0 0.890625
700 1.0 0.921875
701 1.0 0.828125
702 1.0 0.84375
703 1.0 0.90625
704 1.0 0.859375
705 1.0 0.90625
706 1.0 0.921875
707 1.0 0.9375
708 1.0 0.84375
709 1.0 0.875
710 1.0 0.90625
711 1.0 0.90625
712 1.0 0.890625
713 1.0 0.921875
714 1.0 0.90625
715 1.0 0.890625
716 1.0 0.8125
717 1.0 0.875
718 1.0 0.890625
719 1.0 0.890625
720 1.0 0.90625
721 1.0 0.875
722 1.0 0.84375
723 1.0 0.9375
724 1.0 0.90625
725 1.0 0.84375
726 1.0 0.9375
727 1.0 0.875
728 1.0 0.8125
729 1.0 0.84375
730 1.0 0.9375
731 1.0 0.84375
732 1.0 0.875
733 1.0 0.921875
734 1.0 0.78125
735 1.0 0.78125
736 1.0 0.859375
737 1.0 0.84375
738 1.0 0.90625
739 1.0 0.859375
740 1.0 0.875
741 1.0 0.859375
742 1.0 0.890625
743 1.0 0.875
744 1.0 0.890625
745 1.0 0.859375
746 1.0 0.8125
747 1.0 0.859375
748 1.0 0.953125
749 1.0 0.84375
750 1.0 0.890625
751 1.0 0.796875
752 1.0 0.890625
753 1.0 0.796875
754 1.0 0.84375
755 1.0 0.890625
756 1.0 0.875
757 1.0 0.890625
758 1.0 0.921875
759 1.0 0.84375
760 1.0 0.875
761 1.0 0.859375
762 1.0 0.953125
763 1.0 0.890625
764 1.0 0.859375
765 1.0 0.84375
766 1.0 0.828125
767 1.0 0.8125
768 1.0 0.84375
769 1.0 0.859375
770 1.0 0.875
771 1.0 0.890625
772 1.0 0.90625
773 1.0 0.90625
774 1.0 0.953125
775 1.0 0.90625
776 1.0 0.890625
777 1.0 0.890625
778 1.0 0.921875
779 1.0 0.90625
780 1.0 0.90625
781 1.0 0.90625
782 1.0 0.796875
783 1.0 0.765625
784 1.0 0.921875
785 1.0 0.875
786 1.0 0.890625
787 1.0 0.90625
788 1.0 0.90625
789 1.0 0.890625
790 1.0 0.859375
791 1.0 0.890625
792 1.0 0.875
793 1.0 0.796875
794 1.0 0.859375
795 1.0 0.828125
796 1.0 0.890625
797 1.0 0.875
798 1.0 0.890625
799 1.0 0.8125
800 1.0 0.875
801 1.0 0.921875
802 1.0 0.90625
803 1.0 0.890625
804 1.0 0.90625
805 1.0 0.890625
806 1.0 0.90625
807 1.0 0.9375
808 1.0 0.90625
809 1.0 0.90625
810 1.0 0.859375
811 1.0 0.859375
812 1.0 0.890625
813 1.0 0.875
814 1.0 0.8125
815 1.0 0.875
816 1.0 0.921875
817 1.0 0.9375
818 1.0 0.890625
819 1.0 0.90625
820 1.0 0.921875
821 1.0 0.875
822 1.0 0.9375
823 1.0 0.90625
824 1.0 0.875
825 1.0 0.84375
826 1.0 0.875
827 1.0 0.8125
828 1.0 0.8125
829 1.0 0.890625
830 1.0 0.78125
831 1.0 0.890625
832 1.0 0.890625
833 1.0 0.84375
834 1.0 0.859375
835 1.0 0.875
836 1.0 0.890625
837 1.0 0.9375
838 1.0 0.953125
839 1.0 0.875
840 1.0 0.890625
841 1.0 0.78125
842 1.0 0.921875
843 1.0 0.875
844 1.0 0.84375
845 1.0 0.859375
846 1.0 0.828125
847 1.0 0.8125
848 1.0 0.921875
849 1.0 0.890625
850 1.0 0.84375
851 1.0 0.96875
852 1.0 0.90625
853 1.0 0.9375
854 1.0 0.875
855 1.0 0.890625
856 1.0 0.859375
857 1.0 0.890625
858 1.0 0.8125
859 1.0 0.875
860 1.0 0.875
861 1.0 0.875
862 1.0 0.859375
863 1.0 0.875
864 1.0 0.9375
865 1.0 0.796875
866 1.0 0.84375
867 1.0 0.90625
868 1.0 0.875
869 1.0 0.890625
870 1.0 0.953125
871 1.0 0.890625
872 1.0 0.90625
873 1.0 0.828125
874 1.0 0.96875
875 1.0 0.90625
876 1.0 0.84375
877 1.0 0.765625
878 1.0 0.96875
879 1.0 0.890625
880 1.0 0.890625
881 1.0 0.84375
882 1.0 0.890625
883 1.0 0.84375
884 1.0 0.859375
885 1.0 0.84375
886 1.0 0.859375
887 1.0 0.875
888 1.0 0.921875
889 1.0 0.90625
890 1.0 0.90625
891 1.0 0.859375
892 1.0 0.859375
893 1.0 0.9375
894 1.0 0.84375
895 1.0 0.859375
896 1.0 0.90625
897 1.0 0.9375
898 1.0 0.84375
899 1.0 0.890625
900 1.0 0.828125
901 1.0 0.90625
902 1.0 0.90625
903 1.0 0.859375
904 1.0 0.875
905 1.0 0.84375
906 1.0 0.875
907 1.0 0.875
908 1.0 0.859375
909 1.0 0.875
910 1.0 0.9375
911 1.0 0.796875
912 1.0 0.90625
913 1.0 0.859375
914 1.0 0.9375
915 1.0 0.875
916 1.0 0.859375
917 1.0 0.890625
918 1.0 0.890625
919 1.0 0.875
920 1.0 0.953125
921 1.0 0.921875
922 1.0 0.921875
923 1.0 0.890625
924 1.0 0.9375
925 1.0 0.859375
926 1.0 0.90625
927 1.0 0.921875
928 1.0 0.859375
929 1.0 0.859375
930 1.0 0.875
931 1.0 0.890625
932 1.0 0.890625
933 1.0 0.859375
934 1.0 0.859375
935 1.0 0.828125
936 1.0 0.96875
937 1.0 0.875
938 1.0 0.75
939 1.0 0.9375
940 1.0 0.828125
941 1.0 0.890625
942 1.0 0.828125
943 1.0 0.859375
944 1.0 0.875
945 1.0 0.921875
946 1.0 0.890625
947 1.0 0.921875
948 1.0 0.9375
949 1.0 0.953125
950 1.0 0.875
951 1.0 0.859375
952 1.0 0.890625
953 1.0 0.84375
954 1.0 0.875
955 1.0 0.875
956 1.0 0.90625
957 1.0 0.84375
958 1.0 0.828125
959 1.0 0.75
960 1.0 0.890625
961 1.0 0.875
962 1.0 0.921875
963 1.0 0.796875
964 1.0 0.875
965 1.0 0.90625
966 1.0 0.921875
967 1.0 0.796875
968 1.0 0.875
969 1.0 0.921875
970 1.0 0.828125
971 1.0 0.9375
972 1.0 0.890625
973 1.0 0.921875
974 1.0 0.875
975 1.0 0.9375
976 1.0 0.90625
977 1.0 0.953125
978 1.0 0.859375
979 1.0 0.828125
980 1.0 0.9375
981 1.0 0.953125
982 1.0 0.90625
983 1.0 0.828125
984 1.0 0.78125
985 1.0 0.90625
986 1.0 0.921875
987 1.0 0.90625
988 1.0 0.921875
989 1.0 0.890625
990 1.0 0.90625
991 1.0 0.890625
992 1.0 0.78125
993 1.0 0.859375
994 1.0 0.765625
995 1.0 0.8125
996 1.0 0.890625
997 1.0 0.890625
998 1.0 0.875
999 1.0 0.84375

"The goal is to train a generator model, not a discriminator model, and that is where the complexity of GANs truly lies."

The Generator Model

We will define a small latent space of five dimensions and use the standard approach in the GAN literature of using a Gaussian distribution for each variable in the latent space. We will generate new inputs by drawing random numbers from a standard Gaussian distribution, i.e. mean of zero and a standard deviation of one.

  • Specs:
    • Single Hidden Layer with 5 nodes
    • ReLU activation Function
    • He weight initialization
    • Output layer will have 2 nodes+ will use linear activation function
# define the generator model unit
def define_generator(latent_dim, n_outputs=2):
	model = Sequential()
	model.add(Dense(15, activation='relu', kernel_initializer='he_uniform', input_dim=latent_dim))
	model.add(Dense(n_outputs, activation='linear'))
	return model
# define the discriminator model
model = define_generator(5)
# summarize the model
model.summary()
Model: &quot;sequential_3&quot;
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_5 (Dense)              (None, 15)                90        
_________________________________________________________________
dense_6 (Dense)              (None, 2)                 32        
=================================================================
Total params: 122
Trainable params: 122
Non-trainable params: 0
_________________________________________________________________
# generate points in latent space as input for the generator
def generate_latent_points(latent_dim, n):
	# generate points in the latent space
	x_input = np.random.randn(latent_dim * n)
	# reshape into a batch of inputs for the network
	x_input = x_input.reshape(n, latent_dim)
	return x_input
# use the generator to generate n fake examples and plot the results
def generate_fake_samples(generator, latent_dim, n):
	# generate points in latent space
	x_input = generate_latent_points(latent_dim, n)
	# predict outputs
	X = generator.predict(x_input)
    # create class labels
	y = np.zeros((n, 1))
	return X, y

When the discriminator is good at detecting fake samples, the generator is updated more, and when the discriminator model is relatively poor or confused when detecting fake samples, the generator model is updated less.

# define the combined generator and discriminator model, for updating the generator
def define_gan(generator, discriminator):
	# make weights in the discriminator not trainable
	discriminator.trainable = False
	# connect them
	model = Sequential()
	# add generator
	model.add(generator)
	# add the discriminator
	model.add(discriminator)
	# compile model
	model.compile(loss='binary_crossentropy', optimizer='adam')
	return model
# train the generator and discriminator
def train(g_model, d_model, gan_model, latent_dim, n_epochs=10000, n_batch=128, n_eval=2000):
	# determine half the size of one batch, for updating the discriminator
	half_batch = int(n_batch / 2)
	# manually enumerate epochs
	for i in range(n_epochs):
		# prepare real samples
		x_real, y_real = generate_real_samples(half_batch)
		# prepare fake examples
		x_fake, y_fake = generate_fake_samples(g_model, latent_dim, half_batch)
		# update discriminator
		d_model.train_on_batch(x_real, y_real)
		d_model.train_on_batch(x_fake, y_fake)
		# prepare points in latent space as input for the generator
		x_gan = generate_latent_points(latent_dim, n_batch)
		# create inverted labels for the fake samples
		y_gan = np.ones((n_batch, 1))
		# update the generator via the discriminator's error
		gan_model.train_on_batch(x_gan, y_gan)
		# evaluate the model every n_eval epochs
		if (i+1) % n_eval == 0:
			summarize_performance(i, g_model, d_model, latent_dim)
# evaluate the discriminator and plot real and fake points
def summarize_performance(epoch, generator, discriminator, latent_dim, n=100):
	# prepare real samples
	x_real, y_real = generate_real_samples(n)
	# evaluate discriminator on real examples
	_, acc_real = discriminator.evaluate(x_real, y_real, verbose=0)
	# prepare fake examples
	x_fake, y_fake = generate_fake_samples(generator, latent_dim, n)
	# evaluate discriminator on fake examples
	_, acc_fake = discriminator.evaluate(x_fake, y_fake, verbose=0)
	# summarize discriminator performance
	print(epoch, acc_real, acc_fake)
	# scatter plot real and fake data points
	pyplot.scatter(x_real[:, 0], x_real[:, 1], color='red')
	pyplot.scatter(x_fake[:, 0], x_fake[:, 1], color='blue')
	pyplot.show()
# size of the latent space
latent_dim = 5
# create the discriminator
discriminator = define_discriminator()
# create the generator
generator = define_generator(latent_dim)
# create the gan
gan_model = define_gan(generator, discriminator)
# train model
train(generator, discriminator, gan_model, latent_dim)
1999 0.7400000095367432 0.4399999976158142