{ "cells": [ { "cell_type": "markdown", "id": "647060a3", "metadata": {}, "source": [ "# CANN 1D Oscillatory Tracking\n", "\n", "[![Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/brainpy/examples/blob/main/attractors/Mi_2014_CANN_1D_oscillatory_tracking.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/Mi_2014_CANN_1D_oscillatory_tracking.ipynb)" ] }, { "cell_type": "markdown", "id": "6d135f04", "metadata": {}, "source": [ "Implementation of the paper:\n", "\n", "- Si Wu, Kosuke Hamaguchi, and Shun-ichi Amari. \"Dynamics and computation of continuous attractors.\" Neural computation 20.4 (2008): 994-1025.\n", "- Mi, Y., Fung, C. C., Wong, M. K. Y., & Wu, S. (2014). Spike frequency adaptation implements anticipative tracking in continuous attractor neural networks. Advances in neural information processing systems, 1(January), 505." ] }, { "cell_type": "code", "execution_count": 1, "id": "51852ed7", "metadata": { "ExecuteTime": { "end_time": "2023-07-22T04:07:35.934007100Z", "start_time": "2023-07-22T04:07:35.243879300Z" }, "pycharm": { "is_executing": true } }, "outputs": [], "source": [ "import brainpy as bp\n", "import brainpy.math as bm\n", "\n", "bm.set_platform('cpu')" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "ExecuteTime": { "end_time": "2023-07-22T04:07:35.949695100Z", "start_time": "2023-07-22T04:07:35.934007100Z" }, "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "'2.4.3'" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bp.__version__" ] }, { "cell_type": "code", "execution_count": 2, "id": "433fe4d4", "metadata": {}, "outputs": [], "source": [ "class CANN1D(bp.dyn.NeuDyn):\n", " def __init__(self, num, tau=1., tau_v=50., k=1., a=0.3, A=0.2, J0=1.,\n", " z_min=-bm.pi, z_max=bm.pi, m=0.3):\n", " super(CANN1D, self).__init__(size=num)\n", "\n", " # parameters\n", " self.tau = tau # The synaptic time constant\n", " self.tau_v = tau_v\n", " self.k = k # Degree of the rescaled inhibition\n", " self.a = a # Half-width of the range of excitatory connections\n", " self.A = A # Magnitude of the external input\n", " self.J0 = J0 # maximum connection value\n", " self.m = m\n", "\n", " # feature space\n", " self.z_min = z_min\n", " self.z_max = z_max\n", " self.z_range = z_max - z_min\n", " self.x = bm.linspace(z_min, z_max, num) # The encoded feature values\n", " self.rho = num / self.z_range # The neural density\n", " self.dx = self.z_range / num # The stimulus density\n", "\n", " # The connection matrix\n", " self.conn_mat = self.make_conn()\n", "\n", " # variables\n", " self.r = bm.Variable(bm.zeros(num))\n", " self.u = bm.Variable(bm.zeros(num))\n", " self.v = bm.Variable(bm.zeros(num))\n", " self.input = bm.Variable(bm.zeros(num))\n", "\n", " def dist(self, d):\n", " d = bm.remainder(d, self.z_range)\n", " d = bm.where(d > 0.5 * self.z_range, d - self.z_range, d)\n", " return d\n", "\n", " def make_conn(self):\n", " x_left = bm.reshape(self.x, (-1, 1))\n", " x_right = bm.repeat(self.x.reshape((1, -1)), len(self.x), axis=0)\n", " d = self.dist(x_left - x_right)\n", " conn = self.J0 * bm.exp(-0.5 * bm.square(d / self.a)) / (bm.sqrt(2 * bm.pi) * self.a)\n", " return conn\n", "\n", " def get_stimulus_by_pos(self, pos):\n", " return self.A * bm.exp(-0.25 * bm.square(self.dist(self.x - pos) / self.a))\n", "\n", " def update(self):\n", " r1 = bm.square(self.u)\n", " r2 = 1.0 + self.k * bm.sum(r1)\n", " self.r.value = r1 / r2\n", " Irec = bm.dot(self.conn_mat, self.r)\n", " self.u.value = self.u + (-self.u + Irec + self.input - self.v) / self.tau * bp.share['dt']\n", " self.v.value = self.v + (-self.v + self.m * self.u) / self.tau_v * bp.share['dt']\n", " self.input[:] = 0." ] }, { "cell_type": "code", "execution_count": 3, "id": "1c04226c", "metadata": {}, "outputs": [], "source": [ "cann = CANN1D(num=512)" ] }, { "cell_type": "code", "execution_count": 4, "id": "6bc3315e", "metadata": { "scrolled": false }, "outputs": [ { "data": { "application/vnd.jupyter.widget-view+json": { "model_id": "76f9d82a2cd447cc9541cd771fee2086", "version_major": 2, "version_minor": 0 }, "text/plain": [ " 0%| | 0/26000 [00:00