def test_nengo_dl_noise(neuron_type, seed, plt): install_dl_builders() net, rates, lif_kw = rate_nengo_dl_net(neuron_type) n_noise = 1000 # number of noise samples per x point with nengo_dl.Simulator(net, dt=net.dt, minibatch_size=n_noise, seed=seed) as sim: input_data = {net.stim: np.tile(net.x[None, None, :], (n_noise, 1, 1))} sim.step(input_feeds=input_data, extra_feeds={sim.tensor_graph.signals.training: True}) y = sim.data[net.probe][:, 0, :] ymean = y.mean(axis=0) y25 = np.percentile(y, 25, axis=0) y75 = np.percentile(y, 75, axis=0) dy25 = y25 - rates["ref"] dy75 = y75 - rates["ref"] # exponential models roughly fitted to 25/75th percentiles x1mask = net.x > 1.5 x1 = net.x[x1mask] if isinstance(neuron_type.nengo_dl_noise, AlphaRCNoise): exp_model = 0.7 + 2.8 * np.exp(-0.22 * (x1 - 1)) atol = 0.12 * exp_model.max() elif isinstance(neuron_type.nengo_dl_noise, LowpassRCNoise): exp_model = 1.5 + 2.2 * np.exp(-0.22 * (x1 - 1)) atol = 0.2 * exp_model.max() rtol = 0.2 mu_atol = 0.6 # depends on n_noise and variance of noise # --- plots plt.subplot(211) plt.plot(net.x, rates["med"], '--', label='LIF(tau_ref += 0.5*dt)') plt.plot(net.x, ymean, label='nengo_dl') plt.plot(net.x, y25, ':', label='25th') plt.plot(net.x, y75, ':', label='75th') plt.plot(net.x, rates["ref"], 'k--', label='LoihiLIF') plt.legend() plt.subplot(212) plt.plot(net.x, ymean - rates["ref"], 'b', label='mean') plt.plot(net.x, mu_atol * np.ones_like(net.x), 'b:') plt.plot(net.x, -mu_atol * np.ones_like(net.x), 'b:') plt.plot(net.x, y25 - rates["ref"], ':', label='25th') plt.plot(net.x, y75 - rates["ref"], ':', label='75th') plt.plot(x1, exp_model, 'k--') plt.plot(x1, exp_model * (1 + rtol) + atol, 'k:') plt.plot(x1, exp_model * (1 - rtol) - atol, 'k:') plt.plot(x1, -exp_model, 'k--') plt.legend() assert ymean.shape == rates["ref"].shape assert np.allclose(ymean, rates["ref"], atol=mu_atol) assert np.allclose(dy25[x1mask], -exp_model, atol=atol, rtol=rtol) assert np.allclose(dy75[x1mask], exp_model, atol=atol, rtol=rtol)
def test_nengo_dl_neurons(neuron_type, inference_only, Simulator, plt, allclose): install_dl_builders() dt = 0.0007 n = 256 encoders = np.ones((n, 1)) gain = np.zeros(n) if isinstance(neuron_type, nengo.SpikingRectifiedLinear): bias = np.linspace(0, 1001, n) else: bias = np.linspace(0, 30, n) with nengo.Network() as model: nengo_dl.configure_settings(inference_only=inference_only) a = nengo.Ensemble(n, 1, neuron_type=neuron_type, encoders=encoders, gain=gain, bias=bias) ap = nengo.Probe(a.neurons) t_final = 1.0 with nengo_dl.Simulator(model, dt=dt) as dl_sim: dl_sim.run(t_final) with Simulator(model, dt=dt) as loihi_sim: loihi_sim.run(t_final) rates_dlsim = (dl_sim.data[ap] > 0).sum(axis=0) / t_final rates_loihisim = (loihi_sim.data[ap] > 0).sum(axis=0) / t_final zeros = np.zeros((1, gain.size)) rates_ref = neuron_type.rates(zeros, gain, bias, dt=dt).squeeze(axis=0) plt.plot(bias, rates_loihisim, 'r', label='loihi sim') plt.plot(bias, rates_dlsim, 'b-.', label='dl sim') plt.plot(bias, rates_ref, 'k--', label='rates_ref') plt.legend(loc='best') atol = 1. / t_final # the fundamental unit for our rates assert rates_ref.shape == rates_dlsim.shape == rates_loihisim.shape assert allclose(rates_dlsim, rates_ref, atol=atol, rtol=0, xtol=1) assert allclose(rates_loihisim, rates_ref, atol=atol, rtol=0, xtol=1)
def __init__( # noqa: C901 self, network, dt=0.001, seed=None, model=None, precompute=False, target=None, progress_bar=None, remove_passthrough=True, hardware_options=None, ): # initialize values used in __del__ and close() first self.closed = True self.precompute = precompute self.networks = None self.sims = OrderedDict() self._run_steps = None hardware_options = {} if hardware_options is None else hardware_options if progress_bar: warnings.warn("nengo-loihi does not support progress bars") if HAS_DL: install_dl_builders() if model is None: # Call the builder to make a model self.model = Model(dt=float(dt), label="%s, dt=%f" % (network, dt)) else: assert isinstance(model, Model), ( "model is not type 'nengo_loihi.builder.Model'") self.model = model assert self.model.dt == dt if network is not None: nengo.rc.set("decoder_cache", "enabled", "False") config.add_params(network) # ensure seeds are identical to nengo seed_network(network, seeds=self.model.seeds, seeded=self.model.seeded) # split the host into one, two or three networks self.networks = split( network, precompute=precompute, node_neurons=self.model.node_neurons, node_tau=self.model.decode_tau, remove_passthrough=remove_passthrough, ) network = self.networks.chip self.model.chip2host_params = self.networks.chip2host_params self.chip = self.networks.chip self.host = self.networks.host self.host_pre = self.networks.host_pre if len(self.host_pre.all_objects) > 0: host_pre_model = self._get_host_model( self.host_pre, dt=dt, seeds=self.model.seeds, seeded=self.model.seeded) self.sims["host_pre"] = nengo.Simulator(self.host_pre, dt=self.dt, model=host_pre_model, progress_bar=False, optimize=False) if len(self.host.all_objects) > 0: host_model = self._get_host_model( self.host, dt=dt, seeds=self.model.seeds, seeded=self.model.seeded) self.sims["host"] = nengo.Simulator( self.host, dt=self.dt, model=host_model, progress_bar=False, optimize=False) elif not precompute: # If there is no host and precompute=False, then all objects # must be on the chip, which is precomputable in the sense that # no communication has to happen with the host. # We could warn about this, but we want to avoid people having # to specify `precompute` unless they absolutely have to. self.precompute = True # Build the network into the model self.model.build(network) self._probe_outputs = self.model.params self.data = ProbeDict(self._probe_outputs) for sim in self.sims.values(): self.data.add_fallback(sim.data) if seed is None: if network is not None and network.seed is not None: seed = network.seed + 1 else: seed = np.random.randint(npext.maxint) if target is None: target = 'loihi' if HAS_NXSDK else 'sim' self.target = target logger.info("Simulator target is %r", target) logger.info("Simulator precompute is %r", self.precompute) if target != "simreal": discretize_model(self.model) if target in ("simreal", "sim"): self.sims["emulator"] = EmulatorInterface(self.model, seed=seed) elif target == 'loihi': assert HAS_NXSDK, "Must have NxSDK installed to use Loihi hardware" self.sims["loihi"] = HardwareInterface( self.model, use_snips=not self.precompute, seed=seed, **hardware_options) else: raise ValidationError("Must be 'simreal', 'sim', or 'loihi'", attr="target") assert "emulator" in self.sims or "loihi" in self.sims self.closed = False self.reset(seed=seed)
def test_nengo_dl_neuron_grads(neuron_type, plt): from nengo_extras.neurons import SoftLIFRate import tensorflow as tf from tensorflow.python.ops import gradient_checker install_dl_builders() net, rates, lif_kw = rate_nengo_dl_net(neuron_type) with nengo_dl.Simulator(net, dt=net.dt) as sim: sim.run_steps(1, input_feeds={net.stim: net.x[None, None, :]}, extra_feeds={sim.tensor_graph.signals.training: True}) y = sim.data[net.probe][0] # --- compute spiking rates n_spike_steps = 1000 x_spikes = net.x + np.zeros((1, n_spike_steps, 1), dtype=net.x.dtype) with nengo_dl.Simulator(net, dt=net.dt) as sim: sim.run_steps(n_spike_steps, input_feeds={net.stim: x_spikes}, extra_feeds={sim.tensor_graph.signals.training: False}) y_spikes = sim.data[net.probe] y_spikerate = y_spikes.mean(axis=0) # --- compute derivatives if isinstance(neuron_type, LoihiLIF): dy_ref = SoftLIFRate(sigma=net.sigma, **lif_kw).derivative(net.x, net.gain, net.bias) else: # use the derivative of rates['med'] (the smoothed Loihi tuning curve) dy_ref = np.zeros_like(net.j) dy_ref[net.j > 0] = (neuron_type.amplitude / (net.j[net.j > 0] * net.tau_ref1 + 1)**2) with nengo_dl.Simulator(net, dt=net.dt) as sim: n_steps = sim.unroll assert n_steps == 1 inp = sim.tensor_graph.input_ph[net.stim] inp_shape = inp.get_shape().as_list() inp_shape = [n_steps if s is None else s for s in inp_shape] inp_data = np.zeros(inp_shape) + net.x[None, :, None] out = sim.tensor_graph.probe_arrays[net.probe] + 0 out_shape = out.get_shape().as_list() out_shape = [n_steps if s is None else s for s in out_shape] data = { n: np.zeros((sim.minibatch_size, n_steps, n.size_out)) for n in sim.tensor_graph.invariant_inputs } data.update({ p: np.zeros((sim.minibatch_size, n_steps, p.size_in)) for p in sim.tensor_graph.target_phs }) feed = sim._fill_feed(n_steps, data, training=True) with tf.variable_scope(tf.get_variable_scope()) as scope: dx, dy = gradient_checker._compute_dx_and_dy(inp, out, out_shape) sim.sess.run( tf.variables_initializer( scope.get_collection("gradient_vars"))) with sim.sess.as_default(): analytic = gradient_checker._compute_theoretical_jacobian( inp, inp_shape, inp_data, dy, out_shape, dx, extra_feed_dict=feed) dy = np.array(np.diag(analytic)) dx = net.x[1] - net.x[0] dy_est = np.diff(nengo.synapses.Alpha(10).filtfilt(rates["ref"], dt=1)) / dx x1 = 0.5 * (net.x[:-1] + net.x[1:]) # --- plots plt.subplot(211) plt.plot(net.x, rates["med"], '--', label='LIF(tau_ref += 0.5*dt)') plt.plot(net.x, y, label='nengo_dl') plt.plot(net.x, y_spikerate, label='nengo_dl spikes') plt.plot(net.x, rates["ref"], 'k--', label='LoihiLIF') plt.legend(loc=4) plt.subplot(212) plt.plot(x1, dy_est, '--', label='diff(smoothed_y)') plt.plot(net.x, dy, label='nengo_dl') plt.plot(net.x, dy_ref, 'k--', label='diff(SoftLIF)') plt.legend(loc=1) np.fill_diagonal(analytic, 0) assert np.all(analytic == 0) assert np.allclose(y, rates["ref"], atol=1e-3, rtol=1e-5) assert np.allclose(dy, dy_ref, atol=1e-3, rtol=1e-5) assert np.allclose(y_spikerate, rates["ref"], atol=1, rtol=1e-2)
def _install_dl_builders(): # avoid circular import by doing import in here from nengo_loihi.builder.nengo_dl import ( # pylint: disable=import-outside-toplevel install_dl_builders, ) install_dl_builders()
def test_nengo_dl_noise(neuron_type, seed, plt): tf = pytest.importorskip("tensorflow") install_dl_builders() net, rates, lif_kw = rate_nengo_dl_net(neuron_type) n_noise = 1000 # number of noise samples per x point with tf.keras.backend.learning_phase_scope(1): with nengo_dl.Simulator(net, dt=net.dt, minibatch_size=n_noise, seed=seed) as sim: input_data = { net.stim: np.tile(net.x[None, None, :], (n_noise, 1, 1)) } sim.step(data=input_data) y = sim.data[net.probe][:, 0, :] ymean = y.mean(axis=0) y25 = np.percentile(y, 25, axis=0) y75 = np.percentile(y, 75, axis=0) dy25 = y25 - rates["ref"] dy75 = y75 - rates["ref"] # exponential models roughly fitted to 25/75th percentiles x1mask = net.x > 1.5 x1 = net.x[x1mask] if isinstance(neuron_type.nengo_dl_noise, AlphaRCNoise): exp_model = 0.7 + 2.8 * np.exp(-0.22 * (x1 - 1)) atol = 0.12 * exp_model.max() elif isinstance(neuron_type.nengo_dl_noise, LowpassRCNoise): exp_model = 1.5 + 2.2 * np.exp(-0.22 * (x1 - 1)) atol = 0.2 * exp_model.max() rtol = 0.2 mu_atol = 0.6 # depends on n_noise and variance of noise # --- plots plt.subplot(211) plt.plot(net.x, rates["med"], "--", label="LIF(tau_ref += 0.5*dt)") plt.plot(net.x, ymean, label="nengo_dl") plt.plot(net.x, y25, ":", label="25th") plt.plot(net.x, y75, ":", label="75th") plt.plot(net.x, rates["ref"], "k--", label="LoihiLIF") plt.legend() plt.subplot(212) plt.plot(net.x, ymean - rates["ref"], "b", label="mean") plt.plot(net.x, mu_atol * np.ones_like(net.x), "b:") plt.plot(net.x, -mu_atol * np.ones_like(net.x), "b:") plt.plot(net.x, y25 - rates["ref"], ":", label="25th") plt.plot(net.x, y75 - rates["ref"], ":", label="75th") plt.plot(x1, exp_model, "k--") plt.plot(x1, exp_model * (1 + rtol) + atol, "k:") plt.plot(x1, exp_model * (1 - rtol) - atol, "k:") plt.plot(x1, -exp_model, "k--") plt.legend() assert ymean.shape == rates["ref"].shape assert np.allclose(ymean, rates["ref"], atol=mu_atol) assert np.allclose(dy25[x1mask], -exp_model, atol=atol, rtol=rtol) assert np.allclose(dy75[x1mask], exp_model, atol=atol, rtol=rtol)
def test_nengo_dl_neuron_grads(neuron_type, plt): tf = pytest.importorskip("tensorflow") install_dl_builders() net, rates, lif_kw = rate_nengo_dl_net(neuron_type) with tf.keras.backend.learning_phase_scope(1): with nengo_dl.Simulator(net, dt=net.dt) as sim: sim.run_steps(1, data={net.stim: net.x[None, None, :]}) y = sim.data[net.probe][0] # --- compute spiking rates n_spike_steps = 1000 x_spikes = net.x + np.zeros((1, n_spike_steps, 1), dtype=net.x.dtype) with nengo_dl.Simulator(net, dt=net.dt) as sim: sim.run_steps( n_spike_steps, data={net.stim: x_spikes}, ) y_spikes = sim.data[net.probe] y_spikerate = y_spikes.mean(axis=0) # --- compute derivatives if isinstance(neuron_type, LoihiLIF): dy_ref = SoftLIFRate(sigma=net.sigma, **lif_kw).derivative(net.x, net.gain, net.bias) else: # use the derivative of rates['med'] (the smoothed Loihi tuning curve) dy_ref = np.zeros_like(net.j) dy_ref[net.j > 0] = (neuron_type.amplitude / (net.j[net.j > 0] * net.tau_ref1 + 1)**2) with nengo_dl.Simulator(net, dt=net.dt) as sim: assert sim.unroll == 1 # note: not actually checking gradients, just using this to get the # gradients analytic = sim.check_gradients(inputs=[net.x[None, None, :]], atol=1e10)[net.probe]["analytic"][0] dy = np.diagonal(analytic.copy()) dx = net.x[1] - net.x[0] dy_est = np.diff(nengo.synapses.Alpha(10).filtfilt(rates["ref"], dt=1)) / dx x1 = 0.5 * (net.x[:-1] + net.x[1:]) # --- plots plt.subplot(211) plt.plot(net.x, rates["med"], "--", label="LIF(tau_ref += 0.5*dt)") plt.plot(net.x, y, label="nengo_dl") plt.plot(net.x, y_spikerate, label="nengo_dl spikes") plt.plot(net.x, rates["ref"], "k--", label="LoihiLIF") plt.legend(loc=4) plt.subplot(212) plt.plot(x1, dy_est, "--", label="diff(smoothed_y)") plt.plot(net.x, dy, label="nengo_dl") plt.plot(net.x, dy_ref, "k--", label="diff(SoftLIF)") plt.legend(loc=1) np.fill_diagonal(analytic, 0) assert np.all(analytic == 0) assert y.shape == rates["ref"].shape assert np.allclose(y, rates["ref"], atol=1e-3, rtol=1e-5) assert np.allclose(dy, dy_ref, atol=1e-3, rtol=1e-5) assert np.allclose(y_spikerate, rates["ref"], atol=1, rtol=1e-2)