def ConfigTstTrlLog(ss, dt): dt.SetMetaData("name", "TstTrlLog") dt.SetMetaData("desc", "Record of testing per input pattern") dt.SetMetaData("read-only", "true") dt.SetMetaData("precision", str(LogPrec)) nt = ss.TestEnv.Table.Len() sch = etable.Schema( [etable.Column("Trial", etensor.INT64, go.nil, go.nil), etable.Column("TrialName", etensor.STRING, go.nil, go.nil), etable.Column("Cycle", etensor.INT64, go.nil, go.nil)] ) for lnm in ss.TstRecLays: ly = leabra.Layer(ss.Net.LayerByName(lnm)) sch.append( etable.Column(lnm, etensor.FLOAT64, ly.Shp.Shp, go.nil)) dt.SetFromSchema(sch, nt)
def ApplyInputs(ss, en): """ ApplyInputs applies input patterns from given envirbonment. It is good practice to have this be a separate method with appropriate args so that it can be used for various different contexts (training, testing, etc). """ ss.Net.InitExt() # going to the same layers, but good practice and cheap anyway lays = ["LGNon", "LGNoff"] for lnm in lays: ly = leabra.Layer(ss.Net.LayerByName(lnm)) pats = en.State(ly.Nm) if pats != 0: ly.ApplyExt(pats)
def LogTrnEpc(ss, dt): """ LogTrnEpc adds data from current epoch to the TrnEpcLog table. computes epoch averages prior to logging. # this is triggered by increment so use previous value """ row = dt.Rows dt.SetNumRows(row + 1) epc = ss.TrainEnv.Epoch.Prv nt = float(ss.TrainEnv.Table.Len()) # number of trials in view ss.EpcSSE = ss.SumSSE / nt ss.SumSSE = 0 ss.EpcAvgSSE = ss.SumAvgSSE / nt ss.SumAvgSSE = 0 ss.EpcPctErr = float(ss.SumErr) / nt ss.SumErr = 0 ss.EpcPctCor = 1 - ss.EpcPctErr ss.EpcCosDiff = ss.SumCosDiff / nt ss.SumCosDiff = 0 if ss.FirstZero < 0 and ss.EpcPctErr == 0: ss.FirstZero = epc if ss.EpcPctErr == 0: ss.NZero += 1 else: ss.NZero = 0 dt.SetCellFloat("Run", row, float(ss.TrainEnv.Run.Cur)) dt.SetCellFloat("Epoch", row, float(epc)) dt.SetCellFloat("SSE", row, ss.EpcSSE) dt.SetCellFloat("AvgSSE", row, ss.EpcAvgSSE) dt.SetCellFloat("PctErr", row, ss.EpcPctErr) dt.SetCellFloat("PctCor", row, ss.EpcPctCor) dt.SetCellFloat("CosDiff", row, ss.EpcCosDiff) for lnm in ss.LayStatNms: ly = leabra.Layer(ss.Net.LayerByName(lnm)) dt.SetCellFloat(ly.Nm+" ActAvg", row, float(ly.Pool(0).ActAvg.ActPAvgEff)) # note: essential to use Go version of update when called from another goroutine ss.TrnEpcPlot.GoUpdate() if ss.TrnEpcFile != 0: if ss.TrainEnv.Run.Cur == 0 and epc == 0: dt.WriteCSVHeaders(ss.TrnEpcFile, etable.Tab) dt.WriteCSVRow(ss.TrnEpcFile, row, etable.Tab)
def Harmony(ss, nt): """ Harmony computes the harmony (excitatory net input Ge * Act) """ harm = float(0) nu = 0 for lyi in nt.Layers: ly = leabra.Layer(handle=lyi) if ly.IsOff(): continue for nrni in ly.Neurons: nrn = leabra.Neuron(handle=nrni) harm += nrn.Ge * nrn.Act nu += 1 if nu > 0: harm /= float(nu) return harm
def ApplyInputs(ss, en): """ ApplyInputs applies input patterns from given envirbonment. It is good practice to have this be a separate method with appropriate # going to the same layers, but good practice and cheap anyway args so that it can be used for various different contexts (training, testing, etc). """ ss.Net.InitExt() lays = go.Slice_string(["Name", "Identity", "Color", "FavoriteFood", "Size", "Species", "FavoriteToy"]) for lnm in lays : ly = leabra.Layer(ss.Net.LayerByName(lnm)) pats = en.State(ly.Nm) if pats != 0: ly.ApplyExt(pats)
def TrainTrial(ss): """ TrainTrial runs one trial of training using TrainEnv """ if ss.NeedsNewRun: ss.NewRun() ss.TrainEnv.Step() # Key to query counters FIRST because current state is in NEXT epoch # if epoch counter has changed epc = env.CounterCur(ss.TrainEnv, env.Epoch) chg = env.CounterChg(ss.TrainEnv, env.Epoch) if chg: if ss.ViewOn and ss.TrainUpdt.value > leabra.AlphaCycle: ss.UpdateView(True) if epc >= ss.MaxEpcs: # done with training.. ss.RunEnd() if ss.TrainEnv.Run.Incr(): # we are done! ss.StopNow = True return else: ss.NeedsNewRun = True return rch = leabra.Layer(ss.Net.LayerByName("Reach")) if "choice" in ss.TrainEnv.TrialName.Cur: rch.SetType(emer.Compare) else: rch.SetType(emer.Input) if ss.TrainEnv.GroupName.Cur != ss.PrvGpName: # init at start of new group ss.Net.InitActs() ss.PrvGpName = ss.TrainEnv.GroupName.Cur train = True if "delay" in ss.TrainEnv.TrialName.Cur: train = False # don't learn on delay trials ss.ApplyInputs(ss.TrainEnv) ss.AlphaCyc(train) ss.TrialStats(True) # accumulate ss.LogTrnTrl(ss.TrnTrlLog, ss.TrainEnv.Trial.Cur, ss.TrainEnv.TrialName.Cur)
def AlphaCyc(ss): """ AlphaCyc runs one alpha-cycle (100 msec, 4 quarters) of processing. External inputs must have already been applied prior to calling, using ApplyExt method on relevant layers (see TrainTrial, TestTrial). Handles netview updating within scope of AlphaCycle """ if ss.Win != 0: ss.Win.PollEvents( ) # this is essential for GUI responsiveness while running viewUpdt = ss.ViewUpdt.value out = leabra.Layer(ss.Net.LayerByName("Output")) ss.Net.AlphaCycInit() ss.Time.AlphaCycStart() overThresh = False for qtr in range(4): for cyc in range(ss.Time.CycPerQtr): ss.Net.Cycle(ss.Time) ss.Time.CycleInc() if viewUpdt == leabra.Cycle: if cyc != ss.Time.CycPerQtr - 1: # will be updated by quarter ss.UpdateView() if viewUpdt == leabra.FastSpike: if (cyc + 1) % 10 == 0: ss.UpdateView() trgact = out.Neurons[1].Act if trgact > 0.5: overThresh = True break ss.Net.QuarterFinal(ss.Time) ss.Time.QuarterInc() if viewUpdt <= leabra.Quarter: ss.UpdateView() if viewUpdt == leabra.Phase: if qtr >= 2: ss.UpdateView() if overThresh: break ss.UpdateView()
def ConfigTrnTrlLog(ss, dt): dt.SetMetaData("name", "TrnTrlLog") dt.SetMetaData("desc", "Record of training per input event (time step)") dt.SetMetaData("read-only", "true") dt.SetMetaData("precision", str(LogPrec)) nt = 0 sch = etable.Schema( [etable.Column("Run", etensor.INT64, go.nil, go.nil), etable.Column("Epoch", etensor.INT64, go.nil, go.nil), etable.Column("Trial", etensor.INT64, go.nil, go.nil), etable.Column("Event", etensor.INT64, go.nil, go.nil), etable.Column("TD", etensor.FLOAT64, go.nil, go.nil), etable.Column("RewPred", etensor.FLOAT64, go.nil, go.nil)] ) for lnm in ss.TstRecLays: ly = leabra.Layer(ss.Net.LayerByName(lnm)) sch.append( etable.Column(lnm, etensor.FLOAT64, ly.Shp.Shp, go.nil)) dt.SetFromSchema(sch, nt)
def SetParams(ss, sheet, setMsg): """ SetParams sets the params for "Base" and then current ParamSet. If sheet is empty, then it applies all avail sheets (e.g., Network, Sim) otherwise just the named sheet if setMsg = true then we output a message for each param that was set. """ if sheet == "": ss.Params.ValidateSheets(go.Slice_string(["Network", "Sim"])) ss.SetParamsSet("Base", sheet, setMsg) if ss.ParamSet != "" and ss.ParamSet != "Base": sps = ss.ParamSet.split() for ps in sps: ss.SetParamsSet(ps, sheet, setMsg) ly = leabra.Layer(ss.Net.LayerByName("NeckerCube")) ly.Act.Noise.Var = float(ss.Noise) ly.Act.KNa.On = ss.KNaAdapt ly.Act.Update() ss.Time.CycPerQtr = int(ss.CycPerQtr)
def LogTstTrl(ss, dt): """ LogTstTrl adds data from current trial to the TstTrlLog table. log always contains number of testing items """ trl = ss.TestEnv.Trial.Cur row = trl if dt.Rows <= row: dt.SetNumRows(row + 1) dt.SetCellFloat("Trial", row, float(trl)) dt.SetCellString("TrialName", row, ss.TestEnv.TrialName.Cur) for lnm in ss.TstRecLays: tsr = ss.ValsTsr(lnm) ly = leabra.Layer(ss.Net.LayerByName(lnm)) ly.UnitValsTensor(tsr, "Act") dt.SetCellTensor(lnm, row, tsr) ss.TstTrlPlot.GoUpdate()
def SetParamsSet(ss, setNm, sheet, setMsg): """ SetParamsSet sets the params for given params.Set name. If sheet is empty, then it applies all avail sheets (e.g., Network, Sim) otherwise just the named sheet if setMsg = true then we output a message for each param that was set. """ pset = ss.Params.SetByNameTry(setNm) if sheet == "" or sheet == "Network": if "Network" in pset.Sheets: netp = pset.SheetByNameTry("Network") ss.Net.ApplyParams(netp, setMsg) hid = leabra.Layer(ss.Net.LayerByName("Hidden")) fmhid = leabra.Prjn(hid.RcvPrjns.SendName("Hidden")) fmhid.WtInit.Mean = ss.RecurrentWt if sheet == "" or sheet == "Sim": if "Sim" in pset.Sheets: simp = pset.SheetByNameTry("Sim") pyparams.ApplyParams(ss, simp, setMsg) simp.Apply(ss, setMsg)
def LogTstCyc(ss, dt, cyc): """ LogTstCyc adds data from current cycle to the TstCycLog table. log always contains number of testing items """ nt = ss.Net() if dt.Rows <= cyc: dt.SetNumRows(cyc + 1) row = cyc dt.SetCellFloat("Cycle", row, float(cyc)) for lnm in ss.TstRecLays: ly = leabra.Layer(nt.LayerByName(lnm)) dt.SetCellFloat(lnm + "ActAvg", row, float(ly.Pool(0).Inhib.Act.Avg)) # note: essential to use Go version of update when called from another goroutine if cyc % 10 == 0: ss.TstCycPlot.GoUpdate()
def SetParams(ss, sheet, setMsg): """ SetParams sets the params for "Base" and then current ParamSet. If sheet is empty, then it applies all avail sheets (e.g., Network, Sim) otherwise just the named sheet if setMsg = true then we output a message for each param that was set. """ if sheet == "": ss.Params.ValidateSheets(go.Slice_string(["Network", "Sim"])) ss.SetParamsSet("Base", sheet, setMsg) if ss.ParamSet != "" and ss.ParamSet != "Base": sps = ss.ParamSet.split() for ps in sps: ss.SetParamsSet(ps, sheet, setMsg) nt = ss.Net v1 = leabra.Layer(nt.LayerByName("V1")) elat = leabra.Prjn(v1.RcvPrjns[2]) elat.WtScale.Rel = ss.ExcitLateralScale elat.Learn.Learn = ss.ExcitLateralLearn ilat = leabra.Prjn(v1.RcvPrjns[3]) ilat.WtScale.Abs = ss.InhibLateralScale
def LogTstCyc(ss, dt, cyc): """ LogTstCyc adds data from current cycle to the TstCycLog table. log always contains number of testing items """ if dt.Rows <= cyc: dt.SetNumRows(cyc + 1) row = cyc harm = ss.Harmony(ss.Net) dt.SetCellFloat("Cycle", row, float(cyc)) dt.SetCellString("TrialName", row, ss.TestEnv.TrialName.Cur) dt.SetCellFloat("Harmony", row, float(harm)) for lnm in ss.TstRecLays: tsr = ss.ValsTsr(lnm) ly = leabra.Layer(ss.Net.LayerByName(lnm)) ly.UnitValsTensor(tsr, "Act") dt.SetCellTensor(lnm, row, tsr) ss.TstCycPlot.GoUpdate()
def TrialStats(ss, accum): """ TrialStats computes the trial-level statistics and adds them to the epoch accumulators if accum is true. Note that we're accumulating stats here on the Sim side so the core algorithm side remains as simple as possible, and doesn't need to worry about different time-scales over which stats could be accumulated etc. You can also aggregate directly from log data, as is done for testing stats """ out = leabra.Layer(ss.Net.LayerByName("Output")) ss.TrlCosDiff = float(out.CosDiff.Cos) ss.TrlSSE = out.SSE(0.5) # 0.5 = per-unit tolerance -- right side of .5 ss.TrlAvgSSE = ss.TrlSSE / len(out.Neurons) if ss.TrlSSE > 0: ss.TrlErr = 1 else: ss.TrlErr = 0 if accum: ss.SumErr += ss.TrlErr ss.SumSSE += ss.TrlSSE ss.SumAvgSSE += ss.TrlAvgSSE ss.SumCosDiff += ss.TrlCosDiff return
def RunCycles(ss): """ RunCycles updates neuron over specified number of cycles """ ss.Init() ss.StopNow = False ss.Net.InitActs() ss.SetParams("", False) ly = leabra.Layer(ss.Net.LayerByName("Neuron")) nrn = ly.Neurons[0] inputOn = False for cyc in range(ss.NCycles): if ss.Win != 0: ss.Win.PollEvents( ) # this is essential for GUI responsiveness while running ss.Cycle = cyc if cyc == ss.OnCycle: inputOn = True if cyc == ss.OffCycle: inputOn = False nrn.Noise = float(ly.Act.Noise.Gen(-1)) if inputOn: nrn.Ge = 1 else: nrn.Ge = 0 nrn.Ge += nrn.Noise # GeNoise nrn.Gi = 0 if ss.Spike: ss.SpikeUpdt(ss.Net, inputOn) else: ss.RateUpdt(ss.Net, inputOn) ss.LogTstCyc(ss.TstCycLog, ss.Cycle) if ss.Cycle % ss.UpdtInterval == 0: ss.UpdateView() if ss.StopNow: break ss.UpdateView()
def LogTstCyc(ss, dt, cyc): """ LogTstCyc adds data from current cycle to the TstCycLog table. """ if dt.Rows <= cyc: dt.SetNumRows(cyc + 1) row = cyc ly = leabra.Layer(ss.Net.LayerByName("Neuron")) nrn = leabra.Neuron(ly.Neurons[0]) dt.SetCellFloat("Cycle", row, float(cyc)) dt.SetCellFloat("Ge", row, float(nrn.Ge)) dt.SetCellFloat("Inet", row, float(nrn.Inet)) dt.SetCellFloat("Vm", row, float(nrn.Vm)) dt.SetCellFloat("Act", row, float(nrn.Act)) dt.SetCellFloat("Spike", row, float(nrn.Spike)) dt.SetCellFloat("Gk", row, float(nrn.Gk)) dt.SetCellFloat("ISI", row, float(nrn.ISI)) dt.SetCellFloat("AvgISI", row, float(nrn.ISIAvg)) # note: essential to use Go version of update when called from another goroutine if cyc % ss.UpdtInterval == 0: ss.TstCycPlot.GoUpdate()