s72sue / std_neural_nets

A repository of standard neural networks implemented using Nengo
7 stars 4 forks source link

perceptron XOR produces python errors #1

Open jogama opened 4 years ago

jogama commented 4 years ago

Hello,

I came here via the standard neural nets in https://www.nengo.ai/examples/

I first saw

$ python perceptron_for_XOR.py
    Traceback (most recent call last):
      File "perceptron_for_XOR.py", line 110, in <module>
        conn.learning_rule_type['my_pes'].learning_rate = 1e-4
      File "/home/jogama/.local/lib/python2.7/site-packages/nengo/config.py", line 456, in __setattr__
        reraise(exc_info[0], exc_info[1], None)
      File "<string>", line 2, in reraise
    nengo.exceptions.ReadonlyError: PES.learning_rate: learning_rate is read-only and cannot be changed

Fixing that, I saw

$ python2 perceptron_for_XOR.py 
Build finished in 0:00:01.                                                      
Traceback (most recent call last):
  File "perceptron_for_XOR.py", line 144, in <module>
    sim = nengo.Simulator(model)
  File "/home/jogama/.local/lib/python2.7/site-packages/nengo/simulator.py", line 160, in __init__
    progress=pt.next_stage("Building", "Build"))
  File "/home/jogama/.local/lib/python2.7/site-packages/nengo/builder/builder.py", line 123, in build
    built = self.builder.build(self, obj, *args, **kwargs)
  File "/home/jogama/.local/lib/python2.7/site-packages/nengo/builder/builder.py", line 218, in build
    return cls.builders[obj_cls](model, obj, *args, **kwargs)
  File "/home/jogama/.local/lib/python2.7/site-packages/nengo/builder/network.py", line 97, in build_network
    model.build(obj)
  File "/home/jogama/.local/lib/python2.7/site-packages/nengo/builder/builder.py", line 123, in build
    built = self.builder.build(self, obj, *args, **kwargs)
  File "/home/jogama/.local/lib/python2.7/site-packages/nengo/builder/builder.py", line 218, in build
    return cls.builders[obj_cls](model, obj, *args, **kwargs)
  File "/home/jogama/.local/lib/python2.7/site-packages/nengo/builder/ensemble.py", line 175, in build_ensemble
    gain, bias, max_rates, intercepts = get_gain_bias(ens, rng)
  File "/home/jogama/.local/lib/python2.7/site-packages/nengo/builder/ensemble.py", line 115, in get_gain_bias
    "intercept value to below 1." % ens)
nengo.exceptions.BuildError: The specified intercepts for <Ensemble "input"> lead to neurons with negative or non-finite gain. Please adjust the intercepts so that all gains are positive. For most neuron types (e.g., LIF neurons) this is achieved by reducing the maximum intercept value to below 1.

I'll probably either continue fixing this, or (more likely) try to figure out what version of nengo works with this code and install under a pyenv. In either case, would you want a pull request? Could you provide some advice for either case?

In any case, thank you for providing these examples.

This is my current environment:

$ pip freeze
ipython==5.10.0
ipython-genutils==0.2.0
jupyter-client==5.3.5
jupyter-core==4.6.3
matplotlib==2.2.5
nengo==2.8.0
numpy==1.16.6
xchoo commented 4 years ago

We changed the behaviour of the nengo.Sigmoid neurons in Nengo v2.4.0 to more accurately reflect the Sigmoid function. To make this example work with the latest Nengo release:

xchoo commented 4 years ago

Now, a deeper dive as to why the change to the Sigmoid neuron is required. From Nengo v2.4.0 onwards, the inflection point of the Sigmoid neuron (i.e., where the neuron's intercept is on the x-axis) also corresponds to having a firing rate half that of it's maximum firing rate (i.e., 1/tau_ref).

What does this mean in terms of its effect on the notebook? First, for ensembles using the Nengo defaults, this means that for a Sigmoid neuron ensemble, there are a few constraints:

  1. The firing rate at x = 1 is the max_rate value provided to the ensemble (note: this is different from the maximum firing rate of the neuron, which is 1/tau_ref). The maximum firing rate of the neuron must be equal to or exceed this value.
  2. The inflection point of the Sigmoid occurs at x = intercept.
  3. The firing rate at the inflection point is 0.5/tau_ref.
  4. The Sigmoid response curve always increases in value (i.e., the gain is positive).

The default for Nengo ensembles is to have neurons with max_rates of 200-400 Hz. From constraint 1, 1/tau_ref >= 400. Combining this with constraint 3, the firing rate at the inflection point 0.5/tau_ref >= 400. However constraint 4 sets the effective minimum max_rate value for that neuron to 0.5/tau_ref <= 200. Solving all of these constraints leads to the result that tau_ref = 1/400. This is why tau_ref is changed from 0.002 to 0.0025.

Constraint 2 and 3, also mean that with the current Sigmoid neurons, the firing rate of the neurons at x = -1 may be quite high. Since we want neuron response curves that have a decent range of firing rates, the input and error populations have their max_rates and intercepts shifted in order to accomplish this. You can use the response curve plotting code (i.e., p0.plot(*response_curves(input, sim))) to investigate the effect changing the max_rates and intercepts values have on the response curves of the neurons. This change can also be applied to the other neural populations (answer, actual_error), however the input and error populations are the most crucial as they are the ones directly involved in the learning.

jogama commented 4 years ago

Thank you so much for the detailed response! This is a great starting point and will keep me busy for some time. Everything works on my computer with the above mentioned python2 environment. Some of the graphs are somewhat different, but XOR is learned.