Neuromorphic Engineering Book
  • Welcome
  • Preliminaries
    • About the author
    • Preface
    • A tale about passion and fear
    • Before we begin
  • I. Introduction
    • 1. Introducing the perspective of the scientist
      • From the neuron doctrine to emergent behavior
      • Brain modeling
      • Take away lessons
    • 2. Introducing the perspective of the computer architect
      • Limits of integrated circuits
      • Emerging computing paradigms
      • Brain-inspired hardware
      • Take away lessons
      • Errata
    • 3. Introducing the perspective of the algorithm designer
      • From artificial to spiking neural networks
      • Neuromorphic software development
      • Take home lessons
  • II. Scientist perspective
    • 4. Biological description of neuronal dynamics
      • Potentials, spikes and power estimation
      • Take away lessons
      • Errata
    • 5. Models of point neuronal dynamic
      • Tutorial - models of point neuronal processes
        • The leaky integrate and fire model
        • The Izhikevich neuron model
        • The Hodgkin-Huxley neuron model
      • Synapse modeling and point neurons
      • Case study: a SNN for perceptual filling-in
      • Take away lessons
    • 6. Models of morphologically detailed neurons
      • Morphologically detailed modeling
      • The cable equation
      • The compartmental model
      • Case study: direction-selective SAC
      • Take away lessons
    • 7. Models of network dynamic and learning
      • Circuit taxonomy, reconstruction, and simulation
      • Case study: SACs' lateral inhibition in direction selectivity
      • Neuromorphic and biological learning
      • Take away lessons
      • Errate
  • III. Architect perspective
    • 8. Neuromorphic Hardware
      • Transistors and micro-power circuitry
      • The silicon neuron
      • Case study: hardware - software co-synthesis
      • Take away lessons
    • 9. Communication and hybrid circuit design
      • Neural architectures
      • Take away lessons
    • 10. In-memory computing with memristors
      • Memristive computing
      • Take away lessons
      • Errata
  • IV. Algorithm designer perspective
    • 11. Introduction to neuromorphic programming
      • Theory and neuromorphic programming
      • Take away lessons
    • 12. The neural engineering framework
      • NEF: Representation
      • NEF: Transformation
      • NEF: Dynamics
      • Case study: motion detection using oscillation interference
      • Take away lessons
      • Errate
    • 13. Learning spiking neural networks
      • Learning with SNN
      • Take away lessons
Powered by GitBook
On this page
  • Python / Nengo demonstration
  • Transforming sin(x) to 2sin(x) by decoder scaling
  • Transforming sin(x) to sin(x)^2 in
  • Summation of two shifted sin functions
  • Summation of two encoded vectors
  • Multiplication of two 2D vectors
  • Signal gating

Was this helpful?

  1. IV. Algorithm designer perspective
  2. 12. The neural engineering framework

NEF: Transformation

Chapter 12.1.2

PreviousNEF: RepresentationNextNEF: Dynamics

Last updated 1 year ago

Was this helpful?

Learn about the second principle of NEF: transformation

Read Chapter 12.1.2

Python / Nengo demonstration

Imports:

import nengo
from nengo.utils.matplotlib import rasterplot
from nengo.processes import WhiteNoise
import numpy as np
import matplotlib.pyplot as plt

Transforming sin(x) to 2sin(x) by decoder scaling

T = 1.0
max_freq = 5

model = nengo.Network()

with model:
    stim = nengo.Node(lambda t: 0.5*np.sin(10*t))
    ensA = nengo.Ensemble(100, dimensions=1)
    ensB = nengo.Ensemble(100, dimensions=1)
    
    nengo.Connection(stim, ensA)
    nengo.Connection(ensA, ensB, transform=2) #function=lambda x: 2*x)
    
    stim_p = nengo.Probe(stim)
    ensA_p = nengo.Probe(ensA, synapse=.01)
    ensB_p = nengo.Probe(ensB, synapse=.01)
    ensA_spikes_p = nengo.Probe(ensA.neurons, 'output')
    ensB_spikes_p = nengo.Probe(ensB.neurons, 'output')
   
sim = nengo.Simulator(model, seed=4)
sim.run(T)

t = sim.trange()
plt.figure(figsize=(6, 4))
plt.ax = plt.gca()
plt.plot(t, sim.data[stim_p],'r', linewidth=4, label='x')
plt.plot(t, sim.data[ensA_p],'g', label='$\hat{x}$')
plt.plot(t, sim.data[ensB_p],'b', label='$f(\hat{x})=2\hat{x}$')
plt.legend()
plt.ylabel("Output")
plt.xlabel("Time")
plt.show()

Result:

Transforming sin(x) to sin(x)^2 in

T = 1.0
max_freq = 5

model = nengo.Network()

with model:
    stim = nengo.Node(lambda t: 0.5*np.sin(10*t))
    ensA = nengo.Ensemble(100, dimensions=1)
    ensB = nengo.Ensemble(100, dimensions=1)
    
    nengo.Connection(stim, ensA)
    nengo.Connection(ensA, ensB, function=lambda x: x**2)
    
    stim_p = nengo.Probe(stim)
    ensA_p = nengo.Probe(ensA, synapse=.01)
    ensB_p = nengo.Probe(ensB, synapse=.01)
    ensA_spikes_p = nengo.Probe(ensA.neurons, 'output')
    ensB_spikes_p = nengo.Probe(ensB.neurons, 'output')
   
sim = nengo.Simulator(model, seed=4)
sim.run(T)

t = sim.trange()
plt.figure(figsize=(6, 4))
plt.ax = plt.gca()
plt.plot(t, sim.data[stim_p],'r', linewidth=4, label='x')
plt.plot(t, sim.data[ensA_p],'g', label='$\hat{x}$')
plt.plot(t, sim.data[ensB_p],'b', label='$f(\hat{x})=\hat{x}^2$')
plt.legend()
plt.ylabel("Output")
plt.xlabel("Time")
plt.show()

Result:

Summation of two shifted sin functions

T = 1.0
max_freq = 5

model = nengo.Network()

with model:
    stimA = nengo.Node(lambda t: 0.5*np.sin(10*t))
    stimB = nengo.Node(lambda t: 0.5*np.sin(5*t))
    
    ensA = nengo.Ensemble(100, dimensions=1)
    ensB = nengo.Ensemble(100, dimensions=1)
    ensC = nengo.Ensemble(100, dimensions=1)
    
    nengo.Connection(stimA, ensA)
    nengo.Connection(stimB, ensB)
    nengo.Connection(ensA, ensC)
    nengo.Connection(ensB, ensC)
    
    stimA_p = nengo.Probe(stimA)
    stimB_p = nengo.Probe(stimB)
    ensA_p = nengo.Probe(ensA, synapse=.01)
    ensB_p = nengo.Probe(ensB, synapse=.01)
    ensC_p = nengo.Probe(ensC, synapse=.01)
   
sim = nengo.Simulator(model)
sim.run(T)

t = sim.trange()
plt.figure(figsize=(6,4))
plt.plot(t, sim.data[ensA_p],'b', label="$\hat{x}$")
plt.plot(t, sim.data[ensB_p],'m--', label="$\hat{y}$")
plt.plot(t, sim.data[ensC_p],'k--', label="$\hat{x}+\hat{y}$")
plt.legend(loc='best')
plt.ylabel("Output")
plt.xlabel("Time")
plt.show()

Result:

Summation of two encoded vectors

T = 1
max_freq = 5

model = nengo.Network()

with model:

    stimA = nengo.Node([.3,.5])
    stimB = nengo.Node([.3,-.5])
    
    ensA = nengo.Ensemble(100, dimensions=2)
    ensB = nengo.Ensemble(100, dimensions=2)
    ensC = nengo.Ensemble(100, dimensions=2)
    
    nengo.Connection(stimA, ensA)
    nengo.Connection(stimB, ensB)
    nengo.Connection(ensA, ensC)
    nengo.Connection(ensB, ensC)
    
    stimA_p = nengo.Probe(stimA)
    stimB_p = nengo.Probe(stimB)
    ensA_p = nengo.Probe(ensA, synapse=.02)
    ensB_p = nengo.Probe(ensB, synapse=.02)
    ensC_p = nengo.Probe(ensC, synapse=.02)
   
sim = nengo.Simulator(model)
sim.run(T)

plt.figure()
plt.plot(sim.data[ensA_p][:,0], sim.data[ensA_p][:,1], 'g', label="$\hat{x}$")
plt.plot(sim.data[ensB_p][:,0], sim.data[ensB_p][:,1], 'm', label="$\hat{y}$")
plt.plot(sim.data[ensC_p][:,0], sim.data[ensC_p][:,1], 'k', label="$\hat{x} + \hat{y}$")
plt.ylabel("$x_2$")
plt.xlabel("$x_1$")
plt.legend(loc='best')
plt.show()

Result:

Multiplication of two 2D vectors

T = 1.0
max_freq = 5

model = nengo.Network()

with model:
    stimA = nengo.Node(lambda t: 0.5*np.sin(10*t))
    stimB = nengo.Node(lambda t: 0.5*np.sin(5*t))
    
    ensA = nengo.Ensemble(200, dimensions=2)
    ensB = nengo.Ensemble(100, dimensions=1)
    nengo.Connection(stimA, ensA[0])
    nengo.Connection(stimB, ensA[1])

    nengo.Connection(ensA, ensB, function=lambda x: x[0]*x[1])
    
    stimA_p = nengo.Probe(stimA)
    stimB_p = nengo.Probe(stimB)
    ensA_p = nengo.Probe(ensA, synapse=.01)
    ensB_p = nengo.Probe(ensB, synapse=.01)
   
sim = nengo.Simulator(model)
sim.run(T)

t = sim.trange()
plt.figure()
plt.plot(t, sim.data[ensA_p][:,0],'black', label="$\hat{x}[0]$")
plt.plot(t, sim.data[ensA_p][:,1],'black', label="$\hat{x}[1]$")
plt.plot(t, sim.data[ensB_p],'r', label="$\hat{x[0]}\cdot\hat{x[1]}$")
plt.legend(loc='best')
plt.ylabel("Output")
plt.xlabel("Time")
plt.show()

Result:

Signal gating

T = 1.0
max_freq = 5

model = nengo.Network()

with model:
    stimA = nengo.Node(lambda t: 0.5*np.sin(10*t))
    stimB = nengo.Node(lambda t: 0 if (t<.5) else 1)
    
    ensA = nengo.Ensemble(300, dimensions=2, radius=np.sqrt(2))
    ensB = nengo.Ensemble(100, dimensions=1)
    nengo.Connection(stimA, ensA[0])
    nengo.Connection(stimB, ensA[1])
    nengo.Connection(ensA, ensB, function=lambda x: x[0]*x[1])
    
    stimA_p = nengo.Probe(stimA)
    stimB_p = nengo.Probe(stimB)
    ensA_p = nengo.Probe(ensA, synapse=.01)
    ensB_p = nengo.Probe(ensB, synapse=.01)
   
sim = nengo.Simulator(model)
sim.run(T)

t = sim.trange()
plt.figure()
plt.plot(t, sim.data[ensA_p][:,0],'black', label="$\hat{x}[0]$")
plt.plot(t, sim.data[ensA_p][:,1],'blue', label="$\hat{x}[1]$")
plt.plot(t, sim.data[ensB_p],'r', label="$\hat{x[0]}\cdot\hat{x[1]}$")
plt.legend(loc='best')
plt.ylabel("Output")
plt.xlabel("Time")
plt.show()

Result: