Ejemplo n.º 1
0
def test_eval_points_scaling(Simulator, sample, radius, seed, rng):
    eval_points = UniformHypersphere()
    if sample:
        eval_points = eval_points.sample(500, 3, rng=rng)

    model = nengo.Network(seed=seed)
    with model:
        a = nengo.Ensemble(1, 3, eval_points=eval_points, radius=radius)

    with Simulator(model) as sim:
        dists = npext.norm(sim.data[a].eval_points, axis=1)
        assert np.all(dists <= radius)
        assert np.any(dists >= 0.9 * radius)
Ejemplo n.º 2
0
def test_eval_points_scaling(Simulator, sample, radius, seed, rng, scale):
    eval_points = UniformHypersphere()
    if sample:
        eval_points = eval_points.sample(500, 3, rng=rng)

    model = nengo.Network(seed=seed)
    with model:
        a = nengo.Ensemble(1, 3, radius=radius)
        b = nengo.Ensemble(1, 3)
        con = nengo.Connection(a, b, eval_points=eval_points,
                               scale_eval_points=scale)

    sim = Simulator(model)
    dists = npext.norm(sim.data[con].eval_points, axis=1)
    limit = radius if scale else 1.0
    assert np.all(dists <= limit)
    assert np.any(dists >= 0.9 * limit)
Ejemplo n.º 3
0
def test_distributionparam_sample_shape():
    """sample_shape dictates the shape of the sample that can be set."""
    class Test(object):
        dp = params.DistributionParam(default=None, sample_shape=['d1', 10])
        d1 = 4

    inst = Test()
    # Distributions are still cool
    inst.dp = UniformHypersphere()
    assert isinstance(inst.dp, UniformHypersphere)
    # Must be shape (4, 10)
    inst.dp = np.ones((4, 10))
    assert np.all(inst.dp == np.ones((4, 10)))
    with pytest.raises(ValueError):
        inst.dp = np.ones((10, 4))
    assert np.all(inst.dp == np.ones((4, 10)))
Ejemplo n.º 4
0
def test_distorarrayparam_sample_shape():
    """sample_shape dictates the shape of the sample that can be set."""
    class Test:
        dp = DistOrArrayParam("dp", default=None, sample_shape=["d1", 10])
        d1 = 4

    inst = Test()
    # Distributions are still cool
    inst.dp = UniformHypersphere()
    assert isinstance(inst.dp, UniformHypersphere)
    # Must be shape (4, 10)
    inst.dp = np.ones((4, 10))
    assert np.all(inst.dp == np.ones((4, 10)))
    with pytest.raises(ValidationError):
        inst.dp = np.ones((10, 4))
    assert np.all(inst.dp == np.ones((4, 10)))
Ejemplo n.º 5
0
def test_distorarrayparam():
    """DistOrArrayParams can be distributions or samples."""

    class Test:
        dp = DistOrArrayParam("dp", default=None, sample_shape=["*", "*"])

    inst = Test()
    inst.dp = UniformHypersphere()
    assert isinstance(inst.dp, UniformHypersphere)
    inst.dp = np.array([[1], [2], [3]])
    assert np.all(inst.dp == np.array([[1], [2], [3]]))
    with pytest.raises(ValueError):
        inst.dp = "a"
    # Sample must have correct dims
    with pytest.raises(ValueError):
        inst.dp = np.array([1])
Ejemplo n.º 6
0
def random_orthogonal(d, rng=None):
    """Returns a random orthogonal matrix.

    Parameters
    ----------
    d : ``integer``
        Positive dimension of returned matrix.
    rng : :class:`numpy.random.RandomState` or ``None``, optional
        Random number generator state.

    Returns
    -------
    samples : ``(d, d) np.array``
        Random orthogonal matrix (an orthonormal basis);
        linearly transforms any vector into a uniformly sampled
        vector on the ``d``--ball with the same L2 norm.

    See Also
    --------
    :class:`.ScatteredHypersphere`

    Examples
    --------
    >>> from nengolib.stats import random_orthogonal, sphere
    >>> rng = np.random.RandomState(seed=0)
    >>> u = sphere.sample(1000, 3, rng=rng)
    >>> u[:, 0] = 0
    >>> v = u.dot(random_orthogonal(3, rng=rng))

    >>> import matplotlib.pyplot as plt
    >>> from mpl_toolkits.mplot3d import Axes3D
    >>> ax = plt.subplot(111, projection='3d')
    >>> ax.scatter(*u.T, alpha=.5, label="u")
    >>> ax.scatter(*v.T, alpha=.5, label="v")
    >>> ax.patch.set_facecolor('white')
    >>> ax.set_xlim3d(-1, 1)
    >>> ax.set_ylim3d(-1, 1)
    >>> ax.set_zlim3d(-1, 1)
    >>> plt.legend()
    >>> plt.show()
    """

    rng = np.random if rng is None else rng
    m = UniformHypersphere(surface=True).sample(d, d, rng=rng)
    u, s, v = svd(m)
    return np.dot(u, v)
Ejemplo n.º 7
0
def test_ndarrays(Simulator, rng, allclose):
    encoders = UniformHypersphere(surface=True).sample(10, 1, rng=rng)
    max_rates = rng.uniform(200, 400, size=10)
    intercepts = rng.uniform(-1, 1, size=10)
    eval_points = rng.uniform(-1, 1, size=(100, 1))
    with nengo.Network() as net:
        ea = nengo.networks.EnsembleArray(
            10,
            2,
            encoders=encoders,
            max_rates=max_rates,
            intercepts=intercepts,
            eval_points=eval_points,
            n_eval_points=eval_points.shape[0],
        )

    with Simulator(net) as sim:
        pass
    built = sim.data[ea.ea_ensembles[0]]
    assert allclose(built.encoders, encoders)
    assert allclose(built.max_rates, max_rates)
    assert allclose(built.intercepts, intercepts)
    assert allclose(built.eval_points, eval_points)
    assert built.eval_points.shape == eval_points.shape

    with nengo.Network() as net:
        # Incorrect shapes don't fail until build
        ea = nengo.networks.EnsembleArray(
            10,
            2,
            encoders=encoders,
            max_rates=max_rates,
            intercepts=intercepts,
            eval_points=eval_points[:10],
            n_eval_points=eval_points.shape[0],
        )

    with pytest.raises(ValidationError):
        with Simulator(net) as sim:
            pass
Ejemplo n.º 8
0
def test_target_function(Simulator, nl_nodirect, plt, dimensions, radius, seed,
                         rng):
    eval_points = UniformHypersphere().sample(1000, dimensions, rng=rng)
    eval_points *= radius
    f = lambda x: x**2
    targets = f(eval_points)

    model = nengo.Network(seed=seed)
    with model:
        model.config[nengo.Ensemble].neuron_type = nl_nodirect()
        inp = nengo.Node(lambda t: np.sin(t * 2 * np.pi) * radius)
        ens1 = nengo.Ensemble(40 * dimensions, dimensions, radius=radius)
        n1 = nengo.Node(size_in=dimensions)
        n2 = nengo.Node(size_in=dimensions)
        transform = np.linspace(1, -1, num=dimensions).reshape(-1, 1)
        nengo.Connection(inp, ens1, transform=transform)
        # pass in eval_points and targets
        nengo.Connection(ens1, n1, **target_function(eval_points, targets))
        # same, but let the builder apply f
        nengo.Connection(ens1, n2, function=f)
        probe1 = nengo.Probe(n1, synapse=0.03)
        probe2 = nengo.Probe(n2, synapse=0.03)

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

    plt.subplot(2, 1, 1)
    plt.plot(sim.trange(), sim.data[probe1])
    plt.title('Square manually with target_function')
    plt.subplot(2, 1, 2)
    plt.plot(sim.trange(), sim.data[probe2])
    plt.title('Square by passing in function to connection')
    plt.saveas = ('utils.test_connection.test_target_function_%d_%g.pdf' %
                  (dimensions, radius))

    assert np.allclose(sim.data[probe1], sim.data[probe2], atol=0.2 * radius)
Ejemplo n.º 9
0
def get_eval_points(n_points, dims, rng=None, sort=False):
    points = UniformHypersphere(surface=False).sample(n_points, dims, rng=rng)
    return points[np.argsort(points[:, 0])] if sort else points
Ejemplo n.º 10
0
def get_encoders(n_neurons, dims, rng=None):
    return UniformHypersphere(surface=True).sample(n_neurons, dims, rng=rng).T
Ejemplo n.º 11
0
# objective = 'rms'
# objective = 'sp'
if objective == 'nll':
    cost = nll_cost_on_inds
    error = class_error_on_inds
    dout = n_labels
    dtp_cheat = True
elif objective == 'rms':
    cost = squared_cost_on_inds
    error = rms_error_on_inds
    dout = n_labels
    dtp_cheat = True
elif objective == 'sp':
    dout = 50
    pointers = UniformHypersphere(surface=True).sample(n_labels,
                                                       d=dout,
                                                       rng=rng)
    dtp_cheat = False

    def cost(y, yinds, pointers=pointers):
        return pointer_squared_cost_on_inds(y, yinds, pointers)

    def error(y, yinds, pointers=pointers):
        return pointer_class_error_on_inds(y, yinds, pointers)


din = trainX.shape[1]
sizes = [din] + dhids + [dout]

batch_fn = make_flat_batch_fn(trainX, trainY, n_per_batch)
Ejemplo n.º 12
0
def test_hypersphere_warns():
    with pytest.warns(UserWarning, match="min_magnitude ignored because surface"):
        UniformHypersphere(surface=True, min_magnitude=0.1)
Ejemplo n.º 13
0
def test_hypersphere_errors():
    with pytest.raises(ValidationError, match="Must be of type 'bool'"):
        UniformHypersphere(0)

    with pytest.raises(ValidationError, match="Dimensions must be a positive integer"):
        UniformHypersphere().sample(1, d=-1)
Ejemplo n.º 14
0
    def __init__(self, x, ystar, initial_weights, t0=None, t1=None,
                 n_output=None, o_kind='ensemble',
                 o_encoders=UniformHypersphere(surface=True),
                 o_intercepts=Uniform(-1, 0.9), o_rates=Uniform(100, 120),
                 n_error=None, e_kind='ensemble',
                 e_encoders=UniformHypersphere(surface=True),
                 e_intercepts=Uniform(-1, 0.9), e_rates=Uniform(100, 120),
                 psynapse=None, pdt=None, **kwargs):
        super(FeedforwardNetwork, self).__init__(**kwargs)

        din = initial_weights[0].shape[0]
        dout = initial_weights[-1].shape[1]
        dhids = [w.shape[1] for w in initial_weights[:-1]]

        self.n_output = n_output
        self.n_error = n_error
        self.e_kind = e_kind
        self.e_encoders = e_encoders
        self.e_intercepts = e_intercepts
        self.e_rates = e_rates

        self.pargs = dict(synapse=psynapse, sample_every=pdt)

        with self:
            # hidden layers
            self.layers = [
                nengo.Ensemble(dhid, dhid,
                               gain=Choice([1.]), bias=Choice([1.]),
                               label='layer%d' % i)
                for i, dhid in enumerate(dhids)]

            # output layer
            if n_output is None:
                self.output = EAIO(
                    nengo.Node, size_in=dout, label='output')
            elif o_kind == 'ensemble':
                self.output = EAIO(
                    nengo.Ensemble, n_output*dout, dout, label='output',
                    encoders=o_encoders, intercepts=o_intercepts, max_rates=o_rates)
            elif o_kind == 'array':
                self.output = nengo.networks.EnsembleArray(
                    n_output, dout, label='output',
                    encoders=o_encoders, intercepts=o_intercepts, max_rates=o_rates)

            self.yp = nengo.Probe(self.output.output, **self.pargs)

            # error layer
            tmask = ((lambda t: (t > t0) & (t < t1)) if t0 is not None and t1 is not None else \
                     (lambda t: (t > t0)) if t0 is not None else \
                     (lambda t: (t < t1)) if t1 is not None else \
                     (lambda t: (t >= 0)))
            nmask = lambda t: 20 * (tmask(t) - 1)
            if n_error is None:
                ferror = lambda t, x: tmask(t) * x
                self.error = EAIO(
                    nengo.Node, ferror, size_in=dout, label='error')
            elif e_kind == 'ensemble':
                self.error = EAIO(
                    nengo.Ensemble, n_error*dout, dout, label='error',
                    encoders=e_encoders, intercepts=e_intercepts, max_rates=e_rates)
                error_switch = nengo.Node(nmask)
                nengo.Connection(error_switch, self.error.neuron_input,
                                 transform=np.ones((n_error*dout, 1)), synapse=None)
            elif e_kind == 'array':
                self.error = nengo.networks.EnsembleArray(
                    n_error, dout, label='error',
                    encoders=e_encoders, intercepts=e_intercepts, max_rates=e_rates)
                self.error.add_neuron_input()
                error_switch = nengo.Node(nmask)
                nengo.Connection(error_switch, self.error.neuron_input,
                                  transform=np.ones((n_error*dout, 1)), synapse=None)
            else:
                raise ValueError(e_kind)
            self.ep = nengo.Probe(self.error.output, **self.pargs)

        # connections
        nengo.Connection(ystar, self.error.input, transform=-1)
        with self:
            nengo.Connection(self.output.output, self.error.input)

        self.conns = []
        self.conns.append(nengo.Connection(
            x.neurons, self.layers[0].neurons, transform=initial_weights[0].T))

        with self:
            layers = self.layers
            # layers = self.layers + [self.output]
            for layer0, layer1, w in zip(layers, layers[1:], initial_weights[1:]):
                self.conns.append(nengo.Connection(
                    layer0.neurons, layer1.neurons, transform=w.T))
            self.conns.append(nengo.Connection(
                self.layers[-1].neurons, self.output.input, transform=initial_weights[-1].T))
Ejemplo n.º 15
0
def random_orthogonal(d, rng=None):

    rng = np.random if rng is None else rng
    m = UniformHypersphere(surface=True).sample(d, d, rng=rng)
    u, s, v = svd(m)
    return np.dot(u, v)
Ejemplo n.º 16
0
def test_distributions():
    check_init_args(PDF, ["x", "p"])
    check_repr(PDF([1, 2, 3], [0.1, 0.8, 0.1]))
    assert (repr(PDF(
        [1, 2], [0.4, 0.6])) == "PDF(x=array([1., 2.]), p=array([0.4, 0.6]))")

    check_init_args(Uniform, ["low", "high", "integer"])
    check_repr(Uniform(1, 3))
    check_repr(Uniform(1, 4, integer=True))
    assert repr(Uniform(0, 1)) == "Uniform(low=0, high=1)"
    assert repr(Uniform(
        0, 5, integer=True)) == "Uniform(low=0, high=5, integer=True)"

    check_init_args(Gaussian, ["mean", "std"])
    check_repr(Gaussian(0, 2))
    assert repr(Gaussian(1, 0.1)) == "Gaussian(mean=1, std=0.1)"

    check_init_args(Exponential, ["scale", "shift", "high"])
    check_repr(Exponential(2.0))
    check_repr(Exponential(2.0, shift=0.1))
    check_repr(Exponential(2.0, shift=0.1, high=10.0))
    assert repr(Exponential(2.0)) == "Exponential(scale=2.0)"

    check_init_args(UniformHypersphere, ["surface", "min_magnitude"])
    check_repr(UniformHypersphere())
    check_repr(UniformHypersphere(surface=True))
    check_repr(UniformHypersphere(min_magnitude=0.3))
    assert repr(UniformHypersphere()) == "UniformHypersphere()"
    assert repr(
        UniformHypersphere(surface=True)) == "UniformHypersphere(surface=True)"

    check_init_args(ScatteredHypersphere,
                    ["surface", "min_magnitude", "base", "method"])
    check_repr(ScatteredHypersphere())
    check_repr(ScatteredHypersphere(surface=True))
    check_repr(ScatteredHypersphere(min_magnitude=0.3))
    check_repr(ScatteredHypersphere(base=Uniform(0, 1)))
    check_repr(ScatteredHypersphere(method="tfww"))
    assert repr(ScatteredHypersphere()) == "ScatteredHypersphere()"
    assert (repr(ScatteredHypersphere(
        surface=True)) == "ScatteredHypersphere(surface=True)")
    assert (repr(ScatteredHypersphere(base=Uniform(0, 1), method="tfww")) ==
            "ScatteredHypersphere(base=Uniform(low=0, high=1), method='tfww')")

    check_init_args(Choice, ["options", "weights"])
    check_repr(Choice([3, 2, 1]))
    check_repr(Choice([3, 2, 1], weights=[0.1, 0.2, 0.7]))
    assert repr(Choice([1, 2, 3])) == "Choice(options=array([1., 2., 3.]))"
    assert (repr(
        Choice([1, 2, 3], weights=[0.1, 0.5, 0.4])
    ) == "Choice(options=array([1., 2., 3.]), weights=array([0.1, 0.5, 0.4]))")

    check_init_args(Samples, ["samples"])
    check_repr(Samples([3, 2, 1]))
    assert repr(Samples([3, 2, 1])) == "Samples(samples=array([3., 2., 1.]))"

    check_init_args(SqrtBeta, ["n", "m"])
    check_repr(SqrtBeta(3))
    check_repr(SqrtBeta(3, m=2))
    assert repr(SqrtBeta(3)) == "SqrtBeta(n=3)"
    assert repr(SqrtBeta(3, 2)) == "SqrtBeta(n=3, m=2)"

    check_init_args(SubvectorLength, ["dimensions", "subdimensions"])
    check_repr(SubvectorLength(6))
    check_repr(SubvectorLength(6, 2))
    assert repr(SubvectorLength(3)) == "SubvectorLength(dimensions=3)"

    check_init_args(CosineSimilarity, ["dimensions"])
    check_repr(CosineSimilarity(6))
    assert repr(CosineSimilarity(6)) == "CosineSimilarity(dimensions=6)"
Ejemplo n.º 17
0
def test_voja_encoders(Simulator, nl_nodirect, rng, seed, allclose):
    """Tests that voja changes active encoders to the input."""
    n = 200
    learned_vector = np.asarray([0.3, -0.4, 0.6])
    learned_vector /= np.linalg.norm(learned_vector)
    n_change = n // 2  # modify first half of the encoders

    # Set the first half to always fire with random encoders, and the
    # remainder to never fire due to their encoder's dot product with the input
    intercepts = np.asarray([-1] * n_change + [0.99] * (n - n_change))
    rand_encoders = UniformHypersphere(surface=True).sample(
        n_change, len(learned_vector), rng=rng)
    encoders = np.append(rand_encoders, [-learned_vector] * (n - n_change),
                         axis=0)

    m = nengo.Network(seed=seed)
    with m:
        m.config[nengo.Ensemble].neuron_type = nl_nodirect()
        u = nengo.Node(output=learned_vector)
        x = nengo.Ensemble(
            n,
            dimensions=len(learned_vector),
            intercepts=intercepts,
            encoders=encoders,
            max_rates=nengo.dists.Uniform(300.0, 400.0),
            radius=2.0,
        )  # to test encoder scaling

        conn = nengo.Connection(u,
                                x,
                                synapse=None,
                                learning_rule_type=Voja(learning_rate=1e-1))
        p_enc = nengo.Probe(conn.learning_rule, "scaled_encoders")
        p_enc_ens = nengo.Probe(x, "scaled_encoders")

    with Simulator(m) as sim:
        sim.run(1.0)
    t = sim.trange()
    tend = t > 0.5

    # Voja's rule relies on knowing exactly how the encoders were scaled
    # during the build process, because it modifies the scaled_encoders signal
    # proportional to this factor. Therefore, we should check that its
    # assumption actually holds.
    encoder_scale = (sim.data[x].gain / x.radius)[:, np.newaxis]
    assert allclose(sim.data[x].encoders,
                    sim.data[x].scaled_encoders / encoder_scale)

    # Check that the last half kept the same encoders throughout the simulation
    assert allclose(sim.data[p_enc][0, n_change:], sim.data[p_enc][:,
                                                                   n_change:])
    # and that they are also equal to their originally assigned value
    assert allclose(sim.data[p_enc][0, n_change:] / encoder_scale[n_change:],
                    -learned_vector)

    # Check that the first half converged to the input
    assert allclose(
        sim.data[p_enc][tend, :n_change] / encoder_scale[:n_change],
        learned_vector,
        atol=0.01,
    )
    # Check that encoders probed from ensemble equal encoders probed from Voja
    assert allclose(sim.data[p_enc], sim.data[p_enc_ens])
Ejemplo n.º 18
0
def test_hypersphere_dimension_fail(rng):
    with pytest.raises(ValueError):
        UniformHypersphere(0).sample(1, 0)
Ejemplo n.º 19
0
class Ensemble(NengoObject):
    """A group of neurons that collectively represent a vector.

    Parameters
    ----------
    n_neurons : int
        The number of neurons.
    dimensions : int
        The number of representational dimensions.

    radius : int, optional (Default: 1.0)
        The representational radius of the ensemble.
    encoders : Distribution or (n_neurons, dimensions) array_like, optional \
               (Default: UniformHypersphere(surface=True))
        The encoders used to transform from representational space
        to neuron space. Each row is a neuron's encoder; each column is a
        representational dimension.
    intercepts : Distribution or (n_neurons,) array_like, optional \
                 (Default: ``nengo.dists.Uniform(-1.0, 1.0)``)
        The point along each neuron's encoder where its activity is zero. If
        ``e`` is the neuron's encoder, then the activity will be zero when
        ``dot(x, e) <= c``, where ``c`` is the given intercept.
    max_rates : Distribution or (n_neurons,) array_like, optional \
                (Default: ``nengo.dists.Uniform(200, 400)``)
        The activity of each neuron when the input signal ``x`` is magnitude 1
        and aligned with that neuron's encoder ``e``;
        i.e., when ``dot(x, e) = 1``.
    eval_points : Distribution or (n_eval_points, dims) array_like, optional \
                  (Default: ``nengo.dists.UniformHypersphere()``)
        The evaluation points used for decoder solving, spanning the interval
        (-radius, radius) in each dimension, or a distribution from which
        to choose evaluation points.
    n_eval_points : int, optional (Default: None)
        The number of evaluation points to be drawn from the ``eval_points``
        distribution. If None, then a heuristic is used to determine
        the number of evaluation points.
    neuron_type : `~nengo.neurons.NeuronType`, optional \
                  (Default: ``nengo.LIF()``)
        The model that simulates all neurons in the ensemble
        (see `~nengo.neurons.NeuronType`).
    gain : Distribution or (n_neurons,) array_like (Default: None)
        The gains associated with each neuron in the ensemble. If None, then
        the gain will be solved for using ``max_rates`` and ``intercepts``.
    bias : Distribution or (n_neurons,) array_like (Default: None)
        The biases associated with each neuron in the ensemble. If None, then
        the gain will be solved for using ``max_rates`` and ``intercepts``.
    noise : Process, optional (Default: None)
        Random noise injected directly into each neuron in the ensemble
        as current. A sample is drawn for each individual neuron on
        every simulation step.
    normalize_encoders : bool, optional (Default: True)
        Indicates whether the encoders should be normalized.
    label : str, optional (Default: None)
        A name for the ensemble. Used for debugging and visualization.
    seed : int, optional (Default: None)
        The seed used for random number generation.

    Attributes
    ----------
    bias : Distribution or (n_neurons,) array_like or None
        The biases associated with each neuron in the ensemble.
    dimensions : int
        The number of representational dimensions.
    encoders : Distribution or (n_neurons, dimensions) array_like
        The encoders, used to transform from representational space
        to neuron space. Each row is a neuron's encoder, each column is a
        representational dimension.
    eval_points : Distribution or (n_eval_points, dims) array_like
        The evaluation points used for decoder solving, spanning the interval
        (-radius, radius) in each dimension, or a distribution from which
        to choose evaluation points.
    gain : Distribution or (n_neurons,) array_like or None
        The gains associated with each neuron in the ensemble.
    intercepts : Distribution or (n_neurons) array_like or None
        The point along each neuron's encoder where its activity is zero. If
        ``e`` is the neuron's encoder, then the activity will be zero when
        ``dot(x, e) <= c``, where ``c`` is the given intercept.
    label : str or None
        A name for the ensemble. Used for debugging and visualization.
    max_rates : Distribution or (n_neurons,) array_like or None
        The activity of each neuron when ``dot(x, e) = 1``,
        where ``e`` is the neuron's encoder.
    n_eval_points : int or None
        The number of evaluation points to be drawn from the ``eval_points``
        distribution. If None, then a heuristic is used to determine
        the number of evaluation points.
    n_neurons : int or None
        The number of neurons.
    neuron_type : NeuronType
        The model that simulates all neurons in the ensemble
        (see ``nengo.neurons``).
    noise : Process or None
        Random noise injected directly into each neuron in the ensemble
        as current. A sample is drawn for each individual neuron on
        every simulation step.
    radius : int
        The representational radius of the ensemble.
    seed : int or None
        The seed used for random number generation.
    """

    probeable = ('decoded_output', 'input', 'scaled_encoders')

    n_neurons = IntParam('n_neurons', low=1)
    dimensions = IntParam('dimensions', low=1)
    radius = NumberParam('radius', default=1.0, low=1e-10)
    encoders = DistOrArrayParam('encoders',
                                default=UniformHypersphere(surface=True),
                                sample_shape=('n_neurons', 'dimensions'))
    intercepts = DistOrArrayParam('intercepts',
                                  default=Uniform(-1.0, 1.0),
                                  optional=True,
                                  sample_shape=('n_neurons', ))
    max_rates = DistOrArrayParam('max_rates',
                                 default=Uniform(200, 400),
                                 optional=True,
                                 sample_shape=('n_neurons', ))
    eval_points = DistOrArrayParam('eval_points',
                                   default=UniformHypersphere(),
                                   sample_shape=('*', 'dimensions'))
    n_eval_points = IntParam('n_eval_points', default=None, optional=True)
    neuron_type = NeuronTypeParam('neuron_type', default=LIF())
    gain = DistOrArrayParam('gain',
                            default=None,
                            optional=True,
                            sample_shape=('n_neurons', ))
    bias = DistOrArrayParam('bias',
                            default=None,
                            optional=True,
                            sample_shape=('n_neurons', ))
    noise = ProcessParam('noise', default=None, optional=True)
    normalize_encoders = BoolParam('normalize_encoders',
                                   default=True,
                                   optional=True)

    def __init__(self,
                 n_neurons,
                 dimensions,
                 radius=Default,
                 encoders=Default,
                 intercepts=Default,
                 max_rates=Default,
                 eval_points=Default,
                 n_eval_points=Default,
                 neuron_type=Default,
                 gain=Default,
                 bias=Default,
                 noise=Default,
                 normalize_encoders=Default,
                 label=Default,
                 seed=Default):
        super(Ensemble, self).__init__(label=label, seed=seed)
        self.n_neurons = n_neurons
        self.dimensions = dimensions
        self.radius = radius
        self.encoders = encoders
        self.intercepts = intercepts
        self.max_rates = max_rates
        self.n_eval_points = n_eval_points
        self.eval_points = eval_points
        self.bias = bias
        self.gain = gain
        self.neuron_type = neuron_type
        self.noise = noise
        self.normalize_encoders = normalize_encoders

    def __getitem__(self, key):
        return ObjView(self, key)

    def __len__(self):
        return self.dimensions

    @property
    def neurons(self):
        """A direct interface to the neurons in the ensemble."""
        return Neurons(self)

    @neurons.setter
    def neurons(self, dummy):
        raise ReadonlyError(attr="neurons", obj=self)

    @property
    def size_in(self):
        """The dimensionality of the ensemble."""
        return self.dimensions

    @property
    def size_out(self):
        """The dimensionality of the ensemble."""
        return self.dimensions
Ejemplo n.º 20
0
def test_hypersphere_warns(rng):
    with pytest.warns(UserWarning):
        UniformHypersphere(surface=True, min_magnitude=0.1)
Ejemplo n.º 21
0
class Ensemble(NengoObject):
    """A group of neurons that collectively represent a vector.

    Parameters
    ----------
    n_neurons : int
        The number of neurons.
    dimensions : int
        The number of representational dimensions.
    radius : int, optional
        The representational radius of the ensemble.
    encoders : Distribution or ndarray (`n_neurons`, `dimensions`), optional
        The encoders, used to transform from representational space
        to neuron space. Each row is a neuron's encoder, each column is a
        representational dimension.
    intercepts : Distribution or ndarray (`n_neurons`), optional
        The point along each neuron's encoder where its activity is zero. If
        e is the neuron's encoder, then the activity will be zero when
        dot(x, e) <= c, where c is the given intercept.
    max_rates : Distribution or ndarray (`n_neurons`), optional
        The activity of each neuron when dot(x, e) = 1, where e is the neuron's
        encoder.
    eval_points : Distribution or ndarray (`n_eval_points`, `dims`), optional
        The evaluation points used for decoder solving, spanning the interval
        (-radius, radius) in each dimension, or a distribution from which to
        choose evaluation points. Default: ``UniformHypersphere``.
    n_eval_points : int, optional
        The number of evaluation points to be drawn from the `eval_points`
        distribution. If None (the default), then a heuristic is used to
        determine the number of evaluation points.
    neuron_type : Neurons, optional
        The model that simulates all neurons in the ensemble.
    noise : StochasticProcess, optional
        Random noise injected directly into each neuron in the ensemble
        as current. A sample is drawn for each individual neuron on
        every simulation step.
    seed : int, optional
        The seed used for random number generation.
    label : str, optional
        A name for the ensemble. Used for debugging and visualization.
    """

    n_neurons = IntParam(default=None, low=1)
    dimensions = IntParam(default=None, low=1)
    radius = NumberParam(default=1, low=1e-10)
    neuron_type = NeuronTypeParam(default=LIF())
    encoders = DistributionParam(default=UniformHypersphere(surface=True),
                                 sample_shape=('n_neurons', 'dimensions'))
    intercepts = DistributionParam(default=Uniform(-1.0, 1.0),
                                   optional=True,
                                   sample_shape=('n_neurons', ))
    max_rates = DistributionParam(default=Uniform(200, 400),
                                  optional=True,
                                  sample_shape=('n_neurons', ))
    n_eval_points = IntParam(default=None, optional=True)
    eval_points = DistributionParam(default=UniformHypersphere(),
                                    sample_shape=('*', 'dimensions'))
    bias = DistributionParam(default=None,
                             optional=True,
                             sample_shape=('n_neurons', ))
    gain = DistributionParam(default=None,
                             optional=True,
                             sample_shape=('n_neurons', ))
    noise = StochasticProcessParam(default=None, optional=True)
    seed = IntParam(default=None, optional=True)
    label = StringParam(default=None, optional=True)

    def __init__(self,
                 n_neurons,
                 dimensions,
                 radius=Default,
                 encoders=Default,
                 intercepts=Default,
                 max_rates=Default,
                 eval_points=Default,
                 n_eval_points=Default,
                 neuron_type=Default,
                 gain=Default,
                 bias=Default,
                 noise=Default,
                 seed=Default,
                 label=Default):

        self.n_neurons = n_neurons
        self.dimensions = dimensions
        self.radius = radius
        self.encoders = encoders
        self.intercepts = intercepts
        self.max_rates = max_rates
        self.label = label
        self.n_eval_points = n_eval_points
        self.eval_points = eval_points
        self.bias = bias
        self.gain = gain
        self.neuron_type = neuron_type
        self.noise = noise
        self.seed = seed
        self._neurons = Neurons(self)

    def __getitem__(self, key):
        return ObjView(self, key)

    def __len__(self):
        return self.dimensions

    @property
    def neurons(self):
        return self._neurons

    @neurons.setter
    def neurons(self, dummy):
        raise AttributeError("neurons cannot be overwritten.")

    @property
    def probeable(self):
        return ["decoded_output", "input"]

    @property
    def size_in(self):
        return self.dimensions

    @property
    def size_out(self):
        return self.dimensions
Ejemplo n.º 22
0
def test_scattered_hypersphere(dims, surface, seed, plt):
    scipy_special = pytest.importorskip("scipy.special")

    n = 3000
    dists = [
        UniformHypersphere(surface=surface),
        ScatteredHypersphere(surface=surface, method="sct"),
        ScatteredHypersphere(surface=surface, method="sct-approx"),
        ScatteredHypersphere(surface=surface, method="tfww"),
    ]
    assert isinstance(dists[0], UniformHypersphere)

    xx = []  # generated points, for each dist
    times = []  # time taken to generate the points, for each dist
    for dist in dists:
        rng = np.random.RandomState(seed)
        timer = time.time()
        x = dist.sample(n, d=dims, rng=rng)
        timer = time.time() - timer
        rng.shuffle(x)  # shuffle so we can compute distances in blocks without bias
        xx.append(x)
        times.append(timer)

    dd = []  # distance to the nearest point for each point, for each dist
    rr = []  # radii (norms) of all the generated points, for each dist
    for x in xx:
        # compute distances in blocks for efficiency (this means we're not actually
        # getting the minimum distance, just a proxy)
        n_split = 1000
        d_min = []
        for i in range(0, n, n_split):
            xi = x[i : i + n_split]
            d2 = ((xi[:, :, None] - xi.T[None, :, :]) ** 2).sum(axis=1)
            np.fill_diagonal(d2, np.inf)
            d_min.append(np.sqrt(d2.min(axis=1)))
        d_min = np.concatenate(d_min)
        dd.append(d_min)
        rr.append(np.sqrt((x ** 2).sum(axis=1)))

    # compute the approximate distance between points if they were evenly spread
    volume = np.pi ** (0.5 * dims) / scipy_special.gamma(0.5 * dims + 1)
    if surface:
        volume *= dims
    even_distance = (volume / n) ** (1 / (dims - 1 if surface else dims))

    # --- plots
    colors = ["b", "g", "r", "m", "c"]

    plt.subplot(211)
    bins = np.linspace(np.min(dd), np.max(dd), 31)
    for i, d in enumerate(dd):
        histogram, _ = np.histogram(d, bins=bins)
        plt.plot(
            0.5 * (bins[:-1] + bins[1:]),
            histogram,
            colors[i],
        )
        plt.plot([d.min()], [0], colors[i] + "x")
    plt.plot([even_distance], [0], "kx")
    plt.title("surface=%s, dims=%d, n=%d" % (surface, dims, n))

    plt.subplot(212)
    bins = np.linspace(0, 1.1, 31)
    for i, r in enumerate(rr):
        histogram, _ = np.histogram(r, bins=bins)
        plt.plot(
            0.5 * (bins[:-1] + bins[1:]),
            histogram,
            colors[i],
            label=f"{dists[i]}: t={times[i]:0.2e}",
        )
    plt.legend()

    # --- checks
    uniform_min = dd[0].min()
    for i, dist in enumerate(dists):
        if i == 0:
            continue

        # check that we're significantly better than UniformHypersphere
        d_min = dd[i].min()
        assert d_min > 1.2 * uniform_min, str(dist)

        # check that all surface points are on the surface
        if surface:
            assert np.allclose(rr[i], 1.0, atol=1e-5), str(dist)