Hello everyone. In our understanding of the world, continuous attractor neural networks play a vital role. I’ve found examples of chaotic attractors in tutorials, but lately, I’ve been working on a project related to biological cognition and navigation. After setting up a navigation system using Nengo, I plan to utilize continuous attractor neural networks to model place cells, enabling them to integrate exogenous and endogenous information for more precise cognition. However, I’m struggling to find relevant examples to complete my project. I would greatly appreciate it if you could offer me some advice. Thank you very much.
The paper “A Controlled Attractor Network Model of Path Integration in the Rat” (https://compneuro.uwaterloo.ca/files/Conklin.PathIntegration.pdf) presents a continuous attractor model of path integration using the NEF (the math underneath nengo). The code for the model is here: GitHub - ctn-archive/conklin-compneuro2005: A controlled attractor network model of path integration in the rat. However, the data generation code is in Matlab and the main python script uses a very old version of/precursor to nengo. It predates nengo 1.4, which is the oldest version I can find available to install.
A more recent model of path integration in nengo is this: Semantic-Spiking-Neural-SLAM-2023/sspslam/networks/pathintegration.py at main · nsdumont/Semantic-Spiking-Neural-SLAM-2023 · GitHub, which is described in “A model of path integration that connects neural and symbolic representation” (https://escholarship.org/content/qt3pf7f9b4/qt3pf7f9b4.pdf). This is closer to an oscillatory-interference path integration model rather than a CAN, but it does use attractor dynamics as well. Let me know if you have any questions about the model!
Thank you so much! @yaffa.
It was your paper, “SSP-SLAM,” that inspired me. I’d like to expand upon it by enabling it to accept multiple inputs (such as from vision and IMU sensors, considering their computational speeds) and then fuse these inputs using place cells modeled by continuous attractor neural networks after path integration. This would allow for more accurate pose estimation. In essence, I plan to replace the “state update” module in your original work with place cells.
Given that continuous attractor neural networks can mitigate white noise and integrate multiple data sources, I want to build an continuous attractor model that’s not just a velosity integrator but one capable of fusing positional information. I’ve found relevant literature on this, but I’m encountering difficulties when trying to replicate the model using Nengo, and to make it even more challenging, the model is currently one-dimensional. The code I wrote is as follows:
import nengo
import numpy as np
import matplotlib.pyplot as plt
N = 120
halfN = N // 2
dij = np.abs(np.tile(np.arange(N), (N, 1)) - np.tile(np.arange(N).reshape(-1, 1), (1, N)))
dij[dij > halfN] = N - dij[dij > halfN]
nij = dij / halfN
sigma = 0.5
wij = np.exp(-nij**2 / (2 * sigma**2))
wEE = 45 / N
wIE = 60 / N
wEI = -6
wII = -1
gammaE = -1.5
gammaI = -7.5
tauE = 0.05
tauI = 0.0025
deltaT = 0.001
T_E = deltaT/tauE
T_I = deltaT/tauI
wEEij = wEE * wij
z_initial =wEEij[:, halfN]
u = 0.69
X = np.zeros(N)
def plot_points_svg(t, b):
a = b[N:-1]
points = []
for i in range(a.shape[0]):
y = a[i]
points.append(f'<circle cx="{i}" cy="{y*50}" r="0.8" style="fill:black"/>')
plot_points_svg._nengo_html_ = f'''
<svg width="100%" height="100%" viewBox="0 0 120 0.001">
{''.join(points)}
</svg>
''' .format(**locals())
n_neurons = 1000
tau = 0.05
model = nengo.Network(seed=1)
with model:
def cann_iteration(x):
a = np.copy(x)
a[N:-1] = a[N:-1] + (-a[N:-1] + np.maximum(0, gammaE + wEEij @ a[N:-1] + wEI*a[-1] + a[0:N])) * T_E #
return a
def u_iteration(x):
b = np.copy(x)
b[-1] = b[-1] + (-b[-1] + np.maximum(0, gammaI + wIE * np.sum(b[0:N]) + wII * b[-1])) * T_I #
return b
node = nengo.Node(lambda t: 0.69 if t<0.1 else 0, size_out=1)
input = nengo.Node(output=X, size_out=N)
u = nengo.Ensemble(n_neurons=2000, dimensions=N+1, radius=1)
cann = nengo.Ensemble(n_neurons=2000, dimensions=2*N+1, radius=1)
plot = nengo.Node(plot_points_svg, size_in=2*N+1)
nengo.Connection(input, cann[0:N], synapse=None)
nengo.Connection(u[-1], cann[-1], synapse=0.05)
nengo.Connection(cann[N:-1], u[0:-1], synapse=0.05)
nengo.Connection(node, u[-1], synapse=None)
nengo.Connection(cann, plot)
nengo.Connection(cann, cann, function=cann_iteration, synapse=tauI)
nengo.Connection(u, u, function=u_iteration, synapse=tauI)
sim = nengo.Simulator(model)
sim.run(10)
But the result obviously does not form a continuous attractor.
In addition, I found another paper, but the implementation of planar attractors in it is too challenging for me, and I can’t confirm whether it meets the requirement for fusing information. It’s feeling pretty tough.