{ "cells": [ { "cell_type": "markdown", "id": "7947d01e5b89717a", "metadata": { "collapsed": false }, "source": [ "# Discrete Hopfield Network Demo for Image Reconstruction\n", "\n", "[![Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/brainpy/examples/blob/main/attractors/discrete_hopfield_demo_for_image_reconstruction.ipynb)\n", "[![Open in Kaggle](https://kaggle.com/static/images/open-in-kaggle.svg)](https://kaggle.com/kernels/welcome?src=https://github.com/brainpy/examples/blob/main/attractors/discrete_hopfield_demo_for_image_reconstruction.ipynb)" ] }, { "cell_type": "code", "execution_count": 15, "id": "bf2b97b7ccff8066", "metadata": { "ExecuteTime": { "end_time": "2023-10-06T05:59:26.144174700Z", "start_time": "2023-10-06T05:59:26.057839Z" }, "collapsed": false }, "outputs": [], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "\n", "import brainpy as bp\n", "import brainpy.math as bm" ] }, { "cell_type": "code", "execution_count": 16, "id": "d6c43fff-3397-4550-8a90-199fec94a3eb", "metadata": { "ExecuteTime": { "end_time": "2023-10-06T05:59:26.335098800Z", "start_time": "2023-10-06T05:59:26.063270800Z" } }, "outputs": [ { "data": { "text/plain": [ "'2.4.5.post4'" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bp.__version__ " ] }, { "cell_type": "markdown", "id": "653d7ff05e4ff7b5", "metadata": { "collapsed": false }, "source": [ "For the mathematical foundation of the discrete Hopfield network, please see [our previous tutorial](./discrete_hopfield_network.ipynb). " ] }, { "cell_type": "markdown", "id": "4dcff6d82661692e", "metadata": { "collapsed": false }, "source": [ "## Data for testing" ] }, { "cell_type": "markdown", "id": "d7d36b991d96db35", "metadata": { "collapsed": false }, "source": [ "Now we are going to load the data in. I have already saved off two images, a '9' and a '4', to keep things simple for us. We also reshape them into their native [28 x 28] size, so that we can later corrupt them in this domain, and then reconstruct them.\n", "\n", "The data can be downloaded in this url: https://github.com/brainpy/examples/blob/main/attractors/data/data_to_train_on.npy" ] }, { "cell_type": "code", "execution_count": 17, "id": "2e80471a082783f2", "metadata": { "ExecuteTime": { "end_time": "2023-10-06T05:59:26.350738300Z", "start_time": "2023-10-06T05:59:26.096889400Z" }, "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "(2, 784)" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data = (np.load('data/data_to_train_on.npy')).astype(np.float32)\n", "\n", "data.shape" ] }, { "cell_type": "markdown", "id": "a10182bb7478eb63", "metadata": { "collapsed": false }, "source": [ "What does our data look like? Well they are just two binary images, showing a figure '9', and a figure '4'. Let's image them just to take a peek at what they look like." ] }, { "cell_type": "code", "execution_count": 18, "id": "370870dfe2e248f3", "metadata": { "ExecuteTime": { "end_time": "2023-10-06T05:59:26.543340400Z", "start_time": "2023-10-06T05:59:26.101940500Z" }, "collapsed": false }, "outputs": [ { "data": { "image/png": "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40VRRKPRiOHh4Vi2bFmsX78+9u3bV82wi8zpjv2WLVtO+DNwzTXXVDPsIrFz5864+uqro7e3N1auXBkbN26M119/fd5znPPtcSbH3jlPVex5nWfP6wx7XnXsedWw61Vjqe956SLX7t27Y9u2bXH//ffHb3/727juuutifHw8Dh48WPVoi97nPve5OHTo0Nzt1VdfrXqkRefYsWNx+eWXx65du076+IMPPhgPPfRQ7Nq1K/bu3RuDg4Nx0003xZEjRzo86eJzumMfEXHzzTfP+zPw9NNPd3DCxWdycjK2bt0aL730UkxMTMR7770XY2NjcezYsbnnOOfb40yOfYRzns6z51XHntd+9rzq2POqYderxpLf84pkPv/5zxd33HHHvPs++9nPFl//+tcrmmhpeOCBB4rLL7+86jGWlIgonnjiibmP33///WJwcLD4l3/5l7n7/vSnPxX9/f3F97///QomXLw+euyLoig2b95cfOlLX6pknqViZmamiIhicnKyKArnfCd99NgXhXOeatjzqmHP6zx7XnXsedWx61Vjqe15qa7kOn78eLz88ssxNjY27/6xsbF48cUXK5pq6di/f38MDw/H6OhofOUrX4nf//73VY+0pBw4cCCmp6fnnf/1ej1uuOEG53+H7NmzJ1auXBmXXHJJ3H777TEzM1P1SItKs9mMiIjly5dHhHO+kz567D/gnKeT7HnVsudVy/e86vme1352vWostT0vVeR6++23489//nMMDAzMu39gYCCmp6crmmppWLt2bTz66KPxzDPPxA9/+MOYnp6OdevWxeHDh6sebcn44Bx3/ldjfHw8fvrTn8azzz4b3/nOd2Lv3r3xxS9+MWZnZ6sebVEoiiK2b98eX/jCF+LSSy+NCOd8p5zs2Ec45+k8e1517HnV8z2vWr7ntZ9drxpLcc/rqXqAs1Gr1eZ9XBTFCfdRrvHx8bl/vuyyy+Laa6+Nz3zmM/HjH/84tm/fXuFkS4/zvxq33nrr3D9feumlcdVVV8XIyEj84he/iE2bNlU42eJw1113xe9+97v41a9+dcJjzvn2OtWxd85TFX/mO8+e1z2c/9XwPa/97HrVWIp7XqoruVasWBHnn3/+CVV3ZmbmhPpLe33qU5+Kyy67LPbv31/1KEvGB7/lyPnfHYaGhmJkZMSfgRLcfffd8dRTT8Vzzz0Xq1atmrvfOd9+pzr2J+Ocp93sed3Dntd5vud1F9/zymXXq8ZS3fNSRa4LLrggrrzyypiYmJh3/8TERKxbt66iqZam2dnZeO2112JoaKjqUZaM0dHRGBwcnHf+Hz9+PCYnJ53/FTh8+HBMTU35M3AOiqKIu+66K372s5/Fs88+G6Ojo/Med863z+mO/ck452k3e173sOd1nu953cX3vHLY9aqx1Pe8dH9dcfv27fHVr341rrrqqrj22mvjBz/4QRw8eDDuuOOOqkdb1O65557YsGFDXHzxxTEzMxPf/va3o9VqxebNm6sebVE5evRovPHGG3MfHzhwIF555ZVYvnx5XHzxxbFt27bYsWNHrFmzJtasWRM7duyICy+8MG677bYKp14cPu7YL1++PBqNRnz5y1+OoaGhePPNN+Mb3/hGrFixIm655ZYKp85t69at8dhjj8XPf/7z6O3tnfspXn9/fyxbtixqtZpzvk1Od+yPHj3qnKcS9rxq2PM6w55XHXteNex61Vjye14Vv9LxXH33u98tRkZGigsuuKC44oor5v0qTNrj1ltvLYaGhopPfOITxfDwcLFp06Zi3759VY+16Dz33HNFRJxw27x5c1EUf/k1uw888EAxODhY1Ov14vrrry9effXVaodeJD7u2P/xj38sxsbGiosuuqj4xCc+UVx88cXF5s2bi4MHD1Y9dmonO94RUTzyyCNzz3HOt8fpjr1znirZ8zrPntcZ9rzq2POqYderxlLf82pFURTtyWcAAAAA0Bmp3pMLAAAAAE5G5AIAAAAgPZELAAAAgPRELgAAAADSE7kAAAAASE/kAgAAACA9kQsAAACA9EQuAAAAANITuQAAAABIT+QCAAAAID2RCwAAAID0RC4AAAAA0vt/xG5RfjFaA0EAAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Show the training data - it's just two different samples that we are going to want the Hopfield net to store.\n", "fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(15,7.5))\n", "ax[0].imshow(data[0].reshape(28, 28), interpolation='None', cmap='winter')\n", "ax[1].imshow(data[1].reshape(28, 28), interpolation='None', cmap='winter')\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "8984e9a625c31682", "metadata": { "collapsed": false }, "source": [ "We will use this function to take in a good image, and corrupt it, based on two types of noise, either bernouli noise, (where every pixel is randomly flipped in sign), or masking noise, where we blot out entire sections of the image. Our Hopfield net will be able to recover the original image via energy minimization as we will see." ] }, { "cell_type": "code", "execution_count": 19, "id": "42174d069b6e7329", "metadata": { "ExecuteTime": { "end_time": "2023-10-06T05:59:26.543340400Z", "start_time": "2023-10-06T05:59:26.432264300Z" }, "collapsed": false }, "outputs": [], "source": [ "def add_bernouli_noise(img, prob=0.1, mask_value=1.):\n", " rand = np.random.rand(*img.shape) < prob\n", " return np.where(rand, mask_value, img)" ] }, { "cell_type": "code", "execution_count": 20, "id": "c3f79136b1c4aef", "metadata": { "ExecuteTime": { "end_time": "2023-10-06T05:59:26.543340400Z", "start_time": "2023-10-06T05:59:26.438239200Z" }, "collapsed": false }, "outputs": [], "source": [ "def add_mask_noise(img, mask_value=-1, mask_matrix=np.zeros((2,2))):\n", " img = np.copy(img)\n", " img[mask_matrix[0,0]: mask_matrix[0,1], mask_matrix[1,0]: mask_matrix[1,1]] = mask_value\n", " return img" ] }, { "cell_type": "markdown", "id": "97bba2442ce8fbc3", "metadata": { "collapsed": false }, "source": [ "## Models" ] }, { "cell_type": "markdown", "id": "8b6d92b5b6e05c57", "metadata": { "collapsed": false }, "source": [ "We use our implementation in [Discrete Hopfield Network](./discrete_hopfield_network.ipynb). " ] }, { "cell_type": "code", "execution_count": 21, "id": "84f4ff0a1132cb82", "metadata": { "ExecuteTime": { "end_time": "2023-10-06T05:59:26.543340400Z", "start_time": "2023-10-06T05:59:26.480276400Z" }, "collapsed": false }, "outputs": [], "source": [ "class HopfieldNet(bp.DynamicalSystem):\n", " def __init__(self, num):\n", " super().__init__()\n", " self.num = num\n", " self.weight = bm.Variable(bm.zeros([num, num]))\n", "\n", " # Train function for the Hopfield net. (By updating the weights)\n", " @bm.cls_jit\n", " def store_patterns(self, samples):\n", " # data: An array with [d, N]. 'd' is the number of data samples used to train. (In this case 2)\n", " assert samples.ndim == 2\n", " assert samples.shape[1] == self.num\n", "\n", " # Loop through all data samples.\n", " bm.for_loop(self.store, samples)\n", "\n", " # Hopfield nets are a form of RNNs, albeit without self-connections, and so,\n", " # we need to make sure that the diagonal elements of the final weight matrix are zero.\n", " bm.fill_diagonal(self.weight, 0)\n", "\n", " # Storing one sample pattern\n", " @bm.cls_jit\n", " def store(self, sample):\n", " # sample is an array with the shape of (N,)\n", " assert self.num == sample.shape[0]\n", "\n", " # Data cross-product gives neural hopfield update rule.\n", " w_update = bm.outer(sample, sample)\n", "\n", " # Sum all pattern cross-products.\n", " self.weight += w_update\n", "\n", " def async_recover(self, sample, n, energy=False):\n", " # n: the number of iterations to recover\n", " # energy: calculate the energy function\n", " idxs = bm.random.randint(0, self.num, n) # the sampled positions\n", " # JIT compilation requires to label the value to be changed as Variable\n", " sample = bm.Variable(sample)\n", "\n", " def recover(i):\n", " # i: the position to update\n", " # update\n", " sample[i] = bm.sign(bm.inner(self.weight[i], sample))\n", " # return energy\n", " if energy:\n", " return self.energy(sample)\n", "\n", " r = bm.for_loop(recover, idxs) # for loop JIT\n", " return (sample, r) if energy else sample\n", "\n", " def sync_recover(self, sample, n, energy=False):\n", " # n: the number of iterations to recover\n", " # energy: calculate the energy function\n", " idxs = bm.arange(n) # the update times\n", " # JIT compilation requires to label the value to be changed as Variable\n", " sample = bm.Variable(sample)\n", "\n", " def recover(i):\n", " # i: the position to update\n", " # update\n", " sample.value = bm.sign(self.weight @ sample)\n", " # return energy\n", " if energy:\n", " return self.energy(sample)\n", "\n", " r = bm.for_loop(recover, idxs) # for loop JIT\n", " return (sample, r) if energy else sample\n", "\n", " # This function computes the Hopfield nets' energy.\n", " def energy(self, x):\n", " # x: [N] data vector\n", " return bm.inner(- x @ self.weight, x)" ] }, { "cell_type": "markdown", "id": "889dd820-7ec3-451d-be8c-c352e7f774a8", "metadata": {}, "source": [ "## Training" ] }, { "cell_type": "markdown", "id": "2530fb49-6ec5-48c5-9333-d9d016c58518", "metadata": { "collapsed": false }, "source": [ "OK this is where the fun begins! We are now going to train our Hopfield net. The objective is simple: We want it to store those two patterns we are feeding it, such that a faithful reconstruction can be performed, when corrupted versions of either of those inputs is given later in the future." ] }, { "cell_type": "code", "execution_count": 22, "id": "d1e30411c403bae8", "metadata": { "ExecuteTime": { "end_time": "2023-10-06T05:59:26.700059Z", "start_time": "2023-10-06T05:59:26.486904600Z" }, "collapsed": false }, "outputs": [], "source": [ "# Train the Hopfield net! \n", "\n", "# So there are as many neurons as pixels per pattern, and this is what this computes.\n", "net = HopfieldNet(num=data.shape[1])\n", "\n", "# Great - we are all set - now we train! \n", "net.store_patterns(data)" ] }, { "cell_type": "markdown", "id": "c58e21d7-2485-479c-9dc5-25c04208761e", "metadata": {}, "source": [ "Now at this point, we have a trained weight matrix, encoded with the pattern '4' and pattern '9'. (We will see later on that Hopfield nets aren't that memory efficient, but it's still amazing what they are capable of). Now remember - the objective here is simple: We want it to store those two patterns we are feeding it, such that faithful reconstruction can later be performed, when corrupted versions of either of those inputs are presented. But does it work? Let's find out!)." ] }, { "cell_type": "markdown", "id": "17240611-4415-47d5-abf1-e0e617c996cc", "metadata": {}, "source": [ "## Testing" ] }, { "cell_type": "markdown", "id": "b6f0723b-8582-410b-b567-d8dd975edcb3", "metadata": {}, "source": [ "We can corrupt our data in many ways - and here, we can add two types of noise: Bernouli noise, (where every pixel is flipped in sign with a certain probability) and/or masking noise, (where we simply blot out certain regions with one particular sign)." ] }, { "cell_type": "code", "execution_count": 23, "id": "6e0e0205-86f5-4d2d-9759-7b4dfd70073d", "metadata": { "ExecuteTime": { "end_time": "2023-10-06T05:59:26.904916Z", "start_time": "2023-10-06T05:59:26.604377700Z" } }, "outputs": [ { "data": { "image/png": "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XQcAkM3/zQ5/mSXoRF0z6zXnyzxYiccCKuf5YWnsFxFxrnNereiwSfD3v/99jIyMVL0MACCp6enpWLNmTdXL4BOY9QCA83W2Oa/jItcHH3wQ77zzTvT29katVvvExzWbzRgZGYnp6eno6+tr4wq7m32vjr2vhn2vhn2vTua9L4oijh8/HsPDw3HRRV6RoVOdy6yX+TzMzL5Xx95Xw75Xw75XJ/Pen+uc13G/rnjRRRct6aevfX196T45y4F9r469r4Z9r4Z9r07Wve/v7696CZzFUma9rOdhdva9Ova+Gva9Gva9Oln3/lzmPD/mBAAAACA9kQsAAACA9NJGrnq9Hg8//HDU6/Wql9JV7Ht17H017Hs17Ht17D2dwHlYDfteHXtfDfteDftenW7Y+4574XkAAAAAWKq0V3IBAAAAwIdELgAAAADSE7kAAAAASE/kAgAAACC9lJHre9/7XoyNjcVnP/vZuOqqq+LnP/951Uta9hqNRtRqtUW3wcHBqpe17Lz88suxcePGGB4ejlqtFs8+++yi9xdFEY1GI4aHh2PFihWxYcOGOHjwYDWLXWbOtvdbtmw57Wvguuuuq2axy8Tk5GRcc8010dvbG6tXr4477rgj3nzzzUWPcc63xrnsvXOeqpjz2s+c1x7mvOqY86ph1qtGt8956SLXM888E9u2bYuHHnoofv3rX8eNN94YExMTceTIkaqXtux96UtfiqNHjy7c3njjjaqXtOycPHkyrrzyyti1a9cZ3//II4/EY489Frt27YoDBw7E4OBg3HbbbXH8+PE2r3T5OdveR0Tcfvvti74GXnjhhTaucPnZv39/bN26NV599dWYmpqK999/P8bHx+PkyZMLj3HOt8a57H2Ec572M+dVx5zXeua86pjzqmHWq0bXz3lFMl/+8peL++67b9F9f/3Xf11861vfqmhF3eHhhx8urrzyyqqX0VUiovjRj3608PYHH3xQDA4OFt/97ncX7vuf//mfor+/v/iXf/mXCla4fH1874uiKDZv3lz83d/9XSXr6Razs7NFRBT79+8visI5304f3/uicM5TDXNeNcx57WfOq445rzpmvWp025yX6kquU6dOxWuvvRbj4+OL7h8fH49XXnmlolV1j0OHDsXw8HCMjY3FV77ylfjd735X9ZK6yuHDh2NmZmbR+V+v1+Pmm292/rfJvn37YvXq1XH55ZfHvffeG7Ozs1UvaVmZm5uLiIiVK1dGhHO+nT6+9x9yztNO5rxqmfOq5Xte9XzPaz2zXjW6bc5LFbnefffd+POf/xwDAwOL7h8YGIiZmZmKVtUdrr322njqqafixRdfjH/913+NmZmZWL9+fRw7dqzqpXWND89x5381JiYm4umnn469e/fGo48+GgcOHIhbb7015ufnq17aslAURWzfvj1uuOGGWLduXUQ459vlTHsf4Zyn/cx51THnVc/3vGr5ntd6Zr1qdOOc11P1As5HrVZb9HZRFKfdR7kmJiYW/nzFFVfE9ddfH3/1V38VTz75ZGzfvr3ClXUf53817r777oU/r1u3Lq6++uoYHR2N559/PjZt2lThypaH+++/P37zm9/EL37xi9Pe55xvrU/ae+c8VfE1337mvM7h/K+G73mtZ9arRjfOeamu5Fq1alVcfPHFp1Xd2dnZ0+ovrfW5z30urrjiijh06FDVS+kaH/4vR87/zjA0NBSjo6O+BkrwwAMPxHPPPRcvvfRSrFmzZuF+53zrfdLen4lznlYz53UOc177+Z7XWXzPK5dZrxrdOuelilyXXHJJXHXVVTE1NbXo/qmpqVi/fn1Fq+pO8/Pz8dvf/jaGhoaqXkrXGBsbi8HBwUXn/6lTp2L//v3O/wocO3YspqenfQ1cgKIo4v77748f/vCHsXfv3hgbG1v0fud865xt78/EOU+rmfM6hzmv/XzP6yy+55XDrFeNbp/z0v264vbt2+OrX/1qXH311XH99dfH97///Thy5Ejcd999VS9tWXvwwQdj48aNcdlll8Xs7Gx85zvfiWazGZs3b656acvKiRMn4q233lp4+/Dhw/H666/HypUr47LLLott27bFzp07Y+3atbF27drYuXNnXHrppXHPPfdUuOrl4dP2fuXKldFoNOKuu+6KoaGhePvtt+Pb3/52rFq1Ku68884KV53b1q1bY8+ePfHjH/84ent7F36K19/fHytWrIhareacb5Gz7f2JEyec81TCnFcNc157mPOqY86rhlmvGl0/51XxXzpeqH/+538uRkdHi0suuaT4m7/5m0X/FSatcffddxdDQ0PFZz7zmWJ4eLjYtGlTcfDgwaqXtey89NJLRUScdtu8eXNRFP/33+w+/PDDxeDgYFGv14ubbrqpeOONN6pd9DLxaXv/pz/9qRgfHy++8IUvFJ/5zGeKyy67rNi8eXNx5MiRqped2pn2OyKK3bt3LzzGOd8aZ9t75zxVMue1nzmvPcx51THnVcOsV41un/NqRVEUrclnAAAAANAeqV6TCwAAAADOROQCAAAAID2RCwAAAID0RC4AAAAA0hO5AAAAAEhP5AIAAAAgPZELAAAAgPRELgAAAADSE7kAAAAASE/kAgAAACA9kQsAAACA9EQuAAAAANL7X/CalUHwUhIYAAAAAElFTkSuQmCC", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Let's pick one the image '4', and corrupt it.\n", "image = data[1]\n", "\n", "# Corrupt the image with bernouli noise.\n", "corrupted_image = add_bernouli_noise(image, prob=0.1)\n", "\n", "# Let's see the original image, as well as the corrupted version.\n", "fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(15,7.5))\n", "ax[0].imshow(image.reshape(28, 28), interpolation='None', cmap='winter')\n", "ax[1].imshow(corrupted_image.reshape(28, 28), interpolation='None', cmap='winter')\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "ba4bd31b-d490-4444-abac-894675d5ed61", "metadata": { "collapsed": false }, "source": [ "This is the moment of truth: With a corrupted input now at hand, we then present this to our trained net, and hope that it denoises it. We do so by picking pixels at random, and then evaluating their activation functions, based on the current input configuration, (corrupted image), and the set weights, (that do not change here, as the net has already been trained).\n", "\n", "Since the Hopfield net stores patterns as minimal enery states, every iteration where we update a neuron/pixel should place the net into a lower energy configuration - that is - closer to the original pattern we stored - the weights are designed to do so after all." ] }, { "cell_type": "code", "execution_count": 24, "id": "091d2de3-0592-49d5-91a0-571083ff91bd", "metadata": { "ExecuteTime": { "end_time": "2023-10-06T05:59:27.526699500Z", "start_time": "2023-10-06T05:59:26.897805500Z" } }, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAABLkAAAJQCAYAAABioLa9AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAAA4dUlEQVR4nO3de5BU5Zk/8KcVGECHWRBhBrlIJaBGjKvgjTICuiIkmlViRWN0ISZGEdxCQkzQRCbGQGJWk03wsroVlI1Ed2O8JN5C5KJZJcFbdBVdTCBgZIKiziDqcDu/P/zRm3ZQGOiZ7nfm86nqqunTp9/z9Dunu5/69unTuSzLsgAAAACAhO1R6gIAAAAAYHcJuQAAAABInpALAAAAgOQJuQAAAABInpALAAAAgOQJuQAAAABInpALAAAAgOQJuQAAAABInpALAAAAgOQJuSABzzzzTHzhC1+IgQMHRufOnWPvvfeOww8/PK666qp4/fXXS13eLnv77bejtrY2Fi1aVPSxFy1aFLlcbodj33zzzZHL5eLxxx8veg0AAO+3rffYdunQoUPU1NTEmWeeGcuXLy91eUnR7wHv16HUBQAf7qabbooLL7wwDjjggPjqV78aH/vYx2LTpk3x+OOPxw033BCPPfZY3HnnnaUuc5e8/fbb8a1vfSsiIkaOHFnaYgAAWtGcOXPiwAMPjHfffTf++7//O77zne/EwoUL44UXXoju3buXujyAJAm5oIw99thjMXHixDjxxBPjrrvuioqKivxtJ554YnzlK1+JBx54oCjbevvtt6Nr165Nlm/ZsiU2b95csG0AAHbPkCFDYtiwYRHx3od9W7ZsiRkzZsRdd90VX/jCF0pcXcvKsizefffd6NKlS6lLAdoYX1eEMjZz5szI5XJx4403bjdk6tSpU3z605/OX9+6dWtcddVVceCBB0ZFRUX06tUr/umf/ilefvnlgvuNHDkyhgwZEg8//HAMHz48unbtGueee26sXLkycrlcXHXVVXHllVfGwIEDo6KiIhYuXJg/zHvlypUFY23vMPFt4z/yyCNx9NFHR5cuXWK//faLb37zm7Fly5aIiFi5cmXsu+++ERHxrW99K3/I/oQJE/LjLF++PM4666zo1atXVFRUxEEHHRTXXnttk3l44YUXYsyYMdG1a9fo2bNnXHDBBbF+/frmTnfehAkTYu+9944XXnghTjrppNhrr72ipqYmvvvd70ZExJIlS+LYY4+NvfbaKwYPHhy33HJLwf1fffXVuPDCC+NjH/tY7L333tGrV684/vjj45FHHmmyrZdffjlOP/30qKysjL/7u7+Lz3/+87F06dLI5XJx8803F6z7+OOPx6c//eno0aNHdO7cOQ477LD4z//8z11+nABA+dgWeP31r38tWL6z7/9/+ctf4stf/nL069cvOnXqFH369InTTz+9YLxVq1bF2WefXdBbXX311bF169aIiNi0aVP06tUrzjnnnCbjv/nmm9GlS5eYOnVqfllDQ0NMmzYtBg4cGJ06dYr99tsvpkyZEhs2bCi4by6Xi8mTJ8cNN9wQBx10UFRUVOT7J/3ezQXr6vdg9ziSC8rUli1bYsGCBTF06NDo16/fTt1n4sSJceONN8bkyZPj5JNPjpUrV8Y3v/nNWLRoUTz55JPRs2fP/Lpr1qyJs88+Oy655JKYOXNm7LHH/2XeP/rRj2Lw4MHxL//yL9GtW7cYNGhQ1NXVNav+urq6OPPMM+PrX/96XHHFFXHvvffGlVdeGW+88UbMnj07ampq4oEHHogxY8bEF7/4xfjSl74UEZEPvp5//vkYPnx49O/fP66++uqorq6OBx98MP75n/85XnvttZgxY0ZEvNcIjhgxIjp27BjXXXdd9O7dO2699daYPHlys+p9v02bNsW4cePiggsuiK9+9asxb968mD59ejQ0NMQdd9wRX/va16Jv377x4x//OCZMmBBDhgyJoUOHRkTkz5M2Y8aMqK6ujrfeeivuvPPOGDlyZDz00EP5r2Zu2LAhRo0aFa+//np873vfi49+9KPxwAMPxBlnnNGknoULF8aYMWPiqKOOihtuuCGqqqritttuizPOOCPefvvtgnAQAEjPihUrIiJi8ODB+WU7+/7/l7/8JY444ojYtGlTXHrppfHxj3881q1bFw8++GC88cYb0bt373j11Vdj+PDhsXHjxvj2t78d+++/f/zqV7+KadOmxR//+Me47rrromPHjnH22WfHDTfcENdee21069YtX8vPfvazePfdd/NHmb399tsxYsSIePnll/PbfO655+Lyyy+PZ599Nn7zm99ELpfL3/+uu+6KRx55JC6//PKorq6OXr166ffeR78HRZABZamuri6LiOzMM8/cqfWXLVuWRUR24YUXFiz/3e9+l0VEdumll+aXjRgxIouI7KGHHipYd8WKFVlEZB/5yEeyjRs3Ftw2Z86cLCKyFStWFCxfuHBhFhHZwoULm4x/9913F6x73nnnZXvssUf25z//OcuyLHv11VeziMhmzJjR5PGcdNJJWd++fbP6+vqC5ZMnT846d+6cvf7661mWZdnXvva1LJfLZU8//XTBeieeeGKTurZn2+NaunRpftn48eOziMjuuOOO/LJNmzZl++67bxYR2ZNPPplfvm7dumzPPffMpk6d+oHb2Lx5c7Zp06bshBNOyE477bT88muvvTaLiOz+++8vWP/888/PIiKbM2dOftmBBx6YHXbYYdmmTZsK1j355JOzmpqabMuWLR/6OAGA8rCt91iyZEm2adOmbP369dkDDzyQVVdXZ8cdd1zBe/3Ovv+fe+65WceOHbPnn3/+A7f79a9/PYuI7He/+13B8okTJ2a5XC578cUXsyzLsmeeeSaLiOzGG28sWO/II4/Mhg4dmr8+a9asbI899ijoobIsy37+859nEZHdd999+WURkVVVVeX7t230e/o9KDZfV4Q2YuHChRERTT7hOfLII+Oggw6Khx56qGB59+7d4/jjj9/uWJ/+9KejY8eOu1VPZWVlwVcpIyLOOuus2Lp1azz88MMfet933303HnrooTjttNOia9eusXnz5vzlk5/8ZLz77ruxZMmSiHjvcR988MFx6KGHNtnW7sjlcvHJT34yf71Dhw7x0Y9+NGpqauKwww7LL+/Ro0f06tUr/vznPxfc/4YbbojDDz88OnfuHB06dIiOHTvGQw89FMuWLcuvs3jx4qisrIwxY8YU3Pdzn/tcwfWXXnopXnjhhfj85z8fEdFkPtasWRMvvvjibj1eAKB1HX300dGxY8d8L9C9e/e4++67o0OH975s05z3//vvvz9GjRoVBx100Adub8GCBfGxj30sjjzyyILlEyZMiCzLYsGCBRERccghh8TQoUNjzpw5+XWWLVsWv//97+Pcc8/NL/vVr34VQ4YMib//+78vqO2kk07a7i8eHn/88QUn1Nfv6fegJQi5oEz17Nkzunbtmj90fUfWrVsXERE1NTVNbuvTp0/+9m22t97O3Lazevfu3WRZdXV1RESTWt5v3bp1sXnz5vjxj38cHTt2LLhsa0Ree+21/Lrbxt3etnZV165do3PnzgXLOnXqFD169GiybqdOneLdd9/NX7/mmmti4sSJcdRRR8Udd9wRS5YsiaVLl8aYMWPinXfeKXic25un9y/bdi6NadOmNZmPCy+8MCL+bz4AgDTMnTs3li5dGgsWLIjzzz8/li1bVhB8NOf9/9VXX42+fft+6PbWrVv3gX3ittu3Offcc+Oxxx6LF154ISLe+yXIioqKJvU988wzTWqrrKyMLMua9Cbv37Z+T78HLcE5uaBM7bnnnnHCCSfE/fffHy+//PIOG5d99tknIt4719b7133llVcKzscVEQXnSHi/7d22rQFobGwsWP5Bb7bvP2lqROTP67Wt1g/SvXv32HPPPeOcc86JSZMmbXedgQMH5sfa3vnCmnsOsWL66U9/GiNHjozrr7++YPn7T466zz77xO9///sm939/7dv+d9OnT49x48Ztd5sHHHDA7pQMALSygw46KH+y+VGjRsWWLVvi3//93+PnP/95nH766c16/993332b/NDQ++2zzz6xZs2aJstfeeWViIiCXvFzn/tcTJ06NW6++eb4zne+E//xH/8Rp556asGRWD179owuXbrET37yk+1ub0e9p35PvwctwZFcUMamT58eWZbFeeedFxs3bmxy+6ZNm+KXv/xlRET+q4c//elPC9ZZunRpLFu2LE444YTdqmX//fePiIhnnnmmYPk999yz3fXXr1/f5LZ58+bFHnvsEccdd1xERP4XI//2066I9z5VGzVqVDz11FPx8Y9/PIYNG9bksi0oGzVqVDz33HPxhz/8ocm2SiWXyzX5NcxnnnkmHnvssYJlI0aMiPXr18f9999fsPy2224ruH7AAQfEoEGD4g9/+MN252LYsGFRWVnZMg8GAGgVV111VXTv3j0uv/zy2Lp1a7Pe/8eOHRsLFy780K+znXDCCfH888/Hk08+WbB87ty5kcvlYtSoUfll3bt3j1NPPTXmzp0bv/rVr6Kurq7gq4oRESeffHL88Y9/jH322We7tW3rHT+Ifk+/By3BkVxQxo455pi4/vrr48ILL4yhQ4fGxIkT4+CDD45NmzbFU089FTfeeGMMGTIkTjnllDjggAPiy1/+cvz4xz+OPfbYI8aOHZv/dcV+/frFxRdfvFu1HHHEEXHAAQfEtGnTYvPmzdG9e/e4884747e//e12199nn31i4sSJsWrVqhg8eHDcd999cdNNN8XEiROjf//+EfHeebsGDBgQd999d5xwwgnRo0eP6NmzZ+y///7xr//6r3HsscfGJz7xiZg4cWLsv//+sX79+njppZfil7/8Zf68EVOmTImf/OQn8alPfSquvPLK/K/tbDu8vhROPvnk+Pa3vx0zZsyIESNGxIsvvhhXXHFFDBw4MDZv3pxfb/z48fGDH/wgzj777Ljyyivjox/9aNx///3x4IMPRkQU/OLlv/3bv8XYsWPjpJNOigkTJsR+++0Xr7/+eixbtiyefPLJ+K//+q9Wf5wAQPF07949pk+fHpdccknMmzcvzj777J1+/7/iiivi/vvvj+OOOy4uvfTSOOSQQ+LNN9+MBx54IKZOnRoHHnhgXHzxxTF37tz41Kc+FVdccUUMGDAg7r333rjuuuti4sSJBb/qGPHeVxZvv/32mDx5cvTt2zf+4R/+oeD2KVOmxB133BHHHXdcXHzxxfHxj388tm7dGqtWrYpf//rX8ZWvfCWOOuqoD33M+j39HhRdiU98D+yEp59+Ohs/fnzWv3//rFOnTtlee+2VHXbYYdnll1+erV27Nr/eli1bsu9973vZ4MGDs44dO2Y9e/bMzj777Gz16tUF440YMSI7+OCDm2xn268rfv/7399uHf/7v/+bjR49OuvWrVu27777ZhdddFF27733bvfXFQ8++OBs0aJF2bBhw7KKioqspqYmu/TSS5v8WsxvfvOb7LDDDssqKiqyiMjGjx9fUM+5556b7bffflnHjh2zfffdNxs+fHh25ZVXFozx/PPPZyeeeGLWuXPnrEePHtkXv/jF7O67796tX9vZa6+9mqz7QfM2YMCA7FOf+lT+emNjYzZt2rRsv/32yzp37pwdfvjh2V133ZWNHz8+GzBgQMF9V61alY0bNy7be++9s8rKyuwzn/lMdt9992331yn/8Ic/ZJ/97GezXr16ZR07dsyqq6uz448/Prvhhhs+9DECAOVje73HNu+8807Wv3//bNCgQdnmzZuzLNv59//Vq1dn5557blZdXZ117Ngx69OnT/bZz342++tf/5pf589//nN21llnZfvss0/WsWPH7IADDsi+//3vb/dX+7Zs2ZL169cvi4jssssu2+5jeeutt7JvfOMb2QEHHJB16tQpq6qqyg455JDs4osvzurq6vLrRUQ2adKk7Y6h39PvQTHlsizLShOv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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# The number of iterations where we randomly update neurons/pixels\n", "n_iterations = 5000\n", "\n", "# Loop through, and recover the image from it's corrupted self.\n", "# energy_vec: This will store the energy of the Hopfield net.\n", "cleaned_image, energy_vec = net.async_recover(corrupted_image, n_iterations, True)\n", "\n", "# (For imaging purposes)\n", "fig, ax = plt.subplots(nrows = 1, ncols = 2, figsize=(15, 7.5))\n", "ax[0].imshow(corrupted_image.reshape(28, 28), interpolation='None', cmap='winter')\n", "ax[0].set_title('Corrupted Image')\n", "ax[1].imshow(cleaned_image.reshape(28, 28), interpolation='None', cmap='winter')\n", "ax[1].set_title('Recovered Image')\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "9a764cd3-e799-47e8-b73d-64b88af40171", "metadata": {}, "source": [ " The Hopfield energy plotted as the recovery iteration index is shown below. We can see that as the recovery process was being run, the total net energy was being decreased." ] }, { "cell_type": "code", "execution_count": 25, "id": "c1f3a979-9c76-43aa-ad7e-6e8a61a9db30", "metadata": { "ExecuteTime": { "end_time": "2023-10-06T05:59:27.677258400Z", "start_time": "2023-10-06T05:59:27.496820500Z" } }, "outputs": [ { "data": { "image/png": "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a9+JjIzUpZdeqoyMDC1evFhXX321/ud//oce+9DWrVt16NAhpaenKyIiQhEREdqwYYMee+wxRUREmH2g177Vs2dPDR8+XB999FHI/DwTnDq5yMhIpaeny263exy32+3KysoK0qhCV2pqqpKSkjz66XQ6tWHDBrOf6enpslqtHjUHDhzQzp07zZrMzEwdO3ZMb7/9tlnz1ltv6dixY93m78UwDM2YMUN/+9vf9Oqrryo1NdXjdXrtP4ZhyOFw0GMfuummm7Rjxw69++675kdGRoZ+/OMf691339XgwYPptR84HA7t2rVLffv2DZ2f5wteXg6/c29HUFJSYnzwwQfGrFmzjJ49exp79+4N9tA6pePHjxtVVVVGVVWVIclYtmyZUVVVZW7f8OijjxpxcXHG3/72N2PHjh3Gv//7v7d5u2v//v2N9evXG9u2bTO+//3vt3m761VXXWVUVFQYFRUVxvDhw7vNLcWGYRg//elPjbi4OOP111/3uLX45MmTZg29vnBFRUXGxo0bjerqauO9994z5s2bZ4SFhRnl5eWGYdBjfzrzrjrDoNe+MGfOHOP11183PvnkE+PNN980brnlFiMmJsb89ywUekxwChFPPPGEMWjQICMyMtK49tprzVu+0dprr71mSGr1cddddxmG0XLL60MPPWQkJSUZNpvNuOGGG4wdO3Z4nOPrr782ZsyYYfTu3duIjo42brnlFqOmpsaj5vDhw8aPf/xjIyYmxoiJiTF+/OMfG0eOHAnQdxl8bfVYkrF69Wqzhl5fuP/4j/8wf/cvvvhi46abbjJDk2HQY386OzjR6wvn3pfJarUaycnJxh133GG8//775uuh0GOLYRjGhc9bAQAAdH2scQIAAPASwQkAAMBLBCcAAAAvEZwAAAC8RHACAADwEsEJAADASwQnAAAALxGcAAAAvERwAgAA8BLBCQAAwEsEJwAAAC8RnAAAALz0/wD8bupY75mlXAAAAABJRU5ErkJggg==", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Plot the Hopfield energy during recovery\n", "plt.plot(bm.as_numpy(energy_vec))\n", "plt.grid('on')\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "d91d7ef8-aca9-489a-9c2d-541a3d0a877d", "metadata": {}, "source": [ "Our original pattern has been very nicely recovered. What about masking noise and bernouli noise? Let's try that." ] }, { "cell_type": "code", "execution_count": 26, "id": "7718ee7c-284f-4be3-9fa8-474ccb25a302", "metadata": { "ExecuteTime": { "end_time": "2023-10-06T05:59:27.822176400Z", "start_time": "2023-10-06T05:59:27.607537Z" } }, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Masking and Bernouli noise\n", "mask_matrix = np.asarray([[7, 20], [8, 25]], dtype=np.int32)\n", "\n", "image = data[0].reshape(28, 28)\n", "corrupted_image = add_mask_noise(image, mask_value=1, mask_matrix=mask_matrix)\n", "corrupted_image = add_bernouli_noise(corrupted_image, prob=0.1)\n", "\n", "fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(15,7.5))\n", "ax[0].imshow(image, interpolation='None', cmap='winter')\n", "ax[1].imshow(corrupted_image, interpolation='None', cmap='winter')\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "5e696495-a18d-4b98-9728-0c29d8af8012", "metadata": {}, "source": [ "Now that's one ugly looking '9'. Can we recover the hidden pattern?" ] }, { "cell_type": "code", "execution_count": 27, "id": "d7294796-9f8d-469d-92e3-6823e4a97f58", "metadata": { "ExecuteTime": { "end_time": "2023-10-06T05:59:28.266142800Z", "start_time": "2023-10-06T05:59:27.822176400Z" } }, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAABLkAAAJQCAYAAABioLa9AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAAA49klEQVR4nO3de5BU5Zk/8KcVGEBnZkGEGeQilYAaMa7ilTICuiIkmlViRWN0ISZGEfwVEqJBE5kYA4lZTTbBy+pWMGw0uhvjJfEWIhfNKglGja6iiwkEjExQ1BlEHW7n94dLr82MykDPdL/M51PVVfTp028//c7pPg/fPn06l2VZFgAAAACQsN1KXQAAAAAA7CwhFwAAAADJE3IBAAAAkDwhFwAAAADJE3IBAAAAkDwhFwAAAADJE3IBAAAAkDwhFwAAAADJE3IBAAAAkDwhFyTg6aefji984QsxaNCg6Nq1a+y5555x6KGHxlVXXRWvvfZaqcvbYW+99VbU1dXFwoULiz72woULI5fLfejYN998c+RyuXj88ceLXgMAwLa29h5bL506dYra2to444wzYtmyZaUuLyn6PWBbnUpdAPDBbrrpprjgggtiv/32i69+9avxsY99LDZu3BiPP/543HDDDfHYY4/FnXfeWeoyd8hbb70V3/zmNyMiYuTIkaUtBgCgHc2ZMyf233//eOedd+K//uu/4tvf/nYsWLAgnn/++ejRo0epywNIkpALythjjz0WEydOjBNOOCHuuuuuqKioyN92wgknxFe+8pV44IEHivJYb731VnTv3r3Z8s2bN8emTZsKHhsAgJ0zdOjQOOywwyLi3Q/7Nm/eHDNmzIi77rorvvCFL5S4uraVZVm888470a1bt1KXAuxifF0RytjMmTMjl8vFjTfe2GLI1KVLl/j0pz+dv75ly5a46qqrYv/994+Kioro3bt3/NM//VO89NJLBfcbOXJkDB06NB5++OEYPnx4dO/ePc4555xYsWJF5HK5uOqqq+LKK6+MQYMGRUVFRSxYsCB/mPeKFSsKxmrpMPGt4z/yyCNx1FFHRbdu3WKfffaJb3zjG7F58+aIiFixYkXsvffeERHxzW9+M3/I/oQJE/LjLFu2LM4888zo3bt3VFRUxAEHHBDXXntts3l4/vnnY8yYMdG9e/fo1atXnH/++bFu3brWTnfehAkTYs8994znn38+TjzxxNhjjz2itrY2vvOd70RExOLFi+OYY46JPfbYI4YMGRI/+clPCu7/yiuvxAUXXBAf+9jHYs8994zevXvHcccdF4888kizx3rppZfitNNOi8rKyvi7v/u7+PznPx9LliyJXC4XN998c8G6jz/+eHz605+Onj17RteuXeOQQw6J//iP/9jh5wkAlI+tgdff/va3guXbu///61//Gl/+8pejf//+0aVLl+jbt2+cdtppBeOtXLkyzjrrrILe6uqrr44tW7ZERMTGjRujd+/ecfbZZzcb/4033ohu3brF1KlT88saGxtj2rRpMWjQoOjSpUvss88+MWXKlFi/fn3BfXO5XEyePDluuOGGOOCAA6KioiLfP+n3bi5YV78HO8eRXFCmNm/eHPPnz49hw4ZF//79t+s+EydOjBtvvDEmT54cJ510UqxYsSK+8Y1vxMKFC+OJJ56IXr165dddvXp1nHXWWXHxxRfHzJkzY7fd/i/z/uEPfxhDhgyJf/7nf46qqqoYPHhw1NfXt6r++vr6OOOMM+JrX/taXHHFFXHvvffGlVdeGa+//nrMnj07amtr44EHHogxY8bEF7/4xfjSl74UEZEPvp577rkYPnx4DBgwIK6++uqoqamJBx98MP7f//t/8eqrr8aMGTMi4t1GcMSIEdG5c+e47rrrok+fPnHLLbfE5MmTW1XvtjZu3Bjjxo2L888/P7761a/GrbfeGtOnT4/Gxsa444474pJLLol+/frFj370o5gwYUIMHTo0hg0bFhGRP0/ajBkzoqamJt5888248847Y+TIkfHQQw/lv5q5fv36GDVqVLz22mvx3e9+Nz760Y/GAw88EKeffnqzehYsWBBjxoyJI488Mm644Yaorq6O2267LU4//fR46623CsJBACA9y5cvj4iIIUOG5Jdt7/7/r3/9axx++OGxcePGuPTSS+PjH/94rF27Nh588MF4/fXXo0+fPvHKK6/E8OHDY8OGDfGtb30r9t133/jVr34V06ZNiz/96U9x3XXXRefOneOss86KG264Ia699tqoqqrK1/Kzn/0s3nnnnfxRZm+99VaMGDEiXnrppfxjPvvss3H55ZfHM888E7/5zW8il8vl73/XXXfFI488EpdffnnU1NRE79699Xvb0O9BEWRAWaqvr88iIjvjjDO2a/2lS5dmEZFdcMEFBct/97vfZRGRXXrppfllI0aMyCIie+ihhwrWXb58eRYR2Uc+8pFsw4YNBbfNmTMni4hs+fLlBcsXLFiQRUS2YMGCZuPffffdBeuee+652W677Zb95S9/ybIsy1555ZUsIrIZM2Y0ez4nnnhi1q9fv6yhoaFg+eTJk7OuXbtmr732WpZlWXbJJZdkuVwue+qppwrWO+GEE5rV1ZKtz2vJkiX5ZePHj88iIrvjjjvyyzZu3JjtvffeWURkTzzxRH752rVrs9133z2bOnXq+z7Gpk2bso0bN2bHH398duqpp+aXX3vttVlEZPfff3/B+uedd14WEdmcOXPyy/bff//skEMOyTZu3Fiw7kknnZTV1tZmmzdv/sDnCQCUh629x+LFi7ONGzdm69atyx544IGspqYmO/bYYwv29du7/z/nnHOyzp07Z88999z7Pu7Xvva1LCKy3/3udwXLJ06cmOVyueyFF17IsizLnn766SwishtvvLFgvSOOOCIbNmxY/vqsWbOy3XbbraCHyrIs+/nPf55FRHbffffll0VEVl1dne/fttLv6feg2HxdEXYRCxYsiIho9gnPEUccEQcccEA89NBDBct79OgRxx13XItjffrTn47OnTvvVD2VlZUFX6WMiDjzzDNjy5Yt8fDDD3/gfd9555146KGH4tRTT43u3bvHpk2b8pdPfvKT8c4778TixYsj4t3nfeCBB8bBBx/c7LF2Ri6Xi09+8pP56506dYqPfvSjUVtbG4ccckh+ec+ePaN3797xl7/8peD+N9xwQxx66KHRtWvX6NSpU3Tu3DkeeuihWLp0aX6dRYsWRWVlZYwZM6bgvp/73OcKrr/44ovx/PPPx+c///mIiGbzsXr16njhhRd26vkCAO3rqKOOis6dO+d7gR49esTdd98dnTq9+2Wb1uz/77///hg1alQccMAB7/t48+fPj4997GNxxBFHFCyfMGFCZFkW8+fPj4iIgw46KIYNGxZz5szJr7N06dL4/e9/H+ecc05+2a9+9asYOnRo/P3f/31BbSeeeGKLv3h43HHHFZxQX7+n34O2IOSCMtWrV6/o3r17/tD1D7N27dqIiKitrW12W9++ffO3b9XSettz2/bq06dPs2U1NTUREc1q2dbatWtj06ZN8aMf/Sg6d+5ccNnaiLz66qv5dbeO29Jj7aju3btH165dC5Z16dIlevbs2WzdLl26xDvvvJO/fs0118TEiRPjyCOPjDvuuCMWL14cS5YsiTFjxsTbb79d8Dxbmqdtl209l8a0adOazccFF1wQEf83HwBAGubOnRtLliyJ+fPnx3nnnRdLly4tCD5as/9/5ZVXol+/fh/4eGvXrn3fPnHr7Vudc8458dhjj8Xzzz8fEe/+EmRFRUWz+p5++ulmtVVWVkaWZc16k20fW7+n34O24JxcUKZ23333OP744+P++++Pl1566UMbl7322isi3j3X1rbrvvzyywXn44qIgnMkbKul27Y2AE1NTQXL329nu+1JUyMif16vrbW+nx49esTuu+8eZ599dkyaNKnFdQYNGpQfq6XzhbX2HGLF9NOf/jRGjhwZ119/fcHybU+Outdee8Xvf//7Zvfftvatf7vp06fHuHHjWnzM/fbbb2dKBgDa2QEHHJA/2fyoUaNi8+bN8W//9m/x85//PE477bRW7f/33nvvZj80tK299torVq9e3Wz5yy+/HBFR0Ct+7nOfi6lTp8bNN98c3/72t+Pf//3f45RTTik4EqtXr17RrVu3+PGPf9zi431Y76nf0+9BW3AkF5Sx6dOnR5Zlce6558aGDRua3b5x48b45S9/GRGR/+rhT3/604J1lixZEkuXLo3jjz9+p2rZd999IyLi6aefLlh+zz33tLj+unXrmt126623xm677RbHHntsRET+FyPf+2lXxLufqo0aNSqefPLJ+PjHPx6HHXZYs8vWoGzUqFHx7LPPxh//+Mdmj1UquVyu2a9hPv300/HYY48VLBsxYkSsW7cu7r///oLlt912W8H1/fbbLwYPHhx//OMfW5yLww47LCorK9vmyQAA7eKqq66KHj16xOWXXx5btmxp1f5/7NixsWDBgg/8Otvxxx8fzz33XDzxxBMFy+fOnRu5XC5GjRqVX9ajR4845ZRTYu7cufGrX/0q6uvrC76qGBFx0kknxZ/+9KfYa6+9Wqxta+/4fvR7+j1oC47kgjJ29NFHx/XXXx8XXHBBDBs2LCZOnBgHHnhgbNy4MZ588sm48cYbY+jQoXHyySfHfvvtF1/+8pfjRz/6Uey2224xduzY/K8r9u/fPy666KKdquXwww+P/fbbL6ZNmxabNm2KHj16xJ133hm//e1vW1x/r732iokTJ8bKlStjyJAhcd9998VNN90UEydOjAEDBkTEu+ftGjhwYNx9991x/PHHR8+ePaNXr16x7777xr/8y7/EMcccE5/4xCdi4sSJse+++8a6devixRdfjF/+8pf580ZMmTIlfvzjH8enPvWpuPLKK/O/trP18PpSOOmkk+Jb3/pWzJgxI0aMGBEvvPBCXHHFFTFo0KDYtGlTfr3x48fH97///TjrrLPiyiuvjI9+9KNx//33x4MPPhgRUfCLl//6r/8aY8eOjRNPPDEmTJgQ++yzT7z22muxdOnSeOKJJ+I///M/2/15AgDF06NHj5g+fXpcfPHFceutt8ZZZ5213fv/K664Iu6///449thj49JLL42DDjoo3njjjXjggQdi6tSpsf/++8dFF10Uc+fOjU996lNxxRVXxMCBA+Pee++N6667LiZOnFjwq44R735l8fbbb4/JkydHv3794h/+4R8Kbp8yZUrccccdceyxx8ZFF10UH//4x2PLli2xcuXK+PWvfx1f+cpX4sgjj/zA56zf0+9B0ZX4xPfAdnjqqaey8ePHZwMGDMi6dOmS7bHHHtkhhxySXX755dmaNWvy623evDn77ne/mw0ZMiTr3Llz1qtXr+yss87KVq1aVTDeiBEjsgMPPLDZ42z9dcXvfe97LdbxP//zP9no0aOzqqqqbO+9984uvPDC7N57723x1xUPPPDAbOHChdlhhx2WVVRUZLW1tdmll17a7NdifvOb32SHHHJIVlFRkUVENn78+IJ6zjnnnGyfffbJOnfunO29997Z8OHDsyuvvLJgjOeeey474YQTsq5du2Y9e/bMvvjFL2Z33333Tv3azh577NFs3febt4EDB2af+tSn8tebmpqyadOmZfvss0/WtWvX7NBDD83uuuuubPz48dnAgQML7rty5cps3Lhx2Z577plVVlZmn/nMZ7L77ruvxV+n/OMf/5h99rOfzXr37p117tw5q6mpyY477rjshhtu+MDnCACUj5Z6j63efvvtbMCAAdngwYOzTZs2ZVm2/fv/VatWZeecc05WU1OTde7cOevbt2/22c9+Nvvb3/6WX+cvf/lLduaZZ2Z77bVX1rlz52y//fbLvve977X4q32bN2/O+vfvn0VEdtlll7X4XN58883s61//erbffvtlXbp0yaqrq7ODDjoou+iii7L6+vr8ehGRTZo0qcUx9Hv6PSimXJZlWWniNWBX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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# The number of iterations where we randomly update neurons/pixels\n", "n_iterations = 5000\n", "\n", "# Loop through, and recover the image from it's corrupted self.\n", "# energy_vec: This will store the energy of the Hopfield net.\n", "cleaned_image, energy_vec = net.async_recover(corrupted_image.flatten(), n_iterations, True)\n", "\n", "# (For imaging purposes)\n", "fig, ax = plt.subplots(nrows = 1, ncols = 2, figsize=(15, 7.5))\n", "ax[0].imshow(corrupted_image.reshape(28, 28), interpolation='None', cmap='winter')\n", "ax[0].set_title('Corrupted Image')\n", "ax[1].imshow(cleaned_image.reshape(28, 28), interpolation='None', cmap='winter')\n", "ax[1].set_title('Recovered Image')\n", "plt.show()" ] }, { "cell_type": "code", "execution_count": 28, "id": "960da709b523381a", "metadata": { "ExecuteTime": { "end_time": "2023-10-06T05:59:28.412609600Z", "start_time": "2023-10-06T05:59:28.269656200Z" }, "collapsed": false }, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Plot the Hopfield energy during recovery\n", "plt.plot(bm.as_numpy(energy_vec))\n", "plt.grid('on')\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "bb11b697-af90-4a31-9544-535d8da96670", "metadata": {}, "source": [ "Now this is exactly what it means to be 'content addressable' - the fact that we are able to 'snap back' to a previous pattern among many patterns, starting from a corrupted variant was perhaps one of the first success stories of the associationist movement - Hopefield nets - totally connected RNNs, where the relationships between neurons/pixels are impressed into the weights as minimum energy states. In doing so, the iterative changing of neural activations becomes exactly like finding a configuration of least energy - something that is found in nature all the time." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.11.5" } }, "nbformat": 4, "nbformat_minor": 5 }