encoder_type = ['default', 'place_cell', 'band', 'grid_cell'][3] model = nengo.Network(seed=13) # duration = 70 duration = 40 dt = 0.001 n_samples = int(duration / dt) # set of positions to visit on a space filling curve, one for each timestep # positions = hilbert_2d(limit_low, limit_high, n_samples, rng, p=8, N=2, normal_std=0) positions = hilbert_2d(limit_low, limit_high, n_samples, rng, p=5, N=2, normal_std=0)[int(n_samples / 2):] neurons_per_dim = 5 n_neurons = dim * neurons_per_dim n_cconv_neurons = neurons_per_dim * 2 preferred_locations = hilbert_2d(limit_low, limit_high, n_neurons, rng, p=8, N=2, normal_std=3)
def decode_func(ssp): vs = np.tensordot(ssp, hmv, axes=([0], [2])) xy = np.unravel_index(vs.argmax(), vs.shape) x = xs[xy[0]] y = xs[xy[1]] return np.array([x, y]) rng = np.random.RandomState(seed=13) n_neurons = args.dim * args.neurons_per_dim preferred_locations = hilbert_2d(-limit, limit, n_neurons, rng, p=8, N=2, normal_std=3) encoders_place_cell = np.zeros((n_neurons, args.dim)) encoders_band_cell = np.zeros((n_neurons, args.dim)) encoders_grid_cell = np.zeros((n_neurons, args.dim)) encoders_mixed = np.zeros((n_neurons, args.dim)) mixed_intercepts = [] for n in range(n_neurons): ind = rng.randint(0, len(phis)) encoders_place_cell[n, :] = encode_func(preferred_locations[n, :]) encoders_grid_cell[n, :] = grid_cell_encoder( location=preferred_locations[n, :], dim=args.dim, phi=phis[ind], angle=angles[ind], toroid_index=ind )
ret += encode_point_hex(v[0] - dx * np.cos(angle), v[1] - dx * np.sin(angle), X, Y, Z).v return ret model = nengo.Network(seed=args.seed) dt = 0.001 n_samples = int(args.duration / dt) # set of positions to visit on a space filling curve, one for each timestep positions = hilbert_2d(-args.limit, args.limit, n_samples, rng, p=8, N=2, normal_std=0) n_neurons = args.dim * args.neurons_per_dim preferred_locations = hilbert_2d(-args.limit, args.limit, n_neurons, rng, p=8, N=2, normal_std=3) encoders_place_cell = np.zeros((n_neurons, args.dim))
# colours = sns.color_palette("hls", n_colors=dim) # colours = sns.color_palette(n_colors=dim) # colours = sns.color_palette("Paired", n_colors=dim) colours = [ sns.color_palette("muted", n_colors=dim // 2), sns.color_palette("colorblind", n_colors=dim // 2) ] loc = [40, 50] rng = np.random.RandomState(seed=13) sigma = 30 pc_centers = hilbert_2d(limit_low=limit_low, limit_high=limit_high, n_samples=dim, rng=rng) activations = np.zeros((dim, )) for i in range(dim): activations[i] = np.exp(-((pc_centers[i, 0] - loc[0])**2 + (pc_centers[i, 1] - loc[1])**2) / sigma / sigma) fig, ax = plt.subplots(1, 2, figsize=(6, 4), tight_layout=True, gridspec_kw={'width_ratios': [16, 5]}) res = 128 ax[0].set_xlim([0, res]) ax[0].set_ylim([0, res])
heatmap_vectors = get_heatmap_vectors(xs, ys, X, Y) # for direction SSP visualization xs_dir = np.linspace(-1.5, 1.5, 32) ys_dir = np.linspace(-1.5, 1.5, 32) heatmap_vectors_dir = get_heatmap_vectors(xs_dir, ys_dir, X, Y) if not use_spa: # spatial_heatmap = SpatialHeatmap(heatmap_vectors, xs, ys, cmap='plasma', vmin=None, vmax=None) # preferred_locations = hilbert_2d(-limit, limit, n_neurons, rng, p=8, N=2, normal_std=3) preferred_locations = hilbert_2d(limit_low, limit_high, n_neurons, rng, p=8, N=2, normal_std=3) encoders_place_cell = np.zeros((n_neurons, dim)) encoders_band_cell = np.zeros((n_neurons, dim)) encoders_grid_cell = np.zeros((n_neurons, dim)) encoders_mixed = np.zeros((n_neurons, dim)) mixed_intercepts = [] for n in range(n_neurons): ind = rng.randint(0, len(phis)) encoders_place_cell[n, :] = to_ssp(preferred_locations[n, :]) encoders_grid_cell[n, :] = grid_cell_encoder( location=preferred_locations[n, :],
# duration = 70 # one pass for one 'environment' another pass for a different one duration = 40 * 2 duration = 80 * 2 duration = 160 * 2 duration = 200 * 2 dt = 0.001 n_samples = int((duration / 2) / dt) # set of positions to visit on a space filling curve, one for each timestep # positions = hilbert_2d(limit_low, limit_high, n_samples, rng, p=8, N=2, normal_std=0) positions = hilbert_2d(limit_low, limit_high, n_samples, rng, p=6, N=2, normal_std=0) neurons_per_dim = 5 n_neurons = dim * neurons_per_dim n_cconv_neurons = neurons_per_dim * 2 # preferred_locations = hilbert_2d(pc_limit_low, pc_limit_high, n_neurons, rng, p=8, N=2, normal_std=3) preferred_locations = hilbert_2d(pc_limit_low, pc_limit_high, n_neurons, rng, p=10, N=2,
model = nengo.Network(seed=13) # duration = 70 # one pass for each environment duration = 40*args.n_envs dt = 0.001 n_samples = int((duration/args.n_envs) / dt) # set of positions to visit on a space filling curve, one for each timestep # positions = hilbert_2d(limit_low, limit_high, n_samples, rng, p=8, N=2, normal_std=0) positions = hilbert_2d(-args.limit, args.limit, n_samples, rng, p=6, N=2, normal_std=0) neurons_per_dim = 5 n_neurons = args.dim * neurons_per_dim n_cconv_neurons = neurons_per_dim * 2 # preferred_locations = hilbert_2d(-args.limit, args.limit, n_neurons, rng, p=8, N=2, normal_std=3) # preferred_locations = hilbert_2d(pc_limit_low, pc_limit_high, n_neurons, rng, p=10, N=2, normal_std=3) # preferred locations for each neurons, for each environment # using 2x limit so there is a chance that the neuron does not have a place field in the environment preferred_locations = rng.uniform(-2*args.limit, 2*args.limit, (args.n_envs, n_neurons, 2)) def input_func(t): index = int(np.floor(t/dt))
def __init__( self, phis, angles, encoder_rng=np.random, vocab=Default, # subdimensions=Default, neurons_per_dimension=Default, feedback=Default, represent_cc_identity=Default, feedback_synapse=Default, limit_low=-5, limit_high=-5, **kwargs): super(SSPState, self).__init__(**kwargs) self.vocab = vocab self.subdimensions = 6 self.neurons_per_dimension = neurons_per_dimension self.feedback = feedback self.feedback_synapse = feedback_synapse self.represent_cc_identity = represent_cc_identity dimensions = self.vocab.dimensions coord_rot_mat = get_coord_rot_mat(dimensions) inv_coord_rot_mat = np.linalg.pinv(coord_rot_mat) origin = np.zeros((dimensions, )) origin[0] = 1 rot_origin = origin @ coord_rot_mat.T origin_back = rot_origin @ inv_coord_rot_mat.T offset_vec = origin - origin_back # this offset only works for odd dimensions # offset_vec = np.ones((dimensions,)) * 1. / dimensions if ((dimensions - 1) % self.subdimensions != 0) and ( (dimensions - 2) % self.subdimensions != 0): raise ValidationError( "Dimensions (%d) must be divisible by subdimensions (%d)" % (dimensions, self.subdimensions), attr="dimensions", obj=self, ) with self: # if self.represent_cc_identity: # self.state_ensembles = IdentityEnsembleArray( # self.neurons_per_dimension, # dimensions, # self.subdimensions, # label="ssp state", # ) # else: # self.state_ensembles = EnsembleArray( # self.neurons_per_dimension * self.subdimensions, # dimensions // self.subdimensions, # ens_dimensions=self.subdimensions, # eval_points=nengo.dists.CosineSimilarity(dimensions + 2), # intercepts=nengo.dists.CosineSimilarity(dimensions + 2), # label="ssp state", # ) # the dimensionality with the constant(s) removed reduced_dim = coord_rot_mat.shape[0] n_toroids = len(phis) assert n_toroids == reduced_dim // self.subdimensions self.state_ensembles = EnsembleArray( self.neurons_per_dimension * self.subdimensions, n_toroids, ens_dimensions=self.subdimensions, # radius=2./dimensions, radius=1., # eval_points=nengo.dists.CosineSimilarity(dimensions + 2), # intercepts=nengo.dists.CosineSimilarity(dimensions + 2), label="ssp state", ) n_neurons = self.neurons_per_dimension * self.subdimensions # set the intercepts/encoders/eval points based on orientation and angle for k in range(n_toroids): preferred_locations = hilbert_2d(limit_low, limit_high, n_neurons, encoder_rng, p=8, N=2, normal_std=3) encoders_grid_cell = np.zeros((n_neurons, dimensions)) for n in range(n_neurons): encoders_grid_cell[n, :] = grid_cell_encoder( location=preferred_locations[n, :], dim=dimensions, phi=phis[k], angle=angles[k], toroid_index=k) # rotate, shift, and slice out relevant dimensions encoders_transformed = ( encoders_grid_cell @ coord_rot_mat.T)[:, k * 6:(k + 1) * 6].copy() self.state_ensembles.ea_ensembles[ k].intercepts = nengo.dists.Uniform(0, 1) self.state_ensembles.ea_ensembles[ k].encoders = encoders_transformed * (dimensions / 2.) # scaling eval points by the radius, so when they are rescaled later they are correct self.state_ensembles.ea_ensembles[ k].eval_points = encoders_transformed * (dimensions / 2.) # self.state_ensembles.ea_ensembles[k].normalize_encoders = False if self.feedback is not None and self.feedback != 0.0: nengo.Connection( self.state_ensembles.output, self.state_ensembles.input, transform=self.feedback, synapse=self.feedback_synapse, ) # Apply coordinate transform on the input and output self.input = nengo.Node(size_in=dimensions, label="input") self.output = nengo.Node(size_in=dimensions, label="output") # fixed offset to push the result back into the unitary space self.offset = nengo.Node(offset_vec) nengo.Connection(self.input, self.state_ensembles.input, transform=coord_rot_mat * (dimensions / 2.)) nengo.Connection(self.state_ensembles.output, self.output, transform=inv_coord_rot_mat / (dimensions / 2.)) nengo.Connection(self.offset, self.output) # self.input = self.state_ensembles.input # self.output = self.state_ensembles.output self.declare_input(self.input, self.vocab) self.declare_output(self.output, self.vocab)