 # Challenge #1: Clean 0 and 1 output

Welcome to challenges!

The idea is to have a series of simple problems, presented every so often, where people can discuss different circuits and implementations / weigh the pros and cons of various approaches. The goal is to hopefully learn some new techniques for neural circuit design and generate a set of efficient, robust solutions to various problems.

Answers should be posted with code and simulation results!

The first challenge is to generate a circuit that transforms an input signal into a clean 0 if it’s below .5, and a clean 1 if it’s above .5.

The input to the system is `nengo.Node(lambda x: np.cos(x)*.5+.5)` and the system should run for 6 seconds.

Go!

1 Like

Here’s one possible solution:

``````import nengo
import numpy as np

model = nengo.Network()
with model:
stim = nengo.Node(lambda x: np.cos(x)*.5+.5)

b = nengo.Ensemble(n_neurons=50, dimensions=1,
intercepts=nengo.dists.Uniform(.5, 1),
encoders=[[-1]]*50)
out_b = nengo.Ensemble(n_neurons=50, dimensions=1)

output = nengo.Ensemble(n_neurons=50, dimensions=1)

nengo.Connection(stim, b, function=lambda x: x-1)

nengo.Connection(b, out_b.neurons,
function=lambda x: 1,
transform=[[-3]]*out_b.n_neurons)

nengo.Connection(out_b, output, function=lambda x: 1)

probe_input = nengo.Probe(stim)
probe_output = nengo.Probe(output, synapse=.01)

sim = nengo.Simulator(model)
sim.run(6)

import matplotlib.pyplot as plt
plt.plot(sim.trange(), sim.data[probe_input])
plt.plot(sim.trange(), sim.data[probe_output])
plt.legend(['Input', 'Output'])
plt.show()
``````

Here’s another one and look it’s perfect:

``````import nengo
import numpy as np

model = nengo.Network()
with model:
stim = nengo.Node(lambda x: np.cos(x)*.5+.5)

output = nengo.Node(lambda t, x: 0 if x < 0.5 else 1, size_in=1)
nengo.Connection(stim, output)

probe_input = nengo.Probe(stim)
probe_output = nengo.Probe(output, synapse=.01)

sim = nengo.Simulator(model)
sim.run(6)

import matplotlib.pyplot as plt
plt.plot(sim.trange(), sim.data[probe_input])
plt.plot(sim.trange(), sim.data[probe_output])
plt.legend(['Input', 'Output'])
plt.show()
`````` Ok, I’m just kidding with a node you can implement anything. 1 Like

This is an actual solution with neurons:

``````import nengo
import numpy as np

model = nengo.Network()
with model:
stim = nengo.Node(lambda x: np.cos(x)*.5+.5)

threshold = nengo.Ensemble(
75, 1,
intercepts=nengo.dists.Exponential(0.3, 0.5, 1.),
encoders=nengo.dists.Choice([]),
eval_points=nengo.dists.Uniform(.5, 1.))
nengo.Connection(stim, threshold)

output = nengo.Ensemble(75, 1)
nengo.Connection(threshold, output, function=lambda x: 0 if x < 0.5 else 1)

probe_input = nengo.Probe(stim)
probe_output = nengo.Probe(output, synapse=.01)

sim = nengo.Simulator(model)
sim.run(6)

import matplotlib.pyplot as plt
plt.plot(sim.trange(), sim.data[probe_input])
plt.plot(sim.trange(), sim.data[probe_output])
plt.legend(['Input', 'Output'])
plt.show()
`````` 1 Like

Interesting! Compressed down to one population, using 25 less neurons!
Is the `Exponential` more effective here than a `Uniform`?

Actually I though I was using the same number of neurons …

Yes, see here and here.

It should be noted that with the nengo presets (in the dev version of nengo), you can implement the network like so:

``````import nengo
import numpy as np

model = nengo.Network()
with model:
stim = nengo.Node(lambda x: np.cos(x)*.5 + .5)

threshold_val = 0.5
with nengo.presets.ThresholdingEnsembles(threshold_val):
threshold = nengo.Ensemble(75, 1)
nengo.Connection(stim, threshold)

output = nengo.Ensemble(75, 1)
nengo.Connection(threshold, output, function=lambda x: 0 if x < 0.5 else 1)

probe_input = nengo.Probe(stim)
probe_output = nengo.Probe(output, synapse=.01)

sim = nengo.Simulator(model)
sim.run(6)

``````

There is a slight difference in the first parameter of the `Exponential` distribution, but that just affects the steepness of the transition point.

Without preset: With preset: It should also be noted that the presets are not part of any official release yet.

I’ve updated my comment. Great tutorial Jan! Super well put together, thanks for the link!