diff --git a/Scripts/Code/gif_maker.py b/Scripts/Code/gif_maker.py new file mode 100644 index 0000000000000000000000000000000000000000..1428039b3d37b7acbb6cdc845ae37b03c365687c --- /dev/null +++ b/Scripts/Code/gif_maker.py @@ -0,0 +1,11 @@ +import imageio + +images_in = [] +images_out = [] + +for number = 10 to 109: + images_in.append(imageio.imread("in_" + str(number) + ".png")) + images_out.append(imageio.imread("out_" + str(number) + ".png")) + +imageio.mimsave("./in.gif", images_in) +imageio.mimsave("./out.gif", images_out) \ No newline at end of file diff --git a/Scripts/Notebooks/Autoencoder.ipynb b/Scripts/Notebooks/Autoencoder.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..67400a3bedb0802e081c3c06c0b158abc30b6f13 --- /dev/null +++ b/Scripts/Notebooks/Autoencoder.ipynb @@ -0,0 +1,965 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Autoencoder" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Importamos las bibliotecas necesarias" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import time\n", + "import os\n", + "import shutil\n", + "import sys\n", + "import math\n", + "import random\n", + "import tensorflow as tf\n", + "import numpy as np\n", + "import scipy.misc\n", + "from PIL import Image\n", + "import matplotlib.pyplot as plt\n", + "sys.path.append(\"../tools\") # Herramientas propias de MantaFlow\n", + "import uniio # Biblioteca para la lectura de ficheros .uni" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Inicializamos las seed para funciones random. Al ser inicializadas al mismo número, el resultado no cambiará en cada ejecución." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "np.random.seed(13)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Ruta a los datos de simulación, donde también se guardan los resultados." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "base_path = \"../data\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Carga de datos de simulación" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Cargamos los datos desde los ficheros .uni en arrays de numpy." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "densities = []" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "for sim in range(1000, 2000):\n", + " if os.path.exists(\"%s/simSimple_%04d\" % (base_path, sim)): # Comprueba la existencia de las carpetas (cada una 100 frames de datos)\n", + " for i in range(0, 100):\n", + " filename = \"%s/simSimple_%04d/density_%04d.uni\" # Nombre de cada frame (densidad)\n", + " uni_path = filename % (base_path, sim, i) # 100 frames por sim, rellena parametros de la ruta\n", + " header, content = uniio.readUni(uni_path) # Devuelve una array np [Z, Y, X, C]\n", + " h = header[\"dimX\"]\n", + " w = header[\"dimY\"]\n", + " arr = content[:, ::-1, :, :] # Cambia el orden de Y\n", + " arr = np.reshape(arr, [w, h, 1]) # Deshecha Z\n", + " densities.append(arr)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Necesitamos al menos 2 simulaciones para trabajar de manera adecuada." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "load_num = len(densities)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "if load_num <200:\n", + " print(\"Error - usa al menos dos simulaciones completas\")\n", + " exit(1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Convertimos la lista \"densities\" en una array de Numpy." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(15000, 64, 64, 1)" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "densities = np.reshape(densities, (len(densities), 64, 64, 1))\n", + "densities.shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Creación de set de validación" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Creamos el set de validación de entre los datos de simulación generados, al menos una simulación completa o el 10% de los datos (el que sea mayor de los dos)." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Read uni files, total data (15000, 64, 64, 1)\n", + "Split into 13500 training and 1500 validation samples\n" + ] + } + ], + "source": [ + "print(\"Read uni files, total data \" + format(densities.shape))\n", + "\n", + "vali_size = max(100, int(load_num * 0.1)) # Al menos una simu completa\n", + "vali_data = densities[load_num - vali_size : load_num, :]\n", + "densities = densities[0 : load_num - vali_size, :]\n", + "\n", + "print(\"Split into %d training and %d validation samples\" % (densities.shape[0], vali_data.shape[0]))\n", + "\n", + "load_num = densities.shape[0]" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(13500, 64, 64, 1)\n", + "(1500, 64, 64, 1)\n" + ] + } + ], + "source": [ + "densities = np.reshape(densities, (len(densities), 64, 64, 1))\n", + "vali_data = np.reshape(vali_data, (len(vali_data), 64, 64, 1))\n", + "\n", + "print(densities.shape)\n", + "print(vali_data.shape)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Creación del modelo Autoencoder mediante Keras (Sequential)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Importamos las bibliotecas de Keras" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Using TensorFlow backend.\n" + ] + } + ], + "source": [ + "from keras.models import Sequential, Model\n", + "from keras.layers import Input, Conv2D, Conv2DTranspose, BatchNormalization, MaxPooling2D, UpSampling2D, Activation, Dropout\n", + "from keras.optimizers import Adam\n", + "from keras.layers.advanced_activations import LeakyReLU" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "training_epochs = 20\n", + "dropout = 0.25\n", + "batch_size = 96\n", + "feature_multiplier = 32\n", + "init_func = \"glorot_normal\"\n", + "surface_kernel_size = 4\n", + "kernel_size = 2\n", + "adam_learning_rate = 0.001\n", + "adam_epsilon = 1e-8\n", + "adam_lr_decay = 0.0005" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Creacion de las capas del modelo" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "En la primera capa debemos definir las dimensiones del input esperado." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "input_shape = (densities.shape[1], densities.shape[2], densities.shape[3])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Capas del Encoder" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/jon/PycharmProjects/TensorFlow/venv/lib/python3.6/site-packages/keras/activations.py:235: UserWarning: Do not pass a layer instance (such as LeakyReLU) as the activation argument of another layer. Instead, advanced activation layers should be used just like any other layer in a model.\n", + " identifier=identifier.__class__.__name__))\n" + ] + } + ], + "source": [ + "encoder_input_img = Input(shape = (densities.shape[1], \n", + " densities.shape[2], \n", + " densities.shape[3]))\n", + "\n", + "l0 = Conv2D(filters = feature_multiplier * 1, \n", + " kernel_size = surface_kernel_size,\n", + " strides = 2,\n", + " padding = \"same\",\n", + " kernel_initializer = init_func)(encoder_input_img)\n", + "\n", + "l0_act = Activation(\"linear\")(l0)\n", + "\n", + "l0_drop = Dropout(dropout)(l0_act)\n", + "\n", + "l1 = Conv2D(filters = feature_multiplier * 2, \n", + " kernel_size = kernel_size,\n", + " strides = 2,\n", + " kernel_initializer = init_func,\n", + " padding = \"same\")(l0_drop)\n", + "\n", + "l1_batch = BatchNormalization()(l1)\n", + "\n", + "l1_act = Activation(LeakyReLU(alpha = 0.2))(l1_batch)\n", + "\n", + "l1_drop = Dropout(dropout)(l1_act)\n", + "\n", + "l2 = Conv2D(filters = feature_multiplier * 4, \n", + " kernel_size = kernel_size,\n", + " strides = 2,\n", + " kernel_initializer = init_func, \n", + " padding = \"same\")(l1_drop)\n", + "\n", + "l2_batch = BatchNormalization()(l2)\n", + "\n", + "l2_act = Activation(LeakyReLU(alpha = 0.2))(l2_batch)\n", + "\n", + "l2_drop = Dropout(dropout)(l2_act)\n", + "\n", + "l3 = Conv2D(filters = feature_multiplier * 8, \n", + " kernel_size = kernel_size,\n", + " strides = 2,\n", + " kernel_initializer = init_func, \n", + " padding = \"same\")(l2_drop)\n", + "\n", + "l3_batch = BatchNormalization()(l3)\n", + "\n", + "l3_act = Activation(LeakyReLU(alpha = 0.2))(l3_batch)\n", + "\n", + "l3_drop = Dropout(dropout)(l3_act)\n", + "\n", + "l4 = Conv2D(filters = feature_multiplier * 16, \n", + " kernel_size = kernel_size,\n", + " strides = 2,\n", + " kernel_initializer = init_func, \n", + " padding = \"same\")(l3_drop)\n", + "\n", + "l4_batch = BatchNormalization()(l4)\n", + "\n", + "l4_act = Activation(LeakyReLU(alpha = 0.2))(l4_batch)\n", + "\n", + "l4_drop = Dropout(dropout)(l4_act)\n", + "\n", + "l5 = Conv2D(filters = feature_multiplier * 32, \n", + " kernel_size = kernel_size,\n", + " strides = 2,\n", + " kernel_initializer = init_func, \n", + " padding = \"same\")(l4_drop)\n", + "\n", + "l5_batch = BatchNormalization()(l5)\n", + "\n", + "encoder_output = Activation(LeakyReLU(alpha = 0.2))(l5_batch)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Capas del Decoder" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "l6 = Conv2DTranspose(filters = feature_multiplier * 16, \n", + " kernel_size = kernel_size,\n", + " strides = 2,\n", + " kernel_initializer = init_func,\n", + " padding = \"same\")(encoder_output)\n", + "\n", + "l6_batch = BatchNormalization()(l6)\n", + "\n", + "l6_act = Activation(LeakyReLU(alpha = 0.2))(l6_batch)\n", + "\n", + "l7 = Conv2DTranspose(filters = feature_multiplier * 8, \n", + " kernel_size = kernel_size,\n", + " strides = 2,\n", + " kernel_initializer = init_func, \n", + " padding = \"same\")(l6_act)\n", + "\n", + "l7_batch = BatchNormalization()(l7)\n", + "\n", + "l7_act = Activation(LeakyReLU(alpha = 0.2))(l7_batch)\n", + "\n", + "l7_drop = Dropout(dropout)(l7_act)\n", + "\n", + "l8 = Conv2DTranspose(filters = feature_multiplier * 4, \n", + " kernel_size = kernel_size,\n", + " strides = 2,\n", + " kernel_initializer = init_func,\n", + " padding = \"same\")(l7_drop)\n", + "\n", + "l8_batch = BatchNormalization()(l8)\n", + "\n", + "l8_act = Activation(LeakyReLU(alpha = 0.2))(l8_batch)\n", + "\n", + "l8_drop = Dropout(dropout)(l8_act)\n", + "\n", + "l9 = Conv2DTranspose(filters = feature_multiplier * 2, \n", + " kernel_size = kernel_size,\n", + " strides = 2,\n", + " kernel_initializer = init_func,\n", + " padding = \"same\")(l8_drop)\n", + "\n", + "l9_batch = BatchNormalization()(l9)\n", + "\n", + "l9_act = Activation(LeakyReLU(alpha = 0.2))(l9_batch)\n", + "\n", + "l9_drop = Dropout(dropout)(l9_act)\n", + "\n", + "l10 = Conv2DTranspose(filters = feature_multiplier * 1, \n", + " kernel_size = kernel_size,\n", + " strides = 2,\n", + " kernel_initializer = init_func,\n", + " padding = \"same\")(l9_drop)\n", + "\n", + "l10_batch = BatchNormalization()(l10)\n", + "\n", + "l10_act = Activation(LeakyReLU(alpha = 0.2))(l10_batch)\n", + "\n", + "l11 = Conv2DTranspose(filters = input_shape[-1], \n", + " kernel_size = surface_kernel_size,\n", + " strides = 2,\n", + " kernel_initializer = init_func,\n", + " padding = \"same\")(l10_act)\n", + "\n", + "decoder_output = Activation(\"linear\")(l11)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Ensamblando el Autoencoder" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "autoencoder = Model(encoder_input_img, decoder_output)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Es recomendable visualizar el resumen del modelo." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Model: \"model_1\"\n", + "_________________________________________________________________\n", + "Layer (type) Output Shape Param # \n", + "=================================================================\n", + "input_1 (InputLayer) (None, 64, 64, 1) 0 \n", + "_________________________________________________________________\n", + "conv2d_1 (Conv2D) (None, 32, 32, 32) 544 \n", + "_________________________________________________________________\n", + "activation_1 (Activation) (None, 32, 32, 32) 0 \n", + "_________________________________________________________________\n", + "dropout_1 (Dropout) (None, 32, 32, 32) 0 \n", + "_________________________________________________________________\n", + "conv2d_2 (Conv2D) (None, 16, 16, 64) 8256 \n", + "_________________________________________________________________\n", + "batch_normalization_1 (Batch (None, 16, 16, 64) 256 \n", + "_________________________________________________________________\n", + "activation_2 (Activation) (None, 16, 16, 64) 0 \n", + "_________________________________________________________________\n", + "dropout_2 (Dropout) (None, 16, 16, 64) 0 \n", + "_________________________________________________________________\n", + "conv2d_3 (Conv2D) (None, 8, 8, 128) 32896 \n", + "_________________________________________________________________\n", + "batch_normalization_2 (Batch (None, 8, 8, 128) 512 \n", + "_________________________________________________________________\n", + "activation_3 (Activation) (None, 8, 8, 128) 0 \n", + "_________________________________________________________________\n", + "dropout_3 (Dropout) (None, 8, 8, 128) 0 \n", + "_________________________________________________________________\n", + "conv2d_4 (Conv2D) (None, 4, 4, 256) 131328 \n", + "_________________________________________________________________\n", + "batch_normalization_3 (Batch (None, 4, 4, 256) 1024 \n", + "_________________________________________________________________\n", + "activation_4 (Activation) (None, 4, 4, 256) 0 \n", + "_________________________________________________________________\n", + "dropout_4 (Dropout) (None, 4, 4, 256) 0 \n", + "_________________________________________________________________\n", + "conv2d_5 (Conv2D) (None, 2, 2, 512) 524800 \n", + "_________________________________________________________________\n", + "batch_normalization_4 (Batch (None, 2, 2, 512) 2048 \n", + "_________________________________________________________________\n", + "activation_5 (Activation) (None, 2, 2, 512) 0 \n", + "_________________________________________________________________\n", + "dropout_5 (Dropout) (None, 2, 2, 512) 0 \n", + "_________________________________________________________________\n", + "conv2d_6 (Conv2D) (None, 1, 1, 1024) 2098176 \n", + "_________________________________________________________________\n", + "batch_normalization_5 (Batch (None, 1, 1, 1024) 4096 \n", + "_________________________________________________________________\n", + "activation_6 (Activation) (None, 1, 1, 1024) 0 \n", + "_________________________________________________________________\n", + "conv2d_transpose_1 (Conv2DTr (None, 2, 2, 512) 2097664 \n", + "_________________________________________________________________\n", + "batch_normalization_6 (Batch (None, 2, 2, 512) 2048 \n", + "_________________________________________________________________\n", + "activation_7 (Activation) (None, 2, 2, 512) 0 \n", + "_________________________________________________________________\n", + "conv2d_transpose_2 (Conv2DTr (None, 4, 4, 256) 524544 \n", + "_________________________________________________________________\n", + "batch_normalization_7 (Batch (None, 4, 4, 256) 1024 \n", + "_________________________________________________________________\n", + "activation_8 (Activation) (None, 4, 4, 256) 0 \n", + "_________________________________________________________________\n", + "dropout_6 (Dropout) (None, 4, 4, 256) 0 \n", + "_________________________________________________________________\n", + "conv2d_transpose_3 (Conv2DTr (None, 8, 8, 128) 131200 \n", + "_________________________________________________________________\n", + "batch_normalization_8 (Batch (None, 8, 8, 128) 512 \n", + "_________________________________________________________________\n", + "activation_9 (Activation) (None, 8, 8, 128) 0 \n", + "_________________________________________________________________\n", + "dropout_7 (Dropout) (None, 8, 8, 128) 0 \n", + "_________________________________________________________________\n", + "conv2d_transpose_4 (Conv2DTr (None, 16, 16, 64) 32832 \n", + "_________________________________________________________________\n", + "batch_normalization_9 (Batch (None, 16, 16, 64) 256 \n", + "_________________________________________________________________\n", + "activation_10 (Activation) (None, 16, 16, 64) 0 \n", + "_________________________________________________________________\n", + "dropout_8 (Dropout) (None, 16, 16, 64) 0 \n", + "_________________________________________________________________\n", + "conv2d_transpose_5 (Conv2DTr (None, 32, 32, 32) 8224 \n", + "_________________________________________________________________\n", + "batch_normalization_10 (Batc (None, 32, 32, 32) 128 \n", + "_________________________________________________________________\n", + "activation_11 (Activation) (None, 32, 32, 32) 0 \n", + "_________________________________________________________________\n", + "conv2d_transpose_6 (Conv2DTr (None, 64, 64, 1) 513 \n", + "_________________________________________________________________\n", + "activation_12 (Activation) (None, 64, 64, 1) 0 \n", + "=================================================================\n", + "Total params: 5,602,881\n", + "Trainable params: 5,596,929\n", + "Non-trainable params: 5,952\n", + "_________________________________________________________________\n" + ] + } + ], + "source": [ + "autoencoder.summary()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Definimos el optimizador." + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "optimizer = Adam(lr = adam_learning_rate, \n", + " epsilon = adam_epsilon, \n", + " decay = adam_lr_decay)" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "autoencoder.compile(optimizer = optimizer, loss = \"mse\", metrics = [\"mae\"])" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Train on 13500 samples, validate on 1500 samples\n", + "Epoch 1/20\n", + "13500/13500 [==============================] - 175s 13ms/step - loss: 0.0190 - mae: 0.0658 - val_loss: 0.0048 - val_mae: 0.0342\n", + "Epoch 2/20\n", + "13500/13500 [==============================] - 173s 13ms/step - loss: 0.0051 - mae: 0.0339 - val_loss: 0.0047 - val_mae: 0.0230\n", + "Epoch 3/20\n", + "13500/13500 [==============================] - 192s 14ms/step - loss: 0.0037 - mae: 0.0273 - val_loss: 0.0037 - val_mae: 0.0187\n", + "Epoch 4/20\n", + "13500/13500 [==============================] - 191s 14ms/step - loss: 0.0032 - mae: 0.0245 - val_loss: 0.0028 - val_mae: 0.0167\n", + "Epoch 5/20\n", + "13500/13500 [==============================] - 170s 13ms/step - loss: 0.0028 - mae: 0.0225 - val_loss: 0.0021 - val_mae: 0.0156\n", + "Epoch 6/20\n", + "13500/13500 [==============================] - 186s 14ms/step - loss: 0.0025 - mae: 0.0211 - val_loss: 0.0018 - val_mae: 0.0151\n", + "Epoch 7/20\n", + "13500/13500 [==============================] - 170s 13ms/step - loss: 0.0023 - mae: 0.0199 - val_loss: 0.0016 - val_mae: 0.0142\n", + "Epoch 8/20\n", + "13500/13500 [==============================] - 186s 14ms/step - loss: 0.0021 - mae: 0.0191 - val_loss: 0.0016 - val_mae: 0.0143\n", + "Epoch 9/20\n", + "13500/13500 [==============================] - 179s 13ms/step - loss: 0.0020 - mae: 0.0184 - val_loss: 0.0015 - val_mae: 0.0141\n", + "Epoch 10/20\n", + "13500/13500 [==============================] - 187s 14ms/step - loss: 0.0019 - mae: 0.0178 - val_loss: 0.0014 - val_mae: 0.0136\n", + "Epoch 11/20\n", + "13500/13500 [==============================] - 180s 13ms/step - loss: 0.0018 - mae: 0.0173 - val_loss: 0.0013 - val_mae: 0.0136\n", + "Epoch 12/20\n", + "13500/13500 [==============================] - 179s 13ms/step - loss: 0.0017 - mae: 0.0169 - val_loss: 0.0013 - val_mae: 0.0130\n", + "Epoch 13/20\n", + " 1536/13500 [==>...........................] - ETA: 2:24 - loss: 0.0017 - mae: 0.0166" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m<ipython-input-20-e8548ea97e69>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mverbose\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mvalidation_data\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mvali_data\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvali_data\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m shuffle = True)\n\u001b[0m", + "\u001b[0;32m~/PycharmProjects/TensorFlow/venv/lib/python3.6/site-packages/keras/engine/training.py\u001b[0m in \u001b[0;36mfit\u001b[0;34m(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, validation_freq, max_queue_size, workers, use_multiprocessing, **kwargs)\u001b[0m\n\u001b[1;32m 1237\u001b[0m \u001b[0msteps_per_epoch\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0msteps_per_epoch\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1238\u001b[0m \u001b[0mvalidation_steps\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mvalidation_steps\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1239\u001b[0;31m validation_freq=validation_freq)\n\u001b[0m\u001b[1;32m 1240\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1241\u001b[0m def evaluate(self,\n", + "\u001b[0;32m~/PycharmProjects/TensorFlow/venv/lib/python3.6/site-packages/keras/engine/training_arrays.py\u001b[0m in \u001b[0;36mfit_loop\u001b[0;34m(model, fit_function, fit_inputs, out_labels, batch_size, epochs, verbose, callbacks, val_function, val_inputs, shuffle, initial_epoch, steps_per_epoch, validation_steps, validation_freq)\u001b[0m\n\u001b[1;32m 194\u001b[0m \u001b[0mins_batch\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mins_batch\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtoarray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 195\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 196\u001b[0;31m \u001b[0mouts\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfit_function\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mins_batch\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 197\u001b[0m \u001b[0mouts\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mto_list\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mouts\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 198\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0ml\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mo\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mzip\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mout_labels\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mouts\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/PycharmProjects/TensorFlow/venv/lib/python3.6/site-packages/tensorflow_core/python/keras/backend.py\u001b[0m in \u001b[0;36m__call__\u001b[0;34m(self, inputs)\u001b[0m\n\u001b[1;32m 3738\u001b[0m \u001b[0mvalue\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmath_ops\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcast\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalue\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtensor\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdtype\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3739\u001b[0m \u001b[0mconverted_inputs\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvalue\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 3740\u001b[0;31m \u001b[0moutputs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_graph_fn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mconverted_inputs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3741\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3742\u001b[0m \u001b[0;31m# EagerTensor.numpy() will often make a copy to ensure memory safety.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/PycharmProjects/TensorFlow/venv/lib/python3.6/site-packages/tensorflow_core/python/eager/function.py\u001b[0m in \u001b[0;36m__call__\u001b[0;34m(self, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1079\u001b[0m \u001b[0mTypeError\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mFor\u001b[0m \u001b[0minvalid\u001b[0m \u001b[0mpositional\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0mkeyword\u001b[0m \u001b[0margument\u001b[0m \u001b[0mcombinations\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1080\u001b[0m \"\"\"\n\u001b[0;32m-> 1081\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_call_impl\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1082\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1083\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_call_impl\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcancellation_manager\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/PycharmProjects/TensorFlow/venv/lib/python3.6/site-packages/tensorflow_core/python/eager/function.py\u001b[0m in \u001b[0;36m_call_impl\u001b[0;34m(self, args, kwargs, cancellation_manager)\u001b[0m\n\u001b[1;32m 1119\u001b[0m raise TypeError(\"Keyword arguments {} unknown. Expected {}.\".format(\n\u001b[1;32m 1120\u001b[0m list(kwargs.keys()), list(self._arg_keywords)))\n\u001b[0;32m-> 1121\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_call_flat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcaptured_inputs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcancellation_manager\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1122\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1123\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_filtered_call\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/PycharmProjects/TensorFlow/venv/lib/python3.6/site-packages/tensorflow_core/python/eager/function.py\u001b[0m in \u001b[0;36m_call_flat\u001b[0;34m(self, args, captured_inputs, cancellation_manager)\u001b[0m\n\u001b[1;32m 1222\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mexecuting_eagerly\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1223\u001b[0m flat_outputs = forward_function.call(\n\u001b[0;32m-> 1224\u001b[0;31m ctx, args, cancellation_manager=cancellation_manager)\n\u001b[0m\u001b[1;32m 1225\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1226\u001b[0m \u001b[0mgradient_name\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_delayed_rewrite_functions\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mregister\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/PycharmProjects/TensorFlow/venv/lib/python3.6/site-packages/tensorflow_core/python/eager/function.py\u001b[0m in \u001b[0;36mcall\u001b[0;34m(self, ctx, args, cancellation_manager)\u001b[0m\n\u001b[1;32m 509\u001b[0m \u001b[0minputs\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 510\u001b[0m \u001b[0mattrs\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"executor_type\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mexecutor_type\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"config_proto\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mconfig\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 511\u001b[0;31m ctx=ctx)\n\u001b[0m\u001b[1;32m 512\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 513\u001b[0m outputs = execute.execute_with_cancellation(\n", + "\u001b[0;32m~/PycharmProjects/TensorFlow/venv/lib/python3.6/site-packages/tensorflow_core/python/eager/execute.py\u001b[0m in \u001b[0;36mquick_execute\u001b[0;34m(op_name, num_outputs, inputs, attrs, ctx, name)\u001b[0m\n\u001b[1;32m 59\u001b[0m tensors = pywrap_tensorflow.TFE_Py_Execute(ctx._handle, device_name,\n\u001b[1;32m 60\u001b[0m \u001b[0mop_name\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0minputs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mattrs\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 61\u001b[0;31m num_outputs)\n\u001b[0m\u001b[1;32m 62\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mcore\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_NotOkStatusException\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 63\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mname\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " + ] + } + ], + "source": [ + "autoencoder_train = autoencoder.fit(densities, densities, \n", + " epochs = training_epochs,\n", + " batch_size = batch_size,\n", + " verbose = 1,\n", + " validation_data = (vali_data, vali_data),\n", + " shuffle = True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Plot de Loss y Validation Loss respecto a las epochs." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'autoencoder_train' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m<ipython-input-21-399e640ef39b>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mepochs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m12\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mloss\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mautoencoder_train\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mhistory\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"loss\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0mval_loss\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mautoencoder_train\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mhistory\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"val_loss\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mepochs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mloss\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mval_loss\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mNameError\u001b[0m: name 'autoencoder_train' is not defined" + ] + } + ], + "source": [ + "epochs = range(training_epochs)\n", + "loss = autoencoder_train.history[\"loss\"]\n", + "val_loss = autoencoder_train.history[\"val_loss\"]\n", + "\n", + "plt.plot(epochs, loss, val_loss)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Las predicciones del autoencoder sobre los datos de validación." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [], + "source": [ + "decoded_imgs = autoencoder.predict(vali_data)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Plot de 10 imagenes del set de validación y predicción." + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 720x144 with 20 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "n = 10 # Number of frames to display\n", + "\n", + "plt.figure(figsize = (10, 2))\n", + "\n", + "for i in range(n):\n", + " \n", + " ax = plt.subplot(2, n, i + 1)\n", + " plt.imshow(vali_data[i].reshape(64, 64))\n", + " plt.gray()\n", + " ax.get_xaxis().set_visible(False)\n", + " ax.get_yaxis().set_visible(False)\n", + " \n", + " ax = plt.subplot(2, n, i + 1 + n)\n", + " plt.imshow(decoded_imgs[i].reshape(64, 64))\n", + " plt.gray()\n", + " ax.get_xaxis().set_visible(False)\n", + " ax.get_yaxis().set_visible(False)\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Guardamos las imagenes en el directorio /test_simple." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [], + "source": [ + "out_dir = \"%s/test_simple\" % base_path\n", + "if not os.path.exists(out_dir): os.makedirs(out_dir)\n", + "\n", + "for i in range(100):\n", + " scipy.misc.toimage(np.reshape(vali_data[i], [64, 64])).save(\"%s/in_%d.png\" % (out_dir, i))\n", + " scipy.misc.toimage(np.reshape(decoded_imgs[i], [64, 64]),).save(\"%s/out_%d.png\" % (out_dir, i))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Construir el modelo Encoder" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "encoder = Model(autoencoder.input, autoencoder.layers[22].output)\n", + "encoder.summary()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Construir el modelo Decoder" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "decoder_input_img = Input(shape = (autoencoder.layers[21].output_shape[1],\n", + " autoencoder.layers[21].output_shape[2],\n", + " autoencoder.layers[21].output_shape[3]))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "decoder_l0 = decoder_input_img\n", + "decoder_l1 = autoencoder.layers[23](decoder_l0)\n", + "decoder_l2 = autoencoder.layers[24](decoder_l1)\n", + "decoder_l3 = autoencoder.layers[25](decoder_l2)\n", + "decoder_l4 = autoencoder.layers[26](decoder_l3)\n", + "decoder_l5 = autoencoder.layers[27](decoder_l4)\n", + "decoder_l6 = autoencoder.layers[28](decoder_l5)\n", + "decoder_l7 = autoencoder.layers[29](decoder_l6)\n", + "decoder_l8 = autoencoder.layers[30](decoder_l7)\n", + "decoder_l9 = autoencoder.layers[31](decoder_l8)\n", + "decoder_l10 = autoencoder.layers[33](decoder_l9)\n", + "decoder_l11 = autoencoder.layers[34](decoder_l10)\n", + "decoder_l12 = autoencoder.layers[35](decoder_l11)\n", + "decoder_l13 = autoencoder.layers[36](decoder_l12)\n", + "decoder_l14 = autoencoder.layers[37](decoder_l13)\n", + "decoder_l15 = autoencoder.layers[38](decoder_l14)\n", + "decoder_l16 = autoencoder.layers[39](decoder_l15)\n", + "decoder_l17 = autoencoder.layers[40](decoder_l16)\n", + "decoder_l18 = autoencoder.layers[41](decoder_l17)\n", + "decoder_l19 = autoencoder.layers[42](decoder_l18)\n", + "\n", + "decoder = Model(decoder_input_img, decoder_l19)\n", + "decoder.summary()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Output del Encoder" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "encoded_imgs = encoder.predict(vali_data)\n", + "encoded_imgs.shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# LSTM" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "\n", + "El output del modelo encoder sirve como input para la red LSTM." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Output del Decoder" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "decoded_imgs = decoder.predict(encoded_imgs)\n", + "decoded_imgs.shape" + ] + } + ], + "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.6.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Scripts/Notebooks/NumbersConvNb.ipynb b/Scripts/Notebooks/NumbersConvNb.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..b05f5818a44265b1f9e641772518ed6a1f0914b7 --- /dev/null +++ b/Scripts/Notebooks/NumbersConvNb.ipynb @@ -0,0 +1,321 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:517: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_qint8 = np.dtype([(\"qint8\", np.int8, 1)])\n", + "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:518: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_quint8 = np.dtype([(\"quint8\", np.uint8, 1)])\n", + "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:519: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_qint16 = np.dtype([(\"qint16\", np.int16, 1)])\n", + "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:520: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_quint16 = np.dtype([(\"quint16\", np.uint16, 1)])\n", + "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:521: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_qint32 = np.dtype([(\"qint32\", np.int32, 1)])\n", + "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:526: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " np_resource = np.dtype([(\"resource\", np.ubyte, 1)])\n" + ] + } + ], + "source": [ + "import time\n", + "import os\n", + "import shutil\n", + "import sys\n", + "import math\n", + "import random\n", + "import tensorflow as tf\n", + "import numpy as np\n", + "import scipy.misc\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Using TensorFlow backend.\n" + ] + } + ], + "source": [ + "from keras.layers import Input, Dense, Conv2D, MaxPooling2D, UpSampling2D\n", + "from keras.models import Model, Sequential\n", + "from keras import backend as K" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "from keras.datasets import mnist\n", + "(x_train, _), (x_test, _) = mnist.load_data()" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "x_train = x_train.astype('float32') / 255.\n", + "x_test = x_test.astype('float32') / 255." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "x_train = np.reshape(x_train, (len(x_train), 28, 28, 1))\n", + "x_test = np.reshape(x_test, (len(x_test), 28, 28, 1))" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(60000, 28, 28, 1)\n", + "(10000, 28, 28, 1)\n" + ] + } + ], + "source": [ + "print(x_train.shape)\n", + "print(x_test.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "input_shape = (28, 28, 1)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "l0 = Conv2D(16, (3, 3), activation = \"relu\", padding = \"same\", input_shape = input_shape)\n", + "\n", + "l1 = MaxPooling2D((2, 2), padding = \"same\")\n", + "\n", + "l2 = Conv2D(8, (3, 3), activation = \"relu\", padding = \"same\")\n", + "\n", + "l3 = MaxPooling2D((2, 2), padding = \"same\")\n", + "\n", + "l4 = Conv2D(8, (3, 3), activation = \"relu\", padding = \"same\")\n", + "\n", + "l5 = MaxPooling2D((2, 2), padding = \"same\")\n", + "\n", + "l6 = Conv2D(8, (3, 3), activation = \"relu\", padding = \"same\")\n", + "\n", + "l7 = UpSampling2D((2, 2))\n", + "\n", + "l8 = Conv2D(8, (3, 3), activation = \"relu\", padding = \"same\")\n", + "\n", + "l9 = UpSampling2D((2, 2))\n", + "\n", + "l10 = Conv2D(16, (3, 3), activation = \"relu\", padding = \"same\")\n", + "\n", + "l11 = UpSampling2D((2, 2))\n", + "\n", + "l12 = Conv2D(1, (3, 3), activation =\"sigmoid\", padding = \"same\")" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "autoencoder = Sequential([l0, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12])" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "autoencoder.compile(optimizer = \"adadelta\", loss = \"binary_crossentropy\")" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "ename": "ValueError", + "evalue": "Error when checking target: expected conv2d_7 to have shape (32, 32, 1) but got array with shape (28, 28, 1)", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m<ipython-input-11-bf876f0c63dd>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mbatch_size\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m128\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mvalidation_data\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mx_test\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mx_test\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m shuffle = True)\n\u001b[0m", + "\u001b[0;32m~/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/keras/models.py\u001b[0m in \u001b[0;36mfit\u001b[0;34m(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, **kwargs)\u001b[0m\n\u001b[1;32m 1000\u001b[0m \u001b[0minitial_epoch\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0minitial_epoch\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1001\u001b[0m \u001b[0msteps_per_epoch\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0msteps_per_epoch\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1002\u001b[0;31m validation_steps=validation_steps)\n\u001b[0m\u001b[1;32m 1003\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1004\u001b[0m def evaluate(self, x=None, y=None,\n", + "\u001b[0;32m~/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/keras/engine/training.py\u001b[0m in \u001b[0;36mfit\u001b[0;34m(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, **kwargs)\u001b[0m\n\u001b[1;32m 1628\u001b[0m \u001b[0msample_weight\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0msample_weight\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1629\u001b[0m \u001b[0mclass_weight\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mclass_weight\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1630\u001b[0;31m batch_size=batch_size)\n\u001b[0m\u001b[1;32m 1631\u001b[0m \u001b[0;31m# Prepare validation data.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1632\u001b[0m \u001b[0mdo_validation\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/keras/engine/training.py\u001b[0m in \u001b[0;36m_standardize_user_data\u001b[0;34m(self, x, y, sample_weight, class_weight, check_array_lengths, batch_size)\u001b[0m\n\u001b[1;32m 1478\u001b[0m \u001b[0moutput_shapes\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1479\u001b[0m \u001b[0mcheck_batch_axis\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1480\u001b[0;31m exception_prefix='target')\n\u001b[0m\u001b[1;32m 1481\u001b[0m sample_weights = _standardize_sample_weights(sample_weight,\n\u001b[1;32m 1482\u001b[0m self._feed_output_names)\n", + "\u001b[0;32m~/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/keras/engine/training.py\u001b[0m in \u001b[0;36m_standardize_input_data\u001b[0;34m(data, names, shapes, check_batch_axis, exception_prefix)\u001b[0m\n\u001b[1;32m 121\u001b[0m \u001b[0;34m': expected '\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mnames\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m' to have shape '\u001b[0m \u001b[0;34m+\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 122\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m' but got array with shape '\u001b[0m \u001b[0;34m+\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 123\u001b[0;31m str(data_shape))\n\u001b[0m\u001b[1;32m 124\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 125\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mValueError\u001b[0m: Error when checking target: expected conv2d_7 to have shape (32, 32, 1) but got array with shape (28, 28, 1)" + ] + } + ], + "source": [ + "autoencoder.fit(x_train, x_train, \n", + " epochs = 10,\n", + " verbose = 1,\n", + " batch_size = 128,\n", + " validation_data = (x_test, x_test),\n", + " shuffle = True)" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [], + "source": [ + "input_img = Input(shape=(28, 28, 1)) # adapt this if using `channels_first` image data format\n", + "\n", + "x = Conv2D(16, (3, 3), activation='relu', padding='same')(input_img)\n", + "x = MaxPooling2D((2, 2), padding='same')(x)\n", + "x = Conv2D(8, (3, 3), activation='relu', padding='same')(x)\n", + "x = MaxPooling2D((2, 2), padding='same')(x)\n", + "x = Conv2D(8, (3, 3), activation='relu', padding='same')(x)\n", + "encoded = MaxPooling2D((2, 2), padding='same')(x)\n", + "\n", + "# at this point the representation is (4, 4, 8) i.e. 128-dimensional\n", + "\n", + "x = Conv2D(8, (3, 3), activation='relu', padding='same')(encoded)\n", + "x = UpSampling2D((2, 2))(x)\n", + "x = Conv2D(8, (3, 3), activation='relu', padding='same')(x)\n", + "x = UpSampling2D((2, 2))(x)\n", + "x = Conv2D(16, (3, 3), activation='relu')(x)\n", + "x = UpSampling2D((2, 2))(x)\n", + "decoded = Conv2D(1, (3, 3), activation='sigmoid', padding='same')(x)\n", + "\n", + "autoencoder = Model(input_img, decoded)\n", + "autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Train on 60000 samples, validate on 10000 samples\n", + "Epoch 1/50\n", + "60000/60000 [==============================] - 33s 557us/step - loss: 0.2131 - val_loss: 0.1623\n", + "Epoch 2/50\n", + "60000/60000 [==============================] - 33s 553us/step - loss: 0.1550 - val_loss: 0.1452\n", + "Epoch 3/50\n", + "60000/60000 [==============================] - 33s 547us/step - loss: 0.1405 - val_loss: 0.1360\n", + "Epoch 4/50\n", + "60000/60000 [==============================] - 33s 550us/step - loss: 0.1330 - val_loss: 0.1271\n", + "Epoch 5/50\n", + "60000/60000 [==============================] - 34s 559us/step - loss: 0.1284 - val_loss: 0.1262\n", + "Epoch 6/50\n", + "60000/60000 [==============================] - 34s 567us/step - loss: 0.1251 - val_loss: 0.1201\n", + "Epoch 7/50\n", + "60000/60000 [==============================] - 34s 569us/step - loss: 0.1227 - val_loss: 0.1191\n", + "Epoch 8/50\n", + "60000/60000 [==============================] - 34s 562us/step - loss: 0.1207 - val_loss: 0.1160\n", + "Epoch 9/50\n", + "60000/60000 [==============================] - 34s 559us/step - loss: 0.1190 - val_loss: 0.1175\n", + "Epoch 10/50\n", + "60000/60000 [==============================] - 34s 560us/step - loss: 0.1177 - val_loss: 0.1144\n", + "Epoch 11/50\n", + "60000/60000 [==============================] - 34s 562us/step - loss: 0.1166 - val_loss: 0.1132\n", + "Epoch 12/50\n", + "60000/60000 [==============================] - 34s 562us/step - loss: 0.1156 - val_loss: 0.1157\n", + "Epoch 13/50\n", + "60000/60000 [==============================] - 34s 564us/step - loss: 0.1144 - val_loss: 0.1131\n", + "Epoch 14/50\n", + "60000/60000 [==============================] - 34s 561us/step - loss: 0.1136 - val_loss: 0.1143\n", + "Epoch 15/50\n", + "60000/60000 [==============================] - 34s 562us/step - loss: 0.1126 - val_loss: 0.1096\n", + "Epoch 16/50\n", + "60000/60000 [==============================] - 34s 561us/step - loss: 0.1120 - val_loss: 0.1105\n", + "Epoch 17/50\n", + "60000/60000 [==============================] - 34s 561us/step - loss: 0.1113 - val_loss: 0.1080\n", + "Epoch 18/50\n", + "60000/60000 [==============================] - 34s 564us/step - loss: 0.1109 - val_loss: 0.1094\n", + "Epoch 19/50\n", + "60000/60000 [==============================] - 34s 565us/step - loss: 0.1103 - val_loss: 0.1092\n", + "Epoch 20/50\n", + "60000/60000 [==============================] - 34s 564us/step - loss: 0.1097 - val_loss: 0.1097\n", + "Epoch 21/50\n", + "60000/60000 [==============================] - 34s 572us/step - loss: 0.1092 - val_loss: 0.1061\n", + "Epoch 22/50\n", + "32000/60000 [===============>..............] - ETA: 14s - loss: 0.1088" + ] + } + ], + "source": [ + "autoencoder.fit(x_train, x_train,\n", + " epochs=50,\n", + " batch_size=128,\n", + " shuffle=True,\n", + " validation_data=(x_test, x_test))" + ] + }, + { + "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.6.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/Scripts/Notebooks/NumbersNb.ipynb b/Scripts/Notebooks/NumbersNb.ipynb index fa893f7e652f32965c09ea9962aa82385f0d884f..70bcc54954a2eb744953bbc8826f911d3a170d78 100644 --- a/Scripts/Notebooks/NumbersNb.ipynb +++ b/Scripts/Notebooks/NumbersNb.ipynb @@ -2,9 +2,28 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:517: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_qint8 = np.dtype([(\"qint8\", np.int8, 1)])\n", + "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:518: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_quint8 = np.dtype([(\"quint8\", np.uint8, 1)])\n", + "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:519: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_qint16 = np.dtype([(\"qint16\", np.int16, 1)])\n", + "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:520: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_quint16 = np.dtype([(\"quint16\", np.uint16, 1)])\n", + "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:521: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_qint32 = np.dtype([(\"qint32\", np.int32, 1)])\n", + "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:526: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " np_resource = np.dtype([(\"resource\", np.ubyte, 1)])\n" + ] + } + ], "source": [ "import time\n", "import os\n", @@ -20,9 +39,17 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Using TensorFlow backend.\n" + ] + } + ], "source": [ "from keras.layers import Input, Dense\n", "from keras.models import Model" @@ -30,7 +57,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -40,7 +67,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -52,7 +79,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -61,7 +88,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -72,7 +99,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -81,7 +108,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, "outputs": [], "source": [ @@ -91,25 +118,130 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "(60000, 28, 28)" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "x_train.shape" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "array([[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0],\n", + " [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0],\n", + " [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0],\n", + " [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0],\n", + " [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0],\n", + " [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,\n", + " 18, 18, 18, 126, 136, 175, 26, 166, 255, 247, 127, 0, 0,\n", + " 0, 0],\n", + " [ 0, 0, 0, 0, 0, 0, 0, 0, 30, 36, 94, 154, 170,\n", + " 253, 253, 253, 253, 253, 225, 172, 253, 242, 195, 64, 0, 0,\n", + " 0, 0],\n", + " [ 0, 0, 0, 0, 0, 0, 0, 49, 238, 253, 253, 253, 253,\n", + " 253, 253, 253, 253, 251, 93, 82, 82, 56, 39, 0, 0, 0,\n", + " 0, 0],\n", + " [ 0, 0, 0, 0, 0, 0, 0, 18, 219, 253, 253, 253, 253,\n", + " 253, 198, 182, 247, 241, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0],\n", + " [ 0, 0, 0, 0, 0, 0, 0, 0, 80, 156, 107, 253, 253,\n", + " 205, 11, 0, 43, 154, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0],\n", + " [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 1, 154, 253,\n", + " 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0],\n", + " [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 139, 253,\n", + " 190, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0],\n", + " [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 190,\n", + " 253, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0],\n", + " [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35,\n", + " 241, 225, 160, 108, 1, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0],\n", + " [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 81, 240, 253, 253, 119, 25, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0],\n", + " [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 45, 186, 253, 253, 150, 27, 0, 0, 0, 0, 0, 0,\n", + " 0, 0],\n", + " [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0, 16, 93, 252, 253, 187, 0, 0, 0, 0, 0, 0,\n", + " 0, 0],\n", + " [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0, 0, 0, 249, 253, 249, 64, 0, 0, 0, 0, 0,\n", + " 0, 0],\n", + " [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 46, 130, 183, 253, 253, 207, 2, 0, 0, 0, 0, 0,\n", + " 0, 0],\n", + " [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39,\n", + " 148, 229, 253, 253, 253, 250, 182, 0, 0, 0, 0, 0, 0,\n", + " 0, 0],\n", + " [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 114, 221,\n", + " 253, 253, 253, 253, 201, 78, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0],\n", + " [ 0, 0, 0, 0, 0, 0, 0, 0, 23, 66, 213, 253, 253,\n", + " 253, 253, 198, 81, 2, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0],\n", + " [ 0, 0, 0, 0, 0, 0, 18, 171, 219, 253, 253, 253, 253,\n", + " 195, 80, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0],\n", + " [ 0, 0, 0, 0, 55, 172, 226, 253, 253, 253, 253, 244, 133,\n", + " 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0],\n", + " [ 0, 0, 0, 0, 136, 253, 253, 253, 212, 135, 132, 16, 0,\n", + " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0],\n", + " [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0],\n", + " [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0],\n", + " [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n", + " 0, 0]], dtype=uint8)" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "x_train[0]" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -119,7 +251,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ @@ -129,15 +261,15 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "(60000, 28, 28, 1)\n", - "(10000, 28, 28, 1)\n" + "(60000, 784)\n", + "(10000, 784)\n" ] } ], @@ -148,139 +280,32 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "plt.figure(figsize = (2, 2))\n", - "plt.imshow(x_train[900].reshape(28, 28))\n", - "plt.gray()\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "autoencoder.fit(x_train, x_train,\n", - " epochs = 50,\n", - " batch_size = 256,\n", - " shuffle = True,\n", - " validation_data = (x_test, x_test))" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "# encode and decode some digits\n", - "# note that we take them from the *test* set\n", - "encoded_imgs = encoder.predict(x_test)\n", - "decoded_imgs = decoder.predict(encoded_imgs)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [ - "n = 10 # how many digits we will display\n", - "plt.figure(figsize=(20, 4))\n", - "for i in range(n):\n", - " # display original\n", - " ax = plt.subplot(2, n, i + 1)\n", - " plt.imshow(x_test[i].reshape(28, 28))\n", - " plt.gray()\n", - " ax.get_xaxis().set_visible(False)\n", - " ax.get_yaxis().set_visible(False)\n", - "\n", - " # display reconstruction\n", - " ax = plt.subplot(2, n, i + 1 + n)\n", - " plt.imshow(decoded_imgs[i].reshape(28, 28))\n", - " plt.gray()\n", - " ax.get_xaxis().set_visible(False)\n", - " ax.get_yaxis().set_visible(False)\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 1, + "execution_count": 14, "metadata": {}, "outputs": [ { - "name": "stderr", - "output_type": "stream", - "text": [ - "Using TensorFlow backend.\n", - "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:517: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", - " _np_qint8 = np.dtype([(\"qint8\", np.int8, 1)])\n", - "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:518: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", - " _np_quint8 = np.dtype([(\"quint8\", np.uint8, 1)])\n", - "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:519: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", - " _np_qint16 = np.dtype([(\"qint16\", np.int16, 1)])\n", - "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:520: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", - " _np_quint16 = np.dtype([(\"quint16\", np.uint16, 1)])\n", - "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:521: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", - " _np_qint32 = np.dtype([(\"qint32\", np.int32, 1)])\n", - "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:526: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", - " np_resource = np.dtype([(\"resource\", np.ubyte, 1)])\n" - ] + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 144x144 with 1 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" } ], "source": [ - "from keras.layers import Input, Dense, Conv2D, MaxPooling2D, UpSampling2D\n", - "from keras.models import Model\n", - "from keras import backend as K\n", - "\n", - "input_img = Input(shape=(28, 28, 1)) # adapt this if using `channels_first` image data format\n", - "\n", - "x = Conv2D(16, (3, 3), activation='relu', padding='same')(input_img)\n", - "x = MaxPooling2D((2, 2), padding='same')(x)\n", - "x = Conv2D(8, (3, 3), activation='relu', padding='same')(x)\n", - "x = MaxPooling2D((2, 2), padding='same')(x)\n", - "x = Conv2D(8, (3, 3), activation='relu', padding='same')(x)\n", - "encoded = MaxPooling2D((2, 2), padding='same')(x)\n", - "\n", - "# at this point the representation is (4, 4, 8) i.e. 128-dimensional\n", - "\n", - "x = Conv2D(8, (3, 3), activation='relu', padding='same')(encoded)\n", - "x = UpSampling2D((2, 2))(x)\n", - "x = Conv2D(8, (3, 3), activation='relu', padding='same')(x)\n", - "x = UpSampling2D((2, 2))(x)\n", - "x = Conv2D(16, (3, 3), activation='relu')(x)\n", - "x = UpSampling2D((2, 2))(x)\n", - "decoded = Conv2D(1, (3, 3), activation='sigmoid', padding='same')(x)\n", - "\n", - "autoencoder = Model(input_img, decoded)\n", - "autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "from keras.datasets import mnist\n", - "import numpy as np\n", - "\n", - "(x_train, _), (x_test, _) = mnist.load_data()\n", - "\n", - "x_train = x_train.astype('float32') / 255.\n", - "x_test = x_test.astype('float32') / 255.\n", - "x_train = np.reshape(x_train, (len(x_train), 28, 28, 1)) # adapt this if using `channels_first` image data format\n", - "x_test = np.reshape(x_test, (len(x_test), 28, 28, 1)) # adapt this if using `channels_first` image data format" + "plt.figure(figsize = (2, 2))\n", + "plt.imshow(x_train[900].reshape(28, 28))\n", + "plt.gray()\n", + "plt.show()" ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 15, "metadata": {}, "outputs": [ { @@ -289,145 +314,157 @@ "text": [ "Train on 60000 samples, validate on 10000 samples\n", "Epoch 1/50\n", - "60000/60000 [==============================] - 34s 570us/step - loss: 0.2069 - val_loss: 0.1690\n", + "60000/60000 [==============================] - 2s 34us/step - loss: 0.3618 - val_loss: 0.2709\n", "Epoch 2/50\n", - "60000/60000 [==============================] - 34s 571us/step - loss: 0.1578 - val_loss: 0.1431\n", + "60000/60000 [==============================] - 2s 32us/step - loss: 0.2638 - val_loss: 0.2528\n", "Epoch 3/50\n", - "60000/60000 [==============================] - 34s 571us/step - loss: 0.1420 - val_loss: 0.1345\n", + "60000/60000 [==============================] - 2s 31us/step - loss: 0.2420 - val_loss: 0.2292\n", "Epoch 4/50\n", - "60000/60000 [==============================] - 34s 564us/step - loss: 0.1336 - val_loss: 0.1278\n", + "60000/60000 [==============================] - 2s 33us/step - loss: 0.2216 - val_loss: 0.2116\n", "Epoch 5/50\n", - "60000/60000 [==============================] - 35s 582us/step - loss: 0.1280 - val_loss: 0.1259\n", + "60000/60000 [==============================] - 2s 32us/step - loss: 0.2068 - val_loss: 0.1992\n", "Epoch 6/50\n", - "60000/60000 [==============================] - 35s 578us/step - loss: 0.1236 - val_loss: 0.1228\n", + "60000/60000 [==============================] - 2s 30us/step - loss: 0.1960 - val_loss: 0.1901\n", "Epoch 7/50\n", - "60000/60000 [==============================] - 35s 584us/step - loss: 0.1207 - val_loss: 0.1168\n", + "60000/60000 [==============================] - 2s 27us/step - loss: 0.1877 - val_loss: 0.1828\n", "Epoch 8/50\n", - "60000/60000 [==============================] - 36s 598us/step - loss: 0.1183 - val_loss: 0.1145\n", + "60000/60000 [==============================] - 2s 27us/step - loss: 0.1811 - val_loss: 0.1768\n", "Epoch 9/50\n", - "60000/60000 [==============================] - 35s 585us/step - loss: 0.1165 - val_loss: 0.1138\n", + "60000/60000 [==============================] - 2s 27us/step - loss: 0.1756 - val_loss: 0.1715\n", "Epoch 10/50\n", - "60000/60000 [==============================] - 35s 584us/step - loss: 0.1149 - val_loss: 0.1123\n", + "60000/60000 [==============================] - 2s 31us/step - loss: 0.1706 - val_loss: 0.1670\n", "Epoch 11/50\n", - "60000/60000 [==============================] - 36s 593us/step - loss: 0.1133 - val_loss: 0.1151\n", + "60000/60000 [==============================] - 2s 31us/step - loss: 0.1660 - val_loss: 0.1624\n", "Epoch 12/50\n", - "60000/60000 [==============================] - 35s 591us/step - loss: 0.1123 - val_loss: 0.1130\n", + "60000/60000 [==============================] - 2s 30us/step - loss: 0.1616 - val_loss: 0.1581\n", "Epoch 13/50\n", - "60000/60000 [==============================] - 35s 585us/step - loss: 0.1110 - val_loss: 0.1106\n", + "60000/60000 [==============================] - 2s 29us/step - loss: 0.1574 - val_loss: 0.1540\n", "Epoch 14/50\n", - "60000/60000 [==============================] - 34s 573us/step - loss: 0.1101 - val_loss: 0.1077\n", + "60000/60000 [==============================] - 2s 28us/step - loss: 0.1535 - val_loss: 0.1502\n", "Epoch 15/50\n", - "60000/60000 [==============================] - 35s 578us/step - loss: 0.1091 - val_loss: 0.1072\n", + "60000/60000 [==============================] - 2s 30us/step - loss: 0.1499 - val_loss: 0.1468\n", "Epoch 16/50\n", - "60000/60000 [==============================] - 34s 569us/step - loss: 0.1083 - val_loss: 0.1065\n", + "60000/60000 [==============================] - 2s 28us/step - loss: 0.1466 - val_loss: 0.1436\n", "Epoch 17/50\n", - "60000/60000 [==============================] - 36s 592us/step - loss: 0.1072 - val_loss: 0.1058\n", + "60000/60000 [==============================] - 2s 30us/step - loss: 0.1436 - val_loss: 0.1407\n", "Epoch 18/50\n", - "60000/60000 [==============================] - 35s 577us/step - loss: 0.1064 - val_loss: 0.1034\n", + "60000/60000 [==============================] - 2s 28us/step - loss: 0.1410 - val_loss: 0.1381\n", "Epoch 19/50\n", - "60000/60000 [==============================] - 34s 570us/step - loss: 0.1059 - val_loss: 0.1080\n", + "60000/60000 [==============================] - 2s 29us/step - loss: 0.1385 - val_loss: 0.1358\n", "Epoch 20/50\n", - "60000/60000 [==============================] - 35s 577us/step - loss: 0.1050 - val_loss: 0.1041\n", + "60000/60000 [==============================] - 2s 29us/step - loss: 0.1363 - val_loss: 0.1337\n", "Epoch 21/50\n", - "60000/60000 [==============================] - 35s 579us/step - loss: 0.1046 - val_loss: 0.1060\n", + "60000/60000 [==============================] - 2s 29us/step - loss: 0.1342 - val_loss: 0.1315\n", "Epoch 22/50\n", - "60000/60000 [==============================] - 35s 585us/step - loss: 0.1041 - val_loss: 0.1027\n", + "60000/60000 [==============================] - 2s 29us/step - loss: 0.1321 - val_loss: 0.1295\n", "Epoch 23/50\n", - "60000/60000 [==============================] - 35s 575us/step - loss: 0.1035 - val_loss: 0.1024\n", + "60000/60000 [==============================] - 2s 29us/step - loss: 0.1302 - val_loss: 0.1276\n", "Epoch 24/50\n", - "60000/60000 [==============================] - 36s 606us/step - loss: 0.1029 - val_loss: 0.1014\n", + "60000/60000 [==============================] - 2s 29us/step - loss: 0.1284 - val_loss: 0.1258\n", "Epoch 25/50\n", - "60000/60000 [==============================] - 35s 585us/step - loss: 0.1028 - val_loss: 0.1019\n", + "60000/60000 [==============================] - 2s 29us/step - loss: 0.1266 - val_loss: 0.1241\n", "Epoch 26/50\n", - "60000/60000 [==============================] - 35s 584us/step - loss: 0.1026 - val_loss: 0.1022\n", + "60000/60000 [==============================] - 2s 30us/step - loss: 0.1249 - val_loss: 0.1223\n", "Epoch 27/50\n", - "60000/60000 [==============================] - 36s 595us/step - loss: 0.1023 - val_loss: 0.1032\n", + "60000/60000 [==============================] - 2s 31us/step - loss: 0.1232 - val_loss: 0.1207\n", "Epoch 28/50\n", - "60000/60000 [==============================] - 36s 595us/step - loss: 0.1016 - val_loss: 0.1001\n", + "60000/60000 [==============================] - 2s 32us/step - loss: 0.1216 - val_loss: 0.1192\n", "Epoch 29/50\n", - "60000/60000 [==============================] - 35s 583us/step - loss: 0.1015 - val_loss: 0.1011\n", + "60000/60000 [==============================] - 2s 30us/step - loss: 0.1201 - val_loss: 0.1178\n", "Epoch 30/50\n", - "60000/60000 [==============================] - 35s 588us/step - loss: 0.1012 - val_loss: 0.1001\n", + "60000/60000 [==============================] - 2s 31us/step - loss: 0.1187 - val_loss: 0.1164\n", "Epoch 31/50\n", - "60000/60000 [==============================] - 35s 586us/step - loss: 0.1009 - val_loss: 0.0981\n", + "60000/60000 [==============================] - 2s 30us/step - loss: 0.1174 - val_loss: 0.1151\n", "Epoch 32/50\n", - "60000/60000 [==============================] - 35s 583us/step - loss: 0.1005 - val_loss: 0.0986\n", + "60000/60000 [==============================] - 2s 30us/step - loss: 0.1161 - val_loss: 0.1139\n", "Epoch 33/50\n", - "60000/60000 [==============================] - 35s 581us/step - loss: 0.1002 - val_loss: 0.0975\n", + "60000/60000 [==============================] - 2s 28us/step - loss: 0.1150 - val_loss: 0.1127\n", "Epoch 34/50\n", - "60000/60000 [==============================] - 35s 587us/step - loss: 0.1004 - val_loss: 0.0992\n", + "60000/60000 [==============================] - 2s 27us/step - loss: 0.1139 - val_loss: 0.1117\n", "Epoch 35/50\n", - "60000/60000 [==============================] - 37s 615us/step - loss: 0.1001 - val_loss: 0.0986\n", + "60000/60000 [==============================] - 2s 27us/step - loss: 0.1129 - val_loss: 0.1107\n", "Epoch 36/50\n", - "60000/60000 [==============================] - 36s 600us/step - loss: 0.1000 - val_loss: 0.0977\n", + "60000/60000 [==============================] - 2s 29us/step - loss: 0.1120 - val_loss: 0.1099\n", "Epoch 37/50\n", - "60000/60000 [==============================] - 35s 591us/step - loss: 0.0998 - val_loss: 0.0967\n", + "60000/60000 [==============================] - 2s 29us/step - loss: 0.1111 - val_loss: 0.1091\n", "Epoch 38/50\n", - "60000/60000 [==============================] - 36s 597us/step - loss: 0.0995 - val_loss: 0.0990\n", + "60000/60000 [==============================] - 2s 30us/step - loss: 0.1104 - val_loss: 0.1083\n", "Epoch 39/50\n", - "60000/60000 [==============================] - 35s 583us/step - loss: 0.0993 - val_loss: 0.0982\n", + "60000/60000 [==============================] - 2s 30us/step - loss: 0.1096 - val_loss: 0.1076\n", "Epoch 40/50\n", - "60000/60000 [==============================] - 35s 580us/step - loss: 0.0988 - val_loss: 0.1012\n", + "60000/60000 [==============================] - 2s 29us/step - loss: 0.1089 - val_loss: 0.1070\n", "Epoch 41/50\n", - "60000/60000 [==============================] - 35s 586us/step - loss: 0.0990 - val_loss: 0.0962\n", + "60000/60000 [==============================] - 2s 28us/step - loss: 0.1083 - val_loss: 0.1063\n", "Epoch 42/50\n", - "60000/60000 [==============================] - 35s 590us/step - loss: 0.0987 - val_loss: 0.0982\n", + "60000/60000 [==============================] - 2s 27us/step - loss: 0.1077 - val_loss: 0.1058\n", "Epoch 43/50\n", - "60000/60000 [==============================] - 36s 594us/step - loss: 0.0985 - val_loss: 0.0978\n", + "60000/60000 [==============================] - 2s 28us/step - loss: 0.1072 - val_loss: 0.1053\n", "Epoch 44/50\n", - "60000/60000 [==============================] - 35s 578us/step - loss: 0.0984 - val_loss: 0.0986\n", + "60000/60000 [==============================] - 2s 29us/step - loss: 0.1067 - val_loss: 0.1048\n", "Epoch 45/50\n", - "60000/60000 [==============================] - 35s 577us/step - loss: 0.0983 - val_loss: 0.0977\n", + "60000/60000 [==============================] - 2s 27us/step - loss: 0.1062 - val_loss: 0.1043\n", "Epoch 46/50\n", - "60000/60000 [==============================] - 36s 598us/step - loss: 0.0983 - val_loss: 0.0987\n", + "60000/60000 [==============================] - 2s 29us/step - loss: 0.1057 - val_loss: 0.1039\n", "Epoch 47/50\n", - "60000/60000 [==============================] - 35s 578us/step - loss: 0.0981 - val_loss: 0.0952\n", + "60000/60000 [==============================] - 2s 29us/step - loss: 0.1053 - val_loss: 0.1035\n", "Epoch 48/50\n", - "60000/60000 [==============================] - 35s 581us/step - loss: 0.0981 - val_loss: 0.0998\n", + "60000/60000 [==============================] - 2s 30us/step - loss: 0.1049 - val_loss: 0.1031\n", "Epoch 49/50\n", - "60000/60000 [==============================] - 35s 580us/step - loss: 0.0980 - val_loss: 0.0977\n", + "60000/60000 [==============================] - 2s 29us/step - loss: 0.1046 - val_loss: 0.1027\n", "Epoch 50/50\n", - "60000/60000 [==============================] - 35s 575us/step - loss: 0.0975 - val_loss: 0.0970\n" + "60000/60000 [==============================] - 2s 29us/step - loss: 0.1042 - val_loss: 0.1024\n" ] }, { "data": { "text/plain": [ - "<keras.callbacks.History at 0x7fb054474a90>" + "<keras.callbacks.History at 0x7f33ca8d9e80>" ] }, - "execution_count": 3, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "autoencoder.fit(x_train, x_train,\n", - " epochs=50,\n", - " batch_size=128,\n", - " shuffle=True,\n", - " validation_data=(x_test, x_test))" + " epochs = 50,\n", + " batch_size = 256,\n", + " shuffle = True,\n", + " validation_data = (x_test, x_test))" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "# encode and decode some digits\n", + "# note that we take them from the *test* set\n", + "encoded_imgs = encoder.predict(x_test)\n", + "decoded_imgs = decoder.predict(encoded_imgs)" + ] + }, + { + "cell_type": "code", + "execution_count": 17, "metadata": {}, "outputs": [ { - "ename": "NameError", - "evalue": "name 'decoded_imgs' is not defined", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m<ipython-input-6-d88a015e8277>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 12\u001b[0m \u001b[0;31m# display reconstruction\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 13\u001b[0m \u001b[0max\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msubplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mn\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mi\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m1\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mn\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 14\u001b[0;31m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mimshow\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdecoded_imgs\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreshape\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m28\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m28\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 15\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 16\u001b[0m \u001b[0max\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_xaxis\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mset_visible\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mNameError\u001b[0m: name 'decoded_imgs' is not defined" - ] + "data": { + "image/png": "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ZeTIkVG/f//73xavWLHCYn+d0vvSv/71r1Hbm2++afE//vEPi1977bWo3+rVqxNfH9npcgohxGNM7zX9dyKrvfbay+LPPvssaps+fbrF48aNi9r0O/fJJ5+U9N5ZMNMGAAAAAAAgh3hoAwAAAAAAkEM8tAEAAAAAAMihRl3TRkt8hxDCrrvuavHUqVOjtp122snitLzivffe2+K5c+danFSirz6ax7ZkyRKLtZy1N2fOnGi7qa5po3T9ilJdcsklFm+//faJ/TSXtL5t5Nell15qsf/OMI4qY8SIERZrSe5SaWnTlStXRm1du3a1WMvOvvLKK1G/9dZbb533o+h8PreWbZ41a5bF1113XdX26Zhjjqnae2FNvXr1irb79OmT2Ffvbf7yl79UbJ+Kon379tH28ccfn9j3+9//vsV631hpuo7Nc889l9jPr2nj14NECBdffLHFWsI9K79O2+GHH26xLxuu699Ucg2MokpbZ2a33XazWEs9ey+//LLF+rvynXfeifp16dLFYl3LNITyrAOINenzgHPPPddiP8Y222yzev9+/vz50fYLL7xg8dtvvx216W8QXVuxX79+UT89JwwYMCBqmzhxosVaNrzcmGkDAAAAAACQQzy0AQAAAAAAyKFGTY8aNWpU6rbypdq+5MuN7r777hbrNKc999wz8359/PHHFs+YMcNin7KlU6V0ajrWzZFHHmmxls7ccMMNo36LFy+2+H//93+jto8++qhCe4d11a1bt2i7b9++Fut4C4HSiOXy1a9+NdreYYcdLNbpvVmn+vrpnzo9WUtnhhDC1772NYvTyhH/8Ic/tPiee+7JtB9NzZVXXhlt6xRxnYrvU9TKTa99/rvFdPHqSkvZ8XwaAdLddNNN0fYpp5xisd5fhhDCH//4x6rsk9e/f3+LO3ToELU9+OCDFv/+97+v1i7VDE3dDSGE733ve/X2mzRpUrS9aNEiiw8++ODE12/VqpXFmnoVQgiPPPKIxe++++7ad7aJ8/f/jz76qMWaDhVCnB6cljKofEqU8stfoPzuu+++aFvT2tLKd+tzgzfeeMPiyy+/POqnv+u9fffd12K9D33ggQeifvp8Qc8BIYRw1113Wfzkk09aXO5UWWbaAAAAAAAA5BAPbQAAAAAAAHKoUdOjymH58uXR9ujRo+vtl5Z6lUanHvtULJ2KNXjw4JJe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s9XYHVSYpnz4safpV/5ciex8SulJJ51ksaZtt2rVKvE17rjjDot9WtzHH39s8ZAhQ6I2Tf847LDDLO7evXvUrymXcf/Vr35l8YUXXpj57/T8eM4559Qbl4uOP13aYeDAgWV/ryLz6UY6Pkrxu9/9LtpOS4/SlHT9nj344INRPy0p3liYaQMAAAAAAJBDPLQBAAAAAADIIR7aAAAAAAAA5FCTXdPmkksusdiXnh05cqTFL774YtX2qWguuuiiaHvPPfest99TTz0VbVPmuxi++93vWqzlg//yl780wt6gWq644opoW8uepnnnnXcs/s53vhO1aVnHpkbPh7707ze+8Q2LH3vssQa/9tKlS6NtXTujbdu2mV7D532jMpJKrvu1AO67775q7A7K7MQTT4y2TzvtNIt1zYUQ1ix7i/LQkt063k4++eSon445XXtI17Dxrr766mh7p512svjoo4+u9/VCWPNa2JTouiaDBw+O2h599FGL118//im79dZbW5y2/lc56Bp++p3RsuMhhHDNNddUdD8QwqWXXmpxQ9YUOvvssy0u5T6qmphpAwAAAAAAkEM8tAEAAAAAAMihJpMepdPIQwjh//2//2fxBx98ELX94he/qMo+FV3WEn3nnXdetE2Z72Lo2rVrvf99+fLlVd4TVNqIESMs3mGHHUp6jSlTplg8bty4dd6nopg2bZrFWpI2hBB23313i3v06NHg19aytt5DDz0UbQ8aNKjefr5EOcqjc+fO0bZP0fjSvHnzou3x48dXbJ9QOUcccURi25///Odo+5///Geld6fJ01QpjUvlz5Oa7qPpUQcddFDUr3Xr1hb7EuVFpyWW/Xlt++23T/y7r3/96xZvsMEGFl911VVRv6QlG0ql6ct9+vQp62ujfmeccYbFmpLmU+bU5MmTo+0hQ4aUf8cqhJk2AAAAAAAAOcRDGwAAAAAAgBwqdHpUmzZtLL799tujtvXWW89indofQggvv/xyZXcMEZ3+GUIIn376aYNfY8WKFYmvodMjW7Vqlfgam2++ebSdNb1Lp3BedtllUdtHH32U6TWK6Mgjj6z3vw8bNqzKe9I06VTdtAoKadPy77//fou33HLLxH76+l988UXWXYwcddRRJf1dU/b666/XG5fDW2+9lalfz549o+0333yzrPvRVO27777RdtIY9tUXUZv8eXjVqlUW33TTTdXeHVTY448/brGmR33rW9+K+unyASzdkM2oUaPq/e+aThxCnB712WefWfzb3/426vfrX//a4h//+MdRW1LaKiqjX79+0baeG1u2bJn4d7rshlaLCiGEf//732Xau8pjpg0AAAAAAEAO8dAGAAAAAAAgh3hoAwAAAAAAkEOFW9NG16oZOXKkxdtss03Ub9asWRZr+W9U36RJk9b5Nf74xz9G2wsXLrS4Q4cOFvt84XJ79913o+1rr722ou+XJ/vvv3+03bFjx0baE4QQwj333GPxDTfckNhPy8mmrUeTda2arP3uvffeTP3QOHRNpPq2v8QaNpWha/J5S5cutfi2226rxu6gAnRtBb1PCSGExYsXW0yJ7+LR66Ren4855pio389+9jOL//CHP0RtM2bMqNDeFdNf//rXaFvvz7VE9Jlnnhn169Gjh8UHHnhgpveaN29eCXuItfFrH2666ab19tM1wUKI1436+9//Xv4dqxJm2gAAAAAAAOQQD20AAAAAAAByqHDpUd27d7e4T58+if20nLOmSqF8fCl1P+2znE488cSS/k7L/KWldTz99NMWjx8/PrHfCy+8UNJ+FMFxxx0XbWuq4muvvWbx888/X7V9asqGDBli8SWXXBK1tWvXrmLvu2TJkmh76tSpFv/gBz+wWFMYkT91dXWp26isww47LLFtzpw5Fq9YsaIau4MK0PQoP76GDx+e+HeaErDFFltYrN8L1I7XX3/d4p/+9KdR24033mjxddddF7WdeuqpFq9evbpCe1ccei8SQlx2/aSTTkr8u4MOOiix7fPPP7dYx+xPfvKTUnYR9dDz3aWXXprpbx555JFoe8yYMeXcpUbDTBsAAAAAAIAc4qENAAAAAABADvHQBgAAAAAAIIdqfk2brl27Rtu+pNuX/JoOWuYWlfHNb34z2tZcxA022CDTa+yyyy4WN6Rc9wMPPGDxO++8k9jvySeftHjatGmZXx//0aJFC4sHDBiQ2O+JJ56wWHOAUTmzZ8+2eODAgVHbsccea/H5559f1vf1Ze7vuuuusr4+qmPjjTdObGP9hMrQ66Kuz+d9/PHHFn/66acV3Sc0Dr1ODho0KGq74IILLJ48ebLF3/nOdyq/Y6io3/3ud9H2WWedZbG/p/7FL35h8aRJkyq7YwXgr1s//vGPLW7ZsqXFffv2jfq1b9/eYv974uGHH7b4qquuKsNeIoT4eEyZMsXitN+OOgb02BYJM20AAAAAAAByiIc2AAAAAAAAOVTz6VFaQjaEELp06VJvv7Fjx0bblC+tvhtuuGGd/v7kk08u056gXHRq/vLly6M2LZN+2223VW2fsCZfZl23NaXUn0+POuooi/V43n///VG/Zs2aWaxTWVG7vve970Xb77//vsVXX311tXenSfjiiy8sHj9+fNTWs2dPi2fOnFm1fULjOOOMMyz+/ve/H7X95je/sZixWCxLliyJtg8++GCLfWrOZZddZrFPocPaLVq0yGK919FS6iGEsPfee1v885//PGpbvHhxhfauafva175mcefOnS1O++2uaaOaQlwkzLQBAAAAAADIIR7aAAAAAAAA5FCzhqQJNWvWLBc5Rfvvv7/FI0aMiNp0xWnVr1+/aNtPPc67urq6ZmvvtXZ5OYZN1IS6urq+a++2dhzHxsNYLATG4loMGzYs2r755pstHj16dLV3p15FHotbbrlltH3NNddYPGHCBIsLUJ2tyY5FvZfVSkAhxCms99xzT9SmqciffPJJhfauYYo8FvPCV8fdZ599LN5rr70sXocU5SY7FoukCGNx4sSJFvfq1Sux34033mixpgsWQL1jkZk2AAAAAAAAOcRDGwAAAAAAgBzioQ0AAAAAAEAO1WTJ7/79+1uctIZNCCHMmjXL4pUrV1Z0nwAAKAotgYrqW7BgQbR9+umnN9KeoFLGjRtnsZa4BepzwgknRNu67kePHj0sXoc1bYBcaN26tcXNmv13iR5fYv3WW2+t2j7lATNtAAAAAAAAcoiHNgAAAAAAADlUk+lRaXS64Ne//nWLly1b1hi7AwAAAAAl++CDD6LtbbbZppH2BKism2++ud746quvjvotXLiwavuUB8y0AQAAAAAAyCEe2gAAAAAAAOQQD20AAAAAAAByqFldXV32zs2aZe+Msqqrq2u29l5rxzFsVBPq6ur6luOFOI6Nh7FYCIzFAmAsFgJjsQAYi4XAWCwAxmIh1DsWmWkDAAAAAACQQzy0AQAAAAAAyKGGlvxeGkKYXYkdQaquZXwtjmHj4TjWPo5hMXAcax/HsBg4jrWPY1gMHMfaxzEshnqPY4PWtAEAAAAAAEB1kB4FAAAAAACQQzy0AQAAAAAAyCEe2gAAAAAAAOQQD20AAAAAAAByiIc2AAAAAAAAOcRDGwAAAAAAgBzioQ0AAAAAAEAO8dAGAAAAAAAgh3hoAwAAAAAAkEM8tAEAAAAAAMghHtoAAAAAAADkEA9tAAAAAAAAcoiHNgAAAAAAADnEQxsAAAAAAIAc4qENAAAAAABADvHQBgAAAAAAIId4aAMAAAAAAJBDPLQBAAAAAADIIR7aAAAAAAAA5BAPbQAAAAAAAHKIhzYAAAAAAAA5xEMbAAAAAACAHFq/IZ2bNWtWV6kdQbq6urpm5XgdjmGjWlpXV9euHC/EcWw8jMVCYCwWAGOxEBiLBcBYLATGYgEwFguh3rHITBugemY39g4ACCEwFoG8YCwC+cBYBPKh3rHYoJk2QCU0axY/FK6r4+FuLfLHUXFMgcajY5OxCAAAUFuYaQMAAAAAAJBDPLQBAAAAAADIIR7aAAAAAAAA5BBr2qBi1l8/+ev1+eefJ7Z95Sv1P0v84osvou2sa6ist956if3S6PuxDkT9sq6VkdavlNdIU+rrA7Um65hI6sd4AIDS6f2qP5+mtfn7WQBYG2baAAAAAAAA5BAPbQAAAAAAAHKI9CiUVYsWLSxu1apV1NarVy+Ld9ttN4ubN28e9fvggw8sXrRokcULFiyI+q1atcriTTfdNLFNp6GuXLky6rd8+XKLP/nkk6htxYoVoT5NIaUgLaVI082yph6lpatpm0+N07ak2G/7VBB9zbQpyU3huJaL/4zTvgd8rg3jP9us4ypruigAoDzSzsGVPu+S+l19/hhvuOGGFuuSEL6f3nt+/PHHUVvavS2gmGkDAAAAAACQQzy0AQAAAAAAyCEe2gAAAAAAAOQQa9qgwXSNkJNOOilq69Gjh8WHHnpo1LbllltarGvf+PVolOZ3fvrpp1Gb5oUuXLgwahs3bpzFw4YNs3j27NlRP13Txq93kpSrXMSS0mm52GnrzGT57/41Ntlkk6htm222sXjHHXeM2lavXm3xG2+8YfH8+fOjfvrdyFpas1aPVbnpsffrDXXo0MFiHc8HHHBA1E/Xfxo6dGjU9sorr1j80UcfWcznX7+GlL3Xbc2nT/s7HStpr5c27rWfH19ZS9mmvQay88dpo402srhly5aJf/fhhx9a7Ndz43isXdaxo2tehBDC559/brGOxWp/5kW4b8mDrOfMcnzGad+5NBzfdaO/Vy688MKo7YwzzrBY759efPHFqN8f//hHi8eOHRu16Vqb//73vy3mPAyPmTYAAAAAAAA5xEMbAAAAAACAHCpcehRTPitDP9f+/ftbrFP5QgihW7duFrdt2zZq02nC+nrLli2L+ulUbY196kbSNOMQQnj33XctnjJlisWaDuVfI2tp3Ya05U3W6bSllPJOo/0+++yzqG3jjTe2uHv37lGbHnM9ploKPoQ1j3/Se+u/ixLJ/6FTujUdKoR4KvDAgQMt3myzzaJ+S5cutdinro0fP74s+9lU6fHx50Cdtt28eXOL/XjQ86h+7/X8F0L8vffvlZRG58eRvqYf60nvlVYetehjsfIWxi8AACAASURBVJQUh7SUjK233trib37zm1Fb+/btLR4+fLjFL730UtRP01KL/vl7ade+tDTfTp06WdyxY0eLfYrD4sWLLdZzpS8DnHUMpKW3aqqcT9NSeh/nU+XSxnBT4ceofs4bbLCBxf6zynp/mUa/cz4FNuk101L9SblZO72WhhDCo48+avFRRx0Vtfnz75dOOOGEaPvggw+2eMiQIVHbjTfeaPHcuXMt9r+vOHa1oZLPIZhpAwAAAAAAkEM8tAEAAAAAAMihqqRHJU3lTZpW5v/Gb+sUMd8vaSpnXqf41ko6l6ZNvPfeexbr9PwQ4s/fp0koXT195MiRUZtWeNLpvXvvvXfU7/TTT7fYf5emT59usaZfMdX3v9LSE1RaZamsr69j1h8D7bf55ptHbTq9WKeKpr1GqelcaalTeR6b60qnzR944IFRm6ZEaWqF/3w0FbJv375Rm1awWbVqlcVF/kwbKmuqnk9/0Mp7rVu3tlin7IcQwoIFCyzW82FaepSfiq3nWN1fnyai7+2ndydVxvD9iqbcaZlp1f323Xdfi88555yoTY+VXtMnTpwY9dNUnaY2TjUFxaejbLXVVhb7NIkjjjjCYk0X/ctf/hL1+9e//mVx2v2IHte0ipU63tq0aRP103T1zp07R22zZs2yWO/VPvjgg8R9akr3T3qubdeuXdS2zz77WKxjxVcMSvssS+G/B5rGo2ltpVb0a8p0rN98881R25FHHmlx2u9W5ftpSvnXvva1qO2f//ynxYMHD7bYXxf1NZvqMc2aTuw//7Q086T7nrT7o6y/mbJWs82KmTYAAAAAAAA5xEMbAAAAAACAHOKhDQAAAAAAQA5VZE0bn0umJX01N1Tz8UOI10fxeV+6tonm8K5cuTLqp7nEmmvqc5M199fnrWlfzeH98MMPo35aPlpLZPrXLEK5aP1clZa2DCFeS+a1116L2qZNm2bxq6++anFaqUs9Fq1atYr69erVK3F/9TvXVNcqqU9STmZaznwp6yyk8ecHXYvDH+OpU6darGW+09a0KYeif0/037fFFltYfOmll0b9dHynfSd0nPp1ca6++mqLNVd8xowZUb+ir5dQ6ndKx4teB0MIoXfv3hb36dPH4pdffjnqp+toaDlwvw9Z14bS460lpkOI1z7y10zdD13voQjjK+v5NOvfZf1M/L3N4YcfbrGuW+PpehhpuftNga5xoPH2228f9fvud79r8WGHHRa16XHUEup+TZv333/fYv3cy3F+8GPxuOOOs1ivsyGEMGrUKIuXLFlisZ4fQkhfQ7IxvyflWBvK0/XdDjnkEItvuummqJ+e43QNxuuuuy7qp5+xHvcQsq9tkbbOmK5jk7R2aAhrju+i8WuUJK2B6r8Xej09//zzLT7llFMS3yutrLuOHd9PfyPqdTCEuMx32v42pfNy0ho0/h5InyNsu+22Fh9//PFRPx3Pfi3WefPmWfzcc89Z/MILL0T9kp4vhBDf62ibfzaQdv+VBTNtAAAAAAAAcoiHNgAAAAAAADlUtvQonY7m05622WYbi3VaoS+jp21aqjCEELp06WKxTuv1Uw516pG+/nbbbRf106lXviyfTm3Sfu+++27U7/HHH7f4mWeeido0dUqnyfkpnWkl3PI0FU73Radk+lKhkydPttj/W7VUeNYSr5oK51M3OnXqZLFPk1PlLrdaFFnL15Wbn5qoaW6+fLCm0OiYqvR036KXU9RxdeONN1rcs2fPqF9S2Vn/+Ws/n+J2zDHHWKzH+pe//GXUb8yYMRb7c3KtTu/OmhaT9t91yr6Wmg0hhB/+8If1voZPydApulnPc2n7rtfgXXfdNWrT0sJ6PQghvoaWuxxuYyulHKj/u1L4+63u3btb7NMkPvroI4ufeuopi/2xKPq10H8uOv1er0E+pWiPPfaw2H/ub7/9tsVatnfZsmVRv6RrS0M+86Q0urZt20b9dthhB4v9OVSn869ataqk/ah1PrVQSzE/+uijFmu55hDiY6jnuwsuuCDqt9dee1n8xBNPRG1vvPGGxfqbI+13gG/zqWxfasjvjFql95H6+9BbsGCBxf7frvc7ml6safkhxOlMd9xxR2Kb3lf5c4f+vvWpNTNnzrS4qY7FtPsefR5wwAEHRP369+9vsaaL+1RRn1aldHzr/euAAQOifvpbXpdrCCG+nmp6un9uoK9BehQAAAAAAEBB8NAGAAAAAAAgh3hoAwAAAAAAkENlW9NGcyb9uhSbb755vW0+J1hz/jSfLYQ49zSpxJrvp6/vc5h1TRWfv6j5+pojp+XEQoj/XbNmzYraJkyYEOpTaonVPFmxYoXF/nNNKrUXQmnrUmj5YF0byb+3//y1VJse61r5jPMk63o3aZ+tvobPu99vv/0s9t8nzQfVtZRKlfXfkqfSpuXgP9dvf/vbFp900kmJ/ZSOX10bw/+dL7+pucQ6hq+88sqo384772zxI488ErXNmTPH4lrKyU/7PJPWQNG8+BDiNUrOOuusqE1z8qdMmWLx/Pnzo35Zz71Jaxj5fWzZsqXFug5ECHEJeX991uviupa+LIq0UuFZ/qZNmzZR21ZbbWWxHytanvjPf/6zxbW6ZlS56H2jnq90Da4Q4nUS/Xoob731lsU6/ipxvtJxqvehBx98cNRP12d49dVXo7Zp06ZZrGsC+mtf2j1dLdLPzo+dG264wWK/jo3SNUm0DLD/7XPiiSdarPeyIYTw4IMPWvyHP/zBYr8GUtpvhLSS8aqaaxZWil+T5OSTT7bYr3MyduxYi5999lmLdV3EEOL1aLRcuy/Xrb8v/Ho0SdfxxYsXJ76Xvy/QceXfu8j089Lf3SHE5zK97/HPDfQ1dG02vdaFEJ8ntcR3CPHamfr7RNcw86+haw+FEJ8H9Fxb7rVqmWkDAAAAAACQQzy0AQAAAAAAyKGypUfpFCA/1Vantuv0JV+ue/r06Rb76WM6JS2pVGEI8RQrnYrvpzpqSpSfKqV/d/fdd1us0/dDiEuK+WmWuv+lTH/Om6Tp02nTZUv9t2pq3J133mmxn46sx/4HP/hB1KZl/rKWYq3VY9MQWb+L2i8tBS7rtHpNmdEymCHEKYg6ZTuEuEx8qccnqeR7WvpHEaaBKy1LGkJc5tuPK6Wfg07v9VPtNaXHp7/ptOZOnTpZrOmwIYRwyimnWOzH6e23326xjvu8p3Xo5+fTxpK+l/5ate+++1qsJXw9LfOt4yaE5LHTkLGt+7/nnnta7MuQa9rTiBEjojZNrW0K59svpZ1PVdZ0aT0WxxxzTNTm70XUmDFjLC5HyfUi3NuEEP87tJRwjx49on56b+LTGHTM6dhJO95p0j5PTcO5+OKLLT788MOjfu+8847FzzzzTNSm90j6byn3dP5KSbt+p93n6djx51O9Jukx9L9VtLyvpmEcffTRUT89l2+88cZRm6Z/pKXwZJV2n1ur9zP67+jatWvUdtxxx1ncoUOHqO2f//ynxToufWpT0jIZ/tqn22njIe38nXZ8ipC+loX/d+qYOOSQQ6K2a665xmJNS3r99dejfsOGDbN40qRJFmvKZwjx5+/vj/T+9cILL7TYp37r+d8v16BLOej5wqeIrytm2gAAAAAAAOQQD20AAAAAAAByqGzpUcpPu9VpSatXr7bYpyXpFE0/jU2nGKVNidepqLoitKfv5aexaZtO5/JpBFpBZe7cuVGbTkesxQpRWZXj3+OnzJ166qkWayUMf9wfe+wxiydOnBi16eefNjW9aMdjbZKmaPpjoJ+T/95nnSqqr6nTIAcOHBj103QanbIdQpxOkVVTrRDl6TTw73znO1GbVvhRfhq1VmE477zzLPbHxa/8r7bbbjuLtZqGnw6rU5yPOOKIqE2ra+iU/7wfQ51O66fJ6r5rCplWqAkhTtHwlaU0Ze3pp5+2OGuFCy9tGr2+tx6fjh07Rv1mzpxpsX5/Qlgznbm+/atVaedT3fZpcqWcT3W6+BlnnBH10++cnyKu35FSUwuLMJU/rQqPXu/8eNN+/vPTY9KtWzeLfTUgHWM6xV5TNfzr62uHEML1119vsabk+OM9ePBgi1955ZWoTd87a1pHnmVN1dPx51NR9dqyaNEii6+++uqo34svvmixplj59CjdD59OoefCSlc41fu5WkqV0rG42267RW26PIVPX9PKePqb0//bk34nVEIplQFrZeylSauMqWPnl7/8ZdSm51C93/RpnnpvmHR/sTb6G0QrkfmKZcq/l96L6RIuPo2W6lEAAAAAAAAFxEMbAAAAAACAHOKhDQAAAAAAQA6VbU0bzdPyeYOaX5+W46l/V2oeWNJ+NKT8mpb901K5fn9Hjx5tsebChpD/UrSNTT/znXbaKWq74oor6v0bv27QddddZ3HWdY78mjalHKe8r6NRDn7dBZU2rpR+TrpeSZ8+fRJfz+fd67pRabKW+9TjX/Qx2qpVK4tPOOGExH661srLL78ctWmOvubwNqRkpZZC1Lx0X6pY1z3SfPUQQujbt6/Fc+bMsTjvx1CvGWnltXUdEr/ekF6DNFc6hLhUrJ4fs65b0JD1DfSYaJlvv36Olvn269YlnTvSvj+1cn5N20899r5f1vOpru+g5YL1++HpuhwhxCVRs0o7NkVZf0GPj56H/PjQ8axlt0MIYZdddrH48ssvt9iPZ12/5K233rJ48uTJUT+9Bz7nnHOitt13372ef0UI48aNi7aHDh1qsT93ZFUr66EkrU+Sdq3y61Lo+XTkyJEW+zLD+ploKWq/vpf28/cyeh3TfpVYWyXPxy2Nfi577rln1NayZUuLtcR3CCEsXLjQ4rR/e9JaTtVe3yZp3c1aXV9KJa3dF0IIp512msW+pHvSeoD+PKn3gGnjSLc33XTTqO2nP/2pxb169Up8Dd0PPXeHEK9pk7Zm7rpipg0AAAAAAEAO8dAGAAAAAAAghypS8tunESmdKuSntmedJpxV1lLbvqTx2WefbbGWsvXpOb/97W8t9tMss5bxbEp06tqWW25p8e233x71a926tcWLFy+2+IEHHoj6+anfSe9V6emGtTJ92NN/e1rqRqnpYPqaPXv2tNiX/ZsxY4bFw4cPj9p0OmKpx0r3v5aOT0P546Rph36Kvp6jNbVTS3KHsGYJ2S815Fho+szbb79tsZ8u3qJFC4v9cdKp0LWUkpF2Dcr6vdTrk09Fev755y32KcVZ9imNvy4eeeSRFmvqnR7TEEJ47LHHLPbHOOnfmTaVOe/HuD4NmV6f9O/zr6FTyw899FCL/blbvyP33Xdf1LZ8+fK1vu/a1PqxqY+OHf38dMp7CCFstdVWFut9SgjxeNlrr70s1nT7EOLjtXTpUov33nvvqJ+mFPvUAU1f1nK49957b9Tvgw8+sNiPvaz3SLUubRxpKlwIcRqU3l/6e5Ztt93W4rPOOstiLR0cQvo5WVOp9Lu0YMGCqF/eU4ArSa8zafeoPvWv1u7z0pYXKRI9niGE0Lt3b4s1HcrTtmOPPTZq0zGs3xGfvrr55ptbfOqpp0Zt/fr1s1jP4/r7I4T4XvnJJ5+M2nTcVvIYMtMGAAAAAAAgh3hoAwAAAAAAkEMVSY/y0yuTUoX8FKJSpmVmrXKTNv3aVy/SFAHdJ11ZPoQQpk6danHWqeleEacaf8lPZ+zSpYvFt912m8U6RS6EOHVDV/B/4oknon5Jq4aHEH8vtK3UqmTKpw2ookxt1M82a3qU76dTGnWM+amsjz/+uMVLliwp6b3SZH2NWh9//ly46667WqypRyHEaSv/93//Z/F7771X9v3SzzmtGlhSikII8TR/5cd9nsefP2/o8Uq7fqxevdritKnypVxL/BjQfdIUgBDiKcX6b3n11VejfpoulfbvKkcKZq0o5Xzq6RjW1Ao/VqZPn27xkCFDorZS71NU0Y5NCPHx0XPUtGnTon6aWuPPPTomdt55Z4u1Yp7/uzfffNNiPxV/m222sTitismwYcMs9tX/sqbpp1VVzPM5NQt/nHR7s802i9r0M99+++0t9mkdBx10kMV6rP01WM/d/hqsFREHDhxosU9x0/Np1vN/LVfj033XtLQ99tgj6qfHUe91Qoh/a8ycOdPirFWbfJUj/Tt/vi33sh76HfJjrxZT5dK+i3q/qWMlhPj3g6ZA+fSoI444wmKtzOdpepSv8pZ0L+YrRN10000Wjxo1KmrTNFXSowAAAAAAAJoYHtoAAAAAAADkEA9tAAAAAAAAcqgia9qk5WxnLcOdRvPPfMm+rCWCtRzYeeedF7Vp7puWnH7kkUeifpqDV+q/Je/5pevC5/BeccUVFh9yyCEW+zzNl156yWJdb2PevHlRv7T8zqQc7Yaso5SU7+r/Jm1dpVpRag5m0mcUQght2rSx+IADDrDY551OmjTJYl3PqNT9yKoIY0//3T4Pu3v37hb7tSx03YZZs2bV+3r1bTd0n0KIz7Va1tafu5UvNT5//nyLa7U8Ztb1Xfy6Tjom/HdW10XQ8sTLli2L+unnpGtvaCn1EOI1Hs4444yobYcddrBYz6kzZsyI+vmc/yRFGH9J/L8t7d+a1ObPp+3atbO4c+fOFqeVgdf7lzSljPNalnY8Vq1aZfHkyZOjNl0fw6/Ppdc1HWNp65zoOUHP1yHE66jss88+UZveC11//fUW67oKIWQfY2nrcuR13cVyrIPl10rbbrvtLB4wYIDF+psghHhs6mfnP38df34862sedthhFmup8RBC+M1vfpP4+vre/vWT+uVd0po2ulZXCCHsuOOOFvfo0SNq0zExZswYi/35cN9997VY1zDSc20I8T2SX1tT16WaO3euxf78kHXtG20r2nnZj7df//rXFr///vtRW/v27ev9O3/fqMdKx5S/t9E2/7nqeVjLel900UVRv7///e8W++uuvkYlz5PMtAEAAAAAAMghHtoAAAAAAADkUFVKfpcjJUqn/mkpMD/1NCm9wpdb1TKMWr4vhLgk8VNPPWWxToMLIV9TRfNCj5OmQIUQwkknnWSxTntcsGBB1O/aa6+1eOLEiRY3pFx3UkpB1nSoEOLvlk89UbpftVSCWPnPJet+J01lDSGEXXbZpd7Yp3/Mnj3bYp/yljRVNC2Np5R9X1tbLRxH//lryea0EpY69dT/u5OmXKeNI78fffr0sVjPAX76qo5Zn5agU1bLUba4MfjvkG7rv8lPIX7jjTcs9mW49fPcfffdLfalfzV1Q9Mu/PHWqfkHHnhg1KbfIX09TRkJoTxjpdavraXuf1q646GHHmrx1ltvbbFPN50yZUpiW9J7lXo+rdXjlJZao+lRaVPg065VafccSZ+ZnuNCiMvhLl26NGp7+OGHLdbUjVLHXjnu0autlNSvEOIlFPTeI4Q103K/5K85Oq70uI0fPz7qp9cxTfcIIU4Z1/G81157Rf1eeeUViydMmBC16fczLa0mrylu9dHfd/pbTH8LhBDC/vvvb7F+fiGE8PWvf91i/X3nfy9qqk1aqW1Nndpvv/2iNu2rZaAvv/zyqN+7775rcdox0PNKEdKj9PPRc2sI8ec1duzYqC0pDd7/ltdUYT3up512WtSvdevWFvvrov4Gvfjiiy3W1LoQ1ixLnrS/pEcBAAAAAAA0MTy0AQAAAAAAyCEe2gAAAAAAAORQRda08cqR36W5fZrzp/mpvk35Em6XXnqpxVqSNoQQRo8ebfHNN99ssS/hlvfc0HVRajlFLav2k5/8JGrTz1nXr7jzzjujfpoXrMe3IXm6WXO7k9ZKCiGETTfd1GLNffXrfOg6ELWw9kkWWY+3HgOfa6plSrWU8FtvvRX10zKMWdccKke5z1opbZqVL4WoJdf9sdF/n+bx++9v1s9B88G7desWtf3qV7+yuGvXrhb7Y6hlqh9//PGoTddBqtUx5v+9eq3Sz9mXdf3HP/5hcYcOHaI2LfmtJYPbtm0b9WvevLnFumbO8OHDo37Lly+32F/vkq67fn9LUYvjrRL02qLjN4QQBg0aZLFeS31+vpZ+T7of8hpyPi3CsUr7N6StW5M0Zkt9L/3cu3TpErXpGlV+LA4dOtTipHUc097L71etnlNLoePl7bffjtpuueUWi3U9Cz8Wp02bZrGWKvZr4mibX+tN1yo7+eSTLfa/abbcckuLp06dGrVpX/3e1vLxTPo++zVPdE28o48+OmrTNW703tPfB5WyZp+ujRJC/Lvh2GOPtVjHaAghDBs2zOKs91lFO9emnU/99z6J/37oulR6D+nXTFTaL4S49Pjf/vY3i/P4m5+ZNgAAAAAAADnEQxsAAAAAAIAcatT0qIaUM9PXyDoNUKetaWnUEELo2bOnxTpNMYQQrrjiCovnz5+f6b2KppS0iBBCGDBggMU777xz1KZTEbX020svvZT43vo3fnqpbvtSbEnlD/3+ajqXpvOEEELHjh0t1mmuOjXWv6afbpuH6XTV4qcj9u/f32JN3dHShyEkl9kMIT0lal2lTRevleOm++mn/mpKjP/e67TUtOnXOhVVPy997RBC6NWrl8V33HFHYpuOZz9V9sUXX7R43LhxiftRq9LS8fSz8GWGJ02aZLFej0IIYauttrJYp21rWe8Q4rQqLQmt5WT9Pvqy4XvuuWe9+6tlWbFudHz06NEjatP0Gf3uaOpgCPEYTpuGn5YOWkp6rFcr59AQklOFKv1v0OviZZddFrXp8X7++eejNi1RW0ufc2Pw31E9vr6U95w5cyyeN2+exT6NRq+1+jvDpyqmXbc03UevkT69WF/fp0DrfakqdTzngR4fTZnR0vYhhPDggw9a/Mwzz0Rtmh6l18jDDz886tenTx+LdTkEf2+ix6BFixZRm343NG3V/54YMWJE4uvX0vFpbH4869i58sorLfbjSFOdNFUthBB+85vf1Nsvj8eFmTYAAAAAAAA5xEMbAAAAAACAHKpKelSStOniaX1LWY3/7LPPjvppas0999wTtelq1E0pJaoUPu1CpwRutNFGmf5OU6pCiKeY6jTU3r17R/106uSECROiNq2Q0r59e4sPOeSQqN/+++9vcefOnaO2yZMnWzxq1CiL/fRITS/xlZEag362WauHlErH20477RS17bHHHhbrePPpZXoc08a2jsWGpDaVO60qr3yamaYg+pX59Xho5Yotttgi6qeVgbbbbjuLDzzwwKjfvvvua7FWawghnj6sx9CPlUsuucRiHb9FlfRd99ccTZdauHBh1KaV6/SY+nOUtmmFKD+dX4+VrwqlqQT6d76aRq1XYfMq/e9JSt/VFO4Q4uupjmetdhlC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\n", + "text/plain": [ + "<Figure size 1440x288 with 20 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" } ], "source": [ - "import matplotlib.pyplot as plt\n", "n = 10 # how many digits we will display\n", "plt.figure(figsize=(20, 4))\n", "for i in range(n):\n", diff --git a/Scripts/Notebooks/SmokeyConvNb.ipynb b/Scripts/Notebooks/SmokeyConvNb.ipynb index 4e0f4567d4f198641de0f22da94fbe3e81c400a4..a9454f01c5d46935502413a19b97db218a351783 100644 --- a/Scripts/Notebooks/SmokeyConvNb.ipynb +++ b/Scripts/Notebooks/SmokeyConvNb.ipynb @@ -2,28 +2,9 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": 28, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:517: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", - " _np_qint8 = np.dtype([(\"qint8\", np.int8, 1)])\n", - "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:518: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", - " _np_quint8 = np.dtype([(\"quint8\", np.uint8, 1)])\n", - "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:519: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", - " _np_qint16 = np.dtype([(\"qint16\", np.int16, 1)])\n", - "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:520: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", - " _np_quint16 = np.dtype([(\"quint16\", np.uint16, 1)])\n", - "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:521: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", - " _np_qint32 = np.dtype([(\"qint32\", np.int32, 1)])\n", - "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:526: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", - " np_resource = np.dtype([(\"resource\", np.ubyte, 1)])\n" - ] - } - ], + "outputs": [], "source": [ "import time\n", "import os\n", @@ -41,7 +22,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 29, "metadata": {}, "outputs": [], "source": [ @@ -51,7 +32,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 30, "metadata": {}, "outputs": [], "source": [ @@ -60,7 +41,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 31, "metadata": {}, "outputs": [], "source": [ @@ -81,7 +62,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 32, "metadata": {}, "outputs": [], "source": [ @@ -93,7 +74,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 33, "metadata": {}, "outputs": [ { @@ -102,7 +83,7 @@ "(1100, 64, 64, 1)" ] }, - "execution_count": 6, + "execution_count": 33, "metadata": {}, "output_type": "execute_result" } @@ -114,7 +95,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 34, "metadata": {}, "outputs": [ { @@ -137,17 +118,9 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 35, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Using TensorFlow backend.\n" - ] - } - ], + "outputs": [], "source": [ "from keras.layers import Input, Dense, Conv2D, MaxPooling2D, UpSampling2D\n", "from keras.models import Model, Sequential\n", @@ -156,7 +129,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 36, "metadata": {}, "outputs": [], "source": [ @@ -166,7 +139,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 37, "metadata": {}, "outputs": [ { @@ -185,7 +158,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 38, "metadata": {}, "outputs": [], "source": [ @@ -194,35 +167,41 @@ }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 42, "metadata": {}, "outputs": [], "source": [ "l0 = Conv2D(filters = 16, kernel_size = (2, 2), activation = \"relu\", padding = \"same\")(input_img)\n", "l1 = MaxPooling2D((2, 2), padding = \"same\")(l0)\n", - "l2 = Conv2D(filters = 8, kernel_size = (2, 2), activation = \"relu\", padding = \"same\")(l1)\n", - "l3 = MaxPooling2D((2, 2), padding = \"same\")(l2)\n", - "l4 = Conv2D(filters = 8, kernel_size = (2, 2), activation = \"relu\", padding=\"same\")(l3)\n", - "encoded = MaxPooling2D((2, 2), padding = \"same\")(l4)" + "l2 = Conv2D(filters = 32, kernel_size = (2, 2), activation = \"relu\", padding = \"same\")(l1)\n", + "# l3 = MaxPooling2D((2, 2), padding = \"same\")(l2)\n", + "l4 = Conv2D(filters = 64, kernel_size = (2, 2), activation = \"relu\", padding = \"same\")(l2)\n", + "# l5 = MaxPooling2D((2, 2), padding = \"same\")(l4)\n", + "l6 = Conv2D(filters = 128, kernel_size = (2, 2), activation = \"relu\", padding=\"same\")(l4)\n", + "encoded = MaxPooling2D((2, 2), padding = \"same\")(l6)" ] }, { "cell_type": "code", - "execution_count": 23, + "execution_count": 46, "metadata": {}, "outputs": [], "source": [ - "l5 = Conv2D(filters = 8, kernel_size = (2, 2), activation = \"relu\", padding = \"same\")(encoded)\n", - "l6 = UpSampling2D((2, 2))(l5)\n", - "l7 = Conv2D(filters = 8, kernel_size = (2, 2), activation = \"relu\", padding = \"same\")(l6)\n", - "l8 = UpSampling2D((2, 2))(l7)\n", - "l9 = Conv2D(filters = 16, kernel_size = (2, 2), activation = \"relu\")(l8)\n", - "decoded = Conv2D(filters = 1, kernel_size = (2, 2), activation = \"sigmoid\", padding = \"same\")(l9)" + "l7 = Conv2D(filters = 128, kernel_size = (2, 2), activation = \"relu\", padding = \"same\")(encoded)\n", + "# l8 = UpSampling2D((2, 2))(l7)\n", + "l9 = Conv2D(filters = 64, kernel_size = (2, 2), activation = \"relu\", padding = \"same\")(l7)\n", + "# l10 = UpSampling2D((2, 2))(l9)\n", + "l11 = Conv2D(filters = 32, kernel_size = (2, 2), activation = \"relu\", padding = \"same\")(l9)\n", + "l12 = UpSampling2D((2, 2))(l11)\n", + "l13 = Conv2D(filters = 16, kernel_size = (2, 2), activation = \"relu\", padding = \"same\")(l12)\n", + "l10 = UpSampling2D((2, 2))(l13)\n", + "l14 = Conv2D(filters = 8, kernel_size = (2, 2), activation = \"relu\", padding = \"same\")(l10)\n", + "decoded = Conv2D(filters = 1, kernel_size = (2, 2), activation = \"sigmoid\", padding = \"same\")(l14)" ] }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 47, "metadata": {}, "outputs": [], "source": [ @@ -232,39 +211,266 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 48, "metadata": {}, - "outputs": [], - "source": [] + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "_________________________________________________________________\n", + "Layer (type) Output Shape Param # \n", + "=================================================================\n", + "input_2 (InputLayer) (None, 64, 64, 1) 0 \n", + "_________________________________________________________________\n", + "conv2d_24 (Conv2D) (None, 64, 64, 16) 80 \n", + "_________________________________________________________________\n", + "max_pooling2d_6 (MaxPooling2 (None, 32, 32, 16) 0 \n", + "_________________________________________________________________\n", + "conv2d_25 (Conv2D) (None, 32, 32, 32) 2080 \n", + "_________________________________________________________________\n", + "conv2d_26 (Conv2D) (None, 32, 32, 64) 8256 \n", + "_________________________________________________________________\n", + "conv2d_27 (Conv2D) (None, 32, 32, 128) 32896 \n", + "_________________________________________________________________\n", + "max_pooling2d_7 (MaxPooling2 (None, 16, 16, 128) 0 \n", + "_________________________________________________________________\n", + "conv2d_34 (Conv2D) (None, 16, 16, 128) 65664 \n", + "_________________________________________________________________\n", + "conv2d_35 (Conv2D) (None, 16, 16, 64) 32832 \n", + "_________________________________________________________________\n", + "conv2d_36 (Conv2D) (None, 16, 16, 32) 8224 \n", + "_________________________________________________________________\n", + "up_sampling2d_9 (UpSampling2 (None, 32, 32, 32) 0 \n", + "_________________________________________________________________\n", + "conv2d_37 (Conv2D) (None, 32, 32, 16) 2064 \n", + "_________________________________________________________________\n", + "up_sampling2d_10 (UpSampling (None, 64, 64, 16) 0 \n", + "_________________________________________________________________\n", + "conv2d_38 (Conv2D) (None, 64, 64, 8) 520 \n", + "_________________________________________________________________\n", + "conv2d_39 (Conv2D) (None, 64, 64, 1) 33 \n", + "=================================================================\n", + "Total params: 152,649\n", + "Trainable params: 152,649\n", + "Non-trainable params: 0\n", + "_________________________________________________________________\n" + ] + } + ], + "source": [ + "autoencoder.summary()" + ] }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 49, "metadata": {}, "outputs": [ { - "ename": "ValueError", - "evalue": "Error when checking target: expected conv2d_7 to have shape (31, 31, 1) but got array with shape (64, 64, 1)", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m<ipython-input-15-8ab6529663e8>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0mbatch_size\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m64\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0;36m64\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mshuffle\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 5\u001b[0;31m validation_data = (vali_data, vali_data))\n\u001b[0m", - "\u001b[0;32m~/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/keras/engine/training.py\u001b[0m in \u001b[0;36mfit\u001b[0;34m(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, **kwargs)\u001b[0m\n\u001b[1;32m 1628\u001b[0m \u001b[0msample_weight\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0msample_weight\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1629\u001b[0m \u001b[0mclass_weight\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mclass_weight\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1630\u001b[0;31m batch_size=batch_size)\n\u001b[0m\u001b[1;32m 1631\u001b[0m \u001b[0;31m# Prepare validation data.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1632\u001b[0m \u001b[0mdo_validation\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/keras/engine/training.py\u001b[0m in \u001b[0;36m_standardize_user_data\u001b[0;34m(self, x, y, sample_weight, class_weight, check_array_lengths, batch_size)\u001b[0m\n\u001b[1;32m 1478\u001b[0m \u001b[0moutput_shapes\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1479\u001b[0m \u001b[0mcheck_batch_axis\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1480\u001b[0;31m exception_prefix='target')\n\u001b[0m\u001b[1;32m 1481\u001b[0m sample_weights = _standardize_sample_weights(sample_weight,\n\u001b[1;32m 1482\u001b[0m self._feed_output_names)\n", - "\u001b[0;32m~/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/keras/engine/training.py\u001b[0m in \u001b[0;36m_standardize_input_data\u001b[0;34m(data, names, shapes, check_batch_axis, exception_prefix)\u001b[0m\n\u001b[1;32m 121\u001b[0m \u001b[0;34m': expected '\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mnames\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m' to have shape '\u001b[0m \u001b[0;34m+\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 122\u001b[0m \u001b[0mstr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mshape\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;34m' but got array with shape '\u001b[0m \u001b[0;34m+\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 123\u001b[0;31m str(data_shape))\n\u001b[0m\u001b[1;32m 124\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mdata\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 125\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mValueError\u001b[0m: Error when checking target: expected conv2d_7 to have shape (31, 31, 1) but got array with shape (64, 64, 1)" + "name": "stdout", + "output_type": "stream", + "text": [ + "Train on 990 samples, validate on 110 samples\n", + "Epoch 1/50\n", + "990/990 [==============================] - 9s 9ms/step - loss: 0.6835 - val_loss: 0.6546\n", + "Epoch 2/50\n", + "990/990 [==============================] - 8s 8ms/step - loss: 0.6167 - val_loss: 0.4751\n", + "Epoch 3/50\n", + "990/990 [==============================] - 8s 8ms/step - loss: 0.3230 - val_loss: 0.2221\n", + "Epoch 4/50\n", + "990/990 [==============================] - 8s 9ms/step - loss: 0.1818 - val_loss: 0.2110\n", + "Epoch 5/50\n", + "990/990 [==============================] - 8s 9ms/step - loss: 0.1722 - val_loss: 0.2016\n", + "Epoch 6/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.1633 - val_loss: 0.1927\n", + "Epoch 7/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.1551 - val_loss: 0.1842\n", + "Epoch 8/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.1476 - val_loss: 0.1765\n", + "Epoch 9/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.1404 - val_loss: 0.1690\n", + "Epoch 10/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.1336 - val_loss: 0.1621\n", + "Epoch 11/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.1273 - val_loss: 0.1539\n", + "Epoch 12/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.1241 - val_loss: 0.1681\n", + "Epoch 13/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.1295 - val_loss: 0.1494\n", + "Epoch 14/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.1236 - val_loss: 0.1540\n", + "Epoch 15/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.1170 - val_loss: 0.1398\n", + "Epoch 16/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.1166 - val_loss: 0.1500\n", + "Epoch 17/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.1133 - val_loss: 0.1336\n", + "Epoch 18/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.1125 - val_loss: 0.1417\n", + "Epoch 19/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.1077 - val_loss: 0.1262\n", + "Epoch 20/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.1070 - val_loss: 0.1340\n", + "Epoch 21/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.1030 - val_loss: 0.1204\n", + "Epoch 22/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.1029 - val_loss: 0.1291\n", + "Epoch 23/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.0992 - val_loss: 0.1152\n", + "Epoch 24/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.0986 - val_loss: 0.1218\n", + "Epoch 25/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.0948 - val_loss: 0.1106\n", + "Epoch 26/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.0943 - val_loss: 0.1154\n", + "Epoch 27/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.0915 - val_loss: 0.1076\n", + "Epoch 28/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.0919 - val_loss: 0.1120\n", + "Epoch 29/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.0889 - val_loss: 0.1049\n", + "Epoch 30/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.0892 - val_loss: 0.1090\n", + "Epoch 31/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.0869 - val_loss: 0.1030\n", + "Epoch 32/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.0875 - val_loss: 0.1067\n", + "Epoch 33/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.0850 - val_loss: 0.1013\n", + "Epoch 34/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.0858 - val_loss: 0.1046\n", + "Epoch 35/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.0834 - val_loss: 0.0998\n", + "Epoch 36/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.0843 - val_loss: 0.1040\n", + "Epoch 37/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.0824 - val_loss: 0.0989\n", + "Epoch 38/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.0833 - val_loss: 0.1021\n", + "Epoch 39/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.0808 - val_loss: 0.0973\n", + "Epoch 40/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.0812 - val_loss: 0.0998\n", + "Epoch 41/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.0792 - val_loss: 0.0962\n", + "Epoch 42/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.0799 - val_loss: 0.0991\n", + "Epoch 43/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.0783 - val_loss: 0.0954\n", + "Epoch 44/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.0789 - val_loss: 0.0977\n", + "Epoch 45/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.0772 - val_loss: 0.0941\n", + "Epoch 46/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.0775 - val_loss: 0.0962\n", + "Epoch 47/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.0759 - val_loss: 0.0930\n", + "Epoch 48/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.0762 - val_loss: 0.0951\n", + "Epoch 49/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.0750 - val_loss: 0.0921\n", + "Epoch 50/50\n", + "990/990 [==============================] - 7s 7ms/step - loss: 0.0752 - val_loss: 0.0942\n" ] + }, + { + "data": { + "text/plain": [ + "<keras.callbacks.History at 0x7f8e036ea198>" + ] + }, + "execution_count": 49, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ "autoencoder.fit(densities, densities,\n", - " epochs = 500,\n", - " batch_size = 64 * 64,\n", - " shuffle = True,\n", + " epochs = 50,\n", + " batch_size = 330,\n", + " shuffle = False,\n", " validation_data = (vali_data, vali_data))" ] }, + { + "cell_type": "code", + "execution_count": 50, + "metadata": {}, + "outputs": [], + "source": [ + "decoded_imgs = autoencoder.predict(vali_data)" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 720x144 with 20 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "n = 10 # Number of frames to display\n", + "\n", + "plt.figure(figsize = (10, 2))\n", + "\n", + "for i in range(n):\n", + " \n", + " ax = plt.subplot(2, n, i + 1)\n", + " plt.imshow(vali_data[i].reshape(64, 64))\n", + " plt.gray()\n", + " ax.get_xaxis().set_visible(False)\n", + " ax.get_yaxis().set_visible(False)\n", + " \n", + " ax = plt.subplot(2, n, i + 1 + n)\n", + " plt.imshow(decoded_imgs[i].reshape(64, 64))\n", + " plt.gray()\n", + " ax.get_xaxis().set_visible(False)\n", + " ax.get_yaxis().set_visible(False)\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/ipykernel_launcher.py:5: DeprecationWarning: `toimage` is deprecated!\n", + "`toimage` is deprecated in SciPy 1.0.0, and will be removed in 1.2.0.\n", + "Use Pillow's ``Image.fromarray`` directly instead.\n", + " \"\"\"\n", + "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/ipykernel_launcher.py:6: DeprecationWarning: `toimage` is deprecated!\n", + "`toimage` is deprecated in SciPy 1.0.0, and will be removed in 1.2.0.\n", + "Use Pillow's ``Image.fromarray`` directly instead.\n", + " \n" + ] + } + ], + "source": [ + "out_dir = \"%s/test_simple\" % base_path\n", + "if not os.path.exists(out_dir): os.makedirs(out_dir)\n", + "\n", + "for i in range(len(vali_data)):\n", + " scipy.misc.toimage(np.reshape(vali_data[i], [64, 64])).save(\"%s/in_%d.png\" % (out_dir, i))\n", + " scipy.misc.toimage(np.reshape(decoded_imgs[i], [64, 64]),).save(\"%s/out_%d.png\" % (out_dir, i))" + ] + }, { "cell_type": "code", "execution_count": null, diff --git a/Scripts/Notebooks/SmokeyDeepNb.ipynb b/Scripts/Notebooks/SmokeyDeepNb.ipynb index 524ab842cb769ef6b31e4525cc2ff94eb9cd3659..dc999f3287a307d71aae87151b7bea57118e288a 100644 --- a/Scripts/Notebooks/SmokeyDeepNb.ipynb +++ b/Scripts/Notebooks/SmokeyDeepNb.ipynb @@ -588,13 +588,7 @@ "990/990 [==============================] - 1s 1ms/step - loss: 0.0759 - val_loss: 0.1066\n", "Epoch 159/200\n", "990/990 [==============================] - 1s 1ms/step - loss: 0.0756 - val_loss: 0.1077\n", - "Epoch 160/200\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ + "Epoch 160/200\n", "990/990 [==============================] - 1s 1ms/step - loss: 0.0755 - val_loss: 0.1069\n", "Epoch 161/200\n", "990/990 [==============================] - 1s 1ms/step - loss: 0.0753 - val_loss: 0.1095\n", diff --git a/Scripts/Notebooks/SmokeyPruebasNb.ipynb b/Scripts/Notebooks/SmokeyPruebasNb.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..0d0e9c5f63ed7c2698104b8a2a85d88687140fcc --- /dev/null +++ b/Scripts/Notebooks/SmokeyPruebasNb.ipynb @@ -0,0 +1,794 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Autoencoder" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Importamos las bibliotecas necesarias" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:517: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_qint8 = np.dtype([(\"qint8\", np.int8, 1)])\n", + "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:518: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_quint8 = np.dtype([(\"quint8\", np.uint8, 1)])\n", + "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:519: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_qint16 = np.dtype([(\"qint16\", np.int16, 1)])\n", + "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:520: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_quint16 = np.dtype([(\"quint16\", np.uint16, 1)])\n", + "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:521: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " _np_qint32 = np.dtype([(\"qint32\", np.int32, 1)])\n", + "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/framework/dtypes.py:526: FutureWarning: Passing (type, 1) or '1type' as a synonym of type is deprecated; in a future version of numpy, it will be understood as (type, (1,)) / '(1,)type'.\n", + " np_resource = np.dtype([(\"resource\", np.ubyte, 1)])\n" + ] + } + ], + "source": [ + "import time\n", + "import os\n", + "import shutil\n", + "import sys\n", + "import math\n", + "import random\n", + "import tensorflow as tf\n", + "import numpy as np\n", + "import scipy.misc\n", + "import matplotlib.pyplot as plt\n", + "sys.path.append(\"../tools\") # Herramientas propias de MantaFlow\n", + "import uniio # Biblioteca para la lectura de ficheros .uni" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Inicializamos las seed para funciones random. Al ser inicializadas al mismo número, el resultado no cambiará en cada ejecución." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "np.random.seed(13)\n", + "tf.set_random_seed(13)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Ruta a los datos de simulación, donde también se guardan los resultados." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "base_path = \"../data\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Carga de datos de simulación" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Cargamos los datos desde los ficheros .uni en arrays de numpy." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "densities = []" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "for sim in range(1000, 2000):\n", + " if os.path.exists(\"%s/simSimple_%04d\" % (base_path, sim)): # Comprueba la existencia de las carpetas (cada una 100 frames de datos)\n", + " for i in range(0, 100):\n", + " filename = \"%s/simSimple_%04d/density_%04d.uni\" # Nombre de cada frame (densidad)\n", + " uni_path = filename % (base_path, sim, i) # 100 frames por sim, rellena parametros de la ruta\n", + " header, content = uniio.readUni(uni_path) # Devuelve una array np [Z, Y, X, C]\n", + " h = header[\"dimX\"]\n", + " w = header[\"dimY\"]\n", + " arr = content[:, ::-1, :, :] # Cambia el orden de Y\n", + " arr = np.reshape(arr, [w, h, 1]) # Deshecha Z\n", + " densities.append(arr)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Necesitamos al menos 2 simulaciones para trabajar de manera adecuada." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "load_num = len(densities)" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "if load_num <200:\n", + " print(\"Error - usa al menos dos simulaciones completas\")\n", + " exit(1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Convertimos la lista \"densities\" en una array de Numpy." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(1100, 64, 64, 1)" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "densities = np.reshape(densities, (len(densities), 64, 64, 1))\n", + "densities.shape" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Creación de set de validación" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Creamos el set de validación de entre los datos de simulación generados, al menos una simulación completa o el 10% de los datos (el que sea mayor de los dos)." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Read uni files, total data (1100, 64, 64, 1)\n", + "Split into 990 training and 110 validation samples\n" + ] + } + ], + "source": [ + "print(\"Read uni files, total data \" + format(densities.shape))\n", + "\n", + "vali_size = max(100, int(load_num * 0.1)) # Al menos una simu completa\n", + "vali_data = densities[load_num - vali_size : load_num, :]\n", + "densities = densities[0 : load_num - vali_size, :]\n", + "\n", + "print(\"Split into %d training and %d validation samples\" % (densities.shape[0], vali_data.shape[0]))\n", + "\n", + "load_num = densities.shape[0]" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(990, 64, 64, 1)\n", + "(110, 64, 64, 1)\n" + ] + } + ], + "source": [ + "densities = np.reshape(densities, (len(densities), 64, 64, 1))\n", + "vali_data = np.reshape(vali_data, (len(vali_data), 64, 64, 1))\n", + "\n", + "print(densities.shape)\n", + "print(vali_data.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "64 64 1\n" + ] + } + ], + "source": [ + "print(densities.shape[1], densities.shape[2], densities.shape[3])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Creación del modelo Autoencoder mediante Keras (Sequential)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Importamos las bibliotecas de Keras" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Using TensorFlow backend.\n" + ] + } + ], + "source": [ + "from keras.models import Sequential\n", + "from keras.layers import Conv2D, Conv2DTranspose, MaxPooling2D, UpSampling2D, Activation\n", + "from keras.layers.advanced_activations import LeakyReLU" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Creacion de las capas del modelo" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "En la primera capa debemos definir las dimensiones del input esperado." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "input_shape = (densities.shape[1], densities.shape[2], densities.shape[3])" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/jon/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/keras/activations.py:115: UserWarning: Do not pass a layer instance (such as LeakyReLU) as the activation argument of another layer. Instead, advanced activation layers should be used just like any other layer in a model.\n", + " identifier=identifier.__class__.__name__))\n" + ] + } + ], + "source": [ + "l0 = Conv2D(filters = 32, \n", + " kernel_size = 4,\n", + " strides = 2,\n", + " activation = \"linear\", \n", + " padding = \"same\", \n", + " input_shape = input_shape)\n", + "\n", + "l1 = Conv2D(filters = 64, \n", + " kernel_size = 2,\n", + " strides = 2,\n", + " padding = \"same\")\n", + "\n", + "l1_Leaky = Activation(LeakyReLU(alpha = 0.1))\n", + "\n", + "l2 = Conv2D(filters = 128, \n", + " kernel_size = 2,\n", + " strides = 2, \n", + " padding = \"same\")\n", + "\n", + "l2_Leaky = Activation(LeakyReLU(alpha = 0.1))\n", + "\n", + "l3 = Conv2D(filters = 256, \n", + " kernel_size = 2,\n", + " strides = 2, \n", + " padding = \"same\")\n", + "\n", + "l3_Leaky = Activation(LeakyReLU(alpha = 0.1))\n", + "\n", + "l4 = Conv2D(filters = 512, \n", + " kernel_size = 2,\n", + " strides = 2,\n", + " padding = \"same\")\n", + "\n", + "l4_Leaky = Activation(LeakyReLU(alpha = 0.1))\n", + "\n", + "l5 = Conv2D(filters = 1024, \n", + " kernel_size = 2,\n", + " strides = 2,\n", + " padding = \"same\")\n", + "\n", + "l5_Leaky = Activation(LeakyReLU(alpha = 0.1))" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "l6 = Conv2DTranspose(filters = 512, \n", + " kernel_size = 2,\n", + " strides = 2,\n", + " padding = \"same\")\n", + "\n", + "l6_Leaky = Activation(LeakyReLU(alpha = 0.1))\n", + "\n", + "l7 = Conv2DTranspose(filters = 256, \n", + " kernel_size = 2,\n", + " strides = 2,\n", + " padding = \"same\")\n", + "\n", + "l7_Leaky = Activation(LeakyReLU(alpha = 0.1))\n", + "\n", + "l8 = Conv2DTranspose(filters = 128, \n", + " kernel_size = 2,\n", + " strides = 2,\n", + " padding = \"same\")\n", + "\n", + "l8_Leaky = Activation(LeakyReLU(alpha = 0.1))\n", + "\n", + "l9 = Conv2DTranspose(filters = 64, \n", + " kernel_size = 2,\n", + " strides = 2,\n", + " padding = \"same\")\n", + "\n", + "l9_Leaky = Activation(LeakyReLU(alpha = 0.1))\n", + "\n", + "l10 = Conv2DTranspose(filters = 32, \n", + " kernel_size = 2,\n", + " strides = 2,\n", + " padding = \"same\")\n", + "\n", + "l10_Leaky = Activation(LeakyReLU(alpha = 0.1))\n", + "\n", + "l11 = Conv2DTranspose(filters = 1, \n", + " kernel_size = 4,\n", + " strides = 2,\n", + " activation = \"linear\", \n", + " padding = \"same\")" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "autoencoder = Sequential([l0, \n", + " l1, l1_Leaky,\n", + " l2, l2_Leaky,\n", + " l3, l3_Leaky,\n", + " l4, l4_Leaky,\n", + " l5, l5_Leaky,\n", + " l6, l6_Leaky,\n", + " l7, l7_Leaky,\n", + " l8, l8_Leaky,\n", + " l9, l9_Leaky,\n", + " l10, l10_Leaky,\n", + " l11])" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "autoencoder.compile(optimizer = \"adadelta\", loss = \"binary_crossentropy\")" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "_________________________________________________________________\n", + "Layer (type) Output Shape Param # \n", + "=================================================================\n", + "conv2d_1 (Conv2D) (None, 32, 32, 32) 544 \n", + "_________________________________________________________________\n", + "conv2d_2 (Conv2D) (None, 16, 16, 64) 8256 \n", + "_________________________________________________________________\n", + "activation_1 (Activation) (None, 16, 16, 64) 0 \n", + "_________________________________________________________________\n", + "conv2d_3 (Conv2D) (None, 8, 8, 128) 32896 \n", + "_________________________________________________________________\n", + "activation_2 (Activation) (None, 8, 8, 128) 0 \n", + "_________________________________________________________________\n", + "conv2d_4 (Conv2D) (None, 4, 4, 256) 131328 \n", + "_________________________________________________________________\n", + "activation_3 (Activation) (None, 4, 4, 256) 0 \n", + "_________________________________________________________________\n", + "conv2d_5 (Conv2D) (None, 2, 2, 512) 524800 \n", + "_________________________________________________________________\n", + "activation_4 (Activation) (None, 2, 2, 512) 0 \n", + "_________________________________________________________________\n", + "conv2d_6 (Conv2D) (None, 1, 1, 1024) 2098176 \n", + "_________________________________________________________________\n", + "activation_5 (Activation) (None, 1, 1, 1024) 0 \n", + "_________________________________________________________________\n", + "conv2d_transpose_1 (Conv2DTr (None, 2, 2, 512) 2097664 \n", + "_________________________________________________________________\n", + "activation_6 (Activation) (None, 2, 2, 512) 0 \n", + "_________________________________________________________________\n", + "conv2d_transpose_2 (Conv2DTr (None, 4, 4, 256) 524544 \n", + "_________________________________________________________________\n", + "activation_7 (Activation) (None, 4, 4, 256) 0 \n", + "_________________________________________________________________\n", + "conv2d_transpose_3 (Conv2DTr (None, 8, 8, 128) 131200 \n", + "_________________________________________________________________\n", + "activation_8 (Activation) (None, 8, 8, 128) 0 \n", + "_________________________________________________________________\n", + "conv2d_transpose_4 (Conv2DTr (None, 16, 16, 64) 32832 \n", + "_________________________________________________________________\n", + "activation_9 (Activation) (None, 16, 16, 64) 0 \n", + "_________________________________________________________________\n", + "conv2d_transpose_5 (Conv2DTr (None, 32, 32, 32) 8224 \n", + "_________________________________________________________________\n", + "activation_10 (Activation) (None, 32, 32, 32) 0 \n", + "_________________________________________________________________\n", + "conv2d_transpose_6 (Conv2DTr (None, 64, 64, 1) 513 \n", + "=================================================================\n", + "Total params: 5,590,977\n", + "Trainable params: 5,590,977\n", + "Non-trainable params: 0\n", + "_________________________________________________________________\n" + ] + } + ], + "source": [ + "autoencoder.summary()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Train on 990 samples, validate on 110 samples\n", + "Epoch 1/100\n", + "990/990 [==============================] - 15s 15ms/step - loss: 0.1410 - val_loss: 0.1661\n", + "Epoch 2/100\n", + "990/990 [==============================] - 14s 14ms/step - loss: 0.1168 - val_loss: 0.1600\n", + "Epoch 3/100\n", + "990/990 [==============================] - 14s 14ms/step - loss: 0.1128 - val_loss: 0.1535\n", + "Epoch 4/100\n", + "990/990 [==============================] - 14s 14ms/step - loss: 0.1087 - val_loss: 0.1471\n", + "Epoch 5/100\n", + "990/990 [==============================] - 14s 14ms/step - loss: 0.1053 - val_loss: 0.1418\n", + "Epoch 6/100\n", + "990/990 [==============================] - 14s 14ms/step - loss: 0.1029 - val_loss: 0.1381\n", + "Epoch 7/100\n", + "990/990 [==============================] - 14s 14ms/step - loss: 0.1015 - val_loss: 0.1359\n", + "Epoch 8/100\n", + "990/990 [==============================] - 14s 14ms/step - loss: 0.1009 - val_loss: 0.1347\n", + "Epoch 9/100\n", + "990/990 [==============================] - 14s 14ms/step - loss: 0.1007 - val_loss: 0.1340\n", + "Epoch 10/100\n", + "990/990 [==============================] - 14s 14ms/step - loss: 0.1006 - val_loss: 0.1336\n", + "Epoch 11/100\n", + "990/990 [==============================] - 14s 14ms/step - loss: 0.1005 - val_loss: 0.1333\n", + "Epoch 12/100\n", + "990/990 [==============================] - 14s 14ms/step - loss: 0.1004 - val_loss: 0.1331\n", + "Epoch 13/100\n", + "990/990 [==============================] - 14s 14ms/step - loss: 0.1002 - val_loss: 0.1328\n", + "Epoch 14/100\n", + "990/990 [==============================] - 14s 14ms/step - loss: 0.1000 - val_loss: 0.1325\n", + "Epoch 15/100\n", + "990/990 [==============================] - 14s 14ms/step - loss: 0.0998 - val_loss: 0.1320\n", + "Epoch 16/100\n", + "990/990 [==============================] - 14s 14ms/step - loss: 0.0994 - val_loss: 0.1313\n", + "Epoch 17/100\n", + "990/990 [==============================] - 14s 14ms/step - loss: 0.0988 - val_loss: 0.1301\n", + "Epoch 18/100\n", + "990/990 [==============================] - 14s 14ms/step - loss: 0.0978 - val_loss: 0.1281\n", + "Epoch 19/100\n", + "990/990 [==============================] - 14s 14ms/step - loss: 0.0960 - val_loss: 0.1243\n", + "Epoch 20/100\n", + "990/990 [==============================] - 14s 14ms/step - loss: 0.0928 - val_loss: 0.1178\n", + "Epoch 21/100\n", + "990/990 [==============================] - 14s 14ms/step - loss: 0.0882 - val_loss: 0.1106\n", + "Epoch 22/100\n", + "990/990 [==============================] - 14s 14ms/step - loss: 0.0845 - val_loss: 0.1066\n", + "Epoch 23/100\n", + "990/990 [==============================] - 14s 14ms/step - loss: 0.0827 - val_loss: 0.1048\n", + "Epoch 24/100\n", + "990/990 [==============================] - 14s 14ms/step - loss: 0.0820 - val_loss: 0.1038\n", + "Epoch 25/100\n", + "990/990 [==============================] - 14s 14ms/step - loss: 0.0815 - val_loss: 0.1032\n", + "Epoch 26/100\n", + "990/990 [==============================] - 14s 14ms/step - loss: 0.0813 - val_loss: 0.1028\n", + "Epoch 27/100\n", + "990/990 [==============================] - 14s 14ms/step - loss: 0.0811 - val_loss: 0.1028\n", + "Epoch 28/100\n", + "990/990 [==============================] - 14s 14ms/step - loss: 0.0811 - val_loss: 0.1031\n", + "Epoch 29/100\n", + "990/990 [==============================] - 14s 14ms/step - loss: 0.0810 - val_loss: 0.1026\n", + "Epoch 30/100\n", + "990/990 [==============================] - 14s 14ms/step - loss: 0.0810 - val_loss: 0.1026\n", + "Epoch 31/100\n", + "990/990 [==============================] - 14s 14ms/step - loss: 0.0809 - val_loss: 0.1025\n", + "Epoch 32/100\n", + "990/990 [==============================] - 12s 13ms/step - loss: 0.0810 - val_loss: 0.1027\n", + "Epoch 33/100\n", + "990/990 [==============================] - 13s 13ms/step - loss: 0.0810 - val_loss: 0.1025\n", + "Epoch 34/100\n", + "990/990 [==============================] - 12s 12ms/step - loss: 0.0809 - val_loss: 0.1025\n", + "Epoch 35/100\n", + "990/990 [==============================] - 12s 12ms/step - loss: 0.0808 - val_loss: 0.1026\n", + "Epoch 36/100\n", + "990/990 [==============================] - 12s 12ms/step - loss: 0.0808 - val_loss: 0.1024\n", + "Epoch 37/100\n", + "990/990 [==============================] - 12s 12ms/step - loss: 0.0808 - val_loss: 0.1025\n", + "Epoch 38/100\n", + "990/990 [==============================] - 12s 12ms/step - loss: 0.0808 - val_loss: 0.1027\n", + "Epoch 39/100\n", + "990/990 [==============================] - 12s 12ms/step - loss: 0.0807 - val_loss: 0.1025\n", + "Epoch 40/100\n", + "990/990 [==============================] - 12s 12ms/step - loss: 0.0810 - val_loss: 0.1025\n", + "Epoch 41/100\n", + "990/990 [==============================] - 13s 13ms/step - loss: 0.0807 - val_loss: 0.1025\n", + "Epoch 42/100\n", + "990/990 [==============================] - 13s 13ms/step - loss: 0.0807 - val_loss: 0.1023\n", + "Epoch 43/100\n", + "990/990 [==============================] - 13s 13ms/step - loss: 0.0807 - val_loss: 0.1024\n", + "Epoch 44/100\n", + "990/990 [==============================] - 13s 13ms/step - loss: 0.0806 - val_loss: 0.1023\n", + "Epoch 45/100\n", + "990/990 [==============================] - 13s 13ms/step - loss: 0.0806 - val_loss: 0.1023\n", + "Epoch 46/100\n", + "990/990 [==============================] - 13s 13ms/step - loss: 0.0806 - val_loss: 0.1024\n", + "Epoch 47/100\n", + "990/990 [==============================] - 13s 13ms/step - loss: 0.0806 - val_loss: 0.1023\n", + "Epoch 48/100\n", + "990/990 [==============================] - 12s 13ms/step - loss: 0.0806 - val_loss: 0.1023\n", + "Epoch 49/100\n", + "990/990 [==============================] - 13s 13ms/step - loss: 0.0806 - val_loss: 0.1023\n", + "Epoch 50/100\n", + "990/990 [==============================] - 13s 13ms/step - loss: 0.0806 - val_loss: 0.1024\n", + "Epoch 51/100\n", + "990/990 [==============================] - 13s 13ms/step - loss: 0.0805 - val_loss: 0.1024\n", + "Epoch 52/100\n", + "990/990 [==============================] - 13s 13ms/step - loss: 0.0805 - val_loss: 0.1022\n", + "Epoch 53/100\n", + "990/990 [==============================] - 17s 17ms/step - loss: 0.0806 - val_loss: 0.1024\n", + "Epoch 54/100\n", + "990/990 [==============================] - 24s 24ms/step - loss: 0.0805 - val_loss: 0.1023\n", + "Epoch 55/100\n", + "200/990 [=====>........................] - ETA: 17s - loss: 0.0770" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m<ipython-input-19-5ff9607ac4ee>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mbatch_size\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m100\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mvalidation_data\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mvali_data\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvali_data\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m shuffle = False)\n\u001b[0m", + "\u001b[0;32m~/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/keras/models.py\u001b[0m in \u001b[0;36mfit\u001b[0;34m(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, **kwargs)\u001b[0m\n\u001b[1;32m 1000\u001b[0m \u001b[0minitial_epoch\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0minitial_epoch\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1001\u001b[0m \u001b[0msteps_per_epoch\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0msteps_per_epoch\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1002\u001b[0;31m validation_steps=validation_steps)\n\u001b[0m\u001b[1;32m 1003\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1004\u001b[0m def evaluate(self, x=None, y=None,\n", + "\u001b[0;32m~/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/keras/engine/training.py\u001b[0m in \u001b[0;36mfit\u001b[0;34m(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, **kwargs)\u001b[0m\n\u001b[1;32m 1703\u001b[0m \u001b[0minitial_epoch\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0minitial_epoch\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1704\u001b[0m \u001b[0msteps_per_epoch\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0msteps_per_epoch\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1705\u001b[0;31m validation_steps=validation_steps)\n\u001b[0m\u001b[1;32m 1706\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1707\u001b[0m def evaluate(self, x=None, y=None,\n", + "\u001b[0;32m~/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/keras/engine/training.py\u001b[0m in \u001b[0;36m_fit_loop\u001b[0;34m(self, f, ins, out_labels, batch_size, epochs, verbose, callbacks, val_f, val_ins, shuffle, callback_metrics, initial_epoch, steps_per_epoch, validation_steps)\u001b[0m\n\u001b[1;32m 1234\u001b[0m \u001b[0mins_batch\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mins_batch\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mi\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtoarray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1235\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1236\u001b[0;31m \u001b[0mouts\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mins_batch\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1237\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0misinstance\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mouts\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mlist\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1238\u001b[0m \u001b[0mouts\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mouts\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/keras/backend/tensorflow_backend.py\u001b[0m in \u001b[0;36m__call__\u001b[0;34m(self, inputs)\u001b[0m\n\u001b[1;32m 2480\u001b[0m \u001b[0msession\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mget_session\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2481\u001b[0m updated = session.run(fetches=fetches, feed_dict=feed_dict,\n\u001b[0;32m-> 2482\u001b[0;31m **self.session_kwargs)\n\u001b[0m\u001b[1;32m 2483\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mupdated\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moutputs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2484\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/client/session.py\u001b[0m in \u001b[0;36mrun\u001b[0;34m(self, fetches, feed_dict, options, run_metadata)\u001b[0m\n\u001b[1;32m 903\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 904\u001b[0m result = self._run(None, fetches, feed_dict, options_ptr,\n\u001b[0;32m--> 905\u001b[0;31m run_metadata_ptr)\n\u001b[0m\u001b[1;32m 906\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mrun_metadata\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 907\u001b[0m \u001b[0mproto_data\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtf_session\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mTF_GetBuffer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrun_metadata_ptr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/client/session.py\u001b[0m in \u001b[0;36m_run\u001b[0;34m(self, handle, fetches, feed_dict, options, run_metadata)\u001b[0m\n\u001b[1;32m 1138\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mfinal_fetches\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0mfinal_targets\u001b[0m \u001b[0;32mor\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mhandle\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mfeed_dict_tensor\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1139\u001b[0m results = self._do_run(handle, final_targets, final_fetches,\n\u001b[0;32m-> 1140\u001b[0;31m feed_dict_tensor, options, run_metadata)\n\u001b[0m\u001b[1;32m 1141\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1142\u001b[0m \u001b[0mresults\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/client/session.py\u001b[0m in \u001b[0;36m_do_run\u001b[0;34m(self, handle, target_list, fetch_list, feed_dict, options, run_metadata)\u001b[0m\n\u001b[1;32m 1319\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mhandle\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1320\u001b[0m return self._do_call(_run_fn, feeds, fetches, targets, options,\n\u001b[0;32m-> 1321\u001b[0;31m run_metadata)\n\u001b[0m\u001b[1;32m 1322\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1323\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_do_call\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0m_prun_fn\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mhandle\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfeeds\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfetches\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/client/session.py\u001b[0m in \u001b[0;36m_do_call\u001b[0;34m(self, fn, *args)\u001b[0m\n\u001b[1;32m 1325\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_do_call\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfn\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1326\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1327\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mfn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1328\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0merrors\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mOpError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1329\u001b[0m \u001b[0mmessage\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcompat\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mas_text\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0me\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmessage\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/client/session.py\u001b[0m in \u001b[0;36m_run_fn\u001b[0;34m(feed_dict, fetch_list, target_list, options, run_metadata)\u001b[0m\n\u001b[1;32m 1310\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_extend_graph\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1311\u001b[0m return self._call_tf_sessionrun(\n\u001b[0;32m-> 1312\u001b[0;31m options, feed_dict, fetch_list, target_list, run_metadata)\n\u001b[0m\u001b[1;32m 1313\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1314\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_prun_fn\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mhandle\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfeed_dict\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfetch_list\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/PycharmProjects/TensorPlay/venv/lib/python3.6/site-packages/tensorflow/python/client/session.py\u001b[0m in \u001b[0;36m_call_tf_sessionrun\u001b[0;34m(self, options, feed_dict, fetch_list, target_list, run_metadata)\u001b[0m\n\u001b[1;32m 1418\u001b[0m return tf_session.TF_Run(\n\u001b[1;32m 1419\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_session\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0moptions\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfeed_dict\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfetch_list\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtarget_list\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1420\u001b[0;31m status, run_metadata)\n\u001b[0m\u001b[1;32m 1421\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1422\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_call_tf_sessionprun\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mhandle\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfeed_dict\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfetch_list\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " + ] + } + ], + "source": [ + "autoencoder_train = autoencoder.fit(densities, densities, \n", + " epochs = 100,\n", + " verbose = 1,\n", + " batch_size = 100,\n", + " validation_data = (vali_data, vali_data),\n", + " shuffle = False)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name 'autoencoder_train' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m<ipython-input-20-63078c768c65>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mepochs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m100\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mloss\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mautoencoder_train\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mhistory\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"loss\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 3\u001b[0m \u001b[0mval_loss\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mautoencoder_train\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mhistory\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"val_loss\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mepochs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mloss\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mval_loss\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mNameError\u001b[0m: name 'autoencoder_train' is not defined" + ] + } + ], + "source": [ + "epochs = range(100)\n", + "loss = autoencoder_train.history[\"loss\"]\n", + "val_loss = autoencoder_train.history[\"val_loss\"]\n", + "\n", + "plt.plot(epochs, loss, val_loss)\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [], + "source": [ + "decoded_imgs = autoencoder.predict(vali_data)" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "<Figure size 720x144 with 20 Axes>" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "n = 10 # Number of frames to display\n", + "\n", + "plt.figure(figsize = (10, 2))\n", + "\n", + "for i in range(n):\n", + " \n", + " ax = plt.subplot(2, n, i + 1)\n", + " plt.imshow(vali_data[i].reshape(64, 64))\n", + " plt.gray()\n", + " ax.get_xaxis().set_visible(False)\n", + " ax.get_yaxis().set_visible(False)\n", + " \n", + " ax = plt.subplot(2, n, i + 1 + n)\n", + " plt.imshow(decoded_imgs[i].reshape(64, 64))\n", + " plt.gray()\n", + " ax.get_xaxis().set_visible(False)\n", + " ax.get_yaxis().set_visible(False)\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "out_dir = \"%s/test_simple\" % base_path\n", + "if not os.path.exists(out_dir): os.makedirs(out_dir)\n", + "\n", + "for i in range(len(vali_data)):\n", + " scipy.misc.toimage(np.reshape(vali_data[i], [64, 64])).save(\"%s/in_%d.png\" % (out_dir, i))\n", + " scipy.misc.toimage(np.reshape(decoded_imgs[i], [64, 64]),).save(\"%s/out_%d.png\" % (out_dir, i))" + ] + }, + { + "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.6.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}