From 2753cedb61721f52d18643a53e159d9424d0e9c9 Mon Sep 17 00:00:00 2001 From: Eric Hunsberger Date: Wed, 22 May 2019 10:56:01 -0400 Subject: [PATCH] WIP: Neuron voltage subtraction reset for accuracy Subtracting the voltage threshold from the membrane voltage instead of setting it to zero after a spike provides more accurate tuning curves (solves the aliasing problem). However, this is not yet available on Loihi hardware. --- nengo_loihi/emulator/interface.py | 38 +++++++++++++++++++++---------- nengo_loihi/neurons.py | 6 +++-- nengo_loihi/tests/test_neurons.py | 2 +- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/nengo_loihi/emulator/interface.py b/nengo_loihi/emulator/interface.py index e4dc4d28c..f2da98db1 100644 --- a/nengo_loihi/emulator/interface.py +++ b/nengo_loihi/emulator/interface.py @@ -317,18 +317,32 @@ def update(self, rng): u2[self.noise.target_u] += noise[self.noise.target_u] self._overflow(u2, bits=U_BITS, name="u2") - self.voltage[:] = self._decay_voltage(self.voltage, u2) - # We have not been able to create V overflow on the chip, so we do - # not include it here. See github.com/nengo/nengo-loihi/issues/130 - # self.overflow(self.v, bits=V_BIT, name="V") - - np.clip(self.voltage, self.vmin, self.vmax, out=self.voltage) - self.voltage[self.ref_count > 0] = 0 - # TODO^: don't zero voltage in case neuron is saving overshoot - - self.spiked[:] = (self.voltage > self.vth) - self.voltage[self.spiked] = 0 - self.ref_count[self.spiked] = self.ref[self.spiked] + if 0: + self.voltage[:] = self._decay_voltage(self.voltage, u2) + # We have not been able to create V overflow on the chip, so we do + # not include it here. See github.com/nengo/nengo-loihi/issues/130 + # self.overflow(self.v, bits=V_BIT, name="V") + + np.clip(self.voltage, self.vmin, self.vmax, out=self.voltage) + self.voltage[self.ref_count > 0] = 0 + # TODO^: don't zero voltage in case neuron is saving overshoot + + self.spiked[:] = (self.voltage > self.vth) + self.voltage[self.spiked] = 0 + self.ref_count[self.spiked] = self.ref[self.spiked] + else: + v = self._decay_voltage(self.voltage, u2) + self.voltage[self.ref_count <= 0] = v[self.ref_count <= 0] + # We have not been able to create V overflow on the chip, so we do + # not include it here. See github.com/nengo/nengo-loihi/issues/130 + # self.overflow(self.v, bits=V_BIT, name="V") + + np.clip(self.voltage, self.vmin, self.vmax, out=self.voltage) + + self.spiked[:] = (self.voltage > self.vth) & (self.ref_count <= 0) + self.voltage[self.spiked] -= self.vth[self.spiked] + self.ref_count[self.spiked] = self.ref[self.spiked] + # decrement ref_count np.clip(self.ref_count - 1, 0, None, out=self.ref_count) diff --git a/nengo_loihi/neurons.py b/nengo_loihi/neurons.py index 9f78aa968..e602bf2ec 100644 --- a/nengo_loihi/neurons.py +++ b/nengo_loihi/neurons.py @@ -43,7 +43,8 @@ def loihi_lif_rates(neuron_type, x, gain, bias, dt): j = neuron_type.current(x, gain, bias) - 1 out = np.zeros_like(j) period = tau_ref + tau_rc * np.log1p(1. / j[j > 0]) - out[j > 0] = (neuron_type.amplitude / dt) / np.ceil(period / dt) + # out[j > 0] = (neuron_type.amplitude / dt) / np.ceil(period / dt) + out[j > 0] = neuron_type.amplitude / period return out @@ -52,7 +53,8 @@ def loihi_spikingrectifiedlinear_rates(neuron_type, x, gain, bias, dt): out = np.zeros_like(j) period = 1. / j[j > 0] - out[j > 0] = (neuron_type.amplitude / dt) / np.ceil(period / dt) + # out[j > 0] = (neuron_type.amplitude / dt) / np.ceil(period / dt) + out[j > 0] = neuron_type.amplitude / period return out diff --git a/nengo_loihi/tests/test_neurons.py b/nengo_loihi/tests/test_neurons.py index 663c4bd15..c87a28237 100644 --- a/nengo_loihi/tests/test_neurons.py +++ b/nengo_loihi/tests/test_neurons.py @@ -29,7 +29,7 @@ def test_loihi_rates(dt, neuron_type, Simulator, plt, allclose): x = np.linspace(-0.1, 1, n) encoders = np.ones((n, 1)) - max_rates = 400 * np.ones(n) + max_rates = 300 * np.ones(n) intercepts = 0 * np.ones(n) gain, bias = neuron_type.gain_bias(max_rates, intercepts) j = x * gain + bias