def band_region_ssp(v, angle): ret = np.zeros((args.dim,)) ret[:] = encode_point(v[0], v[1], X, Y).v for dx in np.linspace(20./63., 20, 64): ret += encode_point(v[0] + dx * np.cos(angle), v[1] + dx * np.sin(angle), X, Y).v ret += encode_point(v[0] - dx * np.cos(angle), v[1] - dx * np.sin(angle), X, Y).v return ret
def input_ssp(v): if v[2] > .5: if use_offset: return encode_point(v[0], v[1], X, Y).v - offset else: return encode_point(v[0], v[1], X, Y).v else: return np.zeros((dim, ))
def to_hex_region_ssp(v, spacing=4): ret = np.zeros((args.dim,)) ret[:] = encode_point(v[0], v[1], X, Y).v for i in range(3): ret += encode_point(v[0] + spacing * np.cos(vec_dirs[i]), v[1] + spacing * np.sin(vec_dirs[i]), X, Y).v ret += encode_point(v[0] - spacing * np.cos(vec_dirs[i]), v[1] - spacing * np.sin(vec_dirs[i]), X, Y).v return ret
def input_func(t): index = int(np.floor(t / dt)) pos = positions[index % (n_samples - 1)] pos_ssp = encode_point(pos[0], pos[1], X, Y) # item = item_sp if diff_axis: bound = encode_point(pos[0], pos[1], X_new, Y_new) else: bound = item_sp * pos_ssp if index > n_samples - 1: return np.concatenate([pos, bound.v]) else: return np.concatenate([pos, pos_ssp.v])
def __init__(self, n_samples, limit, x_axis_sp, y_axis_sp, rng): self.ssps = np.zeros((n_samples, x_axis_sp.v.shape[0])).astype(np.float32) for i in range(n_samples): x = rng.uniform(-limit, limit) y = rng.uniform(-limit, limit) self.ssps[i, :] = encode_point(x, y, x_axis_sp, y_axis_sp).v
def input_func(t): index = int(np.floor(t/dt)) pos = positions[index % (n_samples - 1)] env_index = (index // (n_samples - 1)) % args.n_envs pos_ssp = encode_point(pos[0], pos[1], Xs[env_index], Ys[env_index]) return np.concatenate([pos, pos_ssp.v])
def encoding_func(positions): return encode_point( x=positions[0]*ssp_scaling, y=positions[1]*ssp_scaling, x_axis_sp=x_axis_sp, y_axis_sp=y_axis_sp ).v
def encoding_func(coords): return encode_point( x=coords[0], y=coords[1], x_axis_sp=x_axis_sp, y_axis_sp=y_axis_sp, ).v
def ssp_enc_func(coords, dim=256, seed=13): rng = np.random.RandomState(seed) x_axis_sp = make_good_unitary(dim, rng=rng) y_axis_sp = make_good_unitary(dim, rng=rng) return encode_point( x=coords[0], y=coords[1], x_axis_sp=x_axis_sp, y_axis_sp=y_axis_sp, ).v
def get_heatmap_vectors_with_offset(xs, ys, x_axis_sp, y_axis_sp): """ Precompute spatial semantic pointers for every location in the linspace Used to quickly compute heat maps by a simple vectorized dot product (matrix multiplication) """ if x_axis_sp.__class__.__name__ == 'SemanticPointer': dim = len(x_axis_sp.v) else: dim = len(x_axis_sp) x_axis_sp = spa.SemanticPointer(data=x_axis_sp) y_axis_sp = spa.SemanticPointer(data=y_axis_sp) vectors = np.zeros((len(xs), len(ys), dim)) for i, x in enumerate(xs): for j, y in enumerate(ys): p = encode_point( x=x, y=y, x_axis_sp=x_axis_sp, y_axis_sp=y_axis_sp, ) vectors[i, j, :] = p.v - offset return vectors
def loc_scale_to_surface(x): # # scale to between -1 and 1 # x_in = x[0] / (shape[0] / 2.) - 1 # y_in = x[1] / (shape[1] / 2.) - 1 # TEMP DEBUGGING x_in = x[0] y_in = x[1] return encode_point(x_in, y_in, x_axis_sp, y_axis_sp).v
def on_click(event): if (event.xdata is not None) and (event.ydata is not None): # TODO: need to make sure these coordinates are in the right reference frame, and translate them if they are not # goal = (event.xdata, event.ydata) # goal = image_coord_to_maze_coord(event.xdata, event.ydata) goal = image_coord_to_maze_coord(event.ydata, event.xdata) print(goal) if args.spatial_encoding == 'ssp': goal_ssp = encode_point(goal[0], goal[1], x_axis_sp, y_axis_sp).v else: goal_ssp = np.array([goal[0], goal[1]]) for i in range(res * res): viz_goal_sps[i, :] = goal_ssp dataset_viz = MazeDataset( maze_ssp=viz_maze_sps, loc_ssps=viz_loc_sps, goal_ssps=viz_goal_sps, locs=viz_locs, goals=viz_goals, direction_outputs= viz_output_dirs, # unused, but should be for wall overlay ) # Each batch will contain the samples for one maze. Must not be shuffled vizloader = torch.utils.data.DataLoader( dataset_viz, batch_size=res * res, shuffle=False, num_workers=0, ) for i, data in enumerate(vizloader): maze_loc_goal_ssps, directions, locs, goals = data outputs = model(maze_loc_goal_ssps) # NOTE: no ground truth is currently given, so no loss or RMSE can be calculated # loss = criterion(outputs, directions) # wall_overlay = (directions.detach().numpy()[:, 0] == 0) & (directions.detach().numpy()[:, 1] == 0) fig_pred, rmse = plot_path_predictions_image( ax=ax, directions_pred=outputs.detach().numpy(), directions_true=locs.detach().numpy(), wall_overlay=wall_overlay) ax.set_title("No ground truth given for RMSE") fig.canvas.draw()
def input_func(t): index = int(np.floor(t / dt)) pos = positions[index % (n_samples - 1)] pos_ssp = encode_point(pos[0], pos[1], X, Y) # item = item_sp bound_first = item_sp * pos_ssp bound_second = item_sp_2 * pos_ssp if index > n_samples - 1: return np.concatenate([pos, bound_second.v]) else: return np.concatenate([pos, bound_first.v])
def plot_heatmap(X, Y, xs, ys, ax): sim = np.zeros((len(xs), len(ys))) for i, x in enumerate(xs): for j, y in enumerate(ys): sim[i, j] = encode_point(x, y, spa.SemanticPointer(data=X), spa.SemanticPointer(data=Y)).v[0] im = ax.imshow(sim, vmin=0, vmax=1) # ax.set_axis_off() ax.set_xticks([]) ax.set_yticks([]) return im
def __call__(self, t, x): output = spa.SemanticPointer(data=np.zeros(self.dim)) for i in range(self.n_items): x_pos = x[i * 3] y_pos = x[i * 3 + 1] identity = np.clip(int(x[i * 3 + 2]), 0, self.n_vocab - 1) output += encode_point(x_pos, y_pos, self.x_axis_sp, self.y_axis_sp) * spa.SemanticPointer( data=self.vocab_vectors[identity]) return output.normalized().v
def one_hot_plot(xs, ys, x=0, y=0, D=8, xi=0, yi=0, name='Origin Point', **kwargs): x_axis_sp, y_axis_sp = one_hot_axes(D=D, xi=xi, yi=yi) point = encode_point(x=x, y=y, x_axis_sp=x_axis_sp, y_axis_sp=y_axis_sp) vs = spatial_dot(point, xs=xs, ys=ys, x_axis_sp=x_axis_sp, y_axis_sp=y_axis_sp) spatial_plot(vs, **kwargs)
def localization_gt(env): x = ((env.state[0] - 0) / coarse_size) * limit_range + xs[0] y = ((env.state[1] - 0) / coarse_size) * limit_range + ys[0] agent_ssp = encode_point(x, y, x_axis_sp, y_axis_sp) return torch.Tensor(agent_ssp.v).unsqueeze(0)
def cleanup_gt(env): x = ((env.goal_state[0] - 0) / coarse_size) * limit_range + xs[0] y = ((env.goal_state[1] - 0) / coarse_size) * limit_range + ys[0] goal_ssp = encode_point(x, y, x_axis_sp, y_axis_sp) return torch.Tensor(goal_ssp.v).unsqueeze(0)
seed=args.env_seed, ) # Fill the item memory with the correct SSP for remembering the goal locations item_memory = nengo_spa.SemanticPointer(data=np.zeros((args.dim, ))) for i in range(n_goals): sp_name = possible_objects[i] x_env, y_env = env.object_locations[sp_name][[0, 1]] # Need to scale to SSP coordinates # Env is 0 to 13, SSP is -5 to 5 x = ((x_env - 0) / coarse_size) * limit_range + xs[0] y = ((y_env - 0) / coarse_size) * limit_range + ys[0] item_memory += vocab[sp_name] * encode_point(x, y, x_axis_sp, y_axis_sp) # item_memory.normalize() item_memory = item_memory.normalized() # Component functions of the full system cleanup_network = FeedForward(input_size=args.dim, hidden_size=args.cleanup_hs, output_size=args.dim) if not args.use_cleanup_gt: cleanup_network.load_state_dict(torch.load( args.cleanup_network, map_location=lambda storage, loc: storage), strict=True) cleanup_network.eval() if args.spiking:
def encode_func(pos): # return encode_point_hex(pos[0], pos[1], X, Y, Z).v return encode_point(pos[0], pos[1], X, Y).v
randomize = False # item_vocab = spa.Vocabulary(args.dim, randomize=randomize) item_vocab = spa.Vocabulary(args.dim) item_vocab.populate(';'.join(list(items.keys()))) limit = 5 res = 256 xs = np.linspace(-limit, limit, res) ys = np.linspace(-limit, limit, res) mem_sp = spa.SemanticPointer(data=np.zeros((args.dim, ))) for key, value in items.items(): # mem_sp += item_vocab[key] * encode_point_hex(value[0], value[1], X, Y, Z) mem_sp += item_vocab[key] * encode_point(value[0], value[1], X, Y) def encode_func(pos): # return encode_point_hex(pos[0], pos[1], X, Y, Z).v return encode_point(pos[0], pos[1], X, Y).v # xs = np.linspace(-1, args.env_size+1, 256) if not os.path.exists('hmv_attractor_exp_{}.npz'.format(args.dim)): # hmv = get_heatmap_vectors_hex(xs, xs, X, Y, Z) hmv = get_heatmap_vectors(xs, xs, X, Y) np.savez('hmv_exp_{}.npz'.format(args.dim), hmv=hmv) else: hmv = np.load('hmv_attractor_exp_{}.npz'.format(args.dim))['hmv']
def experiment(dim=512, n_hierarchy=3, n_items=16, seed=0, limit=5, res=128, thresh=0.5, neural=False, neurons_per_dim=25, time_per_item=1.0, max_items=100): rng = np.random.RandomState(seed=seed) X, Y = get_fixed_dim_sub_toriod_axes( dim=dim, n_proj=3, scale_ratio=0, scale_start_index=0, rng=rng, eps=0.001, ) xs = np.linspace(-limit, limit, res) ys = np.linspace(-limit, limit, res) hmv = get_heatmap_vectors(xs, ys, X, Y) item_vecs = rng.normal(size=(n_items, dim)) for i in range(n_items): item_vecs[i, :] = item_vecs[i, :] / np.linalg.norm(item_vecs[i, :]) locations = rng.uniform(low=-limit, high=limit, size=(n_items, 2)) if n_hierarchy == 1: # no hierarchy case # Encode items into memory mem = np.zeros((dim, )) for i in range(n_items): mem += (spa.SemanticPointer(data=item_vecs[i, :]) * encode_point(locations[i, 0], locations[i, 1], X, Y)).v mem /= np.linalg.norm(mem) mem_sp = spa.SemanticPointer(data=mem) estims = np.zeros(( n_items, dim, )) sims = np.zeros((n_items, )) if neural: # save time for very large numbers of items n_exp_items = min(n_items, max_items) estims = np.zeros(( n_exp_items, dim, )) sims = np.zeros((n_exp_items, )) model = nengo.Network(seed=seed) with model: input_node = nengo.Node( lambda t: item_vecs[int(np.floor(t)) % n_items, :], size_in=0, size_out=dim) mem_node = nengo.Node(mem, size_in=0, size_out=dim) cconv = nengo.networks.CircularConvolution( n_neurons=neurons_per_dim, dimensions=dim, invert_b=True) nengo.Connection(mem_node, cconv.input_a) nengo.Connection(input_node, cconv.input_b) out_node = nengo.Node(size_in=dim, size_out=0) nengo.Connection(cconv.output, out_node) p_out = nengo.Probe(out_node, synapse=0.01) sim = nengo.Simulator(model) sim.run(n_exp_items * time_per_item) output_data = sim.data[p_out] timesteps_per_item = int(time_per_item / 0.001) # timestep offset to cancel transients offset = 100 for i in range(n_exp_items): estims[i, :] = output_data[i * timesteps_per_item + offset:(i + 1) * timesteps_per_item, :].mean(axis=0) sims[i] = np.dot( estims[i, :], encode_point(locations[i, 0], locations[i, 1], X, Y).v) pred_locs = ssp_to_loc_v(estims, hmv, xs, ys) errors = np.linalg.norm(pred_locs - locations[:n_exp_items, :], axis=1) accuracy = len(np.where(errors < thresh)[0]) / n_items rmse = np.sqrt(np.mean(errors**2)) sim = np.mean(sims) else: # retrieve items for i in range(n_items): estims[i, :] = (mem_sp * ~spa.SemanticPointer(data=item_vecs[i, :])).v sims[i] = np.dot( estims[i, :], encode_point(locations[i, 0], locations[i, 1], X, Y).v) pred_locs = ssp_to_loc_v(estims, hmv, xs, ys) errors = np.linalg.norm(pred_locs - locations, axis=1) accuracy = len(np.where(errors < thresh)[0]) / n_items rmse = np.sqrt(np.mean(errors**2)) sim = np.mean(sims) elif n_hierarchy == 2: # TODO: generate vocab and input sequences n_ids = int(np.sqrt(n_items)) f_n_ids = np.sqrt(n_items) id_vecs = rng.normal(size=(n_ids, dim)) for i in range(n_ids): id_vecs[i, :] = id_vecs[i, :] / np.linalg.norm(id_vecs[i, :]) # items to be included in each ID vec item_sums = np.zeros((n_ids, dim)) item_loc_sums = np.zeros((n_ids, dim)) for i in range(n_items): id_ind = min(i // n_ids, n_ids - 1) # id_ind = min(int(i / f_n_ids), n_ids - 1) item_sums[id_ind, :] += item_vecs[i, :] item_loc_sums[id_ind, :] += ( spa.SemanticPointer(data=item_vecs[i, :]) * encode_point(locations[i, 0], locations[i, 1], X, Y)).v # Encode id_vecs into memory, each id is bound to something that has similarity to all items in the ID's map mem = np.zeros((dim, )) for i in range(n_ids): # normalize previous memories item_sums[i, :] = item_sums[i, :] / np.linalg.norm(item_sums[i, :]) item_loc_sums[i, :] = item_loc_sums[i, :] / np.linalg.norm( item_loc_sums[i, :]) mem += (spa.SemanticPointer(data=id_vecs[i, :]) * spa.SemanticPointer(data=item_sums[i, :])).v mem /= np.linalg.norm(mem) mem_sp = spa.SemanticPointer(data=mem) estims = np.zeros(( n_items, dim, )) sims = np.zeros((n_items, )) # retrieve items for i in range(n_items): # noisy ID for the map with this item estim_id = (mem_sp * ~spa.SemanticPointer(data=item_vecs[i, :])).v # get closest clean match id_sims = np.zeros((n_ids, )) for j in range(n_ids): id_sims[j] = np.dot(estim_id, id_vecs[j, :]) best_ind = np.argmax(id_sims) # clean_id = id_vecs[best_ind, :] # item_loc_sums comes from the associative mapping from clean_id estims[i, :] = ( spa.SemanticPointer(data=item_loc_sums[best_ind, :]) * ~spa.SemanticPointer(data=item_vecs[i, :])).v sims[i] = np.dot( estims[i, :], encode_point(locations[i, 0], locations[i, 1], X, Y).v) pred_locs = ssp_to_loc_v(estims, hmv, xs, ys) errors = np.linalg.norm(pred_locs - locations, axis=1) accuracy = len(np.where(errors < thresh)[0]) / n_items rmse = np.sqrt(np.mean(errors**2)) sim = np.mean(sims) elif n_hierarchy == 3: # n_ids = int(np.cbrt(n_items)) f_n_ids = np.cbrt(n_items) n_ids = int(np.ceil(np.cbrt(n_items))) n_ids_inner = int(np.ceil(np.sqrt(n_items / n_ids))) # f_n_ids = np.cbrt(n_items) id_outer_vecs = rng.normal(size=(n_ids, dim)) id_inner_vecs = rng.normal(size=(n_ids_inner, dim)) for i in range(n_ids): id_outer_vecs[i, :] = id_outer_vecs[i, :] / np.linalg.norm( id_outer_vecs[i, :]) # for j in range(n_ids): # id_inner_vecs[i*n_ids+j, :] = id_inner_vecs[i*n_ids+j, :] / np.linalg.norm(id_inner_vecs[i*n_ids+j, :]) for i in range(n_ids_inner): id_inner_vecs[i, :] = id_inner_vecs[i, :] / np.linalg.norm( id_inner_vecs[i, :]) # items to be included in each ID vec item_outer_sums = np.zeros((n_ids, dim)) # item_inner_sums = np.zeros((n_ids*n_ids, dim)) item_inner_sums = np.zeros((n_ids_inner, dim)) item_loc_outer_sums = np.zeros((n_ids, dim)) # item_loc_inner_sums = np.zeros((n_ids*n_ids, dim)) item_loc_inner_sums = np.zeros((n_ids_inner, dim)) for i in range(n_items): id_outer_ind = min(int(i / (f_n_ids * f_n_ids)), n_ids - 1) id_inner_ind = min(int(i / f_n_ids), n_ids_inner - 1) item_outer_sums[id_outer_ind, :] += item_vecs[i, :] item_inner_sums[id_inner_ind, :] += item_vecs[i, :] item_loc_outer_sums[id_outer_ind, :] += ( spa.SemanticPointer(data=item_vecs[i, :]) * encode_point(locations[i, 0], locations[i, 1], X, Y)).v item_loc_inner_sums[id_inner_ind, :] += ( spa.SemanticPointer(data=item_vecs[i, :]) * encode_point(locations[i, 0], locations[i, 1], X, Y)).v # Encode id_vecs into memory, each id is bound to something that has similarity to all items in the ID's map mem_outer = np.zeros((dim, )) mem_inner = np.zeros(( n_ids, dim, )) for i in range(n_ids): # normalize previous memories item_outer_sums[i, :] = item_outer_sums[i, :] / np.linalg.norm( item_outer_sums[i, :]) item_loc_outer_sums[i, :] = item_loc_outer_sums[ i, :] / np.linalg.norm(item_loc_outer_sums[i, :]) mem_outer += (spa.SemanticPointer(data=id_outer_vecs[i, :]) * spa.SemanticPointer(data=item_outer_sums[i, :])).v for j in range(n_ids_inner): # normalize previous memories item_inner_sums[j, :] = item_inner_sums[j, :] / np.linalg.norm( item_inner_sums[j, :]) item_loc_inner_sums[j, :] = item_loc_inner_sums[ j, :] / np.linalg.norm(item_loc_inner_sums[j, :]) i = min(int(j / n_ids), n_ids - 1) mem_inner[i, :] += ( spa.SemanticPointer(data=id_inner_vecs[j, :]) * spa.SemanticPointer(data=item_inner_sums[j, :])).v mem_inner[i, :] /= np.linalg.norm(mem_inner[i, :]) mem_outer /= np.linalg.norm(mem_outer) mem_outer_sp = spa.SemanticPointer(data=mem_outer) estims = np.zeros(( n_items, dim, )) sims = np.zeros((n_items, )) if neural: # time for each item, in seconds time_per_item = 1.0 model = nengo.Network(seed=seed) with model: inp_node = nengo.Node('?', size_in=0, size_out=dim) estim_outer_id = nengo.Ensemble(dimension=dim, n_neurons=dim * neurons_per_dim) out_node = nengo.Node(size_in=dim, size_out=0) p_out = nengo.Probe(out_node, synapse=0.01) sim = nengo.Simulator(model) sim.run(n_items * time_per_item) else: # non-neural version # retrieve items for i in range(n_items): # noisy outer ID for the map with this item estim_outer_id = (mem_outer_sp * ~spa.SemanticPointer(data=item_vecs[i, :])).v # get closest clean match id_sims = np.zeros((n_ids)) for j in range(n_ids): id_sims[j] = np.dot(estim_outer_id, id_outer_vecs[j, :]) best_ind = np.argmax(id_sims) # noisy inner ID for the map with this item estim_inner_id = ( spa.SemanticPointer(data=mem_inner[best_ind, :]) * ~spa.SemanticPointer(data=item_vecs[i, :])).v # get closest clean match id_sims = np.zeros((n_ids_inner)) for j in range(n_ids_inner): id_sims[j] = np.dot(estim_inner_id, id_inner_vecs[j, :]) best_ind = np.argmax(id_sims) # item_loc_sums comes from the associative mapping from clean_id estims[i, :] = (spa.SemanticPointer( data=item_loc_inner_sums[best_ind, :]) * ~spa.SemanticPointer(data=item_vecs[i, :])).v sims[i] = np.dot( estims[i, :], encode_point(locations[i, 0], locations[i, 1], X, Y).v) pred_locs = ssp_to_loc_v(estims, hmv, xs, ys) errors = np.linalg.norm(pred_locs - locations, axis=1) accuracy = len(np.where(errors < thresh)[0]) / n_items rmse = np.sqrt(np.mean(errors**2)) sim = np.mean(sims) else: # 4 split hierarchy vocab = spa.Vocabulary(dimensions=dim, pointer_gen=np.random.RandomState(seed=seed)) filler_id_keys = [] filler_keys = [] mapping = {} items_left = n_items n_levels = 0 while items_left > 1: n_levels += 1 items_left /= 4 print(n_levels) # Location Values, labelled SSP for i in range(n_items): # vocab.populate('Item{}'.format(i)) vocab.add('Loc{}'.format(i), encode_point(locations[i, 0], locations[i, 1], X, Y).v) # level IDs, e.g. CITY, PROVINCE, COUNTRY for i in range(n_levels): vocab.populate('LevelSlot{}.unitary()'.format(i)) # sp = spa.SemanticPointer() # Item IDs, e.g. Waterloo_ID for i in range(n_items): vocab.populate('ItemID{}.unitary()'.format(i)) # level labels (fillers for level ID slots), e.g. Waterloo_ID, Ontario_ID, Canada_ID for i in range(n_levels): for j in range(int(n_items / (4**(n_levels - i - 1)))): vocab.populate('LevelFillerID{}_{}.unitary()'.format(i, j)) # filler_id_keys.append('LevelFillerID{}_{}'.format(i, j)) # filler_keys.append('LevelFiller{}_{}'.format(i, j)) # mapping['LevelFillerID{}_{}'.format(i, j)] = 'LevelFiller{}_{}'.format(i, j) # Second last level with item*location pairs for i in range(int(n_items / 4)): id_str = [] for k in range(n_levels - 1): id_str.append('LevelSlot{} * LevelFillerID{}_{}'.format( k, k, int(i * 4 / (4**(n_levels - k - 1))))) data_str = [] for j in range(4): ind = i * 4 + j data_str.append('ItemID{}*Loc{}'.format(ind, ind)) vocab.populate('Item{} = ({}).normalized()'.format( # i, ' + '.join(id_str + ['LevelSlot{} * LevelFillerID{}_{}'.format(n_levels - 2, n_levels - 2, j)]) ind, ' + '.join(id_str + [ 'LevelSlot{} * LevelFillerID{}_{}'.format( n_levels - 1, n_levels - 1, j) ]))) # vocab.populate('LevelFiller{}_{} = {}'.format(n_levels - 1, i, ' + '.join(data_str))) vocab.populate('LevelFiller{}_{} = ({}).normalized()'.format( n_levels - 2, i, ' + '.join(data_str))) # only appending the ones used filler_id_keys.append('LevelFillerID{}_{}'.format(n_levels - 2, i)) filler_keys.append('LevelFiller{}_{}'.format(n_levels - 2, i)) mapping['LevelFillerID{}_{}'.format( n_levels - 2, i)] = 'LevelFiller{}_{}'.format(n_levels - 2, i) print(sorted(list(vocab.keys()))) # Given each ItemID, calculate the corresponding Loc # Can map from ItemID{X} -> Item{X} # Query based on second last levelID to get the appropriate LevelFillerID # map from LevelFillerID -> LevelFiller # do the query LevelFiller *~ ItemID{X} to get Loc{X} possible_level_filler_id_vecs = np.zeros((int(n_items / 4), dim)) for i in range(int(n_items / 4)): possible_level_filler_id_vecs[i] = vocab[ 'LevelFillerID{}_{}'.format(n_levels - 2, i)].v estims = np.zeros(( n_items, dim, )) sims = np.zeros((n_items, )) if neural: # save time for very large numbers of items n_exp_items = min(n_items, max_items) estims = np.zeros(( n_exp_items, dim, )) sims = np.zeros((n_exp_items, )) filler_id_vocab = vocab.create_subset(keys=filler_id_keys) filler_vocab = vocab.create_subset(keys=filler_keys) filler_all_vocab = vocab.create_subset(keys=filler_keys + filler_id_keys) model = nengo.Network(seed=seed) with model: # The changing item query. Full expanded item, not just ID item_input_node = nengo.Node(lambda t: vocab['Item{}'.format( int(np.floor(t)) % n_items)].v, size_in=0, size_out=dim) # item_input_node = spa.Transcode(lambda t: 'Item{}'.format(int(np.floor(t))), output_vocab=vocab) # The ID for the changing item query item_id_input_node = nengo.Node(lambda t: vocab[ 'ItemID{}'.format(int(np.floor(t)) % n_items)].v, size_in=0, size_out=dim) # item_id_input_node = spa.Transcode(lambda t: 'ItemID{}'.format(int(np.floor(t))), output_vocab=vocab) # Fixed memory based on the level slot to access level_slot_input_node = nengo.Node( lambda t: vocab['LevelSlot{}'.format(n_levels - 2)].v, size_in=0, size_out=dim) model.cconv_noisy_level_filler = nengo.networks.CircularConvolution( n_neurons=neurons_per_dim * 2, dimensions=dim, invert_b=True) nengo.Connection(item_input_node, model.cconv_noisy_level_filler.input_a) nengo.Connection(level_slot_input_node, model.cconv_noisy_level_filler.input_b) # Note: this is set up as heteroassociative between ID and the content (should clean up as well) model.noisy_level_filler_id_cleanup = spa.ThresholdingAssocMem( threshold=0.4, input_vocab=filler_id_vocab, output_vocab=filler_vocab, # mapping=vocab.keys(), mapping=mapping, function=lambda x: x > 0.) nengo.Connection(model.cconv_noisy_level_filler.output, model.noisy_level_filler_id_cleanup.input) model.cconv_location = nengo.networks.CircularConvolution( n_neurons=neurons_per_dim * 2, dimensions=dim, invert_b=True) nengo.Connection(model.noisy_level_filler_id_cleanup.output, model.cconv_location.input_a) nengo.Connection(item_id_input_node, model.cconv_location.input_b) out_node = nengo.Node(size_in=dim, size_out=0) nengo.Connection(model.cconv_location.output, out_node) p_out = nengo.Probe(out_node, synapse=0.01) sim = nengo.Simulator(model) sim.run(n_exp_items * time_per_item) output_data = sim.data[p_out] timesteps_per_item = int(time_per_item / 0.001) # timestep offset to cancel transients offset = 100 for i in range(n_exp_items): estims[i, :] = output_data[i * timesteps_per_item + offset:(i + 1) * timesteps_per_item, :].mean(axis=0) sims[i] = np.dot( estims[i, :], encode_point(locations[i, 0], locations[i, 1], X, Y).v) pred_locs = ssp_to_loc_v(estims, hmv, xs, ys) errors = np.linalg.norm(pred_locs - locations[:n_exp_items, :], axis=1) accuracy = len(np.where(errors < thresh)[0]) / n_items rmse = np.sqrt(np.mean(errors**2)) sim = np.mean(sims) else: # non-neural version # retrieve items for i in range(n_items): noisy_level_filler_id = vocab['Item{}'.format( i)] * ~vocab['LevelSlot{}'.format(n_levels - 2)] # cleanup filler id n_fillers = int(n_items / 4) sim = np.zeros((n_fillers, )) for j in range(n_fillers): sim[j] = np.dot(noisy_level_filler_id.v, possible_level_filler_id_vecs[j, :]) filler_id_ind = np.argmax(sim) # query the appropriate filler loc_estim = vocab['LevelFiller{}_{}'.format( n_levels - 2, filler_id_ind)] * ~vocab['ItemID{}'.format(i)] estims[i, :] = loc_estim.v sims[i] = np.dot( estims[i, :], encode_point(locations[i, 0], locations[i, 1], X, Y).v) pred_locs = ssp_to_loc_v(estims, hmv, xs, ys) errors = np.linalg.norm(pred_locs - locations, axis=1) accuracy = len(np.where(errors < thresh)[0]) / n_items rmse = np.sqrt(np.mean(errors**2)) sim = np.mean(sims) return rmse, accuracy, sim
ys = example_ys # Set up train and test sets train_inputs = np.zeros((args.n_train_samples, args.dim)) train_outputs = np.zeros((args.n_train_samples, 2)) train_coords = np.zeros((args.n_train_samples, 2)) test_inputs = np.zeros((args.n_test_samples, args.dim)) test_outputs = np.zeros((args.n_test_samples, 2)) test_coords = np.zeros((args.n_test_samples, 2)) for n in range(args.n_train_samples): x = np.random.uniform(low=xs[0], high=xs[-1]) y = np.random.uniform(low=ys[0], high=ys[-1]) train_inputs[n, :] = encode_point(x, y, x_axis_sp, y_axis_sp).v train_coords[n, :] = np.array([x, y]) train_outputs[n, :] = path_function(train_coords[n, :], path, xs, ys) for n in range(args.n_test_samples): x = np.random.uniform(low=xs[0], high=xs[-1]) y = np.random.uniform(low=ys[0], high=ys[-1]) test_inputs[n, :] = encode_point(x, y, x_axis_sp, y_axis_sp).v test_coords[n, :] = np.array([x, y]) test_outputs[n, :] = path_function(test_coords[n, :], path, xs, ys) dataset_train = PathDataset(ssp_inputs=train_inputs, direction_outputs=train_outputs, coord_inputs=train_coords) dataset_test = PathDataset(ssp_inputs=test_inputs,
def angle_to_ssp(x): return encode_point(np.cos(x), np.sin(x), x_axis_sp, y_axis_sp).v
def to_ssp(v): return encode_point(v[0], v[1], X, Y).v
parser.add_argument('--res', type=int, default=256) parser.add_argument('--limit', type=int, default=5) args = parser.parse_args() folder = 'images/ssp_rate_maps/dim{}_limit{}_seed{}'.format( args.dim, args.limit, args.seed) if not os.path.exists(folder): os.makedirs(folder) rng = np.random.RandomState(seed=args.seed) x_axis_sp = make_good_unitary(dim=args.dim, rng=rng) y_axis_sp = make_good_unitary(dim=args.dim, rng=rng) xs = np.linspace(-args.limit, args.limit, args.res) ys = np.linspace(-args.limit, args.limit, args.res) activations = np.zeros((args.dim, args.res, args.res)) for i, x in enumerate(xs): for j, y in enumerate(ys): activations[:, i, j] = encode_point(x, y, x_axis_sp, y_axis_sp).v for n in range(args.dim): print("Dimension {} of {}".format(n + 1, args.dim)) fig, ax = plt.subplots() ax.imshow(activations[n, :, :]) fig.savefig("{}/dimension_{}".format(folder, n))
def enc_func(x, y): # return encode_point_hex(pos[0], pos[1], X, Y, Z).v return encode_point(x, y, X, Y).v
goal_x = xs[goal_index[0]] goal_y = ys[goal_index[1]] # make sure the goal is placed in an open space assert (fine_maze[goal_index[0], goal_index[1]] == 0) # Compute the optimal path given this goal # Full solve is set to true, so start_indices is ignored solved_maze = solve_maze(fine_maze, start_indices=goal_index, goal_indices=goal_index, full_solve=True) goals[mi, n, 0] = goal_x goals[mi, n, 1] = goal_y goal_sps[mi, n, :] = encode_point(goal_x, goal_y, x_axis_sp, y_axis_sp).v solved_mazes[mi, n, :, :, :] = solved_maze # Compute energy function to avoid walls # will contain a sum of gaussians placed at all wall locations wall_energy = np.zeros_like(fine_mazes) # will contain directions corresponding to the gradient of the wall energy # to be added to the solved maze to augment the directions chosen wall_gradient = np.zeros_like(solved_mazes) meshgrid = np.meshgrid(xs, ys) # Compute wall energy
def get_ssp_activation(pos): return encode_point(pos[0] * args.ssp_scaling, pos[1] * args.ssp_scaling, x_axis_sp, y_axis_sp).v
node_locs = list() node_locs.append(np.array([1.0, 1.0])) node_locs.append(np.array([1.4, 4.7])) node_locs.append(np.array([3.2, 6.7])) node_locs.append(np.array([3.8, 1.4])) node_locs.append(np.array([4.4, 4.2])) node_locs.append(np.array([6.7, 1.1])) node_locs.append(np.array([7.1, 5.0])) nodes = [] # Vocab of landmark IDs vocab_vectors = np.zeros((len(node_locs), dim)) vocab = spa.Vocabulary(dim, max_similarity=0.01) for i, loc in enumerate(node_locs): nodes.append(Node(index=i, data={'location': loc})) map_sp += encode_point(loc[0], loc[1], x_axis_sp, y_axis_sp) # Note: the landmark IDs don't have to be 'good' unitaries # landmark_ids.append(make_good_unitary(dim)) # landmark_ids.append(spa.SemanticPointer(dim)) # sp = spa.SemanticPointer(dim) # sp.make_unitary() sp = vocab.parse("Landmark{}".format(i)) landmark_ids.append(sp) landmark_map_sp += landmark_ids[i] * encode_point(loc[0], loc[1], x_axis_sp, y_axis_sp) vocab_vectors[i, :] = landmark_ids[i].v