def __init__(self, eplParams): # make sure the type of the parameters class assert isinstance(eplParams, ParamemtersForEPL) super().__init__() # copy the parameters for attr in eplParams.__slots__: setattr(self, attr, getattr(eplParams, attr)) self.net = nx.NxNet() self.stim2bias = [int(1) for i in range(1)] self.stim2bias += [int(i * 1) for i in range(1, 256, 1)] self.numlayers = len(self.numHidNurns) self.numMCs = self.numInputs self.numGCs = np.sum(self.numHidNurns) self.convNumInputs = 0 self.poswgtrng = 64 self.negwgtrng = -64 self.bposwgtrng = 128 self.bnegwgtrng = -128 # probes related data structures self.allMCSomaProbes = None self.exc2InhConnProbes = None self.inh2ExcConnProbesPos = None self.inh2ExcConnProbesNeg = None self.mcADProbes = None self.mcSomaProbes = None self.gcProbes = None self.numStepsRan = 0
def __init__(self, eplParams): # make sure the type of the parameters class assert isinstance(eplParams, ParamemtersForEPL) super().__init__() # copy the parameters for attr in eplParams.__slots__: setattr(self, attr, getattr(eplParams, attr)) self.net = nx.NxNet() # ToDo:Needs to be automated in future # The bias current value to be used for each MC input/stimulus self.stim2bias = [ 0, 34, 36, 38, 41, 43, 46, 50, 54, 59, 65, 72, 81, 92, 107, 129, 161, 214, 321, 641 ] if self.useRandomSeed: np.random.seed(self.randomGenSeed) random.seed(self.randomGenSeed) # probes related data structures self.allMCSomaProbes = None # self.cxProbeIdxs = cxProbeIdxs self.exc2InhConnProbes = None self.inh2ExcConnProbesPos = None self.inh2ExcConnProbesNeg = None self.mcADProbes = None self.mcSomaProbes = None self.gcProbes = None #self.probeIdxs = probeIdxs self.numStepsRan = 0
def __init__(self, numCores, numExcNeuronsPerCore, numInhNeuronsPerCore, inputBiases=None, gcInputBias=None, conn_prob=0.2, delayMCToGC=16, numMCToGCDelays=4, doOnlyInference=True, debug=False, log=True): self.net = nx.NxNet() self.numCores = numCores self.numExcNeuronsPerCore = numExcNeuronsPerCore self.numInhNeuronsPerCore = numInhNeuronsPerCore self.inputBiases = inputBiases self.gcInputBias = gcInputBias self.conn_prob = conn_prob self.numMCToGCDelays = numMCToGCDelays self.delayMCToGC = delayMCToGC self.stim2bias = [ 0, 34, 36, 38, 41, 43, 46, 50, 54, 59, 65, 72, 81, 92, 107, 129, 161, 214, 321, 641 ] self.cycleDuration = 40 self.doOnlyInference = doOnlyInference self.debug = debug self.log = log self.numStepsRan = 0 if not self.debug: self.setupNetwork()
def set_up_network(self, turn_on_learning=True): net = nx.NxNet() # Define compartment prototype(all neurons are the same) if turn_on_learning is True: comProto = nx.CompartmentPrototype(vThMant=10, compartmentCurrentDecay=4096, compartmentVoltageDecay=0, enableSpikeBackprop=1, enableSpikeBackpropFromSelf=1) elif turn_on_learning is False: comProto = nx.CompartmentPrototype(vThMant=10, compartmentCurrentDecay=4096, compartmentVoltageDecay=0) else: print('ERROR! turn_on_learning can only be True or False.') # Create compartment group for different layers comGrp = {} comGrp['inputGrp'] = net.createCompartmentGroup(size=self.num_input, prototype=comProto) comGrp['hiddenGrp'] = net.createCompartmentGroup(size=self.num_hidden, prototype=comProto) comGrp['outputGrp'] = net.createCompartmentGroup(size=self.num_output, prototype=comProto) # Create spike generator as teaching neurons comGrp['inputGen'] = net.createSpikeGenProcess(numPorts=self.num_input) comGrp['outputGen'] = net.createSpikeGenProcess(numPorts=self.num_output) # Define learning rule lr = net.createLearningRule(dw='2*x1*y0', x1Impulse=40, x1TimeConstant=4, y1Impulse=40, y1TimeConstant=4, tEpoch=2) # Define connection prototype if turn_on_learning is True: connProto = nx.ConnectionPrototype(enableLearning=1, learningRule=lr) connTeachingProto = nx.ConnectionPrototype(enableLearning=0) elif turn_on_learning is False: connProto = nx.ConnectionPrototype(enableLearning=0) else: print('ERROR! turn_on_learning can only be True or False.') # Create connections conn = {} if turn_on_learning is True: conn['inputGen_inputGrp'] = comGrp['inputGen'].connect(comGrp['inputGrp'], prototype=connTeachingProto, weight=np.array([[255, 0], [0, 255]])) conn['inputGrp_hiddenGrp'] = comGrp['inputGrp'].connect(comGrp['hiddenGrp'], prototype=connProto, weight=np.ones((4, 2), dtype=int)*50) conn['hiddenGrp_outputGrp'] = comGrp['hiddenGrp'].connect(comGrp['outputGrp'], prototype=connProto, weight=np.ones((1, 4), dtype=int)*50) conn['outputGen_outputGrp'] = comGrp['outputGen'].connect(comGrp['outputGrp'], prototype=connTeachingProto, weight=np.array([255])) elif turn_on_learning is False: conn['inputGen_inputGrp'] = comGrp['inputGen'].connect(comGrp['inputGrp'], prototype=connProto, weight=np.array([[255, 0], [0, 255]])) conn['inputGrp_hiddenGrp'] = comGrp['inputGrp'].connect(comGrp['hiddenGrp'], prototype=connProto, weight=self.weight_1) conn['hiddenGrp_outputGrp'] = comGrp['hiddenGrp'].connect(comGrp['outputGrp'], prototype=connProto, weight=self.weight_2) else: print('ERROR! turn_on_learning can only be True or False.') return net, comGrp, conn
def __init__(self, n_actions, n_states): super().__init__() #initialize network self.network = nx.NxNet() self.started = False #get problem parameters self.n_actions = n_actions self.n_states = n_states self.n_estimates = n_actions * n_states self.shape = (n_actions, n_states)
def __init__(self, numArms=5, neuronsPerArm=1, votingEpoch=128, epochs=10, epsilon=0.1, **kwargs): self.numArms = numArms self.neuronsPerArm = neuronsPerArm self.totalNeurons = numArms * neuronsPerArm self.votingEpoch = votingEpoch self.epochs = epochs self.epsilon = int(100 * epsilon) #set default values for weights and probabilities if 'probabilities' in kwargs: probs = kwargs['probabilities'] for p in probs: assert p in range(0, 100 + 1), "Probabilitiy must be in range [0,100]." assert len( probs) == self.numArms, "Must have probability for each arm." self.probabilities = np.array(probs, dtype='int') else: self.probabilities = 100 * np.ones(numArms, dtype='int') self.seed = kwargs.get('seed', 329801) self.recordWeights = kwargs.get('recordWeights', False) self.recordSpikes = kwargs.get('recordSpikes', False) #initialize the network self.net = nx.NxNet() self.vth = 255 self.started = False #setup the necessary NX prototypes self._create_prototypes() #use these to create the arms whose spiking output will choose a potential reward self._create_trackers() self._create_probes() #compile the generated network to a board self._compile() #create the SNIP which will select an arm, generate rewards, and communicate to #the reinforcement channels self._create_SNIPs() #create channels to/from the SNIP to read out the network's choices/rewards on host self._create_channels()
def __init__(self, n_actions, n_states, **kwargs): self.n_states = n_states self.n_actions = n_actions self.n_estimates = n_actions * n_states self.n_per_state = kwargs.get("n_per_state", 1) self.l_epoch = kwargs.get("l_epoch", 128) self.n_epochs = kwargs.get("n_epochs", 100) self.epsilon = int(kwargs.get("epsilon", 0.1) * 100) self.seed = kwargs.get("seed", 341257896) p_rewards = kwargs.get("p_rewards") if p_rewards is not None: assert p_rewards.shape == ( self.n_states, self.n_actions ), "Rewards must be in (n_states, n_actions) format." #convert 0-1 (probability) range to 0-100 (percentile, int) self.p_rewards = np.clip(p_rewards * 100, 0, 100).astype(np.int) else: self.p_rewards = np.random.randint(100, size=(self.n_states, self.n_actions)) self.recordWeights = kwargs.get('recordWeights', False) self.recordSpikes = kwargs.get('recordSpikes', False) self.net = nx.NxNet() self.vth = 255 self.started = False #create the virtual network self._create_prototypes(self.vth) self._create_trackers() self._create_stubs() self._create_logic() self._create_probes() #compile and link it to Loihi self._compile() self._create_SNIPs() self._create_channels()
def __init__(self, parameters=None): # Get parameters self.p = Parameters() if parameters is None else parameters # Set seed if self.p.seed is not None: np.random.seed(self.p.seed) # Instanciate nx net object self.nxNet = nx.NxNet() # Excitatory connection prototype self.exConnProto = nx.ConnectionPrototype( signMode=nx.SYNAPSE_SIGN_MODE.EXCITATORY, weightExponent=self.p.weightExponent, numTagBits=self.p.numTagBits, numDelayBits=self.p.numDelayBits, numWeightBits=self.p.numWeightBits) # Inhibitory connection prototype self.inConnProto = nx.ConnectionPrototype( signMode=nx.SYNAPSE_SIGN_MODE.INHIBITORY, weightExponent=self.p.weightExponent, numTagBits=self.p.numTagBits, numDelayBits=self.p.numDelayBits, numWeightBits=self.p.numWeightBits) # Mixed connection prototype self.mixedConnProto = nx.ConnectionPrototype( signMode=nx.SYNAPSE_SIGN_MODE.MIXED, weightExponent=self.p.weightExponent, numTagBits=self.p.numTagBits, numDelayBits=self.p.numDelayBits, numWeightBits=self.p.numWeightBits) # Generator connection prototype self.genConnProto = nx.ConnectionPrototype( signMode=nx.SYNAPSE_SIGN_MODE.EXCITATORY, weightExponent=self.p.inputWeightExponent, numTagBits=self.p.numTagBits, numDelayBits=self.p.numDelayBits, numWeightBits=self.p.numWeightBits) """ Network objects """ # Cores self.coresAvailable = np.arange(self.p.numCores) self.numCoresUsed = 0 self.numChipsUsed = 0 # Weights self.initialMasks = SimpleNamespace(**{ 'exex': None, 'inin': None, 'inex': None, 'exin': None }) self.initialWeights = SimpleNamespace(**{ 'exex': None, 'inin': None, 'inex': None, 'exin': None }) self.trainedWeightsExex = None # NxSDK compartment group chunks self.exReservoirChunks = [] self.inReservoirChunks = [] self.outputLayerChunks = [] self.connectionChunks = [] # Probes self.exSpikeProbes = [] self.inSpikeProbes = [] self.outSpikeProbes = [] self.exVoltageProbes = [] self.inVoltageProbes = [] self.outVoltageProbes = [] self.exCurrentProbes = [] self.inCurrentProbes = [] self.weightProbes = [] # Output self.outputMask = None self.outputWeights = None # Spikes self.exSpikeTrains = [] self.inSpikeTrains = [] self.outSpikeTrains = [] # Voltages self.outVoltageTrains = [] # Trace input self.traceSpikes = [] self.traceMasks = [] self.traceWeights = [] # Input self.inputTargetNeurons = [] self.inputSpikes = [] self.inputWeights = None self.inputTrials = [] # Noise input spikes self.noiseSpikes = None self.noiseMask = None self.noiseWeights = None # Instantiate utils and plot self.utils = Utils.instance() self.plot = Plot(self)
def setup_loihi_network(params): """ sets up the HD network :param num_rings: determines the dimensionality, in how many axes do we estimate :param num_neurons: number of neurons on one ring network :param feature_size: number of pixels, determines the size of the visual receptive field :param params: dictionary defined in the main with all parameters (e.g. threshold, tau, and weight values) :param with_vision: True if vision data is used :return: net, InputPort, spike_probes, state_probes, port_cons, HD """ num_rings = params['num_rings'] num_hd = params['num_neurons'] num_vis = params['feature_size'] # num_src determines the number of neurons in spike generators and "helper" neurons num_src = 1 # start position is set to the center neuron start_pos = [int(num_hd / 2), int(num_hd / 2)] # include GHD to enable gazing at learned positions include_GHD = True # Create Loihi network net = nx.NxNet() # Create Prototypes cxProto0 = nx.CompartmentPrototype( vThMant=params['threshold0'], compartmentCurrentDecay=decay(params['taui0']), compartmentVoltageDecay=decay(params['tauv0'])) cxProto1 = nx.CompartmentPrototype( vThMant=params['threshold1'], compartmentCurrentDecay=decay(params['taui1']), compartmentVoltageDecay=decay(params['tauv1'])) cxProto_learn = nx.CompartmentPrototype( vThMant=params['threshold_RHD'], compartmentCurrentDecay=decay(params['taui0']), compartmentVoltageDecay=decay(params['tauv_RHD']), enableSpikeBackprop=1, enableSpikeBackpropFromSelf=1) cxProto_vis = nx.CompartmentPrototype( vThMant=params['threshold_vis'], # refractoryDelay=63, compartmentCurrentDecay=decay(params['taui_vis']), compartmentVoltageDecay=decay(params['tauv_vis'])) cxProto_in = nx.CompartmentPrototype( vThMant=params['threshold_in'], compartmentCurrentDecay=decay(params['taui_in']), compartmentVoltageDecay=decay(params['tauv_in'])) # Create Compartments HD, IHD, SL, SR, VR, VL, North = [], [], [], [], [], [], [] In, RHD, GHD, vision, goal, Keep_gate, HD_gate = [], [], [], [], [], [], [] # In will receive external stimulation from the InputPort In.append( create_group_core_zero(net, name="In1", prototype=cxProto_in, size=5 + num_vis + num_vis)) sc = 0 ''' Names of neuron groups: VR, VL: Velocity Right, Velocity Left, receives encoder information North: Used to set the initial activity at a specific place on the ring HD: Head Direction, outputs the estimated orientation as neuron index which is converted to degrees in /data_visualization IHD: Integrated Head Direction SL, SR: Shift Left, Shift Right RHD: Reset Heading Direction, is connected to the visual input neuron and learns object associations GHD: Goal Heading Direction, is connected to the visual input neuron and learns object associations see https://doi.org/10.3389/fnins.2020.00551 for more information ''' # specify how many 1D rings you want to have, here we have one for pitch and one for yaw, so range(2) # the number of rings determines the dimensions, i.e. how many axis are estimated # the parameters are set in main_hd_net.py for ii in range(num_rings): # create groups VR.append( create_group_core_zero(net, name="VR" + str(ii), prototype=cxProto1, size=num_src)) VL.append( create_group_core_zero(net, name="VL" + str(ii), prototype=cxProto1, size=num_src)) # This group simply initilizes the peak at a given position on the ring North.append( create_group_core_zero(net, name="N" + str(ii), prototype=cxProto0, size=1)) # Groups are distributed over cores on Loihi HD.append( create_group(net, 1 + sc, 5 + sc, name="HD" + str(ii), prototype=cxProto0, size=num_hd)) IHD.append( create_group(net, 5 + sc, 10 + sc, name="IHD" + str(ii), prototype=cxProto0, size=num_hd)) SL.append( create_group(net, 10 + sc, 15 + sc, name="SL" + str(ii), prototype=cxProto0, size=num_hd)) SR.append( create_group(net, 15 + sc, 20 + sc, name="SR" + str(ii), prototype=cxProto0, size=num_hd)) RHD.append( create_group(net, 20 + sc, 25 + sc, name="RHD" + str(ii), prototype=cxProto_learn, size=num_hd)) if include_GHD: GHD.append( create_group(net, 25 + sc, 30 + sc, name="GHD" + str(ii), prototype=cxProto_learn, size=num_hd)) sc += 30 else: sc += 30 vision.append( create_group(net, start_core=61, end_core=62, name="vision", prototype=cxProto_vis, size=num_vis)) if include_GHD: goal.append( create_group(net, start_core=62, end_core=63, name="goal", prototype=cxProto_vis, size=num_vis)) # Create spike input port InputPort = net.createSpikeInputPortGroup(size=In[0].numNodes) # Connection prototypes connProtoEx = nx.ConnectionPrototype( signMode=nx.SYNAPSE_SIGN_MODE.EXCITATORY) connProtoInh = nx.ConnectionPrototype( signMode=nx.SYNAPSE_SIGN_MODE.INHIBITORY) connProtoMix = nx.ConnectionPrototype(signMode=nx.SYNAPSE_SIGN_MODE.MIXED) connProtoEx_in = nx.ConnectionPrototype( signMode=nx.SYNAPSE_SIGN_MODE.EXCITATORY, weight=params['w_in']) connProtoInh_V = nx.ConnectionPrototype( signMode=nx.SYNAPSE_SIGN_MODE.INHIBITORY, weight=-1) connProtoEx_vis = nx.ConnectionPrototype( signMode=nx.SYNAPSE_SIGN_MODE.EXCITATORY, weight=params['w_in_vis']) connProto_iport = nx.ConnectionPrototype(weight=2) # Create learning rule used by the learning-enabled synapse lr = net.createLearningRule(dw='2*y0*x1-32*x0', x1Impulse=125, x1TimeConstant=2, tEpoch=20) connProtoLrn = nx.ConnectionPrototype( enableLearning=True, learningRule=lr, numWeightBits=8, signMode=nx.SYNAPSE_SIGN_MODE.EXCITATORY) # connect initialization input In[0][0].connect(North[0], prototype=connProtoEx_in) In[0][0].connect(North[1], prototype=connProtoEx_in) # connect input to velocity neurons In[0][1].connect(VR[0], prototype=connProtoEx_in) In[0][2].connect(VL[0], prototype=connProtoEx_in) In[0][3].connect(VR[1], prototype=connProtoEx_in) In[0][4].connect(VL[1], prototype=connProtoEx_in) if params['with_vision']: # connect vision input for i in range(num_vis): In[0][5 + i].connect(vision[0][i], prototype=connProtoEx_vis) # connect goal input if include_GHD: for j in range(num_vis): In[0][5 + j].connect(goal[0][j], prototype=connProtoEx_vis) In[0][5 + j + num_vis].connect(goal[0][j], prototype=connProtoEx_vis) for i in range(num_rings): # Set all connections inside each ring network # Vision inhibits IHD and Velocities w_matrix = con.all2all(num_vis, num_hd, params['w_vis_IHD_i']) vision[0].connect(IHD[i], prototype=connProtoInh, weight=w_matrix) if params['w_RHD_IHD_e'] > 0.0: vision[0].connect(VL[i], prototype=connProtoInh_V) vision[0].connect(VR[i], prototype=connProtoInh_V) # HD WTA w_matrix = np.ones((num_hd, num_hd)) * params['w_HD_HD_i'] pre_e, post_e = con.connect_populations_1to1(num_hd, num_hd) for j in range(len(pre_e)): w_matrix[post_e[j], pre_e[j]] = params['w_HD_HD_e'] HD[i].connect(HD[i], prototype=connProtoMix, weight=w_matrix) # Connect HD to Shifts via inhibition w_matrix = np.zeros((num_hd, num_hd)) pre, post = con.connect_populations_inh_shift(num_hd, num_hd) for j in range(len(pre)): w_matrix[post[j], pre[j]] = params['w_HD_S'] HD[i].connect(SR[i], prototype=connProtoInh, weight=w_matrix, connectionMask=w_matrix != 0) HD[i].connect(SL[i], prototype=connProtoInh, weight=w_matrix, connectionMask=w_matrix != 0) # Shifts asymmetric connection to IHD w_matrix = np.zeros((num_hd, num_hd)) pre, post = con.connect_populations_1to1(num_hd, num_hd, shift_offset=1) for j in range(len(pre) - 1): # in order not to connect the last one -1 w_matrix[pre[j], post[j]] = params['w_S_IHD'] SR[i].connect(IHD[i], prototype=connProtoEx, weight=w_matrix, connectionMask=(w_matrix != 0)) w_matrix = np.zeros((num_hd, num_hd)) pre, post = con.connect_populations_1to1(num_hd, num_hd, shift_offset=-1) for j in range(len(pre) - 1): # in order not to connect the last one -1 w_matrix[pre[j], post[j]] = params['w_S_IHD'] SL[i].connect(IHD[i], prototype=connProtoEx, weight=w_matrix, connectionMask=(w_matrix != 0)) # IHD to HD, here one2one excitatory w_matrix = np.zeros((num_hd, num_hd)) pre, post = con.connect_populations_1to1(num_hd, num_hd) for j in range(len(pre)): w_matrix[pre[j], post[j]] = params['w_IHD_HD_e'] IHD[i].connect(HD[i], prototype=connProtoEx, weight=w_matrix, connectionMask=(w_matrix != 0)) # IHD to HD, here inhibitory to all others w_matrix = np.zeros((num_hd, num_hd)) pre, post = con.connect_populations_inh_shift(num_hd, num_hd) for j in range(len(pre)): w_matrix[post[j], pre[j]] = params['w_IHD_HD_i'] IHD[i].connect(HD[i], prototype=connProtoMix, weight=w_matrix, connectionMask=(w_matrix != 0)) # RHD to IHD for reset, one-to-one excitatory, inhibitory to all others if params['w_RHD_IHD_e'] > 0.0: w_matrix = np.zeros((num_hd, num_hd)) pre, post = con.connect_populations_1to1(num_hd, num_hd) for j in range(len(pre)): w_matrix[pre[j], post[j]] = params['w_RHD_IHD_e'] RHD[i].connect(IHD[i], prototype=connProtoEx, weight=w_matrix, connectionMask=(w_matrix != 0)) if params['w_RHD_IHD_i'] > 0.0: w_matrix = np.zeros((num_hd, num_hd)) pre, post = con.connect_populations_inh_shift(num_hd, num_hd) for j in range(len(pre)): w_matrix[post[j], pre[j]] = params['w_RHD_IHD_i'] RHD[i].connect(IHD[i], prototype=connProtoMix, weight=w_matrix, connectionMask=(w_matrix != 0)) # HD to RHD subthreshold w_matrix = np.zeros((num_hd, num_hd)) pre, post = con.connect_populations_1to1(num_hd, num_hd) for j in range(len(pre)): w_matrix[pre[j], post[j]] = params['w_HD_RHD'] HD[i].connect(RHD[i], prototype=connProtoEx, weight=w_matrix, connectionMask=(w_matrix != 0)) if include_GHD: # HD to GHD subthreshold w_matrix = np.zeros((num_hd, num_hd)) pre, post = con.connect_populations_1to1(num_hd, num_hd) for j in range(len(pre)): w_matrix[pre[j], post[j]] = params['w_HD_RHD'] # uses the same weight HD[i].connect(GHD[i], prototype=connProtoEx, weight=w_matrix, connectionMask=(w_matrix != 0)) # plastic synapse to learn landmark position (RHD/GHD) association w_matrix = con.all2all(num_vis, num_hd, params['w_init_plast']) if params['w_RHD_IHD_e'] > 0.0: syn_plast = vision[0].connect(RHD[i], prototype=connProtoLrn, weight=w_matrix) if include_GHD: syn_plast_GHD = goal[0].connect(GHD[i], prototype=connProtoLrn, weight=w_matrix) # Velocities excite shifts w_matrix = con.all2all(num_vis, num_hd, params['w_V_S']) VR[i].connect(SR[i], prototype=connProtoEx, weight=w_matrix) VL[i].connect(SL[i], prototype=connProtoEx, weight=w_matrix) # Initial Heading w_matrix = np.zeros((num_hd, num_src)) w_matrix[start_pos[i], :] = params['w_North_HD'] North[i].connect(HD[i], prototype=connProtoEx, weight=w_matrix) # , connectionMask=(w_matrix != 0)) # input port to input group port_cons = InputPort.connect(In[0], prototype=connProto_iport, connectionMask=sparse.eye(In[0].numNodes)) logicalAxonIds = [] for port_c in port_cons: logicalAxonIds.append(port_c.nodeIds) # Hacking spike probes to create spike counter and defer probing # Check tutorial on lakemont spike counters # lmt counters created will be read from Embedded snip probeParameters = [nx.ProbeParameter.SPIKE] pc_yarp = SpikeProbeCondition(dt=1, tStart=100000000) pc_probe = SpikeProbeCondition(dt=1, tStart=1) # if real-time recording using yarp: set to pc_yarp, for offline probing set to pc_probe pc = pc_yarp # pc_probe spike_probes = OrderedDict() spike_probes['HD1'] = HD[0].probe(probeParameters, pc) spike_probes['HD2'] = HD[1].probe(probeParameters, pc) if include_GHD: # plot GHD instead of RHD spike_probes['RHD1'] = GHD[0].probe(probeParameters, pc) spike_probes['RHD2'] = GHD[1].probe(probeParameters, pc) spike_probes['vision'] = goal[0].probe(probeParameters, pc) else: spike_probes['RHD1'] = RHD[0].probe(probeParameters, pc) spike_probes['RHD2'] = RHD[1].probe(probeParameters, pc) spike_probes['vision'] = vision[0].probe(probeParameters, pc) # Create state probes # voltageProbe1 = HD[1].probe([nx.ProbeParameter.COMPARTMENT_VOLTAGE]) state_probes = OrderedDict() # state_probes['weight'] = syn_plast.probe([nx.ProbeParameter.SYNAPSE_WEIGHT], IntervalProbeCondition(dt=50)) return net, InputPort, spike_probes, state_probes, port_cons, HD
:return: 2D array of binary spike values """ random_spikes = np.random.rand(num_neurons, sim_time) < (firing_rate / 1000.) random_spikes = [ np.where(random_spikes[num, :])[0].tolist() for num in range(num_neurons) ] return random_spikes if __name__ == '__main__': # to see consistent results from run-to-run np.random.seed(0) net = nx.NxNet() sim_time = 8500 pre_neuron_cnt = 20 post_neuron_cnt = 20 # Create pre-synaptic neurons (spike generator) pre_synaptic_neurons = net.createSpikeGenProcess(pre_neuron_cnt) input_spike_times = gen_rand_spikes(pre_neuron_cnt, sim_time, 10) pre_synaptic_neurons.addSpikes( spikeInputPortNodeIds=[num for num in range(pre_neuron_cnt)], spikeTimes=input_spike_times) # Create post-synaptic neuron post_neuron_proto = nx.CompartmentPrototype( vThMant=10,
def __init__(self, params, net=None, name=None): """ The STDE_group contains the sTDE neurons. One neuron consists of 4 compartments that are connected as follows: D (main/soma) | C (current) / \\ (trigger) A B (facilitator) A is the gate and lets B's current pass whenever it spikes. C receives B's current on its voltage variable and decays D receives C's voltage and integrates it, so C is basically a second current input to D The two inputs are called trigger and facilitator following Milde (2018) params are 'tau_fac': current tau of facilitator input 'tau_trigg': current tau of trigger input 'tau_v': voltage tau of TDE Neuron 'tau_c': current tau of TDE Neuron 'weight_fac': amplitude of the facilitator spike 'do_probes' : can be 'all', 'spikes' or None 'num_neurons' : number of sTDE neurons that are created """ if net is None: net = nx.NxNet() self.net = net self.num_neurons = params['num_neurons'] self.neurongroups = {} self.probes = {} self.spikegens = {} weight_fac, exponent_fac = calculate_mant_exp( params['weight_fac'] / params['tau_fac'], 7) # Create auxiliary compartments cpA = nx.CompartmentPrototype( vThMant=1, compartmentCurrentDecay=int(1 / 1 * 2**12), compartmentVoltageDecay=4095, # thresholdBehavior=nx.COMPARTMENT_THRESHOLD_MODE.NO_SPIKE_AND_PASS_V_LG_VTH_TO_PARENT ) cpB = nx.CompartmentPrototype(vThMant=100, compartmentCurrentDecay=int( 1 / params['tau_fac'] * 2**12), compartmentVoltageDecay=4095) cpC = nx.CompartmentPrototype( vThMant=1000, compartmentCurrentDecay=int(1 / 1 * 2**12), compartmentVoltageDecay=int(1 / params['tau_trigg'] * 2**12), thresholdBehavior=nx.COMPARTMENT_THRESHOLD_MODE. NO_SPIKE_AND_PASS_V_LG_VTH_TO_PARENT) # Create main compartment cpD = nx.CompartmentPrototype( vThMant=100, compartmentCurrentDecay=int(1 / params['tau_v'] * 2**12), compartmentVoltageDecay=int(1 / params['tau_c'] * 2**12), ) # build compartment tree cpC.addDendrites(prototypeA=cpA, prototypeB=cpB, joinOp=nx.COMPARTMENT_JOIN_OPERATION.PASS) cpD.addDendrite(prototype=[cpC], joinOp=nx.COMPARTMENT_JOIN_OPERATION.ADD) num_neurons = params['num_neurons'] neuronPrototype = nx.NeuronPrototype(cpD) neurongroup = net.createNeuronGroup(prototype=neuronPrototype, size=num_neurons) sgpA = net.createSpikeGenProcess(numPorts=num_neurons) sgpB = net.createSpikeGenProcess(numPorts=num_neurons) # sgpC = net.createSpikeGenProcess(numPorts=1) connProto = nx.ConnectionPrototype(weight=weight_fac, weightExponent=exponent_fac) sgpA.connect(neurongroup.dendrites[0].dendrites[1], prototype=connProto, connectionMask=sp.sparse.identity(num_neurons)) sgpB.connect(neurongroup.dendrites[0].dendrites[0], prototype=connProto, connectionMask=sp.sparse.identity(num_neurons)) spikegens = [sgpA, sgpB] if params['do_probes'] == 'all': (uA, vA, sA) = neurongroup.dendrites[0].dendrites[1].probe([ nx.ProbeParameter.COMPARTMENT_CURRENT, nx.ProbeParameter.COMPARTMENT_VOLTAGE, nx.ProbeParameter.SPIKE ]) (uB, vB, sB) = neurongroup.dendrites[0].dendrites[0].probe([ nx.ProbeParameter.COMPARTMENT_CURRENT, nx.ProbeParameter.COMPARTMENT_VOLTAGE, nx.ProbeParameter.SPIKE ]) (uC, vC, sC) = neurongroup.dendrites[0].probe([ nx.ProbeParameter.COMPARTMENT_CURRENT, nx.ProbeParameter.COMPARTMENT_VOLTAGE, nx.ProbeParameter.SPIKE ]) (uD, vD, sD) = neurongroup.soma.probe([ nx.ProbeParameter.COMPARTMENT_CURRENT, nx.ProbeParameter.COMPARTMENT_VOLTAGE, nx.ProbeParameter.SPIKE ]) probes = { 'A_current': uA, 'A_voltage': vA, 'A_spikes': sA, 'B_current': uB, 'B_voltage': vB, 'B_spikes': sB, 'C_current': uC, 'C_voltage': vC, 'C_spikes': sC, 'D_current': uD, 'D_voltage': vD, 'D_spikes': sD, } elif params['do_probes'] == 'spikes': sA = neurongroup.dendrites[0].dendrites[1].probe( [nx.ProbeParameter.SPIKE]) sB = neurongroup.dendrites[0].dendrites[0].probe( [nx.ProbeParameter.SPIKE]) sC = neurongroup.dendrites[0].probe([nx.ProbeParameter.SPIKE]) sD = neurongroup.soma.probe([nx.ProbeParameter.SPIKE]) probes = { 'A_spikes': sA, 'B_spikes': sB, 'C_spikes': sC, 'D_spikes': sD, } else: probes = None self.neurongroup = neurongroup self.probes = probes self.spikegens = spikegens self.input0 = neurongroup.dendrites[0].dendrites[0] self.input1 = neurongroup.dendrites[0].dendrites[1]
def __init__( self, topology: netx.DiGraph, input_dim: int, nb_of_conn_per_input: int = 1, alpha=2, beta=0.25, tau_v=40 * ms, tau_i=5 * ms, v_th=1.0, refractory_period=2 * ms, dt=1 * ms, tau_v_pair=None, tau_i_pair=None, bin_size=60 * ms, pair_weight_mode: PairWeightMode = PairWeightMode.HALF_VTH, network=None, debug=False, get_power_eff=False, power_eff_input_freq=None, ): self.net = nx.NxNet() if network is None else network self.board = None self.topology = topology self.number_of_neurons = topology.number_of_nodes() self.pair_weight_mode = pair_weight_mode self.debug = debug self.get_power_eff = get_power_eff self.input_dim = input_dim if get_power_eff: assert not debug, "Can't get power efficiency in debug mode" assert power_eff_input_freq is not None self.power_eff_input_freq = rescale(power_eff_input_freq, 1 / dt) # Rescale variables for Loihi refractory_period = rescale(refractory_period, dt) v_decay = int(2 ** 12 * (1 - np.exp(-1 / rescale(tau_v, dt)))) c_decay = int(2 ** 12 * (1 - np.exp(-1 / rescale(tau_i, dt)))) v_decay_pair = ( v_decay if tau_v_pair is None else int(2 ** 12 * (1 - np.exp(-1 / rescale(tau_v_pair, dt)))) ) c_decay_pair = ( c_decay if tau_i_pair is None else int(2 ** 12 * (1 - np.exp(-1 / rescale(tau_i_pair, dt)))) ) v_th = int(v_th * _SCALING_FACTOR) self.bin_size = rescale(bin_size, dt) build_neuron_nargs = { "nb_of_neurons": topology.number_of_nodes(), "nb_of_synapses": topology.number_of_edges(), "nb_inputs": nb_of_conn_per_input * input_dim, "v_decay": v_decay, "c_decay": c_decay, "v_decay_pair": v_decay_pair, "c_decay_pair": c_decay_pair, "v_th": v_th, "refractory_period": refractory_period, "alpha": alpha, } build_synapse_nargs = { "topology": topology, "alpha": alpha, "beta": beta, } if get_power_eff: cores_left = 128 # For one full loihi chip self.nb_replicas = 0 while True: self.nb_replicas += 1 build_neuron_nargs["starting_core"] = 128 - cores_left nb_cores_used = self._build_neurons(**build_neuron_nargs) self._build_synapses(**build_synapse_nargs) cores_left -= nb_cores_used if cores_left < nb_cores_used: break else: self._build_neurons(**build_neuron_nargs) self._build_synapses(**build_synapse_nargs) self._build_fake_probes() # For snips bin-counters self._build_input_gen( nb_neurons=topology.number_of_nodes(), input_dim=input_dim, nb_of_conn_per_input=nb_of_conn_per_input, ) self.weight_probe = self.connections.probe( [nx.ProbeParameter.SYNAPSE_WEIGHT], probeConditions=[IntervalProbeCondition(dt=self.bin_size)], ) if debug: (self.spike_probe,) = self.grp.probe([nx.ProbeParameter.SPIKE]) (self.pair_spike_probe,) = self._pair_grp.probe([nx.ProbeParameter.SPIKE]) self.tag_probe = self.connections.probe( [nx.ProbeParameter.SYNAPSE_TAG], probeConditions=[IntervalProbeCondition(dt=self.bin_size)], )
def __init__(self, weights, bias, core_list, bias_amp=(1, 1, 1, 1), vth=0.5, cdecay=1 / 2, vdecay=1 / 4): """ :param weights: raw weights from trained SNN :param bias: raw bias from trained SNN :param core_list: core list of each layer and bias neurons :param bias_amp: use multiple bias neurons if bias is large :param vth: raw voltage threshold of trained neuron :param cdecay: raw current decay of trained neuron :param vdecay: raw voltage decay of trained neuron """ assert isinstance(weights, list) and isinstance(bias, list) assert len(weights) == len(bias) assert isinstance(core_list, list) and len(core_list) == len(weights) + 2 self.net = nx.NxNet() self.core_list = core_list self.bias_amp = bias_amp self.loihi_cdecay = int(cdecay * 2**12) self.loihi_vdecay = int(vdecay * 2**12) self.loihi_weights = { 'pos_w': [], 'neg_w': [], 'pos_w_mask': [], 'neg_w_mask': [] } self.loihi_bias = { 'pos_b': [], 'neg_b': [], 'pos_b_mask': [], 'neg_b_mask': [] } self.loihi_vth = [] self.loihi_scale_factor = [] self.loihi_snn_dimension = [] self.loihi_bias_start_end = [0] bias_ita = 0 for num in range(len(weights)): param_dict, new_vth, new_sf = pytorch_trained_snn_param_2_loihi_snn_param_amp( weights[num], bias[num], vth, self.bias_amp[num]) self.loihi_weights['pos_w'].append(param_dict['pos_w']) self.loihi_weights['neg_w'].append(param_dict['neg_w']) self.loihi_weights['pos_w_mask'].append(param_dict['pos_w_mask']) self.loihi_weights['neg_w_mask'].append(param_dict['neg_w_mask']) self.loihi_bias['pos_b'].append(param_dict['pos_b']) self.loihi_bias['neg_b'].append(param_dict['neg_b']) self.loihi_bias['pos_b_mask'].append(param_dict['pos_b_mask']) self.loihi_bias['neg_b_mask'].append(param_dict['neg_b_mask']) self.loihi_vth.append(new_vth) self.loihi_scale_factor.append(new_sf) if num == 0: self.loihi_snn_dimension.append(param_dict['pos_w'].shape[1]) self.loihi_snn_dimension.append(param_dict['pos_w'].shape[0]) bias_ita += bias_amp[num] self.loihi_bias_start_end.append(bias_ita) # network layers self.network_input_layer = None self.network_bias_layer = None self.network_hidden_layer = None self.network_output_layer = None # Online input connections self.pseudo_2_input = None self.pseudo_2_bias = None