{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
"from IPython.display import Image"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"# CNTK 105: Basic autoencoder (AE) with MNIST data\n",
"\n",
"**Prerequisites**: We assume that you have successfully downloaded the MNIST data by completing the tutorial titled CNTK_103A_MNIST_DataLoader.ipynb.\n",
"\n",
"\n",
"## Introduction\n",
"\n",
"In this tutorial we introduce you to the basics of [Autoencoders](https://en.wikipedia.org/wiki/Autoencoder). An autoencoder is an artificial neural network used for unsupervised learning of efficient encodings. In other words, they are used for lossy data-specific compression that is learnt automatically instead of relying on human engineered features. The aim of an autoencoder is to learn a representation (encoding) for a set of data, typically for the purpose of dimensionality reduction. \n",
"\n",
"The autoencoders are very specific to the data-set on hand and are different from standard codecs such as JPEG, MPEG standard based encodings. Once the information is encoded and decoded back to original dimensions some amount of information is lost in the process. Given these encodings are specific to data, autoencoders are not used for compression. However, there are two areas where autoencoders have been found very effective: denoising and dimensionality reduction.\n",
"\n",
"Autoencoders have attracted attention since they have long been thought to be a potential approach for unsupervised learning. Truly unsupervised approaches involve learning useful representations without the need for labels. Autoencoders fall under self-supervised learning, a specific instance of supervised learning where the targets are generated from the input data. \n",
"\n",
"**Goal** \n",
"\n",
"Our goal is to train an autoencoder that compresses MNIST digits image to a vector of smaller dimension and then restores the image. The MNIST data comprises of hand-written digits with little background noise."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"data": {
"text/html": [
"<img src=\"http://cntk.ai/jup/MNIST-image.jpg\" width=\"300\" height=\"300\"/>"
],
"text/plain": [
"<IPython.core.display.Image object>"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Figure 1\n",
"Image(url=\"http://cntk.ai/jup/MNIST-image.jpg\", width=300, height=300)"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"In this tutorial, we will use the [MNIST hand-written digits data](https://en.wikipedia.org/wiki/MNIST_database) to show how images can be encoded and decoded (restored) using feed-forward networks. We will visualize the original and the restored images. We illustrate feed forward network based on two autoencoders: simple and deep autoencoder. More advanced autoencoders will be covered in future 200 series tutorials."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": true,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
"# Import the relevant modules\n",
"from __future__ import print_function # Use a function definition from future version (say 3.x from 2.7 interpreter)\n",
"import matplotlib.pyplot as plt\n",
"import numpy as np\n",
"import os\n",
"import sys\n",
"\n",
"# Import CNTK \n",
"import cntk as C\n",
"import cntk.tests.test_utils\n",
"cntk.tests.test_utils.set_device_from_pytest_env() # (only needed for our build system)\n",
"C.cntk_py.set_fixed_random_seed(1) # fix a random seed for CNTK components\n",
"\n",
"%matplotlib inline"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"There are two run modes:\n",
"- *Fast mode*: `isFast` is set to `True`. This is the default mode for the notebooks, which means we train for fewer iterations or train / test on limited data. This ensures functional correctness of the notebook though the models produced are far from what a completed training would produce.\n",
"\n",
"- *Slow mode*: We recommend the user to set this flag to `False` once the user has gained familiarity with the notebook content and wants to gain insight from running the notebooks for a longer period with different parameters for training. "
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": true,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
"isFast = True"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"## Data reading\n",
"\n",
"In this section, we will read the data generated in CNTK 103 Part A.\n",
"\n",
"The data is in the following format:\n",
"\n",
" |labels 0 0 0 0 0 0 0 1 0 0 |features 0 0 0 0 ... \n",
" (784 integers each representing a pixel)\n",
" \n",
" In this tutorial we are going to use the image pixels corresponding the integer stream named \"features\". We define a `create_reader` function to read the training and test data using the [CTF deserializer](https://cntk.ai/pythondocs/cntk.io.html?highlight=ctfdeserializer#cntk.io.CTFDeserializer). The labels are [1-hot encoded](https://en.wikipedia.org/wiki/One-hot). We ignore them in this tutorial. \n",
"\n",
"We also check if the training and test data file has been downloaded and available for reading by the `create_reader` function. In this tutorial we are using the MNIST data you have downloaded using CNTK_103A_MNIST_DataLoader notebook. The dataset has 60,000 training images and 10,000 test images with each image being 28 x 28 pixels."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": true,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
"# Read a CTF formatted text (as mentioned above) using the CTF deserializer from a file\n",
"def create_reader(path, is_training, input_dim, num_label_classes):\n",
" return C.io.MinibatchSource(C.io.CTFDeserializer(path, C.io.StreamDefs(\n",
" labels_viz = C.io.StreamDef(field='labels', shape=num_label_classes, is_sparse=False),\n",
" features = C.io.StreamDef(field='features', shape=input_dim, is_sparse=False)\n",
" )), randomize = is_training, max_sweeps = C.io.INFINITELY_REPEAT if is_training else 1)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Data directory is ..\\Examples\\Image\\DataSets\\MNIST\n"
]
}
],
"source": [
"# Ensure the training and test data is generated and available for this tutorial.\n",
"# We search in two locations in the toolkit for the cached MNIST data set.\n",
"data_found = False\n",
"for data_dir in [os.path.join(\"..\", \"Examples\", \"Image\", \"DataSets\", \"MNIST\"),\n",
" os.path.join(\"data\", \"MNIST\")]:\n",
" train_file = os.path.join(data_dir, \"Train-28x28_cntk_text.txt\")\n",
" test_file = os.path.join(data_dir, \"Test-28x28_cntk_text.txt\")\n",
" if os.path.isfile(train_file) and os.path.isfile(test_file):\n",
" data_found = True\n",
" break\n",
" \n",
"if not data_found:\n",
" raise ValueError(\"Please generate the data by completing CNTK 103 Part A\")\n",
"print(\"Data directory is {0}\".format(data_dir))\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"## Model Creation (Simple AE)\n",
"\n",
"We start with a simple single fully-connected feedforward network as encoder and as decoder (as shown in the figure below):"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"data": {
"text/html": [
"<img src=\"http://cntk.ai/jup/SimpleAEfig.jpg\" width=\"200\" height=\"200\"/>"
],
"text/plain": [
"<IPython.core.display.Image object>"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Figure 2\n",
"Image(url=\"http://cntk.ai/jup/SimpleAEfig.jpg\", width=200, height=200)"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"The input data is a set of hand written digits images each of 28 x 28 pixels. In this tutorial, we will consider each image as a linear array of 784 pixel values. These pixels are considered as an input having 784 dimensions, one per pixel. Since the goal of the autoencoder is to compress the data and reconstruct the original image, the output dimension is same as the input dimension. We will compress the input to mere 32 dimensions (referred to as the `encoding_dim`). Additionally, since the maximum input value is 255, we normalize the input between 0 and 1. "
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": true,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
"input_dim = 784\n",
"encoding_dim = 32\n",
"output_dim = input_dim\n",
"\n",
"def create_model(features):\n",
" with C.layers.default_options(init = C.glorot_uniform()):\n",
" # We scale the input pixels to 0-1 range\n",
" encode = C.layers.Dense(encoding_dim, activation = C.relu)(features/255.0)\n",
" decode = C.layers.Dense(input_dim, activation = C.sigmoid)(encode)\n",
"\n",
" return decode"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"### Train and test the model\n",
"\n",
"In previous tutorials, we have defined each of the training and testing phases separately. In this tutorial, we combine the two components in one place such that this template could be used as a recipe for your usage. \n",
"\n",
"The `train_and_test` function performs two major tasks:\n",
"- Train the model\n",
"- Evaluate the accuracy of the model on test data\n",
"\n",
"For training:\n",
"\n",
"> The function takes a reader (`reader_train`), a model function (`model_func`) and the target (a.k.a `label`) as input. In this tutorial, we show how to create and pass your **own** loss function. We normalize the `label` function to emit value between 0 and 1 for us to compute the label error using `C.classification_error` function.\n",
"\n",
"> We use Adam optimizer in this tutorial from a range of [learners](https://www.cntk.ai/pythondocs/cntk.learner.html#module-cntk.learner) (optimizers) available in the toolkit. \n",
"\n",
"For testing:\n",
"\n",
"> The function additionally takes a reader (`reader_test`) and evaluates the predicted pixel values made by the model against reference data, in this case the original pixel values for each image.\n"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"collapsed": true,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
"def train_and_test(reader_train, reader_test, model_func):\n",
" \n",
" ###############################################\n",
" # Training the model\n",
" ###############################################\n",
" \n",
" # Instantiate the input and the label variables\n",
" input = C.input_variable(input_dim)\n",
" label = C.input_variable(input_dim)\n",
" \n",
" # Create the model function\n",
" model = model_func(input)\n",
" \n",
" # The labels for this network is same as the input MNIST image.\n",
" # Note: Inside the model we are scaling the input to 0-1 range\n",
" # Hence we rescale the label to the same range\n",
" # We show how one can use their custom loss function\n",
" # loss = -(y* log(p)+ (1-y) * log(1-p)) where p = model output and y = target\n",
" # We have normalized the input between 0-1. Hence we scale the target to same range\n",
" \n",
" target = label/255.0 \n",
" loss = -(target * C.log(model) + (1 - target) * C.log(1 - model))\n",
" label_error = C.classification_error(model, target)\n",
" \n",
" # training config\n",
" epoch_size = 30000 # 30000 samples is half the dataset size \n",
" minibatch_size = 64\n",
" num_sweeps_to_train_with = 5 if isFast else 100\n",
" num_samples_per_sweep = 60000\n",
" num_minibatches_to_train = (num_samples_per_sweep * num_sweeps_to_train_with) // minibatch_size\n",
" \n",
" \n",
" # Instantiate the trainer object to drive the model training\n",
" lr_per_sample = [0.00003]\n",
" lr_schedule = C.learning_rate_schedule(lr_per_sample, C.UnitType.sample, epoch_size)\n",
" \n",
" # Momentum\n",
" momentum_as_time_constant = C.momentum_as_time_constant_schedule(700)\n",
" \n",
" # We use a variant of the Adam optimizer which is known to work well on this dataset\n",
" # Feel free to try other optimizers from \n",
" # https://www.cntk.ai/pythondocs/cntk.learner.html#module-cntk.learner\n",
" learner = C.fsadagrad(model.parameters,\n",
" lr=lr_schedule, momentum=momentum_as_time_constant) \n",
" \n",
" # Instantiate the trainer\n",
" progress_printer = C.logging.ProgressPrinter(0)\n",
" trainer = C.Trainer(model, (loss, label_error), learner, progress_printer)\n",
" \n",
" # Map the data streams to the input and labels.\n",
" # Note: for autoencoders input == label\n",
" input_map = {\n",
" input : reader_train.streams.features,\n",
" label : reader_train.streams.features\n",
" } \n",
" \n",
" aggregate_metric = 0\n",
" for i in range(num_minibatches_to_train):\n",
" # Read a mini batch from the training data file\n",
" data = reader_train.next_minibatch(minibatch_size, input_map = input_map)\n",
" \n",
" # Run the trainer on and perform model training\n",
" trainer.train_minibatch(data)\n",
" samples = trainer.previous_minibatch_sample_count\n",
" aggregate_metric += trainer.previous_minibatch_evaluation_average * samples\n",
" \n",
" train_error = (aggregate_metric*100.0) / (trainer.total_number_of_samples_seen)\n",
" print(\"Average training error: {0:0.2f}%\".format(train_error))\n",
" \n",
" #############################################################################\n",
" # Testing the model\n",
" # Note: we use a test file reader to read data different from a training data\n",
" #############################################################################\n",
" \n",
" # Test data for trained model\n",
" test_minibatch_size = 32\n",
" num_samples = 10000\n",
" num_minibatches_to_test = num_samples / test_minibatch_size\n",
" test_result = 0.0\n",
" \n",
" # Test error metric calculation\n",
" metric_numer = 0\n",
" metric_denom = 0\n",
"\n",
" test_input_map = {\n",
" input : reader_test.streams.features,\n",
" label : reader_test.streams.features\n",
" }\n",
"\n",
" for i in range(0, int(num_minibatches_to_test)):\n",
" \n",
" # We are loading test data in batches specified by test_minibatch_size\n",
" # Each data point in the minibatch is a MNIST digit image of 784 dimensions \n",
" # with one pixel per dimension that we will encode / decode with the \n",
" # trained model.\n",
" data = reader_test.next_minibatch(test_minibatch_size,\n",
" input_map = test_input_map)\n",
"\n",
" # Specify the mapping of input variables in the model to actual\n",
" # minibatch data to be tested with\n",
" eval_error = trainer.test_minibatch(data)\n",
" \n",
" # minibatch data to be trained with\n",
" metric_numer += np.abs(eval_error * test_minibatch_size)\n",
" metric_denom += test_minibatch_size\n",
"\n",
" # Average of evaluation errors of all test minibatches\n",
" test_error = (metric_numer*100.0) / (metric_denom) \n",
" print(\"Average test error: {0:0.2f}%\".format(test_error))\n",
" \n",
" return model, train_error, test_error"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"Let us train the simple autoencoder. We create a training and a test reader"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" average since average since examples\n",
" loss last metric last \n",
" ------------------------------------------------------\n",
"Learning rate per sample: 3e-05\n",
" 544 544 0.947 0.947 64\n",
" 544 544 0.931 0.923 192\n",
" 543 543 0.921 0.913 448\n",
" 542 541 0.924 0.927 960\n",
" 537 532 0.924 0.924 1984\n",
" 493 451 0.821 0.721 4032\n",
" 383 275 0.639 0.46 8128\n",
" 303 223 0.524 0.409 16320\n",
" 251 199 0.396 0.268 32704\n",
" 209 168 0.281 0.167 65472\n",
" 174 139 0.194 0.107 131008\n",
" 144 113 0.125 0.0554 262080\n",
"Average training error: 11.33%\n",
"Average test error: 3.12%\n"
]
}
],
"source": [
"num_label_classes = 10\n",
"reader_train = create_reader(train_file, True, input_dim, num_label_classes)\n",
"reader_test = create_reader(test_file, False, input_dim, num_label_classes)\n",
"model, simple_ae_train_error, simple_ae_test_error = train_and_test(reader_train, \n",
" reader_test, \n",
" model_func = create_model )"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"## Visualize simple AE results"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Original image statistics:\n",
"Max: 255.00, Median: 0.00, Mean: 24.07, Min: 0.00\n",
"Decoded image statistics:\n",
"Max: 249.56, Median: 0.58, Mean: 27.02, Min: 0.00\n"
]
}
],
"source": [
"# Read some data to run the eval\n",
"num_label_classes = 10\n",
"reader_eval = create_reader(test_file, False, input_dim, num_label_classes)\n",
"\n",
"eval_minibatch_size = 50\n",
"eval_input_map = { input : reader_eval.streams.features } \n",
" \n",
"eval_data = reader_eval.next_minibatch(eval_minibatch_size,\n",
" input_map = eval_input_map)\n",
"\n",
"img_data = eval_data[input].asarray()\n",
"\n",
"# Select a random image\n",
"np.random.seed(0) \n",
"idx = np.random.choice(eval_minibatch_size)\n",
"\n",
"orig_image = img_data[idx,:,:]\n",
"decoded_image = model.eval(orig_image)[0]*255\n",
"\n",
"# Print image statistics\n",
"def print_image_stats(img, text):\n",
" print(text)\n",
" print(\"Max: {0:.2f}, Median: {1:.2f}, Mean: {2:.2f}, Min: {3:.2f}\".format(np.max(img),\n",
" np.median(img),\n",
" np.mean(img),\n",
" np.min(img))) \n",
" \n",
"# Print original image\n",
"print_image_stats(orig_image, \"Original image statistics:\")\n",
"\n",
"# Print decoded image\n",
"print_image_stats(decoded_image, \"Decoded image statistics:\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"Let us plot the original and the decoded image. They should look visually similar."
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": true,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
"# Define a helper function to plot a pair of images\n",
"def plot_image_pair(img1, text1, img2, text2):\n",
" fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(6, 6))\n",
"\n",
" axes[0].imshow(img1, cmap=\"gray\")\n",
" axes[0].set_title(text1)\n",
" axes[0].axis(\"off\")\n",
"\n",
" axes[1].imshow(img2, cmap=\"gray\")\n",
" axes[1].set_title(text2)\n",
" axes[1].axis(\"off\")"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x1c9e983f470>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Plot the original and the decoded image\n",
"img1 = orig_image.reshape(28,28)\n",
"text1 = 'Original image'\n",
"\n",
"img2 = decoded_image.reshape(28,28)\n",
"text2 = 'Decoded image'\n",
"\n",
"plot_image_pair(img1, text1, img2, text2)"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true,
"deletable": true,
"editable": true
},
"source": [
"## Model Creation (Deep AE)\n",
"\n",
"We do not have to limit ourselves to a single layer as encoder or decoder, we could instead use a stack of dense layers. Let us create a deep autoencoder."
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"data": {
"text/html": [
"<img src=\"http://cntk.ai/jup/DeepAEfig.jpg\" width=\"500\" height=\"300\"/>"
],
"text/plain": [
"<IPython.core.display.Image object>"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Figure 3\n",
"Image(url=\"http://cntk.ai/jup/DeepAEfig.jpg\", width=500, height=300)"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"The encoding dimensions are 128, 64 and 32 while the decoding dimensions are symmetrically opposite 64, 128 and 784. This increases the number of parameters used to model the transformation and achieves lower error rates at the cost of longer training duration and memory footprint. If we train this deep encoder for larger number iterations by turning the `isFast` flag to be `False`, we get a lower error and the reconstructed images are also marginally better. "
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"collapsed": true,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
"input_dim = 784\n",
"encoding_dims = [128,64,32]\n",
"decoding_dims = [64,128]\n",
"\n",
"encoded_model = None\n",
"\n",
"def create_deep_model(features):\n",
" with C.layers.default_options(init = C.layers.glorot_uniform()):\n",
" encode = C.element_times(C.constant(1.0/255.0), features)\n",
"\n",
" for encoding_dim in encoding_dims:\n",
" encode = C.layers.Dense(encoding_dim, activation = C.relu)(encode)\n",
"\n",
" global encoded_model\n",
" encoded_model= encode\n",
" \n",
" decode = encode\n",
" for decoding_dim in decoding_dims:\n",
" decode = C.layers.Dense(decoding_dim, activation = C.relu)(decode)\n",
"\n",
" decode = C.layers.Dense(input_dim, activation = C.sigmoid)(decode)\n",
" return decode "
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" average since average since examples\n",
" loss last metric last \n",
" ------------------------------------------------------\n",
"Learning rate per sample: 3e-05\n",
" 543 543 0.928 0.928 64\n",
" 543 543 0.925 0.923 192\n",
" 543 543 0.907 0.894 448\n",
" 542 541 0.891 0.877 960\n",
" 527 513 0.768 0.652 1984\n",
" 411 299 0.63 0.496 4032\n",
" 313 217 0.547 0.466 8128\n",
" 260 206 0.476 0.405 16320\n",
" 220 181 0.377 0.278 32704\n",
" 183 146 0.275 0.174 65472\n",
" 150 118 0.185 0.0947 131008\n",
" 125 100 0.119 0.0531 262080\n",
"Average training error: 10.90%\n",
"Average test error: 3.37%\n"
]
}
],
"source": [
"num_label_classes = 10\n",
"reader_train = create_reader(train_file, True, input_dim, num_label_classes)\n",
"reader_test = create_reader(test_file, False, input_dim, num_label_classes)\n",
"\n",
"model, deep_ae_train_error, deep_ae_test_error = train_and_test(reader_train, \n",
" reader_test, \n",
" model_func = create_deep_model) "
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"## Visualize deep AE results"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Original image statistics:\n",
"Max: 255.00, Median: 0.00, Mean: 24.07, Min: 0.00\n",
"Decoded image statistics:\n",
"Max: 250.92, Median: 0.01, Mean: 23.60, Min: 0.00\n"
]
}
],
"source": [
"# Run the same image as the simple autoencoder through the deep encoder\n",
"orig_image = img_data[idx,:,:]\n",
"decoded_image = model.eval(orig_image)[0]*255\n",
"\n",
"# Print image statistics\n",
"def print_image_stats(img, text):\n",
" print(text)\n",
" print(\"Max: {0:.2f}, Median: {1:.2f}, Mean: {2:.2f}, Min: {3:.2f}\".format(np.max(img),\n",
" np.median(img),\n",
" np.mean(img),\n",
" np.min(img))) \n",
" \n",
"# Print original image\n",
"print_image_stats(orig_image, \"Original image statistics:\")\n",
"\n",
"# Print decoded image\n",
"print_image_stats(decoded_image, \"Decoded image statistics:\")\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"Let us plot the original and the decoded image with the deep autoencoder. They should look visually similar."
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"data": {
"image/png": "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\n2oZhGCni/wMkAI0XfxjStgAAAABJRU5ErkJggg==\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x1c9970a1f28>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Plot the original and the decoded image\n",
"img1 = orig_image.reshape(28,28)\n",
"text1 = 'Original image'\n",
"\n",
"img2 = decoded_image.reshape(28,28)\n",
"text2 = 'Decoded image'\n",
"\n",
"plot_image_pair(img1, text1, img2, text2)"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"We have shown how to encode and decode an input. In this section we will explore how we can compare one to another and also show how to extract an encoded input for a given input. For visualizing high dimension data in 2D, [t-SNE](http://scikit-learn.org/stable/modules/generated/sklearn.manifold.TSNE.html) is probably one of the best methods. However, it typically requires relatively low-dimensional data. So a good strategy for visualizing similarity relationships in high-dimensional data is to encode data into a low-dimensional space (e.g. 32 dimensional) using an autoencoder first, extract the encoding of the input data followed by using t-SNE for mapping the compressed data to a 2D plane. \n",
"\n",
"We will use the deep autoencoder outputs to:\n",
"- Compare two images and\n",
"- Show how we can retrieve an encoded (compressed) data. \n",
"\n",
"First we need to read some image data along with their labels. "
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"collapsed": true,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
"# Read some data to run get the image data and the corresponding labels\n",
"num_label_classes = 10\n",
"reader_viz = create_reader(test_file, False, input_dim, num_label_classes)\n",
"\n",
"image = C.input_variable(input_dim)\n",
"image_label = C.input_variable(num_label_classes)\n",
"\n",
"viz_minibatch_size = 50\n",
"\n",
"viz_input_map = { \n",
" image : reader_viz.streams.features, \n",
" image_label : reader_viz.streams.labels_viz \n",
"} \n",
" \n",
"viz_data = reader_eval.next_minibatch(viz_minibatch_size,\n",
" input_map = viz_input_map)\n",
"\n",
"img_data = viz_data[image].asarray()\n",
"imglabel_raw = viz_data[image_label].asarray()"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1: [7, 24, 39, 44, 46]\n",
"3: [1, 13, 18, 26, 37, 40, 43]\n",
"9: [8, 12, 23, 28, 42, 49]\n"
]
}
],
"source": [
"# Map the image labels into indices in minibatch array\n",
"img_labels = [np.argmax(imglabel_raw[i,:,:]) for i in range(0, imglabel_raw.shape[0])] \n",
" \n",
"from collections import defaultdict\n",
"label_dict=defaultdict(list)\n",
"for img_idx, img_label, in enumerate(img_labels):\n",
" label_dict[img_label].append(img_idx) \n",
" \n",
"# Print indices corresponding to 3 digits\n",
"randIdx = [1, 3, 9]\n",
"for i in randIdx:\n",
" print(\"{0}: {1}\".format(i, label_dict[i]))"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"We will [compute cosine distance](https://en.wikipedia.org/wiki/Cosine_similarity) between two images using `scipy`. "
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"collapsed": true,
"deletable": true,
"editable": true
},
"outputs": [],
"source": [
"from scipy import spatial\n",
"\n",
"def image_pair_cosine_distance(img1, img2):\n",
" if img1.size != img2.size:\n",
" raise ValueError(\"Two images need to be of same dimension\")\n",
" return 1 - spatial.distance.cosine(img1, img2)"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Distance between two original image: 0.294\n",
"Distance between two decoded image: 0.346\n"
]
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x1c99ac127b8>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAW0AAADDCAYAAABJYEAIAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJztfXmMbN9a1do9VM/T/f3uj/d4+BhMIBEjJorEmKhANA4Y\nTYjRaIIBJZioQRMDEjXGEBATCCRGFBExDjHigEQ0RIMDoBCFkAg+DDK+h7zfcG/fvt19e7g9HP/o\nWqfXWfXtU9X39lR9v5Wc1OmuqlPnVO29ztrr+/a3S9M0SCQSicR0YOauTyCRSCQSkyNJO5FIJKYI\nSdqJRCIxRUjSTiQSiSlCknYikUhMEZK0E4lEYoqQpH1NKKX8jlLKJ27ivaWUvVLKZ7zquSUSr4Ns\n2/cLU0/apZRfKqUclFKel1K2Syk/Ukr5qlJKuYPTeZ2k9+p7m6ZZa5rml17j2DeOUsrnllJ+oJTy\nQSnl7K7P5yEg2/b9QCnly0opPz78HT5eSvmbpZQ7486pJ21cNIjf3zTNBoBPB/BNAL4WwHfd6Vm9\neTgB8M8BfMVdn8gDQrbt+4ElAF8N4C0AXwDgiwH8xbs6mYdA2gBQAKBpmr2mab4fwB8B8CdKKb8O\nAEopg1LKN5dSfrmU8slSyreXUhbaN5fyB0spPzm8k/7fUsrvHv7/w6WU7yulPC2l/Gwp5U/JexZL\nKf9wqIB+GsDnd07o4r3/spTyfinl50spf27S945cXCnnpZTPGu5/dynlb5dS/v1waPnDpZRPKaV8\n6/B4HyulfJ6892tLKT9XStktpfx0KeUPyXMzpZRvGarjny+l/JnhZ80Mn18vpfz9UsqvllI+UUr5\n+prKa5rmZ5um+W4AHxvzWyWuhmzbd9+2v6Npmv/WNM1p0zSfBPBPAfy2/p/tBtE0zVRvAH4RwBcF\n//9lAF813P9WAP8GwAaAFQDfB+Abhs/9FgA7PAaADwP47OH+DwH4WwDmAXwegPcB/M7hc98E4L8O\nj/kRAD8F4OPD5wqAHwfwlwHMAvgMAD8H4HeNe2/lGs8AfNZw/7uH5/EbAQwA/CCAXwDwx4ef+/UA\n/pO890sBfMpw/w8D2Je//zSAnx5e8waA/zj8rJnh898L4NsBLAJ4G8CPAfjKMb/HrwVwdtft4iFs\n2bbvV9uWz/1eAN94Z+3irhvmDTbsHwXwdcP9fQCfKc/9VgC/MNz/uwC+JXj/p+FiyL8s//tGAP9g\n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\nAElFTkSuQmCC\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x1c999c65a58>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Let s compute the distance between two images of the same number\n",
"digit_of_interest = 6\n",
"\n",
"digit_index_list = label_dict[digit_of_interest]\n",
"\n",
"if len(digit_index_list) < 2:\n",
" print(\"Need at least two images to compare\")\n",
"else:\n",
" imgA = img_data[digit_index_list[0],:,:][0] \n",
" imgB = img_data[digit_index_list[1],:,:][0]\n",
" \n",
" # Print distance between original image\n",
" imgA_B_dist = image_pair_cosine_distance(imgA, imgB)\n",
" print(\"Distance between two original image: {0:.3f}\".format(imgA_B_dist))\n",
" \n",
" # Plot the two images\n",
" img1 = imgA.reshape(28,28)\n",
" text1 = 'Original image 1'\n",
"\n",
" img2 = imgB.reshape(28,28)\n",
" text2 = 'Original image 2'\n",
"\n",
" plot_image_pair(img1, text1, img2, text2)\n",
" \n",
" # Decode the encoded stream \n",
" imgA_decoded = model.eval([imgA])[0]\n",
" imgB_decoded = model.eval([imgB]) [0] \n",
" imgA_B_decoded_dist = image_pair_cosine_distance(imgA_decoded, imgB_decoded)\n",
"\n",
" # Print distance between original image\n",
" print(\"Distance between two decoded image: {0:.3f}\".format(imgA_B_decoded_dist))\n",
" \n",
" # Plot the two images\n",
" # Plot the original and the decoded image\n",
" img1 = imgA_decoded.reshape(28,28)\n",
" text1 = 'Decoded image 1'\n",
"\n",
" img2 = imgB_decoded.reshape(28,28)\n",
" text2 = 'Decoded image 2'\n",
"\n",
" plot_image_pair(img1, text1, img2, text2)"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"Note: The cosine distance between the original images comparable to the distance between the corresponding decoded images. A value of 1 indicates high similarity between the images and 0 indicates no similarity.\n",
"\n",
"Let us now see how to get the encoded vector corresponding to an input image. This should have the dimension of the choke point in the network shown in the figure with the box labeled `E`."
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Length of the original image is 784 and the encoded image is 32\n",
"\n",
"The encoded image: \n",
"[ 0. 22.22325325 3.9777317 13.26123905 9.97513866 0.\n",
" 13.37649727 6.18241978 5.78068304 12.50789165 20.11767769\n",
" 9.77285862 0. 14.75064278 17.07588768 0. 3.6076715\n",
" 8.29384613 20.11726952 15.80433846 3.4400022 0. 0.\n",
" 14.63469696 3.61723995 15.29668236 10.98176098 7.29611969\n",
" 16.65932465 9.66042233 5.93092394 0. ]\n"
]
}
],
"source": [
"imgA = img_data[digit_index_list[0],:,:][0] \n",
"imgA_encoded = encoded_model.eval([imgA])\n",
"\n",
"print(\"Length of the original image is {0:3d} and the encoded image is {1:3d}\".format(len(imgA), \n",
" len(imgA_encoded[0])))\n",
"print(\"\\nThe encoded image: \")\n",
"print(imgA_encoded[0])"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"Let us compare the distance between different digits."
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Distance between two original image: 0.376\n",
"Distance between two decoded image: 0.421\n"
]
},
{
"data": {
"image/png": "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\nBoHG4d4AAAAASUVORK5CYII=\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x1c99ac28780>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAW0AAADDCAYAAABJYEAIAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJztfXuofO9e1uedvffMnr1n377f789z9NjxEihkZFAmEVQq\nRRejQKIoMLTEoMKC0KQiQjQDRSGyzMzoQmQXkyyksItaSilC2jHM6znm8Zzzve3bzJ6ZPbP6Y8+z\nvs965vOumX3fa+bzwGKtvee2Lp/3Wc/7fD7vu1JRFBYIBAKBZqD12DsQCAQCgeURpB0IBAINQpB2\nIBAINAhB2oFAINAgBGkHAoFAgxCkHQgEAg1CkPYdIaX0O1JKH7mPz6aUTlNKn37TfQsEboOI7aeF\nxpN2SukXU0r9lNJxSul1SumHU0pfmVJKj7A7tyl6z362KIq9oih+8Rbffe9IKX1OSun7U0qfSClN\nHnt/VgER208DKaUvTSn92Ow6fDil9DdTSo/GnY0nbbsKiN9fFMWBmX2amX2jmX2NmX3no+7V+mFs\nZv/czL78sXdkhRCx/TTQNbOvMrPnZvb5ZvZFZvYXH2tnVoG0zcySmVlRFKdFUXyfmf0RM/sTKaVf\nZ2aWUmqnlL4ppfRLKaWPppS+LaXUKT+c0h9MKf3E7E76f1NKv3v2/09OKX1vSulVSulnUkp/ij6z\nnVL6hzMF9FNm9nmVHbr67L9MKX08pfRzKaU/t+xn5w4upWlK6TNn29+VUvrbKaV/P+ta/lBK6X0p\npW+Zfd+HUkqfS5/9mpTSz6aUTlJKP5VS+kP0Wiul9M0zdfxzKaU/M/ut1uz1/ZTS308p/UpK6SMp\npa/LqbyiKH6mKIrvMrMPLbhWgeshYvvxY/vbi6L4b0VRXBZF8VEz+6dm9tvqL9s9oiiKRi9m9gtm\n9oXO/3/JzL5ytv0tZvZvzOzAzHbN7HvN7Otnr/0WM3uL7zCzTzazz5pt/6CZ/S0z2zKzzzWzj5vZ\n75y99o1m9l9n3/kBM/tJM/vw7LVkZj9mZn/ZzDbM7NPN7GfN7Hct+mzmGCdm9pmz7e+a7cdvNLO2\nmf2Amf28mf3x2e9+nZn9J/rsl5jZ+2bbf9jMzujvP21mPzU75gMz+4+z32rNXv8eM/s2M9s2sxdm\n9qNm9hULrsevNbPJY8fFKiwR208rtul3v8fMvuHR4uKxA/MeA/tHzOxrZ9tnZvYZ9NpvNbOfn23/\nXTP7Zufzn2pXXf4d+t83mNk/mG3/HAJ19vdXUGB/vpn9onzfXzKz71z02cwxTiWwv51e+7Nm9r/p\n719vZq9rvusnzOwPzLZ/gAPVrrp9E7vqgb3PzC7MrEOv/1FuNJnvD9K+oyVi+2nF9ux9X25mHzaz\nZ48VF5u2uviAmb1OKb1nZjtm9uPU+2nZrNtpZr/GzP6d8/lPsasA6dP/fsnMfhO9/svyGvBBM/tA\nSun17O80+80fXOKzy+BjtD1w/u7hj5TSl5rZX7ArRWR2pcZe0H5wZp+3P2hXKuyjs/OWZsuHr7mv\ngbtHxLY9fGzP7JevN7MvKoridd177xMrSdoppc+zq4v2Q2b20sz6ZvY5xZUfpfiIXalDxa+Y2bOU\n0m5RFOez/33QzP7fbPujdtUofnr296fJd/58URSfndnFX6n57J0hpfRBM/t7ZvYFRVH8yOx/P2Hv\nGvVH7Up1AR+k7Y/YlRp5XswkRuDxEbF9hYeO7ZTS7zGzbzez31cUxaPmbVYlEWlmZimlvZTSF5vZ\nPzOzf1wUxYdmF+U7zOxbZ8rEUkofQELGrjLxX5ZS+oJ0hU9JKX12URS/bGb/3cz+Rkqpk1L6DWb2\nJ83sH88+991m9rUppcOU0qfaVVcO+B9mdppS+upZYmYjXZXE/ebZ6/+i5rN3cipm61276n6+nCVm\nvsyuupjAd5vZV82O+dDMvhovFEXxq2b2H8zsW2bnNaWUPjOl9NuzP3qVAOtcbaZOSql9x8e1tojY\nfncqZusHi+2U0hea2T8xsy8piuLH7/h4ro1VIe1/m1I6tqvuzdea2TdZtfTsa+wqWfKjKaW3dnXB\nPsvMrCiK/2lmX2Zm32pmx2b2X+zdXfmPmdln2JV6+Fdm9leLovjPs9f++uz3fsHMvt/M/hF+rCiK\nqZl9sV0lVH7BrpIr32Fm+4s+m8F1lW4x24+fNrNvtqsky6+a2eeY2Q/T+77Drs7F/zKzH7errvTl\nbP/NzL7UrhJCHzKz13bVIN/v/WBK6dPsqvv6k7PfH5jZ/7nmfgfmEbHtvP8hY9vM/opdHR+qWk5S\nSp7t9CBI0fMNALMu4N8piuIzHntfAoG7xCrF9qoo7cANMOve/t5ZF/cDZvbXzOxfP/Z+BQK3xSrH\ndijtNUZKqWtXNbWfbVd2xveZ2Z8viuLsUXcsELglVjm2g7QDgUCgQQh7JBAIBBqEe6/TTimFlA/c\n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\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x1c996d2bf28>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"digitA = 3\n",
"digitB = 8\n",
"\n",
"digitA_index = label_dict[digitA]\n",
"digitB_index = label_dict[digitB]\n",
"\n",
"imgA = img_data[digitA_index[0],:,:][0] \n",
"imgB = img_data[digitB_index[0],:,:][0]\n",
"\n",
"# Print distance between original image\n",
"imgA_B_dist = image_pair_cosine_distance(imgA, imgB)\n",
"print(\"Distance between two original image: {0:.3f}\".format(imgA_B_dist))\n",
" \n",
"# Plot the two images\n",
"img1 = imgA.reshape(28,28)\n",
"text1 = 'Original image 1'\n",
"\n",
"img2 = imgB.reshape(28,28)\n",
"text2 = 'Original image 2'\n",
"\n",
"plot_image_pair(img1, text1, img2, text2)\n",
" \n",
"# Decode the encoded stream \n",
"imgA_decoded = model.eval([imgA])[0]\n",
"imgB_decoded = model.eval([imgB])[0] \n",
"imgA_B_decoded_dist = image_pair_cosine_distance(imgA_decoded, imgB_decoded)\n",
"\n",
"#Print distance between original image\n",
"print(\"Distance between two decoded image: {0:.3f}\".format(imgA_B_decoded_dist))\n",
"\n",
"# Plot the original and the decoded image\n",
"img1 = imgA_decoded.reshape(28,28)\n",
"text1 = 'Decoded image 1'\n",
"\n",
"img2 = imgB_decoded.reshape(28,28)\n",
"text2 = 'Decoded image 2'\n",
"\n",
"plot_image_pair(img1, text1, img2, text2)"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"Print the results of the deep encoder test error for regression testing"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"3.11675742686\n"
]
}
],
"source": [
"# Simple autoencoder test error\n",
"print(simple_ae_test_error)"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {
"collapsed": false,
"deletable": true,
"editable": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"3.37320691249\n"
]
}
],
"source": [
"# Deep autoencoder test error\n",
"print(deep_ae_test_error)"
]
},
{
"cell_type": "markdown",
"metadata": {
"deletable": true,
"editable": true
},
"source": [
"**Suggested tasks**\n",
"\n",
"- Try different activation functions.\n",
"- Find which images are more similar to one another (a) using original image and (b) decoded image.\n",
"- Try using mean square error as the loss function. Does it improve the performance of the encoder in terms of reduced errors.\n",
"- Can you try different network structure to reduce the error further. Explain your observations.\n",
"- Can you use a different distance metric to compute similarity between the MNIST images.\n",
"- Try a deep encoder with [1000, 500, 250, 128, 64, 32]. What is the training error for same number of iterations? "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true,
"deletable": true,
"editable": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"anaconda-cloud": {},
"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.5.3"
}
},
"nbformat": 4,
"nbformat_minor": 1
}