Skip to content

Instantly share code, notes, and snippets.

@zaccharieramzi
Last active June 13, 2020 18:09
Show Gist options
  • Save zaccharieramzi/8b3cf272dc6f89ec0f45ba3bbed3b11a to your computer and use it in GitHub Desktop.
Save zaccharieramzi/8b3cf272dc6f89ec0f45ba3bbed3b11a to your computer and use it in GitHub Desktop.
MixedBatchGAN
Display the source blob
Display the rendered blob
Raw
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "MixedBatchGAN",
"provenance": [],
"collapsed_sections": [],
"authorship_tag": "ABX9TyOyqoaz64wZO5KaB/POLxnl",
"include_colab_link": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"accelerator": "GPU"
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/zaccharieramzi/8b3cf272dc6f89ec0f45ba3bbed3b11a/mixedbatchgan.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "B2cPftqYbQNF",
"colab_type": "text"
},
"source": [
"# Mixed batch and symmetric discriminators for GAN training"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "E3U62YBKbYdP",
"colab_type": "text"
},
"source": [
"This colaboratory notebook reproduces one bit of the ICML 2018 oral \"Mixed batches and symmetric discriminators for GAN training\", Lucas et al.\n",
"This is an unofficial implementation in TensorFlow.\n",
"\n",
"The basic idea is to go further in the idea that GAN learn a distribution and rather than looking at only one sample of the learned distribution (i.e. one image), the discriminator will have access to a batch of the learned distribution.\n",
"\n",
"Key tricks are:\n",
"- to mix this batch with original images, and have the discriminator learn the proportion of real images;\n",
"- to design a discriminator with batch permutation invariance embedded to prevent the network from learning this aspect."
]
},
{
"cell_type": "code",
"metadata": {
"id": "0fS31XnZKQT0",
"colab_type": "code",
"cellView": "form",
"colab": {}
},
"source": [
"#@title\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"import tensorflow as tf\n",
"from tensorflow.keras.layers import Layer, Dense, Activation\n",
"from tensorflow.keras.models import Model, Sequential\n",
"from tensorflow.keras.optimizers import Adam\n",
"from tensorflow_addons.callbacks import TQDMProgressBar"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "ebzpf6u8KrDz",
"colab_type": "text"
},
"source": [
"# DATA"
]
},
{
"cell_type": "code",
"metadata": {
"id": "-Tjy5jorKtVh",
"colab_type": "code",
"colab": {}
},
"source": [
"def square_centers(square_length):\n",
" square_side = np.arange(square_length)\n",
" square_side = square_side - (square_length-1) / 2\n",
" square_side = square_side / np.sqrt(square_length)\n",
" square_centers = np.meshgrid(square_side, square_side)\n",
" return square_centers\n",
"\n",
"def generate_sample_from_square(square_length, std):\n",
" square_side = np.arange(square_length)\n",
" square_side = square_side - (square_length-1) / 2\n",
" square_side = square_side / np.sqrt(square_length)\n",
" while True:\n",
" position = np.random.choice(square_side, size=2)\n",
" point = np.random.normal(loc=position, scale=std)\n",
" yield point"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "A2Nl2irqL4zy",
"colab_type": "code",
"colab": {}
},
"source": [
"points_ds = tf.data.Dataset.from_generator(\n",
" generate_sample_from_square,\n",
" tf.float32,\n",
" tf.TensorShape([2]),\n",
" args=(5, 0.01),\n",
").batch(128)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "eISiQtTLL6hO",
"colab_type": "code",
"colab": {}
},
"source": [
"def generate_latent_variable(var_dim, batch_size=1, std=1.):\n",
" return tf.random.normal((batch_size, var_dim), stddev=std)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "_wghRJ8UZVr3",
"colab_type": "text"
},
"source": [
"## Visualization"
]
},
{
"cell_type": "code",
"metadata": {
"id": "FV_u-SSJZlr7",
"colab_type": "code",
"colab": {}
},
"source": [
"data = next(points_ds.as_numpy_iterator())\n",
"centers = square_centers(5)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "URT6O3xKZYyJ",
"colab_type": "code",
"outputId": "1771f660-30a7-493d-a99c-a7d02443ebf4",
"cellView": "form",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 283
}
},
"source": [
"#@title\n",
"plt.figure()\n",
"plt.scatter(data[:, 0], data[:, 1])\n",
"plt.scatter(centers[0], centers[1])"
],
"execution_count": 6,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"<matplotlib.collections.PathCollection at 0x7f10c019a2e8>"
]
},
"metadata": {
"tags": []
},
"execution_count": 6
},
{
"output_type": "display_data",
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"tags": [],
"needs_background": "light"
}
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "LvH6uSsXOI16",
"colab_type": "text"
},
"source": [
"# MODELS"
]
},
{
"cell_type": "code",
"metadata": {
"id": "nE7zf4VXXS-o",
"colab_type": "code",
"colab": {}
},
"source": [
"def kl_loss(ratio_true, ratio_pred):\n",
" kl = tf.keras.losses.KLDivergence()\n",
" kl1 = kl(ratio_true, ratio_pred)\n",
" kl2 = kl(1 - ratio_true, 1 - ratio_pred)\n",
" return kl1 + kl2"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "NFH-7uM4Oy-X",
"colab_type": "code",
"colab": {}
},
"source": [
"class PermEquivLayer(Layer):\n",
" def __init__(self, units=512, activation='relu', **kwargs):\n",
" super(PermEquivLayer, self).__init__(**kwargs)\n",
" self.activation = Activation(activation)\n",
" self.parallel_dense = Dense(units)\n",
" self.batch_dense = Dense(units, use_bias=False)\n",
"\n",
" def call(self, inputs):\n",
" parallel_outputs = self.parallel_dense(inputs)\n",
" rho = tf.reduce_mean(inputs, axis=0, keepdims=True)\n",
" batch_outputs = self.batch_dense(rho)\n",
" outputs = self.activation(parallel_outputs + batch_outputs)\n",
" return outputs\n",
"\n",
"class PermEquivDiscriminator(Model):\n",
" def __init__(self, n_layers=3, units=512, activation='relu', **kwargs):\n",
" super(PermEquivDiscriminator, self).__init__(**kwargs)\n",
" self.perm_equiv_layers = [\n",
" PermEquivLayer(units=units, activation=activation)\n",
" for _ in range(n_layers)\n",
" ]\n",
" self.perm_equiv_layers.append(PermEquivLayer(units=1, activation='sigmoid'))\n",
"\n",
" def call(self, inputs):\n",
" outputs = inputs\n",
" for perm_equiv_layer in self.perm_equiv_layers:\n",
" outputs = perm_equiv_layer(outputs)\n",
" outputs = tf.reduce_mean(outputs, axis=0)\n",
" return outputs\n",
"\n",
"\n",
"class BGAN(Model):\n",
" # inspired by https://keras.io/examples/generative/dcgan_overriding_train_step/\n",
" def __init__(self, gamma=0.3, units = 512, **kwargs):\n",
" super(BGAN, self).__init__(**kwargs)\n",
" self.discriminator = PermEquivDiscriminator()\n",
" self.generator = Sequential([Dense(units, activation='relu') for _ in range(3)])\n",
" self.generator.add(Dense(2))\n",
" self.gamma = gamma\n",
" self.i_iter = tf.Variable(0)\n",
" self.gen_train_prop = 5\n",
" self.fix_disc = False\n",
"\n",
" def call(self, inputs):\n",
" return self.generator(inputs)\n",
"\n",
" def compile(self, d_optimizer, g_optimizer):\n",
" super(BGAN, self).compile()\n",
" self.d_optimizer = d_optimizer\n",
" self.g_optimizer = g_optimizer\n",
"\n",
" def train_step(self, data):\n",
" # data is the real samples\n",
" batch_size = tf.shape(data)[0]\n",
" random_latent_vectors = generate_latent_variable(2, batch_size) \n",
" # draw p and beta\n",
" p_inf = tf.random.uniform((1,), maxval=self.gamma)\n",
" p_sup = tf.random.uniform((1,), minval=1 - self.gamma, maxval=1.)\n",
" which_p = tf.greater(tf.random.uniform((1,), minval=0, maxval=1.), 0.5)\n",
" p = tf.cond(which_p, lambda: p_sup, lambda: p_inf)\n",
" beta = tf.cast(tf.greater(tf.random.uniform([batch_size], minval=0, maxval=1.), p), tf.float32)\n",
" # ratio is the number of true samples over the number of samples\n",
" ratio_true = tf.reduce_sum(beta) / tf.cast(batch_size, tf.float32)\n",
" with tf.GradientTape(persistent=True) as tape:\n",
" # Decode to fake samples\n",
" generated_samples = self.generator(random_latent_vectors)\n",
" # Combine with real samples\n",
" combined_samples = beta[:, None] * data + (1-beta[:, None]) * generated_samples\n",
" ratio_pred = self.discriminator(combined_samples)\n",
" tf.debugging.check_numerics(ratio_pred, 'ratio_pred')\n",
" d_loss = kl_loss(ratio_true[None], ratio_pred)\n",
" # if ratio_pred is higher, then the discriminator thinks\n",
" # that there is a higher proportion of true samples\n",
" # Therefore the generator must maximize an increasing function of ratio_pred\n",
" # and minimize a deacreasing function of ratio_pred\n",
" g_loss = - tf.math.log(ratio_pred)\n",
" tf.debugging.check_numerics(d_loss, 'd_loss')\n",
" tf.debugging.check_numerics(g_loss, 'g_loss')\n",
" if not self.fix_disc:\n",
" grads = tape.gradient(d_loss, self.discriminator.trainable_weights)\n",
" self.d_optimizer.apply_gradients(\n",
" zip(grads, self.discriminator.trainable_weights)\n",
" )\n",
" # we train the generator only one fifth of the time\n",
" if self.i_iter % self.gen_train_prop == 0 or self.fix_disc: \n",
" grads = tape.gradient(g_loss, self.generator.trainable_weights)\n",
" self.g_optimizer.apply_gradients(zip(grads, self.generator.trainable_weights))\n",
" self.i_iter.assign_add(1)\n",
" return {\"d_loss\": d_loss, \"g_loss\": g_loss}\n"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "K1ROWNwZV7_t",
"colab_type": "text"
},
"source": [
"# TRAINING"
]
},
{
"cell_type": "code",
"metadata": {
"id": "cH6YbAiMaMVN",
"colab_type": "code",
"colab": {}
},
"source": [
"model = BGAN()\n",
"model.compile(Adam(1e-3), Adam(1e-3))"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "9VkwWESvaZP9",
"colab_type": "code",
"colab": {}
},
"source": [
"history = model.fit(points_ds, epochs=10000, steps_per_epoch=5, verbose=0)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "dwf1NrubcWGR",
"colab_type": "code",
"cellView": "form",
"outputId": "b5eede6b-7a6b-4f7f-cc82-63936d330193",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 281
}
},
"source": [
"#@title\n",
"fig, axs = plt.subplots(1, 2)\n",
"axs[0].plot(history.history['d_loss'], label='d')\n",
"axs[0].set_title('Discriminator loss')\n",
"axs[1].plot(history.history['g_loss'], label='g')\n",
"axs[1].set_title('Generator loss');"
],
"execution_count": 11,
"outputs": [
{
"output_type": "display_data",
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 2 Axes>"
]
},
"metadata": {
"tags": [],
"needs_background": "light"
}
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "MWhUMOPsiskX",
"colab_type": "text"
},
"source": [
"# EVALUATE"
]
},
{
"cell_type": "code",
"metadata": {
"id": "kwgyusrliuo0",
"colab_type": "code",
"colab": {}
},
"source": [
"random_latent_vectors = generate_latent_variable(2, 1024)\n",
"generated_samples = model(random_latent_vectors)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "Ysfrr6-Swjro",
"colab_type": "code",
"outputId": "8b57b2f1-29ce-4370-c4bc-a30f9fc3d850",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 35
}
},
"source": [
"generated_samples.shape"
],
"execution_count": 13,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"TensorShape([1024, 2])"
]
},
"metadata": {
"tags": []
},
"execution_count": 13
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "4R8nANK6wf2F",
"colab_type": "code",
"cellView": "form",
"outputId": "dfb18dd2-ae66-4817-bb18-0621f8bcf107",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 299
}
},
"source": [
"#@title\n",
"plt.figure()\n",
"plt.scatter(generated_samples[:, 0], generated_samples[:, 1])\n",
"plt.scatter(centers[0], centers[1])\n",
"plt.title('Generated samples')"
],
"execution_count": 14,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"Text(0.5, 1.0, 'Generated samples')"
]
},
"metadata": {
"tags": []
},
"execution_count": 14
},
{
"output_type": "display_data",
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"tags": [],
"needs_background": "light"
}
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "eU8Lbw8iS2zu",
"colab_type": "code",
"colab": {}
},
"source": [
""
],
"execution_count": 0,
"outputs": []
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment