def __init__(self, num_func_points, func_value_range=1.0, func_output_dimensions=1, n_neurons=500, label=None, seed=None, add_to_container=None): super(DifferenceFunctionEvaluator, self).__init__(label, seed, add_to_container) intercept_interval = 2.0 / (num_func_points - 1) self.func_output_dimensions = func_output_dimensions self.n_neurons = n_neurons with self: bias_node = nengo.Node(1) self.func_input = nengo.Node(size_in=1) self.func_output = nengo.Node(size_in=func_output_dimensions) self.diff_func_pts = [] self.diff_func_outputs = [] self.func_gate_eas = [] func_domain_inhib_ea = EA(25, num_func_points - 1, encoders=Choice([[-1]]), intercepts=Uniform(0, intercept_interval)) # Generate inhibit signal based of the function domain input value func_domain_inhib_ea.add_output('const', lambda x: 1) inhib_trfm = np.array([np.linspace(-1, 1, num_func_points)[:-1] + intercept_interval / 2.0]) nengo.Connection(bias_node, func_domain_inhib_ea.input, transform=-1 - inhib_trfm.T) nengo.Connection(self.func_input, func_domain_inhib_ea.input, transform=2 * np.ones((num_func_points - 1, 1)), synapse=None) for n in range(func_output_dimensions): func_gate_ea = EA(n_neurons, num_func_points, radius=func_value_range) for i, gate in enumerate(func_gate_ea.all_ensembles[1:]): nengo.Connection(func_domain_inhib_ea.const[i], gate.neurons, transform=[[-5]] * n_neurons) self.func_gate_eas.append(func_gate_ea) self.diff_func_pts.append(func_gate_ea.input) self.diff_func_outputs.append(func_gate_ea.output) nengo.Connection(func_gate_ea.output, self.func_output[n], transform=np.ones((1, num_func_points)), synapse=None)
def Product(n_neurons, dimensions, input_magnitude=1): encoders = nengo.dists.Choice([[1, 1], [1, -1], [-1, 1], [-1, -1]]) product = EnsembleArray(n_neurons, n_ensembles=dimensions, ens_dimensions=2, encoders=encoders, radius=input_magnitude * np.sqrt(2)) with product: product.A = nengo.Node(size_in=dimensions, label="A") product.B = nengo.Node(size_in=dimensions, label="B") nengo.Connection(product.A, product.input[::2], synapse=None) nengo.Connection(product.B, product.input[1::2], synapse=None) # Remove default output for conn in list(product.connections): if conn.post is product.output: product.connections.remove(conn) product.nodes.remove(product.output) # Add product output product.output = product.add_output('product', lambda x: x[0] * x[1], synapse=None) return product
def Product(n_neurons, dimensions, input_magnitude=1): encoders = nengo.dists.Choice([[1, 1], [1, -1], [-1, 1], [-1, -1]]) product = EnsembleArray(n_neurons, n_ensembles=dimensions, ens_dimensions=2, encoders=encoders, radius=input_magnitude * np.sqrt(2)) with product: product.A = nengo.Node(size_in=dimensions, label="A") product.B = nengo.Node(size_in=dimensions, label="B") nengo.Connection(product.A, product.input[::2], synapse=None) nengo.Connection(product.B, product.input[1::2], synapse=None) # Remove default output for conn in list(product.connections): if conn.post is product.output: product.connections.remove(conn) product.nodes.remove(product.output) # Add product output product.output = product.add_output( 'product', lambda x: x[0] * x[1], synapse=None) return product
def VectorNormalize(min_mag, max_mag, dimensions, radius_scale=1.0, n_neurons_norm=50, n_neurons_prod=150, norm_error_per_dimension=0.0003, subtract_scale=1, net=None): if net is None: net = nengo.Network(label="Vector Normalize") max_radius_scale = max_mag * radius_scale norm_sub_in_low = min_mag ** 2 norm_sub_in_high = max_mag ** 2 norm_sub_in_trfm = scale_trfm(norm_sub_in_low, norm_sub_in_high) norm_sub_in_bias = scale_bias(norm_sub_in_low, norm_sub_in_high) norm_sub_in_bias_offset = -(norm_error_per_dimension * dimensions) prod_a_trfm = 1.0 / max_radius_scale prod_b_low = 1.0 - 1.0 / min_mag prod_b_high = 1.0 - 1.0 / max_mag prod_b_trfm = scale_trfm(prod_b_low, prod_b_high) prod_b_bias = scale_bias(prod_b_low, prod_b_high) def norm_sub_func(x, nsit=norm_sub_in_trfm, nsib=norm_sub_in_bias, pbt=prod_b_trfm, pbb=prod_b_bias): return norm_subtract_func(x, nsit, nsib, pbt, pbb) def prod_func(x, y, pat=prod_a_trfm, pbt=prod_b_trfm, pbb=prod_b_bias): return prod_out_func(x, y, pat, 0, pbt, pbb) with net: net.input = nengo.Node(size_in=dimensions) net.output = nengo.Node(size_in=dimensions) bias_node = nengo.Node(1) # Ensemble array to represent input vector and to compute vector # norm norm_array = EnsembleArray(n_neurons_norm, dimensions, radius=max_radius_scale) norm_array.add_output('squared', lambda x: x ** 2) nengo.Connection(net.input, norm_array.input) # Ensemble to calculate amount of magnitude to be subtracted # i.e. (1 - 1 / np.linalg.norm(input)) norm_subtract_ens = nengo.Ensemble(n_neurons_norm, 1, n_eval_points=5000) nengo.Connection(norm_array.squared, norm_subtract_ens, transform=np.ones((1, dimensions)) * norm_sub_in_trfm) nengo.Connection(bias_node, norm_subtract_ens, transform=norm_sub_in_bias + norm_sub_in_bias_offset) # Product network to compute product between input vector and # magnitude to be subtracted prod_array = Product(n_neurons_prod, dimensions) for e in prod_array.product.ensembles: e.n_eval_points = 5000 prod_array.product.add_output('prod2', lambda x: prod_func(x[0], x[1])) prod_array.prod2 = prod_array.product.prod2 nengo.Connection(norm_array.output, prod_array.A, transform=prod_a_trfm) nengo.Connection(norm_subtract_ens, prod_array.B, function=norm_sub_func, transform=np.ones((dimensions, 1))) # Output connections nengo.Connection(norm_array.output, net.output) nengo.Connection(prod_array.prod2, net.output, transform=-subtract_scale) return net
def __init__(self, num_func_points, func_value_range=1.0, func_output_dimensions=1, n_neurons=500, label=None, seed=None, add_to_container=None): super(DifferenceFunctionEvaluator, self).__init__(label, seed, add_to_container) intercept_interval = 2.0 / (num_func_points - 1) self.func_output_dimensions = func_output_dimensions self.n_neurons = n_neurons with self: bias_node = nengo.Node(1) self.func_input = nengo.Node(size_in=1) self.func_output = nengo.Node(size_in=func_output_dimensions) self.diff_func_pts = [] self.diff_func_outputs = [] self.func_gate_eas = [] func_domain_inhib_ea = EA(25, num_func_points - 1, encoders=Choice([[-1]]), intercepts=Uniform( 0, intercept_interval)) # Generate inhibit signal based of the function domain input value func_domain_inhib_ea.add_output('const', lambda x: 1) inhib_trfm = np.array([ np.linspace(-1, 1, num_func_points)[:-1] + intercept_interval / 2.0 ]) nengo.Connection(bias_node, func_domain_inhib_ea.input, transform=-1 - inhib_trfm.T) nengo.Connection(self.func_input, func_domain_inhib_ea.input, transform=2 * np.ones((num_func_points - 1, 1)), synapse=None) for n in range(func_output_dimensions): func_gate_ea = EA(n_neurons, num_func_points, radius=func_value_range) for i, gate in enumerate(func_gate_ea.all_ensembles[1:]): nengo.Connection(func_domain_inhib_ea.const[i], gate.neurons, transform=[[-5]] * n_neurons) self.func_gate_eas.append(func_gate_ea) self.diff_func_pts.append(func_gate_ea.input) self.diff_func_outputs.append(func_gate_ea.output) nengo.Connection(func_gate_ea.output, self.func_output[n], transform=np.ones((1, num_func_points)), synapse=None)
def test_matrix_mul(self): N = 100 Amat = np.asarray([[.5, -.5]]) Bmat = np.asarray([[0, -1.], [.7, 0]]) radius = 1 model = nengo.Model('Matrix Multiplication', seed=123) with model: A = EnsembleArray(nengo.LIF(N * Amat.size), Amat.size, radius=radius) B = EnsembleArray(nengo.LIF(N * Bmat.size), Bmat.size, radius=radius) inputA = nengo.Node(output=Amat.ravel()) inputB = nengo.Node(output=Bmat.ravel()) nengo.Connection(inputA, A.input) nengo.Connection(inputB, B.input) A_p = nengo.Probe( A.output, 'output', sample_every=0.01, filter=0.01) B_p = nengo.Probe( B.output, 'output', sample_every=0.01, filter=0.01) C = EnsembleArray(nengo.LIF(N * Amat.size * Bmat.shape[1] * 2), Amat.size * Bmat.shape[1], dimensions_per_ensemble=2, radius=1.5 * radius) for ens in C.ensembles: ens.encoders = np.tile([[1, 1], [-1, 1], [1, -1], [-1, -1]], (ens.n_neurons // 4, 1)) transformA = np.zeros((C.dimensions, Amat.size)) transformB = np.zeros((C.dimensions, Bmat.size)) for i in range(Amat.shape[0]): for j in range(Amat.shape[1]): for k in range(Bmat.shape[1]): tmp = (j + k * Amat.shape[1] + i * Bmat.size) transformA[tmp * 2][j + i * Amat.shape[1]] = 1 transformB[tmp * 2 + 1][k + j * Bmat.shape[1]] = 1 nengo.Connection(A.output, C.input, transform=transformA) nengo.Connection(B.output, C.input, transform=transformB) C_p = nengo.Probe( C.output, 'output', sample_every=0.01, filter=0.01) D = EnsembleArray(nengo.LIF(N * Amat.shape[0] * Bmat.shape[1]), Amat.shape[0] * Bmat.shape[1], radius=radius) def product(x): return x[0]*x[1] transformC = np.zeros((D.dimensions, Bmat.size)) for i in range(Bmat.size): transformC[i // Bmat.shape[0]][i] = 1 prod = C.add_output("product", product) nengo.Connection(prod, D.input, transform=transformC) D_p = nengo.Probe( D.output, 'output', sample_every=0.01, filter=0.01) sim = self.Simulator(model) sim.run(1) with Plotter(self.Simulator) as plt: t = sim.trange(dt=0.01) plt.plot(t, sim.data(D_p)) for d in np.dot(Amat, Bmat).flatten(): plt.axhline(d, color='k') plt.savefig('test_ensemble_array.test_matrix_mul.pdf') plt.close() self.assertTrue(np.allclose(sim.data(A_p)[50:, 0], 0.5, atol=.1, rtol=.01)) self.assertTrue(np.allclose(sim.data(A_p)[50:, 1], -0.5, atol=.1, rtol=.01)) self.assertTrue(np.allclose(sim.data(B_p)[50:, 0], 0, atol=.1, rtol=.01)) self.assertTrue(np.allclose(sim.data(B_p)[50:, 1], -1, atol=.1, rtol=.01)) self.assertTrue(np.allclose(sim.data(B_p)[50:, 2], .7, atol=.1, rtol=.01)) self.assertTrue(np.allclose(sim.data(B_p)[50:, 3], 0, atol=.1, rtol=.01)) Dmat = np.dot(Amat, Bmat) for i in range(Amat.shape[0]): for k in range(Bmat.shape[1]): self.assertTrue(np.allclose( sim.data(D_p)[-10:, i * Bmat.shape[1] + k], Dmat[i, k], atol=0.1, rtol=0.1), (sim.data(D_p)[-10:, i * Bmat.shape[1] + k], Dmat[i, k]))
def VectorNormalize(min_mag, max_mag, dimensions, radius_scale=1.0, n_neurons_norm=50, n_neurons_prod=150, norm_error_per_dimension=0.0003, subtract_scale=1, net=None): if net is None: net = nengo.Network(label="Vector Normalize") max_radius_scale = max_mag * radius_scale norm_sub_in_low = min_mag**2 norm_sub_in_high = max_mag**2 norm_sub_in_trfm = scale_trfm(norm_sub_in_low, norm_sub_in_high) norm_sub_in_bias = scale_bias(norm_sub_in_low, norm_sub_in_high) norm_sub_in_bias_offset = -(norm_error_per_dimension * dimensions) prod_a_trfm = 1.0 / max_radius_scale prod_b_low = 1.0 - 1.0 / min_mag prod_b_high = 1.0 - 1.0 / max_mag prod_b_trfm = scale_trfm(prod_b_low, prod_b_high) prod_b_bias = scale_bias(prod_b_low, prod_b_high) def norm_sub_func(x, nsit=norm_sub_in_trfm, nsib=norm_sub_in_bias, pbt=prod_b_trfm, pbb=prod_b_bias): return norm_subtract_func(x, nsit, nsib, pbt, pbb) def prod_func(x, y, pat=prod_a_trfm, pbt=prod_b_trfm, pbb=prod_b_bias): return prod_out_func(x, y, pat, 0, pbt, pbb) with net: net.input = nengo.Node(size_in=dimensions) net.output = nengo.Node(size_in=dimensions) bias_node = nengo.Node(1) # Ensemble array to represent input vector and to compute vector # norm norm_array = EnsembleArray(n_neurons_norm, dimensions, radius=max_radius_scale) norm_array.add_output('squared', lambda x: x**2) nengo.Connection(net.input, norm_array.input) # Ensemble to calculate amount of magnitude to be subtracted # i.e. (1 - 1 / np.linalg.norm(input)) norm_subtract_ens = nengo.Ensemble(n_neurons_norm, 1, n_eval_points=5000) nengo.Connection(norm_array.squared, norm_subtract_ens, transform=np.ones((1, dimensions)) * norm_sub_in_trfm) nengo.Connection(bias_node, norm_subtract_ens, transform=norm_sub_in_bias + norm_sub_in_bias_offset) # Product network to compute product between input vector and # magnitude to be subtracted prod_array = Product(n_neurons_prod, dimensions) for e in prod_array.product.ensembles: e.n_eval_points = 5000 prod_array.product.add_output('prod2', lambda x: prod_func(x[0], x[1])) prod_array.prod2 = prod_array.product.prod2 nengo.Connection(norm_array.output, prod_array.A, transform=prod_a_trfm) nengo.Connection(norm_subtract_ens, prod_array.B, function=norm_sub_func, transform=np.ones((dimensions, 1))) # Output connections nengo.Connection(norm_array.output, net.output) nengo.Connection(prod_array.prod2, net.output, transform=-subtract_scale) return net
class InputGatedCleanupMemory(nengo.Network): def __init__(self, n_neurons, dimensions, mem_synapse=0.1, fdbk_transform=1.0, input_transform=1.0, difference_gain=1.0, gate_gain=3, reset_value=None, cleanup_values=None, wta_output=False, wta_inhibit_scale=1, label=None, seed=None, add_to_container=None, **mem_args): super(InputGatedCleanupMemory, self).__init__(label, seed, add_to_container) if cleanup_values is None: raise ValueError('InputGatedCleanupMemory - cleanup_values must' + ' be defined.') else: cleanup_values = np.matrix(cleanup_values) # Keep copy of network parameters self.n_neurons = n_neurons self.dimensions = dimensions self.gate_gain = gate_gain self.input_transform = np.dot(input_transform, cleanup_values) self.mem_synapse = mem_synapse self.mem_args = copy(mem_args) cu_args = copy(mem_args) cu_args['radius'] = 1 cu_args['encoders'] = Choice([[1]]) cu_args['intercepts'] = Uniform(0.5, 1) cu_args['eval_points'] = Uniform(0.6, 1.3) cu_args['n_eval_points'] = 5000 with self: self.input = nengo.Node(size_in=dimensions) self.output = nengo.Node(size_in=dimensions) self.mem = EnsembleArray(n_neurons, cleanup_values.shape[0], label="mem", **cu_args) self.mem.add_output('thresh', function=lambda x: 1) nengo.Connection(self.mem.thresh, self.mem.input, synapse=mem_synapse) if wta_output: nengo.Connection(self.mem.output, self.mem.input, transform=(np.eye(cleanup_values.shape[0]) - 1) * wta_inhibit_scale) # calculate difference between stored value and input diff_args = copy(mem_args) diff_args['radius'] = 1 self.diff = EnsembleArray(n_neurons, cleanup_values.shape[0], label="diff", **diff_args) self.diff_input = self.diff.input nengo.Connection(self.input, self.diff.input, synapse=None, transform=self.input_transform) nengo.Connection(self.mem.output, self.diff.input, transform=-1) # feed difference into integrator nengo.Connection(self.diff.output, self.mem.input, transform=difference_gain, synapse=mem_synapse) # connect cleanup to output nengo.Connection(self.mem.thresh, self.output, transform=cleanup_values.T, synapse=None) # gate difference (if gate==0, update stored value, # otherwise retain stored value) self.gate = nengo.Ensemble(n_neurons, 1, encoders=Choice([[1]]), intercepts=Uniform(0.5, 1)) for e in self.diff.ensembles: nengo.Connection(self.gate, e.neurons, transform=[[-gate_gain]] * e.n_neurons) # No indenty! Not supposed to be within network context if reset_value is not None: make_resettable(self, reset_value)