예제 #1
0
def test_pes_error_clip(plt, seed, Simulator):
    dims = 2
    n_per_dim = 120
    tau = 0.01
    error_scale = 5.  # scale up error signal so it clips
    simtime = 0.3
    model, probes = pes_network(
        n_per_dim, dims, seed, learn_synapse=tau,
        learning_rule_type=nengo.PES(learning_rate=1e-2 / error_scale),
        input_scale=np.array([1., -1.]),
        error_scale=error_scale,
        period=simtime)

    with pytest.warns(UserWarning, match=r'.*PES error.*Clipping.'):
        with Simulator(model) as loihi_sim:
            loihi_sim.run(simtime)

    t = loihi_sim.trange()
    post_tmask = t > simtime - 1.0

    dec_tau = loihi_sim.model.decode_tau
    y = loihi_sim.data[probes['stim']]
    y_dpre = nengo.Lowpass(dec_tau).filt(y)
    y_dpost = nengo.Lowpass(tau).combine(nengo.Lowpass(dec_tau)).filt(y_dpre)
    y_loihi = loihi_sim.data[probes['post']]

    plt.plot(t, y_dpost, 'k', label='target')
    plt.plot(t, y_loihi, 'g', label='loihi')

    # --- assert that we've learned something, but not everything
    error = (rms(y_loihi[post_tmask] - y_dpost[post_tmask])
             / rms(y_dpost[post_tmask]))
    assert error < 0.5
    assert error > 0.05
예제 #2
0
def test_compare_solvers(Simulator, plt, seed, allclose):
    pytest.importorskip("sklearn")

    N = 70
    decoder_solvers = [
        Lstsq(),
        LstsqNoise(),
        LstsqL2(),
        LstsqL2nz(),
        LstsqL1(max_iter=5000),
    ]
    weight_solvers = [LstsqL1(weights=True, max_iter=5000), LstsqDrop(weights=True)]

    tfinal = 4

    def input_function(t):
        return np.interp(t, [1, 3], [-1, 1], left=-1, right=1)

    model = nengo.Network(seed=seed)
    with model:
        u = nengo.Node(output=input_function)
        a = nengo.Ensemble(N, dimensions=1)
        nengo.Connection(u, a)
        ap = nengo.Probe(a)

        probes = []
        names = []
        for solver in decoder_solvers + weight_solvers:
            b = nengo.Ensemble(N, dimensions=1, seed=seed + 1)
            nengo.Connection(a, b, solver=solver)
            probes.append(nengo.Probe(b))
            names.append(
                "%s(%s)" % (type(solver).__name__, "w" if solver.weights else "d")
            )

    with Simulator(model) as sim:
        sim.run(tfinal)
    t = sim.trange()

    # ref = sim.data[up]
    ref = nengo.Lowpass(0.02).filtfilt(sim.data[ap], dt=sim.dt)
    outputs = np.array([sim.data[probe][:, 0] for probe in probes]).T
    outputs_f = nengo.Lowpass(0.02).filtfilt(outputs, dt=sim.dt)

    close = signals_allclose(
        t,
        ref,
        outputs_f,
        atol=0.07,
        rtol=0,
        buf=0.1,
        delay=0.007,
        plt=plt,
        labels=names,
        individual_results=True,
        allclose=allclose,
    )

    for name, c in zip(names, close):
        assert c, "Solver '%s' does not meet tolerances" % name
예제 #3
0
def test_direct_window(legendre, Simulator, seed, plt):
    theta = 1.0
    T = theta

    assert np.allclose(t_default, np.linspace(0, 1, 1000))

    with Network() as model:
        stim = nengo.Node(output=lambda t: t)
        rw = RollingWindow(theta, n_neurons=1, dimensions=12,
                           neuron_type=nengo.Direct(), process=None,
                           legendre=legendre)
        assert rw.theta == theta
        assert rw.dt == 0.001
        assert rw.process is None
        assert rw.synapse == nengo.Lowpass(0.1)
        assert rw.input_synapse == nengo.Lowpass(0.1)

        nengo.Connection(stim, rw.input, synapse=None)
        output = rw.add_output(function=lambda w: np.sum(w**3)**2)
        p_output = nengo.Probe(output, synapse=None)

    with Simulator(model) as sim:
        sim.run(T)

    actual = sim.data[p_output].squeeze()
    t = sim.trange()
    ideal = shift(np.cumsum(t**3)**2)

    plt.figure()
    plt.plot(t, actual, label="Output")
    plt.plot(t, ideal, label="Ideal", linestyle='--')
    plt.legend()

    assert nrmse(actual, ideal) < 0.005
예제 #4
0
def test_eval_points(Simulator, nl_nodirect, plt, seed, rng, logger):
    n = 100
    d = 5
    filter = 0.08

    eval_points = np.logspace(np.log10(300), np.log10(5000), 11)
    eval_points = np.round(eval_points).astype("int")
    max_points = eval_points.max()
    n_trials = 1

    rmses = np.nan * np.zeros((len(eval_points), n_trials))
    for j in range(n_trials):
        points = rng.normal(size=(max_points, d))
        points *= (rng.uniform(size=max_points) / norm(points, axis=-1))[:, None]

        rng_j = np.random.RandomState(348 + j)
        seed = 903824 + j

        # generate random input in unit hypersphere
        x = rng_j.normal(size=d)
        x *= rng_j.uniform() / norm(x)

        for i, n_points in enumerate(eval_points):
            model = nengo.Network(seed=seed)
            with model:
                model.config[nengo.Ensemble].neuron_type = nl_nodirect()
                u = nengo.Node(output=x)
                a = nengo.Ensemble(n * d, dimensions=d, eval_points=points[:n_points])
                nengo.Connection(u, a, synapse=0)
                up = nengo.Probe(u)
                ap = nengo.Probe(a)

            with Timer() as timer:
                sim = Simulator(model)
            sim.run(10 * filter)
            sim.close()

            t = sim.trange()
            xt = nengo.Lowpass(filter).filtfilt(sim.data[up], dt=sim.dt)
            yt = nengo.Lowpass(filter).filtfilt(sim.data[ap], dt=sim.dt)
            t0 = 5 * filter
            t1 = 7 * filter
            tmask = (t > t0) & (t < t1)

            rmses[i, j] = rms(yt[tmask] - xt[tmask])
            logger.info("trial %d", j)
            logger.info("  n_points: %d", n_points)
            logger.info("  duration: %0.3f s", timer.duration)

    # subtract out mean for each model
    rmses_norm = rmses - rmses.mean(0, keepdims=True)

    mean = rmses_norm.mean(1)
    low = rmses_norm.min(1)
    high = rmses_norm.max(1)
    plt.semilogx(eval_points, mean, "k-")
    plt.semilogx(eval_points, high, "r-")
    plt.semilogx(eval_points, low, "b-")
    plt.xlim([eval_points[0], eval_points[-1]])
    plt.xticks(eval_points, eval_points)
예제 #5
0
def test_chip_to_host_function_points(Simulator, seed, plt, allclose):
    """Connection from chip to host that computes a function using points"""
    fn = lambda x: -x
    probe_syn = nengo.Lowpass(0.03)
    simtime = 0.3

    with nengo.Network(seed=seed) as net:
        u = nengo.Node(lambda t: np.sin((2 * np.pi / simtime) * t))
        a = nengo.Ensemble(100, 1)
        # v has a function so it doesn't get removed as passthrough
        v = nengo.Node(lambda t, x: x + 1e-8, size_in=1)
        nengo.Connection(u, a, synapse=None)

        x = np.linspace(-1, 1, 1000).reshape(-1, 1)
        y = fn(x)
        nengo.Connection(a, v, synapse=None, eval_points=x, function=y)

        up = nengo.Probe(u, synapse=probe_syn.combine(nengo.Lowpass(0.005)))
        vp = nengo.Probe(v, synapse=probe_syn)

    with Simulator(net) as sim:
        sim.run(simtime)

    y_ref = fn(sim.data[up])
    plt.plot(sim.trange(), y_ref)
    plt.plot(sim.trange(), sim.data[vp])
    assert allclose(sim.data[vp], y_ref, atol=0.1)
예제 #6
0
def test_network_copies_defaults():
    original = nengo.Network()
    original.config[nengo.Ensemble].radius = 1.5
    original.config[nengo.Connection].synapse = nengo.Lowpass(0.1)

    cp = original.copy()
    assert cp.config[nengo.Ensemble].radius == 1.5
    assert cp.config[nengo.Connection].synapse == nengo.Lowpass(0.1)
예제 #7
0
def test_pes_comm_channel(dims, allclose, plt, seed, Simulator):
    n_per_dim = 120
    tau = 0.01
    simtime = 1.5
    model, probes = pes_network(
        n_per_dim,
        dims,
        seed,
        learn_synapse=tau,
        learning_rule_type=nengo.PES(learning_rate=1e-2),
        period=simtime / 2)

    with nengo.Simulator(model) as nengo_sim:
        nengo_sim.run(simtime)

    with Simulator(model) as loihi_sim:
        loihi_sim.run(simtime)

    with Simulator(model, target='simreal') as real_sim:
        real_sim.run(simtime)

    t = nengo_sim.trange()
    pre_tmask = t > 0.1
    post_tmask = t > simtime / 2

    dec_tau = loihi_sim.model.decode_tau
    y = nengo_sim.data[probes['stim']]
    y_dpre = nengo.Lowpass(dec_tau).filt(y)
    y_dpost = nengo.Lowpass(tau).combine(nengo.Lowpass(dec_tau)).filt(y_dpre)
    y_nengo = nengo_sim.data[probes['post']]
    y_loihi = loihi_sim.data[probes['post']]
    y_real = real_sim.data[probes['post']]

    plt.subplot(211)
    plt.plot(t, y_dpost, 'k', label='target')
    plt.plot(t, y_nengo, 'b', label='nengo')
    plt.plot(t, y_loihi, 'g', label='loihi')
    plt.plot(t, y_real, 'r:', label='real')
    plt.legend()

    plt.subplot(212)
    plt.plot(t[post_tmask], y_loihi[post_tmask] - y_dpost[post_tmask], 'k')
    plt.plot(t[post_tmask], y_loihi[post_tmask] - y_nengo[post_tmask], 'b')

    x_loihi = loihi_sim.data[probes['pre']]
    assert allclose(x_loihi[pre_tmask], y_dpre[pre_tmask], atol=0.1, rtol=0.05)

    assert allclose(y_loihi[post_tmask],
                    y_dpost[post_tmask],
                    atol=0.1,
                    rtol=0.05)
    assert allclose(y_loihi, y_nengo, atol=0.2, rtol=0.2)

    assert allclose(y_real[post_tmask],
                    y_dpost[post_tmask],
                    atol=0.1,
                    rtol=0.05)
    assert allclose(y_real, y_nengo, atol=0.2, rtol=0.2)
예제 #8
0
def generate(net=None, n_neurons=200, alpha=1000.0, beta=1000.0/4.0,
             dt=0.001, analog=False):
    tau = 0.1  # synaptic time constant
    synapse = nengo.Lowpass(tau)

    # the A matrix for our point attractor
    A = np.array([[0.0, 1.0],
                  [-alpha*beta, -alpha]])

    # the B matrix for our point attractor
    B = np.array([[0.0], [alpha*beta]])

    # if you have the nengolib library you can do it this way
    # from nengolib.synapses import ss2sim
    # C = np.eye(2)
    # D = np.zeros((2, 2))
    # linsys = ss2sim((A, B, C, D), synapse=synapse, dt=None if analog else dt)
    # A = linsys.A
    # B = linsys.B

    if analog:
        # account for continuous lowpass filter
        A = tau * A + np.eye(2)
        B = tau * B
    else:
        # discretize state matrices
        Ad = expm(A*dt)
        Bd = np.dot(np.linalg.inv(A), np.dot((Ad - np.eye(2)), B))
        # account for discrete lowpass filter
        a = np.exp(-dt/tau)
        A = 1.0 / (1.0 - a) * (Ad - a * np.eye(2))
        B = 1.0 / (1.0 - a) * Bd

    if net is None:
        net = nengo.Network(label='Point Attractor')
    config = nengo.Config(nengo.Connection, nengo.Ensemble)
    config[nengo.Connection].synapse = nengo.Lowpass(tau)

    with config, net:
        net.ydy = nengo.Ensemble(n_neurons=n_neurons, dimensions=2,
            # set it up so neurons are tuned to one dimensions only
            encoders=nengo.dists.Choice([[1, 0], [-1, 0], [0, 1], [0, -1]]))
        # set up Ax part of point attractor
        nengo.Connection(net.ydy, net.ydy, transform=A)

        # hook up input
        net.input = nengo.Node(size_in=1, size_out=1)
        # set up Bu part of point attractor
        nengo.Connection(net.input, net.ydy, transform=B)

        # hook up output
        net.output = nengo.Node(size_in=1, size_out=1)
        # add in forcing function
        nengo.Connection(net.ydy[0], net.output, synapse=None)

    return net
예제 #9
0
def test_pes_overflow(plt, seed, Simulator):
    dims = 3
    n_per_dim = 300
    tau = 0.01
    simtime = 0.6
    model, probes = pes_network(
        n_per_dim,
        dims,
        seed,
        learn_synapse=tau,
        input_scale=np.linspace(1, 0.7, dims),
        learning_rule_type=nengo.PES(learning_rate=1e-2),
        period=simtime,
    )

    loihi_model = Model()
    # set learning_wgt_exp low to create overflow in weight values
    loihi_model.pes_wgt_exp = -2

    with Simulator(
            model,
            model=loihi_model,
            hardware_options={"allocator": RoundRobin()},
    ) as loihi_sim:
        loihi_sim.run(simtime)

    t = loihi_sim.trange()
    post_tmask = t > simtime - 0.1

    dec_tau = loihi_sim.model.decode_tau
    y = loihi_sim.data[probes["stim"]]
    y_dpre = nengo.Lowpass(dec_tau).filt(y)
    y_dpost = nengo.Lowpass(tau).combine(nengo.Lowpass(dec_tau)).filt(y_dpre)
    y_loihi = loihi_sim.data[probes["post"]]

    plt.plot(t, y_dpost, "k", label="target")
    plt.plot(t, y_loihi, "g", label="loihi")

    # --- fit output to scaled version of target output
    z_ref0 = y_dpost[post_tmask][:, 0]
    z_loihi = y_loihi[post_tmask]
    scale = np.linspace(0, 1, 50)
    E = np.abs(z_loihi - scale[:, None, None] * z_ref0[:, None])
    errors = E.mean(axis=1)  # average over time (errors is: scales x dims)
    for j in range(dims):
        errors_j = errors[:, j]
        i = np.argmin(errors_j)
        assert errors_j[i] < 0.1, ("Learning output for dim %d did not match "
                                   "any scaled version of the target output" %
                                   j)
        assert scale[i] > 0.25, "Learning output for dim %d is too small" % j
        assert scale[i] < 0.9, (
            "Learning output for dim %d is too large "
            "(weights or traces not clipping as expected)" % j)
예제 #10
0
    def test_equivalent_filters(self, minimise):
        """Test construction of filter regions from signals and keyspaces."""
        # Create two keyspaces, two signal parameters and two reception
        # parameters with equivalent synapses.
        ks_a = mock.Mock(name="Keyspace[A]")
        signal_a = SignalParameters(keyspace=ks_a, latching=False)

        ks_b = mock.Mock(name="Keyspace[B]")
        signal_b = SignalParameters(keyspace=ks_b, latching=False)

        rp_a = ReceptionParameters(nengo.Lowpass(0.01), 3, None)
        rp_b = ReceptionParameters(nengo.Lowpass(0.01), 3, None)

        # Create the data structure that is expected as input
        specs = [
            ReceptionSpec(signal_a, rp_a),
            ReceptionSpec(signal_b, rp_b),
        ]

        # Create the regions, with minimisation
        filter_region, routing_region = make_filter_regions(
            specs,
            0.001,
            minimise=minimise,
            filter_routing_tag="spam",
            index_field="eggs")

        # Check that the filter region is as expected
        assert filter_region.dt == 0.001

        if minimise:
            assert len(filter_region.filters) == 1
            assert filter_region.filters[0] == LowpassFilter(3, False, 0.01)
        else:
            assert len(filter_region.filters) == 2
            assert filter_region.filters[0] == LowpassFilter(3, False, 0.01)
            assert filter_region.filters[1] == LowpassFilter(3, False, 0.01)

        # Check that the routing region is as expected
        assert routing_region.filter_routing_tag == "spam"
        assert routing_region.index_field == "eggs"
        if minimise:
            assert (signal_a, 0) in routing_region.signal_routes
            assert (signal_b, 0) in routing_region.signal_routes
        else:
            if (signal_a, 0) in routing_region.signal_routes:
                assert (signal_b, 1) in routing_region.signal_routes
            else:
                assert (signal_b, 0) in routing_region.signal_routes
예제 #11
0
    def test_forced_filter_width(self):
        """Test construction of filter regions from signals and keyspaces."""
        # Create two keyspaces, two signals and two connections with equivalent
        # synapses.
        # Create two keyspaces, two signals and two reception parameters with
        # different synapses.
        ks_a = mock.Mock(name="Keyspace[A]")
        signal_a = SignalParameters(keyspace=ks_a, latching=False)

        ks_b = mock.Mock(name="Keyspace[B]")
        signal_b = SignalParameters(keyspace=ks_b, latching=False)

        rp_a = ReceptionParameters(nengo.Lowpass(0.01), 3, None)
        rp_b = ReceptionParameters(None, 5, None)

        # Create the type of dictionary that is expected as input
        specs = [
            ReceptionSpec(signal_a, rp_a),
            ReceptionSpec(signal_b, rp_b),
        ]

        # Create the regions, with minimisation
        filter_region, routing_region = make_filter_regions(specs,
                                                            0.001,
                                                            width=1)

        # Check that the filter region is as expected
        for f in filter_region.filters:
            assert (f == LowpassFilter(1, False, 0.01)
                    or f == NoneFilter(1, False))  # noqa: E711
예제 #12
0
def test_weights(Simulator, nl, plt, seed):
    n1, n2 = 100, 50

    def func(t):
        return [np.sin(4 * t), np.cos(12 * t)]

    transform = np.array([[0.6, -0.4]])

    m = nengo.Network(label='test_weights', seed=seed)
    with m:
        m.config[nengo.Ensemble].neuron_type = nl()
        u = nengo.Node(output=func)
        a = nengo.Ensemble(n1, dimensions=2, radius=1.5)
        b = nengo.Ensemble(n2, dimensions=1)
        bp = nengo.Probe(b)

        nengo.Connection(u, a)
        nengo.Connection(a,
                         b,
                         transform=transform,
                         solver=LstsqL2(weights=True))

    with Simulator(m) as sim:
        sim.run(1.)

    t = sim.trange()
    x = np.array(func(t)).T
    y = np.dot(x, transform.T)
    z = nengo.Lowpass(0.005).filtfilt(sim.data[bp], dt=sim.dt)
    assert allclose(t, y, z, atol=0.1, buf=0.1, delay=0.01, plt=plt)
예제 #13
0
def test_passthrough_filter(Simulator, plt, seed, allclose):
    m = nengo.Network(seed=seed)
    with m:
        omega = 2 * np.pi * 5
        u = nengo.Node(output=lambda t: np.sin(omega * t))
        passthrough = nengo.Node(size_in=1)
        v = nengo.Node(output=lambda t, x: x, size_in=1)

        synapse = nengo.Lowpass(0.3)
        nengo.Connection(u, passthrough, synapse=None)
        nengo.Connection(passthrough, v, synapse=synapse)

        up = nengo.Probe(u)
        vp = nengo.Probe(v)

    with Simulator(m) as sim:
        sim.run(1.0)

    t = sim.trange()
    x = sim.data[up]
    y = synapse.filt(x, dt=sim.dt, y0=0)
    z = sim.data[vp]

    plt.plot(t, x)
    plt.plot(t, y)
    plt.plot(t, z)

    assert allclose(y[:-1], z[1:], atol=1e-7, rtol=1e-4)
예제 #14
0
def test_function_output_size(Simulator, plt, seed, allclose):
    """Try a function that outputs both 0-d and 1-d arrays"""
    def bad_function(x):
        return x if x > 0 else 0

    model = nengo.Network(seed=seed)
    with model:
        u = nengo.Node(output=lambda t: (t - 0.1) * 10)
        a = nengo.Ensemble(n_neurons=100, dimensions=1)
        b = nengo.Ensemble(n_neurons=100, dimensions=1)
        nengo.Connection(u, a, synapse=None)
        nengo.Connection(a, b, synapse=None, function=bad_function)
        up = nengo.Probe(u)
        bp = nengo.Probe(b, synapse=0.03)

    with Simulator(model) as sim:
        sim.run(0.2)
    t = sim.trange()
    x = nengo.Lowpass(0.03).filt(sim.data[up].clip(0, np.inf), dt=sim.dt)
    y = sim.data[bp]

    plt.plot(t, x, "k")
    plt.plot(t, y)

    assert allclose(x, y, atol=0.1)
예제 #15
0
def test_combined_delay(Simulator, allclose):
    # ensure that two sequential filters has the same output
    # as combining their individual discrete transfer functions
    nt = 50
    tau = 0.005
    dt = 0.001

    sys1 = nengo.Lowpass(tau)
    (num,), den, _ = cont2discrete((sys1.num, sys1.den), dt=dt)
    sys2 = nengo.LinearFilter(np.poly1d(num) ** 2, np.poly1d(den) ** 2, analog=False)

    with nengo.Network() as model:
        u = nengo.Node(1)
        x = nengo.Node(size_in=1)
        nengo.Connection(u, x, synapse=sys1)
        p1 = nengo.Probe(x, synapse=sys1)
        p2 = nengo.Probe(u, synapse=sys2)

    with Simulator(model, dt=dt) as sim:
        sim.run_steps(nt)

    assert allclose(sim.data[p1], sim.data[p2])

    # Both have two time-step delays:
    # for sys1, this comes from two levels of filtering
    # for sys2, this comes from one level of filtering + delay in sys2
    assert allclose(sim.data[p1][:2], 0)
    assert not allclose(sim.data[p1][2], 0, record_rmse=False)
예제 #16
0
    def test_from_parameters_force_width(self, width, latching, tc):
        # Create the mock signal and connection
        signal = SignalParameters(latching=latching)
        rps = ReceptionParameters(nengo.Lowpass(tc), width, None)

        # Create the filter
        lpf = LowpassFilter.from_parameters(signal, rps, width=2)
        assert lpf == LowpassFilter(2, latching, tc)
예제 #17
0
def test_rls_repr():
    assert repr(RLS()) == "RLS(learning_rate=1.0, pre_synapse=Lowpass(0.005))"
    assert (repr(RLS(learning_rate=1e-5)) ==
            "RLS(learning_rate=1e-05, pre_synapse=Lowpass(0.005))")
    assert (repr(
        RLS(pre_synapse=None)) == "RLS(learning_rate=1.0, pre_synapse=None)")
    assert (repr(RLS(learning_rate=1e-2, pre_synapse=nengo.Lowpass(1e-4))) ==
            "RLS(learning_rate=0.01, pre_synapse=Lowpass(0.0001))")
예제 #18
0
def test_neuron_probes(precompute, probe_target, Simulator, seed, plt,
                       allclose):
    simtime = 0.3

    with nengo.Network(seed=seed) as model:
        stim = nengo.Node(lambda t: [np.sin(t * 2 * np.pi / simtime)])

        a = nengo.Ensemble(
            1,
            1,
            neuron_type=nengo.LIF(min_voltage=-1),
            encoders=nengo.dists.Choice([[1]]),
            max_rates=nengo.dists.Choice([100]),
            intercepts=nengo.dists.Choice([0.0]),
        )
        nengo.Connection(stim, a, synapse=None)

        p_stim = nengo.Probe(stim, synapse=0.005)
        p_neurons = nengo.Probe(a.neurons, probe_target)

        probe_synapse = nengo.Alpha(0.01)
        p_stim_f = nengo.Probe(stim,
                               synapse=probe_synapse.combine(
                                   nengo.Lowpass(0.005)))
        p_neurons_f = nengo.Probe(a.neurons,
                                  probe_target,
                                  synapse=probe_synapse)

    with Simulator(model, precompute=precompute) as sim:
        sim.run(simtime)

    scale = float(sim.data[p_neurons].max())
    t = sim.trange()
    x = sim.data[p_stim]
    xf = sim.data[p_stim_f]
    y = sim.data[p_neurons] / scale
    yf = sim.data[p_neurons_f] / scale
    plt.plot(t, x, label="stim")
    plt.plot(t, xf, label="stim filt")
    plt.plot(t, y, label="loihi")
    plt.plot(t, yf, label="loihi filt")
    plt.legend()

    if probe_target == "input":
        # shape of current input should roughly match stimulus
        assert allclose(y, x, atol=0.4, rtol=0)  # noisy, so rough match
        assert allclose(yf, xf, atol=0.05, rtol=0)  # tight match
    elif probe_target == "voltage":
        # check for voltage fluctuations (spiking) when stimulus is positive,
        # and negative voltage when stimulus is most negative
        spos = (t > 0.1 * simtime) & (t < 0.4 * simtime)
        assert allclose(yf[spos], 0.5, atol=0.1, rtol=0.1)
        assert y[spos].std() > 0.25

        sneg = (t > 0.7 * simtime) & (t < 0.9 * simtime)
        assert np.all(y[sneg] < 0)
    def test_combine_linear_and_linear_filter(self):
        # Create the ingoing reception parameters
        reception_params_a = model.ReceptionParameters(nengo.Lowpass(0.05), 1)

        # Create the outgoing reception parameters
        reception_params_b = model.ReceptionParameters(nengo.Lowpass(0.01), 5)

        # Combine the parameter each way round
        for a, b in ((reception_params_a, reception_params_b),
                     (reception_params_a, reception_params_b)):
            new_rps = model_utils._combine_reception_params(a, b)

            # Check filter type
            synapse = new_rps.filter
            assert synapse.num == [1]
            assert np.all(synapse.den == [0.05 * 0.01, 0.05 + 0.01, 1])

            # Check width is the width of the receiving item
            assert new_rps.width == b.width
예제 #20
0
def test_dt(dt, pre_on_chip, Simulator, seed, plt, allclose):
    function = lambda x: -x
    simtime = 0.2

    probe_synapse = nengo.Alpha(0.01)
    conn_synapse = nengo.Lowpass(0.005)
    stim_synapse = probe_synapse
    # stim synapse accounts for delays in connections/probes, so we can compare
    if pre_on_chip:
        stim_synapse = stim_synapse.combine(conn_synapse)

    ens_params = dict(
        intercepts=nengo.dists.Uniform(-0.9, 0.9),
        max_rates=nengo.dists.Uniform(100, 120),
    )

    with nengo.Network(seed=seed) as model:
        nengo_loihi.add_params(model)

        stim = nengo.Node(lambda t: -(np.sin(2 * np.pi * t / simtime)))
        stim_p = nengo.Probe(stim, synapse=stim_synapse)

        pre = nengo.Ensemble(100, 1, **ens_params)
        model.config[pre].on_chip = pre_on_chip
        pre_p = nengo.Probe(pre, synapse=probe_synapse)

        post = nengo.Ensemble(101, 1, **ens_params)
        post_p = nengo.Probe(post, synapse=probe_synapse)

        nengo.Connection(stim, pre, synapse=None)
        nengo.Connection(
            pre,
            post,
            function=function,
            synapse=conn_synapse,
            solver=nengo.solvers.LstsqL2(weights=True),
        )

    with Simulator(model, dt=dt) as sim:
        assert sim.model.decode_tau == conn_synapse.tau
        sim.run(simtime)

    x = sim.data[stim_p]
    y = function(x)
    if pre_on_chip:
        y = conn_synapse.filt(y, dt=dt)
    else:
        y = conn_synapse.combine(conn_synapse).filt(y, dt=dt)
    plt.plot(sim.trange(), x, "k--")
    plt.plot(sim.trange(), y, "k--")
    plt.plot(sim.trange(), sim.data[pre_p])
    plt.plot(sim.trange(), sim.data[post_p])

    assert allclose(sim.data[pre_p], x, rtol=0.1, atol=0.1)
    assert allclose(sim.data[post_p], y, rtol=0.1, atol=0.1)
예제 #21
0
def _test_temporal_solver(plt, Simulator, seed, neuron_type, tau, f, solver):
    dt = 0.002

    # we are cheating a bit here because we'll use the same training data as
    # test data. this makes the unit testing a bit simpler since it's more
    # obvious what will happen when comparing temporal to default
    t = np.arange(0, 0.2, dt)
    stim = np.sin(2 * np.pi * 10 * t)
    function = (f(stim) if tau is None else nengo.Lowpass(tau).filt(f(stim),
                                                                    dt=dt))

    with Network(seed=seed) as model:
        u = nengo.Node(output=nengo.processes.PresentInput(stim, dt))
        x = nengo.Ensemble(100, 1, neuron_type=neuron_type)
        output_ideal = nengo.Node(size_in=1)

        post = dict(n_neurons=500,
                    dimensions=1,
                    neuron_type=nengo.LIFRate(),
                    seed=seed + 1)
        output_temporal = nengo.Ensemble(**post)
        output_default = nengo.Ensemble(**post)

        nengo.Connection(u, output_ideal, synapse=tau, function=f)
        nengo.Connection(u, x, synapse=None)
        nengo.Connection(x,
                         output_temporal,
                         synapse=tau,
                         eval_points=stim[:, None],
                         function=function[:, None],
                         solver=Temporal(synapse=tau, solver=solver))
        nengo.Connection(x,
                         output_default,
                         synapse=tau,
                         eval_points=stim[:, None],
                         function=f,
                         solver=solver)

        p_ideal = nengo.Probe(output_ideal, synapse=None)
        p_temporal = nengo.Probe(output_temporal, synapse=None)
        p_default = nengo.Probe(output_default, synapse=None)

    with Simulator(model, dt) as sim:
        sim.run(t[-1])

    plt.plot(sim.trange(),
             sim.data[p_ideal] - sim.data[p_default],
             label="Default")
    plt.plot(sim.trange(),
             sim.data[p_ideal] - sim.data[p_temporal],
             label="Temporal")
    plt.legend()

    return (nrmse(sim.data[p_default], target=sim.data[p_ideal]) /
            nrmse(sim.data[p_temporal], target=sim.data[p_ideal]))
예제 #22
0
def test_neuron_probe_with_synapse(Simulator, seed, allclose):
    synapse = nengo.Lowpass(0.01)
    with nengo.Network(seed=seed) as net:
        ens = nengo.Ensemble(10, 1)
        p_nosynapse = nengo.Probe(ens.neurons, synapse=None)
        p_synapse = nengo.Probe(ens.neurons, synapse=synapse)

    with Simulator(net) as sim:
        sim.run(0.1)

    assert allclose(sim.data[p_synapse], synapse.filt(sim.data[p_nosynapse]))
예제 #23
0
def test_cchannelchain(Simulator, plt, rng, seed, outfile):
    dims = 2
    layers = 5
    n_neurons = 100
    synapse = nengo.Lowpass(0.01)

    with nengo.Network(seed=seed) as model:
        value = nengo.dists.UniformHypersphere().sample(dims, 1, rng=rng)[:, 0]
        stim = nengo.Node(value)

        ens = [
            nengo.Ensemble(n_neurons, dimensions=dims) for _ in range(layers)
        ]

        nengo.Connection(stim, ens[0])
        for i in range(layers - 1):
            nengo.Connection(ens[i], ens[i + 1], synapse=synapse)

        p_input = nengo.Probe(stim)
        p_outputs = [
            nengo.Probe(ens[i], synapse=synapse) for i in range(layers)
        ]

    sim = Simulator(model)
    sim.run(0.5)

    if type(plt).__name__ != 'Mock':
        figsize = (onecolumn, 4.0) if horizontal else (onecolumn * 2, 4.0)
        setup(figsize=figsize)
        colors = sns.cubehelix_palette(5)
        lines = []
        for i, p_output in enumerate(p_outputs):
            l = plt.plot(sim.trange(),
                         sim.data[p_output],
                         c=colors[i % len(colors)])
            lines.append(l[0])
        plt.legend(lines, ["Ensemble %d" % i for i in range(1, 6)], loc='best')
        plt.plot(sim.trange(), sim.data[p_input], c='k', lw=1)
        plt.xlim(right=0.12)
        plt.yticks((-0.5, 0, 0.5))
        plt.xticks((0, 0.05, 0.1))
        plt.ylabel('Decoded output')
        plt.xlabel('Time (s)')
        sns.despine()
        plt.saveas = 'results-1.svg'

    outfile.write('"n_neurons": %d,\n' % sum(e.n_neurons
                                             for e in model.all_ensembles))
    outfile.write('"simtime": 0.5,\n')
    outfile.write('"rmse": %f,\n' %
                  (rmse(sim.data[p_outputs[-1]][sim.trange() > 0.4], value)))

    if hasattr(sim, 'close'):
        sim.close()
예제 #24
0
def test_synapse():
    inp = tf.keras.Input(shape=(1, ))
    dense0 = tf.keras.layers.Dense(units=10, activation=tf.nn.relu)(inp)
    dense1 = tf.keras.layers.Dense(units=10, activation=None)(dense0)

    model = tf.keras.Model(inp, [dense0, dense1])

    conv = converter.Converter(model, synapse=0.1)

    for conn in conv.net.all_connections:
        if conn.pre is conv.layers[dense0]:
            # synapse set on outputs from neurons
            assert conn.synapse == nengo.Lowpass(0.1)
        else:
            # synapse not set on other connections
            assert conn.synapse is None

    # synapse set on neuron probe
    assert conv.outputs[dense0].synapse == nengo.Lowpass(0.1)
    # not set on non-neuron probe
    assert conv.outputs[dense1].synapse is None
    def test_combine_unknown_filter(self):
        # Create the ingoing reception parameters
        reception_params_a = model.ReceptionParameters(nengo.Lowpass(0.05), 1)

        # Create the outgoing reception parameters
        reception_params_b = model.ReceptionParameters(mock.Mock(), 1)

        # Combine the parameter each way round
        for a, b in ((reception_params_a, reception_params_b),
                     (reception_params_a, reception_params_b)):
            with pytest.raises(NotImplementedError):
                new_rps = model_utils._combine_reception_params(a, b)
예제 #26
0
def generate(net=None,
             n_neurons=200,
             alpha=1000.0,
             beta=1000.0 / 4.0,
             dt=0.001,
             analog=False):
    tau = 0.1  # synaptic time constant

    # the A matrix for our point attractor
    A = np.array([[0.0, 1.0], [-alpha * beta, -alpha]])

    # the B matrix for our point attractor
    B = np.array([[0.0, 0.0], [alpha * beta, 1.0]])

    # discretize
    Ad = expm(A * dt)
    Bd = np.dot(np.linalg.inv(A), np.dot((Ad - np.eye(2)), B))
    # account for discrete lowpass filter
    a = np.exp(-dt / tau)
    if analog:
        A = tau * A + np.eye(2)
        B = tau * B
    else:
        A = 1.0 / (1.0 - a) * (Ad - a * np.eye(2))
        B = 1.0 / (1.0 - a) * Bd

    if net is None:
        net = nengo.Network(label='Point Attractor')
    config = nengo.Config(nengo.Connection, nengo.Ensemble)
    config[nengo.Connection].synapse = nengo.Lowpass(tau)
    # config[nengo.Ensemble].neuron_type = nengo.Direct()

    with config, net:
        net.ydy = nengo.Ensemble(
            n_neurons=n_neurons,
            dimensions=2,
            # set it up so neurons are tuned to one dimensions only
            encoders=nengo.dists.Choice([[1, 0], [-1, 0], [0, 1], [0, -1]]))
        # set up Ax part of point attractor
        nengo.Connection(net.ydy, net.ydy, transform=A)

        # hook up input
        net.input = nengo.Node(size_in=2)
        # set up Bu part of point attractor
        nengo.Connection(net.input, net.ydy, transform=B)

        # hook up output
        net.output = nengo.Node(size_in=1)
        # add in forcing function
        nengo.Connection(net.ydy[0], net.output, synapse=None)

    return net
예제 #27
0
def test_pes_error_clip(plt, seed, Simulator):
    dims = 2
    n_per_dim = 120
    tau = 0.01
    error_scale = 5.0  # scale up error signal so it clips
    simtime = 0.3
    model, probes = pes_network(
        n_per_dim,
        dims,
        seed,
        learn_synapse=tau,
        learning_rule_type=nengo.PES(learning_rate=1e-2 / error_scale),
        input_scale=np.array([1.0, -1.0]),
        error_scale=error_scale,
        period=simtime,
    )

    with pytest.warns(UserWarning, match=r".*PES error.*pes_error_scale.*"):
        with Simulator(model, hardware_options={"allocator":
                                                RoundRobin()}) as loihi_sim:
            loihi_sim.run(simtime)

    t = loihi_sim.trange()
    post_tmask = t > simtime - 1.0

    dec_tau = loihi_sim.model.decode_tau
    y = loihi_sim.data[probes["stim"]]
    y_dpre = nengo.Lowpass(dec_tau).filt(y)
    y_dpost = nengo.Lowpass(tau).combine(nengo.Lowpass(dec_tau)).filt(y_dpre)
    y_loihi = loihi_sim.data[probes["post"]]

    plt.plot(t, y_dpost, "k", label="target")
    plt.plot(t, y_loihi, "g", label="loihi")

    # --- assert that we've learned something, but not everything
    error = rms(y_loihi[post_tmask] - y_dpost[post_tmask]) / rms(
        y_dpost[post_tmask])
    assert error < 0.5
    assert error > 0.05
예제 #28
0
def test_alif(Simulator, plt):
    """Test ALIF and ALIFRate by comparing them to each other"""

    n = 100
    max_rates = 50 * np.ones(n)
    intercepts = np.linspace(-0.99, 0.99, n)
    encoders = np.ones((n, 1))
    nparams = dict(tau_n=1, inc_n=10e-3)
    eparams = dict(n_neurons=n,
                   max_rates=max_rates,
                   intercepts=intercepts,
                   encoders=encoders)

    model = nengo.Network()
    with model:
        u = nengo.Node(output=0.5)
        a = nengo.Ensemble(neuron_type=AdaptiveLIFRate(**nparams),
                           dimensions=1,
                           **eparams)
        b = nengo.Ensemble(neuron_type=AdaptiveLIF(**nparams),
                           dimensions=1,
                           **eparams)
        nengo.Connection(u, a, synapse=0)
        nengo.Connection(u, b, synapse=0)
        ap = nengo.Probe(a.neurons)
        bp = nengo.Probe(b.neurons)

    dt = 1e-3
    with Simulator(model, dt=dt) as sim:
        sim.run(2.)

    t = sim.trange()
    a_rates = sim.data[ap]
    spikes = sim.data[bp]
    b_rates = nengo.Lowpass(0.04).filtfilt(spikes)

    tmask = (t > 0.1) & (t < 1.7)
    rel_rmse = rms(b_rates[tmask] - a_rates[tmask]) / rms(a_rates[tmask])

    ax = plt.subplot(311)
    implot(plt, t, intercepts[::-1], a_rates.T, ax=ax)
    ax.set_ylabel('input')
    ax = plt.subplot(312)
    implot(plt, t, intercepts[::-1], b_rates.T, ax=ax)
    ax.set_ylabel('input')
    ax = plt.subplot(313)
    implot(plt, t, intercepts[::-1], (b_rates - a_rates)[tmask].T, ax=ax)
    ax.set_xlabel('time [s]')
    ax.set_ylabel('input')

    assert rel_rmse < 0.07
예제 #29
0
    def evaluate(self, p, sim, plt):
        sim.run(p.T)
        self.record_speed(p.T)

        ideal = np.array(sim.data[self.probe_ideal])
        for i in range(3):
            ideal = nengo.Lowpass(p.pstc).filt(ideal, dt=p.dt, y0=0)

        if plt is not None:
            plt.plot(sim.trange(), sim.data[self.probe])
            plt.plot(sim.trange(), ideal)

        rmse = np.sqrt(np.mean((sim.data[self.probe] - ideal)**2))
        return dict(rmse=rmse)
예제 #30
0
 def merge_synapses(self, syn1, syn2):
     """Return an equivalent synapse for the two provided synapses."""
     if syn1 is None:
         return syn2
     elif syn2 is None:
         return syn1
     else:
         assert isinstance(syn1, nengo.Lowpass) and isinstance(
             syn2, nengo.Lowpass)
         warnings.warn(
             "Combining two Lowpass synapses, this may change the "
             "behaviour of the network (set `remove_passthrough=False` "
             "to avoid this).")
         return nengo.Lowpass(syn1.tau + syn2.tau)