def test_pes_learning_rate(Simulator, plt, seed): n = 50 dt = 0.0005 T = 1.0 initial = 0.7 desired = -0.9 epsilon = 1e-3 # get to factor epsilon with T seconds # Get activity vector and initial decoders with Network(seed=seed) as model: x = nengo.Ensemble(n, 1, seed=seed, neuron_type=nengo.neurons.LIFRate()) y = nengo.Node(size_in=1) conn = nengo.Connection(x, y, synapse=None) with Simulator(model, dt=dt) as sim: a = get_activities(sim.model, x, [initial]) d = sim.data[conn].weights assert np.any(a > 0) # Use util function to calculate learning_rate init_error = float(desired - np.dot(d, a)) learning_rate, gamma = pes_learning_rate(epsilon / abs(init_error), a, T, dt) # Build model with no filtering on any connections with model: stim = nengo.Node(output=initial) ystar = nengo.Node(output=desired) conn.learning_rule_type = nengo.PES(pre_tau=1e-15, learning_rate=learning_rate) nengo.Connection(stim, x, synapse=None) nengo.Connection(ystar, conn.learning_rule, synapse=0, transform=-1) nengo.Connection(y, conn.learning_rule, synapse=0) p = nengo.Probe(y, synapse=None) decoders = nengo.Probe(conn, 'weights', synapse=None) with Simulator(model, dt=dt) as sim: sim.run(T) # Check that the final error is exactly epsilon assert np.allclose(abs(desired - sim.data[p][-1]), epsilon) # Check that all of the errors are given exactly by gamma**k k = np.arange(len(sim.trange())) error = init_error * gamma**k assert np.allclose(sim.data[p].flatten(), desired - error) # Check that all of the decoders are equal to their analytical solution dk = d.T + init_error * a.T[:, None] * (1 - gamma**k) / np.dot(a, a.T) assert np.allclose(dk, np.squeeze(sim.data[decoders].T)) plt.figure() plt.plot(sim.trange(), sim.data[p], lw=5, alpha=0.5) plt.plot(sim.trange(), desired - error, linestyle='--', lw=5, alpha=0.5)
def _test_lif(Simulator, seed, neuron_type, u, dt, n=500, t=2.0): with Network(seed=seed) as model: stim = nengo.Node(u) x = nengo.Ensemble(n, 1, neuron_type=neuron_type) nengo.Connection(stim, x, synapse=None) p = nengo.Probe(x.neurons) with Simulator(model, dt=dt) as sim: sim.run(t) expected = get_activities(sim.model, x, [u]) * t actual = (sim.data[p] > 0).sum(axis=0) return rmse(actual, expected, axis=0)
def go(freq, max_rates, n_neurons=2500, n_steps=10000, dt=1e-4, sample_every=1e-4, tau=0.02, seed=0): with nengo.Network(seed=seed) as model: u = nengo.Node(output=lambda t: np.sin(freq * 2 * np.pi * t)) x = nengo.Ensemble(n_neurons, 1, max_rates=max_rates, seed=seed, neuron_type=nengo.LIF()) x_rate = nengo.Ensemble(n_neurons, 1, max_rates=max_rates, seed=seed, neuron_type=nengo.LIFRate()) nengo.Connection(u, x, synapse=None) nengo.Connection(u, x_rate, synapse=None) p_u = nengo.Probe(u, synapse=None, sample_every=sample_every) p_v = nengo.Probe(x.neurons, 'voltage', synapse=None, sample_every=sample_every) p_j = nengo.Probe(x.neurons, 'input', synapse=None, sample_every=sample_every) p_r = nengo.Probe(x.neurons, 'refractory_time', synapse=None, sample_every=sample_every) p_ideal = nengo.Probe(x_rate, synapse=tau, sample_every=sample_every) p_actual = nengo.Probe(x, synapse=tau, sample_every=sample_every) with nengo.Simulator(model, dt=dt) as sim: init_lif(sim, x, x0=0) sim.run_steps(n_steps) A = get_activities(sim.model, x, sim.data[p_u]) assert A.shape == sim.data[p_v].shape == sim.data[p_j].shape a_flatten = A.flatten() sl = a_flatten > 0 v = sim.data[p_v].flatten()[sl] j = sim.data[p_j].flatten()[sl] a = a_flatten[sl] r = (sim.data[p_r].flatten()[sl] - dt).clip(0) s = (x.neuron_type.tau_rc * np.log1p((1 - v) / (j - 1)) + r) * a actual = sim.data[p_actual] ideal = sim.data[p_ideal] assert ideal.shape == actual.shape return ( kstest(s, 'uniform'), rmse(actual, ideal), )
def test_init_lif(Simulator, seed, x0): u = 0 if x0 is None else x0 n_neurons = 1000 t = 2.0 ens_kwargs = dict( n_neurons=n_neurons, dimensions=1, max_rates=nengo.dists.Uniform(10, 100), seed=seed, ) with nengo.Network(seed=seed) as model: stim = nengo.Node(u) zero = nengo.Ensemble(**ens_kwargs) init = nengo.Ensemble(**ens_kwargs) nengo.Connection(stim, zero, synapse=None) nengo.Connection(stim, init, synapse=None) p_zero_spikes = nengo.Probe(zero.neurons, 'spikes', synapse=None) p_zero_v = nengo.Probe(zero.neurons, 'voltage', synapse=None) p_init_spikes = nengo.Probe(init.neurons, 'spikes', synapse=None) p_init_v = nengo.Probe(init.neurons, 'voltage', synapse=None) with Simulator(model, seed=seed) as sim: init_lif(sim, init, x0=x0) sim.run(t) # same tuning curves a = get_activities(sim.model, zero, [u]) assert np.allclose(a, get_activities(sim.model, init, [u])) # calculate difference between actual spike counts and ideal count_zero = np.count_nonzero(sim.data[p_zero_spikes], axis=0) count_init = np.count_nonzero(sim.data[p_init_spikes], axis=0) e_zero = count_zero - a * t e_init = count_init - a * t # initialized error is close to zero, better than uninitialized, # with std. dev. close to the uninitialized assert np.abs(np.mean(e_init)) < 0.05 assert np.abs(np.mean(e_zero)) > 0.1 assert np.abs(np.std(e_init) - np.std(e_zero)) < 0.05 # subthreshold neurons are the same between populations subthresh = np.all(sim.data[p_init_spikes] == 0, axis=0) assert np.allclose(subthresh, np.all(sim.data[p_zero_spikes] == 0, axis=0)) assert 0 < np.count_nonzero(subthresh) < n_neurons is_active = ~subthresh # uninitialized always under-counts (unless subthreshold) # the other exception is when a neuron spikes at the very end # since the simulation does not start in its refractory assert np.allclose(e_zero[subthresh], 0) very_end = sim.trange() >= t - init.neuron_type.tau_ref exception = np.any(sim.data[p_zero_spikes][very_end, :] > 0, axis=0) # no more than 10% should be exceptions (heuristic) assert np.count_nonzero(exception) < 0.1 * n_neurons assert np.all(e_zero[is_active & (~exception)] < 0) # uninitialized voltages start at 0 (plus first time-step) assert np.all(sim.data[p_zero_v][0, :] < 0.2) # initialized sub-threshold voltages remain constant # (steady-state input) assert np.allclose(sim.data[p_init_v][0, subthresh], sim.data[p_init_v][-1, subthresh]) def uniformity_test(spikes): # test uniformity of ISIs # returns (r, d, p) where r is the [0, 1) relative # position of the first spike-time within the ISI # d is the KS D-statistic which is the absolute max # distance from the uniform distribution, and p # is the p-value of this statistic t_spike = sim.trange()[[ np.where(s > 0)[0][0] for s in spikes[:, is_active].T ]] assert t_spike.shape == (np.count_nonzero(is_active), ) isi_location = (t_spike - sim.dt) * a[is_active] return (isi_location, ) + kstest(isi_location, 'uniform') r, d, p = uniformity_test(sim.data[p_init_spikes]) assert np.all(r >= 0) assert np.all(r < 1) assert d < 0.1 r, d, p = uniformity_test(sim.data[p_zero_spikes]) assert np.all(r >= 0.7) # heuristic assert np.all(r < 1) assert d > 0.7 assert p < 1e-5
def _test_RLS_network(Simulator, seed, dims, lrate, neuron_type, tau, T_train, T_test, tols): # Input is a scalar sinusoid with given frequency n_neurons = 100 freq = 5 # Learn a linear transformation within T_train seconds transform = np.random.RandomState(seed=seed).randn(dims, 1) lr = RLS(learning_rate=lrate, pre_synapse=tau) with Network(seed=seed) as model: u = nengo.Node(output=lambda t: np.sin(freq * 2 * np.pi * t)) x = nengo.Ensemble(n_neurons, 1, neuron_type=neuron_type) y = nengo.Node(size_in=dims) y_on = nengo.Node(size_in=dims) y_off = nengo.Node(size_in=dims) e = nengo.Node(size_in=dims, output=lambda t, e: e if t < T_train else np.zeros_like(e)) nengo.Connection(u, y, synapse=None, transform=transform) nengo.Connection(u, x, synapse=None) conn_on = nengo.Connection(x, y_on, synapse=None, learning_rule_type=lr, function=lambda _: np.zeros(dims)) nengo.Connection(y, e, synapse=None, transform=-1) nengo.Connection(y_on, e, synapse=None) nengo.Connection(e, conn_on.learning_rule, synapse=tau) nengo.Connection(x, y_off, synapse=None, transform=transform) p_y = nengo.Probe(y, synapse=tau) p_y_on = nengo.Probe(y_on, synapse=tau) p_y_off = nengo.Probe(y_off, synapse=tau) p_inv_gamma = nengo.Probe(conn_on.learning_rule, 'inv_gamma') with Simulator(model) as sim: sim.run(T_train + T_test) # Check _descstr ops = [op for op in sim.model.operators if isinstance(op, SimRLS)] assert len(ops) == 1 assert str(ops[0]).startswith('SimRLS') test = sim.trange() >= T_train on_versus_off = nrmse(sim.data[p_y_on][test], target=sim.data[p_y_off][test]) on_versus_ideal = nrmse(sim.data[p_y_on][test], target=sim.data[p_y][test]) off_versus_ideal = nrmse(sim.data[p_y_off][test], target=sim.data[p_y][test]) A = get_activities(sim.model, x, np.linspace(-1, 1, 1000)[:, None]) gamma_off = A.T.dot(A) + np.eye(n_neurons) / lr.learning_rate gamma_on = inv(sim.data[p_inv_gamma][-1]) gamma_off /= np.linalg.norm(gamma_off) gamma_on /= np.linalg.norm(gamma_on) gamma_diff = nrmse(gamma_on, target=gamma_off) assert on_versus_off < tols[0] assert on_versus_ideal < tols[1] assert off_versus_ideal < tols[2] assert gamma_diff < tols[3]