Skip to content

Instantly share code, notes, and snippets.

@neila
Created December 20, 2019 02:44
Show Gist options
  • Save neila/e4dceccf82ac548c3e150d66ceccf4a2 to your computer and use it in GitHub Desktop.
Save neila/e4dceccf82ac548c3e150d66ceccf4a2 to your computer and use it in GitHub Desktop.
Hopfield Network implementation
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 51,
"metadata": {},
"outputs": [],
"source": [
"#Main resource consulted:\n",
"#http://codeaffectionate.blogspot.com/2013/05/fun-with-hopfield-and-numpy.html\n",
"\n",
"import numpy as np\n",
"from pylab import imshow, cm, show\n",
"import matplotlib.pyplot as plt"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Making some random data. Here I use three letters of my name."
]
},
{
"cell_type": "code",
"execution_count": 52,
"metadata": {},
"outputs": [],
"source": [
"S = \"\"\"\n",
".XXXX\n",
"X....\n",
".XXX.\n",
"....X\n",
"XXXX.\n",
"\"\"\"\n",
" \n",
"H = \"\"\"\n",
"X...X\n",
"X...X\n",
"XXXXX\n",
"X...X\n",
"X...X\n",
"\"\"\"\n",
"\n",
"O = \"\"\"\n",
".XXX.\n",
"X...X\n",
"X...X\n",
"X...X\n",
".XXX.\n",
"\"\"\""
]
},
{
"cell_type": "code",
"execution_count": 53,
"metadata": {},
"outputs": [],
"source": [
"def to_pattern(letter):\n",
" return np.array([+1 if c=='X' else -1 for c in letter.replace('\\n','')])\n",
"\n",
"def display(pattern):\n",
" imshow(pattern.reshape((5,5)),cmap=cm.binary, interpolation='nearest')\n",
" show()"
]
},
{
"cell_type": "code",
"execution_count": 54,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"#example\n",
"display(to_pattern(S))"
]
},
{
"cell_type": "code",
"execution_count": 55,
"metadata": {},
"outputs": [],
"source": [
"patterns = np.array([to_pattern(S), to_pattern(H), to_pattern(O)])"
]
},
{
"cell_type": "code",
"execution_count": 56,
"metadata": {},
"outputs": [],
"source": [
"def train(patterns):\n",
" row,col = patterns.shape\n",
" W = np.zeros((col,col))\n",
" for p in patterns:\n",
" W = W + np.outer(p,p)\n",
" W[np.diag_indices(col)] = 0\n",
" return W/row"
]
},
{
"cell_type": "code",
"execution_count": 57,
"metadata": {},
"outputs": [],
"source": [
"weights = train(patterns)"
]
},
{
"cell_type": "code",
"execution_count": 58,
"metadata": {},
"outputs": [],
"source": [
"def recall(W, pattern, steps=5, verbose=False):\n",
" sgn = np.vectorize(lambda x: -1 if x<0 else +1)\n",
" \n",
" for i in range(steps): \n",
" pattern = sgn(np.dot(pattern,W))\n",
" if verbose == True:\n",
" print(f\"After iteration {i}:\")\n",
" display(pattern)\n",
" \n",
" return pattern"
]
},
{
"cell_type": "code",
"execution_count": 62,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAPgAAAD8CAYAAABaQGkdAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvOIA7rQAACQ9JREFUeJzt3UGIXIUdx/Hfr2skgi0esgfJhsaDCEGokiEIXkpAiBrqVcGchFwqRLCIPXrqTbx4CSoWKopgDhIsEmhABKvOahSTKARJMSJsgoh6UaL/HmYKsWR33mbe2zfv5/cDCzubcfLLy37zZmfHWVeVAGT6Td8DAHSHwIFgBA4EI3AgGIEDwQgcCEbgQDACB4IROBDsui5udMeOHbV79+4ubrp1q6urfU/YlL179/Y9YVOGdHyHdGzPnz+vS5cuedb13MVTVUejUY3H49Zvtwv2zGO0UIb21OIhHd8hHdvRaKTxeDzz4HIXHQhG4EAwAgeCETgQjMCBYAQOBCNwIBiBA8EIHAhG4EAwAgeCETgQjMCBYAQOBCNwIBiBA8EaBW77gO3PbJ+z/WTXowC0Y2bgtpckPSvpXkl7JD1ke0/XwwDMr8kZfJ+kc1X1eVX9KOkVSQ90OwtAG5oEvlPSF1dcvjD9GIAF19qDbLYP2x7bHl+8eLGtmwUwhyaBfylp1xWXV6Yf+4WqOlpVo6oaLS8vt7UPwByaBP6+pFtt32L7ekkPSnq921kA2jDzBx9U1WXbj0p6U9KSpBeq6nTnywDMrdFPNqmqNyS90fEWAC3jmWxAMAIHghE4EIzAgWAEDgQjcCAYgQPBCBwIRuBAMAIHghE4EIzAgWAEDgQjcCAYgQPBCBwIRuBAsEav6LJZq6urst3FTbeuqvqeAHSGMzgQjMCBYAQOBCNwIBiBA8EIHAhG4EAwAgeCETgQjMCBYAQOBCNwIBiBA8EIHAhG4EAwAgeCETgQbGbgtl+wvWb7k60YBKA9Tc7gL0o60PEOAB2YGXhVvSXp6y3YAqBlfA0OBGvtVVVtH5Z0uK3bAzC/1gKvqqOSjkqSbV6LGFgA3EUHgjX5NtnLkt6RdJvtC7Yf6X4WgDbMvIteVQ9txRAA7eMuOhCMwIFgBA4EI3AgGIEDwQgcCEbgQDACB4IROBCMwIFgBA4EI3AgGIEDwQgcCEbgQDACB4J1EvjevXtVVYN4A5JxBgeCETgQjMCBYAQOBCNwIBiBA8EIHAhG4EAwAgeCETgQjMCBYAQOBCNwIBiBA8EIHAhG4EAwAgeCzQzc9i7bJ22fsX3a9pGtGAZgftc1uM5lSY9X1Qe2fytp1faJqjrT8TYAc5p5Bq+qr6rqg+n730k6K2ln18MAzG9TX4Pb3i3pTknvdjEGQLsaB277RkmvSXqsqr69yq8ftj22Pb548WKbGwFco0aB296mSdwvVdWxq12nqo5W1aiqRsvLy21uBHCNmjyKbknPSzpbVU93PwlAW5qcwe+WdEjSftunpm/3dbwLQAtmfpusqt6W5C3YAqBlPJMNCEbgQDACB4IROBCMwIFgBA4EI3AgGIEDwQgcCEbgQDACB4IROBCMwIFgBA4EI3AgGIEDwQgcCNbkBx9s2urqqiYv5bb4qqrvCZsylOP6P0M7vmk4gwPBCBwIRuBAMAIHghE4EIzAgWAEDgQjcCAYgQPBCBwIRuBAMAIHghE4EIzAgWAEDgQjcCAYgQPBZgZue7vt92x/ZPu07ae2YhiA+TV5yaYfJO2vqu9tb5P0tu1/VtW/O94GYE4zA6/Ji2p9P724bfrGC20BA9Doa3DbS7ZPSVqTdKKq3u12FoA2NAq8qn6qqjskrUjaZ/v2/7+O7cO2x7bHbY8EcG029Sh6VX0j6aSkA1f5taNVNaqqUVvjAMynyaPoy7Zvmr5/g6R7JH3a9TAA82vyKPrNkv5ue0mTfxBerarj3c4C0IYmj6J/LOnOLdgCoGU8kw0IRuBAMAIHghE4EIzAgWAEDgQjcCAYgQPBCBwIRuBAMAIHghE4EIzAgWAEDgQjcCAYgQPBmryiC/CrYLvvCa3jDA4EI3AgGIEDwQgcCEbgQDACB4IROBCMwIFgBA4EI3AgGIEDwQgcCEbgQDACB4IROBCMwIFgBA4Eaxy47SXbH9o+3uUgAO3ZzBn8iKSzXQ0B0L5GgdtekXS/pOe6nQOgTU3P4M9IekLSzx1uAdCymYHbPihprapWZ1zvsO2x7XFr6wDMxVW18RXsv0k6JOmypO2SfifpWFU9vMF/s/GNLpBZf/5FM7SX9h3S8R3gsZ05eGbgv7iy/UdJf6mqgzOuN5i/1SF9AkqD/CTse0JjAzy2MwfzfXAg2KbO4I1vlDN4ZwZ4lul7QmMDPLacwYFfMwIHghE4EIzAgWAEDgQjcCAYgQPBCBwIRuBAMAIHghE4EIzAgWAEDgQjcCAYgQPBCBwIRuBAsOs6ut1Lkv7T8m3umN5uqzp8FY9O9naks60dHV+OrfT7Jlfq5CWbumB7XFWjvnc0NaS9Q9oqDWtv31u5iw4EI3Ag2JACP9r3gE0a0t4hbZWGtbfXrYP5GhzA5g3pDA5gkwYRuO0Dtj+zfc72k33v2YjtF2yv2f6k7y2z2N5l+6TtM7ZP2z7S96b12N5u+z3bH023PtX3piZsL9n+0PbxPn7/hQ/c9pKkZyXdK2mPpIds7+l31YZelHSg7xENXZb0eFXtkXSXpD8v8LH9QdL+qvqDpDskHbB9V8+bmjgi6Wxfv/nCBy5pn6RzVfV5Vf0o6RVJD/S8aV1V9Zakr/ve0URVfVVVH0zf/06TT8Sd/a66upr4fnpx2/RtoR9Asr0i6X5Jz/W1YQiB75T0xRWXL2hBPwmHzPZuSXdKerffJeub3t09JWlN0omqWtitU89IekLSz30NGELg6JjtGyW9Jumxqvq27z3rqaqfquoOSSuS9tm+ve9N67F9UNJaVa32uWMIgX8padcVl1emH0MLbG/TJO6XqupY33uaqKpvJJ3UYj/WcbekP9k+r8mXlftt/2OrRwwh8Pcl3Wr7FtvXS3pQ0us9b4rgyf8J8ryks1X1dN97NmJ72fZN0/dvkHSPpE/7XbW+qvprVa1U1W5NPmf/VVUPb/WOhQ+8qi5LelTSm5o8CPRqVZ3ud9X6bL8s6R1Jt9m+YPuRvjdt4G5JhzQ5u5yavt3X96h13CzppO2PNflH/0RV9fKtpyHhmWxAsIU/gwO4dgQOBCNwIBiBA8EIHAhG4EAwAgeCETgQ7L8BJm6b9Kl6sQAAAABJRU5ErkJggg==\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"some_random_pattern = \"\"\"\n",
".X.X.\n",
"X..X.\n",
"...X.\n",
"X.X..\n",
"X.X.X\n",
"\"\"\"\n",
"display(to_pattern(some_random_pattern))"
]
},
{
"cell_type": "code",
"execution_count": 64,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"After iteration 0:\n"
]
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"After iteration 1:\n"
]
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"array([-1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1,\n",
" -1, -1, 1, 1, 1, 1, 1, -1])"
]
},
"execution_count": 64,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"recall(weights,to_pattern(some_random_pattern),2,True)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"After the second iteration we have already converged to S."
]
},
{
"cell_type": "code",
"execution_count": 68,
"metadata": {},
"outputs": [],
"source": [
"def generate_patterns(num, size):\n",
" patterns = []\n",
" for i in range(num):\n",
" patterns.append(np.random.choice((-1,1),size=size))\n",
" return patterns\n",
" \n",
"def corrupt(pattern):\n",
" bad = np.random.randint((np.shape(pattern)[1]))\n",
" pattern[0][bad] = -pattern[0][bad]\n",
" return (pattern)\n",
"\n",
"def capacity(size):\n",
" \"\"\"\n",
" Generates corrupted patterns, trains on the patterns and\n",
" then tests if the network was able to correctly recall the\n",
" corrupted pattern.\n",
" \"\"\"\n",
" num = 1 \n",
" \n",
" while True:\n",
" patterns = generate_patterns(num, size)\n",
" patterns = np.reshape(patterns, (num,size))\n",
"\n",
" corrupt_patterns = [p for p in corrupt(patterns)]\n",
" corrupt_patterns = np.reshape(corrupt_patterns, (num,size))\n",
" \n",
" weights = train(patterns)\n",
" recalled_patterns = recall(weights, corrupt_patterns)\n",
"\n",
" if np.any(np.not_equal(recalled_patterns,patterns)):\n",
" break\n",
" else:\n",
" num +=1 \n",
" \n",
" return num"
]
},
{
"cell_type": "code",
"execution_count": 72,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"network_size = [x for x in range(10,500,10)]\n",
"patternbox = []\n",
"\n",
"\n",
"for size in network_size:\n",
" cap = []\n",
" for i in range(10): #per size average over 10 samples\n",
" cap.append(capacity(size))\n",
" avcap = np.average(cap)\n",
" patternbox.append(avcap)\n",
"\n",
"plt.plot(netw_size, patternbox)\n",
"plt.xlabel(\"Network Size\")\n",
"plt.ylabel(\"Number of patterns accurately stored and recalled\")\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We see that the number of patterns stored and recalled are roughly proportional to the network size. "
]
},
{
"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.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment