{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Update\n\n- Decoder Reconstruction Monet (Like) \n- Train VAE Around 1K Epochs","execution_count":null},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport os\n\nimport numpy as np\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras import layers\nfrom tensorflow.keras.utils import plot_model\n\nfrom tqdm import tqdm\nfrom numpy import asarray\nfrom tensorflow.keras.preprocessing.image import load_img\nfrom tensorflow.keras.preprocessing.image import img_to_array","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Create Sampling Layer","execution_count":null},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"class Sampling(layers.Layer):\n    \"\"\"Uses (z_mean, z_log_var) to sample z, the vector encoding a digit.\"\"\"\n    def call(self, inputs):\n        z_mean, z_log_var = inputs\n        batch = tf.shape(z_mean)[0]\n        dim = tf.shape(z_mean)[1]\n        epsilon = tf.keras.backend.random_normal(shape=(batch, dim))\n        return z_mean + tf.exp(0.5 * z_log_var) * epsilon","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Utiliy Convolutional Block","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# dense block\ndef dense_block(x, f, k, s, d=5):\n    l = x\n    for i in range(d):\n        x = layers.Conv2D(f, kernel_size=k, strides=s, padding='SAME')(l)\n        l = layers.Concatenate()([l, x])\n    return l\n\n# resnetxt block\ndef resnext_block(x, f=32, r=2, c=4):\n    l = []\n    for i in range(c):\n        m = layers.Conv2D(f//(c*r), k=1)(x)\n        m = layers.Conv2D(f//(c*r), k=3)(m)\n        m = layers.Conv2D(f, k=1)(m)\n        l.append(m)\n    m = layer.add(l) \n    return layer.add([x, m])\n\n# residual block\ndef residual_block(x, f=32, r=4):\n    m = layers.Conv2D(x, f//r, k=1)\n    m = layers.Conv2D(m, f//r, k=3)\n    m = layers.Conv2D(m, f, k=1)\n    return layer.add([x, m])\n\n# inception block\ndef inception_module(x, f=32, r=4):\n    a = layers.Conv2D(x, f, k=1)\n    b = layers.Conv2D(x, f//3, k=1)\n    b = layers.Conv2D(b, f, k=3)\n    c = layers.Conv2D(x, f//r, k=1)\n    c = layers.Conv2D(c, f, k=5)\n    d = layer.MaxPooling2D(x, k=3, s=1)\n    d = layers.Conv2D(d, f, k=1)\n    return layers.concatenate([a, b, c, d])\n\n# se block\ndef se_block(x, f, rate=16):\n    m = layers.GlobalAveragePooling2D()(x)\n    m = layers.Dense(m, f // rate)\n    m = layers.Dense(m, f, a='sigmoid')\n    return layer.multiply([x, m])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_latent(decoder):\n    # display a n*n 2D manifold of digits\n    n = 5\n    sample_size = 256\n    scale = 2.0\n    figsize = 15\n    figure = np.zeros((sample_size * n, sample_size * n, 3))\n    # linearly spaced coordinates corresponding to the 2D plot\n    # of digit classes in the latent space\n    grid_x = np.linspace(-scale, scale, n)\n    grid_y = np.linspace(-scale, scale, n)[::-1]\n\n    for i, yi in enumerate(grid_y):\n        for j, xi in enumerate(grid_x):\n            z_sample = np.array([[xi, yi]])\n            x_decoded = decoder.predict(z_sample)\n            sample = x_decoded[0].reshape(sample_size, sample_size, 3)\n            figure[\n                i * sample_size : (i + 1) * sample_size,\n                j * sample_size : (j + 1) * sample_size,\n            ] = sample\n\n    plt.figure(figsize=(figsize, figsize))\n    start_range = sample_size // 2\n    end_range = n * sample_size + start_range + 1\n    pixel_range = np.arange(start_range, end_range, sample_size)\n    sample_range_x = np.round(grid_x, 1)\n    sample_range_y = np.round(grid_y, 1)\n    plt.xticks(pixel_range, sample_range_x)\n    plt.yticks(pixel_range, sample_range_y)\n    plt.xlabel(\"z[0]\")\n    plt.ylabel(\"z[1]\")\n    plt.imshow(figure, cmap=\"Greys_r\")\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Encoder","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"latent_dim = 2\ntotal_epoch = 10000\nbatch_size = 512\nimg_dim = (256, 256)\n\nencoder_inputs = keras.Input(shape=(*img_dim, 3))\n\nx = layers.Conv2D(16, kernel_size=(3,3), strides=(2,2), padding='SAME')(encoder_inputs)\nx = layers.BatchNormalization()(x)\nx = layers.LeakyReLU(0.2)(x)\n\nx = layers.Conv2D(32, kernel_size=(5,5), strides=(2,2), padding='SAME')(x)\nx = layers.BatchNormalization()(x)\nx = layers.LeakyReLU(0.2)(x)\n\nx = layers.Conv2D(64, kernel_size=(7,7), strides=(2,2), padding='SAME')(x)\nx = layers.BatchNormalization()(x)\nx = layers.LeakyReLU(0.2)(x)\n\nx = layers.Conv2D(128, kernel_size=(9,9), strides=(2,2), padding='SAME')(x)\nx = layers.BatchNormalization()(x)\nx = layers.LeakyReLU(0.2)(x)\n\nx = layers.Conv2D(256, kernel_size=(11,11), strides=(2,2), padding='SAME')(x)\nx = layers.BatchNormalization()(x)\nx = layers.LeakyReLU(0.2)(x)\n\nx = layers.GlobalAveragePooling2D()(x)\nx = layers.Dense(256, activation=\"relu\")(x)\n\nz_mean    = layers.Dense(latent_dim, name=\"z_mean\")(x)\nz_log_var = layers.Dense(latent_dim, name=\"z_log_var\")(x)\nz         = Sampling()([z_mean, z_log_var])\n\nencoder = keras.Model(encoder_inputs, \n                      [z_mean, z_log_var, z], name=\"encoder\")\n\nencoder.summary()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Encoder Plot","execution_count":null},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"plot_model(encoder, to_file='model_plot.png', show_shapes=True, show_layer_names=True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Decoder","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"latent_inputs = keras.Input(shape=(latent_dim,))\nx = layers.Dense(8 * 8 * 256, activation=\"relu\")(latent_inputs)\nx = layers.Reshape((8, 8, 256))(x)\n\nx = layers.Conv2DTranspose(256, kernel_size=(11,11), strides=(2,2), padding='SAME')(x)\nx = layers.BatchNormalization()(x)\nx = layers.LeakyReLU(0.2)(x)\n\nx = layers.Conv2DTranspose(128, kernel_size=(9,9), strides=(2,2), padding='SAME')(x)\nx = layers.BatchNormalization()(x)\nx = layers.LeakyReLU(0.2)(x)\n\nx = layers.Conv2DTranspose(64, kernel_size=(7,7), strides=(2,2), padding='SAME')(x)\nx = layers.BatchNormalization()(x)\nx = layers.LeakyReLU(0.2)(x)\n\nx = layers.Conv2DTranspose(32, kernel_size=(5,5), strides=(2,2), padding='SAME')(x)\nx = layers.BatchNormalization()(x)\nx = layers.LeakyReLU(0.2)(x)\n\nx = layers.Conv2DTranspose(16, kernel_size=(3,3), strides=(2,2), padding='SAME')(x)\nx = layers.BatchNormalization()(x)\nx = layers.LeakyReLU(0.2)(x)\n\ndecoder_outputs = layers.Conv2DTranspose(3, 3, activation=\"sigmoid\", padding=\"same\")(x)\ndecoder = keras.Model(latent_inputs, decoder_outputs, name=\"decoder\")\ndecoder.summary()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Decoder Plots","execution_count":null},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"plot_model(decoder, to_file='model_plot.png', show_shapes=True, show_layer_names=True)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Modeling","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"class VAE(keras.Model):\n    def __init__(self, encoder, decoder, **kwargs):\n        super(VAE, self).__init__(**kwargs)\n        self.encoder = encoder\n        self.decoder = decoder\n\n    def train_step(self, data):\n        if isinstance(data, tuple):\n            data = data[0]\n        with tf.GradientTape() as tape:\n            z_mean, z_log_var, z = encoder(data)\n            reconstruction = decoder(z)\n            reconstruction_loss = tf.reduce_mean(\n                keras.losses.binary_crossentropy(data, reconstruction)\n            )\n            reconstruction_loss *= 256 * 256\n            kl_loss = 1 + z_log_var - tf.square(z_mean) - tf.exp(z_log_var)\n            kl_loss = tf.reduce_mean(kl_loss)\n            kl_loss *= -0.5\n            total_loss = reconstruction_loss + kl_loss\n        grads = tape.gradient(total_loss, self.trainable_weights)\n        self.optimizer.apply_gradients(zip(grads, self.trainable_weights))\n        return {\n            \"loss\": total_loss,\n            \"reconstruction_loss\": reconstruction_loss,\n            \"kl_loss\": kl_loss,\n        }","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Training Data","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"trn_images = os.listdir('../input/gan-getting-started/monet_jpg')\ntrn_sizes = []\n\nfor i, img_path in enumerate(tqdm(trn_images)):\n    img = load_img(os.path.join('../input/gan-getting-started/monet_jpg',\n                                f'{img_path}'), target_size=(256, 256))\n    img_ary = img_to_array(img)\n    trn_sizes.append(img_ary.astype(\"float32\")/255.0)\n    \ntrn_sizes = asarray(trn_sizes)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# GAN Monitoring","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# Monitoring GAN \nclass GANMonitor(tf.keras.callbacks.Callback):\n    \"\"\"A callback to generate and save images after each epoch\"\"\"\n\n    def __init__(self, num_img=4):\n        self.num_img = num_img\n\n    def on_epoch_end(self, epoch, logs=None):\n        _, ax = plt.subplots(4, 2, figsize=(12, 12))\n        for i, img in enumerate(test_horses.take(4)):\n            prediction = self.model.gen_G(img)[0].numpy()\n            prediction = (prediction * 127.5 + 127.5).astype(np.uint8)\n            img = (img[0] * 127.5 + 127.5).numpy().astype(np.uint8)\n\n            ax[i, 0].imshow(img)\n            ax[i, 1].imshow(prediction)\n            ax[i, 0].set_title(\"Input image\")\n            ax[i, 1].set_title(\"Translated image\")\n            ax[i, 0].axis(\"off\")\n            ax[i, 1].axis(\"off\")\n\n            prediction = keras.preprocessing.image.array_to_img(prediction)\n            prediction.save(\n                \"generated_img_{i}_{epoch}.png\".format(i=i, epoch=epoch + 1)\n            )\n        plt.show()\n        plt.close()\n        \n        \n# Visualize Recontrucnted Samples Via Decoder (VAE)\n# At Specific Epoch Interval (i.e. 200)\nclass TrainingPlot(tf.keras.callbacks.Callback):\n    def on_train_begin(self, logs={}):    \n        # Initialization code    \n        self.epochs = 0    \n    def on_epoch_end(self, batch, logs={}):    \n        self.epochs += 1     \n        if self.epochs % 200 == 0:\n            print('[Reconstructed] Viz Results of Decoder @ Epoch : ', self.epochs)\n            plot_latent(decoder)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Training","execution_count":null},{"metadata":{"trusted":true,"_kg_hide-output":false},"cell_type":"code","source":"plotter = GANMonitor()\nplots   = TrainingPlot()\nvae     = VAE(encoder, decoder)\n\n# optimizer\nvae.compile(optimizer=keras.optimizers.Adam(),run_eagerly=False)\n\nvae.fit(trn_sizes, \n        epochs=total_epoch, \n        batch_size=batch_size,\n        callbacks = plots, verbose=0)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Plot: Reconstruction Decoder","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"plot_latent(decoder)","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}