{ "cells": [ { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import scipy \n", "import matplotlib.pyplot as plt\n", "from sklearn.neural_network import BernoulliRBM\n", "from sklearn.model_selection import train_test_split\n", "\n", "from tensorflow.keras.datasets import mnist\n", "from joblib import dump, load" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/mnist.npz\n", "11493376/11490434 [==============================] - 1s 0us/step\n", "11501568/11490434 [==============================] - 1s 0us/step\n" ] } ], "source": [ "# Dataset\n", "(X_train, X_test), (X_test, Y_test) = mnist.load_data()\n", "\n", "X_train = X_train.reshape(-1, 784)/255\n", "X_test = X_test.reshape(-1, 784)/255\n", "\n", "# Apply a threshold to binarize the image.\n", "X_train = np.where(X_train > 0.2, 1, 0)\n", "X_test = np.where(X_test > 0.2, 1, 0)\n", "\n", "# Split into training and validation sets\n", "X_train, X_val = train_test_split(X_train, test_size=1/5,random_state=42)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "plt.figure(figsize=(8,4))\n", "\n", "for i in range(10):\n", " plt.subplot(2,5,i+1)\n", " plt.xticks([])\n", " plt.yticks([])\n", " plt.grid(False)\n", " plt.imshow(X_train[10+i].reshape(28,28), cmap='Greys')\n", "plt.tight_layout()" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[BernoulliRBM] Iteration 1, pseudo-likelihood = -139.27, time = 2.79s\n", "[BernoulliRBM] Iteration 2, pseudo-likelihood = -119.16, time = 3.42s\n", "[BernoulliRBM] Iteration 3, pseudo-likelihood = -109.16, time = 4.41s\n", "[BernoulliRBM] Iteration 4, pseudo-likelihood = -102.69, time = 3.73s\n", "[BernoulliRBM] Iteration 5, pseudo-likelihood = -99.14, time = 3.60s\n", "[BernoulliRBM] Iteration 6, pseudo-likelihood = -96.40, time = 3.66s\n", "[BernoulliRBM] Iteration 7, pseudo-likelihood = -93.37, time = 3.70s\n", "[BernoulliRBM] Iteration 8, pseudo-likelihood = -91.71, time = 3.79s\n", "[BernoulliRBM] Iteration 9, pseudo-likelihood = -90.85, time = 3.83s\n", "[BernoulliRBM] Iteration 10, pseudo-likelihood = -88.74, time = 4.12s\n", "[BernoulliRBM] Iteration 11, pseudo-likelihood = -87.61, time = 4.77s\n", "[BernoulliRBM] Iteration 12, pseudo-likelihood = -87.75, time = 5.58s\n", "[BernoulliRBM] Iteration 13, pseudo-likelihood = -85.93, time = 5.29s\n", "[BernoulliRBM] Iteration 14, pseudo-likelihood = -85.74, time = 4.93s\n", "[BernoulliRBM] Iteration 15, pseudo-likelihood = -84.48, time = 5.00s\n", "[BernoulliRBM] Iteration 16, pseudo-likelihood = -84.49, time = 4.30s\n", "[BernoulliRBM] Iteration 17, pseudo-likelihood = -83.59, time = 4.14s\n", "[BernoulliRBM] Iteration 18, pseudo-likelihood = -84.24, time = 4.10s\n", "[BernoulliRBM] Iteration 19, pseudo-likelihood = -82.60, time = 5.32s\n", "[BernoulliRBM] Iteration 20, pseudo-likelihood = -81.76, time = 4.62s\n", "[BernoulliRBM] Iteration 21, pseudo-likelihood = -82.32, time = 4.74s\n", "[BernoulliRBM] Iteration 22, pseudo-likelihood = -82.35, time = 4.07s\n", "[BernoulliRBM] Iteration 23, pseudo-likelihood = -80.71, time = 4.07s\n", "[BernoulliRBM] Iteration 24, pseudo-likelihood = -81.19, time = 4.15s\n", "[BernoulliRBM] Iteration 25, pseudo-likelihood = -80.09, time = 4.68s\n", "[BernoulliRBM] Iteration 26, pseudo-likelihood = -79.46, time = 4.88s\n", "[BernoulliRBM] Iteration 27, pseudo-likelihood = -79.23, time = 4.05s\n", "[BernoulliRBM] Iteration 28, pseudo-likelihood = -79.58, time = 4.66s\n", "[BernoulliRBM] Iteration 29, pseudo-likelihood = -78.54, time = 4.63s\n", "[BernoulliRBM] Iteration 30, pseudo-likelihood = -78.56, time = 5.00s\n", "[BernoulliRBM] Iteration 31, pseudo-likelihood = -78.92, time = 4.48s\n", "[BernoulliRBM] Iteration 32, pseudo-likelihood = -77.79, time = 4.01s\n", "[BernoulliRBM] Iteration 33, pseudo-likelihood = -77.17, time = 4.69s\n", "[BernoulliRBM] Iteration 34, pseudo-likelihood = -78.09, time = 5.33s\n", "[BernoulliRBM] Iteration 35, pseudo-likelihood = -78.10, time = 4.16s\n", "[BernoulliRBM] Iteration 36, pseudo-likelihood = -77.09, time = 3.97s\n", "[BernoulliRBM] Iteration 37, pseudo-likelihood = -76.62, time = 3.96s\n", "[BernoulliRBM] Iteration 38, pseudo-likelihood = -76.79, time = 3.98s\n", "[BernoulliRBM] Iteration 39, pseudo-likelihood = -76.82, time = 3.99s\n", "[BernoulliRBM] Iteration 40, pseudo-likelihood = -76.95, time = 3.95s\n", "[BernoulliRBM] Iteration 41, pseudo-likelihood = -75.60, time = 3.97s\n", "[BernoulliRBM] Iteration 42, pseudo-likelihood = -76.45, time = 3.96s\n", "[BernoulliRBM] Iteration 43, pseudo-likelihood = -76.30, time = 3.97s\n", "[BernoulliRBM] Iteration 44, pseudo-likelihood = -75.51, time = 4.00s\n", "[BernoulliRBM] Iteration 45, pseudo-likelihood = -75.48, time = 3.95s\n", "[BernoulliRBM] Iteration 46, pseudo-likelihood = -75.43, time = 3.99s\n", "[BernoulliRBM] Iteration 47, pseudo-likelihood = -75.19, time = 3.98s\n", "[BernoulliRBM] Iteration 48, pseudo-likelihood = -75.14, time = 3.93s\n", "[BernoulliRBM] Iteration 49, pseudo-likelihood = -76.25, time = 3.98s\n", "[BernoulliRBM] Iteration 50, pseudo-likelihood = -75.27, time = 3.94s\n", "[BernoulliRBM] Iteration 51, pseudo-likelihood = -74.75, time = 3.96s\n", "[BernoulliRBM] Iteration 52, pseudo-likelihood = -74.42, time = 3.92s\n", "[BernoulliRBM] Iteration 53, pseudo-likelihood = -75.16, time = 3.94s\n", "[BernoulliRBM] Iteration 54, pseudo-likelihood = -74.33, time = 3.96s\n", "[BernoulliRBM] Iteration 55, pseudo-likelihood = -74.27, time = 3.97s\n", "[BernoulliRBM] Iteration 56, pseudo-likelihood = -74.92, time = 3.98s\n", "[BernoulliRBM] Iteration 57, pseudo-likelihood = -74.60, time = 3.97s\n", "[BernoulliRBM] Iteration 58, pseudo-likelihood = -74.21, time = 4.00s\n", "[BernoulliRBM] Iteration 59, pseudo-likelihood = -74.07, time = 4.05s\n", "[BernoulliRBM] Iteration 60, pseudo-likelihood = -74.05, time = 4.05s\n", "[BernoulliRBM] Iteration 61, pseudo-likelihood = -74.28, time = 4.30s\n", "[BernoulliRBM] Iteration 62, pseudo-likelihood = -74.32, time = 4.06s\n", "[BernoulliRBM] Iteration 63, pseudo-likelihood = -74.63, time = 4.03s\n", "[BernoulliRBM] Iteration 64, pseudo-likelihood = -73.77, time = 4.15s\n", "[BernoulliRBM] Iteration 65, pseudo-likelihood = -73.59, time = 4.07s\n", "[BernoulliRBM] Iteration 66, pseudo-likelihood = -74.18, time = 4.11s\n", "[BernoulliRBM] Iteration 67, pseudo-likelihood = -73.97, time = 4.16s\n", "[BernoulliRBM] Iteration 68, pseudo-likelihood = -73.35, time = 4.09s\n", "[BernoulliRBM] Iteration 69, pseudo-likelihood = -73.74, time = 4.08s\n", "[BernoulliRBM] Iteration 70, pseudo-likelihood = -73.17, time = 4.10s\n", "[BernoulliRBM] Iteration 71, pseudo-likelihood = -72.99, time = 4.09s\n", "[BernoulliRBM] Iteration 72, pseudo-likelihood = -73.81, time = 4.16s\n", "[BernoulliRBM] Iteration 73, pseudo-likelihood = -74.49, time = 4.15s\n", "[BernoulliRBM] Iteration 74, pseudo-likelihood = -73.50, time = 4.10s\n", "[BernoulliRBM] Iteration 75, pseudo-likelihood = -72.65, time = 4.12s\n", "[BernoulliRBM] Iteration 76, pseudo-likelihood = -74.50, time = 4.19s\n", "[BernoulliRBM] Iteration 77, pseudo-likelihood = -73.83, time = 4.15s\n", "[BernoulliRBM] Iteration 78, pseudo-likelihood = -73.32, time = 4.16s\n", "[BernoulliRBM] Iteration 79, pseudo-likelihood = -72.03, time = 4.21s\n", "[BernoulliRBM] Iteration 80, pseudo-likelihood = -73.27, time = 4.10s\n", "[BernoulliRBM] Iteration 81, pseudo-likelihood = -73.44, time = 4.13s\n", "[BernoulliRBM] Iteration 82, pseudo-likelihood = -72.98, time = 4.06s\n", "[BernoulliRBM] Iteration 83, pseudo-likelihood = -72.57, time = 4.19s\n", "[BernoulliRBM] Iteration 84, pseudo-likelihood = -73.74, time = 4.19s\n", "[BernoulliRBM] Iteration 85, pseudo-likelihood = -73.09, time = 4.12s\n", "[BernoulliRBM] Iteration 86, pseudo-likelihood = -72.51, time = 4.12s\n", "[BernoulliRBM] Iteration 87, pseudo-likelihood = -72.67, time = 4.09s\n", "[BernoulliRBM] Iteration 88, pseudo-likelihood = -72.87, time = 4.12s\n", "[BernoulliRBM] Iteration 89, pseudo-likelihood = -72.88, time = 4.09s\n", "[BernoulliRBM] Iteration 90, pseudo-likelihood = -72.53, time = 4.16s\n", "[BernoulliRBM] Iteration 91, pseudo-likelihood = -71.96, time = 4.19s\n", "[BernoulliRBM] Iteration 92, pseudo-likelihood = -73.49, time = 4.10s\n", "[BernoulliRBM] Iteration 93, pseudo-likelihood = -72.57, time = 4.20s\n", "[BernoulliRBM] Iteration 94, pseudo-likelihood = -72.31, time = 4.16s\n", "[BernoulliRBM] Iteration 95, pseudo-likelihood = -71.32, time = 4.15s\n", "[BernoulliRBM] Iteration 96, pseudo-likelihood = -72.19, time = 4.11s\n", "[BernoulliRBM] Iteration 97, pseudo-likelihood = -72.97, time = 4.10s\n", "[BernoulliRBM] Iteration 98, pseudo-likelihood = -71.58, time = 4.05s\n", "[BernoulliRBM] Iteration 99, pseudo-likelihood = -72.43, time = 4.10s\n", "[BernoulliRBM] Iteration 100, pseudo-likelihood = -72.62, time = 4.09s\n" ] }, { "data": { "text/plain": [ "BernoulliRBM(batch_size=20, learning_rate=0.01, n_components=100, n_iter=100,\n", " random_state=0, verbose=True)" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rbm = BernoulliRBM(random_state=0, n_components=100,\n", " verbose=True, batch_size=20, n_iter=100, learning_rate=0.01)\n", "\n", "rbm.fit(X_train)" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Training set Pseudo-Likelihood = -72.62279377820806\n", "Validation set Pseudo-Likelihood = -75.86983167432844\n" ] } ], "source": [ "print(\"Training set Pseudo-Likelihood =\", rbm.score_samples(X_train).mean())\n", "print(\"Validation set Pseudo-Likelihood =\", rbm.score_samples(X_val).mean())" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Pick a random image from the test set\n", "im_ind = 10\n", "X_pick = X_test[im_ind]\n", "\n", "# Choose 50 random pixels to flip\n", "corr_pixels = 60\n", "pick = np.random.choice(28 * 28, corr_pixels)\n", "x_noisy = np.copy(X_pick)\n", "x_noisy[pick] = ((X_pick[pick] + 1) % 2)\n", "\n", "\n", "# Perform the denoising\n", "k_iter = 12 # Number of Gibbs Sampling Iterations\n", "alpha = 0.9 # Decay factor for the averaging\n", "\n", "# Gibb sampling steps\n", "b = rbm.gibbs(x_noisy)\n", "x_final = np.zeros(784) + np.copy(b)\n", "for i in range(k_iter):\n", " b = rbm.gibbs(b)\n", " x_final += (alpha**(i+1))*b.astype(float) # Averaging the images\n", "\n", "# Applying a threshold to binarize the image\n", "x_final = np.where(x_final > 0.5*np.max(x_final), 1, 0)\n", "\n", "# Plotting the images\n", "fig, ax = plt.subplots(1, 3, figsize=(10, 3))\n", "ax[0].imshow(X_pick.reshape(28, 28), cmap='Greys')\n", "ax[0].set_title('Original')\n", "ax[1].imshow(x_noisy.reshape(28, 28), cmap='Greys')\n", "ax[1].set_title('Corrupted')\n", "ax[2].imshow(x_final.reshape(28, 28), cmap='Greys')\n", "for i in range(3):\n", " ax[i].set_xticks([])\n", " ax[i].set_yticks([])\n", "ax[2].set_title('De-Noised')\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Pick another random image and set some parts of the image to zero.\n", "im_ind = 15\n", "X_missing = X_test[im_ind].copy().reshape(28,28)\n", "X_missing[:,15:] = 0\n", "\n", "# Image Reconstruction\n", "k_iter = 100 # Number of Gibbs iterations\n", "alpha = 0.9 # Decay factor\n", "\n", "X_recon = np.zeros((28,13)) # Array to store the reconstruction\n", "\n", "b = X_missing.copy().reshape(-1)\n", "for i in range(k_iter):\n", " b = rbm.gibbs(b)\n", " X_recon += alpha**(i) * b.reshape(28,28)[:,15:]\n", " b.reshape(28,28)[:,:15] = X_missing[:,:15]\n", "\n", "# Apply a threshold and complete the image\n", "X_recon = np.where(X_recon > 0.5*np.max(X_recon), 1, 0)\n", "X_complete = X_missing.copy()\n", "X_complete[:,15:] = X_recon\n", "\n", "# Plot the figures\n", "fig, ax = plt.subplots(1, 3, figsize=(10, 3))\n", "ax[0].imshow(X_test[im_ind].reshape(28, 28), cmap='Greys')\n", "ax[0].set_title('Original')\n", "ax[1].imshow(X_missing, cmap='Greys')\n", "ax[1].set_title('Corrupted')\n", "ax[2].imshow(X_complete.reshape(28,28), cmap='Greys')\n", "ax[2].set_title('Reconstructed')\n", "for i in range(3):\n", " ax[i].set_xticks([])\n", " ax[i].set_yticks([])\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.4" } }, "nbformat": 4, "nbformat_minor": 2 }