def get_projected_heatmap_vectors(xs, ys, x_axis_sp, y_axis_sp, z_axis_sp): 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) z_axis_sp = spa.SemanticPointer(data=z_axis_sp) vectors = np.zeros((len(xs), len(ys), dim)) for i, x in enumerate(xs): for j, y in enumerate(ys): # xyz = xy_to_xyz([x, y]) xyz = xy_to_xyz_v(np.array([[x, y]]))[0, :] p = encode_point_3d( x=xyz[0], y=xyz[1], z=xyz[2], x_axis_sp=x_axis_sp, y_axis_sp=y_axis_sp, z_axis_sp=z_axis_sp, ) vectors[i, j, :] = p.v return vectors
def get_heatmap_vectors(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 return vectors
def generate_coord_dataset(n_samples, dim, x_axis_sp=None, y_axis_sp=None, z_axis_sp=None, hexagonal_coordinates=False, limits=(-1, 1, -1, 1), seed=13): """ Create a dataset of semantic pointer coordinates and their corresponding real coordinates :param n_samples: number of coordinates to create :param dim: dimensionality of the semantic pointers :param x_axis_sp: optional x_axis semantic pointer. If not supplied, will be generated as a unitary vector :param y_axis_sp: optional y_axis semantic pointer. If not supplied, will be generated as a unitary vector :param z_axis_sp: optional z_axis semantic pointer. If not supplied, will be generated as a unitary vector :param hexagonal_coordinates: if three axes of a hexagonal system are to be used :param limits: limits of the 2D space (x_low, x_high, y_low, y_high) :param seed: random seed for the memories and axis vectors if not supplied :return: vectors, coords, x_axis_sp, y_axis_sp, z_axis_sp """ # This seed must match the one that was used to generate the model np.random.seed(seed) if x_axis_sp is None: x_axis_sp = spa.SemanticPointer(dim) x_axis_sp.make_unitary() if y_axis_sp is None: y_axis_sp = spa.SemanticPointer(dim) y_axis_sp.make_unitary() if z_axis_sp is None: z_axis_sp = spa.SemanticPointer(dim) z_axis_sp.make_unitary() # Semantic pointer vectors vectors = np.zeros((n_samples, dim)) # Actual coordinates coords = np.zeros((n_samples, 2)) for i in range(n_samples): x = np.random.uniform(low=limits[0], high=limits[1]) y = np.random.uniform(low=limits[2], high=limits[3]) if hexagonal_coordinates: vectors[i, :] = encode_hex_point(x, y, x_axis_sp=x_axis_sp, y_axis_sp=y_axis_sp, z_axis_sp=z_axis_sp).v else: vectors[i, :] = encode_point(x, y, x_axis_sp=x_axis_sp, y_axis_sp=y_axis_sp).v coords[i, 0] = x coords[i, 1] = y return vectors, coords, x_axis_sp, y_axis_sp, z_axis_sp
def make_multigoal_ssp_env(map_array, csp_scaling, csp_offset, object_locations, x_axis_vec, y_axis_vec, dim=512, continuous=True, movement_type='holonomic'): params = { 'x_axis_vec': spa.SemanticPointer(data=x_axis_vec), 'y_axis_vec': spa.SemanticPointer(data=y_axis_vec), 'goal_csp': True, 'agent_csp': True, 'csp_dim': dim, 'goal_csp_egocentric': False, # other arguments for bio sensors "full_map_obs": False, "pob": 0, "max_sensor_dist": 10, "n_sensors": 10, "fov": 180, "normalize_dist_sensors": True, "n_grid_cells": 0, "heading": "none", "location": "none", "goal_loc": "none", "bc_n_ring": 12, "bc_n_rad": 3, "bc_dist_rad": 0.75, "bc_receptive_field_min": 1, "bc_receptive_field_max": 1.5, "hd_n_cells": 8, "hd_receptive_field_min": 0.78539816339, "hd_receptive_field_max": 0.78539816339, "goal_vec": "normalized", } obs_dict = generate_obs_dict(params) env = GridWorldEnv( map_array=map_array, object_locations=object_locations, observations=obs_dict, movement_type=movement_type, max_lin_vel=5, max_ang_vel=5, continuous=continuous, max_steps=1000, fixed_episode_length=False, # True, dt=0.1, screen_width=300, screen_height=300, csp_scaling=csp_scaling, csp_offset=csp_offset, ) return env
def one_hot_axes(D=8, xi=0, yi=0): xv = np.zeros((D, )) xv[xi] = 1 yv = np.zeros((D, )) yv[yi] = 1 # Note that making them unitary doesn't seem to be required for one-hot vectors x_axis_sp = spa.SemanticPointer(data=xv) x_axis_sp.make_unitary() y_axis_sp = spa.SemanticPointer(data=yv) y_axis_sp.make_unitary() return x_axis_sp, y_axis_sp
def generate_item_memory(dim, n_items, limits, x_axis_sp, y_axis_sp, normalize_memory=True, encoding='pow'): """ Create a semantic pointer that contains a number of items bound with respective coordinates Returns the memory, along with a list of the items and coordinates used The encoding parameter determines which method is used to store items at locations """ assert encoding in ['pow', 'mag', 'sep_pow'] # Start with an empty memory memory_sp = spa.SemanticPointer(data=np.zeros((dim, ))) coord_list = [] item_list = [] for n in range(n_items): # Generate random point x = np.random.uniform(low=limits[0], high=limits[1]) y = np.random.uniform(low=limits[2], high=limits[3]) # Generate random item item = spa.SemanticPointer(dim) # Add the item to memory at the particular location # This is done differently depending on the encoding method if encoding == 'pow': # Circular convolution power representation pos = encode_point(x, y, x_axis_sp=x_axis_sp, y_axis_sp=y_axis_sp) # Add the item at the point to memory memory_sp += (pos * item) elif encoding == 'mag': # Magnitude scaling representation memory_sp += (x * (item * x_axis_sp) + y * (item * y_axis_sp)) elif encoding == 'sep_pow': # Power representation, but X and Y are independent memory_sp += (item * power(x_axis_sp, x) + item * power(y_axis_sp, y)) coord_list.append((x, y)) item_list.append(item) if normalize_memory: memory_sp.normalize() return memory_sp, coord_list, item_list
def make_good_unitary(D, eps=1e-3, rng=np.random): ''' return: a semantic pointer object with dimension D. ''' a = rng.rand((D - 1) // 2) sign = rng.choice((-1, +1), len(a)) phi = sign * np.pi * (eps + a * (1 - 2 * eps)) assert np.all(np.abs(phi) >= np.pi * eps) assert np.all(np.abs(phi) <= np.pi * (1 - eps)) fv = np.zeros(D, dtype='complex64') fv[0] = 1 fv[1:(D + 1) // 2] = np.cos(phi) + 1j * np.sin(phi) fv[-1:D // 2:-1] = np.conj(fv[1:(D + 1) // 2]) if D % 2 == 0: fv[D // 2] = 1 assert np.allclose(np.abs(fv), 1) v = np.fft.ifft(fv) # assert np.allclose(v.imag, 0, atol=1e-5) v = v.real assert np.allclose(np.fft.fft(v), fv) assert np.allclose(np.linalg.norm(v), 1) return spa.SemanticPointer(v)
def random_unitary(n_samples=1000, dim=3, version=1, eps=0.001): points = np.zeros((n_samples, dim)) good = np.zeros((n_samples, )) for i in range(n_samples): if version == 1: sp = nengo_spa.SemanticPointer(data=np.random.randn(dim)) sp = sp.normalized() sp = sp.unitary() elif version == 0: sp = spa.SemanticPointer(dim) sp.make_unitary() elif version == 2: sp = make_good_unitary(dim=dim) else: raise NotImplementedError points[i, :] = sp.v pf = np.fft.fft(points[i, :]) if dim % 2 == 0: if np.abs(pf[0] - 1) < eps and np.abs(pf[dim // 2] - 1) < eps: good[i] = 1 else: if np.abs(pf[0] - 1) < eps: good[i] = 1 return points, good
def angle_spacing_axes(ang_x, ang_y, off_x=0, off_y=0, dim=32): # X_test = ((np.arange(dim) * ang_x) + off_x) % (2 * np.pi) # Y_test = ((np.arange(dim) * ang_y) + off_y) % (2 * np.pi) X_test = ((np.arange(dim) * ang_x) + off_x) % 360 Y_test = ((np.arange(dim) * ang_y) + off_y) % 360 Xc = np.cos(X_test * np.pi / 180) + 1j * np.sin(X_test * np.pi / 180) Yc = np.cos(Y_test * np.pi / 180) + 1j * np.sin(Y_test * np.pi / 180) X = np.fft.ifft(Xc) Y = np.fft.ifft(Yc) X = spa.SemanticPointer(data=X) Y = spa.SemanticPointer(data=Y) X.make_unitary() Y.make_unitary() return X, Y
def power(s, e): ''' s: a semantic pointer object that represent the axis e: a value that indicates the coordinate return: a encoded semantic pointer object ''' x = np.fft.ifft(np.fft.fft(s.v) ** e).real return spa.SemanticPointer(data=x)
def unitary_points(dim, n_samples, good_unitary=False): points = np.zeros((n_samples, dim)) for i in range(n_samples): if good_unitary: points[i, :] = make_good_unitary(dim=dim).v else: sp = spa.SemanticPointer(dim) sp.make_unitary() points[i, :] = sp.v return points
def unitary_determinant_test(dim=2, n_samples=1000): for i in range(n_samples): if True: vec = make_good_unitary(dim=dim).v print(vec) else: sp = spa.SemanticPointer(dim) sp.make_unitary() vec = sp.v if not np.allclose(np.dot(circulant(vec)[0], circulant(vec)[1]), 0): print(np.dot(circulant(vec)[0], circulant(vec)[1])) print(np.linalg.det(circulant(vec))) # assert np.allclose(np.dot(circulant(vec)[0], circulant(vec)[1]), 0) assert np.allclose(np.abs(np.linalg.det(circulant(vec))), 1) return True
def random_unitary(n_samples=1000, dim=3, version=2): points = np.zeros((n_samples, dim)) for i in range(n_samples): if version == 1: sp = nengo_spa.SemanticPointer(data=np.random.randn(dim)) sp = sp.normalized() sp = sp.unitary() elif version == 0: sp = spa.SemanticPointer(dim) sp.make_unitary() elif version == 2: sp = make_good_unitary(dim=dim) else: raise NotImplementedError points[i, :] = sp.v return points
def generate_region_vector(desired, xs, ys, x_axis_sp, y_axis_sp): """ :param desired: occupancy grid of what points should be in the region and which ones should not be :param xs: linspace in x :param ys: linspace in y :param x_axis_sp: x axis semantic pointer :param y_axis_sp: y axis semantic pointer :return: a normalized semantic pointer designed to be highly similar to the desired region """ vector = np.zeros_like((x_axis_sp.v)) for i, x in enumerate(xs): for j, y in enumerate(ys): if desired[i, j] == 1: vector += encode_point(x, y, x_axis_sp, y_axis_sp).v sp = spa.SemanticPointer(data=vector) sp.normalize() return sp
def encode_dataset(encoded_feature, aggregate_between_feature = 'sum'): ''' encoded_feature: A list of encoded_features. Each entry is an numpy array with size n * dim. aggregate_between_feature: 'sum' or 'multiply' return: a n * d array where n is the number of datapoints and d is the dimension of the sps. ''' m = len(encoded_feature) n = encoded_feature[0].shape[0] dim = encoded_feature[1].shape[1] result = np.zeros((n, dim)) if aggregate_between_feature == 'sum': for i in range(n): for j in range(m): result[i,:] += encoded_feature[j][i,:] elif aggregate_between_feature == 'multiply': for i in range(n): temp = 1 for j in range(m): temp *= spa.SemanticPointer(data=encoded_feature[j][i,:]) result[i,:] = temp.v return result
def step(self): self.diameter += self.diameter_increment self.ellipse_sp = generate_elliptic_region_vector( xs=self.xs, ys=self.ys, x_axis_sp=self.x_axis_sp, y_axis_sp=self.y_axis_sp, f1=self.current_loc, f2=self.goal_loc, diameter=self.diameter, normalize=self.normalize, ) potential_landmark = self.allo_connections_sp * ~self.ellipse_sp # NOTE: this is only correct if allo_connections has landmark_id_sp information in it sim = np.tensordot(potential_landmark.v, self.landmark_vectors, axes=([0], [1])) # argsort sorts from lowest to highest, so create a view that reverses it inds = np.argsort(sim)[::-1] for i in inds: if sim[i] < self.threshold: # The next closest match is below threshold, so all others will be too return None elif i not in self.expanded_list: print( "{} detected as closest connection with diameter {} and {} similarity" .format(i, self.diameter, sim[i])) # Above threshold and has not been expanded yet, add it to the list now self.expanded_list.append(i) # Return the ID and the semantic pointer return i, spa.SemanticPointer(data=self.landmark_vectors[i])
def encode_datapoint(datapoint, sps, binding = 'multiply', aggregate = 'sum'): ''' datapoint: an 1 by m array. m is the number of possible choices of the property being encoded. (ex. when encoding object kind, the possible choices of object kind are 'bolt' and 'nut'). sps: A list of size m. Each entry is the semantic pointer for each of the possible choices. binding: The type to bind each entry. There are two ways: 1. 'multiply': c1*sp1 2. 'power': sp1^c1 aggregate: The type to bind between entries. There are two ways: 1. 'sum': c1*sp1 + c2 * sp2 2. 'multiply': sp1^c1 * sp2^c2 return: a SemanticPointer object that encode a datapoint(ex. c1*sp1 + c2*sp2) ''' m = len(sps) if aggregate == 'sum': result = 0 for i in range(m): result += encode_entry(datapoint[i], sps[i], binding = binding).v return spa.SemanticPointer(data = result) elif aggregate == 'multiply': result = 1 for i in range(m): result *= encode_entry(datapoint[i], sps[i], binding = binding) return result
import nengo_spa from spatial_semantic_pointers.utils import make_good_unitary version = 2 n_samples = 25000 #10000 dim = 5 #3 points = np.zeros((n_samples, dim)) for i in range(n_samples): if version == 1: sp = nengo_spa.SemanticPointer(data=np.random.randn(dim)) sp = sp.normalized() sp = sp.unitary() elif version == 0: sp = spa.SemanticPointer(dim) sp.make_unitary() elif version == 2: sp = make_good_unitary(dim=dim) points[i, :] = sp.v fig = plt.figure() ax = fig.add_subplot(111, projection='3d') def orthogonal_dir_unitary(dim=5, phi=np.pi / 2.): xf = np.zeros((dim, ), dtype='Complex64') xf[0] = 1 xf[1] = np.exp(1.j * phi) xf[2] = 1
# # n_mazes by dim # maze_sps = data['maze_sps'] # n_mazes by n_goals by 2 goals = data['goals'] # n_goals = goals.shape[1] n_mazes = fine_mazes.shape[0] id_size = args.maze_id_dim maze_sps = np.zeros((n_mazes, args.maze_id_dim)) # overwrite data for mi in range(n_mazes): maze_sps[mi, :] = spa.SemanticPointer(args.maze_id_dim).v # the unsqueeze is to add the batch dimension map_id = torch.Tensor(maze_sps[args.maze_index, :]).unsqueeze(0) n_sensors = 36 colour_centers = np.array([ [3, 3], [10, 4], [7, 7], ]) def colour_func(x, y, sigma=7): ret = np.zeros((3, ))
def __init__( self, start_landmark_id, end_landmark_id, landmark_map_sp, con_ego_sp, con_allo_sp, landmark_vectors, x_axis_sp, y_axis_sp, xs, ys, heatmap_vectors, # params for debugging true_allo_con_sps, connectivity_list, con_calculation='true_allo', normalize=True, debug_mode=False, # ellipse params diameter_increment=1, **unused_params): self.debug_mode = debug_mode # Various methods for calculating the connectivity of a particular node. Used for debugging assert con_calculation in ['ego', 'allo', 'true_allo'] self.con_calculation = con_calculation self.start_landmark_id = start_landmark_id self.end_landmark_id = end_landmark_id self.landmark_map_sp = landmark_map_sp self.con_ego_sp = con_ego_sp self.con_allo_sp = con_allo_sp self.landmark_vectors = landmark_vectors self.x_axis_sp = x_axis_sp self.y_axis_sp = y_axis_sp self.xs = xs self.ys = ys self.heatmap_vectors = heatmap_vectors self.true_allo_con_sps = true_allo_con_sps self.connectivity_list = connectivity_list # Whether or not to normalize the ellipse region SP self.normalize = normalize self.diameter_increment = diameter_increment start_landmark_sp = spa.SemanticPointer( self.landmark_vectors[self.start_landmark_id]) end_landmark_sp = spa.SemanticPointer( self.landmark_vectors[self.end_landmark_id]) current_loc_sp = self.landmark_map_sp * ~start_landmark_sp self.goal_loc_sp = self.landmark_map_sp * ~end_landmark_sp self.goal_loc = ssp_to_loc(self.goal_loc_sp, heatmap_vectors=self.heatmap_vectors, xs=self.xs, ys=self.ys) # egocentric displacements to nearby landmarks ego_connections_sp = con_ego_sp * ~start_landmark_sp # allocentric coordinates of nearby landmarks if self.con_calculation == 'ego': # calculating from ego allo_connections_sp = current_loc_sp * ego_connections_sp elif self.con_calculation == 'allo': # getting true value from allo allo_connections_sp = self.con_allo_sp * ~start_landmark_sp elif self.con_calculation == 'true_allo': # get a clean value from allo allo_connections_sp = self.true_allo_con_sps[ self.start_landmark_id] else: raise NotImplementedError # dictionary of nodes currently being expanded self.expanding_nodes = { self.start_landmark_id: ExpandingNode( current_loc_sp=current_loc_sp, goal_loc_sp=self.goal_loc_sp, closest_landmark_id=self.start_landmark_id, allo_connections_sp=allo_connections_sp, landmark_map_sp=self.landmark_map_sp, landmark_vectors=self.landmark_vectors, x_axis_sp=self.x_axis_sp, y_axis_sp=self.y_axis_sp, xs=self.xs, ys=self.ys, heatmap_vectors=self.heatmap_vectors, normalize=self.normalize, ) }
def orthogonal_hex_dir_7dim(phi=np.pi / 2., angle=0): dim = 7 xf = np.zeros((dim, ), dtype='Complex64') xf[0] = 1 xf[1] = np.exp(1.j * phi) xf[2] = 1 xf[3] = 1 xf[4] = np.conj(xf[3]) xf[5] = np.conj(xf[2]) xf[6] = np.conj(xf[1]) yf = np.zeros((dim, ), dtype='Complex64') yf[0] = 1 yf[1] = 1 yf[2] = np.exp(1.j * phi) yf[3] = 1 yf[4] = np.conj(yf[3]) yf[5] = np.conj(yf[2]) yf[6] = np.conj(yf[1]) zf = np.zeros((dim, ), dtype='Complex64') zf[0] = 1 zf[1] = 1 zf[2] = 1 zf[3] = np.exp(1.j * phi) zf[4] = np.conj(zf[3]) zf[5] = np.conj(zf[2]) zf[6] = np.conj(zf[1]) Xh = np.fft.ifft(xf).real Yh = np.fft.ifft(yf).real Zh = np.fft.ifft(zf).real # checks to make sure everything worked correctly assert np.allclose(np.abs(xf), 1) assert np.allclose(np.abs(yf), 1) assert np.allclose(np.fft.fft(Xh), xf) assert np.allclose(np.fft.fft(Yh), yf) assert np.allclose(np.linalg.norm(Xh), 1) assert np.allclose(np.linalg.norm(Yh), 1) axis_sps = [ spa.SemanticPointer(data=Xh), spa.SemanticPointer(data=Yh), spa.SemanticPointer(data=Zh), ] n = 3 points_nd = np.eye(n) * np.sqrt(n) # points in 2D that will correspond to each axis, plus one at zero points_2d = np.zeros((n, 2)) thetas = np.linspace(0, 2 * np.pi, n + 1)[:-1] + angle # TODO: will want a scaling here, or along the high dim axes for i, theta in enumerate(thetas): points_2d[i, 0] = np.cos(theta) points_2d[i, 1] = np.sin(theta) transform_mat = np.linalg.lstsq(points_2d, points_nd) x_axis = transform_mat[0][0, :] / transform_mat[3][0] y_axis = transform_mat[0][1, :] / transform_mat[3][1] X = power(axis_sps[0], x_axis[0]) Y = power(axis_sps[0], y_axis[0]) for i in range(1, n): X *= power(axis_sps[i], x_axis[i]) Y *= power(axis_sps[i], y_axis[i]) sv = transform_mat[3][0] return X, Y, sv, transform_mat[0]
sim_arcs = np.zeros((n_seeds, n_animals)) if not os.path.exists(folder): # Data is not saved already, generate it now and save it after for seed in range(n_seeds): rstate = np.random.RandomState(seed=seed) x_axis_sp = make_good_unitary(dim, rng=rstate) y_axis_sp = make_good_unitary(dim, rng=rstate) heatmap_vectors = get_heatmap_vectors(xs, ys, x_axis_sp, y_axis_sp) vocab_sps = {} for i, animal in enumerate(vocab_labels): vocab_sps[animal] = spa.SemanticPointer(dim) vocab_vectors[i, :] = vocab_sps[animal].v mem = spa.SemanticPointer(data=np.zeros(dim)) fox_pos1 = encode_point(1.2, 1.3, x_axis_sp, y_axis_sp) fox_pos2 = encode_point(-3.4, -1.1, x_axis_sp, y_axis_sp) dog_pos = encode_point(1.7, -1.1, x_axis_sp, y_axis_sp) badger_pos = encode_point(4.1, 3.2, x_axis_sp, y_axis_sp) bear_pos = encode_point(2.1, 2.4, x_axis_sp, y_axis_sp) none_pos = encode_point(0, 0, x_axis_sp, y_axis_sp) mem += vocab_sps['Fox'] * fox_pos1 mem += vocab_sps['Fox'] * fox_pos2 mem += vocab_sps['Dog'] * dog_pos mem += vocab_sps['Badger'] * badger_pos
xs = np.linspace(0, 10, res) ys = np.linspace(0, 10, res) # These will include the space that is the difference between any two nodes xs_larger = np.linspace(-10, 10, res) ys_larger = np.linspace(-10, 10, res) x_axis_sp = make_good_unitary(dim) y_axis_sp = make_good_unitary(dim) heatmap_vectors = get_heatmap_vectors(xs, ys, x_axis_sp, y_axis_sp) heatmap_vectors_larger = get_heatmap_vectors(xs_larger, ys_larger, x_axis_sp, y_axis_sp) # Map map_sp = spa.SemanticPointer(data=np.zeros((dim, ))) # version of the map with landmark IDs bound to each location landmark_map_sp = spa.SemanticPointer(data=np.zeros((dim, ))) # Connectivity # contains each connection egocentrically con_ego_sp = spa.SemanticPointer(data=np.zeros((dim, ))) # contains each connection allocentrically con_allo_sp = spa.SemanticPointer(data=np.zeros((dim, ))) # Agent Location agent_sp = spa.SemanticPointer(data=np.zeros((dim, ))) # True values for individual node connections, for debugging true_allo_con_sps = list()
# args.dim = 256 args.dim = 512 limit_low = 0 limit_high = 13 seed = 13 limit = 10 #5 res = 256 neurons_per_dim = 10 #50 enc_func, repr_dim = get_encoding_function(args, limit_low=limit_low, limit_high=limit_high) X = spa.SemanticPointer(data=enc_func(1, 0)) Y = spa.SemanticPointer(data=enc_func(0, 1)) # get exact params of the encoding used by using the same seed eps = 0.001 n_toroids = ((args.dim - 1) // 2) // args.n_proj rng_params = np.random.RandomState(seed=args.seed) # Randomly select the angle for each toroid phis = rng_params.uniform(0, 2 * np.pi, size=(n_toroids, )) angles = rng_params.uniform(-np.pi + eps, np.pi - eps, size=n_toroids) rng = np.random.RandomState(seed=seed) # phis = (np.pi*.75, np.pi / 2., np.pi/3., np.pi/5., np.pi*.4, np.pi*.6) # # angles = rng.uniform(0, 2*np.pi, size=len(phis))#(0, np.pi/3., np.pi/5.) # angles = (0, np.pi*.3, np.pi*.2, np.pi*.4, np.pi*.1, np.pi*.5)
name="Single Object", vmin=vmin, vmax=vmax, cmap=cmap, ) fig.savefig('figures/single_item.pdf', dpi=600, bbox_inches='tight') ##################### # Two Items Decoded # ##################### if "Two Items Decoded" in plot_types: fig, ax = plt.subplots(tight_layout=True, figsize=(4, 4)) pos1 = encode_point(3, -2, x_axis_sp, y_axis_sp) pos2 = encode_point(-.3, 1.5, x_axis_sp, y_axis_sp) item1 = spa.SemanticPointer(dim) item2 = spa.SemanticPointer(dim) mem = pos1 * item1 + pos2 * item2 decode1 = mem * ~item1 decode2 = mem * ~item2 heatmap( (decode1 + decode2).v, heatmap_vectors, ax, name='', vmin=vmin, vmax=vmax, cmap=cmap,
def __init__(self, data, maze_sps, maze_indices, goal_indices, subsample=2, spatial_encoding='ssp'): x_axis_sp = spa.SemanticPointer(data=data['x_axis_sp']) y_axis_sp = spa.SemanticPointer(data=data['y_axis_sp']) # n_mazes by res by res fine_mazes = data['fine_mazes'] # n_mazes by n_goals by res by res by 2 solved_mazes = data['solved_mazes'] # NOTE: this can be modified from the original dataset, so it is explicitly passed in # n_mazes by dim # maze_sps = data['maze_sps'] # n_mazes by n_goals by 2 goals = data['goals'] n_mazes = data['goal_sps'].shape[0] n_goals = data['goal_sps'].shape[1] dim = data['goal_sps'].shape[2] # NOTE: this code is assuming xs as ys are the same assert(np.all(data['xs'] == data['ys'])) limit_low = data['xs'][0] limit_high = data['xs'][1] # NOTE: only used for one-hot encoded location representation case xso = np.linspace(limit_low, limit_high, int(np.sqrt(dim))) yso = np.linspace(limit_low, limit_high, int(np.sqrt(dim))) # n_mazes by n_goals by dim if spatial_encoding == 'ssp': goal_sps = data['goal_sps'] elif spatial_encoding == 'random': goal_sps = np.zeros_like(data['goal_sps']) for ni in range(goal_sps.shape[0]): for gi in range(goal_sps.shape[1]): goal_sps[ni, gi, :] = encode_random(x=goals[ni, gi, 0], y=goals[ni, gi, 1], dim=dim) elif spatial_encoding == '2d' or spatial_encoding == 'learned': goal_sps = goals.copy() elif spatial_encoding == '2d-normalized': goal_sps = goals.copy() goal_sps = ((goal_sps - xso[0]) * 2 / (xso[-1] - xso[0])) - 1 elif spatial_encoding == 'one-hot': goal_sps = np.zeros((n_mazes, n_goals, len(xso) * len(yso))) for ni in range(goal_sps.shape[0]): for gi in range(goal_sps.shape[1]): goal_sps[ni, gi, :] = encode_one_hot(x=goals[ni, gi, 0], y=goals[ni, gi, 1], xs=xso, ys=yso) elif spatial_encoding == 'trig': goal_sps = np.zeros((n_mazes, n_goals, dim)) for ni in range(goal_sps.shape[0]): for gi in range(goal_sps.shape[1]): goal_sps[ni, gi, :] = encode_trig(x=goals[ni, gi, 0], y=goals[ni, gi, 1], dim=dim) elif spatial_encoding == 'random-trig': goal_sps = np.zeros((n_mazes, n_goals, dim)) for ni in range(goal_sps.shape[0]): for gi in range(goal_sps.shape[1]): goal_sps[ni, gi, :] = encode_random_trig(x=goals[ni, gi, 0], y=goals[ni, gi, 1], dim=dim) elif spatial_encoding == 'random-proj': goal_sps = np.zeros((n_mazes, n_goals, dim)) for ni in range(goal_sps.shape[0]): for gi in range(goal_sps.shape[1]): goal_sps[ni, gi, :] = encode_projection(x=goals[ni, gi, 0], y=goals[ni, gi, 1], dim=dim) else: raise NotImplementedError self.xs = data['xs'] self.ys = data['ys'] # n_mazes = goals.shape[0] # n_goals = goals.shape[1] self.maze_indices = maze_indices self.goal_indices = goal_indices self.n_mazes = len(maze_indices) self.n_goals = len(goal_indices) res = fine_mazes.shape[1] dim = goal_sps.shape[2] n_samples = int(res/subsample) * int(res/subsample) * self.n_mazes * self.n_goals # Visualization viz_locs = np.zeros((n_samples, 2)) viz_goals = np.zeros((n_samples, 2)) viz_loc_sps = np.zeros((n_samples, goal_sps.shape[2])) viz_goal_sps = np.zeros((n_samples, goal_sps.shape[2])) viz_output_dirs = np.zeros((n_samples, 2)) viz_maze_sps = np.zeros((n_samples, maze_sps.shape[1])) # Generate data so each batch contains a single maze and goal si = 0 # sample index, increments each time for mi in maze_indices: for gi in goal_indices: for xi in range(0, res, subsample): for yi in range(0, res, subsample): loc_x = self.xs[xi] loc_y = self.ys[yi] viz_locs[si, 0] = loc_x viz_locs[si, 1] = loc_y viz_goals[si, :] = goals[mi, gi, :] if spatial_encoding == 'ssp': viz_loc_sps[si, :] = encode_point(loc_x, loc_y, x_axis_sp, y_axis_sp).v elif spatial_encoding == 'random': viz_loc_sps[si, :] = encode_random(loc_x, loc_y, dim) elif spatial_encoding == '2d' or spatial_encoding == 'learned': viz_loc_sps[si, :] = np.array([loc_x, loc_y]) elif spatial_encoding == '2d-normalized': viz_loc_sps[si, :] = ((np.array([loc_x, loc_y]) - limit_low)*2 / (limit_high - limit_low)) - 1 elif spatial_encoding == 'one-hot': viz_loc_sps[si, :] = encode_one_hot(x=loc_x, y=loc_y, xs=xso, ys=yso) elif spatial_encoding == 'trig': viz_loc_sps[si, :] = encode_trig(x=loc_x, y=loc_y, dim=dim) elif spatial_encoding == 'random-trig': viz_loc_sps[si, :] = encode_random_trig(x=loc_x, y=loc_y, dim=dim) elif spatial_encoding == 'random-proj': viz_loc_sps[si, :] = encode_projection(x=loc_x, y=loc_y, dim=dim) viz_goal_sps[si, :] = goal_sps[mi, gi, :] viz_output_dirs[si, :] = solved_mazes[mi, gi, xi, yi, :] viz_maze_sps[si, :] = maze_sps[mi] si += 1 self.batch_size = int(si / (self.n_mazes * self.n_goals)) print("Visualization Data Generated") print("Total Samples: {}".format(si)) print("Mazes: {}".format(self.n_mazes)) print("Goals: {}".format(self.n_goals)) print("Batch Size: {}".format(self.batch_size)) print("Batches: {}".format(self.n_mazes * self.n_goals)) 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, ) # Each batch will contain the samples for one maze. Must not be shuffled self.vizloader = torch.utils.data.DataLoader( dataset_viz, batch_size=self.batch_size, shuffle=False, num_workers=0, )
dim = 256 X = make_good_unitary(dim, rng=rng) # X = spa.SemanticPointer(dim) # X.make_unitary() X_circ = circulant(X.v) X_vec = circulant_matrix_to_vec(X_circ) # assert (np.all(X_vec == X.v)) elif axis_vector_type == 'covariance': # generate SSP based on a given circulant matrix data = np.load(args.fname) X_circ = data['covariance'] dim = X_circ.shape[0] X_vec = circulant_matrix_to_vec(X_circ) X = spa.SemanticPointer(data=X_vec) X.make_unitary() X_circ = circulant(X.v) print(X.v) elif axis_vector_type == 'pca': data = np.load(args.dataset) # if the dataset already has activations, just load them if args.spatial_encoding in args.dataset: print("Loading activations directly") activations = data['activations'] flat_pos = data['positions'] else: print("Computing activations")
# help='Directory for saved model and tensorboard log') parser.add_argument('--logdir', type=str, default='', help='Directory for saved model and tensorboard log') parser.add_argument('--load-saved-model', type=str, default='', help='Saved model to load from') parser.add_argument('--folder', type=str, default='figure_output_new_colours', help='folder to save the figures') args = parser.parse_args() assert(args.limit_low < args.limit_high) data = np.load(args.dataset) rng = np.random.RandomState(seed=args.seed) torch.manual_seed(args.seed) np.random.seed(args.seed) x_axis_sp = spa.SemanticPointer(data=data['x_axis_sp']) y_axis_sp = spa.SemanticPointer(data=data['y_axis_sp']) # n_mazes by size by size coarse_mazes = data['coarse_mazes'] # n_mazes by res by res fine_mazes = data['fine_mazes'] # n_mazes by res by res by 2 solved_mazes = data['solved_mazes'] # n_mazes by dim maze_sps = data['maze_sps']
print("Loading existing base maze data") # base data already exists, load it instead of generating base_data = np.load(base_name) xs = base_data['xs'] ys = base_data['ys'] x_axis_vec = base_data['x_axis_sp'] y_axis_vec = base_data['y_axis_sp'] coarse_mazes = base_data['coarse_mazes'] fine_mazes = base_data['fine_mazes'] solved_mazes = base_data['solved_mazes'] maze_sps = base_data['maze_sps'] goal_sps = base_data['goal_sps'] goals = base_data['goals'] x_axis_sp = spa.SemanticPointer(data=x_axis_vec) y_axis_sp = spa.SemanticPointer(data=y_axis_vec) if (not args.no_sensors): if not os.path.exists(sensor_name): print("Generating Sensor Data") n_mazes = solved_mazes.shape[0] n_goals = solved_mazes.shape[1] res = solved_mazes.shape[2] coarse_maze_size = coarse_mazes.shape[1] limit_low = xs[0] limit_high = xs[-1] sensor_scaling = (limit_high - limit_low) / coarse_maze_size
def create_dataloader(data, n_samples, maze_sps, args): x_axis_sp = spa.SemanticPointer(data=data['x_axis_sp']) y_axis_sp = spa.SemanticPointer(data=data['y_axis_sp']) # n_mazes by size by size coarse_mazes = data['coarse_mazes'] # n_mazes by res by res fine_mazes = data['fine_mazes'] # n_mazes by res by res by 2 solved_mazes = data['solved_mazes'] # NOTE: this can be modified from the original dataset, so it is explicitly passed in # n_mazes by dim # maze_sps = data['maze_sps'] # n_mazes by n_goals by 2 goals = data['goals'] n_goals = goals.shape[1] n_mazes = fine_mazes.shape[0] # NOTE: only used for one-hot encoded location representation case xso = np.linspace(args.limit_low, args.limit_high, int(np.sqrt(args.dim))) yso = np.linspace(args.limit_low, args.limit_high, int(np.sqrt(args.dim))) # n_mazes by n_goals by dim if args.spatial_encoding == 'ssp': goal_sps = data['goal_sps'] elif args.spatial_encoding == 'random': goal_sps = np.zeros((n_mazes, n_goals, args.dim)) for ni in range(n_mazes): for gi in range(n_goals): goal_sps[ni, gi, :] = encode_random(x=goals[ni, gi, 0], y=goals[ni, gi, 1], dim=args.dim) elif args.spatial_encoding == '2d' or args.spatial_encoding == 'learned': goal_sps = goals.copy() elif args.spatial_encoding == '2d-normalized': goal_sps = goals.copy() goal_sps = ((goal_sps - xso[0]) * 2 / (xso[-1] - xso[0])) - 1 elif args.spatial_encoding == 'one-hot': goal_sps = np.zeros((n_mazes, n_goals, len(xso)*len(yso))) for ni in range(n_mazes): for gi in range(n_goals): goal_sps[ni, gi, :] = encode_one_hot(x=goals[ni, gi, 0], y=goals[ni, gi, 1], xs=xso, ys=yso) elif args.spatial_encoding == 'trig': goal_sps = np.zeros((n_mazes, n_goals, args.dim)) for ni in range(n_mazes): for gi in range(n_goals): goal_sps[ni, gi, :] = encode_trig(x=goals[ni, gi, 0], y=goals[ni, gi, 1], dim=args.dim) elif args.spatial_encoding == 'random-trig': goal_sps = np.zeros((n_mazes, n_goals, args.dim)) for ni in range(n_mazes): for gi in range(n_goals): goal_sps[ni, gi, :] = encode_random_trig(x=goals[ni, gi, 0], y=goals[ni, gi, 1], dim=args.dim) elif args.spatial_encoding == 'random-proj': goal_sps = np.zeros((n_mazes, n_goals, args.dim)) for ni in range(n_mazes): for gi in range(n_goals): goal_sps[ni, gi, :] = encode_projection(x=goals[ni, gi, 0], y=goals[ni, gi, 1], dim=args.dim) else: raise NotImplementedError if 'xs' in data.keys(): xs = data['xs'] ys = data['ys'] else: # backwards compatibility xs = np.linspace(args.limit_low, args.limit_high, args.res) ys = np.linspace(args.limit_low, args.limit_high, args.res) free_spaces = np.argwhere(fine_mazes == 0) n_free_spaces = free_spaces.shape[0] # Training train_locs = np.zeros((n_samples, 2)) train_goals = np.zeros((n_samples, 2)) train_loc_sps = np.zeros((n_samples, goal_sps.shape[2])) train_goal_sps = np.zeros((n_samples, goal_sps.shape[2])) train_output_dirs = np.zeros((n_samples, 2)) train_maze_sps = np.zeros((n_samples, maze_sps.shape[1])) train_indices = np.random.randint(low=0, high=n_free_spaces, size=n_samples) for n in range(n_samples): # print("Sample {} of {}".format(n + 1, n_samples)) # n_mazes by res by res indices = free_spaces[train_indices[n], :] maze_index = indices[0] x_index = indices[1] y_index = indices[2] goal_index = np.random.randint(low=0, high=n_goals) # 2D coordinate of the agent's current location loc_x = xs[x_index] loc_y = ys[y_index] train_locs[n, 0] = loc_x train_locs[n, 1] = loc_y train_goals[n, :] = goals[maze_index, goal_index, :] if args.spatial_encoding == 'ssp': train_loc_sps[n, :] = encode_point(loc_x, loc_y, x_axis_sp, y_axis_sp).v elif args.spatial_encoding == 'random': train_loc_sps[n, :] = encode_random(loc_x, loc_y, args.dim) elif args.spatial_encoding == '2d' or args.spatial_encoding == 'learned': train_loc_sps[n, :] = np.array([loc_x, loc_y]) elif args.spatial_encoding == '2d-normalized': train_loc_sps[n, :] = ((np.array([loc_x, loc_y]) - xso[0]) * 2 / (xso[-1] - xso[0])) - 1 elif args.spatial_encoding == 'one-hot': train_loc_sps[n, :] = encode_one_hot(x=loc_x, y=loc_y, xs=xso, ys=yso) elif args.spatial_encoding == 'trig': train_loc_sps[n, :] = encode_trig(x=loc_x, y=loc_y, dim=args.dim) elif args.spatial_encoding == 'random-trig': train_loc_sps[n, :] = encode_random_trig(x=loc_x, y=loc_y, dim=args.dim) elif args.spatial_encoding == 'random-proj': train_loc_sps[n, :] = encode_projection(x=loc_x, y=loc_y, dim=args.dim) train_goal_sps[n, :] = goal_sps[maze_index, goal_index, :] train_output_dirs[n, :] = solved_mazes[maze_index, goal_index, x_index, y_index, :] train_maze_sps[n, :] = maze_sps[maze_index] dataset_train = MazeDataset( maze_ssp=train_maze_sps, loc_ssps=train_loc_sps, goal_ssps=train_goal_sps, locs=train_locs, goals=train_goals, direction_outputs=train_output_dirs, ) trainloader = torch.utils.data.DataLoader( dataset_train, batch_size=args.batch_size, shuffle=True, num_workers=0, ) return trainloader