⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 neuron.cpp

📁 此代码经过大量使用
💻 CPP
字号:
/***************************************************************************                          neuron.cpp  -  description                             -------------------    copyright            : (C) 2001, 2002 by Matt Grover    email                : mgrover@amygdala.org ***************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************/using namespace std;#include <iostream.h>#include <cmath>#include "neuron.h"#include "network.h"#include "spikeoutput.h"#include "simplespikeoutput.h"#include "types.h"#include "node.h"#include "mpnetwork.h"#include "instance.h"// Uncomment for debugging messages//#define DEBUG_NEURONNeuron::Neuron(AmIdInt neuronId):    nId(neuronId){    SetDefaults();}Neuron::~Neuron(){    //cout << "Deleting a neuron\n";    // delete the synapses    for (unsigned int i=0; i<axon.size(); ++i) {        delete axon[i];    }    axon.clear();    inputHist.clear();    smpAxon.clear();}// Initialize static variablesAmTimeInt Neuron::simStepSize = 100;bool Neuron::recordOutput = false;OutputMode Neuron::outputMode = OUTPUT_LAYERS;SpikeOutput* Neuron::spikeOutput = new SimpleSpikeOutput;bool Neuron::defaultOutputObj = true;bool Neuron::enforceSign = false;bool Neuron::mpMode = false;bool Neuron::spikeDelaysOn = false;void Neuron::SetDefaults(){    // Default values for constants (made up for now)    memTimeConst = 10.0;    synTimeConst = 2.0; // unused except in learning    //restPtnl = -0.07;    restPtnl = 0.0;    membranePtnl = restPtnl;    refPeriod = 2000;    inputTime = 0;    currTime = 0;    spikeTime = 0;    axonSize = 0;    thresholdPtnl = 5.0;    // abs val of difference between thresh and rest ptnl    maxScaledWeight = 0.0;    maxThreshCrs = 0.0;    convergeRes = 0.0;    usePspLookup = false;    trainingMode = true;    // training off by default    inhibitory = false;    // Set defaults for learning    synPotConst = 0.5;          // A+ in Pulsed Neural Networks    synDepConst = 0.2;          // A- in Pulsed Neural Networks    learningMax = -0.05;        // ms units    posLearnTimeConst = 1.0;    // ms    negLearnTimeConst = 20.0;   // ms    learningConst = 1e-2;   //dendriteSize = 10;    initAxonSize = 100;    //default number of outputs for now    if (nId == 0)    {        nId = int(this);    // default id    }    axon.reserve(initAxonSize);    //allocate some memory for the axon//    inWeightHist.reserve(16);//    inTimeHist.reserve(16);    inputHist.reserve(500);    histBeginIdx = 0;}void Neuron::SetMaxScaledWeight(){    maxScaledWeight = 1;}void Neuron::SetSpikeOutput(SpikeOutput* output){    if (defaultOutputObj) {        delete spikeOutput;        defaultOutputObj = false;    }    spikeOutput = output;}void Neuron::SetTimeConstants(float synapticConst, float membraneConst){    // Don't do anything if the lookup table has already been set.    // This will have to be changed when dynamic constant alterations    // are implemented.    if ( !usePspLookup ) {        synTimeConst = synapticConst;        memTimeConst = membraneConst;    }}void Neuron::CaptureOutput(OutputMode mode){    if (mode == OFF) {        recordOutput = false;    }    else {        recordOutput = true;    }    outputMode = mode;}void Neuron::SendSpike(AmTimeInt& now){    int i;    if ( (schedSpikeTime == now) || (layerType == INPUTLAYER) || (layerType == IOLAYER) ) {        #ifdef DEBUG_NEURON        cout << "\nNeuron " << nId << " spiking!" << endl;        #endif        // Do a check to make sure the refractory period has passed.  This        // check will normally be done before the spike is scheduled, but        // some spikes can get thru anyway (input spikes, for example).        // Any spikes scheduled within the refractory period are ignored.        if ( (now - spikeTime) <= refPeriod ) {            // Don't do anything if spikeTime == 0 because this neuron            // has not yet fired and the simulation time could be less            // than the refractory period.            if (spikeTime) {                return;            }        }        membranePtnl = restPtnl;                currTime = now;        if (spikeDelaysOn) {            SNet->ScheduleSpikeDelay(axon);        }        else {            SynapseItr syn = axon.begin();            for (i=0; i<axonSize; ++i) {                //Synapse* syn = axon[i];                (*syn)->GetPostNeuron()->InputSpike(syn, currTime);                ++syn;            }        }        // Send the remote spikes if in multi-processing mode        if (mpMode)            SendSMPSpike(now);        // do training and reset the history table        if (trainingMode) {            Train(currTime);        }        inputHist.clear();        synapseHist.clear();        spikeTime = schedSpikeTime;        schedSpikeTime = 0;        histBeginIdx = 0;        // If this is an output neuron and output mode        // is turned on, record the event according to        // the outputMode.        if (recordOutput) {            if (outputMode == ALL) {                spikeOutput->OutputEvent(nId, currTime);            }            else if (layerType >= OUTPUTLAYER) {                spikeOutput->OutputEvent(nId, currTime);            }        }    }}void Neuron::SendSMPSpike(AmTimeInt& ){    for(unsigned int i=0; i<smpAxon.size(); i++){        SMPSynapse *syn = smpAxon[i];        syn->SpikeEvent();    }}void Neuron::Train(AmTimeInt& spikeTime){    /**************************************************************************     * Implement a Hebbian learning rule as described in Chapter 14 of _Pulsed     * Neural Networks_.  The learning window is defined by a pair of equations.     * For s <= smax (where s = input time and smax = time of maximum learning),     * W = (Apos - Aneg) * exp( -(smax - s)/synTimeConst ).     * For s > smax,     * W = ( Apos * exp( -(s - smax)/posLearnTimeConst )) -     *               ( Aneg * exp( -(s - smax)/negLearnTimeConst )).     **************************************************************************/    AmTimeInt usTimeDiff;    int numInputs;    float timeDiff;    float weightDiff;    float newWeight;    float window;    SynapseHist tmpInput;    int i;    // Declare the inverses of the learning time constants as statics    static float tauPosInv = 1 / posLearnTimeConst;    static float tauNegInv = 1 / negLearnTimeConst;    static float synTimeConstInv = 1 / synTimeConst;    #ifdef DEBUG_NEURON    cout << "Training...\n";    #endif    // iterate thru inputHist and adjust weights for each    // entry.    numInputs = synapseHist.size();    for (i=0; i<numInputs; i++) {        tmpInput = synapseHist[i];        // The time delta will be negative if the input spike        // arrived before the post synaptic spike time, and        // positive otherwise.        if (tmpInput.time > spikeTime) {            usTimeDiff = tmpInput.time - spikeTime;            timeDiff = float(usTimeDiff) * 0.001;  // divide by 1000 to get ms units        }        else {            usTimeDiff = spikeTime - tmpInput.time;            timeDiff = float(usTimeDiff) * -0.001;        }        #ifdef DEBUG_NEURON        cout << "inputTime: " << tmpInput.time << endl;        cout << "spikeTime: " << spikeTime << endl;        cout << "timeDiff: " << usTimeDiff << endl;        #endif        // s < s*        if (timeDiff < learningMax) {            float expTerm = exp( -(learningMax - timeDiff) * synTimeConstInv );            window = (synPotConst - synDepConst) * expTerm;            weightDiff = ( learningConst * window ) * maxScaledWeight;        }        else {      // s > s*            float expTerm1 = exp( -(timeDiff - learningMax) * tauPosInv );            float expTerm2 = exp( -(timeDiff - learningMax) * tauNegInv );            window = ( synPotConst * expTerm1 ) - ( synDepConst * expTerm2 );            weightDiff = ( learningConst * window ) * maxScaledWeight;        }        newWeight = tmpInput.syn->GetWeight();        if (newWeight < 0.0) {            newWeight = newWeight - weightDiff;        }        else {            newWeight = newWeight + weightDiff;        }        if (abs(newWeight) < maxScaledWeight) {            tmpInput.syn->SetWeight(newWeight);        }    }}void Neuron::AddSynapse(Synapse* synapse){    // normalize weight    float maxWeight = synapse->GetPostNeuron()->GetMaxScaledWeight();    if (!maxWeight) {        throw "maxScaledWeight has not been set.";    }    float synWeight = synapse->GetWeight();    synapse->SetWeight(synWeight*maxWeight);    //synWeight *= maxWeight;    axon.push_back(synapse);    ++axonSize;}void Neuron::AddSMPSynapse(SMPSynapse* synapse){    // normalize weight    float maxWeight = synapse->GetPostNeuron()->GetMaxScaledWeight();    if (!maxWeight) {        throw "maxScaledWeight has not been set.";    }    float synWeight = synapse->GetWeight();    synapse->SetWeight(synWeight*maxWeight);    //synWeight *= maxWeight;    smpAxon.push_back(synapse);}void Neuron::SetAxonSize(int size){    if (size > axonSize) {        axon.reserve(size);    }}void Neuron::SetTableDimensions(int tblSize, int tblRes){    pspLSize = tblSize;    pspStepSize = tblRes;}/** return a pointer to the physical properties of this neuron */PhysicalProperties * Neuron::GetPhysicalProperties(){    return &physicalProperties;}void Neuron::EnableSpikeBatching(){    spikeDelaysOn = true;}//--------------- Methods of class PhysicalProperties --------------------//PhysicalProperties::PhysicalProperties() {    location[0] = 0.;    location[1] = 0.;    location[2] = 0.;}PhysicalProperties::~PhysicalProperties() {}float *PhysicalProperties::GetLocation(float loc[]){    for(int i=0; i<3; i++) loc[i] = location[i];    return loc;}void PhysicalProperties::SetLocation(float _newVal[]){    location[0] = _newVal[0];    location[1] = _newVal[1];    location[2] = _newVal[2];}//-------------- Methods of class Synapse ---------------------------------//Synapse::Synapse(Neuron* _postNrn, float _weight, AmTimeInt _delay = 0):        weight(_weight),        postNrn(_postNrn){    offset = _delay/Network::TimeStepSize();}AmTimeInt Synapse::GetDelay() const{    return offset*Network::TimeStepSize();}//bool CompareSyn(const Synapse* lsyn, const Synapse* rsyn) {//        return lsyn->GetPostNeuron() < rsyn->GetPostNeuron(); }//-------------- Methods of class SMPSynapse ---------------------------------//SMPSynapse::SMPSynapse(MpSpikeInput *_connector, Neuron* _postNrn, float _weight, AmTimeInt _delay = 0):            Synapse(_postNrn, _weight, _delay){    connector = _connector;}void SMPSynapse::SpikeEvent(){    connector->queueSpike(this);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -