Synaptic scaling balances learning in a spiking model of neocortex (Rowan & Neymotin 2013)

 Download zip file   Auto-launch 
Help downloading and running models
Learning in the brain requires complementary mechanisms: potentiation and activity-dependent homeostatic scaling. We introduce synaptic scaling to a biologically-realistic spiking model of neocortex which can learn changes in oscillatory rhythms using STDP, and show that scaling is necessary to balance both positive and negative changes in input from potentiation and atrophy. We discuss some of the issues that arise when considering synaptic scaling in such a model, and show that scaling regulates activity whilst allowing learning to remain unaltered.
1 . Rowan MS, Neymotin SA (2013) Synaptic Scaling Balances Learning in a Spiking Model of Neocortex Adaptive and Natural Computing Algorithms, Tomassini M, Antonioni A, Daolio F, Buesser P, ed. pp.20
Citations  Citation Browser
Model Information (Click on a link to find other models with that property)
Model Type: Realistic Network;
Brain Region(s)/Organism: Neocortex;
Cell Type(s): Neocortex L5/6 pyramidal GLU cell; Neocortex L2/3 pyramidal GLU cell; Neocortex V1 interneuron basket PV GABA cell; Neocortex fast spiking (FS) interneuron; Neocortex spiny stellate cell; Neocortex spiking regular (RS) neuron; Neocortex spiking low threshold (LTS) neuron; Abstract integrate-and-fire adaptive exponential (AdEx) neuron;
Gap Junctions:
Receptor(s): GabaA; AMPA; NMDA;
Transmitter(s): Gaba; Glutamate;
Simulation Environment: NEURON; Python;
Model Concept(s): Synaptic Plasticity; Long-term Synaptic Plasticity; Learning; STDP; Homeostasis;
Implementer(s): Lytton, William [bill.lytton at]; Neymotin, Sam [Samuel.Neymotin at]; Rowan, Mark [m.s.rowan at];
Search NeuronDB for information about:  Neocortex L5/6 pyramidal GLU cell; Neocortex L2/3 pyramidal GLU cell; Neocortex V1 interneuron basket PV GABA cell; GabaA; AMPA; NMDA; Gaba; Glutamate;
autotune.hoc *
basestdp.hoc *
batch.hoc *
batch2.hoc *
checkirreg.hoc * *
col.hoc *
comppowspec.hoc *
condisconcellfig.hoc *
condisconpowfig.hoc *
declist.hoc *
decmat.hoc *
decnqs.hoc *
decvec.hoc *
default.hoc *
drline.hoc *
e2hubsdisconpow.hoc *
e2incconpow.hoc *
filtutils.hoc *
geom.hoc *
graphplug.hoc *
grvec.hoc *
init.hoc *
labels.hoc *
load.hoc *
local.hoc *
makepopspikenq.hoc *
matfftpowplug.hoc *
matpmtmplug.hoc *
matpmtmsubpopplug.hoc *
matspecplug.hoc *
network.hoc *
nload.hoc *
nqpplug.hoc *
nqs.hoc *
nqsnet.hoc *
nrnoc.hoc *
powchgtest.hoc *
python.hoc *
pywrap.hoc *
redE2.hoc *
setup.hoc *
shufmua.hoc *
simctrl.hoc *
spkts.hoc *
stats.hoc *
syncode.hoc *
vsampenplug.hoc *
xgetargs.hoc *
load_file("writedata.hoc") // Allow periodic saving of data to disk

print "Loading stdpscaling.hoc..."
// stdpscaling.hoc
// Mark Rowan, School of Computer Science, University of Birmingham, UK
// September 2012

// Code to enable synaptic scaling whilst STDP is active (set in params.hoc; see below)
// to investigate whether scaling helps to balance excitatory potentiation and
// avoid transition to epilepsy.

// **********************************************************************
// run.hoc should have SPKSZ set to at least 1400e3 elements (assuming 800e3 ms segmentlength and 1 col)
// run.hoc should have prl(0,1) as the last line in the file to turn off printlist recording
// params.hoc should have PreDur, LearnDur, PostDur and other params set appropriately
// params.hoc should have TrairRate (training signal freq, Hz) set
// params.hoc should have TrainW (training signal weight) set
// Other key values in params.hoc:
//   plastEEinc/plastEIinc/plastIEinc/plastIIinc -- increment amount for adding to weights
//     (in paper, these are 0.05, 0.10, 0.05, 0.05 respectively)
//  plastEEmaxw/plastEImaxw/plastIEmaxw/plastIImaxw -- max increase in weight from baseline
//     (in paper, these are 10, 15, 3, 3 respectively)
// **********************************************************************

// **** User-settable parameters ****
// Scaling params
declare("scaling", 1) // Set to 1 to enable compensatory homeostatic synaptic scaling
declare("activitytau", 100e3) // Activity sensor time constant
declare("activitybeta", 4.0e-8) // Scaling weight
declare("activitygamma", 1.0e-10) // Scaling integral controller weight
declare("scalingstart", 800e3) // Time after which to begin synaptic scaling (needs to be long enough for the activity sensors to accurately estimate average firing rates)
numcells = 470 * scale // Number of cells in the network (set in network.hoc:77 and :124)

// Recording params
declare("recording_interval", 10e3) // How many ms between scalefactor recordings
declare("recording_start", 5e3) // Start recording scalefactors after this time 

// Define objects
objref remainingcellIDs, randgen, deletionList, auxFile, varsFile
strdef auxFileName
strdef varsFileName

proc setup() {
  // Initialise RNG
  randgen = new Random()

  // Set scaling parameters in INTF6

  // Create data file
  // filepath should already have been allocated in writedata.hoc
  sprint(auxFileName, "%s/%s", filepath, "aux")
  sprint(varsFileName, "%s/%s", filepath, "vars")
  auxFile = new File(auxFileName)
  varsFile = new File(varsFileName)
  header_written = 0 // Instruct write_scaling_data() to write vars file header

proc turn_on_scaling() {
  if (scaling) {
    printf("Turning on synaptic scaling\n")

proc write_scaling_data() { local k, id, act, trg, scl, type, dead

  if (!header_written) {
    // Write vars file header
    varsFile.printf("# ************* Runtime params *************\n")

    varsFile.printf("buffertime=%d\n", buffertime)
    varsFile.printf("numcells=%d\n", numcells)
    varsFile.printf("scaling=%d\n", scaling)
    varsFile.printf("scalingstart=%d\n", scalingstart)
    varsFile.printf("recording_interval=%d\n", recording_interval)
    varsFile.printf("t_start=%d\n", recording_start)
    varsFile.printf("activitytau=%e\n", activitytau)
    varsFile.printf("activitybeta=%e\n", activitybeta)
    varsFile.printf("activitygamma=%e\n", activitygamma)
    varsFile.printf("\n# Cell ID, cell type, activity sensor, target activity, scaling factor, is-dead\n")
    varsFile.printf("# Recorded every %d ms\n", recording_interval)
    header_written = 1
  // Open aux file for append

  // Record current time
  auxFile.printf("t = %f\n", t)

  // Write data to given file
  for k=0,numcells-1 {
    id = col.ce.o(k).get_id()
    act = col.ce.o(k).get_activity()
    trg = col.ce.o(k).get_target_act()
    scl = col.ce.o(k).get_scale_factor()
    type = col.ce.o(k).get_type()
    dead = col.ce.o(k).get_dead()
    auxFile.printf("%d,%d,%f,%f,%f,%d\n", id,type,act,trg,scl,dead)
    //printf("%d,%d,%f,%f,%f,%d\n", id,type,act,trg,scl,dead)

  // Close file
  // Queue next event
  cvode.event(t+recording_interval, "write_scaling_data()")

// Callback procedure to start the event queue
// NOTE: Only called once, after hoc file initialised and run() has been called
proc stdpscalingeventqueue() {
  cvode.event(scalingstart, "turn_on_scaling()") // Start scaling after initial delay to find activity
  cvode.event(t + recording_start, "write_scaling_data()") // Start recording of scalefactors etc

declare("stdpfih", new FInitializeHandler("stdpscalingeventqueue()")) // Called as soon as INIT finishes