Пример #1
0
    def __init__(self,
                 n_neurons,
                 dimensions,
                 radius=1.0,
                 encoders=nengo.Default,
                 **ens_kwargs):
        super(Product, self).__init__(self)

        with self:
            self.config[nengo.Ensemble].update(ens_kwargs)
            self.A = nengo.Node(size_in=dimensions, label="A")
            self.B = nengo.Node(size_in=dimensions, label="B")
            self.dimensions = dimensions

            if encoders is nengo.Default:
                encoders = Choice([[1, 1], [1, -1], [-1, 1], [-1, -1]])

            optimizer = SubvectorRadiusOptimizer(n_neurons,
                                                 2,
                                                 ens_kwargs=ens_kwargs)
            scaled_r = radius * optimizer.find_optimal_radius(dimensions, 1)

            self.product = EnsembleArray(n_neurons,
                                         n_ensembles=dimensions,
                                         ens_dimensions=2,
                                         radius=scaled_r,
                                         encoders=encoders,
                                         **ens_kwargs)

            nengo.Connection(self.A, self.product.input[::2], synapse=None)
            nengo.Connection(self.B, self.product.input[1::2], synapse=None)

            self.output = self.product.add_output('product',
                                                  lambda x: x[0] * x[1])
Пример #2
0
    def __init__(self, n_neurons, dimensions,
                 radius=1, encoders=nengo.Default, **ens_kwargs):
        self.config[nengo.Ensemble].update(ens_kwargs)
        self.A = nengo.Node(size_in=dimensions, label="A")
        self.B = nengo.Node(size_in=dimensions, label="B")
        self.output = nengo.Node(size_in=dimensions, label="output")
        self.dimensions = dimensions

        if encoders is nengo.Default:
            encoders = np.tile(
                [[1, 1], [1, -1], [-1, 1], [-1, -1]],
                ((n_neurons // 4) + 1, 1))[:n_neurons]

        self.product = EnsembleArray(
            n_neurons, n_ensembles=dimensions, ens_dimensions=2,
            encoders=encoders, radius=np.sqrt(2) * radius)

        nengo.Connection(
            self.A, self.product.input[::2], synapse=None)
        nengo.Connection(
            self.B, self.product.input[1::2], synapse=None)

        nengo.Connection(
            self.product.add_output('product', lambda x: x[0] * x[1]),
            self.output, synapse=None)
Пример #3
0
    def __init__(self,
                 neurons,
                 dimensions,
                 radius=1,
                 encoders=None,
                 **ens_kwargs):
        self.A = nengo.Node(size_in=dimensions, label="A")
        self.B = nengo.Node(size_in=dimensions, label="B")
        self.output = nengo.Node(size_in=dimensions, label="output")
        self.dimensions = dimensions

        if encoders is None and not isinstance(neurons, nengo.Direct):
            encoders = np.tile(
                [[1, 1], [1, -1], [-1, 1], [-1, -1]],
                ((neurons.n_neurons / 4) + 1, 1))[:neurons.n_neurons]
        else:
            encoders = None

        self.product = EnsembleArray(neurons,
                                     n_ensembles=dimensions,
                                     ens_dimensions=2,
                                     encoders=encoders,
                                     radius=np.sqrt(2) * radius,
                                     **ens_kwargs)

        nengo.Connection(self.A, self.product.input[::2], synapse=None)
        nengo.Connection(self.B, self.product.input[1::2], synapse=None)

        nengo.Connection(self.product.add_output('product',
                                                 lambda x: x[0] * x[1]),
                         self.output,
                         synapse=None)
Пример #4
0
    def __init__(self, n_neurons, dimensions, input_magnitude=1.0, **kwargs):
        if "net" in kwargs:
            raise ObsoleteError("The 'net' argument is no longer supported.")
        kwargs.setdefault("label", "Product")
        super().__init__(**kwargs)

        with self:
            self.input_a = nengo.Node(size_in=dimensions, label="input_a")
            self.input_b = nengo.Node(size_in=dimensions, label="input_b")
            self.output = nengo.Node(size_in=dimensions, label="output")

            self.sq1 = EnsembleArray(
                max(1, n_neurons // 2),
                n_ensembles=dimensions,
                ens_dimensions=1,
                radius=input_magnitude * np.sqrt(2),
            )
            self.sq2 = EnsembleArray(
                max(1, n_neurons // 2),
                n_ensembles=dimensions,
                ens_dimensions=1,
                radius=input_magnitude * np.sqrt(2),
            )

            tr = 1.0 / np.sqrt(2.0)
            nengo.Connection(self.input_a,
                             self.sq1.input,
                             transform=tr,
                             synapse=None)
            nengo.Connection(self.input_b,
                             self.sq1.input,
                             transform=tr,
                             synapse=None)
            nengo.Connection(self.input_a,
                             self.sq2.input,
                             transform=tr,
                             synapse=None)
            nengo.Connection(self.input_b,
                             self.sq2.input,
                             transform=-tr,
                             synapse=None)

            sq1_out = self.sq1.add_output("square", np.square)
            nengo.Connection(sq1_out, self.output, transform=0.5, synapse=None)
            sq2_out = self.sq2.add_output("square", np.square)
            nengo.Connection(sq2_out,
                             self.output,
                             transform=-0.5,
                             synapse=None)
Пример #5
0
def Thalamus(dimensions,
             n_neurons_per_ensemble=50,
             mutual_inhib=1,
             threshold=0,
             net=None):
    """Inhibits non-selected actions.

    Converts basal ganglia output into a signal with
    (approximately) 1 for the selected action and 0 elsewhere.
    """

    if net is None:
        net = nengo.Network("Thalamus")

    with net:
        net.actions = EnsembleArray(n_neurons_per_ensemble,
                                    dimensions,
                                    intercepts=Uniform(threshold, 1),
                                    encoders=Choice([[1.0]]),
                                    label="actions")
        nengo.Connection(net.actions.output,
                         net.actions.input,
                         transform=(np.eye(dimensions) - 1) * mutual_inhib)
        net.bias = nengo.Node([1], label="thalamus bias")
        nengo.Connection(net.bias,
                         net.actions.input,
                         transform=np.ones((dimensions, 1)))

    net.input = net.actions.input
    net.output = net.actions.output
    return net
Пример #6
0
    def __init__(
            self, n_neurons, dimensions, radius=1.0,
            encoders=nengo.Default, **ens_kwargs):
        super(Product, self).__init__(self)

        with self:
            self.config[nengo.Ensemble].update(ens_kwargs)
            self.A = nengo.Node(size_in=dimensions, label="A")
            self.B = nengo.Node(size_in=dimensions, label="B")
            self.dimensions = dimensions

            if encoders is nengo.Default:
                encoders = Choice([[1, 1], [1, -1], [-1, 1], [-1, -1]])

            optimizer = SubvectorRadiusOptimizer(
                n_neurons, 2, ens_kwargs=ens_kwargs)
            scaled_r = radius * optimizer.find_optimal_radius(dimensions, 1)

            self.product = EnsembleArray(
                n_neurons, n_ensembles=dimensions, ens_dimensions=2,
                radius=scaled_r, encoders=encoders, **ens_kwargs)

            nengo.Connection(
                self.A, self.product.input[::2], synapse=None)
            nengo.Connection(
                self.B, self.product.input[1::2], synapse=None)

            self.output = self.product.add_output(
                'product', lambda x: x[0] * x[1])
Пример #7
0
class Product(nengo.Network):
    """Computes the element-wise product of two equally sized vectors."""

    def __init__(self, n_neurons, dimensions,
                 radius=1, encoders=nengo.Default, **ens_kwargs):
        self.config[nengo.Ensemble].update(ens_kwargs)
        self.A = nengo.Node(size_in=dimensions, label="A")
        self.B = nengo.Node(size_in=dimensions, label="B")
        self.dimensions = dimensions

        if encoders is nengo.Default:
            encoders = Choice([[1, 1], [1, -1], [-1, 1], [-1, -1]])

        self.product = EnsembleArray(
            n_neurons, n_ensembles=dimensions, ens_dimensions=2,
            encoders=encoders, radius=np.sqrt(2) * radius)

        nengo.Connection(
            self.A, self.product.input[0::2], synapse=None)
        nengo.Connection(
            self.B, self.product.input[1::2], synapse=None)

        self.output = self.product.add_output('product', lambda x: x[0] * x[1])

    def dot_product_transform(self, scale=1.0):
        """Returns a transform for output to compute the scaled dot product."""
        return scale*np.ones((1, self.dimensions))
Пример #8
0
    def __init__(self,
                 dimensions,
                 n_neurons_per_ensemble=50,
                 mutual_inhib=1.0,
                 threshold=0.0,
                 **kwargs):
        if "net" in kwargs:
            raise ObsoleteError("The 'net' argument is no longer supported.")
        kwargs.setdefault("label", "Thalamus")
        super().__init__(**kwargs)

        with self:
            self.actions = EnsembleArray(
                n_neurons_per_ensemble,
                dimensions,
                intercepts=Uniform(threshold, 1),
                encoders=Choice([[1.0]]),
                label="actions",
            )
            nengo.Connection(
                self.actions.output,
                self.actions.input,
                transform=(np.eye(dimensions) - 1) * mutual_inhib,
            )
            self.bias = nengo.Node([1], label="thalamus bias")
            nengo.Connection(self.bias,
                             self.actions.input,
                             transform=np.ones((dimensions, 1)))

        self.input = self.actions.input
        self.output = self.actions.output
Пример #9
0
class Product(nengo.Network):
    """Computes the element-wise product of two equally sized vectors."""

    def __init__(self, n_neurons, dimensions,
                 radius=1, encoders=nengo.Default, **ens_kwargs):
        self.config[nengo.Ensemble].update(ens_kwargs)
        self.A = nengo.Node(size_in=dimensions, label="A")
        self.B = nengo.Node(size_in=dimensions, label="B")
        self.output = nengo.Node(size_in=dimensions, label="output")
        self.dimensions = dimensions

        if encoders is nengo.Default:
            encoders = np.tile(
                [[1, 1], [1, -1], [-1, 1], [-1, -1]],
                ((n_neurons // 4) + 1, 1))[:n_neurons]

        self.product = EnsembleArray(
            n_neurons, n_ensembles=dimensions, ens_dimensions=2,
            encoders=encoders, radius=np.sqrt(2) * radius)

        nengo.Connection(
            self.A, self.product.input[::2], synapse=None)
        nengo.Connection(
            self.B, self.product.input[1::2], synapse=None)

        nengo.Connection(
            self.product.add_output('product', lambda x: x[0] * x[1]),
            self.output, synapse=None)

    def dot_product_transform(self, scale=1.0):
        """Returns a transform for output to compute the scaled dot product."""
        return scale*np.ones((1, self.dimensions))
Пример #10
0
def Product_2D_ens(n_neurons,
                   dimensions,
                   input_magnitude=1,
                   config=None,
                   net=None):
    """Computes the element-wise product of two equally sized vectors."""
    if net is None:
        net = nengo.Network(label="Product")

    if config is None:
        config = nengo.Config(nengo.Ensemble)
        config[nengo.Ensemble].encoders = Choice([[1, 1], [1, -1], [-1, 1],
                                                  [-1, -1]])

    with net, config:
        net.A = nengo.Node(size_in=dimensions, label="A")
        net.B = nengo.Node(size_in=dimensions, label="B")
        net.output = nengo.Node(size_in=dimensions, label="output")

        net.product = EnsembleArray(n_neurons,
                                    n_ensembles=dimensions,
                                    ens_dimensions=2,
                                    radius=input_magnitude * np.sqrt(2))
        nengo.Connection(net.A, net.product.input[::2], synapse=None)
        nengo.Connection(net.B, net.product.input[1::2], synapse=None)
        net.output = net.product.add_output('product', lambda x: x[0] * x[1])
    return net
Пример #11
0
    def __init__(self, neurons, dimensions, radius=1, encoders=None,
                 **ens_kwargs):
        self.A = nengo.Node(size_in=dimensions, label="A")
        self.B = nengo.Node(size_in=dimensions, label="B")
        self.output = nengo.Node(size_in=dimensions, label="output")
        self.dimensions = dimensions

        if encoders is None and not isinstance(neurons, nengo.Direct):
            encoders = np.tile(
                [[1, 1], [1, -1], [-1, 1], [-1, -1]],
                ((neurons.n_neurons / 4) + 1, 1))[:neurons.n_neurons]
        else:
            encoders = None

        self.product = EnsembleArray(
            neurons, n_ensembles=dimensions, ens_dimensions=2,
            encoders=encoders, radius=np.sqrt(2) * radius, **ens_kwargs)

        nengo.Connection(
            self.A, self.product.input[::2], synapse=None)
        nengo.Connection(
            self.B, self.product.input[1::2], synapse=None)

        nengo.Connection(
            self.product.add_output('product', lambda x: x[0] * x[1]),
            self.output, synapse=None)
Пример #12
0
class Product(nengo.Network):
    """Computes the element-wise product of two equally sized vectors."""

    def __init__(self, neurons, dimensions, radius=1, encoders=None,
                 **ens_kwargs):
        self.A = nengo.Node(size_in=dimensions, label="A")
        self.B = nengo.Node(size_in=dimensions, label="B")
        self.output = nengo.Node(size_in=dimensions, label="output")
        self.dimensions = dimensions

        if encoders is None and not isinstance(neurons, nengo.Direct):
            encoders = np.tile(
                [[1, 1], [1, -1], [-1, 1], [-1, -1]],
                ((neurons.n_neurons / 4) + 1, 1))[:neurons.n_neurons]
        else:
            encoders = None

        self.product = EnsembleArray(
            neurons, n_ensembles=dimensions, ens_dimensions=2,
            encoders=encoders, radius=np.sqrt(2) * radius, **ens_kwargs)

        nengo.Connection(
            self.A, self.product.input[::2], synapse=None)
        nengo.Connection(
            self.B, self.product.input[1::2], synapse=None)

        nengo.Connection(
            self.product.add_output('product', lambda x: x[0] * x[1]),
            self.output, synapse=None)

    def dot_product_transform(self, scale=1.0):
        """Returns a transform for output to compute the scaled dot product."""
        return scale*np.ones((1, self.dimensions))
Пример #13
0
class Product(nengo.Network):
    """Computes the element-wise product of two (scaled) unit vectors.

    Requires Scipy.
    """

    # def __init__(self, n_neurons, dimensions, radius=1.0,
    #              n_eval_points=nengo.Default, eval_points=nengo.Default,
    #              encoders=nengo.Default, **ens_kwargs):
    def __init__(self, n_neurons, dimensions, radius=np.sqrt(2.0), encoders=nengo.Default, **ens_kwargs):
        self.A = nengo.Node(size_in=dimensions, label="A")
        self.B = nengo.Node(size_in=dimensions, label="B")
        self.dimensions = dimensions

        if encoders is nengo.Default:
            encoders = Choice([[1, 1], [1, -1], [-1, 1], [-1, -1]])

        self.product = EnsembleArray(
            n_neurons,
            n_ensembles=dimensions,
            ens_dimensions=2,
            encoders=encoders,
            radius=np.sqrt(2) * radius,
            **ens_kwargs
        )

        nengo.Connection(self.A, self.product.input[0::2], synapse=None)
        nengo.Connection(self.B, self.product.input[1::2], synapse=None)

        self.output = self.product.add_output("product", lambda x: x[0] * x[1])
Пример #14
0
    def make(self, neurons, dimensions, radius=1,
             invert_a=False, invert_b=False):
        self.transformA = self._input_transform(
            dimensions, first=True, invert=invert_a)
        self.transformB = self._input_transform(
            dimensions, first=False, invert=invert_b)
        self.transformC = self._output_transform(dimensions)

        self.A = nengo.Node(size_in=dimensions, label='A')
        self.B = nengo.Node(size_in=dimensions, label='B')
        self.ensemble = EnsembleArray(neurons,
                                      self.transformC.shape[1],
                                      dimensions=2,
                                      radius=radius, label='conv')
        self.output = nengo.Node(size_in=dimensions, label='output')

        for ens in self.ensemble.ensembles:
            if not isinstance(neurons, nengo.Direct):
                ens.encoders = np.tile(
                    [[1, 1], [-1, 1], [1, -1], [-1, -1]],
                    (ens.n_neurons // 4, 1))
        nengo.Connection(
            self.A, self.ensemble.input, transform=self.transformA,
            filter=None)
        nengo.Connection(
            self.B, self.ensemble.input, transform=self.transformB,
            filter=None)
        nengo.Connection(self.ensemble.add_output('product', self.product),
                         self.output,
                         filter=None,
                         transform=self.transformC)
Пример #15
0
    def __init__(self, neurons, dimensions, kernel=None,
            input_transform=None):
        self.kernel = kernel if kernel is not None else self.product
        self.dimensions = dimensions
        self.A = nengo.Node(size_in=dimensions, label='A')
        self.B = nengo.Node(size_in=dimensions, label='B')
        self.ensemble = EnsembleArray(neurons,
                n_ensembles=dimensions,
                dimensions=2,
                radius=1,
                label='elementwise_operation')
        self.output = nengo.Node(size_in=dimensions, label='output')

        if input_transform is None:
            self.input_transform = self.elementwise_comparator_transform
        else:
            self.input_transform = input_transform


        for ens in self.ensemble.ensembles:
            if not isinstance(neurons, nengo.Direct):
                ens.encoders = corners(ens.n_neurons)
        nengo.Connection(self.A, self.ensemble.input, synapse=None,
                transform=self.input_transform)
        nengo.Connection(self.B, self.ensemble.input, synapse=None,
                transform=self.input_transform)
        nengo.Connection(self.ensemble.add_output('result', self.kernel),
                self.output)
Пример #16
0
    def __init__(
        self,
        vocab=Default,
        subdimensions=Default,
        neurons_per_dimension=Default,
        feedback=Default,
        represent_cc_identity=Default,
        feedback_synapse=Default,
        **kwargs
    ):
        super(State, self).__init__(**kwargs)

        self.vocab = vocab
        self.subdimensions = subdimensions
        self.neurons_per_dimension = neurons_per_dimension
        self.feedback = feedback
        self.feedback_synapse = feedback_synapse
        self.represent_cc_identity = represent_cc_identity

        dimensions = self.vocab.dimensions

        if dimensions % self.subdimensions != 0:
            raise ValidationError(
                "Dimensions (%d) must be divisible by subdimensions (%d)"
                % (dimensions, self.subdimensions),
                attr="dimensions",
                obj=self,
            )

        with self:
            if self.represent_cc_identity:
                self.state_ensembles = IdentityEnsembleArray(
                    self.neurons_per_dimension,
                    dimensions,
                    self.subdimensions,
                    label="state",
                )
            else:
                self.state_ensembles = EnsembleArray(
                    self.neurons_per_dimension * self.subdimensions,
                    dimensions // self.subdimensions,
                    ens_dimensions=self.subdimensions,
                    eval_points=nengo.dists.CosineSimilarity(dimensions + 2),
                    intercepts=nengo.dists.CosineSimilarity(dimensions + 2),
                    label="state",
                )

            if self.feedback is not None and self.feedback != 0.0:
                nengo.Connection(
                    self.state_ensembles.output,
                    self.state_ensembles.input,
                    transform=self.feedback,
                    synapse=self.feedback_synapse,
                )

        self.input = self.state_ensembles.input
        self.output = self.state_ensembles.output
        self.declare_input(self.input, self.vocab)
        self.declare_output(self.output, self.vocab)
Пример #17
0
    def __init__(
        self,
        dimensions,
        subdimensions=16,
        neurons_per_dimension=50,
        feedback=0.0,
        feedback_synapse=0.1,
        vocab=None,
        label=None,
        seed=None,
        add_to_container=None,
    ):
        super().__init__(label, seed, add_to_container)

        if vocab is None:
            # use the default one for this dimensionality
            vocab = dimensions
        elif vocab.dimensions != dimensions:
            raise ValidationError(
                "Dimensionality of given vocabulary (%d) does not "
                "match dimensionality of buffer (%d)" %
                (vocab.dimensions, dimensions),
                attr="dimensions",
                obj=self,
            )

        # Subdimensions should be at most the number of dimensions
        subdimensions = min(dimensions, subdimensions)

        if dimensions % subdimensions != 0:
            raise ValidationError(
                "Dimensions (%d) must be divisible by subdimensions (%d)" %
                (dimensions, subdimensions),
                attr="dimensions",
                obj=self,
            )

        with self:
            self.state_ensembles = EnsembleArray(
                neurons_per_dimension * subdimensions,
                dimensions // subdimensions,
                ens_dimensions=subdimensions,
                radius=np.sqrt(float(subdimensions) / dimensions),
                label="state",
            )
            self.input = self.state_ensembles.input
            self.output = self.state_ensembles.output

        self.inputs = dict(default=(self.input, vocab))
        self.outputs = dict(default=(self.output, vocab))

        with self:
            if feedback is not None and feedback != 0.0:
                nengo.Connection(
                    self.output,
                    self.input,
                    transform=feedback,
                    synapse=feedback_synapse,
                )
Пример #18
0
def Product(n_neurons, dimensions, input_magnitude=1, config=None, net=None):
    """Computes the element-wise product of two equally sized vectors.

    The network used to calculate the product is described in
    `Precise multiplications with the NEF
    <http://nbviewer.ipython.org/github/ctn-archive/technical-reports/blob/master/Precise-multiplications-with-the-NEF.ipynb#An-alternative-network>`_.

    A simpler version of this network can be found in the `Multiplication
    example <http://pythonhosted.org/nengo/examples/multiplication.html>`_.
    """
    if net is None:
        net = nengo.Network(label="Product")

    if config is None:
        config = nengo.Config(nengo.Ensemble)

    with nested(net, config):
        net.A = nengo.Node(size_in=dimensions, label="A")
        net.B = nengo.Node(size_in=dimensions, label="B")
        net.output = nengo.Node(size_in=dimensions, label="output")

        net.sq1 = EnsembleArray(max(1, n_neurons // 2),
                                n_ensembles=dimensions,
                                ens_dimensions=1,
                                radius=input_magnitude * np.sqrt(2))
        net.sq2 = EnsembleArray(max(1, n_neurons // 2),
                                n_ensembles=dimensions,
                                ens_dimensions=1,
                                radius=input_magnitude * np.sqrt(2))

        tr = 1. / np.sqrt(2.)
        nengo.Connection(net.A, net.sq1.input, transform=tr, synapse=None)
        nengo.Connection(net.B, net.sq1.input, transform=tr, synapse=None)
        nengo.Connection(net.A, net.sq2.input, transform=tr, synapse=None)
        nengo.Connection(net.B, net.sq2.input, transform=-tr, synapse=None)

        sq1_out = net.sq1.add_output('square', np.square)
        nengo.Connection(sq1_out, net.output, transform=.5)
        sq2_out = net.sq2.add_output('square', np.square)
        nengo.Connection(sq2_out, net.output, transform=-.5)

    return net
Пример #19
0
    def __init__(self, n_neurons, dimensions, input_magnitude=1., **kwargs):
        if 'net' in kwargs:
            raise ObsoleteError("The 'net' argument is no longer supported.")
        kwargs.setdefault('label', "Product")
        super().__init__(**kwargs)

        with self:
            self.input_a = nengo.Node(size_in=dimensions, label="input_a")
            self.input_b = nengo.Node(size_in=dimensions, label="input_b")
            self.output = nengo.Node(size_in=dimensions, label="output")

            self.sq1 = EnsembleArray(
                max(1, n_neurons // 2),
                n_ensembles=dimensions,
                ens_dimensions=1,
                radius=input_magnitude * np.sqrt(2),
            )
            self.sq2 = EnsembleArray(
                max(1, n_neurons // 2),
                n_ensembles=dimensions,
                ens_dimensions=1,
                radius=input_magnitude * np.sqrt(2),
            )

            tr = 1. / np.sqrt(2.)
            nengo.Connection(
                self.input_a, self.sq1.input, transform=tr, synapse=None)
            nengo.Connection(
                self.input_b, self.sq1.input, transform=tr, synapse=None)
            nengo.Connection(
                self.input_a, self.sq2.input, transform=tr, synapse=None)
            nengo.Connection(
                self.input_b, self.sq2.input, transform=-tr, synapse=None)

            sq1_out = self.sq1.add_output('square', np.square)
            nengo.Connection(sq1_out, self.output, transform=.5, synapse=None)
            sq2_out = self.sq2.add_output('square', np.square)
            nengo.Connection(sq2_out, self.output, transform=-.5, synapse=None)
Пример #20
0
class Product(nengo.Network):
    """Computes the element-wise product of two (scaled) unit vectors.

    Requires Scipy.
    """
    def __init__(self,
                 n_neurons,
                 dimensions,
                 radius=1.0,
                 encoders=nengo.Default,
                 **ens_kwargs):
        super(Product, self).__init__(self)

        with self:
            self.config[nengo.Ensemble].update(ens_kwargs)
            self.A = nengo.Node(size_in=dimensions, label="A")
            self.B = nengo.Node(size_in=dimensions, label="B")
            self.dimensions = dimensions

            if encoders is nengo.Default:
                encoders = Choice([[1, 1], [1, -1], [-1, 1], [-1, -1]])

            optimizer = SubvectorRadiusOptimizer(n_neurons,
                                                 2,
                                                 ens_kwargs=ens_kwargs)
            scaled_r = radius * optimizer.find_optimal_radius(dimensions, 1)

            self.product = EnsembleArray(n_neurons,
                                         n_ensembles=dimensions,
                                         ens_dimensions=2,
                                         radius=scaled_r,
                                         encoders=encoders,
                                         **ens_kwargs)

            nengo.Connection(self.A, self.product.input[::2], synapse=None)
            nengo.Connection(self.B, self.product.input[1::2], synapse=None)

            self.output = self.product.add_output('product',
                                                  lambda x: x[0] * x[1])

    def dot_product_transform(self, scale=1.0):
        """Returns a transform for output to compute the scaled dot product."""
        return scale * np.ones((1, self.dimensions))
Пример #21
0
class BinaryElementwiseOperation(nengo.Network):
    '''Handles splitting high-dimensions stuff into ensemble arrays
    which each handle one 'dimension' or 'element'.
    the x.output object is of the same dimensions as the inputs'''
    def __init__(self, neurons, dimensions, kernel=None,
            input_transform=None):
        self.kernel = kernel if kernel is not None else self.product
        self.dimensions = dimensions
        self.A = nengo.Node(size_in=dimensions, label='A')
        self.B = nengo.Node(size_in=dimensions, label='B')
        self.ensemble = EnsembleArray(neurons,
                n_ensembles=dimensions,
                dimensions=2,
                radius=1,
                label='elementwise_operation')
        self.output = nengo.Node(size_in=dimensions, label='output')

        if input_transform is None:
            self.input_transform = self.elementwise_comparator_transform
        else:
            self.input_transform = input_transform


        for ens in self.ensemble.ensembles:
            if not isinstance(neurons, nengo.Direct):
                ens.encoders = corners(ens.n_neurons)
        nengo.Connection(self.A, self.ensemble.input, synapse=None,
                transform=self.input_transform)
        nengo.Connection(self.B, self.ensemble.input, synapse=None,
                transform=self.input_transform)
        nengo.Connection(self.ensemble.add_output('result', self.kernel),
                self.output)

    @property
    def elementwise_comparator_transform(self):
        I = np.eye(self.dimensions)
        return np.vstack((I, I))

    @staticmethod
    def product(x):
        return x[0] * x[1]
Пример #22
0
    def __init__(self, n_neurons, dimensions, radius=np.sqrt(2.0), encoders=nengo.Default, **ens_kwargs):
        self.A = nengo.Node(size_in=dimensions, label="A")
        self.B = nengo.Node(size_in=dimensions, label="B")
        self.dimensions = dimensions

        if encoders is nengo.Default:
            encoders = Choice([[1, 1], [1, -1], [-1, 1], [-1, -1]])

        self.product = EnsembleArray(
            n_neurons,
            n_ensembles=dimensions,
            ens_dimensions=2,
            encoders=encoders,
            radius=np.sqrt(2) * radius,
            **ens_kwargs
        )

        nengo.Connection(self.A, self.product.input[0::2], synapse=None)
        nengo.Connection(self.B, self.product.input[1::2], synapse=None)

        self.output = self.product.add_output("product", lambda x: x[0] * x[1])
Пример #23
0
class Product(nengo.Network):
    """Computes the element-wise product of two (scaled) unit vectors.

    Requires Scipy.
    """

    def __init__(
            self, n_neurons, dimensions, radius=1.0,
            encoders=nengo.Default, **ens_kwargs):
        super(Product, self).__init__(self)

        with self:
            self.config[nengo.Ensemble].update(ens_kwargs)
            self.A = nengo.Node(size_in=dimensions, label="A")
            self.B = nengo.Node(size_in=dimensions, label="B")
            self.dimensions = dimensions

            if encoders is nengo.Default:
                encoders = Choice([[1, 1], [1, -1], [-1, 1], [-1, -1]])

            optimizer = SubvectorRadiusOptimizer(
                n_neurons, 2, ens_kwargs=ens_kwargs)
            scaled_r = radius * optimizer.find_optimal_radius(dimensions, 1)

            self.product = EnsembleArray(
                n_neurons, n_ensembles=dimensions, ens_dimensions=2,
                radius=scaled_r, encoders=encoders, **ens_kwargs)

            nengo.Connection(
                self.A, self.product.input[::2], synapse=None)
            nengo.Connection(
                self.B, self.product.input[1::2], synapse=None)

            self.output = self.product.add_output(
                'product', lambda x: x[0] * x[1])

    def dot_product_transform(self, scale=1.0):
        """Returns a transform for output to compute the scaled dot product."""
        return scale * np.ones((1, self.dimensions))
Пример #24
0
    def __init__(self,
                 dimensions,
                 n_neurons_per_ensemble=50,
                 mutual_inhib=1,
                 threshold=0):
        self.actions = EnsembleArray(n_neurons_per_ensemble,
                                     dimensions,
                                     intercepts=Uniform(threshold, 1),
                                     encoders=[[1]] * n_neurons_per_ensemble,
                                     label="actions")

        self.input = self.actions.input
        self.output = self.actions.output

        nengo.Connection(self.actions.output,
                         self.actions.input,
                         transform=(np.eye(dimensions) - 1) * mutual_inhib)

        self.bias = nengo.Node([1])
        nengo.Connection(self.bias,
                         self.actions.input,
                         transform=[[1]] * dimensions)
Пример #25
0
    def __init__(self,
                 dimensions,
                 n_neurons_per_ensemble=100,
                 radius=1.5,
                 tau_ampa=0.002,
                 tau_gaba=0.008,
                 output_weight=-3,
                 input_bias=0.0,
                 solver=None):
        if solver is None:
            try:
                # Best, if we have SciPy
                solver = NnlsL2nz()
            except ImportError:
                # If not, use default
                warnings.warn("SciPy is not installed, so BasalGanglia will "
                              "use default decoder solver. Installing SciPy "
                              "may improve BasalGanglia performance.")
                solver = nengo.Default
        encoders = np.ones((n_neurons_per_ensemble, 1))
        ea_params = {
            'n_neurons': n_neurons_per_ensemble,
            'n_ensembles': dimensions,
            'radius': radius,
            'encoders': encoders,
        }

        self.strD1 = EnsembleArray(label="Striatal D1 neurons",
                                   intercepts=Uniform(self.e, 1),
                                   **ea_params)

        self.strD2 = EnsembleArray(label="Striatal D2 neurons",
                                   intercepts=Uniform(self.e, 1),
                                   **ea_params)

        self.stn = EnsembleArray(label="Subthalamic nucleus",
                                 intercepts=Uniform(self.ep, 1),
                                 **ea_params)

        self.gpi = EnsembleArray(label="Globus pallidus internus",
                                 intercepts=Uniform(self.eg, 1),
                                 **ea_params)

        self.gpe = EnsembleArray(label="Globus pallidus externus",
                                 intercepts=Uniform(self.ee, 1),
                                 **ea_params)

        self.input = nengo.Node(label="input", size_in=dimensions)
        self.output = nengo.Node(label="output", size_in=dimensions)

        # add bias input (BG performs best in the range 0.5--1.5)
        if abs(input_bias) > 0.0:
            self.bias_input = nengo.Node([input_bias] * dimensions)
            nengo.Connection(self.bias_input, self.input)

        # spread the input to StrD1, StrD2, and STN
        nengo.Connection(self.input,
                         self.strD1.input,
                         synapse=None,
                         transform=self.ws * (1 + self.lg))
        nengo.Connection(self.input,
                         self.strD2.input,
                         synapse=None,
                         transform=self.ws * (1 - self.le))
        nengo.Connection(self.input,
                         self.stn.input,
                         synapse=None,
                         transform=self.wt)

        # connect the striatum to the GPi and GPe (inhibitory)
        strD1_output = self.strD1.add_output('func_str',
                                             self.str_func,
                                             solver=solver)
        nengo.Connection(strD1_output,
                         self.gpi.input,
                         synapse=tau_gaba,
                         transform=-np.eye(dimensions) * self.wm)
        strD2_output = self.strD2.add_output('func_str',
                                             self.str_func,
                                             solver=solver)
        nengo.Connection(strD2_output,
                         self.gpe.input,
                         synapse=tau_gaba,
                         transform=-np.eye(dimensions) * self.wm)

        # connect the STN to GPi and GPe (broad and excitatory)
        tr = self.wp * np.ones((dimensions, dimensions))
        stn_output = self.stn.add_output('func_stn',
                                         self.stn_func,
                                         solver=solver)
        nengo.Connection(stn_output,
                         self.gpi.input,
                         transform=tr,
                         synapse=tau_ampa)
        nengo.Connection(stn_output,
                         self.gpe.input,
                         transform=tr,
                         synapse=tau_ampa)

        # connect the GPe to GPi and STN (inhibitory)
        gpe_output = self.gpe.add_output('func_gpe',
                                         self.gpe_func,
                                         solver=solver)
        nengo.Connection(gpe_output,
                         self.gpi.input,
                         synapse=tau_gaba,
                         transform=-self.we)
        nengo.Connection(gpe_output,
                         self.stn.input,
                         synapse=tau_gaba,
                         transform=-self.wg)

        # connect GPi to output (inhibitory)
        gpi_output = self.gpi.add_output('func_gpi',
                                         self.gpi_func,
                                         solver=solver)
        nengo.Connection(gpi_output,
                         self.output,
                         synapse=None,
                         transform=output_weight)
Пример #26
0
    def __init__(self,
                 action_count,
                 n_neurons_per_ensemble=Default,
                 output_weight=Default,
                 input_bias=Default,
                 ampa_synapse=Default,
                 gaba_synapse=Default,
                 sBCBG_params=None,
                 **kwargs):

        kwargs.setdefault('label', "Basal ganglia")
        super(BasalGanglia, self).__init__(**kwargs)

        self.action_count = action_count
        self.input_connections = {}
        self.input_bias = input_bias

        if BasalGanglia.sBCBG:

            # parameters
            filter_tau = .01
            if output_weight == Default:
                self.output_weight = -0.001

            import sBCBG
            if sBCBG_params == None:
                sBCBG_params = {}
            sBCBG.nengo_instantiate(
                self.action_count, self,
                sBCBG_params if sBCBG_params != None else {})

            with self:

                # connect input to CSN
                self.input = nengo.Node(label="input",
                                        size_in=self.action_count)
                scale = nengo.Ensemble(100, self.input.size_out)
                nengo.Connection(self.input, scale)
                for d in range(self.action_count):
                    nengo.Connection(scale[d],
                                     self.pops['CSN'][d],
                                     function=lambda x: 10 * x,
                                     synapse=.01,
                                     label='CSN input')

                # add bias input (BG performs best in the range 0.5--1.5)
                if abs(self.input_bias) > 0.0:
                    self.bias_input = nengo.Node(np.ones(self.action_count) *
                                                 input_bias,
                                                 label="basal ganglia bias")
                    nengo.Connection(self.bias_input, self.input)

                # connect GPi to output (inhibitory)
                decoding_weight = 1  # scaling of decoding GPi->out
                self.output = nengo.Node(label="output",
                                         size_in=self.action_count)
                for d in range(self.action_count):
                    GPi_ens = self.pops["GPi"][d]
                    decoder_values = np.ones(
                        (GPi_ens.n_neurons, 1)) * decoding_weight
                    nengo.Connection(
                        GPi_ens,
                        self.output[d],
                        synapse=nengo.synapses.Lowpass(filter_tau),
                        transform=self.output_weight,
                        #eval_points=eval_points)
                        solver=nengo.solvers.NoSolver(decoder_values))

        else:
            self.n_neurons_per_ensemble = n_neurons_per_ensemble
            self.ampa_synapse = ampa_synapse
            self.gaba_synapse = gaba_synapse
            self.output_weight = output_weight

            # Affects all ensembles / connections in the BG
            # unless overwritten with general_config
            config = nengo.Config(nengo.Ensemble, nengo.Connection)
            config[nengo.Ensemble].radius = 1.5
            config[nengo.Ensemble].encoders = nengo.dists.Choice([[1]])
            try:
                # Best, if we have SciPy
                config[nengo.Connection].solver = nengo.solvers.NnlsL2nz()
            except ImportError:
                warnings.warn("SciPy is not installed, so BasalGanglia will "
                              "use the default decoder solver. Installing "
                              "SciPy may improve BasalGanglia performance.")

            ea_params = {
                'n_neurons': self.n_neurons_per_ensemble,
                'n_ensembles': self.action_count
            }

            with self, config:
                self.strD1 = EnsembleArray(label="Striatal D1 neurons",
                                           intercepts=nengo.dists.Uniform(
                                               Weights.e, 1),
                                           **ea_params)
                self.strD2 = EnsembleArray(label="Striatal D2 neurons",
                                           intercepts=nengo.dists.Uniform(
                                               Weights.e, 1),
                                           **ea_params)
                self.stn = EnsembleArray(label="Subthalamic nucleus",
                                         intercepts=nengo.dists.Uniform(
                                             Weights.ep, 1),
                                         **ea_params)
                self.gpi = EnsembleArray(label="Globus pallidus internus",
                                         intercepts=nengo.dists.Uniform(
                                             Weights.eg, 1),
                                         **ea_params)
                self.gpe = EnsembleArray(label="Globus pallidus externus",
                                         intercepts=nengo.dists.Uniform(
                                             Weights.ee, 1),
                                         **ea_params)

                self.input = nengo.Node(label="input",
                                        size_in=self.action_count)
                self.output = nengo.Node(label="output",
                                         size_in=self.action_count)

                # add bias input (BG performs best in the range 0.5--1.5)
                if abs(self.input_bias) > 0.0:
                    self.bias_input = nengo.Node(np.ones(self.action_count) *
                                                 self.input_bias,
                                                 label="basal ganglia bias")
                    nengo.Connection(self.bias_input, self.input)

                # spread the input to StrD1, StrD2, and STN
                nengo.Connection(self.input,
                                 self.strD1.input,
                                 synapse=None,
                                 transform=Weights.ws * (1 + Weights.lg))
                nengo.Connection(self.input,
                                 self.strD2.input,
                                 synapse=None,
                                 transform=Weights.ws * (1 - Weights.le))
                nengo.Connection(self.input,
                                 self.stn.input,
                                 synapse=None,
                                 transform=Weights.wt)

                # connect the striatum to the GPi and GPe (inhibitory)
                strD1_output = self.strD1.add_output('func_str',
                                                     Weights.str_func)
                strD2_output = self.strD2.add_output('func_str',
                                                     Weights.str_func)
                self.gaba = nengo.Network("GABAergic connections")
                self.gaba.config[nengo.Connection].synapse = self.gaba_synapse
                with self.gaba:
                    nengo.Connection(strD1_output,
                                     self.gpi.input,
                                     transform=-Weights.wm)
                    nengo.Connection(strD2_output,
                                     self.gpe.input,
                                     transform=-Weights.wm)

                # connect the STN to GPi and GPe (broad and excitatory)
                tr = Weights.wp * np.ones(
                    (self.action_count, self.action_count))
                stn_output = self.stn.add_output('func_stn', Weights.stn_func)
                self.ampa = nengo.Network("AMPAergic connectiions")
                self.ampa.config[nengo.Connection].synapse = self.ampa_synapse
                with self.ampa:
                    nengo.Connection(stn_output, self.gpi.input, transform=tr)
                    nengo.Connection(stn_output, self.gpe.input, transform=tr)

                # connect the GPe to GPi and STN (inhibitory)
                gpe_output = self.gpe.add_output('func_gpe', Weights.gpe_func)
                with self.gaba:
                    nengo.Connection(gpe_output,
                                     self.gpi.input,
                                     transform=-Weights.we)
                    nengo.Connection(gpe_output,
                                     self.stn.input,
                                     transform=-Weights.wg)

                # connect GPi to output (inhibitory)
                gpi_output = self.gpi.add_output('func_gpi', Weights.gpi_func)
                nengo.Connection(gpi_output,
                                 self.output,
                                 synapse=None,
                                 transform=self.output_weight)
Пример #27
0
    def __init__(self, dimensions, n_neurons_per_ensemble=100, radius=1.5,
                 tau_ampa=0.002, tau_gaba=0.008, output_weight=-3,
                 input_bias=0.0, solver=None):
        if solver is None:
            try:
                # Best, if we have SciPy
                solver = NnlsL2nz()
            except ImportError:
                # If not, use default
                warnings.warn("SciPy is not installed, so BasalGanglia will "
                              "use default decoder solver. Installing SciPy "
                              "may improve BasalGanglia performance.")
                solver = nengo.Default
        encoders = np.ones((n_neurons_per_ensemble, 1))
        ea_params = {
            'n_neurons': n_neurons_per_ensemble,
            'n_ensembles': dimensions,
            'radius': radius,
            'encoders': encoders,
        }

        self.strD1 = EnsembleArray(label="Striatal D1 neurons",
                                   intercepts=Uniform(self.e, 1), **ea_params)

        self.strD2 = EnsembleArray(label="Striatal D2 neurons",
                                   intercepts=Uniform(self.e, 1), **ea_params)

        self.stn = EnsembleArray(label="Subthalamic nucleus",
                                 intercepts=Uniform(self.ep, 1), **ea_params)

        self.gpi = EnsembleArray(label="Globus pallidus internus",
                                 intercepts=Uniform(self.eg, 1), **ea_params)

        self.gpe = EnsembleArray(label="Globus pallidus externus",
                                 intercepts=Uniform(self.ee, 1), **ea_params)

        self.input = nengo.Node(label="input", size_in=dimensions)
        self.output = nengo.Node(label="output", size_in=dimensions)

        # add bias input (BG performs best in the range 0.5--1.5)
        if abs(input_bias) > 0.0:
            self.bias_input = nengo.Node([input_bias] * dimensions)
            nengo.Connection(self.bias_input, self.input)

        # spread the input to StrD1, StrD2, and STN
        nengo.Connection(self.input, self.strD1.input, synapse=None,
                         transform=self.ws * (1 + self.lg))
        nengo.Connection(self.input, self.strD2.input, synapse=None,
                         transform=self.ws * (1 - self.le))
        nengo.Connection(self.input, self.stn.input, synapse=None,
                         transform=self.wt)

        # connect the striatum to the GPi and GPe (inhibitory)
        strD1_output = self.strD1.add_output(
            'func_str', self.str_func, solver=solver)
        nengo.Connection(strD1_output,
                         self.gpi.input, synapse=tau_gaba,
                         transform=-np.eye(dimensions) * self.wm)
        strD2_output = self.strD2.add_output(
            'func_str', self.str_func, solver=solver)
        nengo.Connection(strD2_output,
                         self.gpe.input, synapse=tau_gaba,
                         transform=-np.eye(dimensions) * self.wm)

        # connect the STN to GPi and GPe (broad and excitatory)
        tr = self.wp * np.ones((dimensions, dimensions))
        stn_output = self.stn.add_output(
            'func_stn', self.stn_func, solver=solver)
        nengo.Connection(stn_output, self.gpi.input,
                         transform=tr, synapse=tau_ampa)
        nengo.Connection(stn_output, self.gpe.input,
                         transform=tr, synapse=tau_ampa)

        # connect the GPe to GPi and STN (inhibitory)
        gpe_output = self.gpe.add_output(
            'func_gpe', self.gpe_func, solver=solver)
        nengo.Connection(gpe_output, self.gpi.input, synapse=tau_gaba,
                         transform=-self.we)
        nengo.Connection(gpe_output, self.stn.input, synapse=tau_gaba,
                         transform=-self.wg)

        # connect GPi to output (inhibitory)
        gpi_output = self.gpi.add_output(
            'func_gpi', self.gpi_func, solver=solver)
        nengo.Connection(gpi_output, self.output, synapse=None,
                         transform=output_weight)
Пример #28
0
    def __init__(
            self,
            input_vocab,
            output_vocab=None,  # noqa: C901
            default_output_vector=None,
            threshold=0.3,
            input_scale=1.0,
            inhibitable=False,
            inhibit_scale=1.0,
            wta_output=False,
            wta_inhibit_scale=2.0,
            wta_synapse=0.005,
            precise=False,
            output_utilities=False,
            output_thresholded_utilities=False,
            neuron_type=nengo.LIF(),
            n_neurons_per_ensemble=10):
        super(AssociativeMemory, self).__init__()

        # If output vocabulary is not specified, use input vocabulary
        # (i.e autoassociative memory)
        if output_vocab is None:
            output_vocab = input_vocab

        # Handle different vocabulary types
        if isinstance(input_vocab, Vocabulary):
            input_vectors = input_vocab.vectors
        elif is_iterable(input_vocab):
            input_vectors = np.matrix(input_vocab)
        else:
            input_vectors = input_vocab

        if isinstance(output_vocab, Vocabulary):
            output_vectors = output_vocab.vectors
        elif is_iterable(output_vocab):
            output_vectors = np.matrix(output_vocab)
        else:
            output_vectors = output_vocab

        # Fail if number of input items and number of output items don't match
        if input_vectors.shape[0] != output_vectors.shape[0]:
            raise ValueError(
                'number of input vectors does not match number of output '
                'vectors. %d != %d' %
                (input_vectors.shape[0], output_vectors.shape[0]))

        N = len(input_vectors)
        n_eval_points = 1500
        eval_point_margin = 0.0001 if precise == True else 0.1
        eval_points = Uniform(
            threshold + eval_point_margin,
            1 + eval_point_margin).sample(n_eval_points).reshape(-1, 1)

        # Ensemble array parameters
        ea_params = {
            'radius': 1.0,
            'neuron_type': neuron_type,
            'n_neurons': n_neurons_per_ensemble,
            'n_ensembles': N,
            'intercepts': Uniform(threshold, 1),
            'max_rates':
            Uniform(80, 100) if precise == True else Uniform(100, 200),
            'encoders': np.ones((n_neurons_per_ensemble, 1)),
            'eval_points': eval_points
        }

        # Thresholding function
        def threshold_func(x):
            return x > threshold

        # Input and output nodes
        self.input = nengo.Node(size_in=input_vectors.shape[1], label="input")
        self.output = nengo.Node(size_in=output_vectors.shape[1],
                                 label="output")

        # Ensemble array to do the thresholding stuff
        self.thresholded_ens_array = EnsembleArray(
            label="thresholded ens array", **ea_params)

        # Connect input and output nodes
        nengo.Connection(self.input,
                         self.thresholded_ens_array.input,
                         synapse=None,
                         transform=input_vectors * input_scale)
        nengo.Connection(self.thresholded_ens_array.add_output(
            'thresholded_output', threshold_func),
                         self.output,
                         synapse=None,
                         transform=output_vectors.T)

        # Configure associative memory to be inhibitable
        if inhibitable:
            # Input node for inhibitory gating signal (if enabled)
            self.inhibit = nengo.Node(size_in=1, label="inhibit")
            nengo.Connection(self.inhibit,
                             self.thresholded_ens_array.input,
                             synapse=None,
                             transform=-np.ones((N, 1)))
            # Note: We can use decoded connection here because all the
            # encoding vectors are [1]

        # Configure associative memory to have mutually inhibited output
        if wta_output:
            nengo.Connection(self.thresholded_ens_array.output,
                             self.thresholded_ens_array.input,
                             synapse=wta_synapse,
                             transform=(np.eye(N) - 1) * inhibit_scale)

        # Configure utilities output
        if output_utilities:
            self.utilities = nengo.Node(size_in=N, label="utilities")
            nengo.Connection(self.thresholded_ens_array.output,
                             self.utilities,
                             synapse=None)

        # Configure utilities output
        if output_thresholded_utilities:
            self.thresholded_utilities = nengo.Node(
                size_in=N, label="thresholded_utilities")
            nengo.Connection(self.thresholded_ens_array.thresholded_output,
                             self.thresholded_utilities,
                             synapse=None)

        # Configure default output vector
        if default_output_vector is not None:
            eval_points = Uniform(0.8, 1).sample(n_eval_points).reshape(-1, 1)
            bias = nengo.Node(output=[1])
            default_vector_gate = nengo.Ensemble(
                n_neurons_per_ensemble,
                dimensions=1,
                encoders=np.ones((n_neurons_per_ensemble, 1)),
                intercepts=Uniform(0.5, 1),
                max_rates=ea_params['max_rates'],
                eval_points=eval_points,
                label="default vector gate")
            nengo.Connection(bias, default_vector_gate, synapse=None)
            nengo.Connection(self.thresholded_ens_array.thresholded_output,
                             default_vector_gate,
                             transform=-np.ones((1, N)),
                             synapse=0.005)
            nengo.Connection(default_vector_gate,
                             self.output,
                             synapse=None,
                             transform=np.matrix(default_output_vector).T)
            if inhibitable:
                nengo.Connection(self.inhibit,
                                 default_vector_gate,
                                 synapse=None,
                                 transform=[[-1]])

        if isinstance(input_vocab, Vocabulary):
            self.inputs = dict(default=(self.input, input_vocab))
        if isinstance(output_vocab, Vocabulary):
            self.outputs = dict(default=(self.output, output_vocab))
Пример #29
0
def Thalamus(dimensions,
             n_neurons_per_ensemble=50,
             mutual_inhib=1.,
             threshold=0.,
             net=None):
    """Inhibits non-selected actions.

    The thalamus is intended to work in tandem with a basal ganglia network.
    It converts basal ganglia output into a signal with (approximately) 1 for
    the selected action and 0 elsewhere.

    In order to suppress low responses and strengthen high responses,
    a constant bias is added to each dimension (i.e., action), and dimensions
    mutually inhibit each other. Additionally, the ensemble representing
    each dimension is created with positive encoders and can be assigned
    positive x-intercepts to threshold low responses.

    Parameters
    ----------
    dimensions : int
        Number of dimensions (i.e., actions).
    n_neurons_per_ensemble : int, optional (Default: 50)
        Number of neurons in each ensemble in the network.
    mutual_inhib : float, optional (Default: 1.)
        Strength of the mutual inhibition between actions.
    threshold : float, optional (Default: 0.)
        The threshold below which values will not be represented.
    net : Network, optional (Default: None)
        A network in which the network components will be built.
        This is typically used to provide a custom set of Nengo object
        defaults through modifying ``net.config``.

    Returns
    -------
    net : Network
        The newly built thalamus network, or the provided ``net``.

    Attributes
    ----------
    net.actions : EnsembleArray
        Each ensemble represents one dimension (action).
    net.bias : Node
        The constant bias injected in each ``actions`` ensemble.
    net.input : Node
        Input to the ``actions`` ensembles.
    net.output : Node
        Output from the ``actions`` ensembles.
    """

    if net is None:
        net = nengo.Network("Thalamus")

    with net:
        net.actions = EnsembleArray(n_neurons_per_ensemble,
                                    dimensions,
                                    intercepts=Uniform(threshold, 1),
                                    encoders=Choice([[1.0]]),
                                    label="actions")
        nengo.Connection(net.actions.output,
                         net.actions.input,
                         transform=(np.eye(dimensions) - 1) * mutual_inhib)
        net.bias = nengo.Node([1], label="thalamus bias")
        nengo.Connection(net.bias,
                         net.actions.input,
                         transform=np.ones((dimensions, 1)))

    net.input = net.actions.input
    net.output = net.actions.output
    return net
Пример #30
0
    def __init__(self, input_vocab, output_vocab=None,  # noqa: C901
                 default_output_vector=None, threshold=0.3, input_scale=1.0,
                 inhibitable=False, inhibit_scale=1.0, wta_output=False,
                 wta_inhibit_scale=2.0, wta_synapse=0.005,
                 output_utilities=False, output_thresholded_utilities=False,
                 neuron_type=nengo.LIF(), n_neurons_per_ensemble=10):
        super(AssociativeMemory, self).__init__()

        # If output vocabulary is not specified, use input vocabulary
        # (i.e autoassociative memory)
        if output_vocab is None:
            output_vocab = input_vocab

        # Handle different vocabulary types
        if isinstance(input_vocab, Vocabulary):
            input_vectors = input_vocab.vectors
        elif is_iterable(input_vocab):
            input_vectors = np.matrix(input_vocab)
        else:
            input_vectors = input_vocab

        if isinstance(output_vocab, Vocabulary):
            output_vectors = output_vocab.vectors
        elif is_iterable(output_vocab):
            output_vectors = np.matrix(output_vocab)
        else:
            output_vectors = output_vocab

        # Fail if number of input items and number of output items don't match
        if input_vectors.shape[0] != output_vectors.shape[0]:
            raise ValueError(
                'number of input vectors does not match number of output '
                'vectors. %d != %d'
                % (input_vectors.shape[0], output_vectors.shape[0]))

        N = len(input_vectors)
        n_eval_points = 500
        eval_point_margin = 0.1
        eval_points = Uniform(
            threshold + eval_point_margin, 1 + eval_point_margin)

        # Ensemble array parameters
        ea_params = {'radius': 1.0,
                     'neuron_type': neuron_type,
                     'n_neurons': n_neurons_per_ensemble,
                     'n_ensembles': N,
                     'intercepts': Uniform(threshold, 1),
                     'max_rates': Uniform(100, 200),
                     'encoders': Choice([[1]]),
                     'n_eval_points': n_eval_points,
                     'eval_points': eval_points}

        # Thresholding function
        def threshold_func(x):
            return x > threshold

        # Input and output nodes
        self.input = nengo.Node(size_in=input_vectors.shape[1], label="input")
        self.output = nengo.Node(size_in=output_vectors.shape[1],
                                 label="output")

        # Ensemble array to do the thresholding stuff
        self.thresholded_ens_array = EnsembleArray(
            label="thresholded ens array", **ea_params)

        # Connect input and output nodes
        nengo.Connection(self.input, self.thresholded_ens_array.input,
                         synapse=None, transform=input_vectors * input_scale)
        nengo.Connection(
            self.thresholded_ens_array.add_output(
                'thresholded_output', threshold_func),
            self.output, synapse=None, transform=output_vectors.T)

        # Configure associative memory to be inhibitable
        if inhibitable:
            # Input node for inhibitory gating signal (if enabled)
            self.inhibit = nengo.Node(size_in=1, label="inhibit")
            nengo.Connection(self.inhibit, self.thresholded_ens_array.input,
                             synapse=None, transform=-np.ones((N, 1)))
            # Note: We can use decoded connection here because all the
            # encoding vectors are [1]

        # Configure associative memory to have mutually inhibited output
        if wta_output:
            nengo.Connection(self.thresholded_ens_array.output,
                             self.thresholded_ens_array.input,
                             synapse=wta_synapse,
                             transform=(np.eye(N) - 1) * inhibit_scale)

        # Configure utilities output
        if output_utilities:
            self.utilities = nengo.Node(size_in=N, label="utilities")
            nengo.Connection(self.thresholded_ens_array.output,
                             self.utilities, synapse=None)

        # Configure utilities output
        if output_thresholded_utilities:
            self.thresholded_utilities = nengo.Node(
                size_in=N, label="thresholded_utilities")
            nengo.Connection(self.thresholded_ens_array.thresholded_output,
                             self.thresholded_utilities, synapse=None)

        # Configure default output vector
        if default_output_vector is not None:
            eval_points = Uniform(0.8, 1)
            bias = nengo.Node(output=[1])
            default_vector_gate = nengo.Ensemble(
                n_neurons_per_ensemble, dimensions=1,
                encoders=Choice([[1]]),
                intercepts=Uniform(0.5, 1),
                max_rates=ea_params['max_rates'],
                n_eval_points=n_eval_points,
                eval_points=eval_points,
                label="default vector gate")
            nengo.Connection(bias, default_vector_gate, synapse=None)
            nengo.Connection(self.thresholded_ens_array.thresholded_output,
                             default_vector_gate, transform=-np.ones((1, N)),
                             synapse=0.005)
            nengo.Connection(default_vector_gate, self.output, synapse=None,
                             transform=np.matrix(default_output_vector).T)
            if inhibitable:
                nengo.Connection(self.inhibit, default_vector_gate,
                                 synapse=None, transform=[[-1]])

        if isinstance(input_vocab, Vocabulary):
            self.inputs = dict(default=(self.input, input_vocab))
        if isinstance(output_vocab, Vocabulary):
            self.outputs = dict(default=(self.output, output_vocab))
Пример #31
0
class AssociativeMemory(Module):
    """Associative memory module.

    Parameters
    ----------
    input_vocab: list of numpy.array, spa.Vocabulary
        The vocabulary (or list of vectors) to match.
    output_vocab: list of numpy.array, spa.Vocabulary, optional
        The vocabulary (or list of vectors) to be produced for each match. If
        not given, the associative memory will act like an auto-associative
        memory (cleanup memory).
    default_output_vector: numpy.array, spa.SemanticPointer, optional
        The vector to be produced if the input value matches none of vectors
        in the input vector list.
    threshold: float, optional
        The association activation threshold.
    input_scale: float, optional
        Scaling factor to apply on the input vectors.

    inhibitable: boolean, optional
        Flag to indicate if the entire associative memory module is
        inhibitable (entire thing can be shut off).
    inhibit_scale: float, optional
        Scaling factor on the gating connections (must have inhibitable =
        True). Setting a larger value will ensure that the cleanup memory
        output is inhibited at a faster rate, however, recovery of the
        network when inhibition is released will be slower.

    wta_output: boolean, optional
        Flag to indicate if output of the associative memory should contain
        more than one vectors. Set to True if only one vectors output is
        desired -- i.e. a winner-take-all (wta) output. Leave as default
        (False) if (possible) combinations of vectors is desired.
    wta_inhibit_scale: float, optional
        Scaling factor on the winner-take-all (wta) inhibitory connections.
    wta_synapse: float, optional
        Synapse to use for the winner-take-all (wta) inhibitory connections.

    output_utilities: boolean, optional
        Flag to indicate if the direct utilities (in addition to the vectors)
        are output as well.
    output_thresholded_utilities: boolean, optional
        Flag to indicate if the direct thresholded utilities (in addition to
        the vectors) are output as well.

    neuron_type: nengo.Neurons, optional
        Neuron type to use in the associative memory. Defaults to
    n_neurons_per_ensemble: int, optional
        Number of neurons per ensemble in the associative memory. There is
        one ensemble created per vector being compared.

    """

    def __init__(self, input_vocab, output_vocab=None,  # noqa: C901
                 default_output_vector=None, threshold=0.3, input_scale=1.0,
                 inhibitable=False, inhibit_scale=1.0, wta_output=False,
                 wta_inhibit_scale=2.0, wta_synapse=0.005,
                 output_utilities=False, output_thresholded_utilities=False,
                 neuron_type=nengo.LIF(), n_neurons_per_ensemble=10):
        super(AssociativeMemory, self).__init__()

        # If output vocabulary is not specified, use input vocabulary
        # (i.e autoassociative memory)
        if output_vocab is None:
            output_vocab = input_vocab

        # Handle different vocabulary types
        if isinstance(input_vocab, Vocabulary):
            input_vectors = input_vocab.vectors
        elif is_iterable(input_vocab):
            input_vectors = np.matrix(input_vocab)
        else:
            input_vectors = input_vocab

        if isinstance(output_vocab, Vocabulary):
            output_vectors = output_vocab.vectors
        elif is_iterable(output_vocab):
            output_vectors = np.matrix(output_vocab)
        else:
            output_vectors = output_vocab

        # Fail if number of input items and number of output items don't match
        if input_vectors.shape[0] != output_vectors.shape[0]:
            raise ValueError(
                'number of input vectors does not match number of output '
                'vectors. %d != %d'
                % (input_vectors.shape[0], output_vectors.shape[0]))

        N = len(input_vectors)
        n_eval_points = 500
        eval_point_margin = 0.1
        eval_points = Uniform(
            threshold + eval_point_margin, 1 + eval_point_margin)

        # Ensemble array parameters
        ea_params = {'radius': 1.0,
                     'neuron_type': neuron_type,
                     'n_neurons': n_neurons_per_ensemble,
                     'n_ensembles': N,
                     'intercepts': Uniform(threshold, 1),
                     'max_rates': Uniform(100, 200),
                     'encoders': Choice([[1]]),
                     'n_eval_points': n_eval_points,
                     'eval_points': eval_points}

        # Thresholding function
        def threshold_func(x):
            return x > threshold

        # Input and output nodes
        self.input = nengo.Node(size_in=input_vectors.shape[1], label="input")
        self.output = nengo.Node(size_in=output_vectors.shape[1],
                                 label="output")

        # Ensemble array to do the thresholding stuff
        self.thresholded_ens_array = EnsembleArray(
            label="thresholded ens array", **ea_params)

        # Connect input and output nodes
        nengo.Connection(self.input, self.thresholded_ens_array.input,
                         synapse=None, transform=input_vectors * input_scale)
        nengo.Connection(
            self.thresholded_ens_array.add_output(
                'thresholded_output', threshold_func),
            self.output, synapse=None, transform=output_vectors.T)

        # Configure associative memory to be inhibitable
        if inhibitable:
            # Input node for inhibitory gating signal (if enabled)
            self.inhibit = nengo.Node(size_in=1, label="inhibit")
            nengo.Connection(self.inhibit, self.thresholded_ens_array.input,
                             synapse=None, transform=-np.ones((N, 1)))
            # Note: We can use decoded connection here because all the
            # encoding vectors are [1]

        # Configure associative memory to have mutually inhibited output
        if wta_output:
            nengo.Connection(self.thresholded_ens_array.output,
                             self.thresholded_ens_array.input,
                             synapse=wta_synapse,
                             transform=(np.eye(N) - 1) * inhibit_scale)

        # Configure utilities output
        if output_utilities:
            self.utilities = nengo.Node(size_in=N, label="utilities")
            nengo.Connection(self.thresholded_ens_array.output,
                             self.utilities, synapse=None)

        # Configure utilities output
        if output_thresholded_utilities:
            self.thresholded_utilities = nengo.Node(
                size_in=N, label="thresholded_utilities")
            nengo.Connection(self.thresholded_ens_array.thresholded_output,
                             self.thresholded_utilities, synapse=None)

        # Configure default output vector
        if default_output_vector is not None:
            eval_points = Uniform(0.8, 1)
            bias = nengo.Node(output=[1])
            default_vector_gate = nengo.Ensemble(
                n_neurons_per_ensemble, dimensions=1,
                encoders=Choice([[1]]),
                intercepts=Uniform(0.5, 1),
                max_rates=ea_params['max_rates'],
                n_eval_points=n_eval_points,
                eval_points=eval_points,
                label="default vector gate")
            nengo.Connection(bias, default_vector_gate, synapse=None)
            nengo.Connection(self.thresholded_ens_array.thresholded_output,
                             default_vector_gate, transform=-np.ones((1, N)),
                             synapse=0.005)
            nengo.Connection(default_vector_gate, self.output, synapse=None,
                             transform=np.matrix(default_output_vector).T)
            if inhibitable:
                nengo.Connection(self.inhibit, default_vector_gate,
                                 synapse=None, transform=[[-1]])

        if isinstance(input_vocab, Vocabulary):
            self.inputs = dict(default=(self.input, input_vocab))
        if isinstance(output_vocab, Vocabulary):
            self.outputs = dict(default=(self.output, output_vocab))
Пример #32
0
class Product(nengo.Network):
    """Computes the element-wise product of two equally sized vectors.

    The network used to calculate the product is described in
    `Gosmann, 2015`_. A simpler version of this network can be found in the
    :doc:`Multiplication example <examples/basic/multiplication>`.

    Note that this network is optimized under the assumption that both input
    values (or both values for each input dimensions of the input vectors) are
    uniformly and independently distributed. Visualized in a joint 2D space,
    this would give a square of equal probabilities for pairs of input values.
    This assumption is violated with non-uniform input value distributions
    (for example, if the input values follow a Gaussian or cosine similarity
    distribution). In that case, no square of equal probabilities is obtained,
    but a probability landscape with circular equi-probability lines. To obtain
    the optimal network accuracy, scale the *input_magnitude* by a factor of
    ``1 / sqrt(2)``.

    .. _Gosmann, 2015:
       https://nbviewer.jupyter.org/github/ctn-archive/technical-reports/blob/
       master/Precise-multiplications-with-the-NEF.ipynb

    Parameters
    ----------
    n_neurons : int
        Number of neurons per dimension in the vector.

        .. note:: These neurons will be distributed evenly across two
                  ensembles. If an odd number of neurons is specified, the
                  extra neuron will not be used.
    dimensions : int
        Number of dimensions in each of the vectors to be multiplied.

    input_magnitude : float, optional (Default: 1.)
        The expected magnitude of the vectors to be multiplied.
        This value is used to determine the radius of the ensembles
        computing the element-wise product.
    **kwargs
        Keyword arguments passed through to ``nengo.Network``
        like 'label' and 'seed'.

    Attributes
    ----------
    input_a : Node
        The first vector to be multiplied.
    input_b : Node
        The second vector to be multiplied.
    output : Node
        The resulting product.
    sq1 : EnsembleArray
        Represents the first squared term. See `Gosmann, 2015`_ for details.
    sq2 : EnsembleArray
        Represents the second squared term. See `Gosmann, 2015`_ for details.
    """
    def __init__(self, n_neurons, dimensions, input_magnitude=1., **kwargs):
        if 'net' in kwargs:
            raise ObsoleteError("The 'net' argument is no longer supported.")
        kwargs.setdefault('label', "Product")
        super().__init__(**kwargs)

        with self:
            self.input_a = nengo.Node(size_in=dimensions, label="input_a")
            self.input_b = nengo.Node(size_in=dimensions, label="input_b")
            self.output = nengo.Node(size_in=dimensions, label="output")

            self.sq1 = EnsembleArray(
                max(1, n_neurons // 2),
                n_ensembles=dimensions,
                ens_dimensions=1,
                radius=input_magnitude * np.sqrt(2),
            )
            self.sq2 = EnsembleArray(
                max(1, n_neurons // 2),
                n_ensembles=dimensions,
                ens_dimensions=1,
                radius=input_magnitude * np.sqrt(2),
            )

            tr = 1. / np.sqrt(2.)
            nengo.Connection(
                self.input_a, self.sq1.input, transform=tr, synapse=None)
            nengo.Connection(
                self.input_b, self.sq1.input, transform=tr, synapse=None)
            nengo.Connection(
                self.input_a, self.sq2.input, transform=tr, synapse=None)
            nengo.Connection(
                self.input_b, self.sq2.input, transform=-tr, synapse=None)

            sq1_out = self.sq1.add_output('square', np.square)
            nengo.Connection(sq1_out, self.output, transform=.5, synapse=None)
            sq2_out = self.sq2.add_output('square', np.square)
            nengo.Connection(sq2_out, self.output, transform=-.5, synapse=None)

    @property
    def A(self):
        warnings.warn(DeprecationWarning("Use 'input_a' instead of 'A'."))
        return self.input_a

    @property
    def B(self):
        warnings.warn(DeprecationWarning("Use 'input_b' instead of 'B'."))
        return self.input_b
Пример #33
0
    def __init__(
            self,
            phis,
            angles,
            encoder_rng=np.random,
            vocab=Default,
            # subdimensions=Default,
            neurons_per_dimension=Default,
            feedback=Default,
            represent_cc_identity=Default,
            feedback_synapse=Default,
            limit_low=-5,
            limit_high=-5,
            **kwargs):
        super(SSPState, self).__init__(**kwargs)

        self.vocab = vocab
        self.subdimensions = 6
        self.neurons_per_dimension = neurons_per_dimension
        self.feedback = feedback
        self.feedback_synapse = feedback_synapse
        self.represent_cc_identity = represent_cc_identity

        dimensions = self.vocab.dimensions

        coord_rot_mat = get_coord_rot_mat(dimensions)
        inv_coord_rot_mat = np.linalg.pinv(coord_rot_mat)

        origin = np.zeros((dimensions, ))
        origin[0] = 1
        rot_origin = origin @ coord_rot_mat.T
        origin_back = rot_origin @ inv_coord_rot_mat.T
        offset_vec = origin - origin_back

        # this offset only works for odd dimensions
        # offset_vec = np.ones((dimensions,)) * 1. / dimensions

        if ((dimensions - 1) % self.subdimensions != 0) and (
            (dimensions - 2) % self.subdimensions != 0):
            raise ValidationError(
                "Dimensions (%d) must be divisible by subdimensions (%d)" %
                (dimensions, self.subdimensions),
                attr="dimensions",
                obj=self,
            )

        with self:
            # if self.represent_cc_identity:
            #     self.state_ensembles = IdentityEnsembleArray(
            #         self.neurons_per_dimension,
            #         dimensions,
            #         self.subdimensions,
            #         label="ssp state",
            #     )
            # else:
            #     self.state_ensembles = EnsembleArray(
            #         self.neurons_per_dimension * self.subdimensions,
            #         dimensions // self.subdimensions,
            #         ens_dimensions=self.subdimensions,
            #         eval_points=nengo.dists.CosineSimilarity(dimensions + 2),
            #         intercepts=nengo.dists.CosineSimilarity(dimensions + 2),
            #         label="ssp state",
            #     )

            # the dimensionality with the constant(s) removed
            reduced_dim = coord_rot_mat.shape[0]
            n_toroids = len(phis)
            assert n_toroids == reduced_dim // self.subdimensions

            self.state_ensembles = EnsembleArray(
                self.neurons_per_dimension * self.subdimensions,
                n_toroids,
                ens_dimensions=self.subdimensions,
                # radius=2./dimensions,
                radius=1.,
                # eval_points=nengo.dists.CosineSimilarity(dimensions + 2),
                # intercepts=nengo.dists.CosineSimilarity(dimensions + 2),
                label="ssp state",
            )
            n_neurons = self.neurons_per_dimension * self.subdimensions
            # set the intercepts/encoders/eval points based on orientation and angle
            for k in range(n_toroids):
                preferred_locations = hilbert_2d(limit_low,
                                                 limit_high,
                                                 n_neurons,
                                                 encoder_rng,
                                                 p=8,
                                                 N=2,
                                                 normal_std=3)
                encoders_grid_cell = np.zeros((n_neurons, dimensions))
                for n in range(n_neurons):
                    encoders_grid_cell[n, :] = grid_cell_encoder(
                        location=preferred_locations[n, :],
                        dim=dimensions,
                        phi=phis[k],
                        angle=angles[k],
                        toroid_index=k)

                # rotate, shift, and slice out relevant dimensions
                encoders_transformed = (
                    encoders_grid_cell @ coord_rot_mat.T)[:, k * 6:(k + 1) *
                                                          6].copy()

                self.state_ensembles.ea_ensembles[
                    k].intercepts = nengo.dists.Uniform(0, 1)
                self.state_ensembles.ea_ensembles[
                    k].encoders = encoders_transformed * (dimensions / 2.)
                # scaling eval points by the radius, so when they are rescaled later they are correct
                self.state_ensembles.ea_ensembles[
                    k].eval_points = encoders_transformed * (dimensions / 2.)
                # self.state_ensembles.ea_ensembles[k].normalize_encoders = False

            if self.feedback is not None and self.feedback != 0.0:
                nengo.Connection(
                    self.state_ensembles.output,
                    self.state_ensembles.input,
                    transform=self.feedback,
                    synapse=self.feedback_synapse,
                )

        # Apply coordinate transform on the input and output

        self.input = nengo.Node(size_in=dimensions, label="input")
        self.output = nengo.Node(size_in=dimensions, label="output")

        # fixed offset to push the result back into the unitary space
        self.offset = nengo.Node(offset_vec)

        nengo.Connection(self.input,
                         self.state_ensembles.input,
                         transform=coord_rot_mat * (dimensions / 2.))
        nengo.Connection(self.state_ensembles.output,
                         self.output,
                         transform=inv_coord_rot_mat / (dimensions / 2.))
        nengo.Connection(self.offset, self.output)

        # self.input = self.state_ensembles.input
        # self.output = self.state_ensembles.output
        self.declare_input(self.input, self.vocab)
        self.declare_output(self.output, self.vocab)
Пример #34
0
class BasalGanglia(nengo.Network):
    """Winner takes all; outputs 0 at max dimension, negative elsewhere."""

    # connection weights from (Gurney, Prescott, & Redgrave, 2001)
    mm = 1
    mp = 1
    me = 1
    mg = 1
    ws = 1
    wt = 1
    wm = 1
    wg = 1
    wp = 0.9
    we = 0.3
    e = 0.2
    ep = -0.25
    ee = -0.2
    eg = -0.2
    le = 0.2
    lg = 0.2

    def __init__(self,
                 dimensions,
                 n_neurons_per_ensemble=100,
                 radius=1.5,
                 tau_ampa=0.002,
                 tau_gaba=0.008,
                 output_weight=-3,
                 input_bias=0.0,
                 solver=None):
        if solver is None:
            try:
                # Best, if we have SciPy
                solver = NnlsL2nz()
            except ImportError:
                # If not, use default
                warnings.warn("SciPy is not installed, so BasalGanglia will "
                              "use default decoder solver. Installing SciPy "
                              "may improve BasalGanglia performance.")
                solver = nengo.Default
        encoders = np.ones((n_neurons_per_ensemble, 1))
        ea_params = {
            'n_neurons': n_neurons_per_ensemble,
            'n_ensembles': dimensions,
            'radius': radius,
            'encoders': encoders,
        }

        self.strD1 = EnsembleArray(label="Striatal D1 neurons",
                                   intercepts=Uniform(self.e, 1),
                                   **ea_params)

        self.strD2 = EnsembleArray(label="Striatal D2 neurons",
                                   intercepts=Uniform(self.e, 1),
                                   **ea_params)

        self.stn = EnsembleArray(label="Subthalamic nucleus",
                                 intercepts=Uniform(self.ep, 1),
                                 **ea_params)

        self.gpi = EnsembleArray(label="Globus pallidus internus",
                                 intercepts=Uniform(self.eg, 1),
                                 **ea_params)

        self.gpe = EnsembleArray(label="Globus pallidus externus",
                                 intercepts=Uniform(self.ee, 1),
                                 **ea_params)

        self.input = nengo.Node(label="input", size_in=dimensions)
        self.output = nengo.Node(label="output", size_in=dimensions)

        # add bias input (BG performs best in the range 0.5--1.5)
        if abs(input_bias) > 0.0:
            self.bias_input = nengo.Node([input_bias] * dimensions)
            nengo.Connection(self.bias_input, self.input)

        # spread the input to StrD1, StrD2, and STN
        nengo.Connection(self.input,
                         self.strD1.input,
                         synapse=None,
                         transform=self.ws * (1 + self.lg))
        nengo.Connection(self.input,
                         self.strD2.input,
                         synapse=None,
                         transform=self.ws * (1 - self.le))
        nengo.Connection(self.input,
                         self.stn.input,
                         synapse=None,
                         transform=self.wt)

        # connect the striatum to the GPi and GPe (inhibitory)
        strD1_output = self.strD1.add_output('func_str',
                                             self.str_func,
                                             solver=solver)
        nengo.Connection(strD1_output,
                         self.gpi.input,
                         synapse=tau_gaba,
                         transform=-np.eye(dimensions) * self.wm)
        strD2_output = self.strD2.add_output('func_str',
                                             self.str_func,
                                             solver=solver)
        nengo.Connection(strD2_output,
                         self.gpe.input,
                         synapse=tau_gaba,
                         transform=-np.eye(dimensions) * self.wm)

        # connect the STN to GPi and GPe (broad and excitatory)
        tr = self.wp * np.ones((dimensions, dimensions))
        stn_output = self.stn.add_output('func_stn',
                                         self.stn_func,
                                         solver=solver)
        nengo.Connection(stn_output,
                         self.gpi.input,
                         transform=tr,
                         synapse=tau_ampa)
        nengo.Connection(stn_output,
                         self.gpe.input,
                         transform=tr,
                         synapse=tau_ampa)

        # connect the GPe to GPi and STN (inhibitory)
        gpe_output = self.gpe.add_output('func_gpe',
                                         self.gpe_func,
                                         solver=solver)
        nengo.Connection(gpe_output,
                         self.gpi.input,
                         synapse=tau_gaba,
                         transform=-self.we)
        nengo.Connection(gpe_output,
                         self.stn.input,
                         synapse=tau_gaba,
                         transform=-self.wg)

        # connect GPi to output (inhibitory)
        gpi_output = self.gpi.add_output('func_gpi',
                                         self.gpi_func,
                                         solver=solver)
        nengo.Connection(gpi_output,
                         self.output,
                         synapse=None,
                         transform=output_weight)

    @classmethod
    def str_func(cls, x):
        if x < cls.e:
            return 0
        return cls.mm * (x - cls.e)

    @classmethod
    def stn_func(cls, x):
        if x < cls.ep:
            return 0
        return cls.mp * (x - cls.ep)

    @classmethod
    def gpe_func(cls, x):
        if x < cls.ee:
            return 0
        return cls.me * (x - cls.ee)

    @classmethod
    def gpi_func(cls, x):
        if x < cls.eg:
            return 0
        return cls.mg * (x - cls.eg)
Пример #35
0
    def __init__(self,
                 action_count,
                 n_neurons_per_ensemble=Default,
                 output_weight=Default,
                 input_bias=Default,
                 ampa_synapse=Default,
                 gaba_synapse=Default,
                 **kwargs):
        super(BasalGanglia, self).__init__(**kwargs)

        self.action_count = action_count
        self.n_neurons_per_ensemble = n_neurons_per_ensemble
        self.output_weight = output_weight
        self.input_bias = input_bias
        self.ampa_synapse = ampa_synapse
        self.gaba_synapse = gaba_synapse

        self.input_connections = {}
        # Affects all ensembles / connections in the BG
        # unless overwritten with general_config
        config = nengo.Config(nengo.Ensemble, nengo.Connection)
        config[nengo.Ensemble].radius = 1.5
        config[nengo.Ensemble].encoders = nengo.dists.Choice([[1]])
        try:
            # Best, if we have SciPy
            config[nengo.Connection].solver = nengo.solvers.NnlsL2nz()
        except ImportError:
            warnings.warn("SciPy is not installed, so BasalGanglia will "
                          "use the default decoder solver. Installing "
                          "SciPy may improve BasalGanglia performance.")

        ea_params = {
            "n_neurons": self.n_neurons_per_ensemble,
            "n_ensembles": self.action_count,
        }

        with self, config:
            self.strD1 = EnsembleArray(label="Striatal D1 neurons",
                                       intercepts=nengo.dists.Uniform(
                                           Weights.e, 1),
                                       **ea_params)
            self.strD2 = EnsembleArray(label="Striatal D2 neurons",
                                       intercepts=nengo.dists.Uniform(
                                           Weights.e, 1),
                                       **ea_params)
            self.stn = EnsembleArray(label="Subthalamic nucleus",
                                     intercepts=nengo.dists.Uniform(
                                         Weights.ep, 1),
                                     **ea_params)
            self.gpi = EnsembleArray(label="Globus pallidus internus",
                                     intercepts=nengo.dists.Uniform(
                                         Weights.eg, 1),
                                     **ea_params)
            self.gpe = EnsembleArray(label="Globus pallidus externus",
                                     intercepts=nengo.dists.Uniform(
                                         Weights.ee, 1),
                                     **ea_params)

            self.input = nengo.Node(label="input", size_in=self.action_count)
            self.output = nengo.Node(label="output", size_in=self.action_count)

            # add bias input (BG performs best in the range 0.5--1.5)
            if abs(self.input_bias) > 0.0:
                self.bias_input = nengo.Node(
                    np.ones(self.action_count) * self.input_bias,
                    label="basal ganglia bias",
                )
                nengo.Connection(self.bias_input, self.input)

            # spread the input to StrD1, StrD2, and STN
            nengo.Connection(
                self.input,
                self.strD1.input,
                synapse=None,
                transform=Weights.ws * (1 + Weights.lg),
            )
            nengo.Connection(
                self.input,
                self.strD2.input,
                synapse=None,
                transform=Weights.ws * (1 - Weights.le),
            )
            nengo.Connection(self.input,
                             self.stn.input,
                             synapse=None,
                             transform=Weights.wt)

            # connect the striatum to the GPi and GPe (inhibitory)
            strD1_output = self.strD1.add_output("func_str", Weights.str_func)
            strD2_output = self.strD2.add_output("func_str", Weights.str_func)
            self.gaba = nengo.Network("GABAergic connections")
            self.gaba.config[nengo.Connection].synapse = self.gaba_synapse
            with self.gaba:
                nengo.Connection(strD1_output,
                                 self.gpi.input,
                                 transform=-Weights.wm)
                nengo.Connection(strD2_output,
                                 self.gpe.input,
                                 transform=-Weights.wm)

            # connect the STN to GPi and GPe (broad and excitatory)
            tr = Weights.wp * np.ones((self.action_count, self.action_count))
            stn_output = self.stn.add_output("func_stn", Weights.stn_func)
            self.ampa = nengo.Network("AMPAergic connectiions")
            self.ampa.config[nengo.Connection].synapse = self.ampa_synapse
            with self.ampa:
                nengo.Connection(stn_output, self.gpi.input, transform=tr)
                nengo.Connection(stn_output, self.gpe.input, transform=tr)

            # connect the GPe to GPi and STN (inhibitory)
            gpe_output = self.gpe.add_output("func_gpe", Weights.gpe_func)
            with self.gaba:
                nengo.Connection(gpe_output,
                                 self.gpi.input,
                                 transform=-Weights.we)
                nengo.Connection(gpe_output,
                                 self.stn.input,
                                 transform=-Weights.wg)

            # connect GPi to output (inhibitory)
            gpi_output = self.gpi.add_output("func_gpi", Weights.gpi_func)
            nengo.Connection(gpi_output,
                             self.output,
                             synapse=None,
                             transform=self.output_weight)
Пример #36
0
    def __init__(self,
                 dimensions,
                 n_neurons_per_ensemble=100,
                 output_weight=-3.,
                 input_bias=0.,
                 ampa_config=None,
                 gaba_config=None,
                 **kwargs):
        if 'net' in kwargs:
            raise ObsoleteError("The 'net' argument is no longer supported.")
        kwargs.setdefault('label', "Basal Ganglia")
        super().__init__(**kwargs)

        ampa_config, override_ampa = config_with_default_synapse(
            ampa_config, nengo.Lowpass(0.002))
        gaba_config, override_gaba = config_with_default_synapse(
            gaba_config, nengo.Lowpass(0.008))

        # Affects all ensembles / connections in the BG
        # unless they've been overridden on `self.config`
        config = nengo.Config(nengo.Ensemble, nengo.Connection)
        config[nengo.Ensemble].radius = 1.5
        config[nengo.Ensemble].encoders = Choice([[1]])
        try:
            # Best, if we have SciPy
            config[nengo.Connection].solver = NnlsL2nz()
        except ImportError:
            # Warn if we can't use the better decoder solver.
            warnings.warn("SciPy is not installed, so BasalGanglia will "
                          "use the default decoder solver. Installing SciPy "
                          "may improve BasalGanglia performance.")

        ea_params = {'n_neurons': n_neurons_per_ensemble,
                     'n_ensembles': dimensions}

        with self, config:
            self.strD1 = EnsembleArray(label="Striatal D1 neurons",
                                       intercepts=Uniform(Weights.e, 1),
                                       **ea_params)
            self.strD2 = EnsembleArray(label="Striatal D2 neurons",
                                       intercepts=Uniform(Weights.e, 1),
                                       **ea_params)
            self.stn = EnsembleArray(label="Subthalamic nucleus",
                                     intercepts=Uniform(Weights.ep, 1),
                                     **ea_params)
            self.gpi = EnsembleArray(label="Globus pallidus internus",
                                     intercepts=Uniform(Weights.eg, 1),
                                     **ea_params)
            self.gpe = EnsembleArray(label="Globus pallidus externus",
                                     intercepts=Uniform(Weights.ee, 1),
                                     **ea_params)

            self.input = nengo.Node(label="input", size_in=dimensions)
            self.output = nengo.Node(label="output", size_in=dimensions)

            # add bias input (BG performs best in the range 0.5--1.5)
            if abs(input_bias) > 0.0:
                self.bias_input = nengo.Node(np.ones(dimensions) * input_bias,
                                             label="basal ganglia bias")
                nengo.Connection(self.bias_input, self.input)

            # spread the input to StrD1, StrD2, and STN
            nengo.Connection(self.input, self.strD1.input, synapse=None,
                             transform=Weights.ws * (1 + Weights.lg))
            nengo.Connection(self.input, self.strD2.input, synapse=None,
                             transform=Weights.ws * (1 - Weights.le))
            nengo.Connection(self.input, self.stn.input, synapse=None,
                             transform=Weights.wt)

            # connect the striatum to the GPi and GPe (inhibitory)
            strD1_output = self.strD1.add_output('func_str', Weights.str_func)
            strD2_output = self.strD2.add_output('func_str', Weights.str_func)
            with gaba_config:
                nengo.Connection(strD1_output, self.gpi.input,
                                 transform=-Weights.wm)
                nengo.Connection(strD2_output, self.gpe.input,
                                 transform=-Weights.wm)

            # connect the STN to GPi and GPe (broad and excitatory)
            tr = Weights.wp * np.ones((dimensions, dimensions))
            stn_output = self.stn.add_output('func_stn', Weights.stn_func)
            with ampa_config:
                nengo.Connection(stn_output, self.gpi.input, transform=tr)
                nengo.Connection(stn_output, self.gpe.input, transform=tr)

            # connect the GPe to GPi and STN (inhibitory)
            gpe_output = self.gpe.add_output('func_gpe', Weights.gpe_func)
            with gaba_config:
                nengo.Connection(
                    gpe_output, self.gpi.input, transform=-Weights.we)
                nengo.Connection(
                    gpe_output, self.stn.input, transform=-Weights.wg)

            # connect GPi to output (inhibitory)
            gpi_output = self.gpi.add_output('func_gpi', Weights.gpi_func)
            nengo.Connection(
                gpi_output, self.output, synapse=None, transform=output_weight)

        # Return ampa_config and gaba_config to previous states, if changed
        if override_ampa:
            del ampa_config[nengo.Connection].synapse
        if override_gaba:
            del gaba_config[nengo.Connection].synapse
Пример #37
0
class CircularConvolution(nengo.Network):
    """CircularConvolution docs XXX"""

    def make(self, neurons, dimensions, radius=1,
             invert_a=False, invert_b=False):
        self.transformA = self._input_transform(
            dimensions, first=True, invert=invert_a)
        self.transformB = self._input_transform(
            dimensions, first=False, invert=invert_b)
        self.transformC = self._output_transform(dimensions)

        self.A = nengo.Node(size_in=dimensions, label='A')
        self.B = nengo.Node(size_in=dimensions, label='B')
        self.ensemble = EnsembleArray(neurons,
                                      self.transformC.shape[1],
                                      dimensions=2,
                                      radius=radius, label='conv')
        self.output = nengo.Node(size_in=dimensions, label='output')

        for ens in self.ensemble.ensembles:
            if not isinstance(neurons, nengo.Direct):
                ens.encoders = np.tile(
                    [[1, 1], [-1, 1], [1, -1], [-1, -1]],
                    (ens.n_neurons // 4, 1))
        nengo.Connection(
            self.A, self.ensemble.input, transform=self.transformA,
            filter=None)
        nengo.Connection(
            self.B, self.ensemble.input, transform=self.transformB,
            filter=None)
        nengo.Connection(self.ensemble.add_output('product', self.product),
                         self.output,
                         filter=None,
                         transform=self.transformC)

    @staticmethod
    def _input_transform(dims, first, invert=False):
        dims2 = 4 * (dims // 2 + 1)
        T = np.zeros((dims2, 2, dims))
        dft = _dft_half_cached(dims)

        for i in range(dims2):
            row = dft[i // 4] if not invert else dft[i // 4].conj()
            if first:
                T[i, 0] = row.real if i % 2 == 0 else row.imag
            else:
                T[i, 1] = row.real if i % 4 == 0 or i % 4 == 3 else row.imag

        # --- Throw away rows that we don't need (b/c they're zero)
        i = np.arange(dims2)
        if dims % 2 == 0:
            T = T[(i == 0) | (i > 3) & (i < len(i) - 3)]
        else:
            T = T[(i == 0) | (i > 3)]

        return T.reshape((-1, dims))

    @staticmethod
    def _output_transform(dims):
        dims2 = (dims // 2 + 1)
        T = np.zeros((dims2, 4, dims))
        idft = _dft_half_cached(dims).conj()

        for i in range(dims2):
            row = idft[i] if i == 0 or 2*i == dims else 2*idft[i]
            T[i, 0] = row.real
            T[i, 1] = -row.real
            T[i, 2] = -row.imag
            T[i, 3] = -row.imag

        T = T.reshape(4*dims2, dims)

        # --- Throw away rows that we don't need (b/c they're zero)
        i = np.arange(4*dims2)
        if dims % 2 == 0:
            T = T[(i == 0) | (i > 3) & (i < len(i) - 3)]
        else:
            T = T[(i == 0) | (i > 3)]

        # scaling is needed since we have 1./sqrt(dims) in DFT
        T *= np.sqrt(dims)

        return T.T

    @staticmethod
    def product(x):
        return x[0] * x[1]
Пример #38
0
def Product(n_neurons, dimensions, input_magnitude=1., net=None, **kwargs):
    """Computes the element-wise product of two equally sized vectors.

    The network used to calculate the product is described in
    `Gosmann, 2015`_. A simpler version of this network can be found in the
    `Multiplication example
    <http://pythonhosted.org/nengo/examples/multiplication.html>`_.

    .. _Gosmann, 2015:
       http://nbviewer.jupyter.org/github/ctn-archive/technical-reports/blob/
       master/Precise-multiplications-with-the-NEF.ipynb#An-alternative-network

    Parameters
    ----------
    n_neurons : int
        Number of neurons per dimension in the vector.

        .. note:: These neurons will be distributed evenly across two
                  ensembles. If an odd number of neurons is specified, the
                  extra neuron will not be used.
    dimensions : int
        Number of dimensions in each of the vectors to be multiplied.

    input_magnitude : float, optional (Default: 1.)
        The expected magnitude of the vectors to be multiplied.
        This value is used to determine the radius of the ensembles
        computing the element-wise product.
    kwargs
        Keyword arguments passed through to ``nengo.Network``.

    Returns
    -------
    net : Network
        The newly built product network, or the provided ``net``.

    Attributes
    ----------
    net.input_a : Node
        The first vector to be multiplied.
    net.input_b : Node
        The second vector to be multiplied.
    net.output : Node
        The resulting product.
    net.sq1 : EnsembleArray
        Represents the first squared term. See `Gosmann, 2015`_ for details.
    net.sq2 : EnsembleArray
        Represents the second squared term. See `Gosmann, 2015`_ for details.
    """
    if net is None:
        kwargs.setdefault('label', "Product")
        net = nengo.Network(**kwargs)
    else:
        warnings.warn("The 'net' argument is deprecated.", DeprecationWarning)

    with net:
        net.input_a = net.A = nengo.Node(size_in=dimensions, label="input_a")
        net.input_b = net.B = nengo.Node(size_in=dimensions, label="input_b")
        net.output = nengo.Node(size_in=dimensions, label="output")

        net.sq1 = EnsembleArray(
            max(1, n_neurons // 2), n_ensembles=dimensions, ens_dimensions=1,
            radius=input_magnitude * np.sqrt(2))
        net.sq2 = EnsembleArray(
            max(1, n_neurons // 2), n_ensembles=dimensions, ens_dimensions=1,
            radius=input_magnitude * np.sqrt(2))

        tr = 1. / np.sqrt(2.)
        nengo.Connection(
            net.input_a, net.sq1.input, transform=tr, synapse=None)
        nengo.Connection(
            net.input_b, net.sq1.input, transform=tr, synapse=None)
        nengo.Connection(
            net.input_a, net.sq2.input, transform=tr, synapse=None)
        nengo.Connection(
            net.input_b, net.sq2.input, transform=-tr, synapse=None)

        sq1_out = net.sq1.add_output('square', np.square)
        nengo.Connection(sq1_out, net.output, transform=.5, synapse=None)
        sq2_out = net.sq2.add_output('square', np.square)
        nengo.Connection(sq2_out, net.output, transform=-.5, synapse=None)

    return net
Пример #39
0
    def __init__(self, dimensions, n_neurons_per_ensemble=100, radius=1.5,
                 tau_ampa=0.002, tau_gaba=0.008, output_weight=-3,
                 decoder_solver=nnls_L2nz):
        encoders = np.ones((n_neurons_per_ensemble, 1))
        ea_params = {
            'neurons': nengo.LIF(n_neurons_per_ensemble),
            'n_ensembles': dimensions,
            'radius': radius,
            'encoders': encoders,
        }

        strD1 = EnsembleArray(label="Striatal D1 neurons",
                              intercepts=Uniform(self.e, 1), **ea_params)

        strD2 = EnsembleArray(label="Striatal D2 neurons",
                              intercepts=Uniform(self.e, 1), **ea_params)

        stn = EnsembleArray(label="Subthalamic nucleus",
                            intercepts=Uniform(self.ep, 1), **ea_params)

        gpi = EnsembleArray(label="Globus pallidus internus",
                            intercepts=Uniform(self.eg, 1), **ea_params)

        gpe = EnsembleArray(label="Globus pallidus externus",
                            intercepts=Uniform(self.ee, 1), **ea_params)

        self.input = nengo.Node(label="input", size_in=dimensions)
        self.output = nengo.Node(label="output", size_in=dimensions)

        # spread the input to StrD1, StrD2, and STN
        nengo.Connection(self.input, strD1.input, synapse=None,
                         transform=self.ws * (1 + self.lg))
        nengo.Connection(self.input, strD2.input, synapse=None,
                         transform=self.ws * (1 - self.le))
        nengo.Connection(self.input, stn.input, synapse=None,
                         transform=self.wt)

        # connect the striatum to the GPi and GPe (inhibitory)
        strD1_output = strD1.add_output(
            'func_str', self.str, decoder_solver=decoder_solver)
        nengo.Connection(strD1_output,
                         gpi.input, synapse=tau_gaba,
                         transform=-np.eye(dimensions) * self.wm)
        strD2_output = strD2.add_output(
            'func_str', self.str, decoder_solver=decoder_solver)
        nengo.Connection(strD2_output,
                         gpe.input, synapse=tau_gaba,
                         transform=-np.eye(dimensions) * self.wm)

        # connect the STN to GPi and GPe (broad and excitatory)
        tr = self.wp * np.ones((dimensions, dimensions))
        stn_output = stn.add_output(
            'func_stn', self.stn, decoder_solver=decoder_solver)
        nengo.Connection(stn_output, gpi.input,
                         transform=tr, synapse=tau_ampa)
        nengo.Connection(stn_output, gpe.input,
                         transform=tr, synapse=tau_ampa)

        # connect the GPe to GPi and STN (inhibitory)
        gpe_output = gpe.add_output(
            'func_gpe', self.gpe, decoder_solver=decoder_solver)
        nengo.Connection(gpe_output, gpi.input, synapse=tau_gaba,
                         transform=-self.we)
        nengo.Connection(gpe_output, stn.input, synapse=tau_gaba,
                         transform=-self.wg)

        # connect GPi to output (inhibitory)
        gpi_output = gpi.add_output(
            'func_gpi', self.gpi, decoder_solver=decoder_solver)
        nengo.Connection(gpi_output, self.output, synapse=None,
                         transform=output_weight)
Пример #40
0
class AssociativeMemory(Module):
    """Associative memory module.

    Parameters
    ----------
    input_vocab: list of numpy.array, spa.Vocabulary
        The vocabulary (or list of vectors) to match.
    output_vocab: list of numpy.array, spa.Vocabulary, optional
        The vocabulary (or list of vectors) to be produced for each match. If
        not given, the associative memory will act like an auto-associative
        memory (cleanup memory).
    default_output_vector: numpy.array, spa.SemanticPointer, optional
        The vector to be produced if the input value matches none of vectors
        in the input vector list.
    threshold: float, optional
        The association activation threshold.
    input_scale: float, optional
        Scaling factor to apply on the input vectors.

    inhibitable: boolean, optional
        Flag to indicate if the entire associative memory module is
        inhibitable (entire thing can be shut off).
    inhibit_scale: float, optional
        Scaling factor on the gating connections (must have inhibitable =
        True). Setting a larger value will ensure that the cleanup memory
        output is inhibited at a faster rate, however, recovery of the
        network when inhibition is released will be slower.

    wta_output: boolean, optional
        Flag to indicate if output of the associative memory should contain
        more than one vectors. Set to True if only one vectors output is
        desired -- i.e. a winner-take-all (wta) output. Leave as default
        (False) if (possible) combinations of vectors is desired.
    wta_inhibit_scale: float, optional
        Scaling factor on the winner-take-all (wta) inhibitory connections.
    wta_synapse: float, optional
        Synapse to use for the winner-take-all (wta) inhibitory connections.

    output_utilities: boolean, optional
        Flag to indicate if the direct utilities (in addition to the vectors)
        are output as well.
    output_thresholded_utilities: boolean, optional
        Flag to indicate if the direct thresholded utilities (in addition to
        the vectors) are output as well.

    neuron_type: nengo.Neurons, optional
        Neuron type to use in the associative memory. Defaults to
    n_neurons_per_ensemble: int, optional
        Number of neurons per ensemble in the associative memory. There is
        one ensemble created per vector being compared.

    """
    def __init__(
            self,
            input_vocab,
            output_vocab=None,  # noqa: C901
            default_output_vector=None,
            threshold=0.3,
            input_scale=1.0,
            inhibitable=False,
            inhibit_scale=1.0,
            wta_output=False,
            wta_inhibit_scale=2.0,
            wta_synapse=0.005,
            precise=False,
            output_utilities=False,
            output_thresholded_utilities=False,
            neuron_type=nengo.LIF(),
            n_neurons_per_ensemble=10):
        super(AssociativeMemory, self).__init__()

        # If output vocabulary is not specified, use input vocabulary
        # (i.e autoassociative memory)
        if output_vocab is None:
            output_vocab = input_vocab

        # Handle different vocabulary types
        if isinstance(input_vocab, Vocabulary):
            input_vectors = input_vocab.vectors
        elif is_iterable(input_vocab):
            input_vectors = np.matrix(input_vocab)
        else:
            input_vectors = input_vocab

        if isinstance(output_vocab, Vocabulary):
            output_vectors = output_vocab.vectors
        elif is_iterable(output_vocab):
            output_vectors = np.matrix(output_vocab)
        else:
            output_vectors = output_vocab

        # Fail if number of input items and number of output items don't match
        if input_vectors.shape[0] != output_vectors.shape[0]:
            raise ValueError(
                'number of input vectors does not match number of output '
                'vectors. %d != %d' %
                (input_vectors.shape[0], output_vectors.shape[0]))

        N = len(input_vectors)
        n_eval_points = 1500
        eval_point_margin = 0.0001 if precise == True else 0.1
        eval_points = Uniform(
            threshold + eval_point_margin,
            1 + eval_point_margin).sample(n_eval_points).reshape(-1, 1)

        # Ensemble array parameters
        ea_params = {
            'radius': 1.0,
            'neuron_type': neuron_type,
            'n_neurons': n_neurons_per_ensemble,
            'n_ensembles': N,
            'intercepts': Uniform(threshold, 1),
            'max_rates':
            Uniform(80, 100) if precise == True else Uniform(100, 200),
            'encoders': np.ones((n_neurons_per_ensemble, 1)),
            'eval_points': eval_points
        }

        # Thresholding function
        def threshold_func(x):
            return x > threshold

        # Input and output nodes
        self.input = nengo.Node(size_in=input_vectors.shape[1], label="input")
        self.output = nengo.Node(size_in=output_vectors.shape[1],
                                 label="output")

        # Ensemble array to do the thresholding stuff
        self.thresholded_ens_array = EnsembleArray(
            label="thresholded ens array", **ea_params)

        # Connect input and output nodes
        nengo.Connection(self.input,
                         self.thresholded_ens_array.input,
                         synapse=None,
                         transform=input_vectors * input_scale)
        nengo.Connection(self.thresholded_ens_array.add_output(
            'thresholded_output', threshold_func),
                         self.output,
                         synapse=None,
                         transform=output_vectors.T)

        # Configure associative memory to be inhibitable
        if inhibitable:
            # Input node for inhibitory gating signal (if enabled)
            self.inhibit = nengo.Node(size_in=1, label="inhibit")
            nengo.Connection(self.inhibit,
                             self.thresholded_ens_array.input,
                             synapse=None,
                             transform=-np.ones((N, 1)))
            # Note: We can use decoded connection here because all the
            # encoding vectors are [1]

        # Configure associative memory to have mutually inhibited output
        if wta_output:
            nengo.Connection(self.thresholded_ens_array.output,
                             self.thresholded_ens_array.input,
                             synapse=wta_synapse,
                             transform=(np.eye(N) - 1) * inhibit_scale)

        # Configure utilities output
        if output_utilities:
            self.utilities = nengo.Node(size_in=N, label="utilities")
            nengo.Connection(self.thresholded_ens_array.output,
                             self.utilities,
                             synapse=None)

        # Configure utilities output
        if output_thresholded_utilities:
            self.thresholded_utilities = nengo.Node(
                size_in=N, label="thresholded_utilities")
            nengo.Connection(self.thresholded_ens_array.thresholded_output,
                             self.thresholded_utilities,
                             synapse=None)

        # Configure default output vector
        if default_output_vector is not None:
            eval_points = Uniform(0.8, 1).sample(n_eval_points).reshape(-1, 1)
            bias = nengo.Node(output=[1])
            default_vector_gate = nengo.Ensemble(
                n_neurons_per_ensemble,
                dimensions=1,
                encoders=np.ones((n_neurons_per_ensemble, 1)),
                intercepts=Uniform(0.5, 1),
                max_rates=ea_params['max_rates'],
                eval_points=eval_points,
                label="default vector gate")
            nengo.Connection(bias, default_vector_gate, synapse=None)
            nengo.Connection(self.thresholded_ens_array.thresholded_output,
                             default_vector_gate,
                             transform=-np.ones((1, N)),
                             synapse=0.005)
            nengo.Connection(default_vector_gate,
                             self.output,
                             synapse=None,
                             transform=np.matrix(default_output_vector).T)
            if inhibitable:
                nengo.Connection(self.inhibit,
                                 default_vector_gate,
                                 synapse=None,
                                 transform=[[-1]])

        if isinstance(input_vocab, Vocabulary):
            self.inputs = dict(default=(self.input, input_vocab))
        if isinstance(output_vocab, Vocabulary):
            self.outputs = dict(default=(self.output, output_vocab))
Пример #41
0
class BasalGanglia(nengo.Network):
    """Winner take all network, typically used for action selection.

    The basal ganglia network outputs approximately 0 at the dimension with
    the largest value, and is negative elsewhere.

    While the basal ganglia is primarily defined by its winner-take-all
    function, it is also organized to match the organization of the human
    basal ganglia. It consists of five ensembles:

    * Striatal D1 dopamine-receptor neurons (``strD1``)
    * Striatal D2 dopamine-receptor neurons (``strD2``)
    * Subthalamic nucleus (``stn``)
    * Globus pallidus internus / substantia nigra reticulata (``gpi``)
    * Globus pallidus externus (``gpe``)

    Interconnections between these areas are also based on known
    neuroanatomical connections. See [1]_ for more details, and [2]_ for
    the original non-spiking basal ganglia model by
    Gurney, Prescott & Redgrave that this model is based on.

    .. note:: The default `.Solver` for the basal ganglia is `.NnlsL2nz`, which
              requires SciPy. If SciPy is not installed, the global default
              solver will be used instead.

    Parameters
    ----------
    dimensions : int
        Number of dimensions (i.e., actions).
    n_neurons_per_ensemble : int, optional (Default: 100)
        Number of neurons in each ensemble in the network.
    output_weight : float, optional (Default: -3.)
        A scaling factor on the output of the basal ganglia
        (specifically on the connection out of the GPi).
    input_bias : float, optional (Default: 0.)
        An amount by which to bias all dimensions of the input node.
        Biasing the input node is important for ensuring that all input
        dimensions are positive and easily comparable.
    ampa_config : config, optional (Default: None)
        Configuration for connections corresponding to biological connections
        to AMPA receptors (i.e., connections from STN to to GPi and GPe).
        If None, a default configuration using a 2 ms lowpass synapse
        will be used.
    gaba_config : config, optional (Default: None)
        Configuration for connections corresponding to biological connections
        to GABA receptors (i.e., connections from StrD1 to GPi, StrD2 to GPe,
        and GPe to GPi and STN). If None, a default configuration using an
        8 ms lowpass synapse will be used.
    **kwargs
        Keyword arguments passed through to ``nengo.Network``
        like 'label' and 'seed'.

    Attributes
    ----------
    bias_input : Node or None
        If ``input_bias`` is non-zero, this node will be created to bias
        all of the dimensions of the input signal.
    gpe : EnsembleArray
        Globus pallidus externus ensembles.
    gpi : EnsembleArray
        Globus pallidus internus ensembles.
    input : Node
        Accepts the input signal.
    output : Node
        Provides the output signal.
    stn : EnsembleArray
        Subthalamic nucleus ensembles.
    strD1 : EnsembleArray
        Striatal D1 ensembles.
    strD2 : EnsembleArray
        Striatal D2 ensembles.

    References
    ----------
    .. [1] Stewart, T. C., Choo, X., & Eliasmith, C. (2010).
       Dynamic behaviour of a spiking model of action selection in the
       basal ganglia. In Proceedings of the 10th international conference on
       cognitive modeling (pp. 235-40).
    .. [2] Gurney, K., Prescott, T., & Redgrave, P. (2001).
       A computational model of action selection in the basal
       ganglia. Biological Cybernetics 84, 401-423.
    """
    def __init__(self,
                 dimensions,
                 n_neurons_per_ensemble=100,
                 output_weight=-3.,
                 input_bias=0.,
                 ampa_config=None,
                 gaba_config=None,
                 **kwargs):
        if 'net' in kwargs:
            raise ObsoleteError("The 'net' argument is no longer supported.")
        kwargs.setdefault('label', "Basal Ganglia")
        super().__init__(**kwargs)

        ampa_config, override_ampa = config_with_default_synapse(
            ampa_config, nengo.Lowpass(0.002))
        gaba_config, override_gaba = config_with_default_synapse(
            gaba_config, nengo.Lowpass(0.008))

        # Affects all ensembles / connections in the BG
        # unless they've been overridden on `self.config`
        config = nengo.Config(nengo.Ensemble, nengo.Connection)
        config[nengo.Ensemble].radius = 1.5
        config[nengo.Ensemble].encoders = Choice([[1]])
        try:
            # Best, if we have SciPy
            config[nengo.Connection].solver = NnlsL2nz()
        except ImportError:
            # Warn if we can't use the better decoder solver.
            warnings.warn("SciPy is not installed, so BasalGanglia will "
                          "use the default decoder solver. Installing SciPy "
                          "may improve BasalGanglia performance.")

        ea_params = {'n_neurons': n_neurons_per_ensemble,
                     'n_ensembles': dimensions}

        with self, config:
            self.strD1 = EnsembleArray(label="Striatal D1 neurons",
                                       intercepts=Uniform(Weights.e, 1),
                                       **ea_params)
            self.strD2 = EnsembleArray(label="Striatal D2 neurons",
                                       intercepts=Uniform(Weights.e, 1),
                                       **ea_params)
            self.stn = EnsembleArray(label="Subthalamic nucleus",
                                     intercepts=Uniform(Weights.ep, 1),
                                     **ea_params)
            self.gpi = EnsembleArray(label="Globus pallidus internus",
                                     intercepts=Uniform(Weights.eg, 1),
                                     **ea_params)
            self.gpe = EnsembleArray(label="Globus pallidus externus",
                                     intercepts=Uniform(Weights.ee, 1),
                                     **ea_params)

            self.input = nengo.Node(label="input", size_in=dimensions)
            self.output = nengo.Node(label="output", size_in=dimensions)

            # add bias input (BG performs best in the range 0.5--1.5)
            if abs(input_bias) > 0.0:
                self.bias_input = nengo.Node(np.ones(dimensions) * input_bias,
                                             label="basal ganglia bias")
                nengo.Connection(self.bias_input, self.input)

            # spread the input to StrD1, StrD2, and STN
            nengo.Connection(self.input, self.strD1.input, synapse=None,
                             transform=Weights.ws * (1 + Weights.lg))
            nengo.Connection(self.input, self.strD2.input, synapse=None,
                             transform=Weights.ws * (1 - Weights.le))
            nengo.Connection(self.input, self.stn.input, synapse=None,
                             transform=Weights.wt)

            # connect the striatum to the GPi and GPe (inhibitory)
            strD1_output = self.strD1.add_output('func_str', Weights.str_func)
            strD2_output = self.strD2.add_output('func_str', Weights.str_func)
            with gaba_config:
                nengo.Connection(strD1_output, self.gpi.input,
                                 transform=-Weights.wm)
                nengo.Connection(strD2_output, self.gpe.input,
                                 transform=-Weights.wm)

            # connect the STN to GPi and GPe (broad and excitatory)
            tr = Weights.wp * np.ones((dimensions, dimensions))
            stn_output = self.stn.add_output('func_stn', Weights.stn_func)
            with ampa_config:
                nengo.Connection(stn_output, self.gpi.input, transform=tr)
                nengo.Connection(stn_output, self.gpe.input, transform=tr)

            # connect the GPe to GPi and STN (inhibitory)
            gpe_output = self.gpe.add_output('func_gpe', Weights.gpe_func)
            with gaba_config:
                nengo.Connection(
                    gpe_output, self.gpi.input, transform=-Weights.we)
                nengo.Connection(
                    gpe_output, self.stn.input, transform=-Weights.wg)

            # connect GPi to output (inhibitory)
            gpi_output = self.gpi.add_output('func_gpi', Weights.gpi_func)
            nengo.Connection(
                gpi_output, self.output, synapse=None, transform=output_weight)

        # Return ampa_config and gaba_config to previous states, if changed
        if override_ampa:
            del ampa_config[nengo.Connection].synapse
        if override_gaba:
            del gaba_config[nengo.Connection].synapse
Пример #42
0
class BasalGanglia(nengo.Network):
    """Winner takes all; outputs 0 at max dimension, negative elsewhere."""

    # connection weights from (Gurney, Prescott, & Redgrave, 2001)
    mm = 1
    mp = 1
    me = 1
    mg = 1
    ws = 1
    wt = 1
    wm = 1
    wg = 1
    wp = 0.9
    we = 0.3
    e = 0.2
    ep = -0.25
    ee = -0.2
    eg = -0.2
    le = 0.2
    lg = 0.2

    def __init__(self, dimensions, n_neurons_per_ensemble=100, radius=1.5,
                 tau_ampa=0.002, tau_gaba=0.008, output_weight=-3,
                 input_bias=0.0, solver=None):
        if solver is None:
            try:
                # Best, if we have SciPy
                solver = NnlsL2nz()
            except ImportError:
                # If not, use default
                warnings.warn("SciPy is not installed, so BasalGanglia will "
                              "use default decoder solver. Installing SciPy "
                              "may improve BasalGanglia performance.")
                solver = nengo.Default
        encoders = np.ones((n_neurons_per_ensemble, 1))
        ea_params = {
            'n_neurons': n_neurons_per_ensemble,
            'n_ensembles': dimensions,
            'radius': radius,
            'encoders': encoders,
        }

        self.strD1 = EnsembleArray(label="Striatal D1 neurons",
                                   intercepts=Uniform(self.e, 1), **ea_params)

        self.strD2 = EnsembleArray(label="Striatal D2 neurons",
                                   intercepts=Uniform(self.e, 1), **ea_params)

        self.stn = EnsembleArray(label="Subthalamic nucleus",
                                 intercepts=Uniform(self.ep, 1), **ea_params)

        self.gpi = EnsembleArray(label="Globus pallidus internus",
                                 intercepts=Uniform(self.eg, 1), **ea_params)

        self.gpe = EnsembleArray(label="Globus pallidus externus",
                                 intercepts=Uniform(self.ee, 1), **ea_params)

        self.input = nengo.Node(label="input", size_in=dimensions)
        self.output = nengo.Node(label="output", size_in=dimensions)

        # add bias input (BG performs best in the range 0.5--1.5)
        if abs(input_bias) > 0.0:
            self.bias_input = nengo.Node([input_bias] * dimensions)
            nengo.Connection(self.bias_input, self.input)

        # spread the input to StrD1, StrD2, and STN
        nengo.Connection(self.input, self.strD1.input, synapse=None,
                         transform=self.ws * (1 + self.lg))
        nengo.Connection(self.input, self.strD2.input, synapse=None,
                         transform=self.ws * (1 - self.le))
        nengo.Connection(self.input, self.stn.input, synapse=None,
                         transform=self.wt)

        # connect the striatum to the GPi and GPe (inhibitory)
        strD1_output = self.strD1.add_output(
            'func_str', self.str_func, solver=solver)
        nengo.Connection(strD1_output,
                         self.gpi.input, synapse=tau_gaba,
                         transform=-np.eye(dimensions) * self.wm)
        strD2_output = self.strD2.add_output(
            'func_str', self.str_func, solver=solver)
        nengo.Connection(strD2_output,
                         self.gpe.input, synapse=tau_gaba,
                         transform=-np.eye(dimensions) * self.wm)

        # connect the STN to GPi and GPe (broad and excitatory)
        tr = self.wp * np.ones((dimensions, dimensions))
        stn_output = self.stn.add_output(
            'func_stn', self.stn_func, solver=solver)
        nengo.Connection(stn_output, self.gpi.input,
                         transform=tr, synapse=tau_ampa)
        nengo.Connection(stn_output, self.gpe.input,
                         transform=tr, synapse=tau_ampa)

        # connect the GPe to GPi and STN (inhibitory)
        gpe_output = self.gpe.add_output(
            'func_gpe', self.gpe_func, solver=solver)
        nengo.Connection(gpe_output, self.gpi.input, synapse=tau_gaba,
                         transform=-self.we)
        nengo.Connection(gpe_output, self.stn.input, synapse=tau_gaba,
                         transform=-self.wg)

        # connect GPi to output (inhibitory)
        gpi_output = self.gpi.add_output(
            'func_gpi', self.gpi_func, solver=solver)
        nengo.Connection(gpi_output, self.output, synapse=None,
                         transform=output_weight)

    @classmethod
    def str_func(cls, x):
        if x < cls.e:
            return 0
        return cls.mm * (x - cls.e)

    @classmethod
    def stn_func(cls, x):
        if x < cls.ep:
            return 0
        return cls.mp * (x - cls.ep)

    @classmethod
    def gpe_func(cls, x):
        if x < cls.ee:
            return 0
        return cls.me * (x - cls.ee)

    @classmethod
    def gpi_func(cls, x):
        if x < cls.eg:
            return 0
        return cls.mg * (x - cls.eg)
Пример #43
0
def BasalGanglia(dimensions,
                 n_neurons_per_ensemble=100,
                 output_weight=-3,
                 input_bias=0.0,
                 ampa_config=None,
                 gaba_config=None,
                 net=None):
    """Winner takes all; outputs 0 at max dimension, negative elsewhere."""

    if net is None:
        net = nengo.Network("Basal Ganglia")

    ampa_config, override_ampa = config_with_default_synapse(
        ampa_config, nengo.Lowpass(0.002))
    gaba_config, override_gaba = config_with_default_synapse(
        gaba_config, nengo.Lowpass(0.008))

    # Affects all ensembles / connections in the BG
    # unless they've been overridden on `net.config`
    config = nengo.Config(nengo.Ensemble, nengo.Connection)
    config[nengo.Ensemble].radius = 1.5
    config[nengo.Ensemble].encoders = Choice([[1]])
    try:
        # Best, if we have SciPy
        config[nengo.Connection].solver = NnlsL2nz()
    except ImportError:
        # Warn if we can't use the better decoder solver.
        warnings.warn("SciPy is not installed, so BasalGanglia will "
                      "use the default decoder solver. Installing SciPy "
                      "may improve BasalGanglia performance.")

    ea_params = {
        'n_neurons': n_neurons_per_ensemble,
        'n_ensembles': dimensions
    }

    with config, net:
        net.strD1 = EnsembleArray(label="Striatal D1 neurons",
                                  intercepts=Uniform(Weights.e, 1),
                                  **ea_params)
        net.strD2 = EnsembleArray(label="Striatal D2 neurons",
                                  intercepts=Uniform(Weights.e, 1),
                                  **ea_params)
        net.stn = EnsembleArray(label="Subthalamic nucleus",
                                intercepts=Uniform(Weights.ep, 1),
                                **ea_params)
        net.gpi = EnsembleArray(label="Globus pallidus internus",
                                intercepts=Uniform(Weights.eg, 1),
                                **ea_params)
        net.gpe = EnsembleArray(label="Globus pallidus externus",
                                intercepts=Uniform(Weights.ee, 1),
                                **ea_params)

        net.input = nengo.Node(label="input", size_in=dimensions)
        net.output = nengo.Node(label="output", size_in=dimensions)

        # add bias input (BG performs best in the range 0.5--1.5)
        if abs(input_bias) > 0.0:
            net.bias_input = nengo.Node(np.ones(dimensions) * input_bias,
                                        label="basal ganglia bias")
            nengo.Connection(net.bias_input, net.input)

        # spread the input to StrD1, StrD2, and STN
        nengo.Connection(net.input,
                         net.strD1.input,
                         synapse=None,
                         transform=Weights.ws * (1 + Weights.lg))
        nengo.Connection(net.input,
                         net.strD2.input,
                         synapse=None,
                         transform=Weights.ws * (1 - Weights.le))
        nengo.Connection(net.input,
                         net.stn.input,
                         synapse=None,
                         transform=Weights.wt)

        # connect the striatum to the GPi and GPe (inhibitory)
        strD1_output = net.strD1.add_output('func_str', Weights.str_func)
        strD2_output = net.strD2.add_output('func_str', Weights.str_func)
        with gaba_config:
            nengo.Connection(strD1_output,
                             net.gpi.input,
                             transform=-Weights.wm)
            nengo.Connection(strD2_output,
                             net.gpe.input,
                             transform=-Weights.wm)

        # connect the STN to GPi and GPe (broad and excitatory)
        tr = Weights.wp * np.ones((dimensions, dimensions))
        stn_output = net.stn.add_output('func_stn', Weights.stn_func)
        with ampa_config:
            nengo.Connection(stn_output, net.gpi.input, transform=tr)
            nengo.Connection(stn_output, net.gpe.input, transform=tr)

        # connect the GPe to GPi and STN (inhibitory)
        gpe_output = net.gpe.add_output('func_gpe', Weights.gpe_func)
        with gaba_config:
            nengo.Connection(gpe_output, net.gpi.input, transform=-Weights.we)
            nengo.Connection(gpe_output, net.stn.input, transform=-Weights.wg)

        # connect GPi to output (inhibitory)
        gpi_output = net.gpi.add_output('func_gpi', Weights.gpi_func)
        nengo.Connection(gpi_output,
                         net.output,
                         synapse=None,
                         transform=output_weight)

    # Return ampa_config and gaba_config to previous states, if changed
    if override_ampa:
        del ampa_config[nengo.Connection].synapse
    if override_gaba:
        del gaba_config[nengo.Connection].synapse

    return net
Пример #44
0
    def __init__(self,
                 dimensions,
                 n_neurons_per_ensemble=100,
                 output_weight=-3.0,
                 input_bias=0.0,
                 ampa_config=None,
                 gaba_config=None,
                 **kwargs):
        if "net" in kwargs:
            raise ObsoleteError("The 'net' argument is no longer supported.")
        kwargs.setdefault("label", "Basal Ganglia")
        super().__init__(**kwargs)

        ampa_config, override_ampa = config_with_default_synapse(
            ampa_config, nengo.Lowpass(0.002))
        gaba_config, override_gaba = config_with_default_synapse(
            gaba_config, nengo.Lowpass(0.008))

        # Affects all ensembles / connections in the BG
        # unless they've been overridden on `self.config`
        config = nengo.Config(nengo.Ensemble, nengo.Connection)
        config[nengo.Ensemble].radius = 1.5
        config[nengo.Ensemble].encoders = Choice([[1]])
        try:
            # Best, if we have SciPy
            config[nengo.Connection].solver = NnlsL2nz()
        except ImportError:
            # Warn if we can't use the better decoder solver.
            warnings.warn("SciPy is not installed, so BasalGanglia will "
                          "use the default decoder solver. Installing SciPy "
                          "may improve BasalGanglia performance.")

        ea_params = {
            "n_neurons": n_neurons_per_ensemble,
            "n_ensembles": dimensions
        }

        with self, config:
            self.strD1 = EnsembleArray(
                label="Striatal D1 neurons",
                intercepts=Uniform(Weights.e, 1),
                **ea_params,
            )
            self.strD2 = EnsembleArray(
                label="Striatal D2 neurons",
                intercepts=Uniform(Weights.e, 1),
                **ea_params,
            )
            self.stn = EnsembleArray(
                label="Subthalamic nucleus",
                intercepts=Uniform(Weights.ep, 1),
                **ea_params,
            )
            self.gpi = EnsembleArray(
                label="Globus pallidus internus",
                intercepts=Uniform(Weights.eg, 1),
                **ea_params,
            )
            self.gpe = EnsembleArray(
                label="Globus pallidus externus",
                intercepts=Uniform(Weights.ee, 1),
                **ea_params,
            )

            self.input = nengo.Node(label="input", size_in=dimensions)
            self.output = nengo.Node(label="output", size_in=dimensions)

            # add bias input (BG performs best in the range 0.5--1.5)
            if abs(input_bias) > 0.0:
                self.bias_input = nengo.Node(np.ones(dimensions) * input_bias,
                                             label="basal ganglia bias")
                nengo.Connection(self.bias_input, self.input)

            # spread the input to StrD1, StrD2, and STN
            nengo.Connection(
                self.input,
                self.strD1.input,
                synapse=None,
                transform=Weights.ws * (1 + Weights.lg),
            )
            nengo.Connection(
                self.input,
                self.strD2.input,
                synapse=None,
                transform=Weights.ws * (1 - Weights.le),
            )
            nengo.Connection(self.input,
                             self.stn.input,
                             synapse=None,
                             transform=Weights.wt)

            # connect the striatum to the GPi and GPe (inhibitory)
            strD1_output = self.strD1.add_output("func_str", Weights.str_func)
            strD2_output = self.strD2.add_output("func_str", Weights.str_func)
            with gaba_config:
                nengo.Connection(strD1_output,
                                 self.gpi.input,
                                 transform=-Weights.wm)
                nengo.Connection(strD2_output,
                                 self.gpe.input,
                                 transform=-Weights.wm)

            # connect the STN to GPi and GPe (broad and excitatory)
            tr = Weights.wp * np.ones((dimensions, dimensions))
            stn_output = self.stn.add_output("func_stn", Weights.stn_func)
            with ampa_config:
                nengo.Connection(stn_output, self.gpi.input, transform=tr)
                nengo.Connection(stn_output, self.gpe.input, transform=tr)

            # connect the GPe to GPi and STN (inhibitory)
            gpe_output = self.gpe.add_output("func_gpe", Weights.gpe_func)
            with gaba_config:
                nengo.Connection(gpe_output,
                                 self.gpi.input,
                                 transform=-Weights.we)
                nengo.Connection(gpe_output,
                                 self.stn.input,
                                 transform=-Weights.wg)

            # connect GPi to output (inhibitory)
            gpi_output = self.gpi.add_output("func_gpi", Weights.gpi_func)
            nengo.Connection(gpi_output,
                             self.output,
                             synapse=None,
                             transform=output_weight)

        # Return ampa_config and gaba_config to previous states, if changed
        if override_ampa:
            del ampa_config[nengo.Connection].synapse
        if override_gaba:
            del gaba_config[nengo.Connection].synapse
Пример #45
0
def Product(n_neurons, dimensions, input_magnitude=1., net=None, **kwargs):
    """Computes the element-wise product of two equally sized vectors.

    The network used to calculate the product is described in
    `Gosmann, 2015`_. A simpler version of this network can be found in the
    `Multiplication example
    <http://pythonhosted.org/nengo/examples/multiplication.html>`_.

    Note that this network is optimized under the assumption that both input
    values (or both values for each input dimensions of the input vectors) are
    uniformly and independently distributed. Visualized in a joint 2D space,
    this would give a square of equal probabilities for pairs of input values.
    This assumption is violated with non-uniform input value distributions
    (for example, if the input values follow a Gaussian or cosine similarity
    distribution). In that case, no square of equal probabilities is obtained,
    but a probability landscape with circular equi-probability lines. To obtain
    the optimal network accuracy, scale the *input_magnitude* by a factor of
    ``1 / sqrt(2)``.

    .. _Gosmann, 2015:
       http://nbviewer.jupyter.org/github/ctn-archive/technical-reports/blob/
       master/Precise-multiplications-with-the-NEF.ipynb#An-alternative-network

    Parameters
    ----------
    n_neurons : int
        Number of neurons per dimension in the vector.

        .. note:: These neurons will be distributed evenly across two
                  ensembles. If an odd number of neurons is specified, the
                  extra neuron will not be used.
    dimensions : int
        Number of dimensions in each of the vectors to be multiplied.

    input_magnitude : float, optional (Default: 1.)
        The expected magnitude of the vectors to be multiplied.
        This value is used to determine the radius of the ensembles
        computing the element-wise product.
    kwargs
        Keyword arguments passed through to ``nengo.Network``.

    Returns
    -------
    net : Network
        The newly built product network, or the provided ``net``.

    Attributes
    ----------
    net.input_a : Node
        The first vector to be multiplied.
    net.input_b : Node
        The second vector to be multiplied.
    net.output : Node
        The resulting product.
    net.sq1 : EnsembleArray
        Represents the first squared term. See `Gosmann, 2015`_ for details.
    net.sq2 : EnsembleArray
        Represents the second squared term. See `Gosmann, 2015`_ for details.
    """
    if net is None:
        kwargs.setdefault('label', "Product")
        net = nengo.Network(**kwargs)
    else:
        warnings.warn("The 'net' argument is deprecated.", DeprecationWarning)

    with net:
        net.input_a = net.A = nengo.Node(size_in=dimensions, label="input_a")
        net.input_b = net.B = nengo.Node(size_in=dimensions, label="input_b")
        net.output = nengo.Node(size_in=dimensions, label="output")

        net.sq1 = EnsembleArray(max(1, n_neurons // 2),
                                n_ensembles=dimensions,
                                ens_dimensions=1,
                                radius=input_magnitude * np.sqrt(2))
        net.sq2 = EnsembleArray(max(1, n_neurons // 2),
                                n_ensembles=dimensions,
                                ens_dimensions=1,
                                radius=input_magnitude * np.sqrt(2))

        tr = 1. / np.sqrt(2.)
        nengo.Connection(net.input_a,
                         net.sq1.input,
                         transform=tr,
                         synapse=None)
        nengo.Connection(net.input_b,
                         net.sq1.input,
                         transform=tr,
                         synapse=None)
        nengo.Connection(net.input_a,
                         net.sq2.input,
                         transform=tr,
                         synapse=None)
        nengo.Connection(net.input_b,
                         net.sq2.input,
                         transform=-tr,
                         synapse=None)

        sq1_out = net.sq1.add_output('square', np.square)
        nengo.Connection(sq1_out, net.output, transform=.5, synapse=None)
        sq2_out = net.sq2.add_output('square', np.square)
        nengo.Connection(sq2_out, net.output, transform=-.5, synapse=None)

    return net
Пример #46
0
class BasalGanglia(nengo.Network):
    """Winner take all network, typically used for action selection.

    The basal ganglia network outputs approximately 0 at the dimension with
    the largest value, and is negative elsewhere.

    While the basal ganglia is primarily defined by its winner-take-all
    function, it is also organized to match the organization of the human
    basal ganglia. It consists of five ensembles:

    * Striatal D1 dopamine-receptor neurons (``strD1``)
    * Striatal D2 dopamine-receptor neurons (``strD2``)
    * Subthalamic nucleus (``stn``)
    * Globus pallidus internus / substantia nigra reticulata (``gpi``)
    * Globus pallidus externus (``gpe``)

    Interconnections between these areas are also based on known
    neuroanatomical connections. See [1]_ for more details, and [2]_ for
    the original non-spiking basal ganglia model by
    Gurney, Prescott & Redgrave that this model is based on.

    .. note:: The default `.Solver` for the basal ganglia is `.NnlsL2nz`, which
              requires SciPy. If SciPy is not installed, the global default
              solver will be used instead.

    Parameters
    ----------
    dimensions : int
        Number of dimensions (i.e., actions).
    n_neurons_per_ensemble : int, optional
        Number of neurons in each ensemble in the network.
    output_weight : float, optional
        A scaling factor on the output of the basal ganglia
        (specifically on the connection out of the GPi).
    input_bias : float, optional
        An amount by which to bias all dimensions of the input node.
        Biasing the input node is important for ensuring that all input
        dimensions are positive and easily comparable.
    ampa_config : config, optional
        Configuration for connections corresponding to biological connections
        to AMPA receptors (i.e., connections from STN to to GPi and GPe).
        If None, a default configuration using a 2 ms lowpass synapse
        will be used.
    gaba_config : config, optional
        Configuration for connections corresponding to biological connections
        to GABA receptors (i.e., connections from StrD1 to GPi, StrD2 to GPe,
        and GPe to GPi and STN). If None, a default configuration using an
        8 ms lowpass synapse will be used.
    **kwargs
        Keyword arguments passed through to ``nengo.Network``
        like 'label' and 'seed'.

    Attributes
    ----------
    bias_input : Node or None
        If ``input_bias`` is non-zero, this node will be created to bias
        all of the dimensions of the input signal.
    gpe : EnsembleArray
        Globus pallidus externus ensembles.
    gpi : EnsembleArray
        Globus pallidus internus ensembles.
    input : Node
        Accepts the input signal.
    output : Node
        Provides the output signal.
    stn : EnsembleArray
        Subthalamic nucleus ensembles.
    strD1 : EnsembleArray
        Striatal D1 ensembles.
    strD2 : EnsembleArray
        Striatal D2 ensembles.

    References
    ----------
    .. [1] Stewart, T. C., Choo, X., & Eliasmith, C. (2010).
       Dynamic behaviour of a spiking model of action selection in the
       basal ganglia. In Proceedings of the 10th international conference on
       cognitive modeling (pp. 235-40).
    .. [2] Gurney, K., Prescott, T., & Redgrave, P. (2001).
       A computational model of action selection in the basal
       ganglia. Biological Cybernetics 84, 401-423.
    """
    def __init__(self,
                 dimensions,
                 n_neurons_per_ensemble=100,
                 output_weight=-3.0,
                 input_bias=0.0,
                 ampa_config=None,
                 gaba_config=None,
                 **kwargs):
        if "net" in kwargs:
            raise ObsoleteError("The 'net' argument is no longer supported.")
        kwargs.setdefault("label", "Basal Ganglia")
        super().__init__(**kwargs)

        ampa_config, override_ampa = config_with_default_synapse(
            ampa_config, nengo.Lowpass(0.002))
        gaba_config, override_gaba = config_with_default_synapse(
            gaba_config, nengo.Lowpass(0.008))

        # Affects all ensembles / connections in the BG
        # unless they've been overridden on `self.config`
        config = nengo.Config(nengo.Ensemble, nengo.Connection)
        config[nengo.Ensemble].radius = 1.5
        config[nengo.Ensemble].encoders = Choice([[1]])
        try:
            # Best, if we have SciPy
            config[nengo.Connection].solver = NnlsL2nz()
        except ImportError:
            # Warn if we can't use the better decoder solver.
            warnings.warn("SciPy is not installed, so BasalGanglia will "
                          "use the default decoder solver. Installing SciPy "
                          "may improve BasalGanglia performance.")

        ea_params = {
            "n_neurons": n_neurons_per_ensemble,
            "n_ensembles": dimensions
        }

        with self, config:
            self.strD1 = EnsembleArray(
                label="Striatal D1 neurons",
                intercepts=Uniform(Weights.e, 1),
                **ea_params,
            )
            self.strD2 = EnsembleArray(
                label="Striatal D2 neurons",
                intercepts=Uniform(Weights.e, 1),
                **ea_params,
            )
            self.stn = EnsembleArray(
                label="Subthalamic nucleus",
                intercepts=Uniform(Weights.ep, 1),
                **ea_params,
            )
            self.gpi = EnsembleArray(
                label="Globus pallidus internus",
                intercepts=Uniform(Weights.eg, 1),
                **ea_params,
            )
            self.gpe = EnsembleArray(
                label="Globus pallidus externus",
                intercepts=Uniform(Weights.ee, 1),
                **ea_params,
            )

            self.input = nengo.Node(label="input", size_in=dimensions)
            self.output = nengo.Node(label="output", size_in=dimensions)

            # add bias input (BG performs best in the range 0.5--1.5)
            if abs(input_bias) > 0.0:
                self.bias_input = nengo.Node(np.ones(dimensions) * input_bias,
                                             label="basal ganglia bias")
                nengo.Connection(self.bias_input, self.input)

            # spread the input to StrD1, StrD2, and STN
            nengo.Connection(
                self.input,
                self.strD1.input,
                synapse=None,
                transform=Weights.ws * (1 + Weights.lg),
            )
            nengo.Connection(
                self.input,
                self.strD2.input,
                synapse=None,
                transform=Weights.ws * (1 - Weights.le),
            )
            nengo.Connection(self.input,
                             self.stn.input,
                             synapse=None,
                             transform=Weights.wt)

            # connect the striatum to the GPi and GPe (inhibitory)
            strD1_output = self.strD1.add_output("func_str", Weights.str_func)
            strD2_output = self.strD2.add_output("func_str", Weights.str_func)
            with gaba_config:
                nengo.Connection(strD1_output,
                                 self.gpi.input,
                                 transform=-Weights.wm)
                nengo.Connection(strD2_output,
                                 self.gpe.input,
                                 transform=-Weights.wm)

            # connect the STN to GPi and GPe (broad and excitatory)
            tr = Weights.wp * np.ones((dimensions, dimensions))
            stn_output = self.stn.add_output("func_stn", Weights.stn_func)
            with ampa_config:
                nengo.Connection(stn_output, self.gpi.input, transform=tr)
                nengo.Connection(stn_output, self.gpe.input, transform=tr)

            # connect the GPe to GPi and STN (inhibitory)
            gpe_output = self.gpe.add_output("func_gpe", Weights.gpe_func)
            with gaba_config:
                nengo.Connection(gpe_output,
                                 self.gpi.input,
                                 transform=-Weights.we)
                nengo.Connection(gpe_output,
                                 self.stn.input,
                                 transform=-Weights.wg)

            # connect GPi to output (inhibitory)
            gpi_output = self.gpi.add_output("func_gpi", Weights.gpi_func)
            nengo.Connection(gpi_output,
                             self.output,
                             synapse=None,
                             transform=output_weight)

        # Return ampa_config and gaba_config to previous states, if changed
        if override_ampa:
            del ampa_config[nengo.Connection].synapse
        if override_gaba:
            del gaba_config[nengo.Connection].synapse
Пример #47
0
class Product(nengo.Network):
    """Computes the element-wise product of two equally sized vectors.

    The network used to calculate the product is described in
    `Gosmann, 2015`_. A simpler version of this network can be found in the
    :doc:`Multiplication example <examples/basic/multiplication>`.

    Note that this network is optimized under the assumption that both input
    values (or both values for each input dimensions of the input vectors) are
    uniformly and independently distributed. Visualized in a joint 2D space,
    this would give a square of equal probabilities for pairs of input values.
    This assumption is violated with non-uniform input value distributions
    (for example, if the input values follow a Gaussian or cosine similarity
    distribution). In that case, no square of equal probabilities is obtained,
    but a probability landscape with circular equi-probability lines. To obtain
    the optimal network accuracy, scale the *input_magnitude* by a factor of
    ``1 / sqrt(2)``.

    .. _Gosmann, 2015:
       https://nbviewer.jupyter.org/github/ctn-archive/technical-reports/blob/
       master/Precise-multiplications-with-the-NEF.ipynb

    Parameters
    ----------
    n_neurons : int
        Number of neurons per dimension in the vector.

        .. note:: These neurons will be distributed evenly across two
                  ensembles. If an odd number of neurons is specified, the
                  extra neuron will not be used.
    dimensions : int
        Number of dimensions in each of the vectors to be multiplied.

    input_magnitude : float, optional (Default: 1.)
        The expected magnitude of the vectors to be multiplied.
        This value is used to determine the radius of the ensembles
        computing the element-wise product.
    **kwargs
        Keyword arguments passed through to ``nengo.Network``
        like 'label' and 'seed'.

    Attributes
    ----------
    input_a : Node
        The first vector to be multiplied.
    input_b : Node
        The second vector to be multiplied.
    output : Node
        The resulting product.
    sq1 : EnsembleArray
        Represents the first squared term. See `Gosmann, 2015`_ for details.
    sq2 : EnsembleArray
        Represents the second squared term. See `Gosmann, 2015`_ for details.
    """
    def __init__(self, n_neurons, dimensions, input_magnitude=1., **kwargs):
        if 'net' in kwargs:
            raise ObsoleteError("The 'net' argument is no longer supported.")
        kwargs.setdefault('label', "Product")
        super().__init__(**kwargs)

        with self:
            self.input_a = nengo.Node(size_in=dimensions, label="input_a")
            self.input_b = nengo.Node(size_in=dimensions, label="input_b")
            self.output = nengo.Node(size_in=dimensions, label="output")

            self.sq1 = EnsembleArray(
                max(1, n_neurons // 2),
                n_ensembles=dimensions,
                ens_dimensions=1,
                radius=input_magnitude * np.sqrt(2),
            )
            self.sq2 = EnsembleArray(
                max(1, n_neurons // 2),
                n_ensembles=dimensions,
                ens_dimensions=1,
                radius=input_magnitude * np.sqrt(2),
            )

            tr = 1. / np.sqrt(2.)
            nengo.Connection(self.input_a,
                             self.sq1.input,
                             transform=tr,
                             synapse=None)
            nengo.Connection(self.input_b,
                             self.sq1.input,
                             transform=tr,
                             synapse=None)
            nengo.Connection(self.input_a,
                             self.sq2.input,
                             transform=tr,
                             synapse=None)
            nengo.Connection(self.input_b,
                             self.sq2.input,
                             transform=-tr,
                             synapse=None)

            sq1_out = self.sq1.add_output('square', np.square)
            nengo.Connection(sq1_out, self.output, transform=.5, synapse=None)
            sq2_out = self.sq2.add_output('square', np.square)
            nengo.Connection(sq2_out, self.output, transform=-.5, synapse=None)

    @property
    def A(self):
        warnings.warn(DeprecationWarning("Use 'input_a' instead of 'A'."))
        return self.input_a

    @property
    def B(self):
        warnings.warn(DeprecationWarning("Use 'input_b' instead of 'B'."))
        return self.input_b
Пример #48
0
class BasalGanglia(Network):
    """Winner take all network, typically used for action selection.

    The basal ganglia network outputs approximately 0 at the dimension with
    the largest value, and is negative elsewhere.

    While the basal ganglia is primarily defined by its winner-take-all
    function, it is also organized to match the organization of the human
    basal ganglia. It consists of five ensembles:

    * Striatal D1 dopamine-receptor neurons (*strD1*)
    * Striatal D2 dopamine-receptor neurons (*strD2*)
    * Subthalamic nucleus (*stn*)
    * Globus pallidus internus / substantia nigra reticulata (*gpi*)
    * Globus pallidus externus (*gpe*)

    Interconnections between these areas are also based on known
    neuroanatomical connections. See [1]_ for more details, and [2]_ for
    the original non-spiking basal ganglia model by
    Gurney, Prescott & Redgrave that this model is based on.

    .. note:: The default `nengo.solvers.Solver` for the basal ganglia is
              `nengo.solvers.NnlsL2nz`, which requires SciPy. If SciPy is not
              installed, the global default solver will be used instead.

    Parameters
    ----------
    action_count : int
        Number of actions.
    n_neuron_per_ensemble : int, optional
        Number of neurons in each ensemble in the network.
    output_weight : float, optional
        A scaling factor on the output of the basal ganglia
        (specifically on the connection out of the GPi).
    input_bias : float, optional
        An amount by which to bias all dimensions of the input node.
        Biasing the input node is important for ensuring that all input
        dimensions are positive and easily comparable.
    ampa_synapse : Synapse, optional
        Synapse for connections corresponding to biological connections
        to AMPA receptors (i.e., connections from STN to to GPi and GPe).
    gaba_synapse : Synapse, optional
        Synapse for connections corresponding to biological connections
        to GABA receptors (i.e., connections from StrD1 to GPi, StrD2 to GPe,
        and GPe to GPi and STN).
    kwargs
        Passed through the `nengo_spa.Network`.

    Attributes
    ----------
    bias_input : nengo.Node or None
        If *input_bias* is non-zero, this node will be created to bias
        all of the dimensions of the input signal.
    gpe : nengo.networks.EnsembleArray
        Globus pallidus externus ensembles.
    gpi : nengo.networks.EnsembleArray
        Globus pallidus internus ensembles.
    input : nengo.Node
        Accepts the input signal.
    output : nengo.Node
        Provides the output signal.
    stn : nengo.networks.EnsembleArray
        Subthalamic nucleus ensembles.
    strD1 : nengo.networks.EnsembleArray
        Striatal D1 ensembles.
    strD2 : nengo.networks.EnsembleArray
        Striatal D2 ensembles.

    References
    ----------
    .. [1] Stewart, T. C., Choo, X., & Eliasmith, C. (2010).
       Dynamic behaviour of a spiking model of action selection in the
       basal ganglia. In Proceedings of the 10th international conference on
       cognitive modeling (pp. 235-40).
    .. [2] Gurney, K., Prescott, T., & Redgrave, P. (2001).
       A computational model of action selection in the basal
       ganglia. Biological Cybernetics 84, 401-423.
    """

    input_synapse = SynapseParam('input_synapse', default=Lowpass(0.002))
    ampa_synapse = SynapseParam('ampa_synapse', default=Lowpass(0.002))
    gaba_synapse = SynapseParam('gaba_synapse', default=Lowpass(0.008))
    n_neurons_per_ensemble = IntParam('n_neurons_per_ensemble',
                                      default=100,
                                      low=1,
                                      readonly=True)
    output_weight = NumberParam('output_weight', default=-3., readonly=True)
    input_bias = NumberParam('input_bias', default=0., readonly=True)

    def __init__(self,
                 action_count,
                 n_neurons_per_ensemble=Default,
                 output_weight=Default,
                 input_bias=Default,
                 ampa_synapse=Default,
                 gaba_synapse=Default,
                 sBCBG_params=None,
                 **kwargs):

        kwargs.setdefault('label', "Basal ganglia")
        super(BasalGanglia, self).__init__(**kwargs)

        self.action_count = action_count
        self.input_connections = {}
        self.input_bias = input_bias

        if BasalGanglia.sBCBG:

            # parameters
            filter_tau = .01
            if output_weight == Default:
                self.output_weight = -0.001

            import sBCBG
            if sBCBG_params == None:
                sBCBG_params = {}
            sBCBG.nengo_instantiate(
                self.action_count, self,
                sBCBG_params if sBCBG_params != None else {})

            with self:

                # connect input to CSN
                self.input = nengo.Node(label="input",
                                        size_in=self.action_count)
                scale = nengo.Ensemble(100, self.input.size_out)
                nengo.Connection(self.input, scale)
                for d in range(self.action_count):
                    nengo.Connection(scale[d],
                                     self.pops['CSN'][d],
                                     function=lambda x: 10 * x,
                                     synapse=.01,
                                     label='CSN input')

                # add bias input (BG performs best in the range 0.5--1.5)
                if abs(self.input_bias) > 0.0:
                    self.bias_input = nengo.Node(np.ones(self.action_count) *
                                                 input_bias,
                                                 label="basal ganglia bias")
                    nengo.Connection(self.bias_input, self.input)

                # connect GPi to output (inhibitory)
                decoding_weight = 1  # scaling of decoding GPi->out
                self.output = nengo.Node(label="output",
                                         size_in=self.action_count)
                for d in range(self.action_count):
                    GPi_ens = self.pops["GPi"][d]
                    decoder_values = np.ones(
                        (GPi_ens.n_neurons, 1)) * decoding_weight
                    nengo.Connection(
                        GPi_ens,
                        self.output[d],
                        synapse=nengo.synapses.Lowpass(filter_tau),
                        transform=self.output_weight,
                        #eval_points=eval_points)
                        solver=nengo.solvers.NoSolver(decoder_values))

        else:
            self.n_neurons_per_ensemble = n_neurons_per_ensemble
            self.ampa_synapse = ampa_synapse
            self.gaba_synapse = gaba_synapse
            self.output_weight = output_weight

            # Affects all ensembles / connections in the BG
            # unless overwritten with general_config
            config = nengo.Config(nengo.Ensemble, nengo.Connection)
            config[nengo.Ensemble].radius = 1.5
            config[nengo.Ensemble].encoders = nengo.dists.Choice([[1]])
            try:
                # Best, if we have SciPy
                config[nengo.Connection].solver = nengo.solvers.NnlsL2nz()
            except ImportError:
                warnings.warn("SciPy is not installed, so BasalGanglia will "
                              "use the default decoder solver. Installing "
                              "SciPy may improve BasalGanglia performance.")

            ea_params = {
                'n_neurons': self.n_neurons_per_ensemble,
                'n_ensembles': self.action_count
            }

            with self, config:
                self.strD1 = EnsembleArray(label="Striatal D1 neurons",
                                           intercepts=nengo.dists.Uniform(
                                               Weights.e, 1),
                                           **ea_params)
                self.strD2 = EnsembleArray(label="Striatal D2 neurons",
                                           intercepts=nengo.dists.Uniform(
                                               Weights.e, 1),
                                           **ea_params)
                self.stn = EnsembleArray(label="Subthalamic nucleus",
                                         intercepts=nengo.dists.Uniform(
                                             Weights.ep, 1),
                                         **ea_params)
                self.gpi = EnsembleArray(label="Globus pallidus internus",
                                         intercepts=nengo.dists.Uniform(
                                             Weights.eg, 1),
                                         **ea_params)
                self.gpe = EnsembleArray(label="Globus pallidus externus",
                                         intercepts=nengo.dists.Uniform(
                                             Weights.ee, 1),
                                         **ea_params)

                self.input = nengo.Node(label="input",
                                        size_in=self.action_count)
                self.output = nengo.Node(label="output",
                                         size_in=self.action_count)

                # add bias input (BG performs best in the range 0.5--1.5)
                if abs(self.input_bias) > 0.0:
                    self.bias_input = nengo.Node(np.ones(self.action_count) *
                                                 self.input_bias,
                                                 label="basal ganglia bias")
                    nengo.Connection(self.bias_input, self.input)

                # spread the input to StrD1, StrD2, and STN
                nengo.Connection(self.input,
                                 self.strD1.input,
                                 synapse=None,
                                 transform=Weights.ws * (1 + Weights.lg))
                nengo.Connection(self.input,
                                 self.strD2.input,
                                 synapse=None,
                                 transform=Weights.ws * (1 - Weights.le))
                nengo.Connection(self.input,
                                 self.stn.input,
                                 synapse=None,
                                 transform=Weights.wt)

                # connect the striatum to the GPi and GPe (inhibitory)
                strD1_output = self.strD1.add_output('func_str',
                                                     Weights.str_func)
                strD2_output = self.strD2.add_output('func_str',
                                                     Weights.str_func)
                self.gaba = nengo.Network("GABAergic connections")
                self.gaba.config[nengo.Connection].synapse = self.gaba_synapse
                with self.gaba:
                    nengo.Connection(strD1_output,
                                     self.gpi.input,
                                     transform=-Weights.wm)
                    nengo.Connection(strD2_output,
                                     self.gpe.input,
                                     transform=-Weights.wm)

                # connect the STN to GPi and GPe (broad and excitatory)
                tr = Weights.wp * np.ones(
                    (self.action_count, self.action_count))
                stn_output = self.stn.add_output('func_stn', Weights.stn_func)
                self.ampa = nengo.Network("AMPAergic connectiions")
                self.ampa.config[nengo.Connection].synapse = self.ampa_synapse
                with self.ampa:
                    nengo.Connection(stn_output, self.gpi.input, transform=tr)
                    nengo.Connection(stn_output, self.gpe.input, transform=tr)

                # connect the GPe to GPi and STN (inhibitory)
                gpe_output = self.gpe.add_output('func_gpe', Weights.gpe_func)
                with self.gaba:
                    nengo.Connection(gpe_output,
                                     self.gpi.input,
                                     transform=-Weights.we)
                    nengo.Connection(gpe_output,
                                     self.stn.input,
                                     transform=-Weights.wg)

                # connect GPi to output (inhibitory)
                gpi_output = self.gpi.add_output('func_gpi', Weights.gpi_func)
                nengo.Connection(gpi_output,
                                 self.output,
                                 synapse=None,
                                 transform=self.output_weight)

    def connect_input(self, source, transform=Default, index=None):
        self.input_connections[index] = nengo.Connection(
            source,
            self.input[index],
            transform=transform,
            synapse=self.input_synapse)
Пример #49
0
    def __init__(self, input_vectors, output_vectors=None,  # noqa: C901
                 default_output_vector=None, threshold=0.3, input_scale=1.0,
                 inhibitable=False, inhibit_scale=1.5, wta_output=False,
                 wta_inhibit_scale=3.0, wta_synapse=0.005,
                 threshold_output=False, label=None, seed=None,
                 add_to_container=None, **ens_args):
        super(AssociativeMemory, self).__init__(label, seed, add_to_container)

        label_prefix = "" if label is None else label + "_"
        n_neurons_per_ensemble = ens_args.get('n_neurons', 50)

        # If output vocabulary is not specified, use input vocabulary
        # (i.e autoassociative memory)
        if output_vectors is None:
            output_vectors = input_vectors

        # Handle different vocabulary types
        if is_iterable(input_vectors):
            input_vectors = np.matrix(input_vectors)

        if is_iterable(output_vectors):
            output_vectors = np.matrix(output_vectors)

        # Fail if number of input items and number of output items don't
        # match
        if input_vectors.shape[0] != output_vectors.shape[0]:
            raise ValueError(
                'Number of input vectors does not match number of output '
                'vectors. %d != %d'
                % (input_vectors.shape[0], output_vectors.shape[0]))

        # Handle possible different threshold / input_scale values for each
        # element in the associative memory
        if not is_iterable(threshold):
            threshold = np.array([threshold] * input_vectors.shape[0])
        else:
            threshold = np.array(threshold)
        if threshold.shape[0] != input_vectors.shape[0]:
            raise ValueError(
                'Number of threshold values do not match number of input'
                'vectors. Got: %d, expected %d.' %
                (threshold.shape[0], input_vectors.shape[0]))

        if not is_iterable(input_scale):
            input_scale = np.matrix([input_scale] * input_vectors.shape[0])
        else:
            input_scale = np.matrix(input_scale)
        if input_scale.shape[1] != input_vectors.shape[0]:
            raise ValueError(
                'Number of input_scale values do not match number of input'
                'vectors. Got: %d, expected %d.' %
                (input_scale.shape[1], input_vectors.shape[0]))

        # Input and output nodes
        N = input_vectors.shape[0]
        self.num_items = N

        with self:
            bias_node = nengo.Node(output=1)

            self.input = nengo.Node(size_in=input_vectors.shape[1],
                                    label="input")
            self.output = nengo.Node(size_in=output_vectors.shape[1],
                                     label="output")

            self.elem_input = nengo.Node(size_in=N, label="element input")
            self.elem_output = nengo.Node(size_in=N, label="element output")

            self.threshold_output = threshold_output

            nengo.Connection(self.input, self.elem_input, synapse=None,
                             transform=np.multiply(input_vectors,
                                                   input_scale.T))

            # Evaluation points parameters
            n_eval_points = 5000

            # Make each ensemble
            self.am_ensembles = []
            for i in range(N):
                # Ensemble array parameters
                ens_params = dict(ens_args)
                ens_params['radius'] = ens_args.get('radius', 1.0)
                ens_params['dimensions'] = 1
                ens_params['n_neurons'] = n_neurons_per_ensemble
                ens_params['intercepts'] = Uniform(threshold[i], 1)
                ens_params['encoders'] = Choice([[1]])
                ens_params['eval_points'] = Uniform(threshold[i], 1.2)
                ens_params['n_eval_points'] = n_eval_points
                ens_params['label'] = label_prefix + str(i)

                # Create ensemble
                e = nengo.Ensemble(**ens_params)
                self.am_ensembles.append(e)

                # Connect input and output nodes
                nengo.Connection(self.elem_input[i], e, synapse=None)
                nengo.Connection(e, self.elem_output[i], synapse=None)

            # Configure associative memory to be inhibitable
            if inhibitable:
                # Input node for inhibitory gating signal (if enabled)
                self.inhibit = nengo.Node(size_in=1, label="inhibit")
                nengo.Connection(self.inhibit, self.elem_input,
                                 transform=-np.ones((N, 1)) * inhibit_scale,
                                 synapse=None)
                # Note: We can use decoded connection here because all the
                # encoding vectors are [1]

            # Configure associative memory to have mutually inhibited output
            if wta_output:
                nengo.Connection(self.elem_output, self.elem_input,
                                 synapse=wta_synapse,
                                 transform=(np.eye(N) - 1) * wta_inhibit_scale)

            # Configure utilities output
            self.utilities = self.elem_output

            # Configure default output vector
            if default_output_vector is not None or threshold_output:
                default_threshold = min(1 - np.min(threshold), 0.9)

                ens_params = dict(ens_args)
                ens_params['radius'] = ens_args.get('radius', 1.0)
                ens_params['dimensions'] = 1
                ens_params['n_neurons'] = n_neurons_per_ensemble
                ens_params['intercepts'] = Uniform(default_threshold, 1)
                ens_params['encoders'] = Choice([[1]])
                ens_params['eval_points'] = Uniform(default_threshold, 1.1)
                ens_params['n_eval_points'] = n_eval_points
                ens_params['label'] = "default vector gate"

                default_vector_gate = nengo.Ensemble(**ens_params)

                nengo.Connection(bias_node, default_vector_gate, synapse=None)
                nengo.Connection(self.elem_output, default_vector_gate,
                                 transform=-2 * np.ones((1, N)), synapse=0.01)

                self.default_output_utility = default_vector_gate
                self.default_output_thresholded_utility = default_vector_gate

                if default_output_vector is not None:
                    nengo.Connection(
                        default_vector_gate, self.output,
                        transform=np.matrix(default_output_vector).T,
                        synapse=None)

                if inhibitable:
                    nengo.Connection(self.inhibit, default_vector_gate,
                                     transform=[[-1]], synapse=None)

            # Set up thresholding ensembles
            if threshold_output:
                # Ensemble array parameters
                ens_params = dict(ens_args)
                ens_params['radius'] = ens_args.get('radius', 1.0)
                ens_params['n_neurons'] = n_neurons_per_ensemble
                ens_params['n_ensembles'] = N
                ens_params['intercepts'] = Uniform(0.5, 1)
                ens_params['encoders'] = Choice([[1]])
                ens_params['eval_points'] = Uniform(0.5, 1.1)
                ens_params['n_eval_points'] = n_eval_points

                self.thresh_ens = EnsembleArray(**ens_params)
                self.thresholded_utilities = self.thresh_ens.output

                nengo.Connection(bias_node, self.thresh_ens.input,
                                 transform=np.ones((N, 1)), synapse=None)
                if wta_output:
                    nengo.Connection(self.elem_output, self.thresh_ens.input,
                                     transform=10 * (np.eye(N) - 1),
                                     synapse=0.01)
                else:
                    ens_params['intercepts'] = Uniform(0.25, 1)
                    self.thresh_ens_int = EnsembleArray(**ens_params)
                    nengo.Connection(bias_node, self.thresh_ens_int.input,
                                     transform=np.ones((N, 1)), synapse=None)
                    nengo.Connection(self.elem_output,
                                     self.thresh_ens_int.input,
                                     transform=-10, synapse=0.005)
                    nengo.Connection(self.thresh_ens_int.output,
                                     self.thresh_ens.input,
                                     transform=-10, synapse=0.005)

                nengo.Connection(self.thresh_ens.output, self.output,
                                 transform=output_vectors.T, synapse=None)

                nengo.Connection(default_vector_gate, self.thresh_ens.input,
                                 transform=-2 * np.ones((N, 1)), synapse=0.01)

                if inhibitable:
                    nengo.Connection(
                        self.inhibit, self.thresh_ens.input,
                        transform=-np.ones((N, 1)) * inhibit_scale,
                        synapse=None)
            else:
                nengo.Connection(self.elem_output, self.output,
                                 transform=output_vectors.T, synapse=None)