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 _build_neurons( self, nb_of_neurons, nb_of_synapses, nb_inputs, v_decay, c_decay, v_decay_pair, c_decay_pair, v_th, refractory_period, alpha, starting_core=64, # Since we use lmt 0, starting with core 64 reduces barrier sync region ): proto_args = { "biasMant": 0, "biasExp": 0, "vThMant": v_th, "compartmentVoltageDecay": v_decay, "refractoryDelay": refractory_period, "enableSpikeBackprop": 1, "enableSpikeBackpropFromSelf": 1, "compartmentCurrentDecay": c_decay, "thresholdBehavior": nx.COMPARTMENT_THRESHOLD_MODE.SPIKE_AND_RESET, "logicalCoreId": 0, } proto = nx.CompartmentPrototype(**proto_args) self.grp = self.net.createCompartmentGroup(size=nb_of_neurons, prototype=proto) proto_args["vThMant"] = v_th + alpha if self.pair_weight_mode & self.PairWeightMode.HALF_VTH: proto_args["vThMant"] += 0.5 * v_th proto_args["compartmentVoltageDecay"] = v_decay_pair proto_args["compartmentCurrentDecay"] = c_decay_pair proto_args["refractoryDelay"] = max(1, refractory_period - 2) proto_pair = nx.CompartmentPrototype(**proto_args) self._pair_grp = self.net.createCompartmentGroup( size=nb_of_neurons, prototype=proto_pair ) nb_of_cores = calc_minimum_number_of_cores( nb_of_neurons * 2 + nb_inputs, nb_of_synapses * 2 + nb_inputs ) _logger.info("Using %i cores" % nb_of_cores) if nb_of_cores > 64: starting_core = 0 ## TODO: Could be more optimal for nb_of_cores > 16 main_neurons_per_core = int(np.ceil(nb_of_neurons / nb_of_cores)) for i, compartment in enumerate(self.grp): core = i // main_neurons_per_core + starting_core compartment.logicalCoreId = core self._pair_grp[i].logicalCoreId = core return nb_of_cores
def createMCNeurons(self, biasMant=0): """ configures the MC neurons""" mcADProto = nx.CompartmentPrototype( logicalCoreId=1, compartmentCurrentDecay=0, vThMant=10, # i.e. 10 * 64 = 640 biasMant=biasMant, refractoryDelay=20, vMinExp=0, numDendriticAccumulators=64, functionalState=nx.COMPARTMENT_FUNCTIONAL_STATE.IDLE, thresholdBehavior=nx.COMPARTMENT_THRESHOLD_MODE.SPIKE_AND_RESET) self.allMCADGroup = self.net.createCompartmentGroup( prototype=mcADProto, size=self.numMCs) mcSomaProto = nx.CompartmentPrototype( logicalCoreId=2, compartmentCurrentDecay=0, compartmentVoltageDecay=4095, enableSpikeBackprop=1, enableSpikeBackpropFromSelf=1, vThMant=2, # i.e. 2 * 64 = 128 refractoryDelay=19, vMinExp=0, numDendriticAccumulators=64, functionalState=nx.COMPARTMENT_FUNCTIONAL_STATE.IDLE, thresholdBehavior=nx.COMPARTMENT_THRESHOLD_MODE.SPIKE_AND_RESET) self.allMCSomaGrp = self.net.createCompartmentGroup() self.mcSomaGrpPerColumn = list() for colIdx in range(self.numColumns): self.mcSomaGrpPerColumn.append(self.net.createCompartmentGroup()) for mcIdx in range(self.numMCsPerColumn): mcSomaCx = self.net.createCompartment(prototype=mcSomaProto) self.mcSomaGrpPerColumn[colIdx].addCompartments(mcSomaCx) self.allMCSomaGrp.addCompartments(mcSomaCx) # Connect each MC-AD neuron to its MC-Soma neuron mcADToSomaConnProtoBox = nx.ConnectionPrototype( weight=3, numWeightBits=8, delay=19, numDelayBits=6, enableDelay=1, signMode=nx.SYNAPSE_SIGN_MODE.EXCITATORY, postSynResponseMode=nx.SYNAPSE_POST_SYN_RESPONSE_MODE.BOX, compressionMode=nx.SYNAPSE_COMPRESSION_MODE.SPARSE) self.mcADToSomaConns = list() for idx in range(self.numMCs): conn = self.net._createConnection(src=self.allMCADGroup[idx], dst=self.allMCSomaGrp[idx], prototype=mcADToSomaConnProtoBox) self.mcADToSomaConns.append(conn)
def createInhibitoryGCNeurons(self): self.allGCNeuronsGroup = self.net.createCompartmentGroup() self.gcNeuronGrpPerCoreList = [] if self.gcInputBias is None: self.gcInputBias = 0 for coreIdx in range(self.numCores): gcNeuronGrpPerCore = self.net.createCompartmentGroup() gcNeuronProtoPerCore = nx.CompartmentPrototype( logicalCoreId=coreIdx, compartmentCurrentDecay=4095, compartmentVoltageDecay=4095, biasMant=0 if not self.debug else self.gcInputBias, vThMant=5 * 200 if not self.debug else self.gcInputBias // 64, refractoryDelay=25, vMinExp=0, numDendriticAccumulators=64, functionalState=nx.COMPARTMENT_FUNCTIONAL_STATE.IDLE, thresholdBehavior=nx.COMPARTMENT_THRESHOLD_MODE.SPIKE_AND_RESET ) for i in range(self.numINeuronsPerCore): gcCx = self.net.createCompartment( prototype=gcNeuronProtoPerCore) gcNeuronGrpPerCore.addCompartments(gcCx) self.allGCNeuronsGroup.addCompartments(gcCx) self.gcNeuronGrpPerCoreList.append(gcNeuronGrpPerCore)
def createGCNeurons(self): """ configures the GC neurons """ self.allGCsGroup = self.net.createCompartmentGroup() self.gcNeuronGrpPerCoreList = [] for coreIdx in range(self.numColumns): gcGrpPerCore = self.net.createCompartmentGroup() gcProtoPerCore = nx.CompartmentPrototype( logicalCoreId=coreIdx, compartmentCurrentDecay=4095, compartmentVoltageDecay=4095, enableSpikeBackprop=1, enableSpikeBackpropFromSelf=1, biasMant=0, vThMant=3 * 200, refractoryDelay=25, vMinExp=0, numDendriticAccumulators=64, functionalState=nx.COMPARTMENT_FUNCTIONAL_STATE.IDLE, thresholdBehavior=nx.COMPARTMENT_THRESHOLD_MODE.SPIKE_AND_RESET ) for _ in range(self.numGCsPerColumn): gcCx = self.net.createCompartment(prototype=gcProtoPerCore) gcGrpPerCore.addCompartments(gcCx) self.allGCsGroup.addCompartments(gcCx) self.gcNeuronGrpPerCoreList.append(gcGrpPerCore)
def connectOutput(self): # Predefine some helper variables nOut = self.p.numOutputNeurons nOutCores = int(np.ceil(nOut / self.p.neuronsPerCore)) nLastOutCore = nOut % self.p.neuronsPerCore # number of ouput neurons in last core # Define output compartment prototypes and compartment groups # initial value is first available core id in core list frCore, toCore = self.coresAvailable[0], self.coresAvailable[0] + nOutCores for i in range(frCore, toCore): # Output compartment prototype outCompProto = nx.CompartmentPrototype( compartmentVoltageDecay=int(1 / self.p.voltageTau * 2**12), compartmentCurrentDecay=int(1 / self.p.currentTau * 2**12), vThMant=self.p.thresholdMant, refractoryDelay=self.p.refractoryDelay, logicalCoreId=i, functionalState=nx.COMPARTMENT_FUNCTIONAL_STATE.IDLE) # Calculate size of compartment: if last core has remainder, use remainder as size size = nLastOutCore if ( i == (toCore - 1) and nLastOutCore > 0) else self.p.neuronsPerCore # Output layer compartment prototype self.outputLayerChunks.append( self.nxNet.createCompartmentGroup(size=size, prototype=outCompProto)) # Remove used core from core list self.removeCoreFromList() # Connect excitatory neurons to output layer connectNetworkChunks(self, fromChunks=self.exReservoirChunks, toChunks=self.outputLayerChunks, mask=self.outputMask, weights=self.outputWeights, prototype=self.exConnProto)
def createGCNeuronsPerPattern(self, patternIdx): """ configures the GC neurons for each pattern""" maxColsPerCore = 128 // self.numGCsPerPatternPerColumn for colIdx in range(self.numColumns): self.gcsPerPatternPerColumn[patternIdx, colIdx] = \ self.net.createCompartmentGroup() coreIdx = self.lastUsedLogicalCoreId + \ math.ceil((colIdx+1)/maxColsPerCore) gcProto = nx.CompartmentPrototype( logicalCoreId=coreIdx, compartmentCurrentDecay=4095, compartmentVoltageDecay=4095, enableSpikeBackprop=1, enableSpikeBackpropFromSelf=1, biasMant=0, vThMant=3 * 200 if patternIdx == 0 else 2**17 - 1, refractoryDelay=25, vMinExp=0, vMaxExp=17, numDendriticAccumulators=64, functionalState=nx.COMPARTMENT_FUNCTIONAL_STATE.IDLE, thresholdBehavior=nx.COMPARTMENT_THRESHOLD_MODE. SPIKE_AND_RESET, ) for _ in range(self.numGCsPerPatternPerColumn): gcCx = self.net.createCompartment(prototype=gcProto) self.gcsPerPatternPerColumn[patternIdx, colIdx].addCompartments(gcCx) self.allGCsPerPattern[patternIdx].addCompartments(gcCx) self.lastUsedLogicalCoreId += math.ceil(self.numGCsPerPattern / 128)
def _build_input_gen(self, nb_neurons, input_dim, nb_of_conn_per_input): if self.get_power_eff: # Create an input neuron for power/time efficiency as spike injector are time costly # That will spike at some specific frequency neuron_spikegen_param = nx.CompartmentPrototype( biasMant=self.power_eff_input_freq, biasExp=6, compartmentVoltageDecay=0, vThMant=1000, ) self.spike_gen = self.net.createCompartmentGroup( size=input_dim, prototype=neuron_spikegen_param ) else: self.spike_gen = self.net.createSpikeGenProcess(numPorts=input_dim) input_proto = nx.ConnectionPrototype(weight=128, weightExponent=6,) pre = np.arange(input_dim * nb_of_conn_per_input) % input_dim post = ( np.random.permutation(max(input_dim, nb_neurons) * nb_of_conn_per_input)[ : input_dim * nb_of_conn_per_input ] % nb_neurons ) connection_mask = np.zeros((input_dim, nb_neurons), dtype=np.int) connection_mask[pre, post] = 1 connection_mask = coo_matrix(connection_mask) self.spike_gen.connect( self.grp, prototype=input_proto, connectionMask=connection_mask.T )
def __core(self): """ Private function for setup feedforward nan :return: poisson_spikes: list :return: pre_2_post_conn: nx.Connection :return: post_neurons: nx.CompartmentGroup :return: astrocyte: combra.Astrocyte """ """ define spike generator as presynaptic neurons """ pre_neurons = self.net.createSpikeGenProcess(self.pre_num) random_spikes = np.random.rand(self.pre_num, self.sim_time) < (self.pre_fr / 1000.) poisson_spikes = [ np.where(random_spikes[num, :])[0].tolist() for num in range(self.pre_num) ] # add spikes to spike generator pre_neurons.addSpikes( spikeInputPortNodeIds=[num for num in range(self.pre_num)], spikeTimes=poisson_spikes) """ define post synaptic neurons """ post_neurons_prototype = nx.CompartmentPrototype( vThMant=self.post_vth, compartmentCurrentDecay=self.post_cdecay, compartmentVoltageDecay=self.post_vdecay, functionalState=nx.COMPARTMENT_FUNCTIONAL_STATE.IDLE) post_neurons = self.net.createCompartmentGroup( size=self.post_num, prototype=post_neurons_prototype) """ define astrocyte """ astrocyte = Astrocyte(self.net) """ define connection between presynaptic neurons and postsynaptic neurons """ pre_2_post_conn_prototype = nx.ConnectionPrototype() mask = np.int_( np.random.rand(self.post_num, self.pre_num) < self.pre_post_conn_p) weight = self.pre_post_w * mask pre_2_post_conn = pre_neurons.connect( post_neurons, prototype=pre_2_post_conn_prototype, connectionMask=mask, weight=weight) """ define connection between neurons and astrocyte """ astrocyte.connectInputNeurons(pre_neurons, self.pre_num) astrocyte.connectOutputNeurons(post_neurons, self.post_num) """ return """ return poisson_spikes, pre_2_post_conn, post_neurons, astrocyte
def set_network_bias_layer(self): """ Setup Network Bias Layer """ assert len(self.core_list[-1]) == self.loihi_bias_start_end[-1] neuron_prototype = nx.CompartmentPrototype( compartmentCurrentDecay=2**12) self.network_bias_layer = self.net.createCompartmentGroup(size=0) for core in self.core_list[-1]: bias_neuron = self.net.createCompartment( prototype=neuron_prototype) bias_neuron.logicalCoreId = core self.network_bias_layer.addCompartments(bias_neuron)
def set_network_input_layer(self): """ Setup Network Input Layer """ assert len(self.core_list[0]) == self.loihi_snn_dimension[0] neuron_prototype = nx.CompartmentPrototype( compartmentCurrentDecay=2**12) self.network_input_layer = self.net.createCompartmentGroup(size=0) for core in self.core_list[0]: input_neuron = self.net.createCompartment( prototype=neuron_prototype) input_neuron.logicalCoreId = core self.network_input_layer.addCompartments(input_neuron)
def createSTONeurons(self): """ configures the sub-threshold oscillatory neurons """ stoNeuronProto = nx.CompartmentPrototype( logicalCoreId=0, compartmentCurrentDecay=4095, vThMant=39, biasMant=64, numDendriticAccumulators=64, vMinExp=0, functionalState=nx.COMPARTMENT_FUNCTIONAL_STATE.IDLE, thresholdBehavior=nx.COMPARTMENT_THRESHOLD_MODE.SPIKE_AND_RESET) self.stoNeuronGroup = self.net.createCompartmentGroup( prototype=stoNeuronProto, size=1)
def set_network_output_layer(self): """ Setup Network Output Layer """ assert len(self.core_list[-2]) == self.loihi_snn_dimension[-1] neuron_prototype = nx.CompartmentPrototype( vThMant=self.loihi_vth[-1], compartmentCurrentDecay=self.loihi_cdecay, compartmentVoltageDecay=self.loihi_vdecay) self.network_output_layer = self.net.createCompartmentGroup(size=0) for core in self.core_list[-2]: single_neuron = self.net.createCompartment( prototype=neuron_prototype) single_neuron.logicalCoreId = core self.network_output_layer.addCompartments(single_neuron)
def createSTONeurons(self): self.stoNeuronGroup = self.net.createCompartmentGroup() for i in range(self.numENeurons): stoNeuronProto = nx.CompartmentPrototype( logicalCoreId=i, compartmentCurrentDecay=4095, vThMant=39, biasMant=64, numDendriticAccumulators=64, vMinExp=0, functionalState=nx.COMPARTMENT_FUNCTIONAL_STATE.IDLE, thresholdBehavior=nx.COMPARTMENT_THRESHOLD_MODE.SPIKE_AND_RESET ) stoNeuronCx = self.net.createCompartment(prototype=stoNeuronProto) self.stoNeuronGroup.addCompartments(stoNeuronCx)
def _create_special_prototypes(self): selfBiasMant = 5 startupCycles = 2 starterThMant = selfBiasMant * startupCycles - 1 self.prototypes['c_prototypes'][ 'starterProto'] = nx.CompartmentPrototype( vThMant=starterThMant, biasMant=selfBiasMant, biasExp=6, functionalState=2, compartmentVoltageDecay=0, compartmentCurrentDecay=4095, logicalCoreId=self.logicalCore, **prototypes.noise_kwargs) self.prototypes['s_prototypes'][ 'starterInhConn'] = nx.ConnectionPrototype(weight=-selfBiasMant)
def set_network_hidden_layer(self): """ Setup Network Hidden Layer """ for l in range(len(self.loihi_snn_dimension) - 2): assert len(self.core_list[l + 1]) == self.loihi_snn_dimension[l + 1] self.network_hidden_layer = [] for layer in range(len(self.loihi_snn_dimension) - 2): neuron_prototype = nx.CompartmentPrototype( vThMant=self.loihi_vth[layer], compartmentCurrentDecay=self.loihi_cdecay, compartmentVoltageDecay=self.loihi_vdecay) current_layer = self.net.createCompartmentGroup(size=0) for core in self.core_list[layer + 1]: single_neuron = self.net.createCompartment( prototype=neuron_prototype) single_neuron.logicalCoreId = core current_layer.addCompartments(single_neuron) self.network_hidden_layer.append(current_layer)
def set_online_input_encoding(self): """ Create Fake Connections for online input encoding :return online_fanin_axon_id """ assert isinstance(self.network_input_layer, CompartmentGroup) assert len(self.core_list[0]) == self.loihi_snn_dimension[0] neuron_prototype = nx.CompartmentPrototype() pseudo_neurons = self.net.createCompartmentGroup(size=0) for core in self.core_list[0]: pseudo_single = self.net.createCompartment( prototype=neuron_prototype) pseudo_single.logicalCoreId = core pseudo_neurons.addCompartments(pseudo_single) conn_w = np.eye(self.loihi_snn_dimension[0]) * 120 conn_mask = np.int_(np.eye(self.loihi_snn_dimension[0])) self.pseudo_2_input = pseudo_neurons.connect( self.network_input_layer, prototype=nx.ConnectionPrototype( signMode=nx.SYNAPSE_SIGN_MODE.EXCITATORY), connectionMask=conn_mask, weight=conn_w)
def __core(self): """ Private function for core function of Astrocyte computation Point Astrocyte is consists 4 compartments spike_receiver: spiking compartment receive all spikes from presynaptic neurons ip3_integrator: slow spiking compartment integrate spikes from spike_receiver sic_generator: non-spike compartment generate voltage sic from ip3 spike spike_generator: spiking compartment :return: spike_receiver: nx.Compartment :return: sr_2_ip3_conn: nx.Connection :return: ip3_integrator: nx.Compartment :return: ip3_2_sic_conn: nx.Connection :return: sic_generator: nx.Compartment :return: spike_generator: nx.CompartmentGroup """ spike_receiver_prototype = nx.CompartmentPrototype( vThMant=self.srVThMant, compartmentCurrentDecay=self.srCurrentDecay, compartmentVoltageDecay=self.srVoltageDecay, activityImpulse=self.srActivityImpulse, activityTimeConstant=self.srActivityTimeConstant, enableHomeostasis=self.srEnableHomeostasis, maxActivity=self.srMinActivity, minActivity=self.srMaxActivity, homeostasisGain=self.srHomeostasisGain, functionalState=nx.COMPARTMENT_FUNCTIONAL_STATE.IDLE) ip3_integrator_prototype = nx.CompartmentPrototype( vThMant=self.ip3VThMant, compartmentCurrentDecay=self.ip3CurrentDecay, compartmentVoltageDecay=self.ip3VoltageDecay, functionalState=nx.COMPARTMENT_FUNCTIONAL_STATE.IDLE) sic_generator_prototype = nx.CompartmentPrototype( compartmentCurrentDecay=self.sicCurrentDecay, compartmentVoltageDecay=self.sicVoltageDecay, thresholdBehavior=nx.COMPARTMENT_THRESHOLD_MODE. NO_SPIKE_AND_PASS_V_LG_VTH_TO_PARENT, functionalState=nx.COMPARTMENT_FUNCTIONAL_STATE.IDLE, stackOut=nx.COMPARTMENT_OUTPUT_MODE.PUSH) spike_generator_prototype = nx.CompartmentPrototype( vThMant=self.sgVThMant, compartmentCurrentDecay=self.sgCurrentDecay, compartmentVoltageDecay=self.sgVoltageDecay, functionalState=nx.COMPARTMENT_FUNCTIONAL_STATE.IDLE, compartmentJoinOperation=nx.COMPARTMENT_JOIN_OPERATION.ADD, stackIn=nx.COMPARTMENT_INPUT_MODE.POP_A) sr_2_ip3_conn_prototype = nx.ConnectionPrototype( signMode=2, numWeightBits=8, weight=self.sr2ip3Weight) ip3_2_sic_conn_prototype = nx.ConnectionPrototype( signMode=2, numWeightBits=8, weight=self.ip32sicWeight) """ Astrocyte model part 1: simulate IP3 integration """ spike_receiver = self.net.createCompartment( prototype=spike_receiver_prototype) ip3_integrator = self.net.createCompartment( prototype=ip3_integrator_prototype) sr_2_ip3_conn = spike_receiver.connect( ip3_integrator, prototype=sr_2_ip3_conn_prototype) """ Astrocyte model part 2: simulate SIC """ sic_generator = self.net.createCompartment( prototype=sic_generator_prototype) spike_generator_tmp = self.net.createCompartment( prototype=spike_generator_prototype) spike_generator = self.net.createCompartmentGroup() spike_generator.addCompartments([spike_generator_tmp]) ip3_2_sic_conn = ip3_integrator.connect( sic_generator, prototype=ip3_2_sic_conn_prototype) """ return """ return [ spike_receiver, sr_2_ip3_conn, ip3_integrator, ip3_2_sic_conn, sic_generator, spike_generator ]
def connectReservoir(self): # Predefine some helper variables nEx = self.p.reservoirExSize nExCores = int(np.ceil(nEx / self.p.neuronsPerCore)) nLastExCore = nEx % self.p.neuronsPerCore # number of excitatory neurons in last core nIn = self.p.reservoirInSize nInCores = int(np.ceil(nIn / self.p.neuronsPerCore)) nLastInCore = nIn % self.p.neuronsPerCore # number of inhibitory neurons in last core exConnProto = None # Create learning rule if self.p.isLearningRule: # Define learning rule lr = self.nxNet.createLearningRule( dw=self.p.learningRule, tEpoch=self.p.learningEpoch, x1Impulse=self.p.learningImpulse, x1TimeConstant=self.p.learningTimeConstant, y1Impulse=self.p.learningImpulse, y1TimeConstant=self.p.learningTimeConstant) # Define connection prototype with learning rule exConnProto = nx.ConnectionPrototype( signMode=nx.SYNAPSE_SIGN_MODE.EXCITATORY, weightExponent=self.p.weightExponent, enableLearning=1, learningRule=lr) else: # Define connection prototype from basic network exConnProto = self.exConnProto # Define excitatory compartment prototypes and compartment groups # initial value is first available core id in core list frCore, toCore = self.coresAvailable[0], self.coresAvailable[0] + nExCores for i in range(frCore, toCore): # Excitatory compartment prototype exCompProto = nx.CompartmentPrototype( compartmentVoltageDecay=int(1 / self.p.voltageTau * 2**12), compartmentCurrentDecay=int(1 / self.p.currentTau * 2**12), vThMant=self.p.thresholdMant, refractoryDelay=self.p.refractoryDelay, logicalCoreId=i, enableSpikeBackprop=self.p.isLearningRule, enableSpikeBackpropFromSelf=self.p.isLearningRule, functionalState=nx.COMPARTMENT_FUNCTIONAL_STATE.IDLE) # Calculate size of compartment: if last core has remainder, use remainder as size size = nLastExCore if (i == (toCore - 1) and nLastExCore > 0) else self.p.neuronsPerCore # Excitatory compartment group self.exReservoirChunks.append( self.nxNet.createCompartmentGroup(size=size, prototype=exCompProto)) # Remove used core from core list self.removeCoreFromList() # Define inhibitory compartment prototypes and compartment groups # initial value is first available core id in core list frCore, toCore = self.coresAvailable[0], self.coresAvailable[0] + nInCores for i in range(frCore, toCore): # Inhibitory compartment prototype inCompProto = nx.CompartmentPrototype( compartmentVoltageDecay=int(1 / self.p.voltageTau * 2**12), compartmentCurrentDecay=int(1 / self.p.currentTau * 2**12), vThMant=self.p.thresholdMant, refractoryDelay=self.p.refractoryDelay, logicalCoreId=i, functionalState=nx.COMPARTMENT_FUNCTIONAL_STATE.IDLE) # Calculate size of compartment: if last core has remainder, use remainder as size size = nLastInCore if (i == (toCore - 1) and nLastInCore > 0) else self.p.neuronsPerCore # Inhibitory compartment prototype self.inReservoirChunks.append( self.nxNet.createCompartmentGroup(size=size, prototype=inCompProto)) # Remove used core from core list self.removeCoreFromList() # Interconnect excitatory and inhibitory network chunks connectNetworkChunks(self, fromChunks=self.exReservoirChunks, toChunks=self.exReservoirChunks, mask=self.initialMasks.exex, weights=self.initialWeights.exex, prototype=exConnProto, store=self.p.isWeightProbe) connectNetworkChunks(self, fromChunks=self.inReservoirChunks, toChunks=self.inReservoirChunks, mask=self.initialMasks.inin, weights=self.initialWeights.inin, prototype=self.inConnProto) connectNetworkChunks(self, fromChunks=self.exReservoirChunks, toChunks=self.inReservoirChunks, mask=self.initialMasks.exin, weights=self.initialWeights.exin, prototype=self.exConnProto) connectNetworkChunks(self, fromChunks=self.inReservoirChunks, toChunks=self.exReservoirChunks, mask=self.initialMasks.inex, weights=self.initialWeights.inex, prototype=self.inConnProto) # Log that all cores are interconnected logging.info('All cores are sucessfully interconnected')
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
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, compartmentCurrentDecay=int(1 / 10 * 2**12), compartmentVoltageDecay=int(1 / 4 * 2**12), functionalState=nx.COMPARTMENT_FUNCTIONAL_STATE.IDLE) post_neurons = net.createCompartmentGroup(size=post_neuron_cnt, prototype=post_neuron_proto) # Create a connection from the pre to post-synaptic neuron conn_proto = nx.ConnectionPrototype() conn_mask = np.zeros((20, 20)) # Turn on connections in the mask between the first 10 pre-synaptic and first 10 post-synaptic neurons conn_mask[0:10] = np.arange(20) < 10 # Turn on connections in the mask between the last 10 pre-synaptic and last 10 post-synaptic neurons conn_mask[-10:] = np.arange(20) >= 10 # Randomly turn off some of the connections enabled in the two groups conn_mask *= (np.random.rand(20, 20) < 0.5)
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 _create_prototypes(self): #setup compartment prototypes c_prototypes = {} n_prototypes = {} s_prototypes = {} #Q Neuron c_prototypes['somaProto'] = nx.CompartmentPrototype( vThMant=self.vth, compartmentCurrentDecay=4095, compartmentVoltageDecay=0) c_prototypes['spkProto'] = nx.CompartmentPrototype( vThMant=self.vth, compartmentCurrentDecay=4095, compartmentVoltageDecay=0, thresholdBehavior=2) c_prototypes['ememProto'] = nx.CompartmentPrototype( vThMant=self.vth, #vMaxExp=15, compartmentCurrentDecay=4095, compartmentVoltageDecay=0, thresholdBehavior=3) c_prototypes['somaProto'].addDendrite([c_prototypes['spkProto']], nx.COMPARTMENT_JOIN_OPERATION.OR) c_prototypes['spkProto'].addDendrite([c_prototypes['ememProto']], nx.COMPARTMENT_JOIN_OPERATION.ADD) n_prototypes['qProto'] = nx.NeuronPrototype(c_prototypes['somaProto']) #S Inverter c_prototypes['invProto'] = nx.CompartmentPrototype( vThMant=self.vth - 1, compartmentCurrentDecay=4095, compartmentVoltageDecay=0, thresholdBehavior=0, functionalState=2) c_prototypes['spkProto'] = nx.CompartmentPrototype( vThMant=self.vth - 1, biasMant=self.vth, biasExp=6, thresholdBehavior=0, compartmentCurrentDecay=4095, compartmentVoltageDecay=0, functionalState=2) c_prototypes['receiverProto'] = nx.CompartmentPrototype( vThMant=self.vth - 1, compartmentCurrentDecay=4095, compartmentVoltageDecay=0, thresholdBehavior=0) c_prototypes['invProto'].addDendrite( [c_prototypes['receiverProto']], nx.COMPARTMENT_JOIN_OPERATION.BLOCK) n_prototypes['invNeuron'] = nx.NeuronPrototype( c_prototypes['invProto']) #AND c_prototypes['andProto'] = nx.CompartmentPrototype( vThMant=self.vth, compartmentCurrentDecay=4095, compartmentVoltageDecay=4095) #Counter (debug) v_th_max = 2**17 - 1 c_prototypes['counterProto'] = nx.CompartmentPrototype( vThMant=v_th_max, compartmentCurrentDecay=4095, compartmentVoltageDecay=0) #Connections s_prototypes['econn'] = nx.ConnectionPrototype(weight=2) s_prototypes['iconn'] = nx.ConnectionPrototype(weight=-2) s_prototypes['vthconn'] = nx.ConnectionPrototype(weight=-self.vth) s_prototypes['spkconn'] = nx.ConnectionPrototype(weight=self.vth) s_prototypes['halfconn'] = nx.ConnectionPrototype( weight=int(self.vth / 2) + 1) s_prototypes['single'] = nx.ConnectionPrototype(weight=2) self.c_prototypes = c_prototypes self.n_prototypes = n_prototypes self.s_prototypes = s_prototypes
def createExcitatoryMCNeurons(self): # Create MC-AD neurons recieve the input biases. The activity of # the MC-AD neurons is gated by the STO Neurons. if self.inputBiases is None: self.inputBiases = [0] * self.numCores self.mcADNeuronGroup = self.net.createCompartmentGroup() for coreIdx in range(self.numCores): mcADProto = nx.CompartmentPrototype( logicalCoreId=coreIdx, compartmentCurrentDecay=0, vThMant=10, # i.e. 10 * 64 = 640 biasMant=self.inputBiases[coreIdx], refractoryDelay=20, vMinExp=0, numDendriticAccumulators=64, functionalState=nx.COMPARTMENT_FUNCTIONAL_STATE.IDLE, thresholdBehavior=nx.COMPARTMENT_THRESHOLD_MODE.SPIKE_AND_RESET ) mcADCx = self.net.createCompartment(prototype=mcADProto) self.mcADNeuronGroup.addCompartments(mcADCx) # Create MC-Soma neurons which get input form MC-AD neurons. MC-Soma # neurons connect to the Inhibitory GC neurons. self.allMCSomaNeuronsGrp = self.net.createCompartmentGroup() self.mcNeuronGrpPerCoreList = [] for coreIdx in range(self.numCores): mcSomaNeuronProto = nx.CompartmentPrototype( logicalCoreId=coreIdx, compartmentCurrentDecay=0, compartmentVoltageDecay=4095, vThMant=2, # i.e. 2 * 64 = 128 refractoryDelay=19, vMinExp=0, numDendriticAccumulators=64, functionalState=nx.COMPARTMENT_FUNCTIONAL_STATE.IDLE, thresholdBehavior=nx.COMPARTMENT_THRESHOLD_MODE.SPIKE_AND_RESET ) mcNeuronGrpPerCore = self.net.createCompartmentGroup() for _ in range(self.numENeuronsPerCore): mcSomaNeuronCx = self.net.createCompartment( prototype=mcSomaNeuronProto) self.allMCSomaNeuronsGrp.addCompartments(mcSomaNeuronCx) mcNeuronGrpPerCore.addCompartments(mcSomaNeuronCx) self.mcNeuronGrpPerCoreList.append(mcNeuronGrpPerCore) # Connect each MC-AD neuron to its MC-Soma neuron mcADToSomaConnProtoBox = nx.ConnectionPrototype( weight=3, delay=19, numDelayBits=6, enableDelay=1, signMode=nx.SYNAPSE_SIGN_MODE.EXCITATORY, postSynResponseMode=nx.SYNAPSE_POST_SYN_RESPONSE_MODE.BOX, compressionMode=nx.SYNAPSE_COMPRESSION_MODE.SPARSE) for coreIdx in range(self.numENeurons): self.net._createConnection(src=self.mcADNeuronGroup[coreIdx], dst=self.allMCSomaNeuronsGrp[coreIdx], prototype=mcADToSomaConnProtoBox)
def create_prototypes(vth=255, logicalCoreId=-1, noisy=0, synscale=1): prototypes = {} prototypes['vth'] = vth #setup compartment prototypes c_prototypes = {} n_prototypes = {} s_prototypes = {} #Q Neuron c_prototypes['somaProto'] = nx.CompartmentPrototype( vThMant=vth, compartmentCurrentDecay=4095, compartmentVoltageDecay=0, logicalCoreId=logicalCoreId, enableNoise=0, **noise_kwargs) c_prototypes['spkProto'] = nx.CompartmentPrototype( vThMant=vth, biasMant=int(vth / 2), biasExp=6, compartmentCurrentDecay=4095, compartmentVoltageDecay=0, thresholdBehavior=2, logicalCoreId=logicalCoreId, enableNoise=noisy, **noise_kwargs) c_prototypes['ememProto'] = nx.CompartmentPrototype( vThMant=vth, #vMaxExp=15, compartmentCurrentDecay=4095, compartmentVoltageDecay=0, thresholdBehavior=3, logicalCoreId=logicalCoreId, enableNoise=0, **noise_kwargs) c_prototypes['somaProto'].addDendrite([c_prototypes['spkProto']], nx.COMPARTMENT_JOIN_OPERATION.OR) c_prototypes['spkProto'].addDendrite([c_prototypes['ememProto']], nx.COMPARTMENT_JOIN_OPERATION.ADD) n_prototypes['qProto'] = nx.NeuronPrototype(c_prototypes['somaProto']) #Soft Reset Neuron c_prototypes['srSomaProto'] = nx.CompartmentPrototype( vThMant=vth, compartmentCurrentDecay=4095, compartmentVoltageDecay=0, logicalCoreId=logicalCoreId, enableNoise=0, **noise_kwargs) c_prototypes['srSpkProto'] = nx.CompartmentPrototype( vThMant=vth, biasMant=0, biasExp=6, compartmentCurrentDecay=4095, compartmentVoltageDecay=0, thresholdBehavior=2, logicalCoreId=logicalCoreId, enableNoise=noisy, **noise_kwargs) c_prototypes['intProto'] = nx.CompartmentPrototype( vThMant=vth, #vMaxExp=15, compartmentCurrentDecay=4095, compartmentVoltageDecay=4095, thresholdBehavior=0, logicalCoreId=logicalCoreId, enableNoise=0, **noise_kwargs) c_prototypes['srSomaProto'].addDendrite([c_prototypes['srSpkProto']], nx.COMPARTMENT_JOIN_OPERATION.OR) c_prototypes['srSpkProto'].addDendrite([c_prototypes['intProto']], nx.COMPARTMENT_JOIN_OPERATION.ADD) n_prototypes['srProto'] = nx.NeuronPrototype(c_prototypes['srSomaProto']) #FF Neuron c_prototypes['ffSomaProto'] = nx.CompartmentPrototype( vThMant=1, compartmentCurrentDecay=4095, compartmentVoltageDecay=0, logicalCoreId=logicalCoreId, enableNoise=0, **noise_kwargs) c_prototypes['ffSomaProto'].addDendrite([c_prototypes['ememProto']], nx.COMPARTMENT_JOIN_OPERATION.ADD) n_prototypes['ffProto'] = nx.NeuronPrototype(c_prototypes['ffSomaProto']) #Inverter compartment c_prototypes['invProto'] = nx.CompartmentPrototype( vThMant=1, biasMant=2, biasExp=6, compartmentVoltageDecay=0, functionalState=2, logicalCoreId=logicalCoreId, enableNoise=0, **noise_kwargs) #buffer / OR c_prototypes['bufferProto'] = nx.CompartmentPrototype( vThMant=1, compartmentVoltageDecay=4095, compartmentCurrentDecay=4095, logicalCoreId=logicalCoreId, enableNoise=0, **noise_kwargs) #AND c_prototypes['andProto'] = nx.CompartmentPrototype( vThMant=vth, compartmentCurrentDecay=4095, compartmentVoltageDecay=4095, logicalCoreId=logicalCoreId, enableNoise=0, **noise_kwargs) #Counter v_th_max = 2**17 - 1 c_prototypes['counterProto'] = nx.CompartmentPrototype( vThMant=v_th_max, compartmentCurrentDecay=4095, compartmentVoltageDecay=0, logicalCoreId=logicalCoreId, enableNoise=0, **noise_kwargs) #Connections #scaled vth used when synscale is being used to increase dynamic range vth = vth / synscale s_prototypes['econn'] = nx.ConnectionPrototype(weight=2) s_prototypes['iconn'] = nx.ConnectionPrototype(weight=-2) s_prototypes['invconn'] = nx.ConnectionPrototype(weight=-1) s_prototypes['vthconn'] = nx.ConnectionPrototype(weight=-vth) s_prototypes['spkconn'] = nx.ConnectionPrototype(weight=vth) s_prototypes['halfconn'] = nx.ConnectionPrototype(weight=int(vth / 2) + 1) s_prototypes['thirdconn'] = nx.ConnectionPrototype(weight=int(vth / 3) + 1) s_prototypes['single'] = nx.ConnectionPrototype(weight=2) prototypes['c_prototypes'] = c_prototypes prototypes['n_prototypes'] = n_prototypes prototypes['s_prototypes'] = s_prototypes return prototypes
def create_prototypes(self, vth=255, logicalCoreId=-1): prototypes = {} prototypes['vth'] = vth #setup compartment prototypes c_prototypes = {} n_prototypes = {} s_prototypes = {} #Q Neuron c_prototypes['somaProto'] = nx.CompartmentPrototype( vThMant=vth, compartmentCurrentDecay=4095, compartmentVoltageDecay=0, logicalCoreId=logicalCoreId) c_prototypes['spkProto'] = nx.CompartmentPrototype( vThMant=vth, compartmentCurrentDecay=4095, compartmentVoltageDecay=0, thresholdBehavior=2, logicalCoreId=logicalCoreId) c_prototypes['ememProto'] = nx.CompartmentPrototype( vThMant=vth, #vMaxExp=15, compartmentCurrentDecay=4095, compartmentVoltageDecay=0, thresholdBehavior=3, logicalCoreId=logicalCoreId) c_prototypes['somaProto'].addDendrite([c_prototypes['spkProto']], nx.COMPARTMENT_JOIN_OPERATION.OR) c_prototypes['spkProto'].addDendrite([c_prototypes['ememProto']], nx.COMPARTMENT_JOIN_OPERATION.ADD) n_prototypes['qProto'] = nx.NeuronPrototype(c_prototypes['somaProto']) #S Inverter c_prototypes['invProto'] = nx.CompartmentPrototype( vThMant=vth - 1, compartmentCurrentDecay=4095, compartmentVoltageDecay=0, thresholdBehavior=0, functionalState=2, logicalCoreId=logicalCoreId) c_prototypes['spkProto'] = nx.CompartmentPrototype( vThMant=vth - 1, biasMant=vth, biasExp=6, thresholdBehavior=0, compartmentCurrentDecay=4095, compartmentVoltageDecay=0, functionalState=2, logicalCoreId=logicalCoreId) c_prototypes['receiverProto'] = nx.CompartmentPrototype( vThMant=vth - 1, compartmentCurrentDecay=4095, compartmentVoltageDecay=0, thresholdBehavior=0, logicalCoreId=logicalCoreId) c_prototypes['invProto'].addDendrite([c_prototypes['receiverProto']], nx.COMPARTMENT_JOIN_OPERATION.BLOCK) n_prototypes['invNeuron'] = nx.NeuronPrototype(c_prototypes['invProto']) c_prototypes['bufferProto'] = nx.CompartmentPrototype( vThMant=1, compartmentCurrentDecay=4095, compartmentVoltageDecay=4095, logicalCoreId=logicalCoreId) #AND c_prototypes['andProto'] = nx.CompartmentPrototype( vThMant=vth, compartmentCurrentDecay=4095, compartmentVoltageDecay=4095, logicalCoreId=logicalCoreId) #Counter (debug) v_th_max = 2**17 - 1 c_prototypes['counterProto'] = nx.CompartmentPrototype( vThMant=v_th_max, compartmentCurrentDecay=4095, compartmentVoltageDecay=0, logicalCoreId=logicalCoreId) #Connections s_prototypes['econn'] = nx.ConnectionPrototype(weight=2) s_prototypes['iconn'] = nx.ConnectionPrototype(weight=-2) s_prototypes['vthconn'] = nx.ConnectionPrototype(weight=-vth) s_prototypes['spkconn'] = nx.ConnectionPrototype(weight=vth) s_prototypes['halfconn'] = nx.ConnectionPrototype(weight=int(vth / 2) + 1) s_prototypes['thirdconn'] = nx.ConnectionPrototype(weight=int(vth / 3) + 1) s_prototypes['single'] = nx.ConnectionPrototype(weight=2) prototypes['c_prototypes'] = c_prototypes prototypes['n_prototypes'] = n_prototypes prototypes['s_prototypes'] = s_prototypes return prototypes