def build_from_ensemble_connection(model, conn): """Build the parameters object for a connection from an Ensemble.""" # Create a random number generator rng = np.random.RandomState(model.seeds[conn]) # Get the transform transform = full_transform(conn, slice_pre=False) # Use Nengo upstream to build parameters for the solver eval_points, activities, targets = connection_b.build_linear_system( model, conn, rng ) # Use cached solver solver = model.decoder_cache.wrap_solver(conn.solver) if conn.solver.weights: raise NotImplementedError( "SpiNNaker does not currently support neuron to neuron connections" ) else: decoders, solver_info = solver(activities, targets, rng=rng) # Return the parameters return BuiltConnection( decoders=decoders, eval_points=eval_points, transform=transform, solver_info=solver_info )
def test_build_linear_system(seed, rng, plt, allclose): func = lambda x: x**2 with nengo.Network(seed=seed) as net: conn = nengo.Connection(nengo.Ensemble(60, 1), nengo.Ensemble(50, 1), function=func) model = Model() model.build(net) eval_points, activities, targets = build_linear_system(model, conn, rng) assert eval_points.shape[1] == 1 assert targets.shape[1] == 1 assert activities.shape[1] == 60 assert eval_points.shape[0] == activities.shape[0] == targets.shape[0] X = eval_points AA = activities.T.dot(activities) AX = activities.T.dot(eval_points) AY = activities.T.dot(targets) WX = np.linalg.solve(AA, AX) WY = np.linalg.solve(AA, AY) Xhat = activities.dot(WX) Yhat = activities.dot(WY) i = np.argsort(eval_points.ravel()) plt.plot(X[i], Xhat[i]) plt.plot(X[i], Yhat[i]) assert allclose(Xhat, X, atol=1e-1) assert allclose(Yhat, func(X), atol=1e-1)
def test_build_linear_system_zeroact(seed, rng): eval_points = np.linspace(-0.1, 0.1, 100)[:, None] with nengo.Network(seed=seed) as net: a = nengo.Ensemble(5, 1, intercepts=nengo.dists.Choice([0.9])) b = nengo.Ensemble(5, 1, intercepts=nengo.dists.Choice([0.9])) model = Model() model.build(net) conn = nengo.Connection(a, b, eval_points=eval_points, add_to_container=False) with pytest.raises(BuildError, match="'activities' matrix is all zero"): build_linear_system(model, conn, rng)
def build_nrn_connection(model, conn): # Create random number generator rng = np.random.RandomState(model.seeds[conn]) # Check pre-conditions assert isinstance(conn.pre, nengo.Ensemble) assert not isinstance(conn.pre.neuron_type, nengo.neurons.Direct) # FIXME assert no rate neurons are used. How to do that? # Get input signal # FIXME this should probably be # model.sig[conn]['in'] = model.sig[conn.pre]["out"] # in both cases if isinstance(conn.pre, nengo.ensemble.Neurons): model.sig[conn]["in"] = model.sig[conn.pre.ensemble]["out"] else: model.sig[conn]["in"] = model.sig[conn.pre]["out"] # Figure out type of connection if isinstance(conn.post, nengo.ensemble.Neurons): raise NotImplementedError() # TODO elif isinstance(conn.post.neuron_type, Compartmental): pass else: raise AssertionError("This function should only be called if post neurons are " "compartmental.") # Solve for weights # FIXME just assuming solver is a weight solver, may that break? # Default solver should probably also produce sparse solutions for # performance reasons eval_points, activities, targets = build_linear_system(model, conn, rng=rng) # account for transform transform = full_transform(conn) targets = np.dot(targets, transform.T) weights, solver_info = conn.solver(activities, targets, rng=rng, E=model.params[conn.post].scaled_encoders.T) # Synapse type synapse = conn.synapse if is_number(synapse): synapse = ExpSyn(synapse) # Connect # TODO: Why is this adjustment of the weights necessary? weights = weights / synapse.tau / 5.0 * 0.1 connections = [[] for i in range(len(weights))] for i, cell in enumerate(ens_to_cells[conn.post]): for j, w in enumerate(weights[:, i]): if w >= 0.0: x = np.random.rand() connections[j].append(synapse.create(cell.neuron.apical(x), w * (x + 1))) else: connections[j].append(synapse.create(cell.neuron.soma(0.5), w)) # 3. Add operator creating events for synapses if pre neuron fired model.add_op(NrnTransmitSpikes(model.sig[conn]["in"], connections))
# a = nengo.Ensemble(n, im_dims) v = nengo.Node(size_in=im_dims, size_out=im_dims) c = nengo.Connection(a, v, eval_points=eval_points, synapse=0.01) w1 = nengo.Node(video_plot, size_in=im_dims) w2 = nengo.Node(rmse_recorder, size_in=im_dims) nengo.Connection(v, w1, synapse=None) nengo.Connection(v, w2, synapse=None) sim = nengo.Simulator(net) # show reconstructed images if 1: from nengo.builder.connection import build_linear_system plt.figure(3) plt.clf() _, A, y = build_linear_system(sim.model, c, None) x = sim.data[c].decoders.T r, c = 2, 5 axes = [[plt.subplot2grid((2 * r, c), (2 * i + k, j)) for k in range(2)] for i in range(r) for j in range(c)] for i in range(r * c): show_image(axes[i][0], y[i].reshape(im_shape)) show_image(axes[i][1], np.dot(A[i], x).reshape(im_shape)) sim.run(1.) print(rmse_total)
def build_nrn_connection(model, conn): # Create random number generator rng = np.random.RandomState(model.seeds[conn]) # Check pre-conditions assert isinstance(conn.pre, nengo.Ensemble) assert not isinstance(conn.pre.neuron_type, nengo.neurons.Direct) # FIXME assert no rate neurons are used. How to do that? # Get input signal # FIXME this should probably be # model.sig[conn]['in'] = model.sig[conn.pre]["out"] # in both cases if isinstance(conn.pre, nengo.ensemble.Neurons): model.sig[conn]['in'] = model.sig[conn.pre.ensemble]['out'] else: model.sig[conn]['in'] = model.sig[conn.pre]["out"] # Figure out type of connection if isinstance(conn.post, nengo.ensemble.Neurons): raise NotImplementedError() # TODO elif isinstance(conn.post.neuron_type, Compartmental): pass else: raise AssertionError( "This function should only be called if post neurons are " "compartmental.") # Solve for weights # FIXME just assuming solver is a weight solver, may that break? # Default solver should probably also produce sparse solutions for # performance reasons eval_points, activities, targets = build_linear_system(model, conn, rng=rng) # account for transform transform = full_transform(conn) targets = np.dot(targets, transform.T) weights, solver_info = conn.solver( activities, targets, rng=rng, E=model.params[conn.post].scaled_encoders.T) # Synapse type synapse = conn.synapse if is_number(synapse): synapse = ExpSyn(synapse) # Connect # TODO: Why is this adjustment of the weights necessary? weights = weights / synapse.tau / 5. * .1 connections = [[] for i in range(len(weights))] for i, cell in enumerate(ens_to_cells[conn.post]): for j, w in enumerate(weights[:, i]): if w >= 0.0: x = np.random.rand() connections[j].append( synapse.create(cell.neuron.apical(x), w * (x + 1))) else: connections[j].append(synapse.create(cell.neuron.soma(0.5), w)) # 3. Add operator creating events for synapses if pre neuron fired model.add_op(NrnTransmitSpikes(model.sig[conn]['in'], connections))